summaryrefslogtreecommitdiff
path: root/distfoldd/compressor.cc
diff options
context:
space:
mode:
Diffstat (limited to 'distfoldd/compressor.cc')
-rw-r--r--distfoldd/compressor.cc94
1 files changed, 94 insertions, 0 deletions
diff --git a/distfoldd/compressor.cc b/distfoldd/compressor.cc
new file mode 100644
index 0000000..98eaa92
--- /dev/null
+++ b/distfoldd/compressor.cc
@@ -0,0 +1,94 @@
+#include <QtCore/QDebug>
+
+#include <zlib.h>
+#include "compressor.h"
+
+Compressor::Compressor()
+{
+}
+
+QByteArray Compressor::compress(const QByteArray& data)
+{
+ if (data.isEmpty()) return data;
+
+ QByteArray in = data, out;
+ z_stream strm;
+ int ret;
+
+ memset(&strm, 0, sizeof(strm));
+ out.resize(qMax(in.size(), 1024));
+
+ strm.avail_in = in.size();
+ strm.next_in = reinterpret_cast<Bytef*>(in.data());
+ strm.avail_out = out.size();
+ strm.next_out = reinterpret_cast<Bytef*>(out.data());
+
+ ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
+ if (ret != Z_OK) {
+ qWarning() << "deflateInit failed";
+ return data;
+ }
+
+ do {
+ if (strm.avail_out == 0) {
+ int cur_size = out.size();
+ out.resize(cur_size * 2);
+ strm.avail_out = cur_size;
+ strm.next_out = reinterpret_cast<Bytef*>(&out.data()[cur_size]);
+ }
+ ret = deflate(&strm, Z_FINISH);
+ } while (ret == Z_OK || ret == Z_BUF_ERROR);
+
+ Q_ASSERT(ret == Z_STREAM_END);
+ Q_ASSERT(strm.avail_in == 0);
+ if (strm.avail_out > 0) {
+ out.resize(out.size() - strm.avail_out);
+ }
+
+ deflateEnd(&strm);
+
+ return out;
+}
+
+QByteArray Compressor::decompress(const QByteArray& data)
+{
+ if (data.isEmpty()) return data;
+
+ QByteArray in = data, out;
+ z_stream strm;
+ int ret;
+
+ memset(&strm, 0, sizeof(strm));
+ out.resize(qMax(static_cast<int>(in.size() * 1.5), 1024));
+
+ strm.avail_in = in.size();
+ strm.next_in = reinterpret_cast<Bytef*>(in.data());
+ strm.avail_out = out.size();
+ strm.next_out = reinterpret_cast<Bytef*>(out.data());
+
+ ret = inflateInit(&strm);
+ if (ret != Z_OK) {
+ qWarning() << "inflateInit failed";
+ return data;
+ }
+
+ do {
+ if (strm.avail_out == 0) {
+ int cur_size = out.size();
+ out.resize(cur_size * 2);
+ strm.avail_out = cur_size;
+ strm.next_out = reinterpret_cast<Bytef*>(&out.data()[cur_size]);
+ }
+ ret = inflate(&strm, Z_FINISH);
+ } while (ret == Z_OK || ret == Z_BUF_ERROR);
+
+ Q_ASSERT(ret == Z_STREAM_END);
+ Q_ASSERT(strm.avail_in == 0);
+ if (strm.avail_out > 0) {
+ out.resize(out.size() - strm.avail_out);
+ }
+
+ inflateEnd(&strm);
+
+ return out;
+}