/*
 * Copyright (c) 2011-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"

#ifdef __APPLE__
#include <libkern/OSByteOrder.h>
#elif __linux__
#include <endian.h>
#define OSLittleEndian __LITTLE_ENDIAN
#define OSBigEndian __BIG_ENDIAN
#elif defined(__FreeBSD__)
#include <sys/endian.h>
#define OSLittleEndian _LITTLE_ENDIAN
#define OSBigEndian _BIG_ENDIAN
#elif defined(_WIN32)
#define OSLittleEndian 1234
#define OSBigEndian 4321
#endif

#if defined(__linux__) || defined(__FreeBSD__)
#define OSSwapLittleToHostInt16 le16toh
#define OSSwapBigToHostInt16 be16toh
#define OSSwapHostToLittleInt16 htole16
#define OSSwapHostToBigInt16 htobe16
#elif defined(_WIN32)
#define OSSwapLittleToHostInt16
#define OSSwapBigToHostInt16 ntohs
#define OSSwapHostToLittleInt16
#define OSSwapHostToBigInt16 htons
#endif

#if defined(__LITTLE_ENDIAN__)
#define DISPATCH_DATA_FORMAT_TYPE_UTF16_HOST DISPATCH_DATA_FORMAT_TYPE_UTF16LE
#define DISPATCH_DATA_FORMAT_TYPE_UTF16_REV DISPATCH_DATA_FORMAT_TYPE_UTF16BE
#elif defined(__BIG_ENDIAN__)
#define DISPATCH_DATA_FORMAT_TYPE_UTF16_HOST DISPATCH_DATA_FORMAT_TYPE_UTF16BE
#define DISPATCH_DATA_FORMAT_TYPE_UTF16_REV DISPATCH_DATA_FORMAT_TYPE_UTF16LE
#else
#error Unsupported Endianness
#endif

enum {
	_DISPATCH_DATA_FORMAT_NONE = 0x1,
	_DISPATCH_DATA_FORMAT_UTF8 = 0x2,
	_DISPATCH_DATA_FORMAT_UTF16LE = 0x4,
	_DISPATCH_DATA_FORMAT_UTF16BE = 0x8,
	_DISPATCH_DATA_FORMAT_UTF_ANY = 0x10,
	_DISPATCH_DATA_FORMAT_BASE32 = 0x20,
	_DISPATCH_DATA_FORMAT_BASE32HEX = 0x40,
	_DISPATCH_DATA_FORMAT_BASE64 = 0x80,
};

#pragma mark -
#pragma mark baseXX tables

static const unsigned char base32_encode_table[] =
		"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";

static const signed char base32_decode_table[] = {
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26,
	27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -2, -1, -1, -1,  0,  1,  2,
	 3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
	20, 21, 22, 23, 24, 25
};
static const ssize_t base32_decode_table_size =
		sizeof(base32_decode_table) / sizeof(*base32_decode_table);

static const unsigned char base32hex_encode_table[] =
		"0123456789ABCDEFGHIJKLMNOPQRSTUV";

static const signed char base32hex_decode_table[] = {
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,  1,  2,
	 3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -2, -1, -1, -1, 10, 11, 12,
	13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
	30, 31
};
static const ssize_t base32hex_decode_table_size =
		sizeof(base32hex_encode_table) / sizeof(*base32hex_encode_table);

static const unsigned char base64_encode_table[] =
		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static const signed char base64_decode_table[] = {
	-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
	-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
	-1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
	-1,  62,  -1,  -1,  -1,  63,  52,  53,  54,  55,  56,  57,  58,  59,
	60,  61,  -1,  -1,  -1,  -2,  -1,  -1,  -1,   0,   1,   2,   3,   4,
	 5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
	19,  20,  21,  22,  23,  24,  25,  -1,  -1,  -1,  -1,  -1,  -1,  26,
	27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,
	41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51
};

static const ssize_t base64_decode_table_size =
		sizeof(base64_decode_table) / sizeof(*base64_decode_table);

#pragma mark -
#pragma mark dispatch_transform_buffer

typedef struct dispatch_transform_buffer_s {
	dispatch_data_t data;
	uint8_t *start;
	union {
		uint8_t *u8;
		uint16_t *u16;
	} ptr;
	size_t size;
} dispatch_transform_buffer_s;

#define BUFFER_MALLOC_MAX (100*1024*1024)

static bool
_dispatch_transform_buffer_new(dispatch_transform_buffer_s *buffer,
		size_t required, size_t size)
{
	size_t remaining = buffer->size - (size_t)(buffer->ptr.u8 - buffer->start);
	if (required == 0 || remaining < required) {
		if (buffer->start) {
			if (buffer->ptr.u8 > buffer->start) {
				dispatch_data_t _new = dispatch_data_create(buffer->start,
						(size_t)(buffer->ptr.u8 - buffer->start), NULL,
						DISPATCH_DATA_DESTRUCTOR_FREE);
				dispatch_data_t _concat = dispatch_data_create_concat(
						buffer->data, _new);
				dispatch_release(_new);
				dispatch_release(buffer->data);
				buffer->data = _concat;
			} else {
				free(buffer->start);
			}
		}
		buffer->size = required + size;
		buffer->start = NULL;
		if (buffer->size > 0) {
			if (buffer->size > BUFFER_MALLOC_MAX) {
				return false;
			}
			buffer->start = (uint8_t*)malloc(buffer->size);
			if (buffer->start == NULL) {
				return false;
			}
		}
		buffer->ptr.u8 = buffer->start;
	}
	return true;
}

#pragma mark -
#pragma mark dispatch_transform_helpers

static dispatch_data_t
_dispatch_data_subrange_map(dispatch_data_t data, const void **ptr,
		size_t offset, size_t size)
{
	dispatch_data_t subrange, map = NULL;

	subrange = dispatch_data_create_subrange(data, offset, size);
	if (dispatch_data_get_size(subrange) == size) {
		map = dispatch_data_create_map(subrange, ptr, NULL);
	}
	dispatch_release(subrange);
	return map;
}

static dispatch_data_format_type_t
_dispatch_transform_detect_utf(dispatch_data_t data)
{
	const void *p;
	dispatch_data_t subrange = _dispatch_data_subrange_map(data, &p, 0, 2);

	if (subrange == NULL) {
		return NULL;
	}

	const uint16_t ch = *(const uint16_t *)p;
	dispatch_data_format_type_t type = DISPATCH_DATA_FORMAT_TYPE_UTF8;

	if (ch == 0xfeff) {
		type = DISPATCH_DATA_FORMAT_TYPE_UTF16_HOST;
	} else if (ch == 0xfffe) {
		type = DISPATCH_DATA_FORMAT_TYPE_UTF16_REV;
	}

	dispatch_release(subrange);

	return type;
}

static uint16_t
_dispatch_transform_swap_to_host(uint16_t x, int32_t byteOrder)
{
	if (byteOrder == OSLittleEndian) {
		return OSSwapLittleToHostInt16(x);
	}
	return OSSwapBigToHostInt16(x);
}

static uint16_t
_dispatch_transform_swap_from_host(uint16_t x, int32_t byteOrder)
{
	if (byteOrder == OSLittleEndian) {
		return OSSwapHostToLittleInt16(x);
	}
	return OSSwapHostToBigInt16(x);
}

#pragma mark -
#pragma mark UTF-8

static uint8_t
_dispatch_transform_utf8_length(uint8_t byte)
{
	if ((byte & 0x80) == 0) {
		return 1;
	} else if ((byte & 0xe0) == 0xc0) {
		return 2;
	} else if ((byte & 0xf0) == 0xe0) {
		return 3;
	} else if ((byte & 0xf8) == 0xf0) {
		return 4;
	}
	return 0;
}

static uint32_t
_dispatch_transform_read_utf8_sequence(const uint8_t *bytes)
{
	uint32_t wch = 0;
	uint8_t seq_length = _dispatch_transform_utf8_length(*bytes);

	switch (seq_length) {
	case 4:
		wch |= (*bytes & 0x7);
		wch <<= 6;
		break;
	case 3:
		wch |= (*bytes & 0xf);
		wch <<= 6;
		break;
	case 2:
		wch |= (*bytes & 0x1f);
		wch <<= 6;
		break;
	case 1:
		wch = (*bytes & 0x7f);
		break;
	default:
		// Not a utf-8 sequence
		break;
	}

	bytes++;
	seq_length--;

	while (seq_length > 0) {
		wch |= (*bytes & 0x3f);
		bytes++;
		seq_length--;

		if (seq_length > 0) {
			wch <<= 6;
		}
	}
	return wch;
}

#pragma mark -
#pragma mark UTF-16

static dispatch_data_t
_dispatch_transform_to_utf16(dispatch_data_t data, int32_t byteOrder)
{
	__block size_t skip = 0;

	__block dispatch_transform_buffer_s buffer = {
		.data = dispatch_data_empty,
	};

	bool success = dispatch_data_apply(data, ^(
			DISPATCH_UNUSED dispatch_data_t region,
			size_t offset, const void *_buffer, size_t size) {
		const uint8_t *src = _buffer;
		size_t i, dest_size;

		if (offset == 0) {
			if (os_mul_and_add_overflow(size, sizeof(uint16_t),
					sizeof(uint16_t), &dest_size)) {
				return (bool)false;
			}
			if (!_dispatch_transform_buffer_new(&buffer, dest_size, 0)) {
				return (bool)false;
			}
			// Insert BOM
			*(buffer.ptr.u16)++ = _dispatch_transform_swap_from_host(0xfeff,
					byteOrder);
		}

		// Skip is incremented if the previous block read-ahead into our block
		if (skip >= size) {
			skip -= size;
			return (bool)true;
		} else if (skip > 0) {
			src += skip;
			size -= skip;
			skip = 0;
		}

		for (i = 0; i < size;) {
			uint32_t wch = 0;
			uint8_t byte_size = _dispatch_transform_utf8_length(*src);
			size_t next;

			if (byte_size == 0) {
				return (bool)false;
			} else if (byte_size + i > size) {
				// UTF-8 byte sequence spans over into the next block(s)
				const void *p;
				dispatch_data_t subrange = _dispatch_data_subrange_map(data, &p,
						offset + i, byte_size);
				if (subrange == NULL) {
					return (bool)false;
				}

				wch = _dispatch_transform_read_utf8_sequence(p);
				skip += byte_size - (size - i);
				src += byte_size;
				i = size;

				dispatch_release(subrange);
			} else {
				wch = _dispatch_transform_read_utf8_sequence(src);
				src += byte_size;
				i += byte_size;
			}

			if (os_mul_overflow(size - i, sizeof(uint16_t), &next)) {
				return (bool)false;
			}
			if (wch == 0xfeff && offset + i == 3) {
				// skip the BOM if any, as we already inserted one ourselves
			} else if (wch >= 0xd800 && wch < 0xdfff) {
				// Illegal range (surrogate pair)
				return (bool)false;
			} else if (wch >= 0x10000) {
				// Surrogate pair
				if (!_dispatch_transform_buffer_new(&buffer, 2 *
						sizeof(uint16_t), next)) {
					return (bool)false;
				}
				wch -= 0x10000;
				*(buffer.ptr.u16)++ = _dispatch_transform_swap_from_host(
						((wch >> 10) & 0x3ff) + 0xd800, byteOrder);
				*(buffer.ptr.u16)++ = _dispatch_transform_swap_from_host(
						(wch & 0x3ff) + 0xdc00, byteOrder);
			} else {
				if (!_dispatch_transform_buffer_new(&buffer, 1 *
						sizeof(uint16_t), next)) {
					return (bool)false;
				}
				*(buffer.ptr.u16)++ = _dispatch_transform_swap_from_host(
						(wch & 0xffff), byteOrder);
			}
		}

		(void)_dispatch_transform_buffer_new(&buffer, 0, 0);

		return (bool)true;
	});

	if (!success) {
		(void)_dispatch_transform_buffer_new(&buffer, 0, 0);
		dispatch_release(buffer.data);
		return NULL;
	}

	return buffer.data;
}

static dispatch_data_t
_dispatch_transform_from_utf16(dispatch_data_t data, int32_t byteOrder)
{
	__block size_t skip = 0;

	__block dispatch_transform_buffer_s buffer = {
		.data = dispatch_data_empty,
	};

	bool success = dispatch_data_apply(data, ^(
			DISPATCH_UNUSED dispatch_data_t region, size_t offset,
			const void *_buffer, size_t size) {
		const uint16_t *src = _buffer;

		if (offset == 0) {
			size_t dest_size = howmany(size, 3) * 2;
			// Assume first buffer will be mostly single-byte UTF-8 sequences
			if (!_dispatch_transform_buffer_new(&buffer, dest_size, 0)) {
				return (bool)false;
			}
		}

		size_t i = 0, max = size / 2;

		// Skip is incremented if the previous block read-ahead into our block
		if (skip >= size) {
			skip -= size;
			return (bool)true;
		} else if (skip > 0) {
			src = (uint16_t *)(((uint8_t *)src) + skip);
			size -= skip;
			max = (size / 2);
			skip = 0;
		}

		// If the buffer is an odd size, allow read ahead into the next region
		if ((size % 2) != 0) {
			max += 1;
		}

		for (i = 0; i < max; i++) {
			uint32_t wch = 0;
			uint16_t ch;
			size_t next;

			if ((i == (max - 1)) && (max > (size / 2))) {
				// Last byte of an odd sized range
				const void *p;
				dispatch_data_t range = _dispatch_data_subrange_map(data, &p,
						offset + (i * 2), 2);
				if (range == NULL) {
					return (bool)false;
				}
				ch = _dispatch_transform_swap_to_host((uint16_t)*(uint64_t*)p,
						byteOrder);
				dispatch_release(range);
				skip += 1;
			} else {
				ch =  _dispatch_transform_swap_to_host(src[i], byteOrder);
			}

			if (ch == 0xfffe && offset == 0 && i == 0) {
				// Wrong-endian BOM at beginning of data
				return (bool)false;
			} else if (ch == 0xfeff && offset == 0 && i == 0) {
				// Correct-endian BOM, skip it
				continue;
			}

			if ((ch >= 0xd800) && (ch <= 0xdbff)) {
				// Surrogate pair
				wch = ((ch - 0xd800u) << 10);
				if (++i >= max) {
					// Surrogate byte isn't in this block
					const void *p;
					dispatch_data_t range = _dispatch_data_subrange_map(data,
							&p, offset + (i * 2), 2);
					if (range == NULL) {
						return (bool)false;
					}
					ch = _dispatch_transform_swap_to_host(*(uint16_t *)p,
							byteOrder);
					dispatch_release(range);
					skip += 2;
				} else {
					ch = _dispatch_transform_swap_to_host(src[i], byteOrder);
				}
				if (!((ch >= 0xdc00) && (ch <= 0xdfff))) {
					return (bool)false;
				}
				wch = (wch | (ch & 0x3ff));
				wch += 0x10000;
			} else if ((ch >= 0xdc00) && (ch <= 0xdfff)) {
				return (bool)false;
			} else {
				wch = ch;
			}

			if (os_mul_overflow(max - i, 2, &next)) {
				return (bool)false;
			}
			if (wch < 0x80) {
				if (!_dispatch_transform_buffer_new(&buffer, 1, next)) {
					return (bool)false;
				}
				*(buffer.ptr.u8)++ = (uint8_t)(wch & 0xff);
			} else if (wch < 0x800) {
				if (!_dispatch_transform_buffer_new(&buffer, 2, next)) {
					return (bool)false;
				}
				*(buffer.ptr.u8)++ = (uint8_t)(0xc0 | (wch >> 6));
				*(buffer.ptr.u8)++ = (uint8_t)(0x80 | (wch & 0x3f));
			} else if (wch < 0x10000) {
				if (!_dispatch_transform_buffer_new(&buffer, 3, next)) {
					return (bool)false;
				}
				*(buffer.ptr.u8)++ = (uint8_t)(0xe0 | (wch >> 12));
				*(buffer.ptr.u8)++ = (uint8_t)(0x80 | ((wch >> 6) & 0x3f));
				*(buffer.ptr.u8)++ = (uint8_t)(0x80 | (wch & 0x3f));
			} else if (wch < 0x200000) {
				if (!_dispatch_transform_buffer_new(&buffer, 4, next)) {
					return (bool)false;
				}
				*(buffer.ptr.u8)++ = (uint8_t)(0xf0 | (wch >> 18));
				*(buffer.ptr.u8)++ = (uint8_t)(0x80 | ((wch >> 12) & 0x3f));
				*(buffer.ptr.u8)++ = (uint8_t)(0x80 | ((wch >> 6) & 0x3f));
				*(buffer.ptr.u8)++ = (uint8_t)(0x80 | (wch & 0x3f));
			}
		}

		(void)_dispatch_transform_buffer_new(&buffer, 0, 0);

		return (bool)true;
	});

	if (!success) {
		(void)_dispatch_transform_buffer_new(&buffer, 0, 0);
		dispatch_release(buffer.data);
		return NULL;
	}

	return buffer.data;
}

static dispatch_data_t
_dispatch_transform_from_utf16le(dispatch_data_t data)
{
	return _dispatch_transform_from_utf16(data, OSLittleEndian);
}

static dispatch_data_t
_dispatch_transform_from_utf16be(dispatch_data_t data)
{
	return _dispatch_transform_from_utf16(data, OSBigEndian);
}

static dispatch_data_t
_dispatch_transform_to_utf16le(dispatch_data_t data)
{
	return _dispatch_transform_to_utf16(data, OSLittleEndian);
}

static dispatch_data_t
_dispatch_transform_to_utf16be(dispatch_data_t data)
{
	return _dispatch_transform_to_utf16(data, OSBigEndian);
}

static dispatch_data_t
_dispatch_transform_to_utf8_without_bom(dispatch_data_t data)
{
	static uint8_t const utf8_bom[] = { 0xef, 0xbb, 0xbf };
	const void *p;
	dispatch_data_t subrange = _dispatch_data_subrange_map(data, &p, 0, 3);
	bool has_bom = false;

	if (subrange) {
		has_bom = (memcmp(p, utf8_bom, sizeof(utf8_bom)) == 0);
		dispatch_release(subrange);
	}
	if (has_bom) {
		return dispatch_data_create_subrange(data, 3,
				dispatch_data_get_size(data) - 3);
	}
	dispatch_retain(data);
	return data;
}

#pragma mark -
#pragma mark base32

static dispatch_data_t
_dispatch_transform_from_base32_with_table(dispatch_data_t data,
		const signed char* table, ssize_t table_size)
{
	__block uint64_t x = 0, count = 0, pad = 0;

	__block dispatch_data_t rv = dispatch_data_empty;

	bool success = dispatch_data_apply(data, ^(
			DISPATCH_UNUSED dispatch_data_t region,
			DISPATCH_UNUSED size_t offset, const void *buffer, size_t size) {
		size_t i, dest_size = howmany(size, 8) * 5;
		uint8_t *dest = (uint8_t*)malloc(dest_size * sizeof(uint8_t));
		uint8_t *ptr = dest;
		if (dest == NULL) {
			return (bool)false;
		}

		const uint8_t *bytes = buffer;

		for (i = 0; i < size; i++) {
			if (bytes[i] == '\n' || bytes[i] == '\t' || bytes[i] == ' ') {
				continue;
			}

			ssize_t index = bytes[i];
			if (index >= table_size || table[index] == -1) {
				free(dest);
				return (bool)false;
			}
			count++;

			signed char value = table[index];
			if (value == -2) {
				value = 0;
				pad++;
			}

			x <<= 5;
			x += (uint64_t)value;

			if ((count & 0x7) == 0) {
				*ptr++ = (x >> 32) & 0xff;
				*ptr++ = (x >> 24) & 0xff;
				*ptr++ = (x >> 16) & 0xff;
				*ptr++ = (x >> 8) & 0xff;
				*ptr++ = x & 0xff;
			}
		}

		size_t final = (size_t)(ptr - dest);
		switch (pad) {
		case 1:
			final -= 1;
			break;
		case 3:
			final -= 2;
			break;
		case 4:
			final -= 3;
			break;
		case 6:
			final -= 4;
			break;
		}

		dispatch_data_t val = dispatch_data_create(dest, final, NULL,
				DISPATCH_DATA_DESTRUCTOR_FREE);
		dispatch_data_t concat = dispatch_data_create_concat(rv, val);

		dispatch_release(val);
		dispatch_release(rv);
		rv = concat;

		return (bool)true;
	});

	if (!success) {
		dispatch_release(rv);
		return NULL;
	}

	return rv;
}

static dispatch_data_t
_dispatch_transform_to_base32_with_table(dispatch_data_t data, const unsigned char* table)
{
	size_t total = dispatch_data_get_size(data), dest_size;
	__block size_t count = 0;

	dest_size = howmany(total, 5);
	// <rdar://problem/25676583>
	// os_mul_overflow(dest_size, 8, &dest_size)
	if (dest_size > SIZE_MAX / 8) {
		return NULL;
	}
	dest_size *= 8;

	uint8_t *dest = (uint8_t*)malloc(dest_size);
	if (dest == NULL) {
		return NULL;
	}

	__block uint8_t *ptr = dest;

	/*
					    0        1        2        3        4
	 8-bit bytes:   xxxxxxxx yyyyyyyy zzzzzzzz xxxxxxxx yyyyyyyy
	 5-bit chunks:  aaaaabbb bbcccccd ddddeeee efffffgg ggghhhhh
	 */

	bool success = dispatch_data_apply(data, ^(
			DISPATCH_UNUSED dispatch_data_t region,
			size_t offset, const void *buffer, size_t size) {
		const uint8_t *bytes = buffer;
		size_t i;

		for (i = 0; i < size; i++, count++) {
			uint8_t curr = bytes[i], last = 0;

			if ((count % 5) != 0) {
				if (i == 0) {
					const void *p;
					dispatch_data_t subrange = _dispatch_data_subrange_map(data,
							&p, offset - 1, 1);
					if (subrange == NULL) {
						return (bool)false;
					}
					last = *(uint8_t*)p;
					dispatch_release(subrange);
				} else {
					last = bytes[i - 1];
				}
			}

			switch (count % 5) {
			case 0:
				// a
				*ptr++ = table[(curr >> 3) & 0x1fu];
				break;
			case 1:
				// b + c
				*ptr++ = table[((last << 2)|(curr >> 6)) & 0x1f];
				*ptr++ = table[(curr >> 1) & 0x1f];
				break;
			case 2:
				// d
				*ptr++ = table[((last << 4)|(curr >> 4)) & 0x1f];
				break;
			case 3:
				// e + f
				*ptr++ = table[((last << 1)|(curr >> 7)) & 0x1f];
				*ptr++ = table[(curr >> 2) & 0x1f];
				break;
			case 4:
				// g + h
				*ptr++ = table[((last << 3)|(curr >> 5)) & 0x1f];
				*ptr++ = table[curr & 0x1f];
				break;
			}
		}

		// Last region, insert padding bytes, if needed
		if (offset + size == total) {
			switch (count % 5) {
			case 0:
				break;
			case 1:
				// b[4:2]
				*ptr++ = table[(bytes[size-1] << 2) & 0x1c];
				break;
			case 2:
				// d[4]
				*ptr++ = table[(bytes[size-1] << 4) & 0x10];
				break;
			case 3:
				// e[4:1]
				*ptr++ = table[(bytes[size-1] << 1) & 0x1e];
				break;
			case 4:
				// g[2:3]
				*ptr++ = table[(bytes[size-1] << 3) & 0x18];
				break;
			}
			switch (count % 5) {
			case 0:
				break;
			case 1:
				*ptr++ = '='; // c
				*ptr++ = '='; // d
				DISPATCH_FALLTHROUGH;
			case 2:
				*ptr++ = '='; // e
				DISPATCH_FALLTHROUGH;
			case 3:
				*ptr++ = '='; // f
				*ptr++ = '='; // g
				DISPATCH_FALLTHROUGH;
			case 4:
				*ptr++ = '='; // h
				break;
			}
		}

		return (bool)true;
	});

	if (!success) {
		free(dest);
		return NULL;
	}
	return dispatch_data_create(dest, dest_size, NULL,
			DISPATCH_DATA_DESTRUCTOR_FREE);
}

static dispatch_data_t
_dispatch_transform_from_base32(dispatch_data_t data)
{
	return _dispatch_transform_from_base32_with_table(data, base32_decode_table,
			base32_decode_table_size);
}

static dispatch_data_t
_dispatch_transform_to_base32(dispatch_data_t data)
{
	return _dispatch_transform_to_base32_with_table(data, base32_encode_table);
}

static dispatch_data_t
_dispatch_transform_from_base32hex(dispatch_data_t data)
{
	return _dispatch_transform_from_base32_with_table(data,
			base32hex_decode_table, base32hex_decode_table_size);
}

static dispatch_data_t
_dispatch_transform_to_base32hex(dispatch_data_t data)
{
	return _dispatch_transform_to_base32_with_table(data,
			base32hex_encode_table);
}

#pragma mark -
#pragma mark base64

static dispatch_data_t
_dispatch_transform_from_base64(dispatch_data_t data)
{
	__block uint64_t x = 0, count = 0;
	__block size_t pad = 0;

	__block dispatch_data_t rv = dispatch_data_empty;

	bool success = dispatch_data_apply(data, ^(
			DISPATCH_UNUSED dispatch_data_t region,
			DISPATCH_UNUSED size_t offset, const void *buffer, size_t size) {
		size_t i, dest_size = howmany(size, 4) * 3;

		uint8_t *dest = (uint8_t*)malloc(dest_size * sizeof(uint8_t));
		uint8_t *ptr = dest;
		if (dest == NULL) {
			return (bool)false;
		}

		const uint8_t *bytes = buffer;

		for (i = 0; i < size; i++) {
			if (bytes[i] == '\n' || bytes[i] == '\t' || bytes[i] == ' ') {
				continue;
			}

			ssize_t index = bytes[i];
			if (index >= base64_decode_table_size ||
					base64_decode_table[index] == -1) {
				free(dest);
				return (bool)false;
			}
			count++;

			signed char value = base64_decode_table[index];
			if (value == -2) {
				value = 0;
				pad++;
			}

			x <<= 6;
			x += (uint64_t)value;

			if ((count & 0x3) == 0) {
				*ptr++ = (x >> 16) & 0xff;
				*ptr++ = (x >> 8) & 0xff;
				*ptr++ = x & 0xff;
			}
		}

		size_t final = (size_t)(ptr - dest);
		if (pad > 0) {
			// 2 bytes of pad means only had one char in final group
			final -= pad;
		}

		dispatch_data_t val = dispatch_data_create(dest, final, NULL,
				DISPATCH_DATA_DESTRUCTOR_FREE);
		dispatch_data_t concat = dispatch_data_create_concat(rv, val);

		dispatch_release(val);
		dispatch_release(rv);
		rv = concat;

		return (bool)true;
	});

	if (!success) {
		dispatch_release(rv);
		return NULL;
	}

	return rv;
}

static dispatch_data_t
_dispatch_transform_to_base64(dispatch_data_t data)
{
	// RFC 4648 states that we should not linebreak
	// http://tools.ietf.org/html/rfc4648
	size_t total = dispatch_data_get_size(data), dest_size;
	__block size_t count = 0;

	dest_size = howmany(total, 3);
	// <rdar://problem/25676583>
	// os_mul_overflow(dest_size, 4, &dest_size)
	if (dest_size > SIZE_MAX / 4) {
		return NULL;
	}
	dest_size *= 4;

	uint8_t *dest = (uint8_t*)malloc(dest_size);
	if (dest == NULL) {
		return NULL;
	}

	__block uint8_t *ptr = dest;

	/*
	 * 3 8-bit bytes:	xxxxxxxx yyyyyyyy zzzzzzzz
	 * 4 6-bit chunks:	aaaaaabb bbbbcccc ccdddddd
	 */

	bool success = dispatch_data_apply(data, ^(
			DISPATCH_UNUSED dispatch_data_t region,
			size_t offset, const void *buffer, size_t size) {
		const uint8_t *bytes = buffer;
		size_t i;

		for (i = 0; i < size; i++, count++) {
			uint8_t curr = bytes[i], last = 0;

			if ((count % 3) != 0) {
				if (i == 0) {
					const void *p;
					dispatch_data_t subrange = _dispatch_data_subrange_map(data,
						&p, offset - 1, 1);
					if (subrange == NULL) {
						return (bool)false;
					}
					last = *(uint8_t*)p;
					dispatch_release(subrange);
				} else {
					last = bytes[i - 1];
				}
			}

			switch (count % 3) {
			case 0:
				*ptr++ = base64_encode_table[(curr >> 2) & 0x3f];
				break;
			case 1:
				*ptr++ = base64_encode_table[((last << 4)|(curr >> 4)) & 0x3f];
				break;
			case 2:
				*ptr++ = base64_encode_table[((last << 2)|(curr >> 6)) & 0x3f];
				*ptr++ = base64_encode_table[(curr & 0x3f)];
				break;
			}
		}

		// Last region, insert padding bytes, if needed
		if (offset + size == total) {
			switch (count % 3) {
			case 0:
				break;
			case 1:
				*ptr++ = base64_encode_table[(bytes[size-1] << 4) & 0x30];
				*ptr++ = '=';
				*ptr++ = '=';
				break;
			case 2:
				*ptr++ = base64_encode_table[(bytes[size-1] << 2) & 0x3c];
				*ptr++ = '=';
				break;
			}
		}

		return (bool)true;
	});

	if (!success) {
		free(dest);
		return NULL;
	}
	return dispatch_data_create(dest, dest_size, NULL,
			DISPATCH_DATA_DESTRUCTOR_FREE);
}

#pragma mark -
#pragma mark dispatch_data_transform

dispatch_data_t
dispatch_data_create_with_transform(dispatch_data_t data,
		dispatch_data_format_type_t input, dispatch_data_format_type_t output)
{
	if (input->type == _DISPATCH_DATA_FORMAT_UTF_ANY) {
		input = _dispatch_transform_detect_utf(data);
		if (input == NULL) {
			return DISPATCH_BAD_INPUT;
		}
	}

	if ((input->type & ~output->input_mask) != 0) {
		return DISPATCH_BAD_INPUT;
	}

	if ((output->type & ~input->output_mask) != 0) {
		return DISPATCH_BAD_INPUT;
	}

	if (dispatch_data_get_size(data) == 0) {
		return data;
	}

	dispatch_data_t temp1;
	if (input->decode) {
		temp1 = input->decode(data);
	} else {
		dispatch_retain(data);
		temp1 = data;
	}

	if (!temp1) {
		return DISPATCH_BAD_INPUT;
	}

	dispatch_data_t temp2;
	if (output->encode) {
		temp2 = output->encode(temp1);
	} else {
		dispatch_retain(temp1);
		temp2 = temp1;
	}

	dispatch_release(temp1);
	return temp2;
}

const struct dispatch_data_format_type_s _dispatch_data_format_type_none = {
	.type = _DISPATCH_DATA_FORMAT_NONE,
	.input_mask = ~0u,
	.output_mask = ~0u,
	.decode = NULL,
	.encode = NULL,
};

const struct dispatch_data_format_type_s _dispatch_data_format_type_base32 = {
	.type = _DISPATCH_DATA_FORMAT_BASE32,
	.input_mask = (_DISPATCH_DATA_FORMAT_NONE | _DISPATCH_DATA_FORMAT_BASE32 |
			_DISPATCH_DATA_FORMAT_BASE32HEX | _DISPATCH_DATA_FORMAT_BASE64),
	.output_mask = (_DISPATCH_DATA_FORMAT_NONE | _DISPATCH_DATA_FORMAT_BASE32 |
			_DISPATCH_DATA_FORMAT_BASE32HEX | _DISPATCH_DATA_FORMAT_BASE64),
	.decode = _dispatch_transform_from_base32,
	.encode = _dispatch_transform_to_base32,
};

const struct dispatch_data_format_type_s _dispatch_data_format_type_base32hex =
{
	.type = _DISPATCH_DATA_FORMAT_BASE32HEX,
	.input_mask = (_DISPATCH_DATA_FORMAT_NONE | _DISPATCH_DATA_FORMAT_BASE32 |
			_DISPATCH_DATA_FORMAT_BASE32HEX | _DISPATCH_DATA_FORMAT_BASE64),
	.output_mask = (_DISPATCH_DATA_FORMAT_NONE | _DISPATCH_DATA_FORMAT_BASE32 |
			_DISPATCH_DATA_FORMAT_BASE32HEX | _DISPATCH_DATA_FORMAT_BASE64),
	.decode = _dispatch_transform_from_base32hex,
	.encode = _dispatch_transform_to_base32hex,
};

const struct dispatch_data_format_type_s _dispatch_data_format_type_base64 = {
	.type = _DISPATCH_DATA_FORMAT_BASE64,
	.input_mask = (_DISPATCH_DATA_FORMAT_NONE | _DISPATCH_DATA_FORMAT_BASE32 |
			_DISPATCH_DATA_FORMAT_BASE32HEX | _DISPATCH_DATA_FORMAT_BASE64),
	.output_mask = (_DISPATCH_DATA_FORMAT_NONE | _DISPATCH_DATA_FORMAT_BASE32 |
			_DISPATCH_DATA_FORMAT_BASE32HEX | _DISPATCH_DATA_FORMAT_BASE64),
	.decode = _dispatch_transform_from_base64,
	.encode = _dispatch_transform_to_base64,
};

const struct dispatch_data_format_type_s _dispatch_data_format_type_utf16le = {
	.type = _DISPATCH_DATA_FORMAT_UTF16LE,
	.input_mask = (_DISPATCH_DATA_FORMAT_UTF8 | _DISPATCH_DATA_FORMAT_UTF16BE |
			_DISPATCH_DATA_FORMAT_UTF16LE),
	.output_mask = (_DISPATCH_DATA_FORMAT_UTF8 | _DISPATCH_DATA_FORMAT_UTF16BE |
			_DISPATCH_DATA_FORMAT_UTF16LE),
	.decode = _dispatch_transform_from_utf16le,
	.encode = _dispatch_transform_to_utf16le,
};

const struct dispatch_data_format_type_s _dispatch_data_format_type_utf16be = {
	.type = _DISPATCH_DATA_FORMAT_UTF16BE,
	.input_mask = (_DISPATCH_DATA_FORMAT_UTF8 | _DISPATCH_DATA_FORMAT_UTF16BE |
			_DISPATCH_DATA_FORMAT_UTF16LE),
	.output_mask = (_DISPATCH_DATA_FORMAT_UTF8 | _DISPATCH_DATA_FORMAT_UTF16BE |
			_DISPATCH_DATA_FORMAT_UTF16LE),
	.decode = _dispatch_transform_from_utf16be,
	.encode = _dispatch_transform_to_utf16be,
};

const struct dispatch_data_format_type_s _dispatch_data_format_type_utf8 = {
	.type = _DISPATCH_DATA_FORMAT_UTF8,
	.input_mask = (_DISPATCH_DATA_FORMAT_UTF8 | _DISPATCH_DATA_FORMAT_UTF16BE |
			_DISPATCH_DATA_FORMAT_UTF16LE),
	.output_mask = (_DISPATCH_DATA_FORMAT_UTF8 | _DISPATCH_DATA_FORMAT_UTF16BE |
			_DISPATCH_DATA_FORMAT_UTF16LE),
	.decode = NULL,
	.encode = _dispatch_transform_to_utf8_without_bom,
};

const struct dispatch_data_format_type_s _dispatch_data_format_type_utf_any = {
	.type = _DISPATCH_DATA_FORMAT_UTF_ANY,
	.input_mask = 0,
	.output_mask = 0,
	.decode = NULL,
	.encode = NULL,
};
