summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Compress')
-rw-r--r--Swiften/Compress/UnitTest/ZLibCompressorTest.cpp35
-rw-r--r--Swiften/Compress/UnitTest/ZLibDecompressorTest.cpp71
-rw-r--r--Swiften/Compress/ZLibCodecompressor.cpp43
-rw-r--r--Swiften/Compress/ZLibCodecompressor.h22
-rw-r--r--Swiften/Compress/ZLibCompressor.h31
-rw-r--r--Swiften/Compress/ZLibDecompressor.h28
-rw-r--r--Swiften/Compress/ZLibException.h11
7 files changed, 241 insertions, 0 deletions
diff --git a/Swiften/Compress/UnitTest/ZLibCompressorTest.cpp b/Swiften/Compress/UnitTest/ZLibCompressorTest.cpp
new file mode 100644
index 0000000..7235f8e
--- /dev/null
+++ b/Swiften/Compress/UnitTest/ZLibCompressorTest.cpp
@@ -0,0 +1,35 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Compress/ZLibCompressor.h"
+
+using namespace Swift;
+
+
+class ZLibCompressorTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(ZLibCompressorTest);
+ CPPUNIT_TEST(testProcess);
+ CPPUNIT_TEST(testProcess_Twice);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ ZLibCompressorTest() {}
+
+ void testProcess() {
+ ZLibCompressor testling;
+ ByteArray result = testling.process("foo");
+
+ CPPUNIT_ASSERT_EQUAL(ByteArray("\x78\xda\x4a\xcb\xcf\x07\x00\x00\x00\xff\xff", 11), result);
+ }
+
+ void testProcess_Twice() {
+ ZLibCompressor testling;
+ testling.process("foo");
+ ByteArray result = testling.process("bar");
+
+ CPPUNIT_ASSERT_EQUAL(ByteArray("\x4a\x4a\x2c\x02\x00\x00\x00\xff\xff",9), result);
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ZLibCompressorTest);
diff --git a/Swiften/Compress/UnitTest/ZLibDecompressorTest.cpp b/Swiften/Compress/UnitTest/ZLibDecompressorTest.cpp
new file mode 100644
index 0000000..871a630
--- /dev/null
+++ b/Swiften/Compress/UnitTest/ZLibDecompressorTest.cpp
@@ -0,0 +1,71 @@
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "Swiften/Compress/ZLibDecompressor.h"
+#include "Swiften/Compress/ZLibCompressor.h"
+#include "Swiften/Compress/ZLibException.h"
+
+using namespace Swift;
+
+
+class ZLibDecompressorTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(ZLibDecompressorTest);
+ CPPUNIT_TEST(testProcess);
+ CPPUNIT_TEST(testProcess_Twice);
+ CPPUNIT_TEST(testProcess_Invalid);
+ CPPUNIT_TEST(testProcess_Huge);
+ CPPUNIT_TEST(testProcess_ChunkSize);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ ZLibDecompressorTest() {}
+
+ void testProcess() {
+ ZLibDecompressor testling;
+ ByteArray result = testling.process(ByteArray("\x78\xda\x4a\xcb\xcf\x07\x00\x00\x00\xff\xff", 11));
+
+ CPPUNIT_ASSERT_EQUAL(ByteArray("foo"), result);
+ }
+
+ void testProcess_Twice() {
+ ZLibDecompressor testling;
+ testling.process(ByteArray("\x78\xda\x4a\xcb\xcf\x07\x00\x00\x00\xff\xff", 11));
+ ByteArray result = testling.process(ByteArray("\x4a\x4a\x2c\x02\x00\x00\x00\xff\xff", 9));
+
+ CPPUNIT_ASSERT_EQUAL(ByteArray("bar"), result);
+ }
+
+ void testProcess_Invalid() {
+ ZLibDecompressor testling;
+ CPPUNIT_ASSERT_THROW(testling.process(ByteArray("invalid")), ZLibException);
+ }
+
+ void testProcess_Huge() {
+ std::vector<char> data;
+ data.reserve(2048);
+ for (unsigned int i = 0; i < 2048; ++i) {
+ data.push_back(static_cast<char>(i));
+ }
+ ByteArray original(&data[0], data.size());
+ ByteArray compressed = ZLibCompressor().process(original);
+ ByteArray decompressed = ZLibDecompressor().process(compressed);
+
+ CPPUNIT_ASSERT_EQUAL(original, decompressed);
+ }
+
+ void testProcess_ChunkSize() {
+ std::vector<char> data;
+ data.reserve(1024);
+ for (unsigned int i = 0; i < 1024; ++i) {
+ data.push_back(static_cast<char>(i));
+ }
+ ByteArray original(&data[0], data.size());
+ ByteArray compressed = ZLibCompressor().process(original);
+ ByteArray decompressed = ZLibDecompressor().process(compressed);
+
+ CPPUNIT_ASSERT_EQUAL(original, decompressed);
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ZLibDecompressorTest);
diff --git a/Swiften/Compress/ZLibCodecompressor.cpp b/Swiften/Compress/ZLibCodecompressor.cpp
new file mode 100644
index 0000000..a14f09d
--- /dev/null
+++ b/Swiften/Compress/ZLibCodecompressor.cpp
@@ -0,0 +1,43 @@
+#include "Swiften/Compress/ZLibCodecompressor.h"
+
+#include <cassert>
+
+#include "Swiften/Compress/ZLibException.h"
+
+namespace Swift {
+
+static const int CHUNK_SIZE = 1024; // If you change this, also change the unittest
+
+ZLibCodecompressor::ZLibCodecompressor() {
+ stream_.zalloc = Z_NULL;
+ stream_.zfree = Z_NULL;
+ stream_.opaque = Z_NULL;
+}
+
+ZLibCodecompressor::~ZLibCodecompressor() {
+}
+
+ByteArray ZLibCodecompressor::process(const ByteArray& input) {
+ ByteArray output;
+ stream_.avail_in = input.getSize();
+ stream_.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(input.getData()));
+ int outputPosition = 0;
+ do {
+ output.resize(outputPosition + CHUNK_SIZE);
+ stream_.avail_out = CHUNK_SIZE;
+ stream_.next_out = reinterpret_cast<Bytef*>(output.getData() + outputPosition);
+ int result = processZStream();
+ if (result != Z_OK && result != Z_BUF_ERROR) {
+ throw ZLibException(/* stream_.msg */);
+ }
+ outputPosition += CHUNK_SIZE;
+ }
+ while (stream_.avail_out == 0);
+ if (stream_.avail_in != 0) {
+ throw ZLibException();
+ }
+ output.resize(outputPosition - stream_.avail_out);
+ return output;
+}
+
+}
diff --git a/Swiften/Compress/ZLibCodecompressor.h b/Swiften/Compress/ZLibCodecompressor.h
new file mode 100644
index 0000000..dd032fa
--- /dev/null
+++ b/Swiften/Compress/ZLibCodecompressor.h
@@ -0,0 +1,22 @@
+#ifndef SWIFTEN_ZLibCodecompressor_H
+#define SWIFTEN_ZLibCodecompressor_H
+
+#include <zlib.h>
+
+#include "Swiften/Base/ByteArray.h"
+
+namespace Swift {
+ class ZLibCodecompressor {
+ public:
+ ZLibCodecompressor();
+ virtual ~ZLibCodecompressor();
+
+ ByteArray process(const ByteArray& data);
+ virtual int processZStream() = 0;
+
+ protected:
+ z_stream stream_;
+ };
+}
+
+#endif
diff --git a/Swiften/Compress/ZLibCompressor.h b/Swiften/Compress/ZLibCompressor.h
new file mode 100644
index 0000000..b5bace6
--- /dev/null
+++ b/Swiften/Compress/ZLibCompressor.h
@@ -0,0 +1,31 @@
+#ifndef SWIFTEN_ZLibCompressor_H
+#define SWIFTEN_ZLibCompressor_H
+
+#include <cassert>
+
+#include "Swiften/Compress/ZLibCodecompressor.h"
+#include "Swiften/Base/ByteArray.h"
+
+namespace Swift {
+ class ZLibCompressor : public ZLibCodecompressor {
+ public:
+ ZLibCompressor() {
+ int result = deflateInit(&stream_, COMPRESSION_LEVEL);
+ assert(result == Z_OK);
+ (void) result;
+ }
+
+ ~ZLibCompressor() {
+ deflateEnd(&stream_);
+ }
+
+ virtual int processZStream() {
+ return deflate(&stream_, Z_SYNC_FLUSH);
+ }
+
+ private:
+ static const int COMPRESSION_LEVEL = 9;
+ };
+}
+
+#endif
diff --git a/Swiften/Compress/ZLibDecompressor.h b/Swiften/Compress/ZLibDecompressor.h
new file mode 100644
index 0000000..808feb2
--- /dev/null
+++ b/Swiften/Compress/ZLibDecompressor.h
@@ -0,0 +1,28 @@
+#ifndef SWIFTEN_ZLibDecompressor_H
+#define SWIFTEN_ZLibDecompressor_H
+
+#include <cassert>
+
+#include "Swiften/Compress/ZLibCodecompressor.h"
+#include "Swiften/Base/ByteArray.h"
+
+namespace Swift {
+ class ZLibDecompressor : public ZLibCodecompressor {
+ public:
+ ZLibDecompressor() {
+ int result = inflateInit(&stream_);
+ assert(result == Z_OK);
+ (void) result;
+ }
+
+ ~ZLibDecompressor() {
+ inflateEnd(&stream_);
+ }
+
+ virtual int processZStream() {
+ return inflate(&stream_, Z_SYNC_FLUSH);
+ }
+ };
+}
+
+#endif
diff --git a/Swiften/Compress/ZLibException.h b/Swiften/Compress/ZLibException.h
new file mode 100644
index 0000000..f16b4ed
--- /dev/null
+++ b/Swiften/Compress/ZLibException.h
@@ -0,0 +1,11 @@
+#ifndef SWIFTEN_ZLIBEXCEPTION_H
+#define SWIFTEN_ZLIBEXCEPTION_H
+
+namespace Swift {
+ class ZLibException {
+ public:
+ ZLibException() {}
+ };
+}
+
+#endif