aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/io/gzip_stream.cc
diff options
context:
space:
mode:
authorGravatar liujisi@google.com <liujisi@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2010-11-02 13:14:58 +0000
committerGravatar liujisi@google.com <liujisi@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2010-11-02 13:14:58 +0000
commit33165fe0d5c265c92f2a67fc2b437b567c24e294 (patch)
tree52def0850ddd2e976da238d1a437fbda79c96e44 /src/google/protobuf/io/gzip_stream.cc
parent80aa23df6c63750e8cdfdcf3996fbc37d63cac61 (diff)
Submit recent changes from internal branch. See CHANGES.txt for more details.
Diffstat (limited to 'src/google/protobuf/io/gzip_stream.cc')
-rw-r--r--src/google/protobuf/io/gzip_stream.cc41
1 files changed, 28 insertions, 13 deletions
diff --git a/src/google/protobuf/io/gzip_stream.cc b/src/google/protobuf/io/gzip_stream.cc
index 84d277f4..0f1ff872 100644
--- a/src/google/protobuf/io/gzip_stream.cc
+++ b/src/google/protobuf/io/gzip_stream.cc
@@ -73,6 +73,17 @@ GzipInputStream::~GzipInputStream() {
zerror_ = inflateEnd(&zcontext_);
}
+static inline int internalInflateInit2(
+ z_stream* zcontext, GzipInputStream::Format format) {
+ int windowBitsFormat = 0;
+ switch (format) {
+ case GzipInputStream::GZIP: windowBitsFormat = 16; break;
+ case GzipInputStream::AUTO: windowBitsFormat = 32; break;
+ case GzipInputStream::ZLIB: windowBitsFormat = 0; break;
+ }
+ return inflateInit2(zcontext, /* windowBits */15 | windowBitsFormat);
+}
+
int GzipInputStream::Inflate(int flush) {
if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) {
// previous inflate filled output buffer. don't change input params yet.
@@ -89,14 +100,7 @@ int GzipInputStream::Inflate(int flush) {
zcontext_.next_in = static_cast<Bytef*>(const_cast<void*>(in));
zcontext_.avail_in = in_size;
if (first) {
- int windowBitsFormat = 0;
- switch (format_) {
- case GZIP: windowBitsFormat = 16; break;
- case AUTO: windowBitsFormat = 32; break;
- case ZLIB: windowBitsFormat = 0; break;
- }
- int error = inflateInit2(&zcontext_,
- /* windowBits */15 | windowBitsFormat);
+ int error = internalInflateInit2(&zcontext_, format_);
if (error != Z_OK) {
return error;
}
@@ -127,9 +131,21 @@ bool GzipInputStream::Next(const void** data, int* size) {
return true;
}
if (zerror_ == Z_STREAM_END) {
- *data = NULL;
- *size = 0;
- return false;
+ if (zcontext_.next_out != NULL) {
+ // sub_stream_ may have concatenated streams to follow
+ zerror_ = inflateEnd(&zcontext_);
+ if (zerror_ != Z_OK) {
+ return false;
+ }
+ zerror_ = internalInflateInit2(&zcontext_, format_);
+ if (zerror_ != Z_OK) {
+ return false;
+ }
+ } else {
+ *data = NULL;
+ *size = 0;
+ return false;
+ }
}
zerror_ = Inflate(Z_NO_FLUSH);
if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) {
@@ -251,8 +267,7 @@ int GzipOutputStream::Deflate(int flush) {
}
error = deflate(&zcontext_, flush);
} while (error == Z_OK && zcontext_.avail_out == 0);
- if (((flush == Z_FULL_FLUSH) || (flush == Z_FINISH))
- && (zcontext_.avail_out != sub_data_size_)) {
+ if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) {
// Notify lower layer of data.
sub_stream_->BackUp(zcontext_.avail_out);
// We don't own the buffer anymore.