1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // Defines simple streams which can zlib compress or decompress data.
16 :
17 : #ifndef SYZYGY_CORE_ZSTREAM_H_
18 : #define SYZYGY_CORE_ZSTREAM_H_
19 :
20 : #include <memory>
21 :
22 : #include "syzygy/core/serialization.h"
23 :
24 : // Forward declaration.
25 m : struct z_stream_s;
26 :
27 m : namespace core {
28 :
29 : // A zlib compressing out-stream. Acts as a filter, accepting the uncompressed
30 : // input that is pushed to it, and pushing compressed output to the chained
31 : // stream.
32 m : class ZOutStream : public OutStream {
33 m : public:
34 : // @{
35 : // Constructor.
36 : // @param out_stream the output stream to receive the compressed data.
37 m : explicit ZOutStream(OutStream* out_stream);
38 : // @}
39 :
40 : // Destructor.
41 m : virtual ~ZOutStream();
42 :
43 : // These are effectively forwarded from zlib.h.
44 m : static const int kZDefaultCompression = -1;
45 m : static const int kZNoCompression = 0;
46 m : static const int kZBestSpeed = 1;
47 m : static const int kZBestCompression = 9;
48 :
49 : // @{
50 : // Initializes this compressor. Must be called prior to calling Write.
51 : // @param level the level of compression. Must be kZDefaultCompression (-1),
52 : // or an integer in the range 0..9, inclusive. If not provided defaults to
53 : // Z_DEFAULT_COMPRESSION.
54 : // @returns true on success, false otherwise.
55 m : bool Init();
56 m : bool Init(int level);
57 : // @}
58 :
59 : // @name OutStream implementation.
60 : // @{
61 : // Writes the given buffer of data to the stream. This may or may not produce
62 : // output in the enclosed out-stream.
63 : // @param length the number of bytes to write.
64 : // @param bytes the buffer of data to write.
65 : // @returns true on success, false otherwise.
66 m : virtual bool Write(size_t length, const Byte* bytes) override;
67 : // After a call to Flush the compressed stream is closed and further calls to
68 : // Write will fail. Flush must be called after all writing is finished in
69 : // order for the output to be well-formed. This does not recursively call
70 : // flush on the child stream.
71 : // @returns true on success, false otherwise.
72 m : virtual bool Flush() override;
73 : // @}
74 :
75 m : private:
76 : // Functor that takes care of cleaning up a zstream object that was
77 : // initialized with deflateInit.
78 m : struct z_stream_s_close {
79 m : inline void operator()(z_stream_s* zstream) const;
80 m : };
81 :
82 m : bool FlushBuffer();
83 :
84 m : std::unique_ptr<z_stream_s, z_stream_s_close> zstream_;
85 m : OutStream* out_stream_;
86 m : std::vector<uint8_t> buffer_;
87 m : };
88 :
89 : // A zlib decompressing in-stream, decompressing the data from the chained
90 : // input stream and returning decompressed data to the caller.
91 m : class ZInStream : public InStream {
92 m : public:
93 : // Constructor.
94 : // @param in_stream the input stream from which we read compressed data.
95 m : explicit ZInStream(InStream* in_stream);
96 :
97 : // Destructor.
98 m : virtual ~ZInStream();
99 :
100 : // Initializes this decompressor. Must be called prior to calling any read
101 : // functions.
102 m : bool Init();
103 :
104 m : protected:
105 : // InStream implementation.
106 m : virtual bool ReadImpl(size_t length,
107 m : Byte* bytes,
108 m : size_t* bytes_read) override;
109 :
110 m : private:
111 : // Functor that takes care of cleaning up a zstream object that was
112 : // initialized with inflateInit.
113 m : struct z_stream_s_close {
114 m : inline void operator()(z_stream_s* zstream) const;
115 m : };
116 :
117 m : std::unique_ptr<z_stream_s, z_stream_s_close> zstream_;
118 m : InStream* in_stream_;
119 m : std::vector<uint8_t> buffer_;
120 m : };
121 :
122 m : } // namespace core
123 :
124 : #endif // SYZYGY_CORE_ZSTREAM_H_
|