File indexing completed on 2025-01-30 10:11:30
0001
0002
0003
0004
0005
0006
0007
0008 #if defined(BXZSTR_Z_SUPPORT) && (BXZSTR_Z_SUPPORT) == 1
0009
0010 #ifndef BXZSTR_Z_STREAM_WRAPPER_HPP
0011 #define BXZSTR_Z_STREAM_WRAPPER_HPP
0012
0013 #include <zlib.h>
0014
0015 #include <string>
0016 #include <sstream>
0017 #include <exception>
0018
0019 #include "stream_wrapper.hpp"
0020
0021 namespace bxz {
0022
0023 class zException : public std::exception {
0024 public:
0025 zException(const std::string &msg, const int ret) : _msg("zlib: ") {
0026 switch (ret) {
0027 case Z_STREAM_ERROR:
0028 _msg += "Z_STREAM_ERROR: ";
0029 break;
0030 case Z_DATA_ERROR:
0031 _msg += "Z_DATA_ERROR: ";
0032 break;
0033 case Z_MEM_ERROR:
0034 _msg += "Z_MEM_ERROR: ";
0035 break;
0036 case Z_VERSION_ERROR:
0037 _msg += "Z_VERSION_ERROR: ";
0038 break;
0039 case Z_BUF_ERROR:
0040 _msg += "Z_BUF_ERROR: ";
0041 break;
0042 default:
0043 std::ostringstream oss;
0044 oss << ret;
0045 _msg += "[" + oss.str() + "]: ";
0046 break;
0047 }
0048 _msg += msg;
0049 }
0050 zException(const std::string msg) : _msg(msg) {}
0051
0052 const char * what() const noexcept { return _msg.c_str(); }
0053
0054 private:
0055 std::string _msg;
0056 };
0057
0058 namespace detail {
0059 class z_stream_wrapper : public z_stream, public stream_wrapper {
0060 public:
0061 z_stream_wrapper(const bool _is_input = true,
0062 const int _level = Z_DEFAULT_COMPRESSION, const int = 0)
0063 : is_input(_is_input) {
0064 z_stream::next_out = Z_NULL;
0065 z_stream::next_in = Z_NULL;
0066 this->zalloc = Z_NULL;
0067 this->zfree = Z_NULL;
0068 this->opaque = Z_NULL;
0069 if (is_input) {
0070 z_stream::avail_in = 0;
0071 z_stream::next_in = Z_NULL;
0072 ret = inflateInit2(this, 15+32);
0073 } else {
0074
0075 ret = deflateInit2(this, _level, Z_DEFLATED, 15+16, 8, Z_DEFAULT_STRATEGY);
0076 }
0077 if (ret != Z_OK) throw zException(this->msg, ret);
0078 }
0079 ~z_stream_wrapper() {
0080 if (is_input) {
0081 inflateEnd(this);
0082 } else {
0083 deflateEnd(this);
0084 }
0085 }
0086
0087 int decompress(const int _flags = Z_NO_FLUSH) override {
0088 ret = inflate(this, _flags);
0089 if (ret != Z_OK && ret != Z_STREAM_END) throw zException(this->msg, ret);
0090 return ret;
0091 }
0092 int compress(const int _flags = Z_NO_FLUSH) override {
0093 ret = deflate(this, _flags);
0094 if (ret != Z_OK && ret != Z_STREAM_END && ret != Z_BUF_ERROR)
0095 throw zException(this->msg, ret);
0096 return ret;
0097 }
0098 bool stream_end() const override { return this->ret == Z_STREAM_END; }
0099 bool done() const override { return (this->ret == Z_BUF_ERROR || this->stream_end()); }
0100
0101 const uint8_t* next_in() const override { return z_stream::next_in; }
0102 long avail_in() const override { return z_stream::avail_in; }
0103 uint8_t* next_out() const override { return z_stream::next_out; }
0104 long avail_out() const override { return z_stream::avail_out; }
0105
0106 void set_next_in(const unsigned char* in) override { z_stream::next_in = (unsigned char*)in; }
0107 void set_avail_in(long in) override { z_stream::avail_in = in; }
0108 void set_next_out(const uint8_t* in) override { z_stream::next_out = const_cast<Bytef*>(in); }
0109 void set_avail_out(long in) override { z_stream::avail_out = in; }
0110
0111 private:
0112 bool is_input;
0113 int ret;
0114 };
0115 }
0116 }
0117
0118 #endif
0119 #endif