/*
 * Copyright (c) 2009-2013 Apple Inc. All rights reserved.
 *
 * @APPLE_APACHE_LICENSE_HEADER_START@
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @APPLE_APACHE_LICENSE_HEADER_END@
 */

#include "internal.h"

/*
 * Dispatch data objects are dispatch objects with standard retain/release
 * memory management. A dispatch data object either points to a number of other
 * dispatch data objects or is a leaf data object.
 * A composite data object specifies the total size of data it represents
 * and list of constituent records.
 *
 *******************************************************************************
 *
 * CURRENT IMPLEMENTATION DETAILS
 *
 *   There are actually 3 kinds of composite objects
 *   - trivial subranges
 *   - unflattened composite data objects
 *   - flattened composite data objects
 *
 * LEAVES (num_records == 0, destructor != nil)
 *
 *   Those objects have a pointer to represented memory in `buf`.
 *
 * UNFLATTENED (num_records > 1, buf == nil, destructor == nil)
 *
 *   This is the generic case of a composite object.
 *
 * FLATTENED (num_records > 1, buf != nil, destructor == nil)
 *
 *   Those objects are non trivial composite objects whose `buf` pointer
 *   is a contiguous representation (copied) of the memory it represents.
 *
 *   Such objects are created when used as an NSData and -bytes is called and
 *   where the dispatch data object is an unflattened composite object.
 *   The underlying implementation is _dispatch_data_get_flattened_bytes
 *
 * TRIVIAL SUBRANGES (num_records == 1, buf == nil, destructor == nil)
 *
 *   Those objects point to a single leaf, never to flattened objects.
 *
 *******************************************************************************
 *
 * Non trivial invariants:
 *
 *   It is forbidden to point into a composite data object and ignore entire
 *   records from it.  (for example by having `from` longer than the first
 *   record length).
 *
 *   dispatch_data_t's are either leaves, or composite objects pointing to
 *   leaves. Depth is never greater than 1.
 *
 *******************************************************************************
 *
 * There are 4 dispatch_data_t constructors who may create non leaf objects,
 * and ensure proper invariants.
 *
 * dispatch_data_copy_region()
 *    This function first sees through trivial subranges, and may in turn
 *    generate new trivial subranges.
 *
 * dispatch_data_create_map()
 *    This function either returns existing data objects, or a leaf.
 *
 * dispatch_data_create_subrange()
 *    This function treats flattened objects like unflattened ones,
 *    and recurses into trivial subranges, it can create trivial subranges.
 *
 * dispatch_data_create_concat()
 *    This function unwraps the top-level composite objects, trivial or not,
 *    and else concatenates the two arguments range lists, hence always creating
 *    unflattened objects, unless one of the arguments was empty.
 *
 *******************************************************************************
 */

#if DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
#define _dispatch_data_retain(x) _dispatch_objc_retain(x)
#define _dispatch_data_release(x) _dispatch_objc_release(x)
#else
#define _dispatch_data_retain(x) dispatch_retain(x)
#define _dispatch_data_release(x) dispatch_release(x)
#endif

DISPATCH_ALWAYS_INLINE
static inline dispatch_data_t
_dispatch_data_alloc(size_t n, size_t extra)
{
	dispatch_data_t data;
	size_t size;
	size_t base_size;

	if (os_add_overflow(sizeof(struct dispatch_data_s), extra, &base_size)) {
		return DISPATCH_OUT_OF_MEMORY;
	}
	if (os_mul_and_add_overflow(n, sizeof(range_record), base_size, &size)) {
		return DISPATCH_OUT_OF_MEMORY;
	}

	data = _dispatch_object_alloc(DISPATCH_DATA_CLASS, size);
	data->num_records = n;
#if !DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
	data->do_targetq = dispatch_get_global_queue(
			DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
	data->do_next = DISPATCH_OBJECT_LISTLESS;
#endif
	return data;
}

static void
_dispatch_data_destroy_buffer(const void* buffer, size_t size,
		dispatch_queue_t queue, dispatch_block_t destructor)
{
	if (destructor == DISPATCH_DATA_DESTRUCTOR_FREE) {
		free((void*)buffer);
	} else if (destructor == DISPATCH_DATA_DESTRUCTOR_NONE) {
		// do nothing
#if HAVE_MACH
	} else if (destructor == DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE) {
		mach_vm_size_t vm_size = size;
		mach_vm_address_t vm_addr = (uintptr_t)buffer;
		mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
#endif
	} else {
		if (!queue) {
			queue = dispatch_get_global_queue(
					DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
		}
		dispatch_async_f(queue, destructor, _dispatch_call_block_and_release);
	}
}

DISPATCH_ALWAYS_INLINE
static inline void
_dispatch_data_init(dispatch_data_t data, const void *buffer, size_t size,
		dispatch_queue_t queue, dispatch_block_t destructor)
{
	data->buf = buffer;
	data->size = size;
	data->destructor = destructor;
	if (queue) {
		_dispatch_retain(queue);
		data->do_targetq = queue;
	}
}

void
_dispatch_data_init_with_bytes(dispatch_data_t data, const void *buffer,
		size_t size, dispatch_block_t destructor)
{
	if (!buffer || !size) {
		if (destructor) {
			_dispatch_data_destroy_buffer(buffer, size, NULL,
					_dispatch_Block_copy(destructor));
		}
		buffer = NULL;
		size = 0;
		destructor = DISPATCH_DATA_DESTRUCTOR_NONE;
	}
	_dispatch_data_init(data, buffer, size, NULL, destructor);
}

dispatch_data_t
dispatch_data_create(const void* buffer, size_t size, dispatch_queue_t queue,
		dispatch_block_t destructor)
{
	dispatch_data_t data;
	void *data_buf = NULL;
	if (!buffer || !size) {
		// Empty data requested so return the singleton empty object. Call
		// destructor immediately in this case to ensure any unused associated
		// storage is released.
		if (destructor) {
			_dispatch_data_destroy_buffer(buffer, size, queue,
					_dispatch_Block_copy(destructor));
		}
		return dispatch_data_empty;
	}
	if (destructor == DISPATCH_DATA_DESTRUCTOR_DEFAULT) {
		// The default destructor was provided, indicating the data should be
		// copied.
		data_buf = malloc(size);
		if (slowpath(!data_buf)) {
			return DISPATCH_OUT_OF_MEMORY;
		}
		buffer = memcpy(data_buf, buffer, size);
		data = _dispatch_data_alloc(0, 0);
		destructor = DISPATCH_DATA_DESTRUCTOR_FREE;
	} else if (destructor == DISPATCH_DATA_DESTRUCTOR_INLINE) {
		data = _dispatch_data_alloc(0, size);
		buffer = memcpy((void*)data + sizeof(struct dispatch_data_s), buffer,
				size);
		destructor = DISPATCH_DATA_DESTRUCTOR_NONE;
	} else {
		data = _dispatch_data_alloc(0, 0);
		destructor = _dispatch_Block_copy(destructor);
	}
	_dispatch_data_init(data, buffer, size, queue, destructor);
	return data;
}

dispatch_data_t
dispatch_data_create_f(const void *buffer, size_t size, dispatch_queue_t queue,
		dispatch_function_t destructor_function)
{
	dispatch_block_t destructor = (dispatch_block_t)destructor_function;
	if (destructor != DISPATCH_DATA_DESTRUCTOR_DEFAULT &&
			destructor != DISPATCH_DATA_DESTRUCTOR_FREE &&
			destructor != DISPATCH_DATA_DESTRUCTOR_NONE &&
#if HAVE_MACH
			destructor != DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE &&
#endif
			destructor != DISPATCH_DATA_DESTRUCTOR_INLINE) {
		destructor = ^{ destructor_function((void*)buffer); };
	}
	return dispatch_data_create(buffer, size, queue, destructor);
}

dispatch_data_t
dispatch_data_create_alloc(size_t size, void** buffer_ptr)
{
	dispatch_data_t data = dispatch_data_empty;
	void *buffer = NULL;

	if (slowpath(!size)) {
		goto out;
	}
	data = _dispatch_data_alloc(0, size);
	buffer = (void*)data + sizeof(struct dispatch_data_s);
	_dispatch_data_init(data, buffer, size, NULL,
			DISPATCH_DATA_DESTRUCTOR_NONE);
out:
	if (buffer_ptr) {
		*buffer_ptr = buffer;
	}
	return data;
}

void
_dispatch_data_dispose(dispatch_data_t dd, DISPATCH_UNUSED bool *allow_free)
{
	if (_dispatch_data_leaf(dd)) {
		_dispatch_data_destroy_buffer(dd->buf, dd->size, dd->do_targetq,
				dd->destructor);
	} else {
		size_t i;
		for (i = 0; i < _dispatch_data_num_records(dd); ++i) {
			_dispatch_data_release(dd->records[i].data_object);
		}
		free((void *)dd->buf);
	}
}

void
_dispatch_data_set_target_queue(dispatch_data_t dd, dispatch_queue_t tq)
{
#if DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
	_dispatch_retain(tq);
	tq = os_atomic_xchg2o(dd, do_targetq, tq, release);
	if (tq) _dispatch_release(tq);
#else
	_dispatch_object_set_target_queue_inline(dd, tq);
#endif
}

size_t
_dispatch_data_debug(dispatch_data_t dd, char* buf, size_t bufsiz)
{
	size_t offset = 0;
	offset += dsnprintf(&buf[offset], bufsiz - offset, "data[%p] = { ", dd);
	if (_dispatch_data_leaf(dd)) {
		offset += dsnprintf(&buf[offset], bufsiz - offset,
				"leaf, size = %zd, buf = %p ", dd->size, dd->buf);
	} else {
		offset += dsnprintf(&buf[offset], bufsiz - offset,
				"composite, size = %zd, num_records = %zd ", dd->size,
				_dispatch_data_num_records(dd));
		if (dd->buf) {
			offset += dsnprintf(&buf[offset], bufsiz - offset,
					", flatbuf = %p ", dd->buf);
		}
		size_t i;
		for (i = 0; i < _dispatch_data_num_records(dd); ++i) {
			range_record r = dd->records[i];
			offset += dsnprintf(&buf[offset], bufsiz - offset, "record[%zd] = "
					"{ from = %zd, length = %zd, data_object = %p }, ", i,
					r.from, r.length, r.data_object);
		}
	}
	offset += dsnprintf(&buf[offset], bufsiz - offset, "}");
	return offset;
}

size_t
dispatch_data_get_size(dispatch_data_t dd)
{
	return dd->size;
}

dispatch_data_t
dispatch_data_create_concat(dispatch_data_t dd1, dispatch_data_t dd2)
{
	dispatch_data_t data;
	size_t n;

	if (!dd1->size) {
		_dispatch_data_retain(dd2);
		return dd2;
	}
	if (!dd2->size) {
		_dispatch_data_retain(dd1);
		return dd1;
	}

	if (os_add_overflow(_dispatch_data_num_records(dd1),
			_dispatch_data_num_records(dd2), &n)) {
		return DISPATCH_OUT_OF_MEMORY;
	}
	data = _dispatch_data_alloc(n, 0);
	data->size = dd1->size + dd2->size;
	// Copy the constituent records into the newly created data object
	// Reference leaf objects as sub-objects
	if (_dispatch_data_leaf(dd1)) {
		data->records[0].from = 0;
		data->records[0].length = dd1->size;
		data->records[0].data_object = dd1;
	} else {
		memcpy(data->records, dd1->records, _dispatch_data_num_records(dd1) *
				sizeof(range_record));
	}
	if (_dispatch_data_leaf(dd2)) {
		data->records[_dispatch_data_num_records(dd1)].from = 0;
		data->records[_dispatch_data_num_records(dd1)].length = dd2->size;
		data->records[_dispatch_data_num_records(dd1)].data_object = dd2;
	} else {
		memcpy(data->records + _dispatch_data_num_records(dd1), dd2->records,
				_dispatch_data_num_records(dd2) * sizeof(range_record));
	}
	size_t i;
	for (i = 0; i < _dispatch_data_num_records(data); ++i) {
		_dispatch_data_retain(data->records[i].data_object);
	}
	return data;
}

dispatch_data_t
dispatch_data_create_subrange(dispatch_data_t dd, size_t offset,
		size_t length)
{
	dispatch_data_t data;

	if (offset >= dd->size || !length) {
		return dispatch_data_empty;
	} else if (length > dd->size - offset) {
		length = dd->size - offset;
	} else if (length == dd->size) {
		_dispatch_data_retain(dd);
		return dd;
	}
	/*
	 * we must only optimize leaves and not flattened objects
	 * because lots of users want to keep the end of a buffer and release
	 * as much memory as they can from the beginning of it
	 *
	 * Using the flatbuf here would be very wrong with respect to that goal
	 */
	if (_dispatch_data_leaf(dd)) {
		data = _dispatch_data_alloc(1, 0);
		data->size = length;
		data->records[0].from = offset;
		data->records[0].length = length;
		data->records[0].data_object = dd;
		_dispatch_data_retain(dd);
		return data;
	}

	// Subrange of a composite dispatch data object
	const size_t dd_num_records = _dispatch_data_num_records(dd);
	bool to_the_end = (offset + length == dd->size);
	size_t i = 0;

	// find the record containing the specified offset
	while (i < dd_num_records && offset >= dd->records[i].length) {
		offset -= dd->records[i++].length;
	}

	// Crashing here indicates memory corruption of passed in data object
	if (slowpath(i >= dd_num_records)) {
		DISPATCH_INTERNAL_CRASH(i,
				"dispatch_data_create_subrange out of bounds");
	}

	// if everything is from a single dispatch data object, avoid boxing it
	if (offset + length <= dd->records[i].length) {
		return dispatch_data_create_subrange(dd->records[i].data_object,
				dd->records[i].from + offset, length);
	}

	// find the record containing the end of the current range
	// and optimize the case when you just remove bytes at the origin
	size_t count, last_length = 0;

	if (to_the_end) {
		count = dd_num_records - i;
	} else {
		last_length = length - (dd->records[i].length - offset);
		count = 1;

		while (i + count < dd_num_records) {
			size_t record_length = dd->records[i + count++].length;

			if (last_length <= record_length) {
				break;
			}
			last_length -= record_length;

			// Crashing here indicates memory corruption of passed in data object
			if (slowpath(i + count >= dd_num_records)) {
				DISPATCH_INTERNAL_CRASH(i + count,
						"dispatch_data_create_subrange out of bounds");
			}
		}
	}

	data = _dispatch_data_alloc(count, 0);
	data->size = length;
	memcpy(data->records, dd->records + i, count * sizeof(range_record));

	if (offset) {
		data->records[0].from += offset;
		data->records[0].length -= offset;
	}
	if (!to_the_end) {
		data->records[count - 1].length = last_length;
	}

	for (i = 0; i < count; i++) {
		_dispatch_data_retain(data->records[i].data_object);
	}
	return data;
}

static void*
_dispatch_data_flatten(dispatch_data_t dd)
{
	void *buffer = malloc(dd->size);

	// Composite data object, copy the represented buffers
	if (buffer) {
		dispatch_data_apply(dd, ^(dispatch_data_t region DISPATCH_UNUSED,
				size_t off, const void* buf, size_t len) {
			memcpy(buffer + off, buf, len);
			return (bool)true;
		});
	}

	return buffer;
}

// When mapping a leaf object or a subrange of a leaf object, return a direct
// pointer to the represented buffer. For all other data objects, copy the
// represented buffers into a contiguous area. In the future it might
// be possible to relocate the buffers instead (if not marked as locked).
dispatch_data_t
dispatch_data_create_map(dispatch_data_t dd, const void **buffer_ptr,
		size_t *size_ptr)
{
	dispatch_data_t data = NULL;
	const void *buffer = NULL;
	size_t size = dd->size;

	if (!size) {
		data = dispatch_data_empty;
		goto out;
	}

	buffer = _dispatch_data_map_direct(dd, 0, NULL, NULL);
	if (buffer) {
		_dispatch_data_retain(dd);
		data = dd;
		goto out;
	}

	buffer = _dispatch_data_flatten(dd);
	if (fastpath(buffer)) {
		data = dispatch_data_create(buffer, size, NULL,
				DISPATCH_DATA_DESTRUCTOR_FREE);
	} else {
		size = 0;
	}

out:
	if (buffer_ptr) {
		*buffer_ptr = buffer;
	}
	if (size_ptr) {
		*size_ptr = size;
	}
	return data;
}

const void *
_dispatch_data_get_flattened_bytes(dispatch_data_t dd)
{
	const void *buffer;
	size_t offset = 0;

	if (slowpath(!dd->size)) {
		return NULL;
	}

	buffer = _dispatch_data_map_direct(dd, 0, &dd, &offset);
	if (buffer) {
		return buffer;
	}

	void *flatbuf = _dispatch_data_flatten(dd);
	if (fastpath(flatbuf)) {
		// we need a release so that readers see the content of the buffer
		if (slowpath(!os_atomic_cmpxchgv2o(dd, buf, NULL, flatbuf,
				&buffer, release))) {
			free(flatbuf);
		} else {
			buffer = flatbuf;
		}
	} else {
		return NULL;
	}

	return buffer + offset;
}

#if DISPATCH_USE_CLIENT_CALLOUT
DISPATCH_NOINLINE
#else
DISPATCH_ALWAYS_INLINE
#endif
static bool
_dispatch_data_apply_client_callout(void *ctxt, dispatch_data_t region, size_t offset,
		const void *buffer, size_t size, dispatch_data_applier_function_t f)
{
	return f(ctxt, region, offset, buffer, size);
}


static bool
_dispatch_data_apply(dispatch_data_t dd, size_t offset, size_t from,
		size_t size, void *ctxt, dispatch_data_applier_function_t applier)
{
	bool result = true;
	const void *buffer;

	buffer = _dispatch_data_map_direct(dd, 0, NULL, NULL);
	if (buffer) {
		return _dispatch_data_apply_client_callout(ctxt, dd,
				offset, buffer + from, size, applier);
	}

	size_t i;
	for (i = 0; i < _dispatch_data_num_records(dd) && result; ++i) {
		result = _dispatch_data_apply(dd->records[i].data_object,
				offset, dd->records[i].from, dd->records[i].length, ctxt,
				applier);
		offset += dd->records[i].length;
	}
	return result;
}

bool
dispatch_data_apply_f(dispatch_data_t dd, void *ctxt,
		dispatch_data_applier_function_t applier)
{
	if (!dd->size) {
		return true;
	}
	return _dispatch_data_apply(dd, 0, 0, dd->size, ctxt, applier);
}

bool
dispatch_data_apply(dispatch_data_t dd, dispatch_data_applier_t applier)
{
	if (!dd->size) {
		return true;
	}
	return _dispatch_data_apply(dd, 0, 0, dd->size, applier,
			(dispatch_data_applier_function_t)_dispatch_Block_invoke(applier));
}

static dispatch_data_t
_dispatch_data_copy_region(dispatch_data_t dd, size_t from, size_t size,
		size_t location, size_t *offset_ptr)
{
	dispatch_data_t reusable_dd = NULL;
	size_t offset = 0;

	if (from == 0 && size == dd->size) {
		reusable_dd = dd;
	}

	if (_dispatch_data_map_direct(dd, from, &dd, &from)) {
		if (reusable_dd) {
			_dispatch_data_retain(reusable_dd);
			return reusable_dd;
		}

		_dispatch_data_retain(dd);
		if (from == 0 && size == dd->size) {
			return dd;
		}

		dispatch_data_t data = _dispatch_data_alloc(1, 0);
		data->size = size;
		data->records[0].from = from;
		data->records[0].length = size;
		data->records[0].data_object = dd;
		return data;
	}

	size_t i;
	for (i = 0; i < _dispatch_data_num_records(dd); ++i) {
		size_t length = dd->records[i].length;

		if (from >= length) {
			from -= length;
			continue;
		}

		length -= from;
		if (location >= offset + length) {
			offset += length;
			from = 0;
			continue;
		}

		from += dd->records[i].from;
		dd = dd->records[i].data_object;
		*offset_ptr += offset;
		location -= offset;
		return _dispatch_data_copy_region(dd, from, length, location, offset_ptr);
	}

	DISPATCH_INTERNAL_CRASH(*offset_ptr+offset,
			"dispatch_data_copy_region out of bounds");
}

// Returs either a leaf object or an object composed of a single leaf object
dispatch_data_t
dispatch_data_copy_region(dispatch_data_t dd, size_t location,
		size_t *offset_ptr)
{
	if (location >= dd->size) {
		*offset_ptr = dd->size;
		return dispatch_data_empty;
	}
	*offset_ptr = 0;
	return _dispatch_data_copy_region(dd, 0, dd->size, location, offset_ptr);
}

#if HAVE_MACH

#ifndef MAP_MEM_VM_COPY
#define MAP_MEM_VM_COPY 0x200000 // <rdar://problem/13336613>
#endif

mach_port_t
dispatch_data_make_memory_entry(dispatch_data_t dd)
{
	mach_port_t mep = MACH_PORT_NULL;
	memory_object_size_t mos;
	mach_vm_size_t vm_size = dd->size;
	mach_vm_address_t vm_addr;
	vm_prot_t flags;
	kern_return_t kr;
	bool copy = (dd->destructor != DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE);

retry:
	if (copy) {
		vm_addr = vm_page_size;
		kr = mach_vm_allocate(mach_task_self(), &vm_addr, vm_size,
				VM_FLAGS_ANYWHERE);
		if (kr) {
			if (kr != KERN_NO_SPACE) {
				(void)dispatch_assume_zero(kr);
			}
			return mep;
		}
		dispatch_data_apply(dd, ^(dispatch_data_t region DISPATCH_UNUSED,
				size_t off, const void* buf, size_t len) {
			memcpy((void*)(vm_addr + off), buf, len);
			return (bool)true;
		});
	} else {
		vm_addr = (uintptr_t)dd->buf;
	}
	flags = VM_PROT_DEFAULT|VM_PROT_IS_MASK|MAP_MEM_VM_COPY;
	mos = vm_size;
	kr = mach_make_memory_entry_64(mach_task_self(), &mos, vm_addr, flags,
			&mep, MACH_PORT_NULL);
	if (kr == KERN_INVALID_VALUE) {
		// Fallback in case MAP_MEM_VM_COPY is not supported
		flags &= ~MAP_MEM_VM_COPY;
		kr = mach_make_memory_entry_64(mach_task_self(), &mos, vm_addr, flags,
				&mep, MACH_PORT_NULL);
	}
	if (dispatch_assume_zero(kr)) {
		mep = MACH_PORT_NULL;
	} else if (mos < vm_size) {
		// Memory object was truncated, e.g. due to lack of MAP_MEM_VM_COPY
		kr = mach_port_deallocate(mach_task_self(), mep);
		(void)dispatch_assume_zero(kr);
		if (!copy) {
			copy = true;
			goto retry;
		}
		mep = MACH_PORT_NULL;
	}
	if (copy) {
		kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
		(void)dispatch_assume_zero(kr);
	}
	return mep;
}
#endif // HAVE_MACH
