diff options
author | lloyd <[email protected]> | 2006-05-18 18:33:19 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2006-05-18 18:33:19 +0000 |
commit | a2c99d3270eb73ef2db5704fc54356c6b75096f8 (patch) | |
tree | ad3d6c4fcc8dd0f403f8105598943616246fe172 /modules/comp_zlib |
Initial checkin1.5.6
Diffstat (limited to 'modules/comp_zlib')
-rw-r--r-- | modules/comp_zlib/modinfo.txt | 16 | ||||
-rw-r--r-- | modules/comp_zlib/zlib.cpp | 266 | ||||
-rw-r--r-- | modules/comp_zlib/zlib.h | 55 |
3 files changed, 337 insertions, 0 deletions
diff --git a/modules/comp_zlib/modinfo.txt b/modules/comp_zlib/modinfo.txt new file mode 100644 index 000000000..32acec513 --- /dev/null +++ b/modules/comp_zlib/modinfo.txt @@ -0,0 +1,16 @@ +realname "Zlib Compressor" +#realname "Zlib/Gzip Compressor" + +uses_external_libs + +define COMPRESSOR_ZLIB +#define COMPRESSOR_GZIP + +add_file zlib.h +add_file zlib.cpp +#add_file gzip.h +#add_file gzip.cpp + +<libs> +all -> z +</libs> diff --git a/modules/comp_zlib/zlib.cpp b/modules/comp_zlib/zlib.cpp new file mode 100644 index 000000000..8bbafcea2 --- /dev/null +++ b/modules/comp_zlib/zlib.cpp @@ -0,0 +1,266 @@ +/************************************************* +* Zlib Compressor Source File * +* (C) 1999-2006 The Botan Project * +*************************************************/ + +#include <botan/zlib.h> +#include <cstring> +#include <map> +#include <zlib.h> + +namespace Botan { + +namespace { + +/************************************************* +* Allocation Information for Zlib * +*************************************************/ +class Zlib_Alloc_Info + { + public: + std::map<void*, u32bit> current_allocs; + Allocator* alloc; + + Zlib_Alloc_Info() { alloc = get_allocator(); } + }; + +/************************************************* +* Allocation Function for Zlib * +*************************************************/ +void* zlib_malloc(void* info_ptr, unsigned int n, unsigned int size) + { + Zlib_Alloc_Info* info = static_cast<Zlib_Alloc_Info*>(info_ptr); + void* ptr = info->alloc->allocate(n * size); + info->current_allocs[ptr] = n * size; + return ptr; + } + +/************************************************* +* Allocation Function for Zlib * +*************************************************/ +void zlib_free(void* info_ptr, void* ptr) + { + Zlib_Alloc_Info* info = static_cast<Zlib_Alloc_Info*>(info_ptr); + std::map<void*, u32bit>::const_iterator i = info->current_allocs.find(ptr); + if(i == info->current_allocs.end()) + throw Invalid_Argument("zlib_free: Got pointer not allocated by us"); + info->alloc->deallocate(ptr, i->second); + } + +} + +/************************************************* +* Wrapper Type for Zlib z_stream * +*************************************************/ +class Zlib_Stream + { + public: + z_stream stream; + + Zlib_Stream() + { + std::memset(&stream, 0, sizeof(z_stream)); + stream.zalloc = zlib_malloc; + stream.zfree = zlib_free; + stream.opaque = new Zlib_Alloc_Info; + } + ~Zlib_Stream() + { + Zlib_Alloc_Info* info = static_cast<Zlib_Alloc_Info*>(stream.opaque); + delete info; + std::memset(&stream, 0, sizeof(z_stream)); + } + }; + +/************************************************* +* Zlib_Compression Constructor * +*************************************************/ +Zlib_Compression::Zlib_Compression(u32bit l) : + level((l >= 9) ? 9 : l), buffer(DEFAULT_BUFFERSIZE) + { + zlib = 0; + } + +/************************************************* +* Start Compressing with Zlib * +*************************************************/ +void Zlib_Compression::start_msg() + { + clear(); + zlib = new Zlib_Stream; + if(deflateInit(&(zlib->stream), level) != Z_OK) + throw Exception("Zlib_Compression: Memory allocation error"); + } + +/************************************************* +* Compress Input with Zlib * +*************************************************/ +void Zlib_Compression::write(const byte input[], u32bit length) + { + zlib->stream.next_in = (Bytef*)input; + zlib->stream.avail_in = length; + + while(zlib->stream.avail_in != 0) + { + zlib->stream.next_out = (Bytef*)buffer.begin(); + zlib->stream.avail_out = buffer.size(); + deflate(&(zlib->stream), Z_NO_FLUSH); + send(buffer.begin(), buffer.size() - zlib->stream.avail_out); + } + } + +/************************************************* +* Finish Compressing with Zlib * +*************************************************/ +void Zlib_Compression::end_msg() + { + zlib->stream.next_in = 0; + zlib->stream.avail_in = 0; + + int rc = Z_OK; + while(rc != Z_STREAM_END) + { + zlib->stream.next_out = (Bytef*)buffer.begin(); + zlib->stream.avail_out = buffer.size(); + rc = deflate(&(zlib->stream), Z_FINISH); + send(buffer.begin(), buffer.size() - zlib->stream.avail_out); + } + clear(); + } + +/************************************************* +* Flush the Zlib Compressor * +*************************************************/ +void Zlib_Compression::flush() + { + zlib->stream.next_in = 0; + zlib->stream.avail_in = 0; + + while(true) + { + zlib->stream.next_out = (Bytef*)buffer.begin(); + zlib->stream.avail_out = buffer.size(); + deflate(&(zlib->stream), Z_FULL_FLUSH); + send(buffer.begin(), buffer.size() - zlib->stream.avail_out); + if(zlib->stream.avail_out == buffer.size()) break; + } + } + +/************************************************* +* Clean up Compression Context * +*************************************************/ +void Zlib_Compression::clear() + { + if(zlib) + { + deflateEnd(&(zlib->stream)); + delete zlib; + zlib = 0; + } + + buffer.clear(); + } + +/************************************************* +* Zlib_Decompression Constructor * +*************************************************/ +Zlib_Decompression::Zlib_Decompression() : buffer(DEFAULT_BUFFERSIZE) + { + zlib = 0; + no_writes = true; + } + +/************************************************* +* Start Decompressing with Zlib * +*************************************************/ +void Zlib_Decompression::start_msg() + { + clear(); + zlib = new Zlib_Stream; + if(inflateInit(&(zlib->stream)) != Z_OK) + throw Exception("Zlib_Decompression: Memory allocation error"); + } + +/************************************************* +* Decompress Input with Zlib * +*************************************************/ +void Zlib_Decompression::write(const byte input[], u32bit length) + { + if(length) no_writes = false; + + zlib->stream.next_in = (Bytef*)input; + zlib->stream.avail_in = length; + + while(zlib->stream.avail_in != 0) + { + zlib->stream.next_out = (Bytef*)buffer.begin(); + zlib->stream.avail_out = buffer.size(); + + int rc = inflate(&(zlib->stream), Z_SYNC_FLUSH); + if(rc != Z_OK && rc != Z_STREAM_END) + { + clear(); + if(rc == Z_DATA_ERROR) + throw Decoding_Error("Zlib_Decompression: Data integrity error"); + if(rc == Z_NEED_DICT) + throw Decoding_Error("Zlib_Decompression: Need preset dictionary"); + if(rc == Z_MEM_ERROR) + throw Exception("Zlib_Decompression: Memory allocation error"); + throw Exception("Zlib_Decompression: Unknown decompress error"); + } + send(buffer.begin(), buffer.size() - zlib->stream.avail_out); + if(rc == Z_STREAM_END) + { + u32bit read_from_block = length - zlib->stream.avail_in; + start_msg(); + zlib->stream.next_in = (Bytef*)input + read_from_block; + zlib->stream.avail_in = length - read_from_block; + input += read_from_block; + length -= read_from_block; + } + } + } + +/************************************************* +* Finish Decompressing with Zlib * +*************************************************/ +void Zlib_Decompression::end_msg() + { + if(no_writes) return; + zlib->stream.next_in = 0; + zlib->stream.avail_in = 0; + + int rc = Z_OK; + while(rc != Z_STREAM_END) + { + zlib->stream.next_out = (Bytef*)buffer.begin(); + zlib->stream.avail_out = buffer.size(); + rc = inflate(&(zlib->stream), Z_SYNC_FLUSH); + if(rc != Z_OK && rc != Z_STREAM_END) + { + clear(); + throw Exception("Zlib_Decompression: Error finalizing decompression"); + } + send(buffer.begin(), buffer.size() - zlib->stream.avail_out); + } + clear(); + } + +/************************************************* +* Clean up Decompression Context * +*************************************************/ +void Zlib_Decompression::clear() + { + no_writes = true; + + if(zlib) + { + inflateEnd(&(zlib->stream)); + delete zlib; + zlib = 0; + } + + buffer.clear(); + } + +} diff --git a/modules/comp_zlib/zlib.h b/modules/comp_zlib/zlib.h new file mode 100644 index 000000000..1557afaab --- /dev/null +++ b/modules/comp_zlib/zlib.h @@ -0,0 +1,55 @@ +/************************************************* +* Zlib Compressor Header File * +* (C) 1999-2006 The Botan Project * +*************************************************/ + +#ifndef BOTAN_EXT_ZLIB_H__ +#define BOTAN_EXT_ZLIB_H__ + +#include <botan/filter.h> + +namespace Botan { + +/************************************************* +* Zlib Compression Filter * +*************************************************/ +class Zlib_Compression : public Filter + { + public: + void write(const byte input[], u32bit length); + void start_msg(); + void end_msg(); + + void flush(); + + Zlib_Compression(u32bit = 6); + ~Zlib_Compression() { clear(); } + private: + void clear(); + const u32bit level; + SecureVector<byte> buffer; + class Zlib_Stream* zlib; + }; + +/************************************************* +* Zlib Decompression Filter * +*************************************************/ +class Zlib_Decompression : public Filter + { + public: + void write(const byte input[], u32bit length); + void start_msg(); + void end_msg(); + + Zlib_Decompression(); + ~Zlib_Decompression() { clear(); } + private: + void clear(); + SecureVector<byte> buffer; + class Zlib_Stream* zlib; + bool no_writes; + }; + +} + +#endif |