1//
2// InflatingStream.h
3//
4// Library: Foundation
5// Package: Streams
6// Module: ZLibStream
7//
8// Definition of the InflatingInputStream and InflatingOutputStream classes.
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Foundation_InflatingStream_INCLUDED
18#define Foundation_InflatingStream_INCLUDED
19
20
21#include "Poco/Foundation.h"
22#include "Poco/BufferedStreamBuf.h"
23#include <istream>
24#include <ostream>
25#if defined(POCO_UNBUNDLED)
26#include <zlib.h>
27#else
28#include "Poco/zlib.h"
29#endif
30
31
32namespace Poco {
33
34
35class Foundation_API InflatingStreamBuf: public BufferedStreamBuf
36 /// This is the streambuf class used by InflatingInputStream and InflatingOutputStream.
37 /// The actual work is delegated to zlib (see http://zlib.net).
38 /// Both zlib (deflate) streams and gzip streams are supported.
39 /// Output streams should always call close() to ensure
40 /// proper completion of decompression.
41{
42public:
43 enum StreamType
44 {
45 STREAM_ZLIB, /// Expect a zlib header, use Adler-32 checksum.
46 STREAM_GZIP, /// Expect a gzip header, use CRC-32 checksum.
47 STREAM_ZIP /// STREAM_ZIP is handled as STREAM_ZLIB, except that we do not check the ADLER32 value (must be checked by caller)
48 };
49
50 InflatingStreamBuf(std::istream& istr, StreamType type);
51 /// Creates an InflatingStreamBuf for expanding the compressed data read from
52 /// the give input stream.
53
54 InflatingStreamBuf(std::istream& istr, int windowBits);
55 /// Creates an InflatingStreamBuf for expanding the compressed data read from
56 /// the given input stream.
57 ///
58 /// Please refer to the zlib documentation of inflateInit2() for a description
59 /// of the windowBits parameter.
60
61 InflatingStreamBuf(std::ostream& ostr, StreamType type);
62 /// Creates an InflatingStreamBuf for expanding the compressed data passed through
63 /// and forwarding it to the given output stream.
64
65 InflatingStreamBuf(std::ostream& ostr, int windowBits);
66 /// Creates an InflatingStreamBuf for expanding the compressed data passed through
67 /// and forwarding it to the given output stream.
68 ///
69 /// Please refer to the zlib documentation of inflateInit2() for a description
70 /// of the windowBits parameter.
71
72 ~InflatingStreamBuf();
73 /// Destroys the InflatingStreamBuf.
74
75 int close();
76 /// Finishes up the stream.
77 ///
78 /// Must be called when inflating to an output stream.
79
80 void reset();
81 /// Resets the stream buffer.
82
83protected:
84 int readFromDevice(char* buffer, std::streamsize length);
85 int writeToDevice(const char* buffer, std::streamsize length);
86 int sync();
87
88private:
89 enum
90 {
91 STREAM_BUFFER_SIZE = 1024,
92 INFLATE_BUFFER_SIZE = 32768
93 };
94
95 std::istream* _pIstr;
96 std::ostream* _pOstr;
97 char* _buffer;
98 z_stream _zstr;
99 bool _eof;
100 bool _check;
101};
102
103
104class Foundation_API InflatingIOS: public virtual std::ios
105 /// The base class for InflatingOutputStream and InflatingInputStream.
106 ///
107 /// This class is needed to ensure the correct initialization
108 /// order of the stream buffer and base classes.
109{
110public:
111 InflatingIOS(std::ostream& ostr, InflatingStreamBuf::StreamType type = InflatingStreamBuf::STREAM_ZLIB);
112 /// Creates an InflatingIOS for expanding the compressed data passed through
113 /// and forwarding it to the given output stream.
114
115 InflatingIOS(std::ostream& ostr, int windowBits);
116 /// Creates an InflatingIOS for expanding the compressed data passed through
117 /// and forwarding it to the given output stream.
118 ///
119 /// Please refer to the zlib documentation of inflateInit2() for a description
120 /// of the windowBits parameter.
121
122 InflatingIOS(std::istream& istr, InflatingStreamBuf::StreamType type = InflatingStreamBuf::STREAM_ZLIB);
123 /// Creates an InflatingIOS for expanding the compressed data read from
124 /// the given input stream.
125
126 InflatingIOS(std::istream& istr, int windowBits);
127 /// Creates an InflatingIOS for expanding the compressed data read from
128 /// the given input stream.
129 ///
130 /// Please refer to the zlib documentation of inflateInit2() for a description
131 /// of the windowBits parameter.
132
133 ~InflatingIOS();
134 /// Destroys the InflatingIOS.
135
136 InflatingStreamBuf* rdbuf();
137 /// Returns a pointer to the underlying stream buffer.
138
139protected:
140 InflatingStreamBuf _buf;
141};
142
143
144class Foundation_API InflatingOutputStream: public std::ostream, public InflatingIOS
145 /// This stream decompresses all data passing through it
146 /// using zlib's inflate algorithm.
147 ///
148 /// After all data has been written to the stream, close()
149 /// must be called to ensure completion of decompression.
150{
151public:
152 InflatingOutputStream(std::ostream& ostr, InflatingStreamBuf::StreamType type = InflatingStreamBuf::STREAM_ZLIB);
153 /// Creates an InflatingOutputStream for expanding the compressed data passed through
154 /// and forwarding it to the given output stream.
155
156 InflatingOutputStream(std::ostream& ostr, int windowBits);
157 /// Creates an InflatingOutputStream for expanding the compressed data passed through
158 /// and forwarding it to the given output stream.
159 ///
160 /// Please refer to the zlib documentation of inflateInit2() for a description
161 /// of the windowBits parameter.
162
163 ~InflatingOutputStream();
164 /// Destroys the InflatingOutputStream.
165
166 int close();
167 /// Finishes up the stream.
168 ///
169 /// Must be called to ensure all data is properly written to
170 /// the target output stream.
171};
172
173
174class Foundation_API InflatingInputStream: public std::istream, public InflatingIOS
175 /// This stream decompresses all data passing through it
176 /// using zlib's inflate algorithm.
177 /// Example:
178 /// std::ifstream istr("data.gz", std::ios::binary);
179 /// InflatingInputStream inflater(istr, InflatingStreamBuf::STREAM_GZIP);
180 /// std::string data;
181 /// inflater >> data;
182 ///
183 /// The underlying input stream can contain more than one gzip/deflate stream.
184 /// After a gzip/deflate stream has been processed, reset() can be called
185 /// to inflate the next stream.
186{
187public:
188 InflatingInputStream(std::istream& istr, InflatingStreamBuf::StreamType type = InflatingStreamBuf::STREAM_ZLIB);
189 /// Creates an InflatingInputStream for expanding the compressed data read from
190 /// the given input stream.
191
192 InflatingInputStream(std::istream& istr, int windowBits);
193 /// Creates an InflatingInputStream for expanding the compressed data read from
194 /// the given input stream.
195 ///
196 /// Please refer to the zlib documentation of inflateInit2() for a description
197 /// of the windowBits parameter.
198
199 ~InflatingInputStream();
200 /// Destroys the InflatingInputStream.
201
202 void reset();
203 /// Resets the zlib machinery so that another zlib stream can be read from
204 /// the same underlying input stream.
205};
206
207
208} // namespace Poco
209
210
211#endif // Foundation_InflatingStream_INCLUDED
212