blob: 8244500010d7482a0e520891323c1caee3758f58 [file] [log] [blame]
Brian Silverman9c614bc2016-02-15 20:20:02 -05001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// https://developers.google.com/protocol-buffers/
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 definition for classes GzipInputStream and
34// GzipOutputStream.
35//
36// GzipInputStream decompresses data from an underlying
37// ZeroCopyInputStream and provides the decompressed data as a
38// ZeroCopyInputStream.
39//
40// GzipOutputStream is an ZeroCopyOutputStream that compresses data to
41// an underlying ZeroCopyOutputStream.
42
43#ifndef GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
44#define GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
45
46#include <zlib.h>
47
48#include <google/protobuf/stubs/common.h>
49#include <google/protobuf/io/zero_copy_stream.h>
50
51namespace google {
52namespace protobuf {
53namespace io {
54
55// A ZeroCopyInputStream that reads compressed data through zlib
56class LIBPROTOBUF_EXPORT GzipInputStream : public ZeroCopyInputStream {
57 public:
58 // Format key for constructor
59 enum Format {
60 // zlib will autodetect gzip header or deflate stream
61 AUTO = 0,
62
63 // GZIP streams have some extra header data for file attributes.
64 GZIP = 1,
65
66 // Simpler zlib stream format.
67 ZLIB = 2,
68 };
69
70 // buffer_size and format may be -1 for default of 64kB and GZIP format
71 explicit GzipInputStream(
72 ZeroCopyInputStream* sub_stream,
73 Format format = AUTO,
74 int buffer_size = -1);
75 virtual ~GzipInputStream();
76
77 // Return last error message or NULL if no error.
78 inline const char* ZlibErrorMessage() const {
79 return zcontext_.msg;
80 }
81 inline int ZlibErrorCode() const {
82 return zerror_;
83 }
84
85 // implements ZeroCopyInputStream ----------------------------------
86 bool Next(const void** data, int* size);
87 void BackUp(int count);
88 bool Skip(int count);
89 int64 ByteCount() const;
90
91 private:
92 Format format_;
93
94 ZeroCopyInputStream* sub_stream_;
95
96 z_stream zcontext_;
97 int zerror_;
98
99 void* output_buffer_;
100 void* output_position_;
101 size_t output_buffer_length_;
102 int64 byte_count_;
103
104 int Inflate(int flush);
105 void DoNextOutput(const void** data, int* size);
106
107 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream);
108};
109
110
111class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream {
112 public:
113 // Format key for constructor
114 enum Format {
115 // GZIP streams have some extra header data for file attributes.
116 GZIP = 1,
117
118 // Simpler zlib stream format.
119 ZLIB = 2,
120 };
121
122 struct Options {
123 // Defaults to GZIP.
124 Format format;
125
126 // What size buffer to use internally. Defaults to 64kB.
127 int buffer_size;
128
129 // A number between 0 and 9, where 0 is no compression and 9 is best
130 // compression. Defaults to Z_DEFAULT_COMPRESSION (see zlib.h).
131 int compression_level;
132
133 // Defaults to Z_DEFAULT_STRATEGY. Can also be set to Z_FILTERED,
134 // Z_HUFFMAN_ONLY, or Z_RLE. See the documentation for deflateInit2 in
135 // zlib.h for definitions of these constants.
136 int compression_strategy;
137
138 Options(); // Initializes with default values.
139 };
140
141 // Create a GzipOutputStream with default options.
142 explicit GzipOutputStream(ZeroCopyOutputStream* sub_stream);
143
144 // Create a GzipOutputStream with the given options.
145 GzipOutputStream(
146 ZeroCopyOutputStream* sub_stream,
147 const Options& options);
148
149 virtual ~GzipOutputStream();
150
151 // Return last error message or NULL if no error.
152 inline const char* ZlibErrorMessage() const {
153 return zcontext_.msg;
154 }
155 inline int ZlibErrorCode() const {
156 return zerror_;
157 }
158
159 // Flushes data written so far to zipped data in the underlying stream.
160 // It is the caller's responsibility to flush the underlying stream if
161 // necessary.
162 // Compression may be less efficient stopping and starting around flushes.
163 // Returns true if no error.
164 //
165 // Please ensure that block size is > 6. Here is an excerpt from the zlib
166 // doc that explains why:
167 //
168 // In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out
169 // is greater than six to avoid repeated flush markers due to
170 // avail_out == 0 on return.
171 bool Flush();
172
173 // Writes out all data and closes the gzip stream.
174 // It is the caller's responsibility to close the underlying stream if
175 // necessary.
176 // Returns true if no error.
177 bool Close();
178
179 // implements ZeroCopyOutputStream ---------------------------------
180 bool Next(void** data, int* size);
181 void BackUp(int count);
182 int64 ByteCount() const;
183
184 private:
185 ZeroCopyOutputStream* sub_stream_;
186 // Result from calling Next() on sub_stream_
187 void* sub_data_;
188 int sub_data_size_;
189
190 z_stream zcontext_;
191 int zerror_;
192 void* input_buffer_;
193 size_t input_buffer_length_;
194
195 // Shared constructor code.
196 void Init(ZeroCopyOutputStream* sub_stream, const Options& options);
197
198 // Do some compression.
199 // Takes zlib flush mode.
200 // Returns zlib error code.
201 int Deflate(int flush);
202
203 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipOutputStream);
204};
205
206} // namespace io
207} // namespace protobuf
208
209} // namespace google
210#endif // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__