~ubuntu-branches/ubuntu/intrepid/enigma/intrepid

« back to all changes in this revision

Viewing changes to lib-src/zipios++/src/inflateinputstreambuf.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Erich Schubert
  • Date: 2005-08-28 15:30:09 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050828153009-sky64kb6tcq37xt5
Tags: 0.92.1-1
* New upstream subversion checkout
* Remove menu.s3m, which we are allowed to distributed but not to modify
  also copyright notice is confusing... (Closes: #321669)
* Rebuild with new libzipios (Closes: #325405)
  I hope this works without a versioned build-dependency
* Added "enigma replaces enigma-data" for upgrades (Closes: #308558)
* Added notes about the fonts copyright.
* updated to policy 3.6.2.1 (no changes)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
#include "zipios++/zipios-config.h"
3
 
 
4
 
#include "zipios++/meta-iostreams.h"
5
 
 
6
 
#include <zlib.h>
7
 
 
8
 
#include "zipios++/fcollexceptions.h"
9
 
#include "zipios++/inflateinputstreambuf.h"
10
 
 
11
 
#include "outputstringstream.h"
12
 
 
13
 
namespace zipios {
14
 
 
15
 
using std::cerr ;
16
 
using std::endl ;
17
 
 
18
 
InflateInputStreambuf::InflateInputStreambuf( streambuf *inbuf, int s_pos, bool del_inbuf ) 
19
 
  : FilterInputStreambuf( inbuf, del_inbuf ),
20
 
    _zs_initialized ( false            ),
21
 
    _invecsize      ( 1000             ),
22
 
    _invec          ( _invecsize       ),
23
 
    _outvecsize     ( 1000             ),
24
 
    _outvec         ( _outvecsize      )
25
 
{
26
 
  // NOTICE: It is important that this constructor and the methods it
27
 
  // calls doesn't do anything with the input streambuf _inbuf, other
28
 
  // than repositioning it to the specified position. The reason is
29
 
  // that this class can be subclassed, and the subclass should get a
30
 
  // chance to read from the buffer first)
31
 
 
32
 
  // zlib init:
33
 
  _zs.zalloc = Z_NULL ;
34
 
  _zs.zfree  = Z_NULL ;
35
 
  _zs.opaque = Z_NULL ;
36
 
 
37
 
  reset( s_pos ) ;
38
 
  // We're not checking the return value of reset() and throwing
39
 
  // an exception in case of an error, because we cannot catch the exception
40
 
  // in the constructors of subclasses with all compilers.
41
 
}
42
 
 
43
 
InflateInputStreambuf::~InflateInputStreambuf() {
44
 
  // Dealloc z_stream stuff
45
 
  int err = inflateEnd( &_zs ) ;
46
 
  if( err != Z_OK ) {
47
 
    cerr << "~inflatebuf: inflateEnd failed" ;
48
 
#ifdef HAVE_ZERROR
49
 
    cerr << ": " << zError( err ) ;
50
 
#endif
51
 
    cerr << endl ;
52
 
  }
53
 
}
54
 
 
55
 
 
56
 
int InflateInputStreambuf::underflow() {
57
 
  // If not underflow don't fill buffer
58
 
  if ( gptr() < egptr() )
59
 
    return static_cast< unsigned char >( *gptr() ) ;
60
 
 
61
 
  // Prepare _outvec and get array pointers
62
 
  _zs.avail_out = _outvecsize ; 
63
 
  _zs.next_out  = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
64
 
 
65
 
  // Inflate until _outvec is full
66
 
  // eof (or I/O prob) on _inbuf will break out of loop too.
67
 
  int err = Z_OK ;
68
 
  while ( _zs.avail_out > 0 && err == Z_OK ) {
69
 
    if ( _zs.avail_in == 0 ) { // fill _invec
70
 
      int bc = _inbuf->sgetn( &(_invec[ 0 ] ) , 
71
 
                              _invecsize ) ;
72
 
      // FIXME: handle i/o problems.
73
 
      _zs.next_in  = reinterpret_cast< unsigned char * >( &( _invec[0] ) ) ;
74
 
      _zs.avail_in = bc ;
75
 
      // If we could not read any new data (bc == 0) and inflate isn't
76
 
      // done it will return Z_BUF_ERROR and thus breaks out of the
77
 
      // loop. This means we don't have to respond to the situation
78
 
      // where we can't read more bytes here.
79
 
    }
80
 
 
81
 
    err = inflate( &_zs, Z_NO_FLUSH ) ;
82
 
  }
83
 
  // Normally the number of inflated bytes will be the
84
 
  // full length of the output buffer, but if we can't read
85
 
  // more input from the _inbuf streambuf, we end up with
86
 
  // less.
87
 
  int inflated_bytes = _outvecsize - _zs.avail_out ;
88
 
  setg( &( _outvec[ 0 ] ),
89
 
        &( _outvec[ 0 ] ),
90
 
        &( _outvec[ 0 ] ) + inflated_bytes ) ;
91
 
  // FIXME: look at the error returned from inflate here, if there is
92
 
  // some way to report it to the InflateInputStreambuf user.
93
 
  // Until I find out I'll just print a warning to stdout.
94
 
  if( err != Z_OK && err != Z_STREAM_END ) {
95
 
#if defined (HAVE_STD_IOSTREAM) && defined (USE_STD_IOSTREAM)
96
 
    // Throw an exception to make istream set badbit
97
 
    OutputStringStream msgs ;
98
 
    msgs << "InflateInputStreambuf: inflate failed" ;
99
 
#ifdef HAVE_ZERROR
100
 
    msgs << ": " << zError( err ) ;
101
 
#endif
102
 
    throw IOException( msgs.str() ) ;
103
 
#endif
104
 
    // If HAVE_STD_IOSTREAM not defined we just return eof
105
 
    // if no output is produced, and that happens anyway
106
 
  }
107
 
  if (inflated_bytes > 0 )
108
 
    return static_cast< unsigned char >( *gptr() ) ;
109
 
  else 
110
 
    return EOF ; // traits_type::eof() ;
111
 
}
112
 
 
113
 
 
114
 
 
115
 
// This method is called in the constructor, so it must not
116
 
// read anything from the input streambuf _inbuf (see notice in constructor)
117
 
bool InflateInputStreambuf::reset( int stream_position ) {
118
 
  if ( stream_position >= 0 ) { // reposition _inbuf
119
 
    _inbuf->pubseekpos( stream_position ) ;
120
 
  }
121
 
 
122
 
  // _zs.next_in and avail_in must be set according to
123
 
  // zlib.h (inline doc).
124
 
  _zs.next_in  = reinterpret_cast< unsigned char * >( &( _invec[0] ) ) ;
125
 
  _zs.avail_in = 0 ;
126
 
  
127
 
  int err ;
128
 
  if( _zs_initialized ) {                    // just reset it
129
 
    err = inflateReset( &_zs ) ;
130
 
  } else {                                   // init it
131
 
    err = inflateInit2( &_zs, -MAX_WBITS ) ;
132
 
    /* windowBits is passed < 0 to tell that there is no zlib header.
133
 
     Note that in this case inflate *requires* an extra "dummy" byte
134
 
     after the compressed stream in order to complete decompression
135
 
     and return Z_STREAM_END.  We always have an extra "dummy" byte,
136
 
     because there is always some trailing data after the compressed
137
 
     data (either the next entry or the central directory.  */
138
 
    _zs_initialized = true ;
139
 
  }
140
 
 
141
 
  // streambuf init:
142
 
  // The important thing here, is that 
143
 
  // - the pointers are not NULL (which would mean unbuffered)
144
 
  // - and that gptr() is not less than  egptr() (so we trigger underflow
145
 
  //   the first time data is read).
146
 
  setg( &( _outvec[ 0 ] ),
147
 
        &( _outvec[ 0 ] ) + _outvecsize,
148
 
        &( _outvec[ 0 ] ) + _outvecsize ) ;
149
 
 
150
 
  if ( err == Z_OK )
151
 
    return true ;
152
 
  else
153
 
    return false ;
154
 
}
155
 
 
156
 
} // namespace
157
 
 
158
 
/** \file
159
 
    Implementation of InflateInputStreambuf.
160
 
*/
161
 
 
162
 
/*
163
 
  Zipios++ - a small C++ library that provides easy access to .zip files.
164
 
  Copyright (C) 2000  Thomas S�ndergaard
165
 
  
166
 
  This library is free software; you can redistribute it and/or
167
 
  modify it under the terms of the GNU Lesser General Public
168
 
  License as published by the Free Software Foundation; either
169
 
  version 2 of the License, or (at your option) any later version.
170
 
  
171
 
  This library is distributed in the hope that it will be useful,
172
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
173
 
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
174
 
  Lesser General Public License for more details.
175
 
  
176
 
  You should have received a copy of the GNU Lesser General Public
177
 
  License along with this library; if not, write to the Free Software
178
 
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
179
 
*/