Re: [Boost-bugs] [Boost C++ Libraries] #2557: iostreams filtering_stream w/ gzip infinite loop when writing to a full drive

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