Imported Upstream version 15.19.0
[platform/upstream/libzypp.git] / zypp / base / GzStream.h
index 7aa4e10..6512008 100644 (file)
@@ -10,7 +10,7 @@
 |                                         (C) SuSE Linux Products GmbH |
 \----------------------------------------------------------------------/
 
-  File:       gzstream.h
+  File:       GzStream.h
 
   Author:     Michael Andres <ma@suse.de>
   Maintainer: Michael Andres <ma@suse.de>
   Purpose: Streams reading and writing gzip files.
 
 /-*/
-#ifndef gzstream_h
-#define gzstream_h
+#ifndef ZYPP_BASE_GZSTREAM_H
+#define ZYPP_BASE_GZSTREAM_H
 
-#include <iostream>
+#include <iosfwd>
+#include <streambuf>
 #include <vector>
 #include <zlib.h>
 
 ///////////////////////////////////////////////////////////////////
-//
-//     CLASS NAME : ZlibError
-/**
- * @short Helper class to ship zlib errors.
- **/
-struct ZlibError
-{
-  /**
-   * The zlib error code
-   **/
-  int _zError;
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
 
-  /**
-   * errno, valid if zError is Z_ERRNO
-   **/
-  int _errno;
+  ///////////////////////////////////////////////////////////////////
+  namespace gzstream_detail
+  { /////////////////////////////////////////////////////////////////
 
-  ZlibError()
-  : _zError( 0 ), _errno( 0 )
-  {}
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : ZlibError
+    /**
+     * @short Helper class to ship zlib errors.
+     **/
+    struct ZlibError
+    {
+      /**
+       * The zlib error code
+       **/
+      int _zError;
+
+      /**
+       * errno, valid if zError is Z_ERRNO
+       **/
+      int _errno;
+
+      ZlibError()
+      : _zError( 0 ), _errno( 0 )
+      {}
+
+      /**
+       * Return string describing the zlib error code
+       **/
+      std::string
+      strerror() const;
+    };
+    ///////////////////////////////////////////////////////////////////
+
+    /** \relates ZlibError Stream output. */
+    inline std::ostream & operator<<( std::ostream & str, const ZlibError & obj )
+    { return str << obj.strerror(); }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : fgzstreambuf
+    /**
+     * @short Streambuffer reading or writing gzip files.
+     *
+     * Read and write mode are mutual exclusive. Seek is supported,
+     * but zlib restrictions appy (only forward seek in write mode;
+     * backward seek in read mode might be expensive).Putback is not
+     * supported.
+     *
+     * Reading plain (no gziped) files is possible as well.
+     *
+     * This streambuf is used in @ref ifgzstream and  @ref ofgzstream.
+     **/
+    class fgzstreambuf : public std::streambuf {
 
-  /**
-   * Return string describing the zlib error code
-   **/
-  std::string
-  strerror() const;
-};
-///////////////////////////////////////////////////////////////////
+    public:
 
-///////////////////////////////////////////////////////////////////
-//
-//     CLASS NAME : fgzstreambuf
-/**
- * @short Streambuffer reading or writing gzip files.
- *
- * Read and write mode are mutual exclusive. Seek is supported,
- * but zlib restrictions appy (only forward seek in write mode;
- * backward seek in read mode might be expensive).Putback is not
- * supported.
- *
- * Reading plain (no gziped) files is possible as well.
- *
- * This streambuf is used in @ref ifgzstream and  @ref ofgzstream.
- **/
-class fgzstreambuf : public std::streambuf {
-
-  public:
-
-    fgzstreambuf( unsigned bufferSize_r = 512 )
-    : _file( NULL )
-    , _mode( std::ios_base::openmode(0) )
-    , _buffer( (bufferSize_r?bufferSize_r:1), 0 )
-    {}
-
-    virtual
-    ~fgzstreambuf()
-    { close(); }
-
-    bool
-    isOpen() const
-    { return _file; }
-
-    bool
-    inReadMode() const
-    { return( _mode == std::ios_base::in ); }
-
-    bool
-    inWriteMode() const
-    { return( _mode == std::ios_base::out ); }
-
-    fgzstreambuf *
-    open( const char * name_r, std::ios_base::openmode mode_r );
-
-    fgzstreambuf *
-    close();
+      fgzstreambuf( unsigned bufferSize_r = 512 )
+      : _fd( -1 )
+      ,_file( NULL )
+      , _mode( std::ios_base::openmode(0) )
+      , _buffer( (bufferSize_r?bufferSize_r:1), 0 )
+      {}
 
-    /**
-     * The last error returned retuned fron zlib.
-     **/
-    ZlibError
-    zError() const
-    { return _error; }
+      virtual
+      ~fgzstreambuf()
+      { close(); }
 
-  protected:
+      bool
+      isOpen() const
+      { return _file; }
 
-    virtual int
-    sync();
+      bool
+      inReadMode() const
+      { return( _mode == std::ios_base::in ); }
 
-    virtual int_type
-    overflow( int_type c = traits_type::eof() );
+      bool
+      inWriteMode() const
+      { return( _mode == std::ios_base::out ); }
 
-    virtual int_type
-    underflow();
+      fgzstreambuf *
+      open( const char * name_r, std::ios_base::openmode mode_r = std::ios_base::in );
 
-    virtual pos_type
-    seekoff( off_type off_r, std::ios_base::seekdir way_r, std::ios_base::openmode /* ignored */ )
-    { return seekTo( off_r, way_r ); }
+        fgzstreambuf *
+        close();
 
-    virtual pos_type
-    seekpos( pos_type pos_r, std::ios_base::openmode /* ignored */ )
-    { return seekTo( off_type(pos_r), std::ios_base::beg ); }
+       //! Tell the file position in the compressed file.
+       //! Analogous to tell(2), complementary to gztell.
+       pos_type compressed_tell() const;
 
-  private:
+        /**
+         * The last error returned fron zlib.
+         **/
+        ZlibError
+        zError() const
+        { return _error; }
 
-    typedef std::vector<char> buffer_type;
+    protected:
 
-    gzFile                   _file;
+      virtual int
+      sync();
 
-    std::ios_base::openmode  _mode;
+      virtual int_type
+      overflow( int_type c = traits_type::eof() );
 
-    buffer_type              _buffer;
+      virtual int_type
+      underflow();
 
-    ZlibError                _error;
+      virtual pos_type
+      seekoff( off_type off_r, std::ios_base::seekdir way_r, std::ios_base::openmode /* ignored */ )
+      { return seekTo( off_r, way_r ); }
 
-  private:
+      virtual pos_type
+      seekpos( pos_type pos_r, std::ios_base::openmode /* ignored */ )
+      { return seekTo( off_type(pos_r), std::ios_base::beg ); }
 
-    void
-    setZError()
-    { gzerror( _file, &_error._zError ); }
+    private:
 
-    std::streamsize
-    zReadTo( char * buffer_r, std::streamsize maxcount_r );
+      typedef std::vector<char> buffer_type;
 
-    bool
-    zWriteFrom( const char * buffer_r, std::streamsize count_r );
+      //! file descriptor of the compressed file
+      int                     _fd;
 
-    pos_type
-    zSeekTo( off_type off_r, std::ios_base::seekdir way_r );
+      gzFile                   _file;
 
-    pos_type
-    zTell();
+      std::ios_base::openmode  _mode;
 
-    pos_type
-    seekTo( off_type off_r, std::ios_base::seekdir way_r );
-};
-///////////////////////////////////////////////////////////////////
+      buffer_type              _buffer;
 
-///////////////////////////////////////////////////////////////////
-//
-//     CLASS NAME : fXstream<class _BStr,class _SBuf>
-/**
- * @short Common template to define ifgzstream/ofgzstream
- * reading/writing gzip files.
- *
- * Don't use fXstream directly, but @ref ifgzstream or
- * @ref ofgzstream. fXstream is just to aviod almost
- * duplicate code.
- **/
-template<class _BStream,class _StreamBuf>
-  class fXstream : public _BStream
-  {
-  public:
-
-    typedef _BStream               stream_type;
-    typedef _StreamBuf             streambuf_type;
-
-    fXstream()
-    : stream_type( NULL )
-    { this->init( &_streambuf ); }
-
-    explicit
-    fXstream( const char * file_r )
-    : stream_type( NULL )
-    { this->init( &_streambuf ); this->open( file_r ); }
-
-    virtual
-    ~fXstream()
-    {}
-
-    bool
-    is_open() const
-    { return _streambuf.isOpen(); }
-
-    void
-    open( const char * file_r )
-    {
-      if ( !_streambuf.open( file_r, defMode(*this) ) )
-        this->setstate(std::ios_base::failbit);
-      else
-        this->clear();
-    }
-
-    void
-    close()
-    {
-      if ( !_streambuf.close() )
-        this->setstate(std::ios_base::failbit);
-    }
+      ZlibError                _error;
 
-    /**
-     * The last error returned retuned fron zlib.
-     **/
-    ZlibError
-    zError() const
-    { return _streambuf.zError(); }
+    private:
 
+      void
+      setZError()
+      { gzerror( _file, &_error._zError ); }
 
-  private:
+      std::streamsize
+      zReadTo( char * buffer_r, std::streamsize maxcount_r );
 
-    streambuf_type _streambuf;
+      bool
+      zWriteFrom( const char * buffer_r, std::streamsize count_r );
 
-    std::ios_base::openmode
-    defMode( const std::istream & str_r )
-    { return std::ios_base::in; }
+      pos_type
+      zSeekTo( off_type off_r, std::ios_base::seekdir way_r );
 
-    std::ios_base::openmode
-    defMode( const std::ostream & str_r )
-    { return std::ios_base::out; }
+      pos_type
+      zTell();
 
-};
-///////////////////////////////////////////////////////////////////
+      pos_type
+      seekTo( off_type off_r, std::ios_base::seekdir way_r );
+    };
+    ///////////////////////////////////////////////////////////////////
 
-///////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : fXstream<class TBStr,class TSBuf>
+    /**
+     * @short Common template to define ifgzstream/ofgzstream
+     * reading/writing gzip files.
+     *
+     * Don't use fXstream directly, but @ref ifgzstream or
+     * @ref ofgzstream. fXstream is just to avoid almost
+     * duplicate code.
+     **/
+    template<class TBStream,class TStreamBuf>
+      class fXstream : public TBStream
+      {
+      public:
+
+        typedef gzstream_detail::ZlibError ZlibError;
+        typedef TBStream                   stream_type;
+        typedef TStreamBuf                 streambuf_type;
+
+        fXstream()
+        : stream_type( NULL )
+        { this->init( &_streambuf ); }
+
+        explicit
+        fXstream( const char * file_r )
+        : stream_type( NULL )
+        { this->init( &_streambuf ); this->open( file_r ); }
+
+        virtual
+        ~fXstream()
+        {}
+
+        bool
+        is_open() const
+        { return _streambuf.isOpen(); }
+
+        void
+        open( const char * file_r )
+        {
+          if ( !_streambuf.open( file_r, defMode(*this) ) )
+            this->setstate(std::ios_base::failbit);
+          else
+            this->clear();
+        }
+
+        void
+        close()
+        {
+          if ( !_streambuf.close() )
+            this->setstate(std::ios_base::failbit);
+        }
+
+        /**
+         * The last error returned retuned fron zlib.
+         **/
+        ZlibError
+        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:
+
+        streambuf_type _streambuf;
+
+        std::ios_base::openmode
+        defMode( const std::istream & str_r )
+        { return std::ios_base::in; }
+
+        std::ios_base::openmode
+        defMode( const std::ostream & str_r )
+        { return std::ios_base::out; }
+
+      };
+    ///////////////////////////////////////////////////////////////////
+
+    /////////////////////////////////////////////////////////////////
+  } // namespace gzstream_detail
+  ///////////////////////////////////////////////////////////////////
 
-/**
- * istream reading gzip files as well as plain files.
- **/
-typedef fXstream<std::istream,fgzstreambuf> ifgzstream;
+  /**
  * istream reading gzip files as well as plain files.
  **/
+  typedef gzstream_detail::fXstream<std::istream,gzstream_detail::fgzstreambuf> ifgzstream;
 
-/**
- * ostream writing gzip files.
- **/
-typedef fXstream<std::ostream,fgzstreambuf> ofgzstream;
+  /**
  * ostream writing gzip files.
  **/
+  typedef gzstream_detail::fXstream<std::ostream,gzstream_detail::fgzstreambuf> ofgzstream;
 
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
 ///////////////////////////////////////////////////////////////////
 
-#endif // gzstream_h
+#endif // ZYPP_BASE_GZSTREAM_H