+ unify DLL export defines to namespace names
git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5000 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d
This commit is contained in:
179
src/zipios++/inflateinputstreambuf.cpp
Normal file
179
src/zipios++/inflateinputstreambuf.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
|
||||
#include "zipios-config.h"
|
||||
|
||||
#include "meta-iostreams.h"
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#include "fcollexceptions.h"
|
||||
#include "inflateinputstreambuf.h"
|
||||
|
||||
#include "outputstringstream.h"
|
||||
|
||||
namespace zipios {
|
||||
|
||||
using std::cerr ;
|
||||
using std::endl ;
|
||||
|
||||
InflateInputStreambuf::InflateInputStreambuf( streambuf *inbuf, int s_pos, bool del_inbuf )
|
||||
: FilterInputStreambuf( inbuf, del_inbuf ),
|
||||
_zs_initialized ( false ),
|
||||
_invecsize ( 1000 ),
|
||||
_invec ( _invecsize ),
|
||||
_outvecsize ( 1000 ),
|
||||
_outvec ( _outvecsize )
|
||||
{
|
||||
// NOTICE: It is important that this constructor and the methods it
|
||||
// calls doesn't do anything with the input streambuf _inbuf, other
|
||||
// than repositioning it to the specified position. The reason is
|
||||
// that this class can be subclassed, and the subclass should get a
|
||||
// chance to read from the buffer first)
|
||||
|
||||
// zlib init:
|
||||
_zs.zalloc = Z_NULL ;
|
||||
_zs.zfree = Z_NULL ;
|
||||
_zs.opaque = Z_NULL ;
|
||||
|
||||
reset( s_pos ) ;
|
||||
// We're not checking the return value of reset() and throwing
|
||||
// an exception in case of an error, because we cannot catch the exception
|
||||
// in the constructors of subclasses with all compilers.
|
||||
}
|
||||
|
||||
InflateInputStreambuf::~InflateInputStreambuf() {
|
||||
// Dealloc z_stream stuff
|
||||
int err = inflateEnd( &_zs ) ;
|
||||
if( err != Z_OK ) {
|
||||
cerr << "~inflatebuf: inflateEnd failed" ;
|
||||
#ifdef HAVE_ZERROR
|
||||
cerr << ": " << zError( err ) ;
|
||||
#endif
|
||||
cerr << endl ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int InflateInputStreambuf::underflow() {
|
||||
// If not underflow don't fill buffer
|
||||
if ( gptr() < egptr() )
|
||||
return static_cast< unsigned char >( *gptr() ) ;
|
||||
|
||||
// Prepare _outvec and get array pointers
|
||||
_zs.avail_out = _outvecsize ;
|
||||
_zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
|
||||
|
||||
// Inflate until _outvec is full
|
||||
// eof (or I/O prob) on _inbuf will break out of loop too.
|
||||
int err = Z_OK ;
|
||||
while ( _zs.avail_out > 0 && err == Z_OK ) {
|
||||
if ( _zs.avail_in == 0 ) { // fill _invec
|
||||
int bc = _inbuf->sgetn( &(_invec[ 0 ] ) ,
|
||||
_invecsize ) ;
|
||||
// FIXME: handle i/o problems.
|
||||
_zs.next_in = reinterpret_cast< unsigned char * >( &( _invec[0] ) ) ;
|
||||
_zs.avail_in = bc ;
|
||||
// If we could not read any new data (bc == 0) and inflate isn't
|
||||
// done it will return Z_BUF_ERROR and thus breaks out of the
|
||||
// loop. This means we don't have to respond to the situation
|
||||
// where we can't read more bytes here.
|
||||
}
|
||||
|
||||
err = inflate( &_zs, Z_NO_FLUSH ) ;
|
||||
}
|
||||
// Normally the number of inflated bytes will be the
|
||||
// full length of the output buffer, but if we can't read
|
||||
// more input from the _inbuf streambuf, we end up with
|
||||
// less.
|
||||
int inflated_bytes = _outvecsize - _zs.avail_out ;
|
||||
setg( &( _outvec[ 0 ] ),
|
||||
&( _outvec[ 0 ] ),
|
||||
&( _outvec[ 0 ] ) + inflated_bytes ) ;
|
||||
// FIXME: look at the error returned from inflate here, if there is
|
||||
// some way to report it to the InflateInputStreambuf user.
|
||||
// Until I find out I'll just print a warning to stdout.
|
||||
if( err != Z_OK && err != Z_STREAM_END ) {
|
||||
#if defined (HAVE_STD_IOSTREAM) && defined (USE_STD_IOSTREAM)
|
||||
// Throw an exception to make istream set badbit
|
||||
OutputStringStream msgs ;
|
||||
msgs << "InflateInputStreambuf: inflate failed" ;
|
||||
#ifdef HAVE_ZERROR
|
||||
msgs << ": " << zError( err ) ;
|
||||
#endif
|
||||
throw IOException( msgs.str() ) ;
|
||||
#endif
|
||||
// If HAVE_STD_IOSTREAM not defined we just return eof
|
||||
// if no output is produced, and that happens anyway
|
||||
}
|
||||
if (inflated_bytes > 0 )
|
||||
return static_cast< unsigned char >( *gptr() ) ;
|
||||
else
|
||||
return EOF ; // traits_type::eof() ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// This method is called in the constructor, so it must not
|
||||
// read anything from the input streambuf _inbuf (see notice in constructor)
|
||||
bool InflateInputStreambuf::reset( int stream_position ) {
|
||||
if ( stream_position >= 0 ) { // reposition _inbuf
|
||||
_inbuf->pubseekpos( stream_position ) ;
|
||||
}
|
||||
|
||||
// _zs.next_in and avail_in must be set according to
|
||||
// zlib.h (inline doc).
|
||||
_zs.next_in = reinterpret_cast< unsigned char * >( &( _invec[0] ) ) ;
|
||||
_zs.avail_in = 0 ;
|
||||
|
||||
int err ;
|
||||
if( _zs_initialized ) { // just reset it
|
||||
err = inflateReset( &_zs ) ;
|
||||
} else { // init it
|
||||
err = inflateInit2( &_zs, -MAX_WBITS ) ;
|
||||
/* windowBits is passed < 0 to tell that there is no zlib header.
|
||||
Note that in this case inflate *requires* an extra "dummy" byte
|
||||
after the compressed stream in order to complete decompression
|
||||
and return Z_STREAM_END. We always have an extra "dummy" byte,
|
||||
because there is always some trailing data after the compressed
|
||||
data (either the next entry or the central directory. */
|
||||
_zs_initialized = true ;
|
||||
}
|
||||
|
||||
// streambuf init:
|
||||
// The important thing here, is that
|
||||
// - the pointers are not NULL (which would mean unbuffered)
|
||||
// - and that gptr() is not less than egptr() (so we trigger underflow
|
||||
// the first time data is read).
|
||||
setg( &( _outvec[ 0 ] ),
|
||||
&( _outvec[ 0 ] ) + _outvecsize,
|
||||
&( _outvec[ 0 ] ) + _outvecsize ) ;
|
||||
|
||||
if ( err == Z_OK )
|
||||
return true ;
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/** \file
|
||||
Implementation of InflateInputStreambuf.
|
||||
*/
|
||||
|
||||
/*
|
||||
Zipios++ - a small C++ library that provides easy access to .zip files.
|
||||
Copyright (C) 2000 Thomas Søndergaard
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
Reference in New Issue
Block a user