Index: trunk/MagicSoft/Mars/mbase/MZlib.cc
===================================================================
--- trunk/MagicSoft/Mars/mbase/MZlib.cc	(revision 7442)
+++ trunk/MagicSoft/Mars/mbase/MZlib.cc	(revision 7449)
@@ -28,5 +28,5 @@
 // MZlib
 //
-// This is a C++ wrapper for zlib (taken from root)
+// This is a C++ wrapper for zlib.
 //
 // WARNING: - There might not be support for all features.
@@ -53,5 +53,5 @@
     }
 
-    fFile = gzopen(name, "rb0");
+    fFile = gzopen(name, "rb");
     if (fFile == 0)
     {
@@ -70,6 +70,4 @@
         return;
 
-    sync();
-
     if (gzclose(fFile) != Z_OK)
         clear(rdstate()|ios::badbit);
@@ -79,4 +77,23 @@
 
 // --------------------------------------------------------------------------
+//
+// Fill the buffer starting at the current file position and reset buffer
+// pointers by calling setg
+//
+int MZlib::fill_buffer(int putback)
+{
+    const int num = gzread(fFile, fBuffer+4, fgBufferSize-4);
+    if (num <= 0) // ERROR or EOF
+        return EOF;
+
+    // reset buffer pointers
+    setg(fBuffer+(4-putback), fBuffer+4, fBuffer+4+num);
+
+    return num;
+}
+
+// --------------------------------------------------------------------------
+//
+// Handle a buffer underflow (buffer went empty)
 //
 int MZlib::underflow()
@@ -88,15 +105,12 @@
         return EOF;
 
-    // implementation of inbuf
+    // gptr()-eback(): if more than four bytes are already flushed
     const int putback = gptr()-eback()>4 ? 4 : gptr()-eback();
 
+    // Copy the last four bytes flushed into the putback area
     memcpy(fBuffer+(4-putback), gptr()-putback, putback);
 
-    const int num = gzread(fFile, fBuffer+4, fgBufferSize-4);
-    if (num <= 0) // ERROR or EOF
+    if (fill_buffer(putback)==EOF)
         return EOF;
-
-    // reset buffer pointers
-    setg(fBuffer+(4-putback), fBuffer+4, fBuffer+4+num);
 
     // return next character
@@ -106,54 +120,64 @@
 // --------------------------------------------------------------------------
 //
-int MZlib::flush_buffer()
+streambuf::pos_type MZlib::seekoff(streambuf::off_type offset, ios_base::seekdir dir, ios_base::openmode)
 {
-    // Separate the writing of the buffer from overflow() and sync() operation.
-    const int w = pptr() - pbase();
+    // Using a switch instead results in:
+    //  In member function `virtual std::streampos MZlib::seekoff(long int, std::_Ios_Seekdir, std::_Ios_Openmode)':
+    //  warning: enumeration value `_M_ios_seekdir_end' not handled in switch
+    //  warning: case value `0' not in enumerated type `_Ios_Seekdir'
+    //  warning: case value `1' not in enumerated type `_Ios_Seekdir'
+    //  warning: case value `2' not in enumerated type `_Ios_Seekdir'
 
-    if (gzwrite(fFile, pbase(), w) != w)
-        return EOF;
+    if (dir==ios::cur)
+    {
+        // Position in z-stream
+        const z_off_t zpos = gztell(fFile); //gzseek(fFile, 0, SEEK_CUR);
 
-    pbump(-w);
+        // Calculate future position in streambuffer
+        const char *ptr = gptr()+offset;
 
-    return w;
-}
+        // Check if the new position will still be in the buffer
+        // In this case the target data was already decompressed.
+        if (ptr<eback() || ptr>=egptr())
+            return seekpos(zpos+ptr-egptr());
 
-/*
-int MZlib::overflow( int c)
-{
-    if ( ! ( mode & ios::out) || ! opened)
-        return EOF;
+        gbump(offset);
+        return zpos+offset;
 
-    if (c != EOF)
-    {
-        *pptr() = c;
-        pbump(1);
+        // zpos-blen: Position in z-stream coresponding to buffer position
+        // return seekpos(gztell(fFile)+gptr()-egptr()+offset);
+    }
 
-    }
-    if ( flush_buffer() == EOF)
-        return EOF;
+    if (dir==ios::beg)
+        return seekpos(offset);
 
-    return c;
-}
-*/
+    /*
+      // SEEK_END not supported by zlib
+      if (dir==ios::end)
+      {
+          // Position in z-stream
+          const z_off_t zpos = gzseek(fFile, offset, SEEK_END);
+          if (zpos<0)
+              return EOF;
+  
+          return fill_buffer()==EOF ? EOF : zpos;
+      }
+      */
+    return EOF;
 
-// --------------------------------------------------------------------------
-//
-int MZlib::sync()
-{
-    // Use flush_buffer() instead of overflow(EOF) to
-    // cause proper behavior with std::endl and flush()
-    if (pptr() && pptr()>pbase())
-    {
-        if (flush_buffer() == EOF)
-            return -1;
-    }
-    return 0;
 }
 
 // --------------------------------------------------------------------------
 //
-streambuf::pos_type MZlib::seekoff(streambuf::off_type offset, ios_base::seekdir dir, ios_base::openmode)
+streambuf::pos_type MZlib::seekpos(streambuf::pos_type pos, ios_base::openmode)
 {
-    return gzseek(fFile, offset, dir);
+    // Seek the z-stream to the given position
+    if (gzseek(fFile, pos, SEEK_SET)<0)
+        return EOF;
+
+    // Fill buffer
+    if (fill_buffer()==EOF)
+        return EOF;
+
+    return pos;
 }
Index: trunk/MagicSoft/Mars/mbase/MZlib.h
===================================================================
--- trunk/MagicSoft/Mars/mbase/MZlib.h	(revision 7442)
+++ trunk/MagicSoft/Mars/mbase/MZlib.h	(revision 7449)
@@ -13,4 +13,5 @@
 
 #include <iostream>  // base classes for MLog
+#include <fstream>
 
 class MZlib : public std::streambuf, virtual public std::istream, public TObject
@@ -22,19 +23,15 @@
     char   fBuffer[fgBufferSize]; // data buffer
 
-    int flush_buffer();
     int underflow();
-    int sync();
+    int fill_buffer(int putback=0);
 
 public:
     MZlib() : istream(this), fFile(0)
     {
-        setp(fBuffer,   fBuffer+fgBufferSize-1);
         setg(fBuffer+4, fBuffer+4, fBuffer+4);
     }
     MZlib(const char *name) : istream(this), fFile(0)
     {
-        setp(fBuffer,   fBuffer+fgBufferSize-1);
         setg(fBuffer+4, fBuffer+4, fBuffer+4);
-
         open(name);
     }
@@ -47,7 +44,7 @@
 
     std::streambuf::pos_type seekoff(std::streambuf::off_type, std::ios_base::seekdir,
-                                     std::ios_base::openmode = std::ios_base::in | std::ios_base::out);
-    //std::streambuf::pos_type seekpos(std::streambuf::pos_type,
-    //                                 std::ios_base::openmode = std::ios_base::in | std::ios_base::out);
+                                     std::ios_base::openmode = std::ios_base::in);
+    std::streambuf::pos_type seekpos(std::streambuf::pos_type,
+                                     std::ios_base::openmode = std::ios_base::in);
 
     ClassDef(MZlib, 0) // A C++ wrapper to istream zlib files
