diff options
| -rw-r--r-- | include/io/izlibstream.h | 5 | ||||
| -rw-r--r-- | src/io/izlibstream.cpp | 8 | ||||
| -rw-r--r-- | test/testfiles/trailing_data.zlib | bin | 0 -> 20 bytes | |||
| -rw-r--r-- | test/zlibstream_test.h | 21 |
4 files changed, 33 insertions, 1 deletions
diff --git a/include/io/izlibstream.h b/include/io/izlibstream.h index d3c4faa14e..4c6d5def85 100644 --- a/include/io/izlibstream.h +++ b/include/io/izlibstream.h @@ -64,6 +64,11 @@ private: * This istream wraps another istream. The izlibstream will read compressed * data from the wrapped istream and inflate (decompress) it with zlib. * + * @note If you want to read more data from the wrapped istream after the end + * of the compressed data, then it must allow seeking. It is unavoidable for + * the izlibstream to consume more data after the compressed data. + * It will automatically attempt to seek the wrapped istream back to the point + * after the end of the compressed data. * @sa inflate_streambuf */ class izlibstream : public std::istream diff --git a/src/io/izlibstream.cpp b/src/io/izlibstream.cpp index 85e04a189a..0a7512469e 100644 --- a/src/io/izlibstream.cpp +++ b/src/io/izlibstream.cpp @@ -78,7 +78,13 @@ inflate_streambuf::int_type inflate_streambuf::underflow() throw std::bad_alloc(); case Z_STREAM_END: - stream_end = true; + if(!stream_end) + { + stream_end = true; + //In case we consumed too much, we have to rewind the input stream + is.clear(); + is.seekg(-static_cast<std::streamoff>(zstr.avail_in), std::ios_base::cur); + } if(have == 0) return traits_type::eof(); break; diff --git a/test/testfiles/trailing_data.zlib b/test/testfiles/trailing_data.zlib Binary files differnew file mode 100644 index 0000000000..83848f3024 --- /dev/null +++ b/test/testfiles/trailing_data.zlib diff --git a/test/zlibstream_test.h b/test/zlibstream_test.h index f8308cf7c5..e76745f80f 100644 --- a/test/zlibstream_test.h +++ b/test/zlibstream_test.h @@ -133,6 +133,27 @@ public: } } + void test_inflate_trailing() + { + //This file contains additional uncompressed data after the zlib-compressed data + std::ifstream file("trailing_data.zlib", std::ios::binary); + izlibstream izls(file, 32); + TS_ASSERT(file && izls); + + std::string str; + izls >> str; + TS_ASSERT(izls); + TS_ASSERT(izls.eof()); + TS_ASSERT_EQUALS(str, "foobar"); + + //Now read the uncompressed data + TS_ASSERT(file); + TS_ASSERT(!file.eof()); + file >> str; + TS_ASSERT(!file.bad()); + TS_ASSERT_EQUALS(str, "barbaz"); + } + void test_deflate_zlib() { //Here we assume that inflating works and has already been tested |
