15a645f22SBen Gras ///////////////////////////////////////////////////////////////////////////////
25a645f22SBen Gras //
35a645f22SBen Gras /// \file common.h
45a645f22SBen Gras /// \brief Common functions needed in many places in liblzma
55a645f22SBen Gras //
65a645f22SBen Gras // Author: Lasse Collin
75a645f22SBen Gras //
85a645f22SBen Gras // This file has been put into the public domain.
95a645f22SBen Gras // You can do whatever you want with this file.
105a645f22SBen Gras //
115a645f22SBen Gras ///////////////////////////////////////////////////////////////////////////////
125a645f22SBen Gras
135a645f22SBen Gras #include "common.h"
145a645f22SBen Gras
155a645f22SBen Gras
165a645f22SBen Gras /////////////
175a645f22SBen Gras // Version //
185a645f22SBen Gras /////////////
195a645f22SBen Gras
205a645f22SBen Gras extern LZMA_API(uint32_t)
lzma_version_number(void)215a645f22SBen Gras lzma_version_number(void)
225a645f22SBen Gras {
235a645f22SBen Gras return LZMA_VERSION;
245a645f22SBen Gras }
255a645f22SBen Gras
265a645f22SBen Gras
275a645f22SBen Gras extern LZMA_API(const char *)
lzma_version_string(void)285a645f22SBen Gras lzma_version_string(void)
295a645f22SBen Gras {
305a645f22SBen Gras return LZMA_VERSION_STRING;
315a645f22SBen Gras }
325a645f22SBen Gras
335a645f22SBen Gras
345a645f22SBen Gras ///////////////////////
355a645f22SBen Gras // Memory allocation //
365a645f22SBen Gras ///////////////////////
375a645f22SBen Gras
3811be35a1SLionel Sambuc extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
lzma_alloc(size_t size,const lzma_allocator * allocator)39*0a6a1f1dSLionel Sambuc lzma_alloc(size_t size, const lzma_allocator *allocator)
405a645f22SBen Gras {
415a645f22SBen Gras // Some malloc() variants return NULL if called with size == 0.
425a645f22SBen Gras if (size == 0)
435a645f22SBen Gras size = 1;
445a645f22SBen Gras
455a645f22SBen Gras void *ptr;
465a645f22SBen Gras
475a645f22SBen Gras if (allocator != NULL && allocator->alloc != NULL)
485a645f22SBen Gras ptr = allocator->alloc(allocator->opaque, 1, size);
495a645f22SBen Gras else
505a645f22SBen Gras ptr = malloc(size);
515a645f22SBen Gras
525a645f22SBen Gras return ptr;
535a645f22SBen Gras }
545a645f22SBen Gras
555a645f22SBen Gras
56*0a6a1f1dSLionel Sambuc extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
lzma_alloc_zero(size_t size,const lzma_allocator * allocator)57*0a6a1f1dSLionel Sambuc lzma_alloc_zero(size_t size, const lzma_allocator *allocator)
58*0a6a1f1dSLionel Sambuc {
59*0a6a1f1dSLionel Sambuc // Some calloc() variants return NULL if called with size == 0.
60*0a6a1f1dSLionel Sambuc if (size == 0)
61*0a6a1f1dSLionel Sambuc size = 1;
62*0a6a1f1dSLionel Sambuc
63*0a6a1f1dSLionel Sambuc void *ptr;
64*0a6a1f1dSLionel Sambuc
65*0a6a1f1dSLionel Sambuc if (allocator != NULL && allocator->alloc != NULL) {
66*0a6a1f1dSLionel Sambuc ptr = allocator->alloc(allocator->opaque, 1, size);
67*0a6a1f1dSLionel Sambuc if (ptr != NULL)
68*0a6a1f1dSLionel Sambuc memzero(ptr, size);
69*0a6a1f1dSLionel Sambuc } else {
70*0a6a1f1dSLionel Sambuc ptr = calloc(1, size);
71*0a6a1f1dSLionel Sambuc }
72*0a6a1f1dSLionel Sambuc
73*0a6a1f1dSLionel Sambuc return ptr;
74*0a6a1f1dSLionel Sambuc }
75*0a6a1f1dSLionel Sambuc
76*0a6a1f1dSLionel Sambuc
775a645f22SBen Gras extern void
lzma_free(void * ptr,const lzma_allocator * allocator)78*0a6a1f1dSLionel Sambuc lzma_free(void *ptr, const lzma_allocator *allocator)
795a645f22SBen Gras {
805a645f22SBen Gras if (allocator != NULL && allocator->free != NULL)
815a645f22SBen Gras allocator->free(allocator->opaque, ptr);
825a645f22SBen Gras else
835a645f22SBen Gras free(ptr);
845a645f22SBen Gras
855a645f22SBen Gras return;
865a645f22SBen Gras }
875a645f22SBen Gras
885a645f22SBen Gras
895a645f22SBen Gras //////////
905a645f22SBen Gras // Misc //
915a645f22SBen Gras //////////
925a645f22SBen Gras
935a645f22SBen Gras extern size_t
lzma_bufcpy(const uint8_t * restrict in,size_t * restrict in_pos,size_t in_size,uint8_t * restrict out,size_t * restrict out_pos,size_t out_size)945a645f22SBen Gras lzma_bufcpy(const uint8_t *restrict in, size_t *restrict in_pos,
955a645f22SBen Gras size_t in_size, uint8_t *restrict out,
965a645f22SBen Gras size_t *restrict out_pos, size_t out_size)
975a645f22SBen Gras {
985a645f22SBen Gras const size_t in_avail = in_size - *in_pos;
995a645f22SBen Gras const size_t out_avail = out_size - *out_pos;
1005a645f22SBen Gras const size_t copy_size = my_min(in_avail, out_avail);
1015a645f22SBen Gras
1025a645f22SBen Gras memcpy(out + *out_pos, in + *in_pos, copy_size);
1035a645f22SBen Gras
1045a645f22SBen Gras *in_pos += copy_size;
1055a645f22SBen Gras *out_pos += copy_size;
1065a645f22SBen Gras
1075a645f22SBen Gras return copy_size;
1085a645f22SBen Gras }
1095a645f22SBen Gras
1105a645f22SBen Gras
1115a645f22SBen Gras extern lzma_ret
lzma_next_filter_init(lzma_next_coder * next,const lzma_allocator * allocator,const lzma_filter_info * filters)112*0a6a1f1dSLionel Sambuc lzma_next_filter_init(lzma_next_coder *next, const lzma_allocator *allocator,
1135a645f22SBen Gras const lzma_filter_info *filters)
1145a645f22SBen Gras {
1155a645f22SBen Gras lzma_next_coder_init(filters[0].init, next, allocator);
1165a645f22SBen Gras next->id = filters[0].id;
1175a645f22SBen Gras return filters[0].init == NULL
1185a645f22SBen Gras ? LZMA_OK : filters[0].init(next, allocator, filters);
1195a645f22SBen Gras }
1205a645f22SBen Gras
1215a645f22SBen Gras
1225a645f22SBen Gras extern lzma_ret
lzma_next_filter_update(lzma_next_coder * next,const lzma_allocator * allocator,const lzma_filter * reversed_filters)123*0a6a1f1dSLionel Sambuc lzma_next_filter_update(lzma_next_coder *next, const lzma_allocator *allocator,
1245a645f22SBen Gras const lzma_filter *reversed_filters)
1255a645f22SBen Gras {
1265a645f22SBen Gras // Check that the application isn't trying to change the Filter ID.
1275a645f22SBen Gras // End of filters is indicated with LZMA_VLI_UNKNOWN in both
1285a645f22SBen Gras // reversed_filters[0].id and next->id.
1295a645f22SBen Gras if (reversed_filters[0].id != next->id)
1305a645f22SBen Gras return LZMA_PROG_ERROR;
1315a645f22SBen Gras
1325a645f22SBen Gras if (reversed_filters[0].id == LZMA_VLI_UNKNOWN)
1335a645f22SBen Gras return LZMA_OK;
1345a645f22SBen Gras
1355a645f22SBen Gras assert(next->update != NULL);
1365a645f22SBen Gras return next->update(next->coder, allocator, NULL, reversed_filters);
1375a645f22SBen Gras }
1385a645f22SBen Gras
1395a645f22SBen Gras
1405a645f22SBen Gras extern void
lzma_next_end(lzma_next_coder * next,const lzma_allocator * allocator)141*0a6a1f1dSLionel Sambuc lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator)
1425a645f22SBen Gras {
1435a645f22SBen Gras if (next->init != (uintptr_t)(NULL)) {
1445a645f22SBen Gras // To avoid tiny end functions that simply call
1455a645f22SBen Gras // lzma_free(coder, allocator), we allow leaving next->end
1465a645f22SBen Gras // NULL and call lzma_free() here.
1475a645f22SBen Gras if (next->end != NULL)
1485a645f22SBen Gras next->end(next->coder, allocator);
1495a645f22SBen Gras else
1505a645f22SBen Gras lzma_free(next->coder, allocator);
1515a645f22SBen Gras
1525a645f22SBen Gras // Reset the variables so the we don't accidentally think
1535a645f22SBen Gras // that it is an already initialized coder.
1545a645f22SBen Gras *next = LZMA_NEXT_CODER_INIT;
1555a645f22SBen Gras }
1565a645f22SBen Gras
1575a645f22SBen Gras return;
1585a645f22SBen Gras }
1595a645f22SBen Gras
1605a645f22SBen Gras
1615a645f22SBen Gras //////////////////////////////////////
1625a645f22SBen Gras // External to internal API wrapper //
1635a645f22SBen Gras //////////////////////////////////////
1645a645f22SBen Gras
1655a645f22SBen Gras extern lzma_ret
lzma_strm_init(lzma_stream * strm)1665a645f22SBen Gras lzma_strm_init(lzma_stream *strm)
1675a645f22SBen Gras {
1685a645f22SBen Gras if (strm == NULL)
1695a645f22SBen Gras return LZMA_PROG_ERROR;
1705a645f22SBen Gras
1715a645f22SBen Gras if (strm->internal == NULL) {
1725a645f22SBen Gras strm->internal = lzma_alloc(sizeof(lzma_internal),
1735a645f22SBen Gras strm->allocator);
1745a645f22SBen Gras if (strm->internal == NULL)
1755a645f22SBen Gras return LZMA_MEM_ERROR;
1765a645f22SBen Gras
1775a645f22SBen Gras strm->internal->next = LZMA_NEXT_CODER_INIT;
1785a645f22SBen Gras }
1795a645f22SBen Gras
180*0a6a1f1dSLionel Sambuc memzero(strm->internal->supported_actions,
181*0a6a1f1dSLionel Sambuc sizeof(strm->internal->supported_actions));
1825a645f22SBen Gras strm->internal->sequence = ISEQ_RUN;
1835a645f22SBen Gras strm->internal->allow_buf_error = false;
1845a645f22SBen Gras
1855a645f22SBen Gras strm->total_in = 0;
1865a645f22SBen Gras strm->total_out = 0;
1875a645f22SBen Gras
1885a645f22SBen Gras return LZMA_OK;
1895a645f22SBen Gras }
1905a645f22SBen Gras
1915a645f22SBen Gras
1925a645f22SBen Gras extern LZMA_API(lzma_ret)
lzma_code(lzma_stream * strm,lzma_action action)1935a645f22SBen Gras lzma_code(lzma_stream *strm, lzma_action action)
1945a645f22SBen Gras {
1955a645f22SBen Gras // Sanity checks
1965a645f22SBen Gras if ((strm->next_in == NULL && strm->avail_in != 0)
1975a645f22SBen Gras || (strm->next_out == NULL && strm->avail_out != 0)
1985a645f22SBen Gras || strm->internal == NULL
1995a645f22SBen Gras || strm->internal->next.code == NULL
200*0a6a1f1dSLionel Sambuc || (unsigned int)(action) > LZMA_ACTION_MAX
2015a645f22SBen Gras || !strm->internal->supported_actions[action])
2025a645f22SBen Gras return LZMA_PROG_ERROR;
2035a645f22SBen Gras
2045a645f22SBen Gras // Check if unsupported members have been set to non-zero or non-NULL,
2055a645f22SBen Gras // which would indicate that some new feature is wanted.
2065a645f22SBen Gras if (strm->reserved_ptr1 != NULL
2075a645f22SBen Gras || strm->reserved_ptr2 != NULL
2085a645f22SBen Gras || strm->reserved_ptr3 != NULL
2095a645f22SBen Gras || strm->reserved_ptr4 != NULL
2105a645f22SBen Gras || strm->reserved_int1 != 0
2115a645f22SBen Gras || strm->reserved_int2 != 0
2125a645f22SBen Gras || strm->reserved_int3 != 0
2135a645f22SBen Gras || strm->reserved_int4 != 0
2145a645f22SBen Gras || strm->reserved_enum1 != LZMA_RESERVED_ENUM
2155a645f22SBen Gras || strm->reserved_enum2 != LZMA_RESERVED_ENUM)
2165a645f22SBen Gras return LZMA_OPTIONS_ERROR;
2175a645f22SBen Gras
2185a645f22SBen Gras switch (strm->internal->sequence) {
2195a645f22SBen Gras case ISEQ_RUN:
2205a645f22SBen Gras switch (action) {
2215a645f22SBen Gras case LZMA_RUN:
2225a645f22SBen Gras break;
2235a645f22SBen Gras
2245a645f22SBen Gras case LZMA_SYNC_FLUSH:
2255a645f22SBen Gras strm->internal->sequence = ISEQ_SYNC_FLUSH;
2265a645f22SBen Gras break;
2275a645f22SBen Gras
2285a645f22SBen Gras case LZMA_FULL_FLUSH:
2295a645f22SBen Gras strm->internal->sequence = ISEQ_FULL_FLUSH;
2305a645f22SBen Gras break;
2315a645f22SBen Gras
2325a645f22SBen Gras case LZMA_FINISH:
2335a645f22SBen Gras strm->internal->sequence = ISEQ_FINISH;
2345a645f22SBen Gras break;
235*0a6a1f1dSLionel Sambuc
236*0a6a1f1dSLionel Sambuc case LZMA_FULL_BARRIER:
237*0a6a1f1dSLionel Sambuc strm->internal->sequence = ISEQ_FULL_BARRIER;
238*0a6a1f1dSLionel Sambuc break;
2395a645f22SBen Gras }
2405a645f22SBen Gras
2415a645f22SBen Gras break;
2425a645f22SBen Gras
2435a645f22SBen Gras case ISEQ_SYNC_FLUSH:
2445a645f22SBen Gras // The same action must be used until we return
2455a645f22SBen Gras // LZMA_STREAM_END, and the amount of input must not change.
2465a645f22SBen Gras if (action != LZMA_SYNC_FLUSH
2475a645f22SBen Gras || strm->internal->avail_in != strm->avail_in)
2485a645f22SBen Gras return LZMA_PROG_ERROR;
2495a645f22SBen Gras
2505a645f22SBen Gras break;
2515a645f22SBen Gras
2525a645f22SBen Gras case ISEQ_FULL_FLUSH:
2535a645f22SBen Gras if (action != LZMA_FULL_FLUSH
2545a645f22SBen Gras || strm->internal->avail_in != strm->avail_in)
2555a645f22SBen Gras return LZMA_PROG_ERROR;
2565a645f22SBen Gras
2575a645f22SBen Gras break;
2585a645f22SBen Gras
2595a645f22SBen Gras case ISEQ_FINISH:
2605a645f22SBen Gras if (action != LZMA_FINISH
2615a645f22SBen Gras || strm->internal->avail_in != strm->avail_in)
2625a645f22SBen Gras return LZMA_PROG_ERROR;
2635a645f22SBen Gras
2645a645f22SBen Gras break;
2655a645f22SBen Gras
266*0a6a1f1dSLionel Sambuc case ISEQ_FULL_BARRIER:
267*0a6a1f1dSLionel Sambuc if (action != LZMA_FULL_BARRIER
268*0a6a1f1dSLionel Sambuc || strm->internal->avail_in != strm->avail_in)
269*0a6a1f1dSLionel Sambuc return LZMA_PROG_ERROR;
270*0a6a1f1dSLionel Sambuc
271*0a6a1f1dSLionel Sambuc break;
272*0a6a1f1dSLionel Sambuc
2735a645f22SBen Gras case ISEQ_END:
2745a645f22SBen Gras return LZMA_STREAM_END;
2755a645f22SBen Gras
2765a645f22SBen Gras case ISEQ_ERROR:
2775a645f22SBen Gras default:
2785a645f22SBen Gras return LZMA_PROG_ERROR;
2795a645f22SBen Gras }
2805a645f22SBen Gras
2815a645f22SBen Gras size_t in_pos = 0;
2825a645f22SBen Gras size_t out_pos = 0;
2835a645f22SBen Gras lzma_ret ret = strm->internal->next.code(
2845a645f22SBen Gras strm->internal->next.coder, strm->allocator,
2855a645f22SBen Gras strm->next_in, &in_pos, strm->avail_in,
2865a645f22SBen Gras strm->next_out, &out_pos, strm->avail_out, action);
2875a645f22SBen Gras
2885a645f22SBen Gras strm->next_in += in_pos;
2895a645f22SBen Gras strm->avail_in -= in_pos;
2905a645f22SBen Gras strm->total_in += in_pos;
2915a645f22SBen Gras
2925a645f22SBen Gras strm->next_out += out_pos;
2935a645f22SBen Gras strm->avail_out -= out_pos;
2945a645f22SBen Gras strm->total_out += out_pos;
2955a645f22SBen Gras
2965a645f22SBen Gras strm->internal->avail_in = strm->avail_in;
2975a645f22SBen Gras
298*0a6a1f1dSLionel Sambuc // Cast is needed to silence a warning about LZMA_TIMED_OUT, which
299*0a6a1f1dSLionel Sambuc // isn't part of lzma_ret enumeration.
300*0a6a1f1dSLionel Sambuc switch ((unsigned int)(ret)) {
3015a645f22SBen Gras case LZMA_OK:
3025a645f22SBen Gras // Don't return LZMA_BUF_ERROR when it happens the first time.
3035a645f22SBen Gras // This is to avoid returning LZMA_BUF_ERROR when avail_out
3045a645f22SBen Gras // was zero but still there was no more data left to written
3055a645f22SBen Gras // to next_out.
3065a645f22SBen Gras if (out_pos == 0 && in_pos == 0) {
3075a645f22SBen Gras if (strm->internal->allow_buf_error)
3085a645f22SBen Gras ret = LZMA_BUF_ERROR;
3095a645f22SBen Gras else
3105a645f22SBen Gras strm->internal->allow_buf_error = true;
3115a645f22SBen Gras } else {
3125a645f22SBen Gras strm->internal->allow_buf_error = false;
3135a645f22SBen Gras }
3145a645f22SBen Gras break;
3155a645f22SBen Gras
316*0a6a1f1dSLionel Sambuc case LZMA_TIMED_OUT:
317*0a6a1f1dSLionel Sambuc strm->internal->allow_buf_error = false;
318*0a6a1f1dSLionel Sambuc ret = LZMA_OK;
319*0a6a1f1dSLionel Sambuc break;
320*0a6a1f1dSLionel Sambuc
3215a645f22SBen Gras case LZMA_STREAM_END:
3225a645f22SBen Gras if (strm->internal->sequence == ISEQ_SYNC_FLUSH
323*0a6a1f1dSLionel Sambuc || strm->internal->sequence == ISEQ_FULL_FLUSH
324*0a6a1f1dSLionel Sambuc || strm->internal->sequence
325*0a6a1f1dSLionel Sambuc == ISEQ_FULL_BARRIER)
3265a645f22SBen Gras strm->internal->sequence = ISEQ_RUN;
3275a645f22SBen Gras else
3285a645f22SBen Gras strm->internal->sequence = ISEQ_END;
3295a645f22SBen Gras
3305a645f22SBen Gras // Fall through
3315a645f22SBen Gras
3325a645f22SBen Gras case LZMA_NO_CHECK:
3335a645f22SBen Gras case LZMA_UNSUPPORTED_CHECK:
3345a645f22SBen Gras case LZMA_GET_CHECK:
3355a645f22SBen Gras case LZMA_MEMLIMIT_ERROR:
3365a645f22SBen Gras // Something else than LZMA_OK, but not a fatal error,
3375a645f22SBen Gras // that is, coding may be continued (except if ISEQ_END).
3385a645f22SBen Gras strm->internal->allow_buf_error = false;
3395a645f22SBen Gras break;
3405a645f22SBen Gras
3415a645f22SBen Gras default:
3425a645f22SBen Gras // All the other errors are fatal; coding cannot be continued.
3435a645f22SBen Gras assert(ret != LZMA_BUF_ERROR);
3445a645f22SBen Gras strm->internal->sequence = ISEQ_ERROR;
3455a645f22SBen Gras break;
3465a645f22SBen Gras }
3475a645f22SBen Gras
3485a645f22SBen Gras return ret;
3495a645f22SBen Gras }
3505a645f22SBen Gras
3515a645f22SBen Gras
3525a645f22SBen Gras extern LZMA_API(void)
lzma_end(lzma_stream * strm)3535a645f22SBen Gras lzma_end(lzma_stream *strm)
3545a645f22SBen Gras {
3555a645f22SBen Gras if (strm != NULL && strm->internal != NULL) {
3565a645f22SBen Gras lzma_next_end(&strm->internal->next, strm->allocator);
3575a645f22SBen Gras lzma_free(strm->internal, strm->allocator);
3585a645f22SBen Gras strm->internal = NULL;
3595a645f22SBen Gras }
3605a645f22SBen Gras
3615a645f22SBen Gras return;
3625a645f22SBen Gras }
3635a645f22SBen Gras
3645a645f22SBen Gras
365*0a6a1f1dSLionel Sambuc extern LZMA_API(void)
lzma_get_progress(lzma_stream * strm,uint64_t * progress_in,uint64_t * progress_out)366*0a6a1f1dSLionel Sambuc lzma_get_progress(lzma_stream *strm,
367*0a6a1f1dSLionel Sambuc uint64_t *progress_in, uint64_t *progress_out)
368*0a6a1f1dSLionel Sambuc {
369*0a6a1f1dSLionel Sambuc if (strm->internal->next.get_progress != NULL) {
370*0a6a1f1dSLionel Sambuc strm->internal->next.get_progress(strm->internal->next.coder,
371*0a6a1f1dSLionel Sambuc progress_in, progress_out);
372*0a6a1f1dSLionel Sambuc } else {
373*0a6a1f1dSLionel Sambuc *progress_in = strm->total_in;
374*0a6a1f1dSLionel Sambuc *progress_out = strm->total_out;
375*0a6a1f1dSLionel Sambuc }
376*0a6a1f1dSLionel Sambuc
377*0a6a1f1dSLionel Sambuc return;
378*0a6a1f1dSLionel Sambuc }
379*0a6a1f1dSLionel Sambuc
380*0a6a1f1dSLionel Sambuc
3815a645f22SBen Gras extern LZMA_API(lzma_check)
lzma_get_check(const lzma_stream * strm)3825a645f22SBen Gras lzma_get_check(const lzma_stream *strm)
3835a645f22SBen Gras {
3845a645f22SBen Gras // Return LZMA_CHECK_NONE if we cannot know the check type.
3855a645f22SBen Gras // It's a bug in the application if this happens.
3865a645f22SBen Gras if (strm->internal->next.get_check == NULL)
3875a645f22SBen Gras return LZMA_CHECK_NONE;
3885a645f22SBen Gras
3895a645f22SBen Gras return strm->internal->next.get_check(strm->internal->next.coder);
3905a645f22SBen Gras }
3915a645f22SBen Gras
3925a645f22SBen Gras
3935a645f22SBen Gras extern LZMA_API(uint64_t)
lzma_memusage(const lzma_stream * strm)3945a645f22SBen Gras lzma_memusage(const lzma_stream *strm)
3955a645f22SBen Gras {
3965a645f22SBen Gras uint64_t memusage;
3975a645f22SBen Gras uint64_t old_memlimit;
3985a645f22SBen Gras
3995a645f22SBen Gras if (strm == NULL || strm->internal == NULL
4005a645f22SBen Gras || strm->internal->next.memconfig == NULL
4015a645f22SBen Gras || strm->internal->next.memconfig(
4025a645f22SBen Gras strm->internal->next.coder,
4035a645f22SBen Gras &memusage, &old_memlimit, 0) != LZMA_OK)
4045a645f22SBen Gras return 0;
4055a645f22SBen Gras
4065a645f22SBen Gras return memusage;
4075a645f22SBen Gras }
4085a645f22SBen Gras
4095a645f22SBen Gras
4105a645f22SBen Gras extern LZMA_API(uint64_t)
lzma_memlimit_get(const lzma_stream * strm)4115a645f22SBen Gras lzma_memlimit_get(const lzma_stream *strm)
4125a645f22SBen Gras {
4135a645f22SBen Gras uint64_t old_memlimit;
4145a645f22SBen Gras uint64_t memusage;
4155a645f22SBen Gras
4165a645f22SBen Gras if (strm == NULL || strm->internal == NULL
4175a645f22SBen Gras || strm->internal->next.memconfig == NULL
4185a645f22SBen Gras || strm->internal->next.memconfig(
4195a645f22SBen Gras strm->internal->next.coder,
4205a645f22SBen Gras &memusage, &old_memlimit, 0) != LZMA_OK)
4215a645f22SBen Gras return 0;
4225a645f22SBen Gras
4235a645f22SBen Gras return old_memlimit;
4245a645f22SBen Gras }
4255a645f22SBen Gras
4265a645f22SBen Gras
4275a645f22SBen Gras extern LZMA_API(lzma_ret)
lzma_memlimit_set(lzma_stream * strm,uint64_t new_memlimit)4285a645f22SBen Gras lzma_memlimit_set(lzma_stream *strm, uint64_t new_memlimit)
4295a645f22SBen Gras {
4305a645f22SBen Gras // Dummy variables to simplify memconfig functions
4315a645f22SBen Gras uint64_t old_memlimit;
4325a645f22SBen Gras uint64_t memusage;
4335a645f22SBen Gras
4345a645f22SBen Gras if (strm == NULL || strm->internal == NULL
4355a645f22SBen Gras || strm->internal->next.memconfig == NULL)
4365a645f22SBen Gras return LZMA_PROG_ERROR;
4375a645f22SBen Gras
4385a645f22SBen Gras if (new_memlimit != 0 && new_memlimit < LZMA_MEMUSAGE_BASE)
4395a645f22SBen Gras return LZMA_MEMLIMIT_ERROR;
4405a645f22SBen Gras
4415a645f22SBen Gras return strm->internal->next.memconfig(strm->internal->next.coder,
4425a645f22SBen Gras &memusage, &old_memlimit, new_memlimit);
4435a645f22SBen Gras }
444