1010// This file contains the implementation of classes GzipInputStream and
1111// GzipOutputStream.
1212
13+ #include < zlib.h>
14+ #define HAVE_ZLIB 1
1315
1416#if HAVE_ZLIB
1517#include " google/protobuf/io/gzip_stream.h"
@@ -37,6 +39,18 @@ GzipInputStream::GzipInputStream(ZeroCopyInputStream* sub_stream, Format format,
3739 zcontext_.avail_in = 0 ;
3840 zcontext_.total_in = 0 ;
3941 zcontext_.msg = nullptr ;
42+ #else
43+ zcontext_ = new z_stream;
44+ zcontext_->state = Z_NULL;
45+ zcontext_->zalloc = Z_NULL;
46+ zcontext_->zfree = Z_NULL;
47+ zcontext_->opaque = Z_NULL;
48+ zcontext_->total_out = 0 ;
49+ zcontext_->next_in = nullptr ;
50+ zcontext_->avail_in = 0 ;
51+ zcontext_->total_in = 0 ;
52+ zcontext_->msg = nullptr ;
53+
4054 if (buffer_size == -1 ) {
4155 output_buffer_length_ = kDefaultBufferSize ;
4256 } else {
@@ -46,11 +60,17 @@ GzipInputStream::GzipInputStream(ZeroCopyInputStream* sub_stream, Format format,
4660 ABSL_CHECK (output_buffer_ != nullptr );
4761 zcontext_.next_out = static_cast <Bytef*>(output_buffer_);
4862 zcontext_.avail_out = output_buffer_length_;
63+ #else
64+ zcontext_->next_out = static_cast <Bytef*>(output_buffer_);
65+ zcontext_->avail_out = output_buffer_length_;
4966 output_position_ = output_buffer_;
5067}
5168GzipInputStream::~GzipInputStream () {
5269 internal::SizedDelete (output_buffer_, output_buffer_length_);
5370 zerror_ = inflateEnd (&zcontext_);
71+ #else
72+ zerror_ = inflateEnd (zcontext_);
73+ delete zcontext_;
5474}
5575
5676static inline int internalInflateInit2 (z_stream* zcontext,
@@ -97,12 +117,42 @@ int GzipInputStream::Inflate(int flush) {
97117 output_position_ = output_buffer_;
98118 int error = inflate (&zcontext_, flush);
99119 return error;
120+ #else
121+ if ((zerror_ == Z_OK) && (zcontext_->avail_out == 0 )) {
122+ // previous inflate filled output buffer. don't change input params yet.
123+ } else if (zcontext_->avail_in == 0 ) {
124+ const void * in;
125+ int in_size;
126+ bool first = zcontext_->next_in == nullptr ;
127+ bool ok = sub_stream_->Next (&in, &in_size);
128+ if (!ok) {
129+ zcontext_->next_out = nullptr ;
130+ zcontext_->avail_out = 0 ;
131+ return Z_STREAM_END;
132+ }
133+ zcontext_->next_in = static_cast <Bytef*>(const_cast <void *>(in));
134+ zcontext_->avail_in = in_size;
135+ if (first) {
136+ int error = internalInflateInit2 (zcontext_, format_);
137+ if (error != Z_OK) {
138+ return error;
139+ }
140+ }
141+ }
142+ zcontext_->next_out = static_cast <Bytef*>(output_buffer_);
143+ zcontext_->avail_out = output_buffer_length_;
144+ output_position_ = output_buffer_;
145+ int error = inflate (zcontext_, flush);
146+ return error;
100147}
101148
102149void GzipInputStream::DoNextOutput (const void ** data, int * size) {
103150 *data = output_position_;
104151 *size = ((uintptr_t )zcontext_.next_out ) - ((uintptr_t )output_position_);
105152 output_position_ = zcontext_.next_out ;
153+ #else
154+ *size = ((uintptr_t )zcontext_->next_out ) - ((uintptr_t )output_position_);
155+ output_position_ = zcontext_->next_out ;
106156}
107157
108158// implements ZeroCopyInputStream ----------------------------------
@@ -139,6 +189,39 @@ bool GzipInputStream::Next(const void** data, int* size) {
139189 // The underlying stream's Next returned false inside Inflate.
140190 return false ;
141191 }
192+ #else
193+ bool ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) ||
194+ (zerror_ == Z_BUF_ERROR);
195+ if ((!ok) || (zcontext_->next_out == nullptr )) {
196+ return false ;
197+ }
198+ if (zcontext_->next_out != output_position_) {
199+ DoNextOutput (data, size);
200+ return true ;
201+ }
202+ if (zerror_ == Z_STREAM_END) {
203+ if (zcontext_->next_out != nullptr ) {
204+ // sub_stream_ may have concatenated streams to follow
205+ zerror_ = inflateEnd (zcontext_);
206+ byte_count_ += zcontext_->total_out ;
207+ if (zerror_ != Z_OK) {
208+ return false ;
209+ }
210+ zerror_ = internalInflateInit2 (zcontext_, format_);
211+ if (zerror_ != Z_OK) {
212+ return false ;
213+ }
214+ } else {
215+ *data = nullptr ;
216+ *size = 0 ;
217+ return false ;
218+ }
219+ }
220+ zerror_ = Inflate (Z_NO_FLUSH);
221+ if ((zerror_ == Z_STREAM_END) && (zcontext_->next_out == nullptr )) {
222+ // The underlying stream's Next returned false inside Inflate.
223+ return false ;
224+ }
142225 ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) ||
143226 (zerror_ == Z_BUF_ERROR);
144227 if (!ok) {
@@ -171,8 +254,16 @@ int64_t GzipInputStream::ByteCount() const {
171254 reinterpret_cast <uintptr_t >(output_position_);
172255 }
173256 return ret;
257+ #else
258+ int64_t ret = byte_count_ + zcontext_->total_out ;
259+ if (zcontext_->next_out != nullptr && output_position_ != nullptr ) {
260+ ret += reinterpret_cast <uintptr_t >(zcontext_->next_out ) -
261+ reinterpret_cast <uintptr_t >(output_position_);
262+ }
263+ return ret;
174264}
175265
266+
176267// =========================================================================
177268
178269GzipOutputStream::Options::Options ()
@@ -210,6 +301,18 @@ void GzipOutputStream::Init(ZeroCopyOutputStream* sub_stream,
210301 zcontext_.avail_in = 0 ;
211302 zcontext_.total_in = 0 ;
212303 zcontext_.msg = nullptr ;
304+ #else
305+ zcontext_ = new z_stream;
306+ zcontext_->zalloc = Z_NULL;
307+ zcontext_->zfree = Z_NULL;
308+ zcontext_->opaque = Z_NULL;
309+ zcontext_->next_out = nullptr ;
310+ zcontext_->avail_out = 0 ;
311+ zcontext_->total_out = 0 ;
312+ zcontext_->next_in = nullptr ;
313+ zcontext_->avail_in = 0 ;
314+ zcontext_->total_in = 0 ;
315+ zcontext_->msg = nullptr ;
213316 // default to GZIP format
214317 int windowBitsFormat = 16 ;
215318 if (options.format == ZLIB) {
@@ -219,6 +322,11 @@ void GzipOutputStream::Init(ZeroCopyOutputStream* sub_stream,
219322 deflateInit2 (&zcontext_, options.compression_level , Z_DEFLATED,
220323 /* windowBits */ 15 | windowBitsFormat,
221324 /* memLevel (default) */ 8 , options.compression_strategy );
325+ #else
326+ zerror_ =
327+ deflateInit2 (zcontext_, options.compression_level , Z_DEFLATED,
328+ /* windowBits */ 15 | windowBitsFormat,
329+ /* memLevel (default) */ 8 , options.compression_strategy );
222330}
223331
224332GzipOutputStream::~GzipOutputStream () {
@@ -252,6 +360,30 @@ int GzipOutputStream::Deflate(int flush) {
252360 sub_data_size_ = 0 ;
253361 }
254362 return error;
363+ #else
364+ int error = Z_OK;
365+ do {
366+ if ((sub_data_ == nullptr ) || (zcontext_->avail_out == 0 )) {
367+ bool ok = sub_stream_->Next (&sub_data_, &sub_data_size_);
368+ if (!ok) {
369+ sub_data_ = nullptr ;
370+ sub_data_size_ = 0 ;
371+ return Z_BUF_ERROR;
372+ }
373+ ABSL_CHECK_GT (sub_data_size_, 0 );
374+ zcontext_->next_out = static_cast <Bytef*>(sub_data_);
375+ zcontext_->avail_out = sub_data_size_;
376+ }
377+ error = deflate (zcontext_, flush);
378+ } while (error == Z_OK && zcontext_->avail_out == 0 );
379+ if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) {
380+ // Notify lower layer of data.
381+ sub_stream_->BackUp (zcontext_->avail_out );
382+ // We don't own the buffer anymore.
383+ sub_data_ = nullptr ;
384+ sub_data_size_ = 0 ;
385+ }
386+ return error;
255387}
256388
257389// implements ZeroCopyOutputStream ---------------------------------
@@ -276,21 +408,52 @@ bool GzipOutputStream::Next(void** data, int* size) {
276408 ABSL_DLOG (FATAL) << " Deflate left bytes unconsumed" ;
277409 }
278410 return true ;
411+ #else
412+ if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
413+ return false ;
414+ }
415+ if (zcontext_->avail_in != 0 ) {
416+ zerror_ = Deflate (Z_NO_FLUSH);
417+ if (zerror_ != Z_OK) {
418+ return false ;
419+ }
420+ }
421+ if (zcontext_->avail_in == 0 ) {
422+ // all input was consumed. reset the buffer.
423+ zcontext_->next_in = static_cast <Bytef*>(input_buffer_);
424+ zcontext_->avail_in = input_buffer_length_;
425+ *data = input_buffer_;
426+ *size = input_buffer_length_;
427+ } else {
428+ // The loop in Deflate should consume all avail_in
429+ ABSL_DLOG (FATAL) << " Deflate left bytes unconsumed" ;
430+ }
431+ return true ;
279432}
280433void GzipOutputStream::BackUp (int count) {
281434 ABSL_CHECK_GE (zcontext_.avail_in , static_cast <uInt>(count));
282435 zcontext_.avail_in -= count;
436+ #else
437+ ABSL_CHECK_GE (zcontext_->avail_in , static_cast <uInt>(count));
438+ zcontext_->avail_in -= count;
283439}
284440int64_t GzipOutputStream::ByteCount () const {
285441 return zcontext_.total_in + zcontext_.avail_in ;
442+ #else
443+ return zcontext_->total_in + zcontext_->avail_in ;
286444}
287445
446+
288447bool GzipOutputStream::Flush () {
289448 zerror_ = Deflate (Z_FULL_FLUSH);
290449 // Return true if the flush succeeded or if it was a no-op.
450+ return (zerror_ == Z_OK ||
451+ (zerror_ == Z_BUF_ERROR && zcontext_.avail_in == 0 &&
452+ zcontext_.avail_out != 0 );
453+ #else
291454 return (zerror_ == Z_OK) ||
292- (zerror_ == Z_BUF_ERROR && zcontext_. avail_in == 0 &&
293- zcontext_. avail_out != 0 );
455+ (zerror_ == Z_BUF_ERROR && zcontext_-> avail_in == 0 &&
456+ zcontext_-> avail_out != 0 );
294457}
295458
296459bool GzipOutputStream::Close () {
@@ -301,6 +464,8 @@ bool GzipOutputStream::Close() {
301464 zerror_ = Deflate (Z_FINISH);
302465 } while (zerror_ == Z_OK);
303466 zerror_ = deflateEnd (&zcontext_);
467+ #else
468+ zerror_ = deflateEnd (zcontext_);
304469 bool ok = zerror_ == Z_OK;
305470 zerror_ = Z_STREAM_END;
306471 return ok;
0 commit comments