Browse Source

Allow seeking a ZStream back to 0 (but no other location)

rdb 9 years ago
parent
commit
6f8fd916f3
2 changed files with 56 additions and 0 deletions
  1. 53 0
      panda/src/express/zStreamBuf.cxx
  2. 3 0
      panda/src/express/zStreamBuf.h

+ 53 - 0
panda/src/express/zStreamBuf.cxx

@@ -170,6 +170,59 @@ close_write() {
   }
 }
 
+/**
+ * Implements seeking within the stream.  ZStreamBuf only allows seeking back
+ * to the beginning of the stream.
+ */
+streampos ZStreamBuf::
+seekoff(streamoff off, ios_seekdir dir, ios_openmode which) {
+  // Necessary for tellg() to work after seeking to 0.
+  if (dir == ios::cur && off == 0) {
+    if (_source->tellg() == 0) {
+      return 0;
+    } else {
+      return -1;
+    }
+  }
+
+  if (off != 0 || dir != ios::beg) {
+    // We only know how to reposition to the beginning.
+    return -1;
+  }
+
+  if (which != ios::in) {
+    // We can only do this with the input stream.
+    return -1;
+  }
+
+  size_t n = egptr() - gptr();
+  gbump(n);
+
+  _source->seekg(0, ios::beg);
+  if (_source->tellg() == 0) {
+    _z_source.next_in = Z_NULL;
+    _z_source.avail_in = 0;
+    _z_source.next_out = Z_NULL;
+    _z_source.avail_out = 0;
+    int result = inflateReset(&_z_source);
+    if (result < 0) {
+      show_zlib_error("inflateReset", result, _z_source);
+    }
+    return 0;
+  }
+
+  return -1;
+}
+
+/**
+ * Implements seeking within the stream.  ZStreamBuf only allows seeking back
+ * to the beginning of the stream.
+ */
+streampos ZStreamBuf::
+seekpos(streampos pos, ios_openmode which) {
+  return seekoff(pos, ios::beg, which);
+}
+
 /**
  * Called by the system ostream implementation when its internal buffer is
  * filled, plus one character.

+ 3 - 0
panda/src/express/zStreamBuf.h

@@ -35,6 +35,9 @@ public:
   void open_write(ostream *dest, bool owns_dest, int compression_level);
   void close_write();
 
+  virtual streampos seekoff(streamoff off, ios_seekdir dir, ios_openmode which);
+  virtual streampos seekpos(streampos pos, ios_openmode which);
+
 protected:
   virtual int overflow(int c);
   virtual int sync();