source: XMLIO_V2/external/src/POCO/Foundation/InflatingStream.cpp @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 6.3 KB
Line 
1//
2// InflatingStream.cpp
3//
4// $Id: //poco/1.3/Foundation/src/InflatingStream.cpp#3 $
5//
6// Library: Foundation
7// Package: Streams
8// Module:  ZLibStream
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// Permission is hereby granted, free of charge, to any person or organization
14// obtaining a copy of the software and accompanying documentation covered by
15// this license (the "Software") to use, reproduce, display, distribute,
16// execute, and transmit the Software, and to prepare derivative works of the
17// Software, and to permit third-parties to whom the Software is furnished to
18// do so, all subject to the following:
19//
20// The copyright notices in the Software and this entire statement, including
21// the above license grant, this restriction and the following disclaimer,
22// must be included in all copies of the Software, in whole or in part, and
23// all derivative works of the Software, unless such copies or derivative
24// works are solely in the form of machine-executable object code generated by
25// a source language processor.
26//
27// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
30// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
31// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
32// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33// DEALINGS IN THE SOFTWARE.
34//
35
36
37#include <Poco/InflatingStream.h>
38#include <Poco/Exception.h>
39
40
41namespace Poco {
42
43
44InflatingStreamBuf::InflatingStreamBuf(std::istream& istr, StreamType type): 
45        BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in),
46        _pIstr(&istr),
47        _pOstr(0),
48        _eof(false),
49        _check(type != STREAM_ZIP)
50{
51        _zstr.zalloc    = Z_NULL;
52        _zstr.zfree     = Z_NULL;
53        _zstr.opaque    = Z_NULL;
54        _zstr.next_in   = 0;
55        _zstr.avail_in  = 0;
56        _zstr.next_out  = 0;
57        _zstr.avail_out = 0;
58
59        int rc = inflateInit2(&_zstr, 15 + (type == STREAM_GZIP ? 16 : 0));
60        if (rc != Z_OK) throw IOException(zError(rc)); 
61
62        _buffer = new char[INFLATE_BUFFER_SIZE];
63}
64
65
66InflatingStreamBuf::InflatingStreamBuf(std::ostream& ostr, StreamType type): 
67        BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::out),
68        _pIstr(0),
69        _pOstr(&ostr),
70        _eof(false),
71        _check(type != STREAM_ZIP)
72{
73        _zstr.zalloc    = Z_NULL;
74        _zstr.zfree     = Z_NULL;
75        _zstr.opaque    = Z_NULL;
76        _zstr.next_in   = 0;
77        _zstr.avail_in  = 0;
78        _zstr.next_out  = 0;
79        _zstr.avail_out = 0;
80
81        int rc = inflateInit2(&_zstr, 15 + (type == STREAM_GZIP ? 16 : 0));
82        if (rc != Z_OK) throw IOException(zError(rc));
83
84        _buffer = new char[INFLATE_BUFFER_SIZE];
85}
86
87
88InflatingStreamBuf::~InflatingStreamBuf()
89{
90        try
91        {
92                close();
93        }
94        catch (...)
95        {
96        }
97        delete [] _buffer;
98}
99
100
101int InflatingStreamBuf::close()
102{
103        sync();
104        if (_pIstr || _pOstr)
105        {
106                int rc = inflateEnd(&_zstr);
107                if (rc != Z_OK) throw IOException(zError(rc));
108                _pIstr = 0;
109                _pOstr = 0;
110        }
111        return 0;
112}
113
114
115void InflatingStreamBuf::reset()
116{
117        int rc = inflateReset(&_zstr);
118        if (rc == Z_OK)
119                _eof = false;
120        else
121                throw IOException(zError(rc));
122}
123
124
125int InflatingStreamBuf::readFromDevice(char* buffer, std::streamsize length)
126{
127        if (_eof || !_pIstr) return 0;
128
129        if (_zstr.avail_in == 0)
130        {
131                int n = 0;
132                if (_pIstr->good())
133                {
134                        _pIstr->read(_buffer, INFLATE_BUFFER_SIZE);
135                        n = static_cast<int>(_pIstr->gcount());
136                }
137                if (n == 0) return 0;
138                _zstr.next_in   = (unsigned char*) _buffer;
139                _zstr.avail_in  = n;
140        }
141        _zstr.next_out  = (unsigned char*) buffer;
142        _zstr.avail_out = static_cast<unsigned>(length);
143        for (;;)
144        {
145                int rc = inflate(&_zstr, Z_NO_FLUSH);
146                if (rc == Z_DATA_ERROR && !_check)
147                {
148                        if (_zstr.avail_in == 0)
149                        {
150                                if (_pIstr->good())
151                                        rc = Z_OK;
152                                else
153                                        rc = Z_STREAM_END;
154                        }
155                }
156                if (rc == Z_STREAM_END)
157                {
158                        _eof = true;
159                        return static_cast<int>(length) - _zstr.avail_out;
160                }
161                if (rc != Z_OK) throw IOException(zError(rc));
162                if (_zstr.avail_out == 0)
163                        return static_cast<int>(length);
164                if (_zstr.avail_in == 0)
165                {
166                        int n = 0;
167                        if (_pIstr->good())
168                        {
169                                _pIstr->read(_buffer, INFLATE_BUFFER_SIZE);
170                                n = static_cast<int>(_pIstr->gcount());
171                        }
172                        if (n > 0)
173                        {
174                                _zstr.next_in  = (unsigned char*) _buffer;
175                                _zstr.avail_in = n;
176                        }
177                }
178        }
179}
180
181
182int InflatingStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
183{
184        if (length == 0 || !_pOstr) return 0;
185       
186        _zstr.next_in   = (unsigned char*) buffer;
187        _zstr.avail_in  = static_cast<unsigned>(length);
188        _zstr.next_out  = (unsigned char*) _buffer;
189        _zstr.avail_out = INFLATE_BUFFER_SIZE;
190        for (;;)
191        {
192                int rc = inflate(&_zstr, Z_NO_FLUSH);
193                if (rc == Z_STREAM_END)
194                {
195                        _pOstr->write(_buffer, INFLATE_BUFFER_SIZE - _zstr.avail_out);
196                        if (!_pOstr->good()) throw IOException(zError(rc));
197                        break;
198                }
199                if (rc != Z_OK) throw IOException(zError(rc)); 
200                if (_zstr.avail_out == 0)
201                {
202                        _pOstr->write(_buffer, INFLATE_BUFFER_SIZE);
203                        if (!_pOstr->good()) throw IOException(zError(rc));
204                        _zstr.next_out  = (unsigned char*) _buffer;
205                        _zstr.avail_out = INFLATE_BUFFER_SIZE;
206                }
207                if (_zstr.avail_in == 0)
208                {
209                        _pOstr->write(_buffer, INFLATE_BUFFER_SIZE - _zstr.avail_out);
210                        if (!_pOstr->good()) throw IOException(zError(rc)); 
211                        _zstr.next_out  = (unsigned char*) _buffer;
212                        _zstr.avail_out = INFLATE_BUFFER_SIZE;
213                        break;
214                }
215        }
216        return static_cast<int>(length);
217}
218
219
220InflatingIOS::InflatingIOS(std::ostream& ostr, InflatingStreamBuf::StreamType type):
221        _buf(ostr, type)
222{
223        poco_ios_init(&_buf);
224}
225
226
227InflatingIOS::InflatingIOS(std::istream& istr, InflatingStreamBuf::StreamType type):
228        _buf(istr, type)
229{
230        poco_ios_init(&_buf);
231}
232
233
234InflatingIOS::~InflatingIOS()
235{
236}
237
238
239InflatingStreamBuf* InflatingIOS::rdbuf()
240{
241        return &_buf;
242}
243
244
245InflatingOutputStream::InflatingOutputStream(std::ostream& ostr, InflatingStreamBuf::StreamType type):
246        InflatingIOS(ostr, type),
247        std::ostream(&_buf)
248{
249}
250
251
252InflatingOutputStream::~InflatingOutputStream()
253{
254}
255
256
257int InflatingOutputStream::close()
258{
259        return _buf.close();
260}
261
262
263InflatingInputStream::InflatingInputStream(std::istream& istr, InflatingStreamBuf::StreamType type):
264        InflatingIOS(istr, type),
265        std::istream(&_buf)
266{
267}
268
269
270InflatingInputStream::~InflatingInputStream()
271{
272}
273
274
275void InflatingInputStream::reset()
276{
277        _buf.reset();
278        clear();
279}
280
281
282} // namespace Poco
Note: See TracBrowser for help on using the repository browser.