summaryrefslogtreecommitdiffstats
path: root/source/StringCompression.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/StringCompression.cpp')
-rw-r--r--source/StringCompression.cpp129
1 files changed, 127 insertions, 2 deletions
diff --git a/source/StringCompression.cpp b/source/StringCompression.cpp
index b7e08cb11..36946b282 100644
--- a/source/StringCompression.cpp
+++ b/source/StringCompression.cpp
@@ -5,13 +5,12 @@
#include "Globals.h"
#include "StringCompression.h"
-#include "zlib.h"
-/// Compresses a_Data into a_Compressed; return Z_XXX error constants same as zlib's compress2()
+/// Compresses a_Data into a_Compressed; returns Z_XXX error constants same as zlib's compress2()
int CompressString(const char * a_Data, int a_Length, AString & a_Compressed)
{
uLongf CompressedSize = compressBound(a_Length);
@@ -53,3 +52,129 @@ int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed
+
+int CompressStringGZIP(const char * a_Data, int a_Length, AString & a_Compressed)
+{
+ // Compress a_Data into a_Compressed using GZIP; return Z_XXX error constants same as zlib's compress2()
+
+ a_Compressed.reserve(a_Length);
+
+ char Buffer[64 KiB];
+ z_stream strm;
+ memset(&strm, 0, sizeof(strm));
+ strm.next_in = (Bytef *)a_Data;
+ strm.avail_in = a_Length;
+ strm.next_out = (Bytef *)Buffer;
+ strm.avail_out = sizeof(Buffer);
+
+ int res = deflateInit2(&strm, 9, Z_DEFLATED, 31, 9, Z_DEFAULT_STRATEGY);
+ if (res != Z_OK)
+ {
+ LOG("%s: compression initialization failed: %d (\"%s\").", __FUNCTION__, res, strm.msg);
+ return res;
+ }
+
+ while (true)
+ {
+ res = deflate(&strm, Z_FINISH);
+ switch (res)
+ {
+ case Z_OK:
+ {
+ // Some data has been compressed. Consume the buffer and continue compressing
+ a_Compressed.append(Buffer, sizeof(Buffer) - strm.avail_out);
+ strm.avail_out = sizeof(Buffer);
+ if (strm.avail_in == 0)
+ {
+ // All data has been compressed
+ deflateEnd(&strm);
+ return Z_OK;
+ }
+ break;
+ }
+
+ case Z_STREAM_END:
+ {
+ // Finished compressing. Consume the rest of the buffer and return
+ a_Compressed.append(Buffer, sizeof(Buffer) - strm.avail_out);
+ deflateEnd(&strm);
+ return Z_OK;
+ }
+
+ default:
+ {
+ // An error has occurred, log it and return the error value
+ LOG("%s: compression failed: %d (\"%s\").", __FUNCTION__, res, strm.msg);
+ deflateEnd(&strm);
+ return res;
+ }
+ } // switch (res)
+ } // while (true)
+}
+
+
+
+
+
+extern int UncompressStringGZIP(const char * a_Data, int a_Length, AString & a_Uncompressed)
+{
+ // Uncompresses a_Data into a_Uncompressed using GZIP; returns Z_OK for success or Z_XXX error constants same as zlib
+
+ a_Uncompressed.reserve(a_Length);
+
+ char Buffer[64 KiB];
+ z_stream strm;
+ memset(&strm, 0, sizeof(strm));
+ strm.next_in = (Bytef *)a_Data;
+ strm.avail_in = a_Length;
+ strm.next_out = (Bytef *)Buffer;
+ strm.avail_out = sizeof(Buffer);
+
+ int res = inflateInit2(&strm, 31); // Force GZIP decoding
+ if (res != Z_OK)
+ {
+ LOG("%s: uncompression initialization failed: %d (\"%s\").", __FUNCTION__, res, strm.msg);
+ return res;
+ }
+
+ while (true)
+ {
+ res = inflate(&strm, Z_FINISH);
+ switch (res)
+ {
+ case Z_OK:
+ {
+ // Some data has been uncompressed. Consume the buffer and continue uncompressing
+ a_Uncompressed.append(Buffer, sizeof(Buffer) - strm.avail_out);
+ strm.avail_out = sizeof(Buffer);
+ if (strm.avail_in == 0)
+ {
+ // All data has been uncompressed
+ inflateEnd(&strm);
+ return Z_OK;
+ }
+ break;
+ }
+
+ case Z_STREAM_END:
+ {
+ // Finished uncompressing. Consume the rest of the buffer and return
+ a_Uncompressed.append(Buffer, sizeof(Buffer) - strm.avail_out);
+ inflateEnd(&strm);
+ return Z_OK;
+ }
+
+ default:
+ {
+ // An error has occurred, log it and return the error value
+ LOG("%s: uncompression failed: %d (\"%s\").", __FUNCTION__, res, strm.msg);
+ inflateEnd(&strm);
+ return res;
+ }
+ } // switch (res)
+ } // while (true)
+}
+
+
+
+