/*
 *  duk_hbuffer allocation and freeing.
 */

#include "duk_internal.h"

/* Allocate a new duk_hbuffer of a certain type and return a pointer to it
 * (NULL on error).  Write buffer data pointer to 'out_bufdata' (only if
 * allocation successful).
 */
DUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_small_uint_t flags, void **out_bufdata) {
	duk_hbuffer *res = NULL;
	duk_size_t header_size;
	duk_size_t alloc_size;

	DUK_ASSERT(heap != NULL);
	DUK_ASSERT(out_bufdata != NULL);

	DUK_DDD(DUK_DDDPRINT("allocate hbuffer"));

	/* Size sanity check.  Should not be necessary because caller is
	 * required to check this, but we don't want to cause a segfault
	 * if the size wraps either in duk_size_t computation or when
	 * storing the size in a 16-bit field.
	 */
	if (size > DUK_HBUFFER_MAX_BYTELEN) {
		DUK_D(DUK_DPRINT("hbuffer alloc failed: size too large: %ld", (long) size));
		return NULL;  /* no need to write 'out_bufdata' */
	}

	if (flags & DUK_BUF_FLAG_EXTERNAL) {
		header_size = sizeof(duk_hbuffer_external);
		alloc_size = sizeof(duk_hbuffer_external);
	} else if (flags & DUK_BUF_FLAG_DYNAMIC) {
		header_size = sizeof(duk_hbuffer_dynamic);
		alloc_size = sizeof(duk_hbuffer_dynamic);
	} else {
		header_size = sizeof(duk_hbuffer_fixed);
		alloc_size = sizeof(duk_hbuffer_fixed) + size;
		DUK_ASSERT(alloc_size >= sizeof(duk_hbuffer_fixed));  /* no wrapping */
	}

	res = (duk_hbuffer *) DUK_ALLOC(heap, alloc_size);
	if (!res) {
		goto error;
	}

	/* zero everything unless requested not to do so */
#if defined(DUK_USE_ZERO_BUFFER_DATA)
	DUK_MEMZERO((void *) res,
	            (flags & DUK_BUF_FLAG_NOZERO) ? header_size : alloc_size);
#else
	DUK_MEMZERO((void *) res, header_size);
#endif

	if (flags & DUK_BUF_FLAG_EXTERNAL) {
		duk_hbuffer_external *h;
		h = (duk_hbuffer_external *) res;
		DUK_UNREF(h);
		*out_bufdata = NULL;
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
#if defined(DUK_USE_HEAPPTR16)
/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */
#else
		DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap, h, NULL);
#endif
#endif
		DUK_ASSERT(DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap, h) == NULL);
	} else if (flags & DUK_BUF_FLAG_DYNAMIC) {
		duk_hbuffer_dynamic *h = (duk_hbuffer_dynamic *) res;
		void *ptr;

		if (size > 0) {
			DUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL));  /* alloc external with size zero */
			DUK_DDD(DUK_DDDPRINT("dynamic buffer with nonzero size, alloc actual buffer"));
#ifdef DUK_USE_ZERO_BUFFER_DATA
			ptr = DUK_ALLOC_ZEROED(heap, size);
#else
			ptr = DUK_ALLOC(heap, size);
#endif
			if (!ptr) {
				/* Because size > 0, NULL check is correct */
				goto error;
			}
			*out_bufdata = ptr;

			DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, ptr);
		} else {
			*out_bufdata = NULL;
#if defined(DUK_USE_EXPLICIT_NULL_INIT)
#if defined(DUK_USE_HEAPPTR16)
/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */
#else
			DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, NULL);
#endif
#endif
			DUK_ASSERT(DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, h) == NULL);
		}
	} else {
		*out_bufdata = (void *) ((duk_hbuffer_fixed *) res + 1);
	}

	DUK_HBUFFER_SET_SIZE(res, size);

	DUK_HEAPHDR_SET_TYPE(&res->hdr, DUK_HTYPE_BUFFER);
	if (flags & DUK_BUF_FLAG_DYNAMIC) {
		DUK_HBUFFER_SET_DYNAMIC(res);
		if (flags & DUK_BUF_FLAG_EXTERNAL) {
			DUK_HBUFFER_SET_EXTERNAL(res);
		}
	} else {
		DUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL));
	}
        DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &res->hdr);

	DUK_DDD(DUK_DDDPRINT("allocated hbuffer: %p", (void *) res));
	return res;

 error:
	DUK_DD(DUK_DDPRINT("hbuffer allocation failed"));

	DUK_FREE(heap, res);
	return NULL;  /* no need to write 'out_bufdata' */
}

/* For indirect allocs. */

DUK_INTERNAL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud) {
	duk_hbuffer_dynamic *buf = (duk_hbuffer_dynamic *) ud;
	DUK_UNREF(heap);
	return (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, buf);
}
