source: XMLIO_V2/external/src/POCO/Foundation.save/DeflatingStream.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.9 KB
Line 
1//
2// DeflatingStream.cpp
3//
4// $Id: //poco/1.3/Foundation/src/DeflatingStream.cpp#2 $
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/DeflatingStream.h"
38#include "Poco/Exception.h"
39
40
41namespace Poco {
42
43
44DeflatingStreamBuf::DeflatingStreamBuf(std::istream& istr, StreamType type, int level): 
45        BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in),
46        _pIstr(&istr),
47        _pOstr(0),
48        _eof(false)
49{
50        _zstr.zalloc    = Z_NULL;
51        _zstr.zfree     = Z_NULL;
52        _zstr.opaque    = Z_NULL;
53        _zstr.next_in   = 0;
54        _zstr.avail_in  = 0;
55        _zstr.next_out  = 0;
56        _zstr.avail_out = 0;
57
58        int rc = deflateInit2(&_zstr, level, Z_DEFLATED, 15 + (type == STREAM_GZIP ? 16 : 0), 8, Z_DEFAULT_STRATEGY);
59        if (rc != Z_OK) throw IOException(zError(rc)); 
60
61        _buffer = new char[DEFLATE_BUFFER_SIZE];
62}
63
64
65DeflatingStreamBuf::DeflatingStreamBuf(std::ostream& ostr, StreamType type, int level): 
66        BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::out),
67        _pIstr(0),
68        _pOstr(&ostr),
69        _eof(false)
70{
71        _zstr.zalloc    = Z_NULL;
72        _zstr.zfree     = Z_NULL;
73        _zstr.opaque    = Z_NULL;
74        _zstr.next_in   = 0;
75        _zstr.avail_in  = 0;
76        _zstr.next_out  = 0;
77        _zstr.avail_out = 0;
78
79        int rc = deflateInit2(&_zstr, level, Z_DEFLATED, 15 + (type == STREAM_GZIP ? 16 : 0), 8, Z_DEFAULT_STRATEGY);
80        if (rc != Z_OK) throw IOException(zError(rc)); 
81
82        _buffer = new char[DEFLATE_BUFFER_SIZE];
83}
84
85
86DeflatingStreamBuf::~DeflatingStreamBuf()
87{
88        try
89        {
90                close();
91        }
92        catch (...)
93        {
94        }
95        delete [] _buffer;
96}
97
98
99int DeflatingStreamBuf::close()
100{
101        sync();
102        if (_pIstr)
103        {
104                int rc = deflateEnd(&_zstr);
105                if (rc != Z_OK) throw IOException(zError(rc));
106                _pIstr = 0;
107        }
108        else if (_pOstr)
109        {
110                if (_zstr.next_out)
111                {
112                        int rc = deflate(&_zstr, Z_FINISH);
113                        if (rc != Z_OK && rc != Z_STREAM_END) throw IOException(zError(rc)); 
114                        _pOstr->write(_buffer, DEFLATE_BUFFER_SIZE - _zstr.avail_out);
115                        if (!_pOstr->good()) throw IOException(zError(rc)); 
116                        _zstr.next_out  = (unsigned char*) _buffer;
117                        _zstr.avail_out = DEFLATE_BUFFER_SIZE;
118                        while (rc != Z_STREAM_END)
119                        {
120                                rc = deflate(&_zstr, Z_FINISH);
121                                if (rc != Z_OK && rc != Z_STREAM_END) throw IOException(zError(rc)); 
122                                _pOstr->write(_buffer, DEFLATE_BUFFER_SIZE - _zstr.avail_out);
123                                if (!_pOstr->good()) throw IOException(zError(rc)); 
124                                _zstr.next_out  = (unsigned char*) _buffer;
125                                _zstr.avail_out = DEFLATE_BUFFER_SIZE;
126                        }
127                        rc = deflateEnd(&_zstr);
128                        if (rc != Z_OK) throw IOException(zError(rc));
129                }
130                _pOstr = 0;
131        }
132        return 0;
133}
134
135
136int DeflatingStreamBuf::readFromDevice(char* buffer, std::streamsize length)
137{
138        if (!_pIstr) return 0;
139        if (_zstr.avail_in == 0 && !_eof)
140        {
141                int n = 0;
142                if (_pIstr->good())
143                {
144                        _pIstr->read(_buffer, DEFLATE_BUFFER_SIZE);
145                        n = static_cast<int>(_pIstr->gcount());
146                }
147                if (n > 0)
148                {
149                        _zstr.next_in  = (unsigned char*) _buffer;
150                        _zstr.avail_in = n;
151                }
152                else
153                {
154                        _zstr.next_in  = 0;
155                        _zstr.avail_in = 0;
156                        _eof = true;
157                }
158        }
159        _zstr.next_out  = (unsigned char*) buffer;
160        _zstr.avail_out = static_cast<unsigned>(length);
161        for (;;)
162        {
163                int rc = deflate(&_zstr, _eof ? Z_FINISH : Z_NO_FLUSH);
164                if (_eof && rc == Z_STREAM_END) 
165                {
166                        rc = deflateEnd(&_zstr);
167                        if (rc != Z_OK) throw IOException(zError(rc));
168                        _pIstr = 0;
169                        return static_cast<int>(length) - _zstr.avail_out;
170                }
171                if (rc != Z_OK) throw IOException(zError(rc)); 
172                if (_zstr.avail_out == 0)
173                {
174                        return static_cast<int>(length);
175                }
176                if (_zstr.avail_in == 0)
177                {
178                        int n = 0;
179                        if (_pIstr->good())
180                        {
181                                _pIstr->read(_buffer, DEFLATE_BUFFER_SIZE);
182                                n = static_cast<int>(_pIstr->gcount());
183                        }
184                        if (n > 0)
185                        {
186                                _zstr.next_in  = (unsigned char*) _buffer;
187                                _zstr.avail_in = n;
188                        }
189                        else
190                        {
191                                _zstr.next_in  = 0;
192                                _zstr.avail_in = 0;
193                                _eof = true;
194                        }
195                }
196        }
197}
198
199
200int DeflatingStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
201{
202        if (length == 0 || !_pOstr) return 0;
203
204        _zstr.next_in   = (unsigned char*) buffer;
205        _zstr.avail_in  = static_cast<unsigned>(length);
206        _zstr.next_out  = (unsigned char*) _buffer;
207        _zstr.avail_out = DEFLATE_BUFFER_SIZE;
208        for (;;)
209        {
210                int rc = deflate(&_zstr, Z_NO_FLUSH);
211                if (rc != Z_OK) throw IOException(zError(rc)); 
212                if (_zstr.avail_out == 0)
213                {
214                        _pOstr->write(_buffer, DEFLATE_BUFFER_SIZE);
215                        if (!_pOstr->good()) throw IOException(zError(rc)); 
216                        _zstr.next_out  = (unsigned char*) _buffer;
217                        _zstr.avail_out = DEFLATE_BUFFER_SIZE;
218                }
219                if (_zstr.avail_in == 0)
220                {
221                        _pOstr->write(_buffer, DEFLATE_BUFFER_SIZE - _zstr.avail_out);
222                        if (!_pOstr->good()) throw IOException(zError(rc)); 
223                        _zstr.next_out  = (unsigned char*) _buffer;
224                        _zstr.avail_out = DEFLATE_BUFFER_SIZE;
225                        break;
226                }
227        }
228        return static_cast<int>(length);
229}
230
231
232DeflatingIOS::DeflatingIOS(std::ostream& ostr, DeflatingStreamBuf::StreamType type, int level):
233        _buf(ostr, type, level)
234{
235        poco_ios_init(&_buf);
236}
237
238
239DeflatingIOS::DeflatingIOS(std::istream& istr, DeflatingStreamBuf::StreamType type, int level):
240        _buf(istr, type, level)
241{
242        poco_ios_init(&_buf);
243}
244
245
246DeflatingIOS::~DeflatingIOS()
247{
248}
249
250
251DeflatingStreamBuf* DeflatingIOS::rdbuf()
252{
253        return &_buf;
254}
255
256
257DeflatingOutputStream::DeflatingOutputStream(std::ostream& ostr, DeflatingStreamBuf::StreamType type, int level):
258        DeflatingIOS(ostr, type, level),
259        std::ostream(&_buf)
260{
261}
262
263
264DeflatingOutputStream::~DeflatingOutputStream()
265{
266}
267
268
269int DeflatingOutputStream::close()
270{
271        return _buf.close();
272}
273
274
275DeflatingInputStream::DeflatingInputStream(std::istream& istr, DeflatingStreamBuf::StreamType type, int level):
276        DeflatingIOS(istr, type, level),
277        std::istream(&_buf)
278{
279}
280
281
282DeflatingInputStream::~DeflatingInputStream()
283{
284}
285
286
287} // namespace Poco
Note: See TracBrowser for help on using the repository browser.