source/AccessorySDK/Support/utfconv.c
int
utf16_to_utf32(const uint16_t *inUTF16, size_t inUTF16ByteLen, 
               uint32_t *inUTF32Buf, size_t *outUTF32ByteLen, size_t inUTF32BufByteLen, 
               int inFlags)
{
	int result = 0;
	const uint16_t* source = inUTF16;
	const uint16_t* sourceEnd = (const uint16_t*)(((const uint8_t*)source) + inUTF16ByteLen);
	uint32_t* target = inUTF32Buf;
	uint32_t* targetEnd = (uint32_t*)(((uint8_t*)target) + inUTF32BufByteLen);
	uint32_t ch, ch2;
	while (source < sourceEnd) {
		ch = *source++;
		/* If we have a surrogate pair, convert to UTF-32 first. */
		if (ch >= SP_HIGH_FIRST && ch <= SP_HIGH_LAST) {
			/* If the 16 bits following the high surrogate are in the source buffer... */
			if (source < sourceEnd) {
				ch2 = *source;
				/* If it's a low surrogate, convert to UTF-32. */
				if (ch2 >= SP_LOW_FIRST && ch2 <= SP_LOW_LAST) {
					ch = ((ch - SP_HIGH_FIRST) << SP_HALF_SHIFT) + (ch2 - SP_LOW_FIRST) + SP_HALF_BASE;
					++source;
				} else if (inFlags & UTF_STRICT) { /* it's an unpaired high surrogate */
					--source; /* return to the illegal value itself */
					result = EINVAL;
					break;
				}
			} else { /* We don't have the 16 bits following the high surrogate. */
				--source; /* return to the high surrogate */
				result = EINVAL;
				break;
			}
		} else if (inFlags & UTF_STRICT) {
			/* UTF-16 surrogate values are illegal in UTF-32 */
			if (ch >= SP_LOW_FIRST && ch <= SP_LOW_LAST) {
				--source; /* return to the illegal value itself */
				result = EINVAL;
				break;
			}
		}
		if (target >= targetEnd) {
			result = ENAMETOOLONG;
			break;
		}
		*target++ = ch;
	}
	*outUTF32ByteLen = (size_t)(((uint8_t*)target) - ((uint8_t*)inUTF32Buf));
	return result;
}
/*
 * utf32_to_utf16 - Converts a UTF-16 string to UTF-32. Ported from public Unicode, Inc. code.
 *
 * This function takes a UTF-16 input string, inUTF16, of inUTF16ByteLen 
 * bytes and produces the UTF-32 output into a buffer of inUTF32BufByteLen 
 * bytes pointed to by inUTF32Buf. The size of the output in bytes is 
 * returned in outUTF32ByteLen. The UTF-32 string is *not* null terminated.
 *
 * NOTES:
 *    The resulting UTF-32 string is not NULL terminated.
 *
 * input flags:
 *    UTF_STRICT: Fail on irregular sequences and isolated surrogates.
 *
 * result:
 *    ENAMETOOLONG: Name didn't fit; only buflen bytes were encoded
 *
 *    EINVAL: Illegal char found.
 */
Converts a UTF-16 string to UTF-32. Ported from public Unicode, Inc. code.
This function takes a UTF-16 input string, inUTF16, of inUTF16ByteLen
bytes and produces the UTF-32 output into a buffer of inUTF32BufByteLen
bytes pointed to by inUTF32Buf. The size of the output in bytes is
returned in outUTF32ByteLen. The UTF-32 string is *not* null terminated.

The resulting UTF-32 string is not NULL terminated.

input flags:
UTF_STRICT: Fail on irregular sequences and isolated surrogates.

Name didn't fit; only buflen bytes were encoded

Illegal char found.
Converts a UTF - 16 string to UTF - 32 . Ported from public Unicode Inc . code . This function takes a UTF - 16 input string inUTF16 of inUTF16ByteLen bytes and produces the UTF - 32 output into a buffer of inUTF32BufByteLen bytes pointed to by inUTF32Buf . The size of the output in bytes is returned in outUTF32ByteLen . The UTF - 32 string is * not * null terminated . The resulting UTF - 32 string is not NULL terminated . input flags : UTF_STRICT : Fail on irregular sequences and isolated surrogates . Name didn ' t fit ; only buflen bytes were encoded Illegal char found .
int
utf16_to_utf32(const uint16_t *inUTF16, size_t inUTF16ByteLen, 
               uint32_t *inUTF32Buf, size_t *outUTF32ByteLen, size_t inUTF32BufByteLen, 
               int inFlags)
{
	int result = 0;
	const uint16_t* source = inUTF16;
	const uint16_t* sourceEnd = (const uint16_t*)(((const uint8_t*)source) + inUTF16ByteLen);
	uint32_t* target = inUTF32Buf;
	uint32_t* targetEnd = (uint32_t*)(((uint8_t*)target) + inUTF32BufByteLen);
	uint32_t ch, ch2;
	while (source < sourceEnd) {
		ch = *source++;
		if (ch >= SP_HIGH_FIRST && ch <= SP_HIGH_LAST) {
			if (source < sourceEnd) {
				ch2 = *source;
				if (ch2 >= SP_LOW_FIRST && ch2 <= SP_LOW_LAST) {
					ch = ((ch - SP_HIGH_FIRST) << SP_HALF_SHIFT) + (ch2 - SP_LOW_FIRST) + SP_HALF_BASE;
					++source;
				} else if (inFlags & UTF_STRICT) { 
					--source; 
					result = EINVAL;
					break;
				}
			} else { 
				--source; 
				result = EINVAL;
				break;
			}
		} else if (inFlags & UTF_STRICT) {
			if (ch >= SP_LOW_FIRST && ch <= SP_LOW_LAST) {
				--source; 
				result = EINVAL;
				break;
			}
		}
		if (target >= targetEnd) {
			result = ENAMETOOLONG;
			break;
		}
		*target++ = ch;
	}
	*outUTF32ByteLen = (size_t)(((uint8_t*)target) - ((uint8_t*)inUTF32Buf));
	return result;
}
int utf16_to_utf32 ( const uint16_t * inUTF16 , size_t inUTF16ByteLen , uint32_t * inUTF32Buf , size_t * outUTF32ByteLen , size_t inUTF32BufByteLen , int inFlags ) { int result = 0 ; const uint16_t * source = inUTF16 ; const uint16_t * sourceEnd = ( const uint16_t * ) ( ( ( const uint8_t * ) source ) + inUTF16ByteLen ) ; uint32_t * target = inUTF32Buf ; uint32_t * targetEnd = ( uint32_t * ) ( ( ( uint8_t * ) target ) + inUTF32BufByteLen ) ; uint32_t ch , ch2 ; while ( source < sourceEnd ) { ch = * source ++ ; if ( ch >= SP_HIGH_FIRST && ch <= SP_HIGH_LAST ) { if ( source < sourceEnd ) { ch2 = * source ; if ( ch2 >= SP_LOW_FIRST && ch2 <= SP_LOW_LAST ) { ch = ( ( ch - SP_HIGH_FIRST ) << SP_HALF_SHIFT ) + ( ch2 - SP_LOW_FIRST ) + SP_HALF_BASE ; ++ source ; } else if ( inFlags & UTF_STRICT ) { -- source ; result = EINVAL ; break ; } } else { -- source ; result = EINVAL ; break ; } } else if ( inFlags & UTF_STRICT ) { if ( ch >= SP_LOW_FIRST && ch <= SP_LOW_LAST ) { -- source ; result = EINVAL ; break ; } } if ( target >= targetEnd ) { result = ENAMETOOLONG ; break ; } * target ++ = ch ; } * outUTF32ByteLen = ( size_t ) ( ( ( uint8_t * ) target ) - ( ( uint8_t * ) inUTF32Buf ) ) ; return result ; }
utf32_to_utf16 - Converts a UTF-16 string to UTF-32.
utf32_to_utf16 - Converts a UTF - 16 string to UTF - 32 .
/* If we have a surrogate pair, convert to UTF-32 first. */ /* If the 16 bits following the high surrogate are in the source buffer... */ /* If it's a low surrogate, convert to UTF-32. */ /* it's an unpaired high surrogate */ /* return to the illegal value itself */ /* We don't have the 16 bits following the high surrogate. */ /* return to the high surrogate */ /* UTF-16 surrogate values are illegal in UTF-32 */ /* return to the illegal value itself */