Code

revert 11172, synthesized events are used to update controls spinbuttons
[inkscape.git] / src / streams-zlib.cpp
1 /*
2  * IO layer : zlib streambuf
3  *
4  * Authors:
5  *   Johan Ceuppens <jceuppen at easynet dot be>
6  *
7  * Copyright (C) 2004 Johan Ceuppens
8  *
9  * Released under GNU LGPL, read the file 'COPYING.LIB' for more information
10  */
12 #include "streams-zlib.h"
14 namespace Inkscape {
16 /**
17  * ZlibBuffer
18  */
20 ZlibBuffer::ZlibBuffer(URIHandle& urih)
21   : _urihandle(&urih), _putsize(BUFSIZE_STREAM), _getsize(BUFSIZE_STREAM)
22 {
23     init_inflation();
24 }
26 int ZlibBuffer::allocate_buffers()
27 {
28     if (!eback()) {
29         char *buf = new char[_getsize + _putsize];
30         setg(buf, buf , buf);
31         buf += _getsize;
32         setp(buf, buf + _putsize);
33         return 1;
34     }
35     return 0;
36 }
38 int ZlibBuffer::reallocate_buffers(int new_getsize, int new_putsize)
39 {
40     char *new_buffer = new char[new_getsize + new_putsize];
42     std::memcpy(new_buffer, eback(), _getsize);
43     std::memcpy(new_buffer, eback() + _getsize, _putsize);
45     setg(new_buffer, new_buffer + (gptr() - eback()),
46          new_buffer + new_getsize);
47     new_buffer += new_getsize;
48     setp(new_buffer, new_buffer + new_putsize);
50     _getsize = new_getsize;
51     _putsize = new_putsize;
53     return 1;
54 }
56 int ZlibBuffer::underflow()
57 {
58     if (eback() == 0 && allocate_buffers() == 0)
59         return EOF;
61     if (consume_and_inflate() == EOF)
62         return EOF;
64     return *(unsigned char *)gptr();
65 }
67 int ZlibBuffer::overflow(int c)
68 {
69     if (c == EOF)
70         return flush_output();
72     if (pbase() == 0 && allocate_buffers() == 0)
73         return EOF;
75     if (pptr() >= epptr() &&
76         flush_output() == EOF)
77         return EOF;
79     putchar(c);
81     if (pptr() >= epptr() &&
82         flush_output() == EOF)
83         return EOF;
85     return c;
86 }
88 int ZlibBuffer::consume(guint8 *buf, int nbytes)
89 {
90     return do_consume(buf, nbytes);
91 }
93 int ZlibBuffer::do_consume(guint8 *buf, int nbytes)
94 {
95     nbytes = _urihandle->read(buf, nbytes);
97     if (nbytes == EOF)
98         return EOF;
99     else if (nbytes == 0)
100         return EOF;
102     return nbytes;
105 int ZlibBuffer::do_consume_and_inflate(int nbytes)
107     guint8 buf[nbytes];
108     if (consume(buf, nbytes) == EOF)
109         return EOF;
111     GByteArray *gba = inflate(buf, nbytes);
112     copy_to_get(gba->data, gba->len);
114     g_byte_array_free(gba, TRUE);
115     return 1;
118 int ZlibBuffer::consume_and_inflate()
120     return do_consume_and_inflate(BUFSIZE_STREAM);
123 int ZlibBuffer::flush_output()
125     if (pptr() <= pbase())
126         return 0;
127     int len = pptr() - pbase();
128     int nbytes = _urihandle->write(pbase(), len);
129     setp(pbase(), pbase() + BUFSIZE_STREAM);
130     if (len == nbytes)
131         return 0;
132     else
133         return EOF;
136 void ZlibBuffer::init_inflation() throw(ZlibBufferException)
138     memset(&_zs, 0, sizeof(z_stream));
140     _zs.zalloc = Z_NULL;
141     _zs.zfree = Z_NULL;
142     _zs.opaque = Z_NULL;
144     if(inflateInit2(&_zs, -15) != Z_OK) {
145         throw ZlibBufferException();
146     }
150 void ZlibBuffer::reset_inflation() throw(ZlibBufferException)
152     if (inflateReset(&_zs) != Z_OK)
153         throw ZlibBufferException();
156 GByteArray *ZlibBuffer::inflate(guint8 *in_buffer, int nbytes)
158     return do_inflate(in_buffer, nbytes);
161 GByteArray *ZlibBuffer::do_inflate(guint8 *data, int nbytes)
163     GByteArray *gba = g_byte_array_new();
164     guint8 out_buffer[BUFSIZE_STREAM];
166     _zs.avail_in = 0;
167     guint32 crc = crc32(0, Z_NULL, 0);
169     if (!_zs.avail_in) {
170         _zs.avail_in = nbytes;
171         _zs.next_in = (Bytef *)data;
172         crc = crc32(crc, (Bytef *)data, _zs.avail_in);
173     }
174     do {
175         _zs.next_out = out_buffer;
176         _zs.avail_out = BUFSIZE_STREAM;
178         int ret = ::inflate(&_zs, Z_NO_FLUSH);
179         if (BUFSIZE_STREAM != _zs.avail_out) {
180             unsigned int tmp_len = BUFSIZE_STREAM - _zs.avail_out;
181             g_byte_array_append(gba, out_buffer, tmp_len);
182         }
183         
184         if (ret == Z_STREAM_END) {
185             break;
186         }
187         if (ret != Z_OK) {
188             std::fprintf(stderr, "decompression error %d\n", ret);
189             break;
190         }
191     } while (_zs.avail_in);
193     return gba;
196 int ZlibBuffer::copy_to_get(guint8 *data, int nbytes)
198     return do_copy_to_get(data, nbytes);
201 int ZlibBuffer::do_copy_to_get(guint8 *data, int nbytes)
203     if (nbytes + gptr() - eback() > _getsize)
204         reallocate_buffers(nbytes + gptr() - eback() + BUFSIZE_STREAM,
205                            _putsize);
207     std::memcpy(gptr(), data, nbytes);
208     setg(eback(), gptr(), gptr() + nbytes);
209     return 1;
212 } // namespace Inkscape
214 /*
215   Local Variables:
216   mode:c++
217   c-file-style:"stroustrup"
218   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
219   indent-tabs-mode:nil
220   fill-column:99
221   End:
222 */
223 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :