-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathinflate.cc
50 lines (44 loc) · 1.35 KB
/
inflate.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include "libpstack/inflatereader.h"
#include "libpstack/stringify.h"
#include <zlib.h>
namespace pstack {
InflateReader::InflateReader(size_t inflatedSize, const Reader &upstream)
: MemReader(std::string("inflated content from ") + stringify(upstream),
inflatedSize, new char[inflatedSize])
{
char xferbuf[32768];
z_stream stream{};
int window = 15;
if (inflateInit2(&stream, window) != Z_OK)
throw (Exception() << "inflateInit2 failed");
stream.avail_out = inflatedSize;
using bytep = Bytef *;
stream.next_out = bytep(data);
bool eof = false;
size_t inputOffset = 0;
for (bool done = false; !done; ) {
if (stream.avail_in == 0 && !eof) {
// keep the input buffer full
stream.avail_in = upstream.read(inputOffset, sizeof xferbuf, xferbuf);
inputOffset += stream.avail_in;
stream.next_in = bytep(xferbuf);
if (stream.avail_in == 0)
eof = true;
}
switch (inflate(&stream, eof ? Z_FINISH : Z_SYNC_FLUSH)) {
case Z_STREAM_END:
done = true;
// fallthrough
case Z_OK:
break;
default:
throw (Exception() << "inflate failed");
}
}
inflateEnd(&stream);
}
InflateReader::~InflateReader()
{
delete[] data;
}
}