diff options
Diffstat (limited to 'logic/GZip.cpp')
-rw-r--r-- | logic/GZip.cpp | 76 |
1 files changed, 62 insertions, 14 deletions
diff --git a/logic/GZip.cpp b/logic/GZip.cpp index 5207f3f0..d38d06e2 100644 --- a/logic/GZip.cpp +++ b/logic/GZip.cpp @@ -2,12 +2,6 @@ #include <zlib.h> #include <QByteArray> -// HACK: workaround for terrible macro crap on Windows -int wrap_inflate (z_streamp strm, int flush) -{ - return inflate(strm, flush); -} - bool GZip::decompress(const QByteArray &compressedBytes, QByteArray &uncompressedBytes) { if (compressedBytes.size() == 0) @@ -17,16 +11,13 @@ bool GZip::decompress(const QByteArray &compressedBytes, QByteArray &uncompresse } unsigned uncompLength = compressedBytes.size(); - unsigned half_length = compressedBytes.size() / 2; uncompressedBytes.clear(); uncompressedBytes.resize(uncompLength); z_stream strm; + memset(&strm, 0, sizeof(strm)); strm.next_in = (Bytef *)compressedBytes.data(); strm.avail_in = compressedBytes.size(); - strm.total_out = 0; - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; bool done = false; @@ -35,20 +26,22 @@ bool GZip::decompress(const QByteArray &compressedBytes, QByteArray &uncompresse return false; } + int err = Z_OK; + while (!done) { // If our output buffer is too small if (strm.total_out >= uncompLength) { - uncompressedBytes.resize(uncompLength + half_length); - uncompLength += half_length; + uncompressedBytes.resize(uncompLength * 2); + uncompLength *= 2; } strm.next_out = (Bytef *)(uncompressedBytes.data() + strm.total_out); strm.avail_out = uncompLength - strm.total_out; // Inflate another chunk. - int err = wrap_inflate(&strm, Z_SYNC_FLUSH); + err = inflate(&strm, Z_SYNC_FLUSH); if (err == Z_STREAM_END) done = true; else if (err != Z_OK) @@ -57,7 +50,7 @@ bool GZip::decompress(const QByteArray &compressedBytes, QByteArray &uncompresse } } - if (inflateEnd(&strm) != Z_OK) + if (inflateEnd(&strm) != Z_OK || !done) { return false; } @@ -65,3 +58,58 @@ bool GZip::decompress(const QByteArray &compressedBytes, QByteArray &uncompresse uncompressedBytes.resize(strm.total_out); return true; } + +bool GZip::compress(const QByteArray &uncompressedBytes, QByteArray &compressedBytes) +{ + if (uncompressedBytes.size() == 0) + { + compressedBytes = uncompressedBytes; + return true; + } + + unsigned compLength = std::min(uncompressedBytes.size(), 16); + compressedBytes.clear(); + compressedBytes.resize(compLength); + + z_stream zs; + memset(&zs, 0, sizeof(zs)); + + if (deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16 + MAX_WBITS), 8, Z_DEFAULT_STRATEGY) != Z_OK) + { + return false; + } + + zs.next_in = (Bytef*)uncompressedBytes.data(); + zs.avail_in = uncompressedBytes.size(); + + int ret; + compressedBytes.resize(uncompressedBytes.size()); + + unsigned offset = 0; + unsigned temp = 0; + do + { + auto remaining = compressedBytes.size() - offset; + if(remaining < 1) + { + compressedBytes.resize(compressedBytes.size() * 2); + } + zs.next_out = (Bytef *) (compressedBytes.data() + offset); + temp = zs.avail_out = compressedBytes.size() - offset; + ret = deflate(&zs, Z_FINISH); + offset += temp - zs.avail_out; + } while (ret == Z_OK); + + compressedBytes.resize(offset); + + if (deflateEnd(&zs) != Z_OK) + { + return false; + } + + if (ret != Z_STREAM_END) + { + return false; + } + return true; +}
\ No newline at end of file |