1// (C) Copyright Milan Svoboda 2008.
2// Originally developed under the fusecompress project.
3// Based on bzip2.cpp by:
4// (C) Copyright Jonathan Turkanis 2003.
5// Distributed under the Boost Software License, Version 1.0. (See accompanying
6// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
7
8// See http://www.boost.org/libs/iostreams for documentation.
9
10// Define BOOST_IOSTREAMS_SOURCE so that <boost/iostreams/detail/config.hpp>
11// knows that we are building the library (possibly exporting code), rather
12// than using it (possibly importing code).
13#define BOOST_IOSTREAMS_SOURCE
14
15#include <lzma.h>
16
17#include <boost/throw_exception.hpp>
18#include <boost/iostreams/detail/config/dyn_link.hpp>
19#include <boost/iostreams/filter/lzma.hpp>
20
21
22#ifndef BOOST_IOSTREAMS_LZMA_NO_MULTITHREADED
23 #if LZMA_VERSION < 50020002
24 #define BOOST_IOSTREAMS_LZMA_NO_MULTITHREADED
25 #endif
26#endif
27
28namespace boost { namespace iostreams {
29
30namespace lzma {
31
32 // Compression levels
33
34const uint32_t no_compression = 0;
35const uint32_t best_speed = 1;
36const uint32_t best_compression = 9;
37const uint32_t default_compression = 2;
38
39 // Status codes
40
41const int okay = LZMA_OK;
42const int stream_end = LZMA_STREAM_END;
43const int unsupported_check = LZMA_UNSUPPORTED_CHECK;
44const int mem_error = LZMA_MEM_ERROR;
45const int options_error = LZMA_OPTIONS_ERROR;
46const int data_error = LZMA_DATA_ERROR;
47const int buf_error = LZMA_BUF_ERROR;
48const int prog_error = LZMA_PROG_ERROR;
49
50 // Flush codes
51
52const int finish = LZMA_FINISH;
53const int full_flush = LZMA_FULL_FLUSH;
54const int sync_flush = LZMA_SYNC_FLUSH;
55const int run = LZMA_RUN;
56
57 // Code for current OS
58
59} // End namespace lzma.
60
61//------------------Implementation of lzma_error------------------------------//
62
63lzma_error::lzma_error(int error)
64 : BOOST_IOSTREAMS_FAILURE("lzma error"), error_(error)
65 { }
66
67void lzma_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(int error)
68{
69 switch (error) {
70 case LZMA_OK:
71 case LZMA_STREAM_END:
72 return;
73 case LZMA_MEM_ERROR:
74 boost::throw_exception(e: std::bad_alloc());
75 default:
76 boost::throw_exception(e: lzma_error(error));
77 }
78}
79
80//------------------Implementation of lzma_base-------------------------------//
81
82namespace detail {
83
84lzma_base::lzma_base()
85 : stream_(new lzma_stream), level_(lzma::default_compression), threads_(1)
86 { }
87
88lzma_base::~lzma_base() { delete static_cast<lzma_stream*>(stream_); }
89
90void lzma_base::before( const char*& src_begin, const char* src_end,
91 char*& dest_begin, char* dest_end )
92{
93 lzma_stream* s = static_cast<lzma_stream*>(stream_);
94 s->next_in = reinterpret_cast<uint8_t*>(const_cast<char*>(src_begin));
95 s->avail_in = static_cast<size_t>(src_end - src_begin);
96 s->next_out = reinterpret_cast<uint8_t*>(dest_begin);
97 s->avail_out= static_cast<size_t>(dest_end - dest_begin);
98}
99
100void lzma_base::after(const char*& src_begin, char*& dest_begin, bool)
101{
102 lzma_stream* s = static_cast<lzma_stream*>(stream_);
103 src_begin = const_cast<const char*>(reinterpret_cast<const char*>(s->next_in));
104 dest_begin = reinterpret_cast<char*>(s->next_out);
105}
106
107int lzma_base::deflate(int action)
108{
109 return lzma_code(strm: static_cast<lzma_stream*>(stream_), action: static_cast<lzma_action>(action));
110}
111
112int lzma_base::inflate(int action)
113{
114 return lzma_code(strm: static_cast<lzma_stream*>(stream_), action: static_cast<lzma_action>(action));
115}
116
117void lzma_base::reset(bool compress, bool realloc)
118{
119 lzma_stream* s = static_cast<lzma_stream*>(stream_);
120 lzma_end(strm: s);
121 if (realloc)
122 {
123 init_stream(compress);
124 }
125}
126
127void lzma_base::do_init
128 ( const lzma_params& p, bool compress,
129 lzma::alloc_func, lzma::free_func,
130 void* )
131{
132
133 level_ = p.level;
134 threads_ = p.threads;
135
136#ifndef BOOST_IOSTREAMS_LZMA_NO_MULTITHREADED
137 if (threads_ == 0) {
138 threads_ = lzma_cputhreads();
139 }
140#endif
141
142 init_stream(compress);
143}
144
145void lzma_base::init_stream(bool compress)
146{
147 lzma_stream* s = static_cast<lzma_stream*>(stream_);
148
149 memset(s: s, c: 0, n: sizeof(*s));
150
151#ifndef BOOST_IOSTREAMS_LZMA_NO_MULTITHREADED
152 const lzma_mt opt = { .flags: 0, .threads: threads_, .block_size: 0, .timeout: 1000, .preset: level_, NULL, .check: LZMA_CHECK_CRC32 };
153#endif
154
155 lzma_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(
156 error: compress ?
157#ifdef BOOST_IOSTREAMS_LZMA_NO_MULTITHREADED
158 lzma_easy_encoder(s, level_, LZMA_CHECK_CRC32) :
159#else
160 lzma_stream_encoder_mt(strm: s, options: &opt) :
161#endif
162 lzma_stream_decoder(strm: s, memlimit: 100 * 1024 * 1024, LZMA_CONCATENATED)
163 );
164}
165
166
167} // End namespace detail.
168
169//----------------------------------------------------------------------------//
170
171} } // End namespaces iostreams, boost.
172

source code of boost/libs/iostreams/src/lzma.cpp