X-Git-Url: https://git.saurik.com/apple/cf.git/blobdiff_plain/47a9ab1f151d80a00a045f81937ddac81c51a463..bd5b749cf7786ae858ab372fc8f64179736c6515:/StringEncodings.subproj/CFUnicodePrecomposition.c diff --git a/StringEncodings.subproj/CFUnicodePrecomposition.c b/StringEncodings.subproj/CFUnicodePrecomposition.c deleted file mode 100644 index c2cc29f..0000000 --- a/StringEncodings.subproj/CFUnicodePrecomposition.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* CFUnicodePrecomposition.c - Copyright 1999-2002, Apple, Inc. All rights reserved. - Responsibility: Aki Inoue -*/ - -#include -#include -#include -#include "CFUniChar.h" -#include "CFUnicodePrecomposition.h" -#include "CFInternal.h" -#include "CFUniCharPriv.h" - -// Canonical Precomposition -static UTF32Char *__CFUniCharPrecompSourceTable = NULL; -static uint32_t __CFUniCharPrecompositionTableLength = 0; -static uint16_t *__CFUniCharBMPPrecompDestinationTable = NULL; -static uint32_t *__CFUniCharNonBMPPrecompDestinationTable = NULL; - -static const uint8_t *__CFUniCharNonBaseBitmapForBMP_P = NULL; // Adding _P so the symbol name is different from the one in CFUnicodeDecomposition.c -static const uint8_t *__CFUniCharCombiningClassForBMP = NULL; - -static CFSpinLock_t __CFUniCharPrecompositionTableLock = 0; - -static void __CFUniCharLoadPrecompositionTable(void) { - - __CFSpinLock(&__CFUniCharPrecompositionTableLock); - - if (NULL == __CFUniCharPrecompSourceTable) { - const void *bytes = CFUniCharGetMappingData(kCFUniCharCanonicalPrecompMapping); - uint32_t bmpMappingLength; - - if (NULL == bytes) { - __CFSpinUnlock(&__CFUniCharPrecompositionTableLock); - return; - } - - __CFUniCharPrecompositionTableLength = *(((uint32_t *)bytes)++); - bmpMappingLength = *(((uint32_t *)bytes)++); - __CFUniCharPrecompSourceTable = (UTF32Char *)bytes; - __CFUniCharBMPPrecompDestinationTable = (uint16_t *)((intptr_t)bytes + (__CFUniCharPrecompositionTableLength * sizeof(UTF32Char) * 2)); - __CFUniCharNonBMPPrecompDestinationTable = (uint32_t *)(((intptr_t)__CFUniCharBMPPrecompDestinationTable) + bmpMappingLength); - - __CFUniCharNonBaseBitmapForBMP_P = CFUniCharGetBitmapPtrForPlane(kCFUniCharNonBaseCharacterSet, 0); - __CFUniCharCombiningClassForBMP = CFUniCharGetUnicodePropertyDataForPlane(kCFUniCharCombiningProperty, 0); - } - - __CFSpinUnlock(&__CFUniCharPrecompositionTableLock); -} - - // Adding _P so the symbol name is different from the one in CFUnicodeDecomposition.c -#define __CFUniCharIsNonBaseCharacter __CFUniCharIsNonBaseCharacter_P -CF_INLINE bool __CFUniCharIsNonBaseCharacter(UTF32Char character) { - return CFUniCharIsMemberOfBitmap(character, (character < 0x10000 ? __CFUniCharNonBaseBitmapForBMP_P : CFUniCharGetBitmapPtrForPlane(kCFUniCharNonBaseCharacterSet, ((character >> 16) & 0xFF)))); -} - -typedef struct { - UTF16Char _key; - UTF16Char _value; -} __CFUniCharPrecomposeBMPMappings; - -static UTF16Char __CFUniCharGetMappedBMPValue(const __CFUniCharPrecomposeBMPMappings *theTable, uint32_t numElem, UTF16Char character) { - const __CFUniCharPrecomposeBMPMappings *p, *q, *divider; - - if ((character < theTable[0]._key) || (character > theTable[numElem-1]._key)) { - return 0; - } - p = theTable; - q = p + (numElem-1); - while (p <= q) { - divider = p + ((q - p) >> 1); /* divide by 2 */ - if (character < divider->_key) { q = divider - 1; } - else if (character > divider->_key) { p = divider + 1; } - else { return divider->_value; } - } - return 0; -} - -typedef struct { - UTF32Char _key; - uint32_t _value; -} __CFUniCharPrecomposeMappings; - -static uint32_t __CFUniCharGetMappedValue_P(const __CFUniCharPrecomposeMappings *theTable, uint32_t numElem, UTF32Char character) { - const __CFUniCharPrecomposeMappings *p, *q, *divider; - - if ((character < theTable[0]._key) || (character > theTable[numElem-1]._key)) { - return 0; - } - p = theTable; - q = p + (numElem-1); - while (p <= q) { - divider = p + ((q - p) >> 1); /* divide by 2 */ - if (character < divider->_key) { q = divider - 1; } - else if (character > divider->_key) { p = divider + 1; } - else { return divider->_value; } - } - return 0; -} - -__private_extern__ -UTF32Char CFUniCharPrecomposeCharacter(UTF32Char base, UTF32Char combining) { - uint32_t value; - - if (NULL == __CFUniCharPrecompSourceTable) __CFUniCharLoadPrecompositionTable(); - - if (!(value = __CFUniCharGetMappedValue_P((const __CFUniCharPrecomposeMappings *)__CFUniCharPrecompSourceTable, __CFUniCharPrecompositionTableLength, combining))) return 0xFFFD; - - // We don't have precomposition in non-BMP - if (value & kCFUniCharNonBmpFlag) { - value = __CFUniCharGetMappedValue_P((const __CFUniCharPrecomposeMappings *)((uint32_t *)__CFUniCharNonBMPPrecompDestinationTable + (value & 0xFFFF)), (value >> 16) & 0x7FFF, base); - } else { - value = __CFUniCharGetMappedBMPValue((const __CFUniCharPrecomposeBMPMappings *)((uint32_t *)__CFUniCharBMPPrecompDestinationTable + (value & 0xFFFF)), (value >> 16), base); - } - return (value ? value : 0xFFFD); -} - -#define HANGUL_SBASE 0xAC00 -#define HANGUL_LBASE 0x1100 -#define HANGUL_VBASE 0x1161 -#define HANGUL_TBASE 0x11A7 -#define HANGUL_SCOUNT 11172 -#define HANGUL_LCOUNT 19 -#define HANGUL_VCOUNT 21 -#define HANGUL_TCOUNT 28 -#define HANGUL_NCOUNT (HANGUL_VCOUNT * HANGUL_TCOUNT) - -CF_INLINE void __CFUniCharMoveBufferFromEnd(UTF16Char *convertedChars, uint32_t length, uint32_t delta) { - const UTF16Char *limit = convertedChars; - UTF16Char *dstP; - - convertedChars += length; - dstP = convertedChars + delta; - - while (convertedChars > limit) *(--dstP) = *(--convertedChars); -} - -bool CFUniCharPrecompose(const UTF16Char *characters, uint32_t length, uint32_t *consumedLength, UTF16Char *precomposed, uint32_t maxLength, uint32_t *filledLength) { - UTF32Char currentChar = 0, lastChar = 0, precomposedChar = 0xFFFD; - uint32_t originalLength = length, usedLength = 0; - UTF16Char *currentBase = precomposed; - uint8_t currentClass, lastClass = 0; - bool currentBaseIsBMP = true; - bool isPrecomposed; - - if (NULL == __CFUniCharPrecompSourceTable) __CFUniCharLoadPrecompositionTable(); - - while (length > 0) { - currentChar = *(characters++); - --length; - - if (CFUniCharIsSurrogateHighCharacter(currentChar) && (length > 0) && CFUniCharIsSurrogateLowCharacter(*characters)) { - currentChar = CFUniCharGetLongCharacterForSurrogatePair(currentChar, *(characters++)); - --length; - } - - if (lastChar && __CFUniCharIsNonBaseCharacter(currentChar)) { - isPrecomposed = (precomposedChar == 0xFFFD ? false : true); - if (isPrecomposed) lastChar = precomposedChar; - - currentClass = (currentChar > 0xFFFF ? CFUniCharGetUnicodeProperty(currentChar, kCFUniCharCombiningProperty) : CFUniCharGetCombiningPropertyForCharacter(currentChar, __CFUniCharCombiningClassForBMP)); - - if ((lastClass == 0) || (currentClass != lastClass)) { - if ((precomposedChar = CFUniCharPrecomposeCharacter(lastChar, currentChar)) == 0xFFFD) { - if (isPrecomposed) precomposedChar = lastChar; - lastClass = currentClass; - } else { - lastClass = 0; - continue; - } - } - if (currentChar > 0xFFFF) { // Non-BMP - usedLength += 2; - if (usedLength > maxLength) break; - currentChar -= 0x10000; - *(precomposed++) = (UTF16Char)((currentChar >> 10) + 0xD800UL); - *(precomposed++) = (UTF16Char)((currentChar & 0x3FF) + 0xDC00UL); - } else { - ++usedLength; - if (usedLength > maxLength) break; - *(precomposed++) = (UTF16Char)currentChar; - } - } else { - if ((currentChar >= HANGUL_LBASE) && (currentChar < (HANGUL_LBASE + 0xFF))) { // Hangul Jamo - int8_t lIndex = currentChar - HANGUL_LBASE; - - if ((length > 0) && (0 <= lIndex) && (lIndex <= HANGUL_LCOUNT)) { - int16_t vIndex = *characters - HANGUL_VBASE; - - if ((vIndex >= 0) && (vIndex <= HANGUL_VCOUNT)) { - int16_t tIndex = 0; - - ++characters; --length; - - if (length > 0) { - tIndex = *characters - HANGUL_TBASE; - if ((tIndex < 0) || (tIndex > HANGUL_TCOUNT)) { - tIndex = 0; - } else { - ++characters; --length; - } - } - currentChar = (lIndex * HANGUL_VCOUNT + vIndex) * HANGUL_TCOUNT + tIndex + HANGUL_SBASE; - } - } - } - - if (precomposedChar != 0xFFFD) { - if (currentBaseIsBMP) { // Non-BMP - if (lastChar > 0xFFFF) { // Last char was Non-BMP - --usedLength; - memmove(currentBase + 1, currentBase + 2, (precomposed - (currentBase + 2)) * sizeof(UTF16Char)); - } - *(currentBase) = (UTF16Char)precomposedChar; - } else { - if (lastChar < 0x10000) { // Last char was BMP - ++usedLength; - if (usedLength > maxLength) break; - __CFUniCharMoveBufferFromEnd(currentBase + 1, precomposed - (currentBase + 1), 1); - } - precomposedChar -= 0x10000; - *currentBase = (UTF16Char)((precomposedChar >> 10) + 0xD800UL); - *(currentBase + 1) = (UTF16Char)((precomposedChar & 0x3FF) + 0xDC00UL); - } - precomposedChar = 0xFFFD; - } - currentBase = precomposed; - - lastChar = currentChar; - lastClass = 0; - - if (currentChar > 0xFFFF) { // Non-BMP - usedLength += 2; - if (usedLength > maxLength) break; - currentChar -= 0x10000; - *(precomposed++) = (UTF16Char)((currentChar >> 10) + 0xD800UL); - *(precomposed++) = (UTF16Char)((currentChar & 0x3FF) + 0xDC00UL); - currentBaseIsBMP = false; - } else { - ++usedLength; - if (usedLength > maxLength) break; - *(precomposed++) = (UTF16Char)currentChar; - currentBaseIsBMP = true; - } - } - } - - if (precomposedChar != 0xFFFD) { - if (currentChar > 0xFFFF) { // Non-BMP - if (lastChar < 0x10000) { // Last char was BMP - ++usedLength; - if (usedLength > maxLength) { - if (consumedLength) *consumedLength = originalLength - length; - if (filledLength) *filledLength = usedLength; - return false; - } - __CFUniCharMoveBufferFromEnd(currentBase + 1, precomposed - (currentBase + 1), 1); - } - precomposedChar -= 0x10000; - *currentBase = (UTF16Char)((precomposedChar >> 10) + 0xD800UL); - *(currentBase + 1) = (UTF16Char)((precomposedChar & 0x3FF) + 0xDC00UL); - } else { - if (lastChar > 0xFFFF) { // Last char was Non-BMP - --usedLength; - memmove(currentBase + 1, currentBase + 2, (precomposed - (currentBase + 2)) * sizeof(UTF16Char)); - } - *(currentBase) = (UTF16Char)precomposedChar; - } - } - - if (consumedLength) *consumedLength = originalLength - length; - if (filledLength) *filledLength = usedLength; - - return true; -} -