Botan
1.11.15
|
00001 /* 00002 * Lzma Compressor 00003 * (C) 2001 Peter J Jones 00004 * 2001-2007,2014 Jack Lloyd 00005 * 2006 Matt Johnston 00006 * 2012 Vojtech Kral 00007 * 00008 * Botan is released under the Simplified BSD License (see license.txt) 00009 */ 00010 00011 #include <botan/lzma.h> 00012 #include <botan/internal/compress_utils.h> 00013 #include <lzma.h> 00014 00015 namespace Botan { 00016 00017 BOTAN_REGISTER_COMPRESSION(LZMA_Compression, LZMA_Decompression); 00018 00019 namespace { 00020 00021 class LZMA_Stream : public Zlib_Style_Stream<lzma_stream, byte> 00022 { 00023 public: 00024 LZMA_Stream() 00025 { 00026 auto a = new ::lzma_allocator; 00027 a->opaque = alloc(); 00028 a->alloc = Compression_Alloc_Info::malloc<size_t>; 00029 a->free = Compression_Alloc_Info::free; 00030 streamp()->allocator = a; 00031 } 00032 00033 ~LZMA_Stream() 00034 { 00035 ::lzma_end(streamp()); 00036 delete streamp()->allocator; 00037 } 00038 00039 bool run(u32bit flags) override 00040 { 00041 lzma_ret rc = ::lzma_code(streamp(), static_cast<lzma_action>(flags)); 00042 00043 if(rc == LZMA_MEM_ERROR) 00044 throw std::bad_alloc(); 00045 else if (rc != LZMA_OK && rc != LZMA_STREAM_END) 00046 throw std::runtime_error("Lzma error"); 00047 00048 return (rc == LZMA_STREAM_END); 00049 } 00050 00051 u32bit run_flag() const override { return LZMA_RUN; } 00052 u32bit flush_flag() const override { return LZMA_FULL_FLUSH; } 00053 u32bit finish_flag() const override { return LZMA_FINISH; } 00054 }; 00055 00056 class LZMA_Compression_Stream : public LZMA_Stream 00057 { 00058 public: 00059 LZMA_Compression_Stream(size_t level) 00060 { 00061 lzma_ret rc = ::lzma_easy_encoder(streamp(), level, LZMA_CHECK_CRC64); 00062 00063 if(rc == LZMA_MEM_ERROR) 00064 throw std::bad_alloc(); 00065 else if(rc != LZMA_OK) 00066 throw std::runtime_error("lzma compress initialization failed"); 00067 } 00068 }; 00069 00070 class LZMA_Decompression_Stream : public LZMA_Stream 00071 { 00072 public: 00073 LZMA_Decompression_Stream() 00074 { 00075 lzma_ret rc = ::lzma_stream_decoder(streamp(), UINT64_MAX, 00076 LZMA_TELL_UNSUPPORTED_CHECK); 00077 00078 if(rc == LZMA_MEM_ERROR) 00079 throw std::bad_alloc(); 00080 else if(rc != LZMA_OK) 00081 throw std::runtime_error("Bad setting in lzma_stream_decoder"); 00082 } 00083 }; 00084 00085 } 00086 00087 Compression_Stream* LZMA_Compression::make_stream() const 00088 { 00089 return new LZMA_Compression_Stream(m_level); 00090 } 00091 00092 Compression_Stream* LZMA_Decompression::make_stream() const 00093 { 00094 return new LZMA_Decompression_Stream; 00095 } 00096 00097 }