From: Christian P. <cp...@us...> - 2005-01-06 16:41:47
|
Update of /cvsroot/pclasses/pclasses2/src/IO In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11357/src/IO Modified Files: ZLib.cpp Log Message: Rework of ZLibStream and ZLibOutputStream. Added ZLibInputStream. Index: ZLib.cpp =================================================================== RCS file: /cvsroot/pclasses/pclasses2/src/IO/ZLib.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- ZLib.cpp 3 Jan 2005 13:43:49 -0000 1.1 +++ ZLib.cpp 6 Jan 2005 16:41:38 -0000 1.2 @@ -20,6 +20,7 @@ #include "pclasses/IO/ZLib.h" #include <zlib.h> +#include <iostream> namespace P { @@ -44,12 +45,15 @@ return _msg; } -ZLibStream::ZLibStream() +ZLibStream::ZLibStream(size_t bufferSize) { + if(bufferSize < 1) + bufferSize = 64; + _strm = new z_stream; - _buffer = new char[1024]; - _bufferSize = 1024; - + _buffer = new char[bufferSize]; + _bufferSize = bufferSize; + _strm->zalloc = Z_NULL; _strm->zfree = Z_NULL; _strm->opaque = Z_NULL; @@ -57,8 +61,6 @@ _strm->next_out = (Bytef*)_buffer; _strm->avail_in = 0; _strm->avail_out = _bufferSize; - - _crc32 = ::crc32(0L, Z_NULL, 0); } ZLibStream::~ZLibStream() @@ -72,28 +74,31 @@ return _bufferSize - _strm->avail_out; } -size_t ZLibStream::read(char* buffer, size_t count) throw(ZLibError) +const char* ZLibStream::buffer() const throw() +{ + return (const char*)_strm->next_out - (_bufferSize - _strm->avail_out); +} + +size_t ZLibStream::dequeue(size_t count) throw(ZLibError) { size_t avail = bytesAvail(); if(count > avail) count = avail; - memcpy(buffer, _strm->next_out - avail, count); - // move remaining bytes to top of buffer ... if(count < avail) memmove(_buffer, _strm->next_out - avail + count, avail - count); - _strm->next_out = (Bytef*)_buffer; - _strm->avail_out = _bufferSize; + _strm->next_out -= count; + _strm->avail_out += count; return count; } -UInt32 ZLibStream::crc32() const throw() +UInt32 ZLibStream::adler32() const throw() { - return _crc32; + return _strm->adler; } void ZLibStream::put(const char* buffer, size_t count) throw(ZLibError) @@ -106,97 +111,108 @@ _strm->avail_out -= count; } - -ZLibOutputStream::ZLibOutputStream(int level) throw(ZLibError) -: ZLibStream(), _state(Ready) +ZLibOutputStream::ZLibOutputStream(int level, size_t bufferSize) throw(ZLibError) +: ZLibStream(bufferSize) { int ret; - if((ret = deflateInit(_strm, level)) != Z_OK) + if((ret = ::deflateInit(_strm, level)) != Z_OK) throw ZLibError(ret, _strm->msg, "Could not init zlib deflate", P_SOURCEINFO); - - putFooter(); } ZLibOutputStream::~ZLibOutputStream() throw() { + ::deflateEnd(_strm); } -void ZLibOutputStream::putHeader() +size_t ZLibOutputStream::deflate(const char* buffer, size_t count) throw(ZLibError) { - char header[] = { 0x1f /*magic1*/, 0x8b /*magic2*/, Z_DEFLATED, 0 /*flags*/, - 0, 0, 0, 0 /*time*/, 0 /*xflags*/, 0x03 /* OS code*/ }; + if(!count) + return 0; - put(header, sizeof(header)); + _strm->next_in = (Bytef*)buffer; + _strm->avail_in = count; + + int ret = ::deflate(_strm, Z_NO_FLUSH); + if(ret != Z_OK) + throw ZLibError(ret, _strm->msg, "Could not deflate", P_SOURCEINFO); + + // return with number of bytes consumed ... + size_t deflated = count - _strm->avail_in; + return deflated; } -void ZLibOutputStream::putFooter() +void ZLibOutputStream::sync() throw(ZLibError) { - UInt32 footer[2]; - footer[0] = UInt32(_crc32).littleEndian(); - footer[1] = UInt32(_strm->total_in).littleEndian(); - - put((const char*)footer, sizeof(footer)); + int ret = ::deflate(_strm, Z_SYNC_FLUSH); + if(ret != Z_OK) + throw ZLibError(ret, _strm->msg, "Could not sync stream", P_SOURCEINFO); } -size_t ZLibOutputStream::deflate(const char* buffer, size_t count) throw(ZLibError) +bool ZLibOutputStream::finish() throw(ZLibError) { - if(!count) - return 0; + int ret = ::deflate(_strm, Z_FINISH); + // not enough buffer was avail... should call finish() again + if(ret == Z_OK) + return false; - size_t deflated = 0; + if(ret != Z_STREAM_END) + throw ZLibError(Z_BUF_ERROR, 0, "Could not finish stream", P_SOURCEINFO); - if(_state == Ready) - { - _strm->next_in = (Bytef*)buffer; - _strm->avail_in = count; - - int ret = ::deflate(_strm, Z_NO_FLUSH); - if(ret != Z_OK) - throw ZLibError(ret, _strm->msg, "Could not deflate", P_SOURCEINFO); + return true; +} - // update crc32 and return with number of bytes consumed ... - deflated = count - _strm->avail_in; - _crc32 = ::crc32(_crc32, (const Bytef*)buffer, deflated); - } +void ZLibOutputStream::reset() throw(ZLibError) +{ + _strm->next_out = (Bytef*)_buffer; + _strm->avail_out = _bufferSize; - return deflated; + int ret = ::deflateReset(_strm); + if(ret != Z_OK) + throw ZLibError(ret, _strm->msg, "Could not reset stream", P_SOURCEINFO); } -bool ZLibOutputStream::finish() throw(ZLibError) +ZLibInputStream::ZLibInputStream(size_t bufferSize) throw(ZLibError) +: ZLibStream(bufferSize) { - if(_state < AboutToFinish) - { - int ret = ::deflate(_strm, Z_FINISH); - // not enough buffer was avail... should call finish() again - if(ret == Z_OK) - return false; - - if(ret != Z_STREAM_END) - throw ZLibError(Z_BUF_ERROR, 0, "Could not finish zlib stream", P_SOURCEINFO); - - _state = AboutToFinish; - } + int ret; + if((ret = ::inflateInit(_strm)) != Z_OK) + throw ZLibError(ret, _strm->msg, "Could not init zlib inflate", P_SOURCEINFO); +} - if(_state == AboutToFinish) - { - if(_strm->avail_out < 8) - return false; +ZLibInputStream::~ZLibInputStream() throw() +{ + ::inflateEnd(_strm); +} - putHeader(); - _state = Finished; +size_t ZLibInputStream::inflate(const char* buffer, size_t count) throw(ZLibError) +{ + if(!count) + return 0; + + _strm->next_in = (Bytef*)buffer; + _strm->avail_in = count; + + int ret = ::inflate(_strm, Z_NO_FLUSH); + if(ret == Z_STREAM_END) + { + // we do nothing, so this or next call to inflate() returns 0 } + else if(ret != Z_OK) + throw ZLibError(ret, _strm->msg, "Could not inflate", P_SOURCEINFO); - return true; + // return with number of bytes consumed ... + size_t inflated = count - _strm->avail_in; + return inflated; } -void ZLibOutputStream::reset() throw(ZLibError) +void ZLibInputStream::reset() throw(ZLibError) { _strm->next_out = (Bytef*)_buffer; _strm->avail_out = _bufferSize; - _crc32 = ::crc32(0L, Z_NULL, 0); - _state = Ready; - deflateReset(_strm); + int ret = ::inflateReset(_strm); + if(ret != Z_OK) + throw ZLibError(ret, _strm->msg, "Could not reset stream", P_SOURCEINFO); } |