diff options
Diffstat (limited to 'distfoldd/compressor.cc')
-rw-r--r-- | distfoldd/compressor.cc | 94 |
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; +} |