Subject: Re: [Boost-bugs] [Boost C++ Libraries] #2557: iostreams filtering_stream w/ gzip infinite loop when writing to a full drive
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2010-11-03 15:23:36
#2557: iostreams filtering_stream w/ gzip infinite loop when writing to a full
drive
-----------------------------------------------------+----------------------
Reporter: Tomasz Åniatowski <kailoran@â¦> | Owner: turkanis
Type: Bugs | Status: assigned
Milestone: Boost 1.38.0 | Component: iostreams
Version: Boost 1.37.0 | Severity: Problem
Resolution: | Keywords:
-----------------------------------------------------+----------------------
Comment (by michal-slizak@â¦):
The gzip file consists of a sequence of compressed chunks.
You can manually compress data chunks and append them to a file:
{{{
class StreamSink
{
public:
typedef char char_type;
typedef boost::iostreams::sink_tag category;
StreamSink();
StreamSink(std::ostream * stream);
std::streamsize write(const char * ptr, std::streamsize n);
void close();
bool isOpen() const;
private:
bool opened;
std::ostream * stream;
};
StreamSink::StreamSink():
opened(false),
stream(NULL)
{
}
StreamSink::StreamSink(std::ostream * stream):
opened(true),
stream(stream)
{
assert(stream != NULL, "StreamSink constructed from NULL");
}
std::streamsize StreamSink::write(const char * ptr, std::streamsize n)
{
assert(this->stream != NULL, "Writing to NULL stream");
this->stream->write(ptr, n);
return n;
}
void StreamSink::close()
{
this->opened = false;
this->stream = NULL;
}
bool StreamSink::isOpen() const
{
return this->opened;
}
void writeGzippedSection(string const & filename, ios_base::openmode mode,
string const & data)
{
try
{
std::ofstream out(filename.c_str(), mode | ios::binary);
out.exceptions(std::ios_base::badbit |
std::ios_base::failbit);
StreamSink sink(&out);
boost::iostreams::gzip_compressor compressor;
compressor.write(sink, data.c_str(), data.length());
compressor.close(sink, BOOST_IOS::out);
}
catch (boost::iostreams::gzip_error const & e)
{
std::cerr << "gzip error: " << e.error() << ", zlib error:
" << e.zlib_error_code() << std::endl;
throw;
}
catch (ofstream::failure const & e)
{
std::cerr << "ofstream::failure: " << e.what() <<
std::endl;
throw;
}
}
}}}
The code above produces decompressable files (tested with zcat, zless and
gunzip). Also, when out-of-space occurs, chunks that were written
successfully can be recovered.
The code may not be pretty, but it works.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/2557#comment:4> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:04 UTC