Implemented fgzstreambuf::compressed_tell and fXstream::getbuf to
authorMartin Vidner <mvidner@suse.cz>
Thu, 7 Sep 2006 12:35:08 +0000 (12:35 +0000)
committerMartin Vidner <mvidner@suse.cz>
Thu, 7 Sep 2006 12:35:08 +0000 (12:35 +0000)
enable progress reporting on compressed streams.

ifgzstream gs;
...
gs.getbuf().compressed_tell()

package/libzypp.changes
zypp/base/GzStream.cc
zypp/base/GzStream.h

index dff4128..f8451bf 100644 (file)
@@ -1,4 +1,10 @@
 -------------------------------------------------------------------
+Thu Sep  7 14:32:38 CEST 2006 - mvidner@suse.cz
+
+- Implemented fgzstreambuf::compressed_tell and fXstream::getbuf to
+  enable progress reporting on compressed streams.
+
+-------------------------------------------------------------------
 Wed Sep  6 18:31:20 CEST 2006 - dmacvicar@suse.de
 
 - better error propagation
index ac378ca..97b77dc 100644 (file)
 
 #include "zypp/base/GzStream.h"
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
 ///////////////////////////////////////////////////////////////////
 namespace zypp
 { /////////////////////////////////////////////////////////////////
@@ -66,10 +70,17 @@ namespace zypp
       fgzstreambuf * ret = NULL;
       if ( ! isOpen() )
         {
+         // we expect gzdopen to handle errors of ::open
           if ( mode_r == std::ios_base::in )
-            _file = gzopen( name_r, "rb" );
+         {
+            _fd = ::open( name_r, O_RDONLY );
+            _file = gzdopen( _fd, "rb" );
+         }
           else if ( mode_r == std::ios_base::out )
-            _file = gzopen( name_r, "wb" );
+         {
+            _fd = ::open( name_r, O_WRONLY );
+            _file = gzdopen( _fd, "wb" );
+         }
           // else: not supported
 
           if ( isOpen() )
@@ -108,6 +119,7 @@ namespace zypp
           bool failed = false;
           if ( sync() != 0 )
             failed = true;
+         // it also closes _fd, fine
           if ( gzclose( _file ) != Z_OK )
             {
               failed = true;
@@ -115,6 +127,7 @@ namespace zypp
             }
 
           // Reset everything
+         _fd = -1;
           _file = NULL;
           _mode = std::ios_base::openmode(0);
           setp( NULL, NULL );
@@ -326,6 +339,14 @@ namespace zypp
       return ret;
     }
 
+    fgzstreambuf::pos_type
+    fgzstreambuf::compressed_tell() const
+    {
+       off_t pos = lseek (_fd, 0, SEEK_CUR);
+       // hopefully the conversion is ok
+       return pos;
+    }
+
     /////////////////////////////////////////////////////////////////
   } // namespace gzstream_detail
   ///////////////////////////////////////////////////////////////////
index 24b8c7a..6c03af1 100644 (file)
@@ -83,7 +83,8 @@ namespace zypp
     public:
 
       fgzstreambuf( unsigned bufferSize_r = 512 )
-      : _file( NULL )
+      : _fd( -1 )
+      ,_file( NULL )
       , _mode( std::ios_base::openmode(0) )
       , _buffer( (bufferSize_r?bufferSize_r:1), 0 )
       {}
@@ -110,6 +111,10 @@ namespace zypp
         fgzstreambuf *
         close();
 
+       //! Tell the file position in the compressed file.
+       //! Analogous to tell(2), complementary to gztell.
+       pos_type compressed_tell() const;
+
         /**
          * The last error returned fron zlib.
          **/
@@ -140,6 +145,9 @@ namespace zypp
 
       typedef std::vector<char> buffer_type;
 
+      //! file descriptor of the compressed file
+      int                     _fd;
+
       gzFile                   _file;
 
       std::ios_base::openmode  _mode;
@@ -231,6 +239,11 @@ namespace zypp
         zError() const
         { return _streambuf.zError(); }
 
+       //! Similar to ios::rdbuf.
+       //! But it returns our specific type, not the generic streambuf *.
+       const streambuf_type&
+        getbuf() const
+        { return _streambuf; }
 
       private: