From 179fa413b047bede6e32109e2ce82437c5fb8d34 Mon Sep 17 00:00:00 2001 From: MenTaLguY Date: Mon, 16 Jan 2006 02:36:01 +0000 Subject: moving trunk for module inkscape (bzr r1) --- src/streams-zlib.cpp | 223 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 src/streams-zlib.cpp (limited to 'src/streams-zlib.cpp') diff --git a/src/streams-zlib.cpp b/src/streams-zlib.cpp new file mode 100644 index 000000000..73106db17 --- /dev/null +++ b/src/streams-zlib.cpp @@ -0,0 +1,223 @@ +/* + * IO layer : zlib streambuf + * + * Authors: + * Johan Ceuppens + * + * Copyright (C) 2004 Johan Ceuppens + * + * Released under GNU LGPL, read the file 'COPYING.LIB' for more information + */ + +#include "streams-zlib.h" + +namespace Inkscape { + +/** + * ZlibBuffer + */ + +ZlibBuffer::ZlibBuffer(URIHandle& urih) + : _urihandle(&urih), _putsize(BUFSIZE_STREAM), _getsize(BUFSIZE_STREAM) +{ + init_inflation(); +} + +int ZlibBuffer::allocate_buffers() +{ + if (!eback()) { + char *buf = new char[_getsize + _putsize]; + setg(buf, buf , buf); + buf += _getsize; + setp(buf, buf + _putsize); + return 1; + } + return 0; +} + +int ZlibBuffer::reallocate_buffers(int new_getsize, int new_putsize) +{ + char *new_buffer = new char[new_getsize + new_putsize]; + + std::memcpy(new_buffer, eback(), _getsize); + std::memcpy(new_buffer, eback() + _getsize, _putsize); + + setg(new_buffer, new_buffer + (gptr() - eback()), + new_buffer + new_getsize); + new_buffer += new_getsize; + setp(new_buffer, new_buffer + new_putsize); + + _getsize = new_getsize; + _putsize = new_putsize; + + return 1; +} + +int ZlibBuffer::underflow() +{ + if (eback() == 0 && allocate_buffers() == 0) + return EOF; + + if (consume_and_inflate() == EOF) + return EOF; + + return *(unsigned char *)gptr(); +} + +int ZlibBuffer::overflow(int c) +{ + if (c == EOF) + return flush_output(); + + if (pbase() == 0 && allocate_buffers() == 0) + return EOF; + + if (pptr() >= epptr() && + flush_output() == EOF) + return EOF; + + putchar(c); + + if (pptr() >= epptr() && + flush_output() == EOF) + return EOF; + + return c; +} + +int ZlibBuffer::consume(guint8 *buf, int nbytes) +{ + return do_consume(buf, nbytes); +} + +int ZlibBuffer::do_consume(guint8 *buf, int nbytes) +{ + nbytes = _urihandle->read(buf, nbytes); + + if (nbytes == EOF) + return EOF; + else if (nbytes == 0) + return EOF; + + return nbytes; +} + +int ZlibBuffer::do_consume_and_inflate(int nbytes) +{ + guint8 buf[nbytes]; + if (consume(buf, nbytes) == EOF) + return EOF; + + GByteArray *gba = inflate(buf, nbytes); + copy_to_get(gba->data, gba->len); + + g_byte_array_free(gba, TRUE); + return 1; +} + +int ZlibBuffer::consume_and_inflate() +{ + return do_consume_and_inflate(BUFSIZE_STREAM); +} + +int ZlibBuffer::flush_output() +{ + if (pptr() <= pbase()) + return 0; + int len = pptr() - pbase(); + int nbytes = _urihandle->write(pbase(), len); + setp(pbase(), pbase() + BUFSIZE_STREAM); + if (len == nbytes) + return 0; + else + return EOF; +} + +void ZlibBuffer::init_inflation() throw(ZlibBufferException) +{ + memset(&_zs, 0, sizeof(z_stream)); + + _zs.zalloc = Z_NULL; + _zs.zfree = Z_NULL; + _zs.opaque = Z_NULL; + + if(inflateInit2(&_zs, -15) != Z_OK) { + throw ZlibBufferException(); + } + +} + +void ZlibBuffer::reset_inflation() throw(ZlibBufferException) +{ + if (inflateReset(&_zs) != Z_OK) + throw ZlibBufferException(); +} + +GByteArray *ZlibBuffer::inflate(guint8 *in_buffer, int nbytes) +{ + return do_inflate(in_buffer, nbytes); +} + +GByteArray *ZlibBuffer::do_inflate(guint8 *data, int nbytes) +{ + GByteArray *gba = g_byte_array_new(); + guint8 out_buffer[BUFSIZE_STREAM]; + + _zs.avail_in = 0; + guint32 crc = crc32(0, Z_NULL, 0); + + if (!_zs.avail_in) { + _zs.avail_in = nbytes; + _zs.next_in = (Bytef *)data; + crc = crc32(crc, (Bytef *)data, _zs.avail_in); + } + do { + _zs.next_out = out_buffer; + _zs.avail_out = BUFSIZE_STREAM; + + int ret = ::inflate(&_zs, Z_NO_FLUSH); + if (BUFSIZE_STREAM != _zs.avail_out) { + unsigned int tmp_len = BUFSIZE_STREAM - _zs.avail_out; + g_byte_array_append(gba, out_buffer, tmp_len); + } + + if (ret == Z_STREAM_END) { + break; + } + if (ret != Z_OK) { + std::fprintf(stderr, "decompression error %d\n", ret); + break; + } + } while (_zs.avail_in); + + return gba; +} + +int ZlibBuffer::copy_to_get(guint8 *data, int nbytes) +{ + return do_copy_to_get(data, nbytes); +} + +int ZlibBuffer::do_copy_to_get(guint8 *data, int nbytes) +{ + if (nbytes + gptr() - eback() > _getsize) + reallocate_buffers(nbytes + gptr() - eback() + BUFSIZE_STREAM, + _putsize); + + std::memcpy(gptr(), data, nbytes); + setg(eback(), gptr(), gptr() + nbytes); + return 1; +} + +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : -- cgit v1.2.3