Skip to content

Commit f6c7580

Browse files
Internal change
PiperOrigin-RevId: 839339175
1 parent 0f79fec commit f6c7580

File tree

2 files changed

+187
-4
lines changed

2 files changed

+187
-4
lines changed

src/google/protobuf/io/gzip_stream.cc

Lines changed: 167 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
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
}
5168
GzipInputStream::~GzipInputStream() {
5269
internal::SizedDelete(output_buffer_, output_buffer_length_);
5370
zerror_ = inflateEnd(&zcontext_);
71+
#else
72+
zerror_ = inflateEnd(zcontext_);
73+
delete zcontext_;
5474
}
5575

5676
static 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

102149
void 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

178269
GzipOutputStream::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

224332
GzipOutputStream::~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
}
280433
void 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
}
284440
int64_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+
288447
bool 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

296459
bool 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;

src/google/protobuf/io/gzip_stream.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,18 @@
2424
#include "google/protobuf/io/zero_copy_stream.h"
2525
#include "google/protobuf/port.h"
2626
#include <zlib.h>
27+
// Externally we always want to include <zlib.h>, but internally we only want to
28+
// do that for Android builds, where we get zlib for free as a shared library.
29+
// Otherwise we have to get zlib from //third_party/zlib. For this
30+
// reason during the migration the rust version of zlib, some classes are
31+
// defined in the .cc file. others checks on PROTO2_OPENSOURCE were set in this
32+
// file to implement this forward declarations only for the internal version.
33+
// TODO - b/477521589: Remove this comment after the migration is complete.
2734

2835
// Must be included last.
2936
#include "google/protobuf/port_def.inc"
3037

38+
3139
namespace google {
3240
namespace protobuf {
3341
namespace io {
@@ -60,6 +68,9 @@ class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED PROTOBUF_EXPORT
6068
const {
6169
return zcontext_.msg;
6270
}
71+
#else
72+
PROTOBUF_FUTURE_ADD_EARLY_NODISCARD const char* ZlibErrorMessage() const;
73+
6374
PROTOBUF_FUTURE_ADD_EARLY_NODISCARD inline int ZlibErrorCode() const {
6475
return zerror_;
6576
}
@@ -76,7 +87,9 @@ class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED PROTOBUF_EXPORT
7687

7788
ZeroCopyInputStream* sub_stream_;
7889

79-
z_stream zcontext_;
90+
z_stream_s zcontext_;
91+
#else
92+
struct z_stream_s* zcontext_;
8093
int zerror_;
8194

8295
void* output_buffer_;
@@ -134,6 +147,9 @@ class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED PROTOBUF_EXPORT
134147
const {
135148
return zcontext_.msg;
136149
}
150+
#else
151+
PROTOBUF_FUTURE_ADD_EARLY_NODISCARD const char* ZlibErrorMessage() const;
152+
137153
PROTOBUF_FUTURE_ADD_EARLY_NODISCARD inline int ZlibErrorCode() const {
138154
return zerror_;
139155
}
@@ -170,7 +186,9 @@ class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED PROTOBUF_EXPORT
170186
void* sub_data_;
171187
int sub_data_size_;
172188

173-
z_stream zcontext_;
189+
z_stream_s zcontext_;
190+
#else
191+
struct z_stream_s* zcontext_;
174192
int zerror_;
175193
void* input_buffer_;
176194
size_t input_buffer_length_;

0 commit comments

Comments
 (0)