Path: blob/master/Utilities/cmliblzma/liblzma/common/stream_buffer_decoder.c
3153 views
// SPDX-License-Identifier: 0BSD12///////////////////////////////////////////////////////////////////////////////3//4/// \file stream_buffer_decoder.c5/// \brief Single-call .xz Stream decoder6//7// Author: Lasse Collin8//9///////////////////////////////////////////////////////////////////////////////1011#include "stream_decoder.h"121314extern LZMA_API(lzma_ret)15lzma_stream_buffer_decode(uint64_t *memlimit, uint32_t flags,16const lzma_allocator *allocator,17const uint8_t *in, size_t *in_pos, size_t in_size,18uint8_t *out, size_t *out_pos, size_t out_size)19{20// Sanity checks21if (in_pos == NULL || (in == NULL && *in_pos != in_size)22|| *in_pos > in_size || out_pos == NULL23|| (out == NULL && *out_pos != out_size)24|| *out_pos > out_size)25return LZMA_PROG_ERROR;2627// Catch flags that are not allowed in buffer-to-buffer decoding.28if (flags & LZMA_TELL_ANY_CHECK)29return LZMA_PROG_ERROR;3031// Initialize the Stream decoder.32// TODO: We need something to tell the decoder that it can use the33// output buffer as workspace, and thus save significant amount of RAM.34lzma_next_coder stream_decoder = LZMA_NEXT_CODER_INIT;35lzma_ret ret = lzma_stream_decoder_init(36&stream_decoder, allocator, *memlimit, flags);3738if (ret == LZMA_OK) {39// Save the positions so that we can restore them in case40// an error occurs.41const size_t in_start = *in_pos;42const size_t out_start = *out_pos;4344// Do the actual decoding.45ret = stream_decoder.code(stream_decoder.coder, allocator,46in, in_pos, in_size, out, out_pos, out_size,47LZMA_FINISH);4849if (ret == LZMA_STREAM_END) {50ret = LZMA_OK;51} else {52// Something went wrong, restore the positions.53*in_pos = in_start;54*out_pos = out_start;5556if (ret == LZMA_OK) {57// Either the input was truncated or the58// output buffer was too small.59assert(*in_pos == in_size60|| *out_pos == out_size);6162// If all the input was consumed, then the63// input is truncated, even if the output64// buffer is also full. This is because65// processing the last byte of the Stream66// never produces output.67if (*in_pos == in_size)68ret = LZMA_DATA_ERROR;69else70ret = LZMA_BUF_ERROR;7172} else if (ret == LZMA_MEMLIMIT_ERROR) {73// Let the caller know how much memory would74// have been needed.75uint64_t memusage;76(void)stream_decoder.memconfig(77stream_decoder.coder,78memlimit, &memusage, 0);79}80}81}8283// Free the decoder memory. This needs to be done even if84// initialization fails, because the internal API doesn't85// require the initialization function to free its memory on error.86lzma_next_end(&stream_decoder, allocator);8788return ret;89}909192