29 #include <boost/scope_exit.hpp> 52 static void * LZMA_API_CALL
lzmaAlloc(
void *
UNUSED(opaque),
size_t nmemb,
size_t size) {
53 return malloc(nmemb * size);
66 lzma_filter filters[2] = {
67 { LZMA_FILTER_LZMA1, 0 },
68 { LZMA_VLI_UNKNOWN , 0 }
71 if (!lzma_filter_decoder_is_supported(filters[0].
id))
72 throw Exception(
"LZMA1 compression not supported");
75 if (lzma_properties_size(&propsSize, &filters[0]) != LZMA_OK)
76 throw Exception(
"Can't get LZMA1 properties size");
78 if (propsSize > inputSize)
79 throw Exception(
"LZMA1 properties size larger than input data");
81 if (lzma_properties_decode(&filters[0], &
kLZMAAllocator, data, propsSize) != LZMA_OK)
82 throw Exception(
"Failed to decode LZMA1 properties");
85 inputSize -= propsSize;
87 lzma_stream strm = LZMA_STREAM_INIT;
88 BOOST_SCOPE_EXIT( (&strm) (&filters) ) {
91 } BOOST_SCOPE_EXIT_END
93 lzma_ret lzmaRet = LZMA_OK;
95 if ((lzmaRet = lzma_raw_decoder(&strm, filters)) != LZMA_OK)
96 throw Exception(
"Failed to create raw LZMA1 decoder: %d", (
int) lzmaRet);
101 strm.avail_in = inputSize;
102 strm.next_out = outputData.
get();
103 strm.avail_out = outputSize;
105 lzmaRet = lzma_code(&strm, LZMA_FINISH);
107 if (noEndMarker && (lzmaRet == LZMA_OK) && (strm.avail_in == 0) && (strm.avail_out == 0))
110 if ((lzmaRet != LZMA_STREAM_END) || (strm.avail_out != 0)) {
111 if (lzmaRet == LZMA_OK)
112 throw Exception(
"Failed to uncompress LZMA1 data: premature end of output buffer");
114 if (strm.avail_out != 0)
115 throw Exception(
"Failed to uncompress LZMA1 data: output buffer not completely filled");
117 throw Exception(
"Failed to uncompress LZMA1 data: %d", (
int) lzmaRet);
125 if (input.
read(inputData.
get(), inputSize) != inputSize)
Generic interface for a readable data stream.
PointerType release()
Returns the plain pointer value and releases ScopedPtr.
Implementing the reading stream interfaces for plain memory blocks.
Decompress LZMA, using liblzma.
static void *LZMA_API_CALL lzmaAlloc(void *opaque, size_t nmemb, size_t size)
static void LZMA_API_CALL lzmaFree(void *opaque, void *ptr)
A simple scoped smart pointer template.
Basic exceptions to throw.
virtual size_t read(void *dataPtr, size_t dataSize)=0
Read data from the stream.
Simple memory based 'stream', which implements the ReadStream interface for a plain memory block...
Low-level type definitions to handle fixed width types portably.
const Exception kReadError("Read error")
Exception when reading from a stream failed.
byte * decompressLZMA1(const byte *data, size_t inputSize, size_t outputSize, bool noEndMarker)
Decompress using the LZMA1 algorithm.
PointerType get() const
Returns the plain pointer value.
static lzma_allocator kLZMAAllocator
Interface for a seekable & readable data stream.