File indexing completed on 2025-01-18 10:01:11
0001
0002
0003
0004
0005
0006
0007
0008 #if defined(BXZSTR_BZ2_SUPPORT) && (BXZSTR_BZ2_SUPPORT) == 1
0009
0010 #ifndef BXZSTR_BZ_STREAM_WRAPPER_HPP
0011 #define BXZSTR_BZ_STREAM_WRAPPER_HPP
0012
0013 #include <bzlib.h>
0014
0015 #include <string>
0016 #include <sstream>
0017 #include <exception>
0018
0019 #include "stream_wrapper.hpp"
0020
0021 namespace bxz {
0022
0023 class bzException : public std::exception {
0024 public:
0025 bzException(const int ret) : _msg("bzlib: ") {
0026 switch (ret) {
0027 case BZ_CONFIG_ERROR:
0028 _msg += "BZ_CONFIG_ERROR: ";
0029 break;
0030 case BZ_SEQUENCE_ERROR:
0031 _msg += "BZ_SEQUENCE_ERROR: ";
0032 break;
0033 case BZ_PARAM_ERROR:
0034 _msg += "BZ_PARAM_ERROR: ";
0035 break;
0036 case BZ_MEM_ERROR:
0037 _msg += "BZ_MEM_ERROR: ";
0038 break;
0039 case BZ_DATA_ERROR:
0040 _msg += "BZ_DATA_ERROR: ";
0041 break;
0042 case BZ_DATA_ERROR_MAGIC:
0043 _msg += "BZ_DATA_ERROR_MAGIC: ";
0044 break;
0045 case BZ_IO_ERROR:
0046 _msg += "BZ_IO_ERROR: ";
0047 break;
0048 case BZ_UNEXPECTED_EOF:
0049 _msg += "BZ_UNEXPECTED_EOF: ";
0050 break;
0051 case BZ_OUTBUFF_FULL:
0052 _msg += "BZ_OUTBUFF_FULL: ";
0053 break;
0054 default:
0055 std::ostringstream oss;
0056 oss << ret;
0057 _msg += "[" + oss.str() + "]: ";
0058 break;
0059 }
0060 _msg += ret;
0061 }
0062 bzException(const std::string msg) : _msg(msg) {}
0063
0064 const char * what() const noexcept { return _msg.c_str(); }
0065
0066 private:
0067 std::string _msg;
0068 };
0069
0070 namespace detail {
0071 class bz_stream_wrapper : public bz_stream, public stream_wrapper {
0072 public:
0073 bz_stream_wrapper(const bool _is_input = true, const int _level = 9, const int _wf = 30)
0074 : is_input(_is_input) {
0075 bz_stream::next_out = NULL;
0076 bz_stream::next_in = NULL;
0077 this->bzalloc = NULL;
0078 this->bzfree = NULL;
0079 this->opaque = NULL;
0080 if (is_input) {
0081 bz_stream::avail_in = 0;
0082 bz_stream::next_in = NULL;
0083 ret = BZ2_bzDecompressInit(this, 0, 0);
0084 } else {
0085
0086 ret = BZ2_bzCompressInit(this, _level, 0, _wf);
0087 }
0088 if (ret != BZ_OK) throw bzException(ret);
0089 }
0090 ~bz_stream_wrapper() {
0091 if (is_input) {
0092 BZ2_bzDecompressEnd(this);
0093 } else {
0094 BZ2_bzCompressEnd(this);
0095 }
0096 }
0097
0098 int decompress(const int = 0) override {
0099 ret = BZ2_bzDecompress(this);
0100 if (ret != BZ_OK && ret != BZ_STREAM_END) throw bzException(ret);
0101 return ret;
0102 }
0103 int compress(const int _flags = BZ_RUN) override {
0104 ret = BZ2_bzCompress(this, _flags);
0105 if (!ret) throw bzException(ret);
0106 return ret;
0107 }
0108 bool stream_end() const override { return this->ret == BZ_STREAM_END; }
0109 bool done() const override { return this->stream_end(); }
0110
0111 const uint8_t* next_in() const override { return (uint8_t*)bz_stream::next_in; }
0112 long avail_in() const override { return bz_stream::avail_in; }
0113 uint8_t* next_out() const override { return (uint8_t*)bz_stream::next_out; }
0114 long avail_out() const override { return bz_stream::avail_out; }
0115
0116 void set_next_in(const unsigned char* in) override { bz_stream::next_in = (char*)in; }
0117 void set_avail_in(const long in) override { bz_stream::avail_in = in; }
0118 void set_next_out(const uint8_t* in) override { bz_stream::next_out = (char*)in; }
0119 void set_avail_out(const long in) override { bz_stream::avail_out = in; }
0120
0121 private:
0122 bool is_input;
0123 int ret;
0124 };
0125 }
0126 }
0127
0128 #endif
0129 #endif