xref: /minix3/external/public-domain/xz/dist/src/liblzma/common/common.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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