blob: 65ef7214b003c7008593885044bb94dcbb6964fb [file] [log] [blame]
Ed Tanous9140a672017-04-24 17:01:32 -07001#include <zlib.h>
2#include <test_utils.hpp>
3#include <cstring>
4
5bool gzipInflate(const std::string& compressedBytes,
6 std::string& uncompressedBytes) {
7 if (compressedBytes.size() == 0) {
8 uncompressedBytes = compressedBytes;
9 return true;
10 }
11
12 uncompressedBytes.clear();
13
14 unsigned full_length = compressedBytes.size();
15 unsigned half_length = compressedBytes.size() / 2;
16
17 unsigned uncompLength = full_length;
18 char* uncomp = (char*)calloc(sizeof(char), uncompLength);
19
20 z_stream strm;
21 strm.next_in = (Bytef*)compressedBytes.c_str();
22 strm.avail_in = compressedBytes.size();
23 strm.total_out = 0;
24 strm.zalloc = Z_NULL;
25 strm.zfree = Z_NULL;
26
27 bool done = false;
28
29 if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) {
30 free(uncomp);
31 return false;
32 }
33
34 while (!done) {
35 // If our output buffer is too small
36 if (strm.total_out >= uncompLength) {
37 // Increase size of output buffer
38 char* uncomp2 = (char*)calloc(sizeof(char), uncompLength + half_length);
39 std::memcpy(uncomp2, uncomp, uncompLength);
40 uncompLength += half_length;
41 free(uncomp);
42 uncomp = uncomp2;
43 }
44
45 strm.next_out = (Bytef*)(uncomp + strm.total_out);
46 strm.avail_out = uncompLength - strm.total_out;
47
48 // Inflate another chunk.
49 int err = inflate(&strm, Z_SYNC_FLUSH);
50 if (err == Z_STREAM_END)
51 done = true;
52 else if (err != Z_OK) {
53 break;
54 }
55 }
56
57 if (inflateEnd(&strm) != Z_OK) {
58 free(uncomp);
59 return false;
60 }
61
62 for (size_t i = 0; i < strm.total_out; ++i) {
63 uncompressedBytes += uncomp[i];
64 }
65 free(uncomp);
66 return true;
67}