47 static const int kDefaultBufferSize = 65536;
52 zcontext_.state = Z_NULL;
53 zcontext_.zalloc = Z_NULL;
54 zcontext_.zfree = Z_NULL;
55 zcontext_.opaque = Z_NULL;
56 zcontext_.total_out = 0;
57 zcontext_.next_in =
NULL;
58 zcontext_.avail_in = 0;
59 zcontext_.total_in = 0;
62 output_buffer_length_ = kDefaultBufferSize;
66 output_buffer_ =
operator new(output_buffer_length_);
68 zcontext_.next_out =
static_cast<Bytef*
>(output_buffer_);
69 zcontext_.avail_out = output_buffer_length_;
70 output_position_ = output_buffer_;
72 GzipInputStream::~GzipInputStream() {
73 operator delete(output_buffer_);
74 zerror_ = inflateEnd(&zcontext_);
77 static inline int internalInflateInit2(z_stream* zcontext,
78 GzipInputStream::Format
format) {
79 int windowBitsFormat = 0;
81 case GzipInputStream::GZIP:
82 windowBitsFormat = 16;
84 case GzipInputStream::AUTO:
85 windowBitsFormat = 32;
87 case GzipInputStream::ZLIB:
91 return inflateInit2(zcontext, 15 | windowBitsFormat);
94 int GzipInputStream::Inflate(
int flush) {
95 if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) {
97 }
else if (zcontext_.avail_in == 0) {
101 bool ok = sub_stream_->Next(&in, &in_size);
103 zcontext_.next_out =
NULL;
104 zcontext_.avail_out = 0;
107 zcontext_.next_in =
static_cast<Bytef*
>(
const_cast<void*
>(in));
108 zcontext_.avail_in = in_size;
110 int error = internalInflateInit2(&zcontext_, format_);
116 zcontext_.next_out =
static_cast<Bytef*
>(output_buffer_);
117 zcontext_.avail_out = output_buffer_length_;
118 output_position_ = output_buffer_;
119 int error = inflate(&zcontext_, flush);
123 void GzipInputStream::DoNextOutput(
const void**
data,
int*
size) {
124 *
data = output_position_;
125 *
size = ((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_);
126 output_position_ = zcontext_.next_out;
130 bool GzipInputStream::Next(
const void**
data,
int*
size) {
131 bool ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) ||
132 (zerror_ == Z_BUF_ERROR);
133 if ((!ok) || (zcontext_.next_out ==
NULL)) {
136 if (zcontext_.next_out != output_position_) {
140 if (zerror_ == Z_STREAM_END) {
141 if (zcontext_.next_out !=
NULL) {
143 zerror_ = inflateEnd(&zcontext_);
145 if (zerror_ != Z_OK) {
148 zerror_ = internalInflateInit2(&zcontext_, format_);
149 if (zerror_ != Z_OK) {
158 zerror_ = Inflate(Z_NO_FLUSH);
159 if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out ==
NULL)) {
163 ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END) ||
164 (zerror_ == Z_BUF_ERROR);
171 void GzipInputStream::BackUp(
int count) {
172 output_position_ =
reinterpret_cast<void*
>(
173 reinterpret_cast<uintptr_t
>(output_position_) -
count);
188 int64 GzipInputStream::ByteCount()
const {
190 if (zcontext_.next_out !=
NULL && output_position_ !=
NULL) {
191 ret +=
reinterpret_cast<uintptr_t
>(zcontext_.next_out) -
192 reinterpret_cast<uintptr_t
>(output_position_);
199 GzipOutputStream::Options::Options()
202 compression_level(Z_DEFAULT_COMPRESSION),
203 compression_strategy(Z_DEFAULT_STRATEGY) {}
205 GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream) {
206 Init(sub_stream, Options());
209 GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream,
216 sub_stream_ = sub_stream;
220 input_buffer_length_ =
options.buffer_size;
221 input_buffer_ =
operator new(input_buffer_length_);
224 zcontext_.zalloc = Z_NULL;
225 zcontext_.zfree = Z_NULL;
226 zcontext_.opaque = Z_NULL;
227 zcontext_.next_out =
NULL;
228 zcontext_.avail_out = 0;
229 zcontext_.total_out = 0;
230 zcontext_.next_in =
NULL;
231 zcontext_.avail_in = 0;
232 zcontext_.total_in = 0;
233 zcontext_.msg =
NULL;
235 int windowBitsFormat = 16;
237 windowBitsFormat = 0;
240 deflateInit2(&zcontext_,
options.compression_level, Z_DEFLATED,
241 15 | windowBitsFormat,
242 8,
options.compression_strategy);
245 GzipOutputStream::~GzipOutputStream() {
247 operator delete(input_buffer_);
251 int GzipOutputStream::Deflate(
int flush) {
254 if ((sub_data_ ==
NULL) || (zcontext_.avail_out == 0)) {
255 bool ok = sub_stream_->Next(&sub_data_, &sub_data_size_);
262 zcontext_.next_out =
static_cast<Bytef*
>(sub_data_);
263 zcontext_.avail_out = sub_data_size_;
265 error = deflate(&zcontext_, flush);
266 }
while (
error == Z_OK && zcontext_.avail_out == 0);
267 if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) {
269 sub_stream_->BackUp(zcontext_.avail_out);
278 bool GzipOutputStream::Next(
void**
data,
int*
size) {
279 if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
282 if (zcontext_.avail_in != 0) {
283 zerror_ = Deflate(Z_NO_FLUSH);
284 if (zerror_ != Z_OK) {
288 if (zcontext_.avail_in == 0) {
290 zcontext_.next_in =
static_cast<Bytef*
>(input_buffer_);
291 zcontext_.avail_in = input_buffer_length_;
292 *
data = input_buffer_;
293 *
size = input_buffer_length_;
296 GOOGLE_LOG(DFATAL) <<
"Deflate left bytes unconsumed";
300 void GzipOutputStream::BackUp(
int count) {
302 zcontext_.avail_in -=
count;
304 int64 GzipOutputStream::ByteCount()
const {
305 return zcontext_.total_in + zcontext_.avail_in;
308 bool GzipOutputStream::Flush() {
309 zerror_ = Deflate(Z_FULL_FLUSH);
311 return (zerror_ == Z_OK) ||
312 (zerror_ == Z_BUF_ERROR && zcontext_.avail_in == 0 &&
313 zcontext_.avail_out != 0);
317 if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
321 zerror_ = Deflate(Z_FINISH);
322 }
while (zerror_ == Z_OK);
323 zerror_ = deflateEnd(&zcontext_);
324 bool ok = zerror_ == Z_OK;
325 zerror_ = Z_STREAM_END;