byteme
C++ wrappers for buffered inputs
All Classes Namespaces Files Functions Variables Pages
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 <stdexcept>
5#include <vector>
6#include <cstddef>
7
8#include "zlib.h"
9
10#include "Writer.hpp"
11#include "check_buffer_size.hpp"
12
19namespace byteme {
20
28 int mode = 2;
29
35
40 std::size_t buffer_size = 65536;
41};
42
48class ZlibBufferWriter final : public Writer {
49private:
53 struct ZStream {
54 ZStream(int mode, int level) {
55 strm.zalloc = Z_NULL;
56 strm.zfree = Z_NULL;
57 strm.opaque = Z_NULL;
58 strm.avail_in = 0;
59 strm.next_in = Z_NULL;
60
61 // Check out https://zlib.net/manual.html for the constants.
62 int windowBits;
63 if (mode == 0) { // deflate
64 windowBits = -15;
65 } else if (mode == 1) { // Zlib
66 windowBits = 15;
67 } else if (mode == 2) { // Gzip
68 windowBits = 16 + 15;
69 } else {
70 throw std::runtime_error("unknown Zlib compression mode supplied");
71 }
72
73 int ret = deflateInit2(&strm, level, Z_DEFLATED, windowBits, 8, Z_DEFAULT_STRATEGY);
74 if (ret != Z_OK) {
75 throw std::runtime_error("failed to initialize Zlib buffer compression");
76 }
77 }
78
79 ~ZStream() {
80 deflateEnd(&strm);
81 return;
82 }
83
84 public:
85 // Delete the remaining constructors.
86 ZStream(const ZStream&) = delete;
87 ZStream(ZStream&&) = delete;
88 ZStream& operator=(const ZStream&) = delete;
89 ZStream& operator=(ZStream&&) = delete;
90
91 public:
92 z_stream strm;
93 };
98public:
103 my_zstr(options.mode, options.compression_level),
104 my_holding(
105 check_buffer_size<decltype(decltype(ZStream::strm)::avail_out)>( // constrained for the z_stream interface.
106 check_buffer_size(options.buffer_size)
107 )
108 )
109 {}
110
111public:
112 using Writer::write;
113
114 void write(const unsigned char* buffer, std::size_t n) {
115 typedef decltype(decltype(ZStream::strm)::avail_in) Size; // constrained for the z_stream interface.
116 safe_write<Size, false>(
117 buffer,
118 n,
119 [&](const unsigned char* buffer0, Size n0) -> void {
120 my_zstr.strm.next_in = const_cast<unsigned char*>(buffer0); // for C compatibility.
121 my_zstr.strm.avail_in = n0;
122 dump(Z_NO_FLUSH);
123 }
124 );
125 }
126
127 void finish() {
128 my_zstr.strm.next_in = nullptr;
129 my_zstr.strm.avail_in = 0;
130 dump(Z_FINISH);
131 }
132
133private:
134 ZStream my_zstr;
135 std::vector<unsigned char> my_holding;
136
137 void dump(int flag) {
138 do {
139 my_zstr.strm.avail_out = my_holding.size();
140 my_zstr.strm.next_out = my_holding.data();
141 deflate(&(my_zstr.strm), flag); // no need to check, see https://zlib.net/zlib_how.html.
142 std::size_t compressed = my_holding.size() - my_zstr.strm.avail_out;
143 output.insert(output.end(), my_holding.begin(), my_holding.begin() + compressed);
144 } while (my_zstr.strm.avail_out == 0);
145 }
146
147public:
151 // Exposed for back-compatibility only.
152 std::vector<unsigned char> output;
161 std::vector<unsigned char>& get_output() {
162 return output;
163 }
164};
165
166}
167
168#endif
Write to an output sink.
Virtual class for writing bytes to a sink.
Definition Writer.hpp:21
virtual void write(const unsigned char *buffer, std::size_t n)=0
Compress and write bytes to a Zlib-compressed buffer.
Definition ZlibBufferWriter.hpp:48
ZlibBufferWriter(const ZlibBufferWriterOptions &options)
Definition ZlibBufferWriter.hpp:102
void finish()
Definition ZlibBufferWriter.hpp:127
void write(const unsigned char *buffer, std::size_t n)
Definition ZlibBufferWriter.hpp:114
std::vector< unsigned char > & get_output()
Definition ZlibBufferWriter.hpp:161
Simple byte readers and writers.
Options for the ZlibBufferWriter constructor.
Definition ZlibBufferWriter.hpp:24
int compression_level
Definition ZlibBufferWriter.hpp:34
int mode
Definition ZlibBufferWriter.hpp:28
std::size_t buffer_size
Definition ZlibBufferWriter.hpp:40