23 :
public std::exception
32 _msg +=
"Z_STREAM_ERROR: ";
35 _msg +=
"Z_DATA_ERROR: ";
38 _msg +=
"Z_MEM_ERROR: ";
41 _msg +=
"Z_VERSION_ERROR: ";
44 _msg +=
"Z_BUF_ERROR: ";
47 std::ostringstream oss;
49 _msg +=
"[" + oss.str() +
"]: ";
70 this->zalloc = Z_NULL;
72 this->opaque = Z_NULL;
77 this->next_in = Z_NULL;
78 ret = inflateInit2(
this, 15+32);
82 ret = deflateInit2(
this, _level, Z_DEFLATED, 15+16, 8, Z_DEFAULT_STRATEGY);
84 if (ret != Z_OK)
throw Exception(
this, ret);
104 :
public std::streambuf
108 std::size_t _buff_size = default_buff_size,
bool _auto_detect =
true)
111 buff_size(_buff_size),
112 auto_detect(_auto_detect),
113 auto_detect_run(false),
117 in_buff =
new char [buff_size];
118 in_buff_start = in_buff;
119 in_buff_end = in_buff;
120 out_buff =
new char [buff_size];
121 setg(out_buff, out_buff, out_buff);
131 if (zstrm_p)
delete zstrm_p;
136 if (this->gptr() == this->egptr())
139 char * out_buff_free_start = out_buff;
143 if (in_buff_start == in_buff_end)
146 in_buff_start = in_buff;
147 std::streamsize sz = sbuf_p->sgetn(in_buff, buff_size);
148 in_buff_end = in_buff + sz;
149 if (in_buff_end == in_buff_start)
break;
152 if (auto_detect && ! auto_detect_run)
154 auto_detect_run =
true;
155 unsigned char b0 = *
reinterpret_cast< unsigned char *
>(in_buff_start);
156 unsigned char b1 = *
reinterpret_cast< unsigned char *
>(in_buff_start + 1);
160 is_text = ! (in_buff_start + 2 <= in_buff_end
161 && ((b0 == 0x1F && b1 == 0x8B)
162 || (b0 == 0x78 && (b1 == 0x01
169 assert(in_buff_start == in_buff);
170 std::swap(in_buff, out_buff);
171 out_buff_free_start = in_buff_end;
172 in_buff_start = in_buff;
173 in_buff_end = in_buff;
179 zstrm_p->next_in =
reinterpret_cast< decltype(zstrm_p-
>next_in) >(in_buff_start);
180 zstrm_p->avail_in = (uInt)(in_buff_end - in_buff_start);
181 zstrm_p->next_out =
reinterpret_cast< decltype(zstrm_p-
>next_out) >(out_buff_free_start);
182 zstrm_p->avail_out = (uInt)((out_buff + buff_size) - out_buff_free_start);
183 int ret = inflate(zstrm_p, Z_NO_FLUSH);
185 if (ret != Z_OK && ret != Z_STREAM_END)
throw Exception(zstrm_p, ret);
187 in_buff_start =
reinterpret_cast< decltype(in_buff_start)
>(zstrm_p->next_in);
188 in_buff_end = in_buff_start + zstrm_p->avail_in;
189 out_buff_free_start =
reinterpret_cast< decltype(out_buff_free_start)
>(zstrm_p->next_out);
190 assert(out_buff_free_start + zstrm_p->avail_out == out_buff + buff_size);
192 if (ret == Z_STREAM_END)
198 }
while (out_buff_free_start == out_buff);
202 this->setg(out_buff, out_buff, out_buff_free_start);
204 return this->gptr() == this->egptr()
206 : traits_type::to_int_type(*this->gptr());
220 static const std::size_t default_buff_size = (std::size_t)1 << 20;
224 :
public std::streambuf
228 std::size_t _buff_size = default_buff_size,
int _level = Z_DEFAULT_COMPRESSION)
230 zstrm_p(new detail::z_stream_wrapper(false, _level)),
231 buff_size(_buff_size)
234 in_buff =
new char [buff_size];
235 out_buff =
new char [buff_size];
236 setp(in_buff, in_buff + buff_size);
245 while (ret != Z_STREAM_END && ret != Z_BUF_ERROR)
247 zstrm_p->next_out =
reinterpret_cast< decltype(zstrm_p-
>next_out) >(out_buff);
248 zstrm_p->avail_out = (uInt)buff_size;
249 ret = deflate(zstrm_p, flush);
250 if (ret != Z_OK && ret != Z_STREAM_END && ret != Z_BUF_ERROR)
throw Exception(zstrm_p, ret);
251 std::streamsize sz = sbuf_p->sputn(out_buff,
reinterpret_cast< decltype(out_buff)
>(zstrm_p->next_out) - out_buff);
252 if (sz !=
reinterpret_cast< decltype(out_buff)
>(zstrm_p->next_out) - out_buff)
280 virtual std::streambuf::int_type
overflow(std::streambuf::int_type c = traits_type::eof())
282 zstrm_p->next_in =
reinterpret_cast< decltype(zstrm_p-
>next_in) >(pbase());
283 zstrm_p->avail_in = (uInt)(pptr() - pbase());
284 while (zstrm_p->avail_in > 0)
286 int r = deflate_loop(Z_NO_FLUSH);
289 setp(
nullptr,
nullptr);
290 return traits_type::eof();
293 setp(in_buff, in_buff + buff_size);
294 return traits_type::eq_int_type(c, traits_type::eof()) ? traits_type::eof() : sputc((
char)c);
300 if (! pptr())
return -1;
302 zstrm_p->next_in =
nullptr;
303 zstrm_p->avail_in = 0;
304 if (deflate_loop(Z_FINISH) != 0)
return -1;
305 deflateReset(zstrm_p);
315 static const std::size_t default_buff_size = (std::size_t)1 << 20;
319 :
public std::istream
325 exceptions(std::ios_base::badbit);
330 exceptions(std::ios_base::badbit);
339 :
public std::ostream
345 exceptions(std::ios_base::badbit);
350 exceptions(std::ios_base::badbit);
361 template <
typename FStream_Type >
365 : _fs(filename, mode)
377 explicit ifstream(
const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)
381 exceptions(std::ios_base::badbit);
385 if (rdbuf())
delete rdbuf();
394 explicit ofstream(
const std::string& filename, std::ios_base::openmode mode = std::ios_base::out)
398 exceptions(std::ios_base::badbit);
402 if (rdbuf())
delete rdbuf();
Exception(const std::string msg)
detail::z_stream_wrapper * zstrm_p
virtual std::streambuf::int_type underflow()
istream(std::istream &is)
ostreambuf(std::streambuf *_sbuf_p, std::size_t _buff_size=default_buff_size, int _level=Z_DEFAULT_COMPRESSION)
Exception class thrown by failed zlib operations.
Exception(z_stream *zstrm_p, int ret)
const char * what() const NOEXCEPT
detail::z_stream_wrapper * zstrm_p
ostream(std::streambuf *sbuf_p)
int deflate_loop(int flush)
z_stream_wrapper(bool _is_input=true, int _level=Z_DEFAULT_COMPRESSION)
ostream(std::ostream &os)
ifstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
virtual std::streambuf::int_type overflow(std::streambuf::int_type c=traits_type::eof())
ofstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::out)
istream(std::streambuf *sbuf_p)
strict_fstream_holder(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
istreambuf(std::streambuf *_sbuf_p, std::size_t _buff_size=default_buff_size, bool _auto_detect=true)