diff options
Diffstat (limited to 'src/compression')
-rw-r--r-- | src/compression/bzip2/bzip2.cpp | 271 | ||||
-rw-r--r-- | src/compression/bzip2/bzip2.h | 59 | ||||
-rw-r--r-- | src/compression/bzip2/modinfo.txt | 17 | ||||
-rw-r--r-- | src/compression/zlib/modinfo.txt | 19 | ||||
-rw-r--r-- | src/compression/zlib/zlib.cpp | 283 | ||||
-rw-r--r-- | src/compression/zlib/zlib.h | 56 |
6 files changed, 705 insertions, 0 deletions
diff --git a/src/compression/bzip2/bzip2.cpp b/src/compression/bzip2/bzip2.cpp new file mode 100644 index 000000000..712dacd7d --- /dev/null +++ b/src/compression/bzip2/bzip2.cpp @@ -0,0 +1,271 @@ +/************************************************* +* Bzip Compressor Source File * +* (C) 2001 Peter J Jones * +* 2001-2007 Jack Lloyd * +* 2006 Matt Johnston * +*************************************************/ + +#include <botan/bzip2.h> +#include <map> +#include <cstring> +#define BZ_NO_STDIO +#include <bzlib.h> + +namespace Botan { + +namespace { + +/************************************************* +* Allocation Information for Bzip * +*************************************************/ +class Bzip_Alloc_Info + { + public: + std::map<void*, u32bit> current_allocs; + Allocator* alloc; + + Bzip_Alloc_Info() { alloc = Allocator::get(false); } + }; + +/************************************************* +* Allocation Function for Bzip * +*************************************************/ +void* bzip_malloc(void* info_ptr, int n, int size) + { + Bzip_Alloc_Info* info = static_cast<Bzip_Alloc_Info*>(info_ptr); + void* ptr = info->alloc->allocate(n * size); + info->current_allocs[ptr] = n * size; + return ptr; + } + +/************************************************* +* Allocation Function for Bzip * +*************************************************/ +void bzip_free(void* info_ptr, void* ptr) + { + Bzip_Alloc_Info* info = static_cast<Bzip_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("bzip_free: Got pointer not allocated by us"); + info->alloc->deallocate(ptr, i->second); + } + +} + +/************************************************* +* Wrapper Type for Bzip2 Stream * +*************************************************/ +class Bzip_Stream + { + public: + bz_stream stream; + + Bzip_Stream() + { + std::memset(&stream, 0, sizeof(bz_stream)); + stream.bzalloc = bzip_malloc; + stream.bzfree = bzip_free; + stream.opaque = new Bzip_Alloc_Info; + } + ~Bzip_Stream() + { + Bzip_Alloc_Info* info = static_cast<Bzip_Alloc_Info*>(stream.opaque); + delete info; + std::memset(&stream, 0, sizeof(bz_stream)); + } + }; + +/************************************************* +* Bzip_Compression Constructor * +*************************************************/ +Bzip_Compression::Bzip_Compression(u32bit l) : + level((l >= 9) ? 9 : l), buffer(DEFAULT_BUFFERSIZE) + { + bz = 0; + } + +/************************************************* +* Start Compressing with Bzip * +*************************************************/ +void Bzip_Compression::start_msg() + { + clear(); + bz = new Bzip_Stream; + if(BZ2_bzCompressInit(&(bz->stream), level, 0, 0) != BZ_OK) + throw Exception("Bzip_Compression: Memory allocation error"); + } + +/************************************************* +* Compress Input with Bzip * +*************************************************/ +void Bzip_Compression::write(const byte input[], u32bit length) + { + bz->stream.next_in = reinterpret_cast<char*>(const_cast<byte*>(input)); + bz->stream.avail_in = length; + + while(bz->stream.avail_in != 0) + { + bz->stream.next_out = reinterpret_cast<char*>(buffer.begin()); + bz->stream.avail_out = buffer.size(); + BZ2_bzCompress(&(bz->stream), BZ_RUN); + send(buffer, buffer.size() - bz->stream.avail_out); + } + } + +/************************************************* +* Finish Compressing with Bzip * +*************************************************/ +void Bzip_Compression::end_msg() + { + bz->stream.next_in = 0; + bz->stream.avail_in = 0; + + int rc = BZ_OK; + while(rc != BZ_STREAM_END) + { + bz->stream.next_out = reinterpret_cast<char*>(buffer.begin()); + bz->stream.avail_out = buffer.size(); + rc = BZ2_bzCompress(&(bz->stream), BZ_FINISH); + send(buffer, buffer.size() - bz->stream.avail_out); + } + clear(); + } + +/************************************************* +* Flush the Bzip Compressor * +*************************************************/ +void Bzip_Compression::flush() + { + bz->stream.next_in = 0; + bz->stream.avail_in = 0; + + int rc = BZ_OK; + while(rc != BZ_RUN_OK) + { + bz->stream.next_out = reinterpret_cast<char*>(buffer.begin()); + bz->stream.avail_out = buffer.size(); + rc = BZ2_bzCompress(&(bz->stream), BZ_FLUSH); + send(buffer, buffer.size() - bz->stream.avail_out); + } + } + +/************************************************* +* Clean up Compression Context * +*************************************************/ +void Bzip_Compression::clear() + { + if(!bz) return; + BZ2_bzCompressEnd(&(bz->stream)); + delete bz; + bz = 0; + } + +/************************************************* +* Bzip_Decompression Constructor * +*************************************************/ +Bzip_Decompression::Bzip_Decompression(bool s) : + small_mem(s), buffer(DEFAULT_BUFFERSIZE) + { + no_writes = true; + bz = 0; + } + +/************************************************* +* Decompress Input with Bzip * +*************************************************/ +void Bzip_Decompression::write(const byte input_arr[], u32bit length) + { + if(length) no_writes = false; + + char* input = reinterpret_cast<char*>(const_cast<byte*>(input_arr)); + + bz->stream.next_in = input; + bz->stream.avail_in = length; + + while(bz->stream.avail_in != 0) + { + bz->stream.next_out = reinterpret_cast<char*>(buffer.begin()); + bz->stream.avail_out = buffer.size(); + + int rc = BZ2_bzDecompress(&(bz->stream)); + + if(rc != BZ_OK && rc != BZ_STREAM_END) + { + clear(); + if(rc == BZ_DATA_ERROR) + throw Decoding_Error("Bzip_Decompression: Data integrity error"); + if(rc == BZ_DATA_ERROR_MAGIC) + throw Decoding_Error("Bzip_Decompression: Invalid input"); + if(rc == BZ_MEM_ERROR) + throw Exception("Bzip_Decompression: Memory allocation error"); + throw Exception("Bzip_Decompression: Unknown decompress error"); + } + + send(buffer, buffer.size() - bz->stream.avail_out); + + if(rc == BZ_STREAM_END) + { + u32bit read_from_block = length - bz->stream.avail_in; + start_msg(); + bz->stream.next_in = input + read_from_block; + bz->stream.avail_in = length - read_from_block; + input += read_from_block; + length -= read_from_block; + } + } + } + +/************************************************* +* Start Decompressing with Bzip * +*************************************************/ +void Bzip_Decompression::start_msg() + { + clear(); + bz = new Bzip_Stream; + + if(BZ2_bzDecompressInit(&(bz->stream), 0, small_mem) != BZ_OK) + throw Exception("Bzip_Decompression: Memory allocation error"); + + no_writes = true; + } + +/************************************************* +* Finish Decompressing with Bzip * +*************************************************/ +void Bzip_Decompression::end_msg() + { + if(no_writes) return; + bz->stream.next_in = 0; + bz->stream.avail_in = 0; + + int rc = BZ_OK; + while(rc != BZ_STREAM_END) + { + bz->stream.next_out = reinterpret_cast<char*>(buffer.begin()); + bz->stream.avail_out = buffer.size(); + rc = BZ2_bzDecompress(&(bz->stream)); + + if(rc != BZ_OK && rc != BZ_STREAM_END) + { + clear(); + throw Exception("Bzip_Decompression: Error finalizing decompression"); + } + + send(buffer, buffer.size() - bz->stream.avail_out); + } + + clear(); + } + +/************************************************* +* Clean up Decompression Context * +*************************************************/ +void Bzip_Decompression::clear() + { + if(!bz) return; + BZ2_bzDecompressEnd(&(bz->stream)); + delete bz; + bz = 0; + } + +} diff --git a/src/compression/bzip2/bzip2.h b/src/compression/bzip2/bzip2.h new file mode 100644 index 000000000..1244924ca --- /dev/null +++ b/src/compression/bzip2/bzip2.h @@ -0,0 +1,59 @@ +/************************************************* +* Bzip Compressor Header File * +* (C) 2001 Peter J Jones * +* 2001-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_BZIP2_H__ +#define BOTAN_BZIP2_H__ + +#include <botan/filter.h> + +namespace Botan { + +/************************************************* +* Bzip Compression Filter * +*************************************************/ +class Bzip_Compression : public Filter + { + public: + void write(const byte input[], u32bit length); + void start_msg(); + void end_msg(); + + void flush(); + + Bzip_Compression(u32bit = 9); + ~Bzip_Compression() { clear(); } + private: + void clear(); + + const u32bit level; + SecureVector<byte> buffer; + class Bzip_Stream* bz; + }; + +/************************************************* +* Bzip Decompression Filter * +*************************************************/ +class Bzip_Decompression : public Filter + { + public: + void write(const byte input[], u32bit length); + void start_msg(); + void end_msg(); + + Bzip_Decompression(bool = false); + ~Bzip_Decompression() { clear(); } + private: + void clear(); + + const bool small_mem; + SecureVector<byte> buffer; + class Bzip_Stream* bz; + bool no_writes; + }; + +} + +#endif diff --git a/src/compression/bzip2/modinfo.txt b/src/compression/bzip2/modinfo.txt new file mode 100644 index 000000000..efedc097f --- /dev/null +++ b/src/compression/bzip2/modinfo.txt @@ -0,0 +1,17 @@ +# This module was written by Peter J. Jones + +realname "Bzip2 Compressor" + +define COMPRESSOR_BZIP2 +modset compression + +load_on request + +<add> +bzip2.h +bzip2.cpp +</add> + +<libs> +all -> bz2 +</libs> diff --git a/src/compression/zlib/modinfo.txt b/src/compression/zlib/modinfo.txt new file mode 100644 index 000000000..c1f1f998c --- /dev/null +++ b/src/compression/zlib/modinfo.txt @@ -0,0 +1,19 @@ +realname "Zlib Compressor" +#realname "Zlib/Gzip Compressor" + +define COMPRESSOR_ZLIB +#define COMPRESSOR_ZLIB,COMPRESSOR_GZIP + +load_on request +modset compression + +<add> +zlib.h +zlib.cpp +#gzip.h +#gzip.cpp +</add> + +<libs> +all -> z +</libs> diff --git a/src/compression/zlib/zlib.cpp b/src/compression/zlib/zlib.cpp new file mode 100644 index 000000000..36a9640e3 --- /dev/null +++ b/src/compression/zlib/zlib.cpp @@ -0,0 +1,283 @@ +/************************************************* +* Zlib Compressor Source File * +* (C) 2001 Peter J Jones * +* 2001-2007 Jack Lloyd * +* 2006 Matt Johnston * +*************************************************/ + +#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 = Allocator::get(false); } + }; + +/************************************************* +* 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 = static_cast<Bytef*>(const_cast<byte*>(input)); + zlib->stream.avail_in = length; + + while(zlib->stream.avail_in != 0) + { + zlib->stream.next_out = static_cast<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 = reinterpret_cast<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.avail_out = buffer.size(); + + zlib->stream.next_out = reinterpret_cast<Bytef*>(buffer.begin()); + + + 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_arr[], u32bit length) + { + if(length) no_writes = false; + + // non-const needed by zlib api :( + Bytef* input = reinterpret_cast<Bytef*>(const_cast<byte*>(input_arr)); + + zlib->stream.next_in = input; + zlib->stream.avail_in = length; + + while(zlib->stream.avail_in != 0) + { + zlib->stream.next_out = reinterpret_cast<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 = 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 = reinterpret_cast<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/src/compression/zlib/zlib.h b/src/compression/zlib/zlib.h new file mode 100644 index 000000000..c3baea4ee --- /dev/null +++ b/src/compression/zlib/zlib.h @@ -0,0 +1,56 @@ +/************************************************* +* Zlib Compressor Header File * +* (C) 2001 Peter J Jones * +* 2001-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_ZLIB_H__ +#define BOTAN_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 |