/*
 * 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
#define OSSwapLittleToHostInt16 le16toh
#define OSSwapBigToHostInt16 be16toh
#define OSSwapHostToLittleInt16 htole16
#define OSSwapHostToBigInt16 htobe16
#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 >= 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);
}

#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_T_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
			case 2:
				*ptr++ = '='; // e
			case 3:
				*ptr++ = '='; // f
				*ptr++ = '='; // g
			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_T_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 = NULL,
};

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,
};
