+++ /dev/null
-/*---------------------------------------------------------------------\
-| |
-| __ __ ____ _____ ____ |
-| \ \ / /_ _/ ___|_ _|___ \ |
-| \ V / _` \___ \ | | __) | |
-| | | (_| |___) || | / __/ |
-| |_|\__,_|____/ |_| |_____| |
-| |
-| core system |
-| (C) SuSE Linux Products GmbH |
-\----------------------------------------------------------------------/
-
- File: gzstream.cc
-
- Author: Michael Andres <ma@suse.de>
- Maintainer: Michael Andres <ma@suse.de>
-
- Purpose: Streams reading and writing gzip files.
-
-/-*/
-
-#include "y2util/gzstream.h"
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ZlibError
-//
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : ZlibError::strerror
-// METHOD TYPE : std::string
-//
-std::string
-ZlibError::strerror() const
-{
- std::string ret = ( _zError ? ::zError( _zError ) : "OK" );
- if ( _zError == Z_ERRNO )
- ret += std::string("(") + ::strerror( _errno ) + ")";
- return ret;
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : fgzstreambuf
-//
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : fgzstreambuf::open
-// METHOD TYPE : fgzstreambuf *
-//
-fgzstreambuf *
-fgzstreambuf::open( const char * name_r, std::ios_base::openmode mode_r )
-{
- fgzstreambuf * ret = NULL;
- if ( ! isOpen() )
- {
- if ( mode_r == std::ios_base::in )
- _file = gzopen( name_r, "rb" );
- else if ( mode_r == std::ios_base::out )
- _file = gzopen( name_r, "wb" );
- // else: not supported
-
- if ( isOpen() )
- {
- // Store mode and initialize the internal buffer.
- _mode = mode_r;
- if ( inReadMode() )
- {
- setp( NULL, NULL );
- setg( &(_buffer[0]), &(_buffer[0]), &(_buffer[0]) );
- }
- else
- {
- setp( &(_buffer[0]), &(_buffer[_buffer.size()-1]) );
- setg( NULL, NULL, NULL );
- }
- ret = this;
- }
- else
- setZError();
- }
- return ret;
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : fgzstreambuf::close
-// METHOD TYPE : fgzstreambuf *
-//
-fgzstreambuf *
-fgzstreambuf::close()
-{
- fgzstreambuf * ret = NULL;
- if ( isOpen() )
- {
- bool failed = false;
- if ( sync() != 0 )
- failed = true;
- if ( gzclose( _file ) != Z_OK )
- {
- failed = true;
- setZError();
- }
-
- // Reset everything
- _file = NULL;
- _mode = std::ios_base::openmode(0);
- setp( NULL, NULL );
- setg( NULL, NULL, NULL );
- if ( ! failed )
- ret = this;
- }
- return ret;
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : fgzstreambuf::sync
-// METHOD TYPE : int
-//
-int
-fgzstreambuf::sync()
-{
- int ret = 0;
- if ( pbase() < pptr() ) {
- const int_type res = overflow();
- if ( traits_type::eq_int_type( res, traits_type::eof() ) )
- ret = -1;
- }
- return ret;
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : fgzstreambuf::overflow
-// METHOD TYPE : fgzstreambuf::int_type
-//
-fgzstreambuf::int_type
-fgzstreambuf::overflow( int_type c )
-{
- int_type ret = traits_type::eof();
- if ( inWriteMode() )
- {
- if ( ! traits_type::eq_int_type( c, traits_type::eof() ) )
- {
- *pptr() = traits_type::to_char_type( c );
- pbump(1);
- }
- if ( pbase() <= pptr() )
- {
- if ( zWriteFrom( pbase(), pptr() - pbase() ) )
- {
- setp( &(_buffer[0]), &(_buffer[_buffer.size()-1]) );
- ret = traits_type::not_eof( c );
- }
- // else: error writing the file
- }
- }
- return ret;
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : fgzstreambuf::underflow
-// METHOD TYPE : fgzstreambuf::int_type
-//
-fgzstreambuf::int_type
-fgzstreambuf::underflow()
-{
- int_type ret = traits_type::eof();
- if ( inReadMode() )
- {
- if ( gptr() < egptr() )
- return traits_type::to_int_type( *gptr() );
-
- const std::streamsize got = zReadTo( &(_buffer[0]), _buffer.size() );
- if ( got > 0 )
- {
- setg( &(_buffer[0]), &(_buffer[0]), &(_buffer[got]) );
- ret = traits_type::to_int_type( *gptr() );
- }
- else if ( got == 0 )
- {
- // EOF
- setg( &(_buffer[0]), &(_buffer[0]), &(_buffer[0]) );
- }
- // else: error reading the file
- }
- return ret;
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : fgzstreambuf::zReadTo
-// METHOD TYPE : std::streamsize
-//
-std::streamsize
-fgzstreambuf::zReadTo( char * buffer_r, std::streamsize maxcount_r )
-{
- int read = gzread( _file, buffer_r, maxcount_r );
- if ( read < 0 )
- setZError();
- return read;
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : fgzstreambuf::zWriteFrom
-// METHOD TYPE : bool
-//
-bool
-fgzstreambuf::zWriteFrom( const char * buffer_r, std::streamsize count_r )
-{
- int written = 0;
- if ( count_r )
- {
- if ( (written = gzwrite( _file, buffer_r, count_r )) == 0 )
- setZError();
- }
- return( written == count_r );
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : fgzstreambuf::zSeekTo
-// METHOD TYPE : fgzstreambuf::pos_type
-//
-fgzstreambuf::pos_type
-fgzstreambuf::zSeekTo( off_type off_r, std::ios_base::seekdir way_r )
-{
- z_off_t ret = gzseek( _file, off_r, way_r );
- if ( ret == -1 )
- setZError();
- return ret;
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : fgzstreambuf::zTell
-// METHOD TYPE : fgzstreambuf::pos_type
-//
-fgzstreambuf::pos_type
-fgzstreambuf::zTell()
-{
- z_off_t ret = gztell( _file );
- if ( ret == -1 )
- setZError();
- return ret;
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : fgzstreambuf::seekTo
-// METHOD TYPE : fgzstreambuf::pos_type
-//
-fgzstreambuf::pos_type
-fgzstreambuf::seekTo( off_type off_r, std::ios_base::seekdir way_r )
-{
- pos_type ret = pos_type(off_type(-1));
- if ( isOpen() )
- {
- if ( inWriteMode() )
- {
- if ( sync() == 0 )
- ret = zSeekTo( off_r, way_r );
- }
- else
- {
- off_type zegptr = zTell();
- if ( zegptr != off_type(-1) )
- {
- if ( way_r == std::ios_base::end )
- {
- // Invalidate buffer and seek.
- // XXX improve by transformation into ios_base::beg
- // to see whether we stay inside the buffer.
- setg( &(_buffer[0]), &(_buffer[0]), &(_buffer[0]) );
- ret = zSeekTo( off_r, way_r );
- }
- else
- {
- // Transform into ios_base::beg and seek.
- off_type zeback = zegptr - ( egptr() - eback() );
- off_type zgptr = zegptr - ( egptr() - gptr() );
- off_type zngptr = off_r;
- if ( way_r == std::ios_base::cur )
- {
- zngptr += zgptr;
- way_r = std::ios_base::beg;
- }
-
- if ( way_r == std::ios_base::beg )
- {
- if ( zeback <= zngptr && zngptr <= zegptr )
- {
- // Still inside buffer, adjust gptr and
- // calculate new position.
- setg( eback(),
- eback() + (zngptr-zeback),
- egptr() );
- ret = pos_type(zngptr);
- }
- else
- {
- // Invalidate buffer and seek.
- setg( &(_buffer[0]), &(_buffer[0]), &(_buffer[0]) );
- ret = zSeekTo( off_r, way_r );
- }
- }
- }
- }
- }
- }
- return ret;
-}
+++ /dev/null
-/*---------------------------------------------------------------------\
-| |
-| __ __ ____ _____ ____ |
-| \ \ / /_ _/ ___|_ _|___ \ |
-| \ V / _` \___ \ | | __) | |
-| | | (_| |___) || | / __/ |
-| |_|\__,_|____/ |_| |_____| |
-| |
-| core system |
-| (C) SuSE Linux Products GmbH |
-\----------------------------------------------------------------------/
-
- 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
-
-#include <iostream>
-#include <vector>
-#include <zlib.h>
-
-///////////////////////////////////////////////////////////////////
-//
-// 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;
-};
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// 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();
-
- /**
- * The last error returned retuned fron zlib.
- **/
- ZlibError
- zError() const
- { return _error; }
-
- protected:
-
- virtual int
- sync();
-
- virtual int_type
- overflow( int_type c = traits_type::eof() );
-
- virtual int_type
- underflow();
-
- 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 ); }
-
- virtual pos_type
- seekpos( pos_type pos_r, std::ios_base::openmode /* ignored */ )
- { return seekTo( off_type(pos_r), std::ios_base::beg ); }
-
- private:
-
- typedef std::vector<char> buffer_type;
-
- gzFile _file;
-
- std::ios_base::openmode _mode;
-
- buffer_type _buffer;
-
- ZlibError _error;
-
- private:
-
- void
- setZError()
- { gzerror( _file, &_error._zError ); }
-
- std::streamsize
- zReadTo( char * buffer_r, std::streamsize maxcount_r );
-
- bool
- zWriteFrom( const char * buffer_r, std::streamsize count_r );
-
- pos_type
- zSeekTo( off_type off_r, std::ios_base::seekdir way_r );
-
- pos_type
- zTell();
-
- pos_type
- seekTo( off_type off_r, std::ios_base::seekdir way_r );
-};
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// 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);
- }
-
- /**
- * The last error returned retuned fron zlib.
- **/
- ZlibError
- zError() const
- { return _streambuf.zError(); }
-
-
- 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; }
-
-};
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-
-/**
- * istream reading gzip files as well as plain files.
- **/
-typedef fXstream<std::istream,fgzstreambuf> ifgzstream;
-
-/**
- * ostream writing gzip files.
- **/
-typedef fXstream<std::ostream,fgzstreambuf> ofgzstream;
-
-///////////////////////////////////////////////////////////////////
-
-#endif // gzstream_h