Search code examples
c++segmentation-faultgzipboost-iostreams

Crash if I try to copy uncompressed filtering_istream to stringstream


I want to uncompress a file and write its content into a stringstream.

This is the code I tried:

string readGZipLog () {
 try {
      using namespace boost::iostreams;
      ifstream file(currentFile.c_str(), std::ios_base::in | std::ios_base::binary);
      boost::iostreams::filtering_istream in;
      in.push(gzip_decompressor());
      in.push(file);
      std::stringstream strstream;
      boost::iostreams::copy(in, strstream);
      return strstream.str();
 } catch (std::exception& e) {
      cout << e.what() << endl;
 }
}

void writeGZipLog (char* data) {
    try {
      using namespace boost::iostreams;
      std::ofstream file( currentFile.c_str(), std::ios_base::out |  std::ios_base::binary );
      boost::iostreams::filtering_ostream out;
      out.push( gzip_compressor() );
      out.push(file);
      std::stringstream strstream;
      strstream << data;
      boost::iostreams::copy( strstream, data );
    } catch (std::exception& e) {
      cout << e.what() << endl;
    }
 }

It compiles without any warnings (and of course errors) but the function readGZipLog() crashes while running:

gzip error
./build: line 3: 22174 Segmentation fault      ./test

./build is the script that compiles and starts the application ./test automatically

I checked the file: It contains something, but I can't ungzip it using gunzip. So I am not sure whether the compression worked properly and if this has something to do with the gzip error thrown by Boost.

Can you give me a hit where the error(s) is(/are)?

Thanks for your help!

Paul


Solution

  • after a lot of research and trying I finally found a way how to handle (de)compression correctly.

    This is the code that works for me without any problems (with gzip and bzip2):

    string readGZipLog () {
        using namespace boost::iostreams;
        using namespace std;
       try {
          ifstream file(currentFile.c_str(), ios_base::in | ios_base::binary);
          boost::iostreams::filtering_istream in;
          in.push(gzip_decompressor());
          in.push(file);
          stringstream strstream;
          boost::iostreams::copy(in, strstream);
          return strstream.str();
        } catch (const gzip_error& exception) {
          cout << "Boost Description of Error: " << exception.what() << endl;
          return "err";
        }
    }
    
    bool writeGZipLog (char* data) {
        using namespace boost::iostreams;
        using namespace std;
        try {
          std::ofstream file( currentFile.c_str(), std::ios_base::app );
          boost::iostreams::filtering_ostream out;
          out.push( gzip_compressor() );
          out.push(file);
          stringstream strstream;
          strstream << data;
          boost::iostreams::copy(strstream, out);
          return true;
        } catch (const gzip_error& exception) {
           cout << "Boost Description of Error: " << exception.what() << endl;
           return false;
        }
    }
    

    What I can say is that I did some errors that were not necessary and I just found by looking at the code again many hours later. boost::iostreams::copy( std::stringstream , char* ); for example will even fail if 1 + 1 was 3.

    I hope that this code piece will help somebody as it helped me.

    Paul :)