[iostreams] gzip problem
Hi @boost, I have a file format containing chunks of gzipped data (using gzip_decompressor/gzip_compressor). Inbetween these chunks there is other (plain) data. So can keep the archive seekable. However apparently this doesn't work out as it should. Whenever gzip_decompressor reaches the end of a chunk it throws an exception. The trouble-making line is in basic_gzip_decompressor::read: if (footer_.done()) { if (footer_.crc() != this->crc()) boost::throw_exception(gzip_error(gzip::bad_crc)); int c = boost::iostreams::get(peek); if (traits_type::is_eof(c)) { ----------------------------- state_ = s_done; } else { peek.putback(c); base_type::close(peek, BOOST_IOS::in); state_ = s_start; header_.reset(); footer_.reset(); } } Thus after the footer is read and checked, the decompressor checks whether or not eof is reached. Obvisiously this isn't the case here - the decompressed chunk is just embedded in the file. Thus the decompressor restarts, but cannot find another header thus throwing an exception. Would it be reasonable to just insert a break? header_.reset(); footer_.reset(); + break; } } This would solve _my_ problem. Or is there another way to work around this issue? Best Olaf
On Feb 21, 2014, at 5:00 AM, Olaf Krzikalla
I have a file format containing chunks of gzipped data (using gzip_decompressor/gzip_compressor). Inbetween these chunks there is other (plain) data. So can keep the archive seekable. However apparently this doesn't work out as it should. Whenever gzip_decompressor reaches the end of a chunk it throws an exception.
after the footer is read and checked, the decompressor checks whether or not eof is reached. Obvisiously this isn't the case here - the decompressed chunk is just embedded in the file. Thus the decompressor restarts, but cannot find another header thus throwing an exception.
Could you wrap the input stream in a filter that would pass through only the chunk, pretending to its consumer that the chunk is the entire stream?
Am 21.02.2014 16:26, schrieb Nat Goodspeed:
Could you wrap the input stream in a filter that would pass through only the chunk, pretending to its consumer that the chunk is the entire stream? Yep, the following code does the trick:
struct chunk_device : boost::iostreams::source { std::istream& stream_; std::streamsize size_; chunk_device(std::istream& is, std::streamsize sz) : stream_(is), size_(sz) {} std::streamsize read(char* s, std::streamsize n) { if (size_ == 0) { return -1; } n = std::min(n, size_); std::streamsize result = stream_.read(s, n).gcount(); size_ -= result; return result; } }; Thanks Olaf
participants (2)
-
Nat Goodspeed
-
Olaf Krzikalla