aboutsummaryrefslogtreecommitdiffstats
path: root/modules/compression/zlib/zlib.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-09-28 15:34:09 +0000
committerlloyd <[email protected]>2008-09-28 15:34:09 +0000
commitea32d18231b9c6c5c84b3754c4249170d3b4e4c0 (patch)
treecc179337d0594ed105768011722b9dbae105e07a /modules/compression/zlib/zlib.cpp
parentb841401e095cfc1aa0708689d7920eb95ece71af (diff)
This is the first checkin to net.randombit.botan.modularized, which
has the intent of modularizing Botan's source code, and making it much easier to add or remove various things at compile time. In this first checkin: Add support for nested directories in modules/ and move all the modules into grouped directories like entropy/ or compression/ Currently this is not ideal, it will _only_ find code in modules/*/*/modinfo.txt, while it would be much better to allow for arbitrary nestings under modules (find modules -name modinfo.txt) for more complicated setups. This 'new' (OMG I've found directories!) structure allows for a more free naming convention (no need for leading es_, ml_, etc to group names, though some keep it for lack of a more meaningful name being obvious to me right at the moment).
Diffstat (limited to 'modules/compression/zlib/zlib.cpp')
-rw-r--r--modules/compression/zlib/zlib.cpp283
1 files changed, 283 insertions, 0 deletions
diff --git a/modules/compression/zlib/zlib.cpp b/modules/compression/zlib/zlib.cpp
new file mode 100644
index 000000000..36a9640e3
--- /dev/null
+++ b/modules/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();
+ }
+
+}