The EOF logic wasn't quite correct
authorMikko Rasa <tdb@tdb.fi>
Fri, 3 Aug 2012 08:57:49 +0000 (11:57 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 3 Aug 2012 08:57:49 +0000 (11:57 +0300)
If the underlying object reported EOF after reading the last byte, then
ZlibCompressed would report EOF itself before giving out all data from
the buffers.

source/io/base.h
source/io/zlibcompressed.cpp
source/io/zlibcompressed.h

index 3d862169177f1711c6a9d3820e4fb3f97a6b94ca..394a2c2306e60ebbe9f8bb7ddee0e1d4f37b4403 100644 (file)
@@ -87,7 +87,9 @@ protected:
        void set_eof();
 
 public:
-       /** Returns the end-of-file flag. */
+       /** Returns the end-of-file flag.  Note that some types of objects won't
+       indicate end-of-file until you try to read at least one byte past the actual
+       end, while others indicate it when you've read the last byte. */
        bool eof() const { return eof_flag; }
 
        /** Returns the system-level handle for the object.  Used by Console to
index ea5e8030142f5fcfb90b72171b268ed1cdba3b7b..90b54a214bed69ce272952e3ebad8ca05e6ff1d4 100644 (file)
@@ -42,6 +42,7 @@ ZlibCompressed::ZlibCompressed(Base &b, unsigned level):
        buffer_size(1024),
        in_buffer(0),
        out_buffer(0),
+       stream_end(false),
        priv(0)
 {
 #ifdef WITH_ZLIB
@@ -219,7 +220,7 @@ unsigned ZlibCompressed::do_read(char *data, unsigned size)
                {
                        int ret = inflate(&priv->stream, Z_NO_FLUSH);
                        if(ret==Z_STREAM_END)
-                               set_eof();
+                               stream_end = true;
                        else if(ret!=Z_OK)
                                throw zlib_error("inflate", ret);
                        need_more_input = (priv->stream.next_out==out_buffer);
@@ -227,7 +228,7 @@ unsigned ZlibCompressed::do_read(char *data, unsigned size)
 
                if(need_more_input)
                {
-                       if(eof_flag)
+                       if(stream_end)
                                break;
 
                        if(priv->stream.next_in>in_buffer)
@@ -237,9 +238,12 @@ unsigned ZlibCompressed::do_read(char *data, unsigned size)
                        unsigned len = below.read(reinterpret_cast<char *>(priv->stream.next_in), in_buffer+buffer_size-priv->stream.next_in);
                        priv->stream.avail_in += len;
                        if(!len && below.eof())
-                               set_eof();
+                               stream_end = true;
                }
        }
+
+       if(size>0 && processed==0 && stream_end)
+               set_eof();
 #else
        (void)data;
        (void)size;
index 1ee427413ddc1cc448338278fab543f19bbd2ca9..feb21c635d406ea567708119fd2c9d467f697f0c 100644 (file)
@@ -36,6 +36,7 @@ private:
        unsigned buffer_size;
        unsigned char *in_buffer;
        unsigned char *out_buffer;
+       bool stream_end;
        Private *priv;
 
 public: