///////////////////////////////////////////////////////////////////////////////
//
/// \file       common.h
/// \brief      Common functions needed in many places in liblzma
//
//  Author:     Lasse Collin
//
//  This file has been put into the public domain.
//  You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////

#include "common.h"

#include <dlfcn.h>


/////////////
// Version //
/////////////

extern LZMA_API(uint32_t)
lzma_version_number(void)
{
	return LZMA_VERSION;
}


extern LZMA_API(const char *)
lzma_version_string(void)
{
	return LZMA_VERSION_STRING;
}


///////////////////////
// Memory allocation //
///////////////////////

extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
lzma_alloc(size_t size, const lzma_allocator *allocator)
{
	// Some malloc() variants return NULL if called with size == 0.
	if (size == 0)
		size = 1;

	void *ptr;

	if (allocator != NULL && allocator->alloc != NULL)
		ptr = allocator->alloc(allocator->opaque, 1, size);
	else
		ptr = malloc(size);

	return ptr;
}


extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
lzma_alloc_zero(size_t size, const lzma_allocator *allocator)
{
	// Some calloc() variants return NULL if called with size == 0.
	if (size == 0)
		size = 1;

	void *ptr;

	if (allocator != NULL && allocator->alloc != NULL) {
		ptr = allocator->alloc(allocator->opaque, 1, size);
		if (ptr != NULL)
			memzero(ptr, size);
	} else {
		ptr = calloc(1, size);
	}

	return ptr;
}


extern void
lzma_free(void *ptr, const lzma_allocator *allocator)
{
	if (allocator != NULL && allocator->free != NULL)
		allocator->free(allocator->opaque, ptr);
	else
		free(ptr);

	return;
}


//////////
// Misc //
//////////

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)
{
	const size_t in_avail = in_size - *in_pos;
	const size_t out_avail = out_size - *out_pos;
	const size_t copy_size = my_min(in_avail, out_avail);

	memcpy(out + *out_pos, in + *in_pos, copy_size);

	*in_pos += copy_size;
	*out_pos += copy_size;

	return copy_size;
}


extern lzma_ret
lzma_next_filter_init(lzma_next_coder *next, const lzma_allocator *allocator,
		const lzma_filter_info *filters)
{
	lzma_next_coder_init(filters[0].init, next, allocator);
	next->id = filters[0].id;
	return filters[0].init == NULL
			? LZMA_OK : filters[0].init(next, allocator, filters);
}


extern lzma_ret
lzma_next_filter_update(lzma_next_coder *next, const lzma_allocator *allocator,
		const lzma_filter *reversed_filters)
{
	// Check that the application isn't trying to change the Filter ID.
	// End of filters is indicated with LZMA_VLI_UNKNOWN in both
	// reversed_filters[0].id and next->id.
	if (reversed_filters[0].id != next->id)
		return LZMA_PROG_ERROR;

	if (reversed_filters[0].id == LZMA_VLI_UNKNOWN)
		return LZMA_OK;

	assert(next->update != NULL);
	return next->update(next->coder, allocator, NULL, reversed_filters);
}


extern void
lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator)
{
	if (next->init != (uintptr_t)(NULL)) {
		// To avoid tiny end functions that simply call
		// lzma_free(coder, allocator), we allow leaving next->end
		// NULL and call lzma_free() here.
		if (next->end != NULL)
			next->end(next->coder, allocator);
		else
			lzma_free(next->coder, allocator);

		// Reset the variables so the we don't accidentally think
		// that it is an already initialized coder.
		*next = LZMA_NEXT_CODER_INIT;
	}

	return;
}


//////////////////////////////////////
// External to internal API wrapper //
//////////////////////////////////////

static bool
liblzma2_loaded(void)
{
	void *handle = dlopen("liblzma.so.2", RTLD_LAZY | RTLD_NOLOAD);
	if (handle) {
		dlclose(handle);
		return true;
	}
	return false;
}

extern lzma_ret
lzma_strm_init(lzma_stream *strm)
{
	if (strm == NULL)
		return LZMA_PROG_ERROR;

	if (strm->internal == NULL) {
		strm->internal = lzma_alloc(sizeof(lzma_internal),
				strm->allocator);
		if (strm->internal == NULL)
			return LZMA_MEM_ERROR;

		strm->internal->next = LZMA_NEXT_CODER_INIT;
		strm->internal->liblzma2_compat = liblzma2_loaded();
	}

	memzero(strm->internal->supported_actions,
			sizeof(strm->internal->supported_actions));
	strm->internal->sequence = ISEQ_RUN;
	strm->internal->allow_buf_error = false;

	strm->total_in = 0;
	strm->total_out = 0;

	return LZMA_OK;
}


// Before v5.0.0~6 (liblzma: A few ABI tweaks to reserve space in
// structures, 2010-10-23), the reserved fields in lzma_stream were:
//
//	void *reserved_ptr1;
//	void *reserved_ptr2;
//	uint64_t reserved_int1;
//	uint64_t reserved_int2;
//	lzma_reserved_enum reserved_enum1;
//	lzma_reserved_enum reserved_enum2;
//
// Nowadays there are two more pointers between reserved_ptr2 and
// reserved_int1 and two size_t fields between reserved_int2 and
// reserved_enum1.
//
// When strm->internal->liblzma2_compat is set, limit the checks of
// reserved fields to fields that were present in the old ABI to avoid
// segfaults and spurious "Unsupported options" from callers sharing
// the process image that expect the old ABI.
extern LZMA_API(lzma_ret)
lzma_code(lzma_stream *strm, lzma_action action)
{
	// Sanity checks
	if ((strm->next_in == NULL && strm->avail_in != 0)
			|| (strm->next_out == NULL && strm->avail_out != 0)
			|| strm->internal == NULL
			|| strm->internal->next.code == NULL
			|| (unsigned int)(action) > LZMA_ACTION_MAX
			|| !strm->internal->supported_actions[action])
		return LZMA_PROG_ERROR;

	// Check if unsupported members have been set to non-zero or non-NULL,
	// which would indicate that some new feature is wanted.
	if (strm->reserved_ptr1 != NULL
			|| strm->reserved_ptr2 != NULL
			|| strm->reserved_ptr3 != NULL
			|| strm->reserved_ptr4 != NULL)
		return LZMA_OPTIONS_ERROR;

	if (strm->internal->liblzma2_compat)
		; /* Enough checks. */
	else if (strm->reserved_int1 != 0
			|| strm->reserved_int2 != 0
			|| strm->reserved_int3 != 0
			|| strm->reserved_int4 != 0
			|| strm->reserved_enum1 != LZMA_RESERVED_ENUM
			|| strm->reserved_enum2 != LZMA_RESERVED_ENUM)
		return LZMA_OPTIONS_ERROR;

	switch (strm->internal->sequence) {
	case ISEQ_RUN:
		switch (action) {
		case LZMA_RUN:
			break;

		case LZMA_SYNC_FLUSH:
			strm->internal->sequence = ISEQ_SYNC_FLUSH;
			break;

		case LZMA_FULL_FLUSH:
			strm->internal->sequence = ISEQ_FULL_FLUSH;
			break;

		case LZMA_FINISH:
			strm->internal->sequence = ISEQ_FINISH;
			break;

		case LZMA_FULL_BARRIER:
			strm->internal->sequence = ISEQ_FULL_BARRIER;
			break;
		}

		break;

	case ISEQ_SYNC_FLUSH:
		// The same action must be used until we return
		// LZMA_STREAM_END, and the amount of input must not change.
		if (action != LZMA_SYNC_FLUSH
				|| strm->internal->avail_in != strm->avail_in)
			return LZMA_PROG_ERROR;

		break;

	case ISEQ_FULL_FLUSH:
		if (action != LZMA_FULL_FLUSH
				|| strm->internal->avail_in != strm->avail_in)
			return LZMA_PROG_ERROR;

		break;

	case ISEQ_FINISH:
		if (action != LZMA_FINISH
				|| strm->internal->avail_in != strm->avail_in)
			return LZMA_PROG_ERROR;

		break;

	case ISEQ_FULL_BARRIER:
		if (action != LZMA_FULL_BARRIER
				|| strm->internal->avail_in != strm->avail_in)
			return LZMA_PROG_ERROR;

		break;

	case ISEQ_END:
		return LZMA_STREAM_END;

	case ISEQ_ERROR:
	default:
		return LZMA_PROG_ERROR;
	}

	size_t in_pos = 0;
	size_t out_pos = 0;
	lzma_ret ret = strm->internal->next.code(
			strm->internal->next.coder, strm->allocator,
			strm->next_in, &in_pos, strm->avail_in,
			strm->next_out, &out_pos, strm->avail_out, action);

	strm->next_in += in_pos;
	strm->avail_in -= in_pos;
	strm->total_in += in_pos;

	strm->next_out += out_pos;
	strm->avail_out -= out_pos;
	strm->total_out += out_pos;

	strm->internal->avail_in = strm->avail_in;

	// Cast is needed to silence a warning about LZMA_TIMED_OUT, which
	// isn't part of lzma_ret enumeration.
	switch ((unsigned int)(ret)) {
	case LZMA_OK:
		// Don't return LZMA_BUF_ERROR when it happens the first time.
		// This is to avoid returning LZMA_BUF_ERROR when avail_out
		// was zero but still there was no more data left to written
		// to next_out.
		if (out_pos == 0 && in_pos == 0) {
			if (strm->internal->allow_buf_error)
				ret = LZMA_BUF_ERROR;
			else
				strm->internal->allow_buf_error = true;
		} else {
			strm->internal->allow_buf_error = false;
		}
		break;

	case LZMA_TIMED_OUT:
		strm->internal->allow_buf_error = false;
		ret = LZMA_OK;
		break;

	case LZMA_STREAM_END:
		if (strm->internal->sequence == ISEQ_SYNC_FLUSH
				|| strm->internal->sequence == ISEQ_FULL_FLUSH
				|| strm->internal->sequence
					== ISEQ_FULL_BARRIER)
			strm->internal->sequence = ISEQ_RUN;
		else
			strm->internal->sequence = ISEQ_END;

	// Fall through

	case LZMA_NO_CHECK:
	case LZMA_UNSUPPORTED_CHECK:
	case LZMA_GET_CHECK:
	case LZMA_MEMLIMIT_ERROR:
		// Something else than LZMA_OK, but not a fatal error,
		// that is, coding may be continued (except if ISEQ_END).
		strm->internal->allow_buf_error = false;
		break;

	default:
		// All the other errors are fatal; coding cannot be continued.
		assert(ret != LZMA_BUF_ERROR);
		strm->internal->sequence = ISEQ_ERROR;
		break;
	}

	return ret;
}


extern LZMA_API(void)
lzma_end(lzma_stream *strm)
{
	if (strm != NULL && strm->internal != NULL) {
		lzma_next_end(&strm->internal->next, strm->allocator);
		lzma_free(strm->internal, strm->allocator);
		strm->internal = NULL;
	}

	return;
}


extern LZMA_API(void)
lzma_get_progress(lzma_stream *strm,
		uint64_t *progress_in, uint64_t *progress_out)
{
	if (strm->internal->next.get_progress != NULL) {
		strm->internal->next.get_progress(strm->internal->next.coder,
				progress_in, progress_out);
	} else {
		*progress_in = strm->total_in;
		*progress_out = strm->total_out;
	}

	return;
}


extern LZMA_API(lzma_check)
lzma_get_check(const lzma_stream *strm)
{
	// Return LZMA_CHECK_NONE if we cannot know the check type.
	// It's a bug in the application if this happens.
	if (strm->internal->next.get_check == NULL)
		return LZMA_CHECK_NONE;

	return strm->internal->next.get_check(strm->internal->next.coder);
}


extern LZMA_API(uint64_t)
lzma_memusage(const lzma_stream *strm)
{
	uint64_t memusage;
	uint64_t old_memlimit;

	if (strm == NULL || strm->internal == NULL
			|| strm->internal->next.memconfig == NULL
			|| strm->internal->next.memconfig(
				strm->internal->next.coder,
				&memusage, &old_memlimit, 0) != LZMA_OK)
		return 0;

	return memusage;
}


extern LZMA_API(uint64_t)
lzma_memlimit_get(const lzma_stream *strm)
{
	uint64_t old_memlimit;
	uint64_t memusage;

	if (strm == NULL || strm->internal == NULL
			|| strm->internal->next.memconfig == NULL
			|| strm->internal->next.memconfig(
				strm->internal->next.coder,
				&memusage, &old_memlimit, 0) != LZMA_OK)
		return 0;

	return old_memlimit;
}


extern LZMA_API(lzma_ret)
lzma_memlimit_set(lzma_stream *strm, uint64_t new_memlimit)
{
	// Dummy variables to simplify memconfig functions
	uint64_t old_memlimit;
	uint64_t memusage;

	if (strm == NULL || strm->internal == NULL
			|| strm->internal->next.memconfig == NULL)
		return LZMA_PROG_ERROR;

	if (new_memlimit != 0 && new_memlimit < LZMA_MEMUSAGE_BASE)
		return LZMA_MEMLIMIT_ERROR;

	return strm->internal->next.memconfig(strm->internal->next.coder,
			&memusage, &old_memlimit, new_memlimit);
}
