summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorljfa <ljfa-ag@web.de>2015-09-21 18:10:03 +0200
committerljfa <ljfa-ag@web.de>2015-09-21 18:10:03 +0200
commit8773152a57a4e1524be66c7d6777c48de246040f (patch)
tree4820f57edbe07859737624b8dfcdbf91309a8687
parent57136429177ed86e2152154d4ecc229d3afe6d94 (diff)
downloadProject-Tick-8773152a57a4e1524be66c7d6777c48de246040f.tar.gz
Project-Tick-8773152a57a4e1524be66c7d6777c48de246040f.zip
Make the inflate_streambuf rewind the input
-rw-r--r--include/io/izlibstream.h5
-rw-r--r--src/io/izlibstream.cpp8
-rw-r--r--test/testfiles/trailing_data.zlibbin0 -> 20 bytes
-rw-r--r--test/zlibstream_test.h21
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
new file mode 100644
index 0000000000..83848f3024
--- /dev/null
+++ b/test/testfiles/trailing_data.zlib
Binary files differ
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