Botan  1.11.15
src/lib/compression/lzma/lzma.cpp
Go to the documentation of this file.
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 }