FreeCAD

Форк
0
/
deflateoutputstreambuf.cpp 
223 строки · 5.9 Кб
1

2
#include "zipios-config.h"
3

4
#include "meta-iostreams.h"
5

6
#include <zlib.h>
7

8
#include "fcollexceptions.h"
9
#include "deflateoutputstreambuf.h"
10

11
#include "outputstringstream.h"
12

13
namespace zipios {
14

15
using std::cerr ;
16
using std::endl ;
17

18
DeflateOutputStreambuf::DeflateOutputStreambuf( streambuf *outbuf, bool user_init, 
19
						bool del_outbuf ) 
20
  : FilterOutputStreambuf( outbuf, del_outbuf ),
21
    _zs_initialized ( false            ),
22
    _invecsize      ( 1000             ),
23
    _invec          ( _invecsize       ),
24
    _outvecsize     ( 1000             ),
25
    _outvec         ( _outvecsize      )
26
{
27
  // NOTICE: It is important that this constructor and the methods it
28
  // calls doesn't do anything with the output streambuf _outbuf The
29
  // reason is that this class can be subclassed, and the subclass
30
  // should get a chance to write to the buffer first
31

32
  // zlib init:
33
  _zs.zalloc = Z_NULL ;
34
  _zs.zfree  = Z_NULL ;
35
  _zs.opaque = Z_NULL ;
36

37
  if ( user_init && ! init() )
38
    cerr << "DeflateOutputStreambuf::reset() failed!\n" ; // FIXME: throw something
39

40
}
41

42

43
DeflateOutputStreambuf::~DeflateOutputStreambuf() {
44
  closeStream() ;
45
}
46

47

48
// This method is called in the constructor, so it must not write
49
// anything to the output streambuf _outbuf (see notice in
50
// constructor)
51
bool DeflateOutputStreambuf::init( int comp_level ) {
52
  static const int default_mem_level = 8 ;
53

54
  // _zs.next_in and avail_in must be set according to
55
  // zlib.h (inline doc).
56
  _zs.next_in  = reinterpret_cast< unsigned char * >( &( _invec[ 0 ] ) ) ;
57
  _zs.avail_in = 0 ;
58

59
  _zs.next_out  = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
60
  _zs.avail_out = _outvecsize ;
61

62
  int err ;
63
  if( _zs_initialized ) {                    // just reset it
64
    endDeflation() ;
65
    err = deflateReset( &_zs ) ;
66
    // FIXME: bug, for deflateReset we do not update the compression level
67
  } else {                                   // init it
68
    err = deflateInit2( &_zs, comp_level, Z_DEFLATED, -MAX_WBITS, 
69
			default_mem_level, Z_DEFAULT_STRATEGY ) ;
70
    /* windowBits is passed < 0 to tell that no zlib header should be
71
       written. */
72
    _zs_initialized = true ;
73
  }
74

75
  // streambuf init:
76
  setp( &( _invec[ 0 ] ), &( _invec[ 0 ] ) + _invecsize ) ;
77

78
  _crc32 = crc32( 0, Z_NULL, 0 ) ;
79
  _overflown_bytes = 0 ;
80

81
  if ( err == Z_OK )
82
    return true ;
83
  else
84
    return false ;
85
}
86

87

88
bool DeflateOutputStreambuf::closeStream() {
89
  int err = Z_OK ;
90
  if( _zs_initialized ) {
91
    endDeflation() ;
92
    err = deflateEnd( &_zs ) ;
93
    _zs_initialized = false ;
94
  }
95
  
96
  if ( err == Z_OK )
97
    return true ;
98
  else {
99
    cerr << "DeflateOutputStreambuf::closeStream(): deflateEnd failed" ;
100
#ifdef HAVE_ZERROR
101
    cerr << ": " << zError( err ) ;
102
#endif
103
    cerr << endl ;
104
    return false ;
105
  }
106
}
107

108

109
int DeflateOutputStreambuf::overflow( int c ) {
110
  _zs.avail_in = pptr() - pbase() ;
111
  _zs.next_in = reinterpret_cast< unsigned char * >( &( _invec[ 0 ] ) ) ;
112

113
  _crc32 = crc32( _crc32, _zs.next_in, _zs.avail_in ) ; // update crc32
114
  _overflown_bytes += _zs.avail_in ;
115

116
  _zs.next_out  = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
117
  _zs.avail_out = _outvecsize ;
118

119
  // Deflate until _invec is empty.
120
  int err = Z_OK ;
121
  while ( ( _zs.avail_in > 0 || _zs.avail_out == 0 ) && err == Z_OK ) {
122
    if ( _zs.avail_out == 0 )
123
      flushOutvec() ;
124

125
    err = deflate( &_zs, Z_NO_FLUSH ) ;
126
  }
127

128
  flushOutvec() ;
129
  
130
  // Update 'put' pointers
131
  setp( &( _invec[ 0 ] ), &( _invec[ 0 ] ) + _invecsize ) ;
132
  
133
  if( err != Z_OK && err != Z_STREAM_END ) {
134
#if defined (HAVE_STD_IOSTREAM) && defined (USE_STD_IOSTREAM)
135
    // Throw an exception to make istream set badbit
136
    OutputStringStream msgs ;
137
    msgs << "Deflation failed" ;
138
#ifdef HAVE_ZERROR
139
    msgs << ": " << zError( err ) ;
140
#endif
141
    throw IOException( msgs.str() ) ;
142
#endif
143
    cerr << "Deflation failed\n" ;
144
    return EOF ;
145
  }
146

147
  if ( c != EOF ) {
148
    *pptr() = c ;
149
    pbump( 1 ) ;
150
  }
151

152
  return 0 ;
153
}
154

155
int DeflateOutputStreambuf::sync() {
156
  // FIXME: Do something
157
//    return overflow() ;
158
  return 0 ;
159
}
160

161

162
bool DeflateOutputStreambuf::flushOutvec() {
163
  int deflated_bytes = _outvecsize - _zs.avail_out ;
164
  int bc = _outbuf->sputn( &( _outvec[ 0 ] ), deflated_bytes ) ;
165

166
  _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
167
  _zs.avail_out = _outvecsize ;
168

169
  return deflated_bytes == bc ;
170
}
171

172

173
void DeflateOutputStreambuf::endDeflation() {
174
  overflow() ;
175

176
  _zs.next_out  = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ;
177
  _zs.avail_out = _outvecsize ;
178

179
  // Deflate until _invec is empty.
180
  int err = Z_OK ;
181

182
  while ( err == Z_OK ) {
183
    if ( _zs.avail_out == 0 )
184
      flushOutvec() ;
185

186
    err = deflate( &_zs, Z_FINISH ) ;
187
  }
188

189
  flushOutvec() ;
190

191
  if ( err != Z_STREAM_END ) {
192
    cerr << "DeflateOutputStreambuf::endDeflation(): deflation failed:\n" ;
193
#ifdef HAVE_ZERROR
194
    cerr << ": " << zError( err ) ;
195
#endif
196
    cerr << endl ;
197
  }
198
}
199

200

201
} // namespace
202

203
/** \file
204
    Implementation of DeflateOutputStreambuf.
205
*/
206

207
/*
208
  Zipios++ - a small C++ library that provides easy access to .zip files.
209
  Copyright (C) 2000  Thomas Søndergaard
210
  
211
  This library is free software; you can redistribute it and/or
212
  modify it under the terms of the GNU Lesser General Public
213
  License as published by the Free Software Foundation; either
214
  version 2 of the License, or (at your option) any later version.
215
  
216
  This library is distributed in the hope that it will be useful,
217
  but WITHOUT ANY WARRANTY; without even the implied warranty of
218
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
219
  Lesser General Public License for more details.
220
  
221
  You should have received a copy of the GNU Lesser General Public
222
  License along with this library; if not, write to the Free Software
223
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
224
*/
225

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.