1*3b35e7eeSXin LI // SPDX-License-Identifier: 0BSD 2*3b35e7eeSXin LI 381ad8388SMartin Matuska /////////////////////////////////////////////////////////////////////////////// 481ad8388SMartin Matuska // 581ad8388SMartin Matuska /// \file block_buffer_decoder.c 681ad8388SMartin Matuska /// \brief Single-call .xz Block decoder 781ad8388SMartin Matuska // 881ad8388SMartin Matuska // Author: Lasse Collin 981ad8388SMartin Matuska // 1081ad8388SMartin Matuska /////////////////////////////////////////////////////////////////////////////// 1181ad8388SMartin Matuska 1281ad8388SMartin Matuska #include "block_decoder.h" 1381ad8388SMartin Matuska 1481ad8388SMartin Matuska 1581ad8388SMartin Matuska extern LZMA_API(lzma_ret) 1653200025SRui Paulo lzma_block_buffer_decode(lzma_block *block, const lzma_allocator *allocator, 1781ad8388SMartin Matuska const uint8_t *in, size_t *in_pos, size_t in_size, 1881ad8388SMartin Matuska uint8_t *out, size_t *out_pos, size_t out_size) 1981ad8388SMartin Matuska { 2081ad8388SMartin Matuska if (in_pos == NULL || (in == NULL && *in_pos != in_size) 2181ad8388SMartin Matuska || *in_pos > in_size || out_pos == NULL 2281ad8388SMartin Matuska || (out == NULL && *out_pos != out_size) 2381ad8388SMartin Matuska || *out_pos > out_size) 2481ad8388SMartin Matuska return LZMA_PROG_ERROR; 2581ad8388SMartin Matuska 2681ad8388SMartin Matuska // Initialize the Block decoder. 2781ad8388SMartin Matuska lzma_next_coder block_decoder = LZMA_NEXT_CODER_INIT; 2881ad8388SMartin Matuska lzma_ret ret = lzma_block_decoder_init( 2981ad8388SMartin Matuska &block_decoder, allocator, block); 3081ad8388SMartin Matuska 3181ad8388SMartin Matuska if (ret == LZMA_OK) { 3281ad8388SMartin Matuska // Save the positions so that we can restore them in case 3381ad8388SMartin Matuska // an error occurs. 3481ad8388SMartin Matuska const size_t in_start = *in_pos; 3581ad8388SMartin Matuska const size_t out_start = *out_pos; 3681ad8388SMartin Matuska 3781ad8388SMartin Matuska // Do the actual decoding. 3881ad8388SMartin Matuska ret = block_decoder.code(block_decoder.coder, allocator, 3981ad8388SMartin Matuska in, in_pos, in_size, out, out_pos, out_size, 4081ad8388SMartin Matuska LZMA_FINISH); 4181ad8388SMartin Matuska 4281ad8388SMartin Matuska if (ret == LZMA_STREAM_END) { 4381ad8388SMartin Matuska ret = LZMA_OK; 4481ad8388SMartin Matuska } else { 4581ad8388SMartin Matuska if (ret == LZMA_OK) { 4681ad8388SMartin Matuska // Either the input was truncated or the 4781ad8388SMartin Matuska // output buffer was too small. 4881ad8388SMartin Matuska assert(*in_pos == in_size 4981ad8388SMartin Matuska || *out_pos == out_size); 5081ad8388SMartin Matuska 5181ad8388SMartin Matuska // If all the input was consumed, then the 5281ad8388SMartin Matuska // input is truncated, even if the output 5381ad8388SMartin Matuska // buffer is also full. This is because 5481ad8388SMartin Matuska // processing the last byte of the Block 5581ad8388SMartin Matuska // never produces output. 5681ad8388SMartin Matuska // 5781ad8388SMartin Matuska // NOTE: This assumption may break when new 5881ad8388SMartin Matuska // filters are added, if the end marker of 5981ad8388SMartin Matuska // the filter doesn't consume at least one 6081ad8388SMartin Matuska // complete byte. 6181ad8388SMartin Matuska if (*in_pos == in_size) 6281ad8388SMartin Matuska ret = LZMA_DATA_ERROR; 6381ad8388SMartin Matuska else 6481ad8388SMartin Matuska ret = LZMA_BUF_ERROR; 6581ad8388SMartin Matuska } 6681ad8388SMartin Matuska 6781ad8388SMartin Matuska // Restore the positions. 6881ad8388SMartin Matuska *in_pos = in_start; 6981ad8388SMartin Matuska *out_pos = out_start; 7081ad8388SMartin Matuska } 7181ad8388SMartin Matuska } 7281ad8388SMartin Matuska 7381ad8388SMartin Matuska // Free the decoder memory. This needs to be done even if 7481ad8388SMartin Matuska // initialization fails, because the internal API doesn't 7581ad8388SMartin Matuska // require the initialization function to free its memory on error. 7681ad8388SMartin Matuska lzma_next_end(&block_decoder, allocator); 7781ad8388SMartin Matuska 7881ad8388SMartin Matuska return ret; 7981ad8388SMartin Matuska } 80