byteme
C++ wrappers for buffered inputs
Loading...
Searching...
No Matches
ZlibBufferWriter.hpp
Go to the documentation of this file.
1#ifndef BYTEME_ZLIB_BUFFER_WRITER_HPP
2#define BYTEME_ZLIB_BUFFER_WRITER_HPP
3
4#include "zlib.h"
5#include <stdexcept>
6#include <vector>
7#include "Writer.hpp"
8
15namespace byteme {
16
22class ZlibBufferWriter : public Writer {
23private:
27 struct ZStream {
28 ZStream(int mode, int level) {
29 strm.zalloc = Z_NULL;
30 strm.zfree = Z_NULL;
31 strm.opaque = Z_NULL;
32 strm.avail_in = 0;
33 strm.next_in = Z_NULL;
34
35 // Check out https://zlib.net/manual.html for the constants.
36 int windowBits;
37 if (mode == 0) { // deflate
38 windowBits = -15;
39 } else if (mode == 1) { // Zlib
40 windowBits = 15;
41 } else if (mode == 2) { // Gzip
42 windowBits = 16 + 15;
43 } else {
44 throw std::runtime_error("unknown Zlib compression mode supplied");
45 }
46
47 int ret = deflateInit2(&strm, level, Z_DEFLATED, windowBits, 8, Z_DEFAULT_STRATEGY);
48 if (ret != Z_OK) {
49 throw std::runtime_error("failed to initialize Zlib buffer compression");
50 }
51 }
52
53 ~ZStream() {
54 deflateEnd(&strm);
55 return;
56 }
57
58 public:
59 // Delete the remaining constructors.
60 ZStream(const ZStream&) = delete;
61 ZStream(ZStream&&) = delete;
62 ZStream& operator=(const ZStream&) = delete;
63 ZStream& operator=(ZStream&&) = delete;
64
65 public:
66 z_stream strm;
67 };
72public:
80 ZlibBufferWriter(int mode = 2, int compression_level = 6, size_t buffer_size = 65536) : my_zstr(mode, compression_level), my_holding(buffer_size) {}
81
82public:
83 using Writer::write;
84
85 void write(const unsigned char* buffer, size_t n) {
86 my_zstr.strm.next_in = const_cast<unsigned char*>(buffer); // for C compatibility.
87 my_zstr.strm.avail_in = n;
88 dump(Z_NO_FLUSH);
89 }
90
91 void finish() {
92 my_zstr.strm.next_in = nullptr;
93 my_zstr.strm.avail_in = 0;
94 dump(Z_FINISH);
95 }
96
97private:
98 ZStream my_zstr;
99 std::vector<unsigned char> my_holding;
100
101 void dump(int flag) {
102 do {
103 my_zstr.strm.avail_out = my_holding.size();
104 my_zstr.strm.next_out = my_holding.data();
105 deflate(&(my_zstr.strm), flag); // no need to check, see https://zlib.net/zlib_how.html.
106 size_t compressed = my_holding.size() - my_zstr.strm.avail_out;
107 output.insert(output.end(), my_holding.begin(), my_holding.begin() + compressed);
108 } while (my_zstr.strm.avail_out == 0);
109 }
110
111public:
115 // Exposed for back-compatibility only.
116 std::vector<unsigned char> output;
125 std::vector<unsigned char>& get_output() {
126 return output;
127 }
128};
129
130}
131
132#endif
Write to an output sink.
Virtual class for writing bytes to a sink.
Definition Writer.hpp:18
virtual void write(const unsigned char *buffer, size_t n)=0
Compress and write bytes to a Zlib-compressed buffer.
Definition ZlibBufferWriter.hpp:22
ZlibBufferWriter(int mode=2, int compression_level=6, size_t buffer_size=65536)
Definition ZlibBufferWriter.hpp:80
void finish()
Definition ZlibBufferWriter.hpp:91
void write(const unsigned char *buffer, size_t n)
Definition ZlibBufferWriter.hpp:85
std::vector< unsigned char > & get_output()
Definition ZlibBufferWriter.hpp:125
Simple byte readers and writers.