1 /*
2 * Lzma Compressor
3 * (C) 2001 Peter J Jones
4 * 2001-2007,2014 Jack Lloyd
5 * 2006 Matt Johnston
6 * 2012 Vojtech Kral
7 *
8 * Botan is released under the Simplified BSD License (see license.txt)
9 */
10
11 #include <botan/lzma.h>
12 #include <botan/internal/compress_utils.h>
13 #include <botan/exceptn.h>
14 #include <lzma.h>
15
16 namespace Botan {
17
18 namespace {
19
20 class LZMA_Stream : public Zlib_Style_Stream<lzma_stream, uint8_t>
21 {
22 public:
LZMA_Stream()23 LZMA_Stream()
24 {
25 m_allocator.opaque = alloc();
26 m_allocator.alloc = Compression_Alloc_Info::malloc<size_t>;
27 m_allocator.free = Compression_Alloc_Info::free;
28 streamp()->allocator = &m_allocator;
29 }
30
~LZMA_Stream()31 ~LZMA_Stream()
32 {
33 ::lzma_end(streamp());
34 }
35
run(uint32_t flags)36 bool run(uint32_t flags) override
37 {
38 lzma_ret rc = ::lzma_code(streamp(), static_cast<lzma_action>(flags));
39
40 if(rc != LZMA_OK && rc != LZMA_STREAM_END)
41 throw Compression_Error("lzma_code", ErrorType::LzmaError, rc);
42
43 return (rc == LZMA_STREAM_END);
44 }
45
run_flag() const46 uint32_t run_flag() const override { return LZMA_RUN; }
flush_flag() const47 uint32_t flush_flag() const override { return LZMA_FULL_FLUSH; }
finish_flag() const48 uint32_t finish_flag() const override { return LZMA_FINISH; }
49 private:
50 ::lzma_allocator m_allocator;
51 };
52
53 class LZMA_Compression_Stream final : public LZMA_Stream
54 {
55 public:
LZMA_Compression_Stream(size_t level)56 explicit LZMA_Compression_Stream(size_t level)
57 {
58 if(level == 0)
59 level = 6; // default
60 else if(level > 9)
61 level = 9; // clamp to maximum allowed value
62
63 lzma_ret rc = ::lzma_easy_encoder(streamp(), level, LZMA_CHECK_CRC64);
64
65 if(rc != LZMA_OK)
66 throw Compression_Error("lzam_easy_encoder", ErrorType::LzmaError, rc);
67 }
68 };
69
70 class LZMA_Decompression_Stream final : public LZMA_Stream
71 {
72 public:
LZMA_Decompression_Stream()73 LZMA_Decompression_Stream()
74 {
75 lzma_ret rc = ::lzma_stream_decoder(streamp(), UINT64_MAX,
76 LZMA_TELL_UNSUPPORTED_CHECK);
77
78 if(rc != LZMA_OK)
79 throw Compression_Error("lzma_stream_decoder", ErrorType::LzmaError, rc);
80 }
81 };
82
83 }
84
make_stream(size_t level) const85 Compression_Stream* LZMA_Compression::make_stream(size_t level) const
86 {
87 return new LZMA_Compression_Stream(level);
88 }
89
make_stream() const90 Compression_Stream* LZMA_Decompression::make_stream() const
91 {
92 return new LZMA_Decompression_Stream;
93 }
94
95 }
96