File indexing completed on 2025-01-30 10:11:29
0001
0002
0003
0004
0005
0006
0007
0008 #if defined(BXZSTR_LZMA_SUPPORT) && (BXZSTR_LZMA_SUPPORT) == 1
0009
0010 #ifndef BXZSTR_LZMA_STREAM_WRAPPER_HPP
0011 #define BXZSTR_LZMA_STREAM_WRAPPER_HPP
0012
0013 #include <lzma.h>
0014
0015 #include <string>
0016 #include <sstream>
0017 #include <exception>
0018
0019 #include "stream_wrapper.hpp"
0020
0021 namespace bxz {
0022
0023 class lzmaException : public std::exception {
0024 public:
0025 lzmaException(const lzma_ret ret) : _msg("liblzma: ") {
0026 switch (ret) {
0027 case LZMA_MEM_ERROR:
0028 _msg += "LZMA_MEM_ERROR: ";
0029 break;
0030 case LZMA_OPTIONS_ERROR:
0031 _msg += "LZMA_OPTIONS_ERROR: ";
0032 break;
0033 case LZMA_UNSUPPORTED_CHECK:
0034 _msg += "LZMA_UNSUPPORTED_CHECK: ";
0035 break;
0036 case LZMA_PROG_ERROR:
0037 _msg += "LZMA_PROG_ERROR: ";
0038 break;
0039 case LZMA_BUF_ERROR:
0040 _msg += "LZMA_BUF_ERROR: ";
0041 break;
0042 case LZMA_DATA_ERROR:
0043 _msg += "LZMA_DATA_ERROR: ";
0044 break;
0045 case LZMA_FORMAT_ERROR:
0046 _msg += "LZMA_FORMAT_ERROR: ";
0047 break;
0048 case LZMA_NO_CHECK:
0049 _msg += "LZMA_NO_CHECK: ";
0050 break;
0051 case LZMA_MEMLIMIT_ERROR:
0052 _msg += "LZMA_MEMLIMIT_ERROR: ";
0053 break;
0054 default:
0055 std::ostringstream oss;
0056 oss << ret;
0057 _msg += "[" + oss.str() + "]: ";
0058 break;
0059 }
0060 _msg += ret;
0061 }
0062 lzmaException(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 lzma_stream_wrapper : public lzma_stream, public stream_wrapper {
0072 public:
0073 lzma_stream_wrapper(const bool _is_input = true, const int _level = 2, const int _flags = 0)
0074 : lzma_stream(LZMA_STREAM_INIT), is_input(_is_input) {
0075 lzma_ret ret;
0076 lzma_stream::next_in = NULL;
0077 lzma_stream::next_out = NULL;
0078 if (is_input) {
0079 lzma_stream::avail_in = 0;
0080 lzma_stream::next_in = NULL;
0081 ret = lzma_auto_decoder(this, UINT64_MAX, _flags);
0082 } else {
0083 ret = lzma_easy_encoder(this, _level, LZMA_CHECK_CRC64);
0084 }
0085 if (ret != LZMA_OK) throw lzmaException(ret);
0086 }
0087 ~lzma_stream_wrapper() { lzma_end(this); }
0088
0089 int decompress(const int = 0) override {
0090 ret = lzma_code(this, LZMA_RUN);
0091 if (ret != LZMA_OK && ret != LZMA_STREAM_END && ret) throw lzmaException(ret);
0092 return (int)ret;
0093 }
0094 int compress(const int _flags = LZMA_RUN) override {
0095 ret = lzma_code(this, (lzma_action)_flags);
0096 if (ret != LZMA_OK && ret != LZMA_STREAM_END && ret != LZMA_BUF_ERROR)
0097 throw lzmaException(ret);
0098 return (int)ret;
0099 }
0100 bool stream_end() const override { return this->ret == LZMA_STREAM_END; }
0101 bool done() const override { return (this->ret == LZMA_BUF_ERROR || this->stream_end()); }
0102
0103 const uint8_t* next_in() const override { return lzma_stream::next_in; }
0104 long avail_in() const override { return lzma_stream::avail_in; }
0105 uint8_t* next_out() const override { return lzma_stream::next_out; }
0106 long avail_out() const override { return lzma_stream::avail_out; }
0107
0108 void set_next_in(const unsigned char* in) override { lzma_stream::next_in = in; }
0109 void set_avail_in(long in) override { lzma_stream::avail_in = in; }
0110 void set_next_out(const uint8_t* in) override { lzma_stream::next_out = const_cast<uint8_t*>(in); }
0111 void set_avail_out(long in) override { lzma_stream::avail_out = in; }
0112
0113 private:
0114 bool is_input;
0115 lzma_ret ret;
0116 };
0117 }
0118 }
0119 #endif
0120 #endif