magpie
Loading...
Searching...
No Matches
CompressionDataAdapter.hpp
1#pragma once
2
3#include <cmath>
4#include <cstddef>
5#include <cstdint>
6#include <cstring>
7#include <nghttp2/nghttp2.h>
8#include <stdexcept>
9#include <vector>
10#include <zlib.h>
11#include "DataAdapter.hpp"
12
13namespace magpie {
14
16protected:
17 DataAdapter* readSource;
18
19 z_stream stream;
20public:
21 static inline int DEFLATE_HEADER = 0;
22 static inline int GZIP_HEADER = 16;
23
30 DataAdapter* readSource,
31 bool gzip = true
32 ) : readSource(readSource) {
33 stream.zfree = nullptr;
34 stream.zalloc = nullptr;
35 stream.opaque = nullptr;
36
37 if (deflateInit2(
38 &stream,
39 6,
40 Z_DEFLATED,
41 15 | (gzip ? GZIP_HEADER : DEFLATE_HEADER),
42 8,
43 Z_DEFAULT_STRATEGY
44 ) != Z_OK) {
45 throw std::runtime_error("Critical zlib init error");
46 }
47 }
49
52
53 size_t getChunk(
54 size_t len,
55 uint8_t* buf,
56 uint32_t* dataFlags
57 ) override {
58 size_t blocks = (size_t) std::ceil(
59 (double) len / (double) 16384
60 );
61 // Per https://www.zlib.net/zlib_tech.html, there's 5 bytes of overhead per block.
62 // This means that as long as we reserve enough bytes for the headers, we don't need to cache anything. We read
63 // less than we need to ensure that we have enough room for the headers.
64 size_t overheadBytes = 5 * (blocks + 1);
65
66 std::vector<uint8_t> intermediateBuf;
67 // The intermediateBuf is adjusted for the size of gzip overhead
68 intermediateBuf.resize(len - overheadBytes);
69 size_t readLen = readSource->getChunk(
70 intermediateBuf.size(),
71 intermediateBuf.data(),
72 dataFlags
73 );
74
75 stream.next_in = intermediateBuf.data();
76 stream.avail_in = readLen;
77 stream.next_out = buf;
78 stream.avail_out = len;
79
80 if (
81 deflate(&stream, Z_FULL_FLUSH) != Z_OK
82 ) {
83 throw std::runtime_error("Failed to deflate");
84 }
85 size_t outputSize = len - stream.avail_out;
86 return outputSize;
87 }
88};
89
90}
Definition CompressionDataAdapter.hpp:15
CompressionDataAdapter(DataAdapter *readSource, bool gzip=true)
Definition CompressionDataAdapter.hpp:29
Definition DataAdapter.hpp:16