~ubuntu-branches/ubuntu/oneiric/mozc/oneiric

« back to all changes in this revision

Viewing changes to protobuf/files/src/google/protobuf/io/gzip_stream.cc

  • Committer: Bazaar Package Importer
  • Author(s): Nobuhiro Iwamatsu
  • Date: 2010-07-14 03:26:47 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100714032647-13qjisj6m8cm8jdx
Tags: 0.12.410.102-1
* New upstream release (Closes: #588971).
  - Add mozc-server, mozc-utils-gui and scim-mozc packages.
* Update debian/rules.
  Add --gypdir option to build_mozc.py.
* Update debian/control.
  - Bumped standards-version to 3.9.0.
  - Update description.
* Add mozc icon (Closes: #588972).
* Add patch which revises issue 18.
  ibus_mozc_issue18.patch
* kFreeBSD build support.
  support_kfreebsd.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Protocol Buffers - Google's data interchange format
2
 
// Copyright 2008 Google Inc.  All rights reserved.
3
 
// http://code.google.com/p/protobuf/
4
 
//
5
 
// Redistribution and use in source and binary forms, with or without
6
 
// modification, are permitted provided that the following conditions are
7
 
// met:
8
 
//
9
 
//     * Redistributions of source code must retain the above copyright
10
 
// notice, this list of conditions and the following disclaimer.
11
 
//     * Redistributions in binary form must reproduce the above
12
 
// copyright notice, this list of conditions and the following disclaimer
13
 
// in the documentation and/or other materials provided with the
14
 
// distribution.
15
 
//     * Neither the name of Google Inc. nor the names of its
16
 
// contributors may be used to endorse or promote products derived from
17
 
// this software without specific prior written permission.
18
 
//
19
 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
 
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
 
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
 
 
31
 
// Author: brianolson@google.com (Brian Olson)
32
 
//
33
 
// This file contains the implementation of classes GzipInputStream and
34
 
// GzipOutputStream.
35
 
 
36
 
#include "config.h"
37
 
 
38
 
#if HAVE_ZLIB
39
 
#include <google/protobuf/io/gzip_stream.h>
40
 
 
41
 
#include <google/protobuf/stubs/common.h>
42
 
 
43
 
namespace google {
44
 
namespace protobuf {
45
 
namespace io {
46
 
 
47
 
static const int kDefaultBufferSize = 65536;
48
 
 
49
 
GzipInputStream::GzipInputStream(
50
 
    ZeroCopyInputStream* sub_stream, Format format, int buffer_size)
51
 
    : format_(format), sub_stream_(sub_stream), zerror_(Z_OK) {
52
 
  zcontext_.zalloc = Z_NULL;
53
 
  zcontext_.zfree = Z_NULL;
54
 
  zcontext_.opaque = Z_NULL;
55
 
  zcontext_.total_out = 0;
56
 
  zcontext_.next_in = NULL;
57
 
  zcontext_.avail_in = 0;
58
 
  zcontext_.total_in = 0;
59
 
  zcontext_.msg = NULL;
60
 
  if (buffer_size == -1) {
61
 
    output_buffer_length_ = kDefaultBufferSize;
62
 
  } else {
63
 
    output_buffer_length_ = buffer_size;
64
 
  }
65
 
  output_buffer_ = operator new(output_buffer_length_);
66
 
  GOOGLE_CHECK(output_buffer_ != NULL);
67
 
  zcontext_.next_out = static_cast<Bytef*>(output_buffer_);
68
 
  zcontext_.avail_out = output_buffer_length_;
69
 
  output_position_ = output_buffer_;
70
 
}
71
 
GzipInputStream::~GzipInputStream() {
72
 
  operator delete(output_buffer_);
73
 
  zerror_ = inflateEnd(&zcontext_);
74
 
}
75
 
 
76
 
int GzipInputStream::Inflate(int flush) {
77
 
  if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) {
78
 
    // previous inflate filled output buffer. don't change input params yet.
79
 
  } else if (zcontext_.avail_in == 0) {
80
 
    const void* in;
81
 
    int in_size;
82
 
    bool first = zcontext_.next_in == NULL;
83
 
    bool ok = sub_stream_->Next(&in, &in_size);
84
 
    if (!ok) {
85
 
      zcontext_.next_out = NULL;
86
 
      zcontext_.avail_out = 0;
87
 
      return Z_STREAM_END;
88
 
    }
89
 
    zcontext_.next_in = static_cast<Bytef*>(const_cast<void*>(in));
90
 
    zcontext_.avail_in = in_size;
91
 
    if (first) {
92
 
      int windowBitsFormat = 0;
93
 
      switch (format_) {
94
 
        case GZIP: windowBitsFormat = 16; break;
95
 
        case AUTO: windowBitsFormat = 32; break;
96
 
        case ZLIB: windowBitsFormat = 0; break;
97
 
      }
98
 
      int error = inflateInit2(&zcontext_,
99
 
        /* windowBits */15 | windowBitsFormat);
100
 
      if (error != Z_OK) {
101
 
        return error;
102
 
      }
103
 
    }
104
 
  }
105
 
  zcontext_.next_out = static_cast<Bytef*>(output_buffer_);
106
 
  zcontext_.avail_out = output_buffer_length_;
107
 
  output_position_ = output_buffer_;
108
 
  int error = inflate(&zcontext_, flush);
109
 
  return error;
110
 
}
111
 
 
112
 
void GzipInputStream::DoNextOutput(const void** data, int* size) {
113
 
  *data = output_position_;
114
 
  *size = ((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_);
115
 
  output_position_ = zcontext_.next_out;
116
 
}
117
 
 
118
 
// implements ZeroCopyInputStream ----------------------------------
119
 
bool GzipInputStream::Next(const void** data, int* size) {
120
 
  bool ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END)
121
 
      || (zerror_ == Z_BUF_ERROR);
122
 
  if ((!ok) || (zcontext_.next_out == NULL)) {
123
 
    return false;
124
 
  }
125
 
  if (zcontext_.next_out != output_position_) {
126
 
    DoNextOutput(data, size);
127
 
    return true;
128
 
  }
129
 
  if (zerror_ == Z_STREAM_END) {
130
 
    *data = NULL;
131
 
    *size = 0;
132
 
    return false;
133
 
  }
134
 
  zerror_ = Inflate(Z_NO_FLUSH);
135
 
  if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) {
136
 
    // The underlying stream's Next returned false inside Inflate.
137
 
    return false;
138
 
  }
139
 
  ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END)
140
 
      || (zerror_ == Z_BUF_ERROR);
141
 
  if (!ok) {
142
 
    return false;
143
 
  }
144
 
  DoNextOutput(data, size);
145
 
  return true;
146
 
}
147
 
void GzipInputStream::BackUp(int count) {
148
 
  output_position_ = reinterpret_cast<void*>(
149
 
      reinterpret_cast<uintptr_t>(output_position_) - count);
150
 
}
151
 
bool GzipInputStream::Skip(int count) {
152
 
  const void* data;
153
 
  int size;
154
 
  bool ok = Next(&data, &size);
155
 
  while (ok && (size < count)) {
156
 
    count -= size;
157
 
    ok = Next(&data, &size);
158
 
  }
159
 
  if (size > count) {
160
 
    BackUp(size - count);
161
 
  }
162
 
  return ok;
163
 
}
164
 
int64 GzipInputStream::ByteCount() const {
165
 
  return zcontext_.total_out +
166
 
    (((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_));
167
 
}
168
 
 
169
 
// =========================================================================
170
 
 
171
 
GzipOutputStream::Options::Options()
172
 
    : format(GZIP),
173
 
      buffer_size(kDefaultBufferSize),
174
 
      compression_level(Z_DEFAULT_COMPRESSION),
175
 
      compression_strategy(Z_DEFAULT_STRATEGY) {}
176
 
 
177
 
GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream) {
178
 
  Init(sub_stream, Options());
179
 
}
180
 
 
181
 
GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream,
182
 
                                   const Options& options) {
183
 
  Init(sub_stream, options);
184
 
}
185
 
 
186
 
GzipOutputStream::GzipOutputStream(
187
 
    ZeroCopyOutputStream* sub_stream, Format format, int buffer_size) {
188
 
  Options options;
189
 
  options.format = format;
190
 
  if (buffer_size != -1) {
191
 
    options.buffer_size = buffer_size;
192
 
  }
193
 
  Init(sub_stream, options);
194
 
}
195
 
 
196
 
void GzipOutputStream::Init(ZeroCopyOutputStream* sub_stream,
197
 
                            const Options& options) {
198
 
  sub_stream_ = sub_stream;
199
 
  sub_data_ = NULL;
200
 
  sub_data_size_ = 0;
201
 
 
202
 
  input_buffer_length_ = options.buffer_size;
203
 
  input_buffer_ = operator new(input_buffer_length_);
204
 
  GOOGLE_CHECK(input_buffer_ != NULL);
205
 
 
206
 
  zcontext_.zalloc = Z_NULL;
207
 
  zcontext_.zfree = Z_NULL;
208
 
  zcontext_.opaque = Z_NULL;
209
 
  zcontext_.next_out = NULL;
210
 
  zcontext_.avail_out = 0;
211
 
  zcontext_.total_out = 0;
212
 
  zcontext_.next_in = NULL;
213
 
  zcontext_.avail_in = 0;
214
 
  zcontext_.total_in = 0;
215
 
  zcontext_.msg = NULL;
216
 
  // default to GZIP format
217
 
  int windowBitsFormat = 16;
218
 
  if (options.format == ZLIB) {
219
 
    windowBitsFormat = 0;
220
 
  }
221
 
  zerror_ = deflateInit2(
222
 
      &zcontext_,
223
 
      options.compression_level,
224
 
      Z_DEFLATED,
225
 
      /* windowBits */15 | windowBitsFormat,
226
 
      /* memLevel (default) */8,
227
 
      options.compression_strategy);
228
 
}
229
 
 
230
 
GzipOutputStream::~GzipOutputStream() {
231
 
  Close();
232
 
  if (input_buffer_ != NULL) {
233
 
    operator delete(input_buffer_);
234
 
  }
235
 
}
236
 
 
237
 
// private
238
 
int GzipOutputStream::Deflate(int flush) {
239
 
  int error = Z_OK;
240
 
  do {
241
 
    if ((sub_data_ == NULL) || (zcontext_.avail_out == 0)) {
242
 
      bool ok = sub_stream_->Next(&sub_data_, &sub_data_size_);
243
 
      if (!ok) {
244
 
        sub_data_ = NULL;
245
 
        sub_data_size_ = 0;
246
 
        return Z_BUF_ERROR;
247
 
      }
248
 
      GOOGLE_CHECK_GT(sub_data_size_, 0);
249
 
      zcontext_.next_out = static_cast<Bytef*>(sub_data_);
250
 
      zcontext_.avail_out = sub_data_size_;
251
 
    }
252
 
    error = deflate(&zcontext_, flush);
253
 
  } while (error == Z_OK && zcontext_.avail_out == 0);
254
 
  if (((flush == Z_FULL_FLUSH) || (flush == Z_FINISH))
255
 
      && (zcontext_.avail_out != sub_data_size_)) {
256
 
    // Notify lower layer of data.
257
 
    sub_stream_->BackUp(zcontext_.avail_out);
258
 
    // We don't own the buffer anymore.
259
 
    sub_data_ = NULL;
260
 
    sub_data_size_ = 0;
261
 
  }
262
 
  return error;
263
 
}
264
 
 
265
 
// implements ZeroCopyOutputStream ---------------------------------
266
 
bool GzipOutputStream::Next(void** data, int* size) {
267
 
  if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
268
 
    return false;
269
 
  }
270
 
  if (zcontext_.avail_in != 0) {
271
 
    zerror_ = Deflate(Z_NO_FLUSH);
272
 
    if (zerror_ != Z_OK) {
273
 
      return false;
274
 
    }
275
 
  }
276
 
  if (zcontext_.avail_in == 0) {
277
 
    // all input was consumed. reset the buffer.
278
 
    zcontext_.next_in = static_cast<Bytef*>(input_buffer_);
279
 
    zcontext_.avail_in = input_buffer_length_;
280
 
    *data = input_buffer_;
281
 
    *size = input_buffer_length_;
282
 
  } else {
283
 
    // The loop in Deflate should consume all avail_in
284
 
    GOOGLE_LOG(DFATAL) << "Deflate left bytes unconsumed";
285
 
  }
286
 
  return true;
287
 
}
288
 
void GzipOutputStream::BackUp(int count) {
289
 
  GOOGLE_CHECK_GE(zcontext_.avail_in, count);
290
 
  zcontext_.avail_in -= count;
291
 
}
292
 
int64 GzipOutputStream::ByteCount() const {
293
 
  return zcontext_.total_in + zcontext_.avail_in;
294
 
}
295
 
 
296
 
bool GzipOutputStream::Flush() {
297
 
  do {
298
 
    zerror_ = Deflate(Z_FULL_FLUSH);
299
 
  } while (zerror_ == Z_OK);
300
 
  return zerror_ == Z_OK;
301
 
}
302
 
 
303
 
bool GzipOutputStream::Close() {
304
 
  if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
305
 
    return false;
306
 
  }
307
 
  do {
308
 
    zerror_ = Deflate(Z_FINISH);
309
 
  } while (zerror_ == Z_OK);
310
 
  zerror_ = deflateEnd(&zcontext_);
311
 
  bool ok = zerror_ == Z_OK;
312
 
  zerror_ = Z_STREAM_END;
313
 
  return ok;
314
 
}
315
 
 
316
 
}  // namespace io
317
 
}  // namespace protobuf
318
 
}  // namespace google
319
 
 
320
 
#endif  // HAVE_ZLIB