aboutsummaryrefslogtreecommitdiffstats
path: root/modules/comp_zlib
diff options
context:
space:
mode:
authorlloyd <[email protected]>2006-05-18 18:33:19 +0000
committerlloyd <[email protected]>2006-05-18 18:33:19 +0000
commita2c99d3270eb73ef2db5704fc54356c6b75096f8 (patch)
treead3d6c4fcc8dd0f403f8105598943616246fe172 /modules/comp_zlib
Initial checkin1.5.6
Diffstat (limited to 'modules/comp_zlib')
-rw-r--r--modules/comp_zlib/modinfo.txt16
-rw-r--r--modules/comp_zlib/zlib.cpp266
-rw-r--r--modules/comp_zlib/zlib.h55
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