Home | History | Annotate | Download | only in io
      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 (at) 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/io/zero_copy_stream.h>
     49 
     50 namespace google {
     51 namespace protobuf {
     52 namespace io {
     53 
     54 // A ZeroCopyInputStream that reads compressed data through zlib
     55 class LIBPROTOBUF_EXPORT GzipInputStream : public ZeroCopyInputStream {
     56  public:
     57   // Format key for constructor
     58   enum Format {
     59     // zlib will autodetect gzip header or deflate stream
     60     AUTO = 0,
     61 
     62     // GZIP streams have some extra header data for file attributes.
     63     GZIP = 1,
     64 
     65     // Simpler zlib stream format.
     66     ZLIB = 2,
     67   };
     68 
     69   // buffer_size and format may be -1 for default of 64kB and GZIP format
     70   explicit GzipInputStream(
     71       ZeroCopyInputStream* sub_stream,
     72       Format format = AUTO,
     73       int buffer_size = -1);
     74   virtual ~GzipInputStream();
     75 
     76   // Return last error message or NULL if no error.
     77   inline const char* ZlibErrorMessage() const {
     78     return zcontext_.msg;
     79   }
     80   inline int ZlibErrorCode() const {
     81     return zerror_;
     82   }
     83 
     84   // implements ZeroCopyInputStream ----------------------------------
     85   bool Next(const void** data, int* size);
     86   void BackUp(int count);
     87   bool Skip(int count);
     88   int64 ByteCount() const;
     89 
     90  private:
     91   Format format_;
     92 
     93   ZeroCopyInputStream* sub_stream_;
     94 
     95   z_stream zcontext_;
     96   int zerror_;
     97 
     98   void* output_buffer_;
     99   void* output_position_;
    100   size_t output_buffer_length_;
    101 
    102   int Inflate(int flush);
    103   void DoNextOutput(const void** data, int* size);
    104 
    105   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream);
    106 };
    107 
    108 
    109 class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream {
    110  public:
    111   // Format key for constructor
    112   enum Format {
    113     // GZIP streams have some extra header data for file attributes.
    114     GZIP = 1,
    115 
    116     // Simpler zlib stream format.
    117     ZLIB = 2,
    118   };
    119 
    120   struct Options {
    121     // Defaults to GZIP.
    122     Format format;
    123 
    124     // What size buffer to use internally.  Defaults to 64kB.
    125     int buffer_size;
    126 
    127     // A number between 0 and 9, where 0 is no compression and 9 is best
    128     // compression.  Defaults to Z_DEFAULT_COMPRESSION (see zlib.h).
    129     int compression_level;
    130 
    131     // Defaults to Z_DEFAULT_STRATEGY.  Can also be set to Z_FILTERED,
    132     // Z_HUFFMAN_ONLY, or Z_RLE.  See the documentation for deflateInit2 in
    133     // zlib.h for definitions of these constants.
    134     int compression_strategy;
    135 
    136     Options();  // Initializes with default values.
    137   };
    138 
    139   // Create a GzipOutputStream with default options.
    140   explicit GzipOutputStream(ZeroCopyOutputStream* sub_stream);
    141 
    142   // Create a GzipOutputStream with the given options.
    143   GzipOutputStream(
    144       ZeroCopyOutputStream* sub_stream,
    145       const Options& options);
    146 
    147   // DEPRECATED:  Use one of the above constructors instead.
    148   GzipOutputStream(
    149       ZeroCopyOutputStream* sub_stream,
    150       Format format,
    151       int buffer_size = -1) GOOGLE_ATTRIBUTE_DEPRECATED;
    152 
    153   virtual ~GzipOutputStream();
    154 
    155   // Return last error message or NULL if no error.
    156   inline const char* ZlibErrorMessage() const {
    157     return zcontext_.msg;
    158   }
    159   inline int ZlibErrorCode() const {
    160     return zerror_;
    161   }
    162 
    163   // Flushes data written so far to zipped data in the underlying stream.
    164   // It is the caller's responsibility to flush the underlying stream if
    165   // necessary.
    166   // Compression may be less efficient stopping and starting around flushes.
    167   // Returns true if no error.
    168   bool Flush();
    169 
    170   // Writes out all data and closes the gzip stream.
    171   // It is the caller's responsibility to close the underlying stream if
    172   // necessary.
    173   // Returns true if no error.
    174   bool Close();
    175 
    176   // implements ZeroCopyOutputStream ---------------------------------
    177   bool Next(void** data, int* size);
    178   void BackUp(int count);
    179   int64 ByteCount() const;
    180 
    181  private:
    182   ZeroCopyOutputStream* sub_stream_;
    183   // Result from calling Next() on sub_stream_
    184   void* sub_data_;
    185   int sub_data_size_;
    186 
    187   z_stream zcontext_;
    188   int zerror_;
    189   void* input_buffer_;
    190   size_t input_buffer_length_;
    191 
    192   // Shared constructor code.
    193   void Init(ZeroCopyOutputStream* sub_stream, const Options& options);
    194 
    195   // Do some compression.
    196   // Takes zlib flush mode.
    197   // Returns zlib error code.
    198   int Deflate(int flush);
    199 
    200   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipOutputStream);
    201 };
    202 
    203 }  // namespace io
    204 }  // namespace protobuf
    205 
    206 }  // namespace google
    207 #endif  // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
    208