X-Git-Url: https://git.saurik.com/apple/cf.git/blobdiff_plain/47a9ab1f151d80a00a045f81937ddac81c51a463..bd5b749cf7786ae858ab372fc8f64179736c6515:/String.subproj/CFCharacterSet.c diff --git a/String.subproj/CFCharacterSet.c b/String.subproj/CFCharacterSet.c deleted file mode 100644 index 1cbe9d3..0000000 --- a/String.subproj/CFCharacterSet.c +++ /dev/null @@ -1,2681 +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@ - */ -/* CFCharacterSet.c - Copyright 1999-2002, Apple, Inc. All rights reserved. - Responsibility: Aki Inoue -*/ - -#include -#include -#include "CFCharacterSetPriv.h" -#include -#include -#include "CFInternal.h" -#include "CFUniChar.h" -#include "CFUniCharPriv.h" -#include -#include - -#if !defined(__MACOS8__) -#define __MACOS8__ 0 -#endif - -#define BITSPERBYTE 8 /* (CHAR_BIT * sizeof(unsigned char)) */ -#define LOG_BPB 3 -#define LOG_BPLW 5 -#define NUMCHARACTERS 65536 - -#define MAX_ANNEX_PLANE (16) - -/* Number of things in the array keeping the bits. -*/ -#define __kCFBitmapSize (NUMCHARACTERS / BITSPERBYTE) - -/* How many elements max can be in an __kCFCharSetClassString CFCharacterSet -*/ -#define __kCFStringCharSetMax 64 - -/* The last builtin set ID number -*/ -#define __kCFLastBuiltinSetID kCFCharacterSetSymbol - -/* How many elements in the "singles" array before we use binary search. -*/ -#define __kCFSetBreakeven 10 - -/* This tells us, within 1k or so, whether a thing is POTENTIALLY in the set (in the bitmap blob of the private structure) before we bother to do specific checking. -*/ -#define __CFCSetBitsInRange(n, i) (i[n>>15] & (1L << ((n>>10) % 32))) - -/* Compact bitmap params -*/ -#define __kCFCompactBitmapNumPages (256) - -#define __kCFCompactBitmapMaxPages (128) // the max pages allocated - -#define __kCFCompactBitmapPageSize (__kCFBitmapSize / __kCFCompactBitmapNumPages) - -typedef struct { - CFCharacterSetRef *_nonBMPPlanes; - unsigned int _validEntriesBitmap; - unsigned char _numOfAllocEntries; - unsigned char _isAnnexInverted; - uint16_t _padding; -} CFCharSetAnnexStruct; - -struct __CFCharacterSet { - CFRuntimeBase _base; - CFHashCode _hashValue; - union { - struct { - CFIndex _type; - } _builtin; - struct { - UInt32 _firstChar; - CFIndex _length; - } _range; - struct { - UniChar *_buffer; - CFIndex _length; - } _string; - struct { - uint8_t *_bits; - } _bitmap; - struct { - uint8_t *_cBits; - } _compactBitmap; - } _variants; - CFCharSetAnnexStruct *_annex; -}; - -/* _base._info values interesting for CFCharacterSet -*/ -enum { - __kCFCharSetClassTypeMask = 0x0070, - __kCFCharSetClassBuiltin = 0x0000, - __kCFCharSetClassRange = 0x0010, - __kCFCharSetClassString = 0x0020, - __kCFCharSetClassBitmap = 0x0030, - __kCFCharSetClassSet = 0x0040, - __kCFCharSetClassCompactBitmap = 0x0040, - - __kCFCharSetIsInvertedMask = 0x0008, - __kCFCharSetIsInverted = 0x0008, - - __kCFCharSetHasHashValueMask = 0x00004, - __kCFCharSetHasHashValue = 0x0004, - - /* Generic CFBase values */ - __kCFCharSetIsMutableMask = 0x0001, - __kCFCharSetIsMutable = 0x0001, -}; - -/* Inline accessor macros for _base._info -*/ -CF_INLINE Boolean __CFCSetIsMutable(CFCharacterSetRef cset) {return (cset->_base._info & __kCFCharSetIsMutableMask) == __kCFCharSetIsMutable;} -CF_INLINE Boolean __CFCSetIsBuiltin(CFCharacterSetRef cset) {return (cset->_base._info & __kCFCharSetClassTypeMask) == __kCFCharSetClassBuiltin;} -CF_INLINE Boolean __CFCSetIsRange(CFCharacterSetRef cset) {return (cset->_base._info & __kCFCharSetClassTypeMask) == __kCFCharSetClassRange;} -CF_INLINE Boolean __CFCSetIsString(CFCharacterSetRef cset) {return (cset->_base._info & __kCFCharSetClassTypeMask) == __kCFCharSetClassString;} -CF_INLINE Boolean __CFCSetIsBitmap(CFCharacterSetRef cset) {return (cset->_base._info & __kCFCharSetClassTypeMask) == __kCFCharSetClassBitmap;} -CF_INLINE Boolean __CFCSetIsCompactBitmap(CFCharacterSetRef cset) {return (cset->_base._info & __kCFCharSetClassTypeMask) == __kCFCharSetClassCompactBitmap;} -CF_INLINE Boolean __CFCSetIsInverted(CFCharacterSetRef cset) {return (cset->_base._info & __kCFCharSetIsInvertedMask) == __kCFCharSetIsInverted;} -CF_INLINE Boolean __CFCSetHasHashValue(CFCharacterSetRef cset) {return (cset->_base._info & __kCFCharSetHasHashValueMask) == __kCFCharSetHasHashValue;} -CF_INLINE UInt32 __CFCSetClassType(CFCharacterSetRef cset) {return (cset->_base._info & __kCFCharSetClassTypeMask);} - -CF_INLINE void __CFCSetPutIsMutable(CFMutableCharacterSetRef cset, Boolean isMutable) {(isMutable ? (cset->_base._info |= __kCFCharSetIsMutable) : (cset->_base._info &= ~ __kCFCharSetIsMutable));} -CF_INLINE void __CFCSetPutIsInverted(CFMutableCharacterSetRef cset, Boolean isInverted) {(isInverted ? (cset->_base._info |= __kCFCharSetIsInverted) : (cset->_base._info &= ~__kCFCharSetIsInverted));} -CF_INLINE void __CFCSetPutHasHashValue(CFMutableCharacterSetRef cset, Boolean hasHash) {(hasHash ? (cset->_base._info |= __kCFCharSetHasHashValue) : (cset->_base._info &= ~__kCFCharSetHasHashValue));} -CF_INLINE void __CFCSetPutClassType(CFMutableCharacterSetRef cset, UInt32 classType) {cset->_base._info &= ~__kCFCharSetClassTypeMask; cset->_base._info |= classType;} - - -/* Inline contents accessor macros -*/ -CF_INLINE CFCharacterSetPredefinedSet __CFCSetBuiltinType(CFCharacterSetRef cset) {return cset->_variants._builtin._type;} -CF_INLINE UInt32 __CFCSetRangeFirstChar(CFCharacterSetRef cset) {return cset->_variants._range._firstChar;} -CF_INLINE CFIndex __CFCSetRangeLength(CFCharacterSetRef cset) {return cset->_variants._range._length;} -CF_INLINE UniChar *__CFCSetStringBuffer(CFCharacterSetRef cset) {return (UniChar*)(cset->_variants._string._buffer);} -CF_INLINE CFIndex __CFCSetStringLength(CFCharacterSetRef cset) {return cset->_variants._string._length;} -CF_INLINE uint8_t *__CFCSetBitmapBits(CFCharacterSetRef cset) {return cset->_variants._bitmap._bits;} -CF_INLINE uint8_t *__CFCSetCompactBitmapBits(CFCharacterSetRef cset) {return cset->_variants._compactBitmap._cBits;} - -CF_INLINE void __CFCSetPutBuiltinType(CFMutableCharacterSetRef cset, CFCharacterSetPredefinedSet type) {cset->_variants._builtin._type = type;} -CF_INLINE void __CFCSetPutRangeFirstChar(CFMutableCharacterSetRef cset, UInt32 first) {cset->_variants._range._firstChar = first;} -CF_INLINE void __CFCSetPutRangeLength(CFMutableCharacterSetRef cset, CFIndex length) {cset->_variants._range._length = length;} -CF_INLINE void __CFCSetPutStringBuffer(CFMutableCharacterSetRef cset, UniChar *theBuffer) {cset->_variants._string._buffer = theBuffer;} -CF_INLINE void __CFCSetPutStringLength(CFMutableCharacterSetRef cset, CFIndex length) {cset->_variants._string._length = length;} -CF_INLINE void __CFCSetPutBitmapBits(CFMutableCharacterSetRef cset, uint8_t *bits) {cset->_variants._bitmap._bits = bits;} -CF_INLINE void __CFCSetPutCompactBitmapBits(CFMutableCharacterSetRef cset, uint8_t *bits) {cset->_variants._compactBitmap._cBits = bits;} - -/* Validation funcs -*/ -#if defined(CF_ENABLE_ASSERTIONS) -CF_INLINE void __CFCSetValidateBuiltinType(CFCharacterSetPredefinedSet type, const char *func) { - CFAssert2(type > 0 && type <= __kCFLastBuiltinSetID, __kCFLogAssertion, "%s: Unknowen builtin type %d", func, type); -} -CF_INLINE void __CFCSetValidateRange(CFRange theRange, const char *func) { - CFAssert3(theRange.location >= 0 && theRange.location + theRange.length <= 0x1FFFFF, __kCFLogAssertion, "%s: Range out of Unicode range (location -> %d length -> %d)", func, theRange.location, theRange.length); -} -CF_INLINE void __CFCSetValidateTypeAndMutability(CFCharacterSetRef cset, const char *func) { - __CFGenericValidateType(cset, __kCFCharacterSetTypeID); - CFAssert1(__CFCSetIsMutable(cset), __kCFLogAssertion, "%s: Immutable character set passed to mutable function", func); -} -#else -#define __CFCSetValidateBuiltinType(t,f) -#define __CFCSetValidateRange(r,f) -#define __CFCSetValidateTypeAndMutability(r,f) -#endif - -/* Inline utility funcs -*/ -static Boolean __CFCSetIsEqualBitmap(const UInt32 *bits1, const UInt32 *bits2) { - CFIndex length = __kCFBitmapSize / sizeof(UInt32); - - if (bits1 == bits2) { - return true; - } else if (bits1 && bits2) { - if (bits1 == (const UInt32 *)-1) { - while (length--) if ((UInt32)-1 != *bits2++) return false; - } else if (bits2 == (const UInt32 *)-1) { - while (length--) if ((UInt32)-1 != *bits1++) return false; - } else { - while (length--) if (*bits1++ != *bits2++) return false; - } - return true; - } else if (!bits1 && !bits2) { // empty set - return true; - } else { - if (bits2) bits1 = bits2; - if (bits1 == (const UInt32 *)-1) return false; - while (length--) if (*bits1++) return false; - return true; - } -} - -CF_INLINE Boolean __CFCSetIsEqualBitmapInverted(const UInt32 *bits1, const UInt32 *bits2) { - CFIndex length = __kCFBitmapSize / sizeof(UInt32); - - while (length--) if (*bits1++ != ~(*(bits2++))) return false; - return true; -} - -static Boolean __CFCSetIsBitmapEqualToRange(const UInt32 *bits, UniChar firstChar, UniChar lastChar, Boolean isInverted) { - CFIndex firstCharIndex = firstChar >> LOG_BPB; - CFIndex lastCharIndex = lastChar >> LOG_BPB; - CFIndex length; - UInt32 value; - - if (firstCharIndex == lastCharIndex) { - value = ((((UInt32)0xFF) << (firstChar & (BITSPERBYTE - 1))) & (((UInt32)0xFF) >> ((BITSPERBYTE - 1) - (lastChar & (BITSPERBYTE - 1))))) << (((sizeof(UInt32) - 1) - (firstCharIndex % sizeof(UInt32))) * BITSPERBYTE); - value = CFSwapInt32HostToBig(value); - firstCharIndex = lastCharIndex = firstChar >> LOG_BPLW; - if (*(bits + firstCharIndex) != (isInverted ? ~value : value)) return FALSE; - } else { - UInt32 firstCharMask; - UInt32 lastCharMask; - - length = firstCharIndex % sizeof(UInt32); - firstCharMask = (((((UInt32)0xFF) << (firstChar & (BITSPERBYTE - 1))) & 0xFF) << (((sizeof(UInt32) - 1) - length) * BITSPERBYTE)) | (0xFFFFFFFF >> ((length + 1) * BITSPERBYTE)); - - length = lastCharIndex % sizeof(UInt32); - lastCharMask = ((((UInt32)0xFF) >> ((BITSPERBYTE - 1) - (lastChar & (BITSPERBYTE - 1)))) << (((sizeof(UInt32) - 1) - length) * BITSPERBYTE)) | (0xFFFFFFFF << ((sizeof(UInt32) - length) * BITSPERBYTE)); - - firstCharIndex = firstChar >> LOG_BPLW; - lastCharIndex = lastChar >> LOG_BPLW; - - if (firstCharIndex == lastCharIndex) { - firstCharMask &= lastCharMask; - value = CFSwapInt32HostToBig(firstCharMask & lastCharMask); - if (*(bits + firstCharIndex) != (isInverted ? ~value : value)) return FALSE; - } else { - value = CFSwapInt32HostToBig(firstCharMask); - if (*(bits + firstCharIndex) != (isInverted ? ~value : value)) return FALSE; - - value = CFSwapInt32HostToBig(lastCharMask); - if (*(bits + lastCharIndex) != (isInverted ? ~value : value)) return FALSE; - } - } - - length = firstCharIndex; - value = (isInverted ? 0xFFFFFFFF : 0); - while (length--) { - if (*(bits++) != value) return FALSE; - } - - ++bits; // Skip firstCharIndex - length = (lastCharIndex - (firstCharIndex + 1)); - value = (isInverted ? 0 : 0xFFFFFFFF); - while (length-- > 0) { - if (*(bits++) != value) return FALSE; - } - if (firstCharIndex != lastCharIndex) ++bits; - - length = (0xFFFF >> LOG_BPLW) - lastCharIndex; - value = (isInverted ? 0xFFFFFFFF : 0); - while (length--) { - if (*(bits++) != value) return FALSE; - } - - return TRUE; -} - -CF_INLINE Boolean __CFCSetIsBitmapSupersetOfBitmap(const UInt32 *bits1, const UInt32 *bits2, Boolean isInverted1, Boolean isInverted2) { - CFIndex length = __kCFBitmapSize / sizeof(UInt32); - UInt32 val1, val2; - - while (length--) { - val2 = (isInverted2 ? ~(*(bits2++)) : *(bits2++)); - val1 = (isInverted1 ? ~(*(bits1++)) : *(bits1++)) & val2; - if (val1 != val2) return false; - } - - return true; -} - -CF_INLINE Boolean __CFCSetHasNonBMPPlane(CFCharacterSetRef cset) { return ((cset)->_annex && (cset)->_annex->_validEntriesBitmap ? true : false); } -CF_INLINE Boolean __CFCSetAnnexIsInverted (CFCharacterSetRef cset) { return ((cset)->_annex && (cset)->_annex->_isAnnexInverted ? true : false); } -CF_INLINE UInt32 __CFCSetAnnexValidEntriesBitmap(CFCharacterSetRef cset) { return ((cset)->_annex && (cset)->_annex->_validEntriesBitmap ? (cset)->_annex->_validEntriesBitmap : 0); } - -CF_INLINE Boolean __CFCSetIsEmpty(CFCharacterSetRef cset) { - if (__CFCSetHasNonBMPPlane(cset) || __CFCSetAnnexIsInverted(cset)) return false; - - switch (__CFCSetClassType(cset)) { - case __kCFCharSetClassRange: if (!__CFCSetRangeLength(cset)) return true; break; - case __kCFCharSetClassString: if (!__CFCSetStringLength(cset)) return true; break; - case __kCFCharSetClassBitmap: if (!__CFCSetBitmapBits(cset)) return true; break; - case __kCFCharSetClassCompactBitmap: if (!__CFCSetCompactBitmapBits(cset)) return true; break; - } - return false; -} - -CF_INLINE void __CFCSetBitmapAddCharacter(uint8_t *bitmap, UniChar theChar) { - bitmap[(theChar) >> LOG_BPB] |= (((unsigned)1) << (theChar & (BITSPERBYTE - 1))); -} - -CF_INLINE void __CFCSetBitmapRemoveCharacter(uint8_t *bitmap, UniChar theChar) { - bitmap[(theChar) >> LOG_BPB] &= ~(((unsigned)1) << (theChar & (BITSPERBYTE - 1))); -} - -CF_INLINE Boolean __CFCSetIsMemberBitmap(const uint8_t *bitmap, UniChar theChar) { - return ((bitmap[(theChar) >> LOG_BPB] & (((unsigned)1) << (theChar & (BITSPERBYTE - 1)))) ? true : false); -} - -#define NUM_32BIT_SLOTS (NUMCHARACTERS / 32) - -CF_INLINE void __CFCSetBitmapFastFillWithValue(UInt32 *bitmap, uint8_t value) { - UInt32 mask = (value << 24) | (value << 16) | (value << 8) | value; - UInt32 numSlots = NUMCHARACTERS / 32; - - while (numSlots--) *(bitmap++) = mask; -} - -CF_INLINE void __CFCSetBitmapAddCharactersInRange(uint8_t *bitmap, UniChar firstChar, UniChar lastChar) { - if (firstChar == lastChar) { - bitmap[firstChar >> LOG_BPB] |= (((unsigned)1) << (firstChar & (BITSPERBYTE - 1))); - } else { - UInt32 idx = firstChar >> LOG_BPB; - UInt32 max = lastChar >> LOG_BPB; - - if (idx == max) { - bitmap[idx] |= (((unsigned)0xFF) << (firstChar & (BITSPERBYTE - 1))) & (((unsigned)0xFF) >> ((BITSPERBYTE - 1) - (lastChar & (BITSPERBYTE - 1)))); - } else { - bitmap[idx] |= (((unsigned)0xFF) << (firstChar & (BITSPERBYTE - 1))); - bitmap[max] |= (((unsigned)0xFF) >> ((BITSPERBYTE - 1) - (lastChar & (BITSPERBYTE - 1)))); - - ++idx; - while (idx < max) bitmap[idx++] = 0xFF; - } - } -} - -CF_INLINE void __CFCSetBitmapRemoveCharactersInRange(uint8_t *bitmap, UniChar firstChar, UniChar lastChar) { - UInt32 idx = firstChar >> LOG_BPB; - UInt32 max = lastChar >> LOG_BPB; - - if (idx == max) { - bitmap[idx] &= ~((((unsigned)0xFF) << (firstChar & (BITSPERBYTE - 1))) & (((unsigned)0xFF) >> ((BITSPERBYTE - 1) - (lastChar & (BITSPERBYTE - 1))))); - } else { - bitmap[idx] &= ~(((unsigned)0xFF) << (firstChar & (BITSPERBYTE - 1))); - bitmap[max] &= ~(((unsigned)0xFF) >> ((BITSPERBYTE - 1) - (lastChar & (BITSPERBYTE - 1)))); - - ++idx; - while (idx < max) bitmap[idx++] = 0; - } -} - -#define __CFCSetAnnexBitmapSetPlane(bitmap,plane) ((bitmap) |= (1 << (plane))) -#define __CFCSetAnnexBitmapClearPlane(bitmap,plane) ((bitmap) &= (~(1 << (plane)))) -#define __CFCSetAnnexBitmapGetPlane(bitmap,plane) ((bitmap) & (1 << (plane))) - -CF_INLINE void __CFCSetAnnexSetIsInverted(CFCharacterSetRef cset, Boolean flag) { - if (cset->_annex) ((CFMutableCharacterSetRef)cset)->_annex->_isAnnexInverted = flag; -} - -CF_INLINE void __CFCSetAllocateAnnexForPlane(CFCharacterSetRef cset, int plane) { - if (cset->_annex == NULL) { - ((CFMutableCharacterSetRef)cset)->_annex = (CFCharSetAnnexStruct *)CFAllocatorAllocate(CFGetAllocator(cset), sizeof(CFCharSetAnnexStruct), 0); - cset->_annex->_numOfAllocEntries = plane; - cset->_annex->_isAnnexInverted = false; - cset->_annex->_validEntriesBitmap = 0; - cset->_annex->_nonBMPPlanes = (CFCharacterSetRef*)CFAllocatorAllocate(CFGetAllocator(cset), sizeof(CFCharacterSetRef) * plane, 0); - } else if (cset->_annex->_numOfAllocEntries < plane) { - cset->_annex->_numOfAllocEntries = plane; - cset->_annex->_nonBMPPlanes = (CFCharacterSetRef*)CFAllocatorReallocate(CFGetAllocator(cset), (void *)cset->_annex->_nonBMPPlanes, sizeof(CFCharacterSetRef) * plane, 0); - } -} - -CF_INLINE void __CFCSetPutCharacterSetToAnnexPlane(CFCharacterSetRef cset, CFCharacterSetRef annexCSet, int plane) { - __CFCSetAllocateAnnexForPlane(cset, plane); - if (__CFCSetAnnexBitmapGetPlane(cset->_annex->_validEntriesBitmap, plane)) CFRelease(cset->_annex->_nonBMPPlanes[plane - 1]); - if (annexCSet) { - cset->_annex->_nonBMPPlanes[plane - 1] = CFRetain(annexCSet); - __CFCSetAnnexBitmapSetPlane(cset->_annex->_validEntriesBitmap, plane); - } else { - __CFCSetAnnexBitmapClearPlane(cset->_annex->_validEntriesBitmap, plane); - } -} - -CF_INLINE CFCharacterSetRef __CFCSetGetAnnexPlaneCharacterSet(CFCharacterSetRef cset, int plane) { - __CFCSetAllocateAnnexForPlane(cset, plane); - if (!__CFCSetAnnexBitmapGetPlane(cset->_annex->_validEntriesBitmap, plane)) { - cset->_annex->_nonBMPPlanes[plane - 1] = (CFCharacterSetRef)CFCharacterSetCreateMutable(CFGetAllocator(cset)); - __CFCSetAnnexBitmapSetPlane(cset->_annex->_validEntriesBitmap, plane); - } - return cset->_annex->_nonBMPPlanes[plane - 1]; -} - -CF_INLINE CFCharacterSetRef __CFCSetGetAnnexPlaneCharacterSetNoAlloc(CFCharacterSetRef cset, int plane) { - return (cset->_annex && __CFCSetAnnexBitmapGetPlane(cset->_annex->_validEntriesBitmap, plane) ? cset->_annex->_nonBMPPlanes[plane - 1] : NULL); -} - -CF_INLINE void __CFCSetDeallocateAnnexPlane(CFCharacterSetRef cset) { - if (cset->_annex) { - int idx; - - for (idx = 0;idx < MAX_ANNEX_PLANE;idx++) { - if (__CFCSetAnnexBitmapGetPlane(cset->_annex->_validEntriesBitmap, idx + 1)) { - CFRelease(cset->_annex->_nonBMPPlanes[idx]); - } - } - CFAllocatorDeallocate(CFGetAllocator(cset), cset->_annex->_nonBMPPlanes); - CFAllocatorDeallocate(CFGetAllocator(cset), cset->_annex); - ((CFMutableCharacterSetRef)cset)->_annex = NULL; - } -} - -CF_INLINE uint8_t __CFCSetGetHeaderValue(const uint8_t *bitmap, int *numPages) { - uint8_t value = *bitmap; - - if ((value == 0) || (value == UINT8_MAX)) { - int numBytes = __kCFCompactBitmapPageSize - 1; - - while (numBytes > 0) { - if (*(++bitmap) != value) break; - --numBytes; - } - if (numBytes == 0) return value; - } - return (uint8_t)(++(*numPages)); -} - -CF_INLINE bool __CFCSetIsMemberInCompactBitmap(const uint8_t *compactBitmap, UTF16Char character) { - uint8_t value = compactBitmap[(character >> 8)]; // Assuming __kCFCompactBitmapNumPages == 256 - - if (value == 0) { - return false; - } else if (value == UINT8_MAX) { - return true; - } else { - compactBitmap += (__kCFCompactBitmapNumPages + (__kCFCompactBitmapPageSize * (value - 1))); - character &= 0xFF; // Assuming __kCFCompactBitmapNumPages == 256 - return ((compactBitmap[(character / BITSPERBYTE)] & (1 << (character % BITSPERBYTE))) ? true : false); - } -} - -CF_INLINE uint32_t __CFCSetGetCompactBitmapSize(const uint8_t *compactBitmap) { - uint32_t length = __kCFCompactBitmapNumPages; - uint32_t size = __kCFCompactBitmapNumPages; - uint8_t value; - - while (length-- > 0) { - value = *(compactBitmap++); - if ((value != 0) && (value != UINT8_MAX)) size += __kCFCompactBitmapPageSize; - } - return size; -} - -/* Take a private "set" structure and make a bitmap from it. Return the bitmap. THE CALLER MUST RELEASE THE RETURNED MEMORY as necessary. -*/ - -CF_INLINE void __CFCSetBitmapProcessManyCharacters(unsigned char *map, unsigned n, unsigned m, Boolean isInverted) { - if (isInverted) { - __CFCSetBitmapRemoveCharactersInRange(map, n, m); - } else { - __CFCSetBitmapAddCharactersInRange(map, n, m); - } -} - -CF_INLINE void __CFExpandCompactBitmap(const uint8_t *src, uint8_t *dst) { - const uint8_t *srcBody = src + __kCFCompactBitmapNumPages; - int i; - uint8_t value; - - for (i = 0;i < __kCFCompactBitmapNumPages;i++) { - value = *(src++); - if ((value == 0) || (value == UINT8_MAX)) { - memset(dst, value, __kCFCompactBitmapPageSize); - } else { - memmove(dst, srcBody, __kCFCompactBitmapPageSize); - srcBody += __kCFCompactBitmapPageSize; - } - dst += __kCFCompactBitmapPageSize; - } -} - - -static void __CFCheckForExpandedSet(CFCharacterSetRef cset) { - static int8_t __CFNumberOfPlanesForLogging = -1; - static bool warnedOnce = false; - - if (0 > __CFNumberOfPlanesForLogging) { - const char *envVar = getenv("CFCharacterSetCheckForExpandedSet"); - long value = (envVar ? strtol(envVar, NULL, 0) : 0); - __CFNumberOfPlanesForLogging = (((value > 0) && (value <= 16)) ? value : 0); - } - - if (__CFNumberOfPlanesForLogging) { - uint32_t entries = __CFCSetAnnexValidEntriesBitmap(cset); - int count = 0; - - while (entries) { - if ((entries & 1) && (++count >= __CFNumberOfPlanesForLogging)) { - if (!warnedOnce) { - CFLog(0, CFSTR("An expanded CFMutableCharacter has been detected. Recommend to compact with CFCharacterSetCreateCopy")); - warnedOnce = true; - } - break; - } - entries >>= 1; - } - } -} - -static void __CFCSetGetBitmap(CFCharacterSetRef cset, uint8_t *bits) { - uint8_t *bitmap; - CFIndex length = __kCFBitmapSize; - - if (__CFCSetIsBitmap(cset) && (bitmap = __CFCSetBitmapBits(cset))) { - memmove(bits, bitmap, __kCFBitmapSize); - } else { - Boolean isInverted = __CFCSetIsInverted(cset); - uint8_t value = (isInverted ? (uint8_t)-1 : 0); - - bitmap = bits; - while (length--) *bitmap++ = value; // Initialize the buffer - - if (!__CFCSetIsEmpty(cset)) { - switch (__CFCSetClassType(cset)) { - case __kCFCharSetClassBuiltin: { - UInt8 result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(cset), 0, bits, isInverted); - if (result == kCFUniCharBitmapEmpty && isInverted) { - length = __kCFBitmapSize; - bitmap = bits; - while (length--) *bitmap++ = 0; - } else if (result == kCFUniCharBitmapAll && !isInverted) { - length = __kCFBitmapSize; - bitmap = bits; - while (length--) *bitmap++ = (UInt8)0xFF; - } - } - break; - - case __kCFCharSetClassRange: { - UInt32 theChar = __CFCSetRangeFirstChar(cset); - if (theChar < NUMCHARACTERS) { // the range starts in BMP - length = __CFCSetRangeLength(cset); - if (theChar + length >= NUMCHARACTERS) length = NUMCHARACTERS - theChar; - if (isInverted) { - __CFCSetBitmapRemoveCharactersInRange(bits, theChar, (theChar + length) - 1); - } else { - __CFCSetBitmapAddCharactersInRange(bits, theChar, (theChar + length) - 1); - } - } - } - break; - - case __kCFCharSetClassString: { - const UniChar *buffer = __CFCSetStringBuffer(cset); - length = __CFCSetStringLength(cset); - while (length--) (isInverted ? __CFCSetBitmapRemoveCharacter(bits, *buffer++) : __CFCSetBitmapAddCharacter(bits, *buffer++)); - } - break; - - case __kCFCharSetClassCompactBitmap: - __CFExpandCompactBitmap(__CFCSetCompactBitmapBits(cset), bits); - break; - } - } - } -} - -static Boolean __CFCharacterSetEqual(CFTypeRef cf1, CFTypeRef cf2); - -static Boolean __CFCSetIsEqualAnnex(CFCharacterSetRef cf1, CFCharacterSetRef cf2) { - CFCharacterSetRef subSet1; - CFCharacterSetRef subSet2; - Boolean isAnnexInvertStateIdentical = (__CFCSetAnnexIsInverted(cf1) == __CFCSetAnnexIsInverted(cf2) ? true: false); - int idx; - - if (isAnnexInvertStateIdentical) { - if (__CFCSetAnnexValidEntriesBitmap(cf1) != __CFCSetAnnexValidEntriesBitmap(cf2)) return false; - for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { - subSet1 = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(cf1, idx); - subSet2 = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(cf2, idx); - - if (subSet1 && !__CFCharacterSetEqual(subSet1, subSet2)) return false; - } - } else { - uint8_t bitsBuf[__kCFBitmapSize]; -#if __MACOS8__ - uint8_t *bitsBuf2 = NULL; -#else __MACOS8__ - uint8_t bitsBuf2[__kCFBitmapSize]; -#endif __MACOS8__ - - for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { - subSet1 = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(cf1, idx); - subSet2 = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(cf2, idx); - - if (subSet1 == NULL && subSet2 == NULL) { -#if __MACOS8__ - if (bitsBuf2) CFAllocatorDeallocate(NULL, bitsBuf2); -#endif __MACOS8__ - return false; - } else if (subSet1 == NULL) { - if (__CFCSetIsBitmap(subSet2)) { - if (!__CFCSetIsEqualBitmap((const UInt32 *)__CFCSetBitmapBits(subSet2), (const UInt32 *)-1)) { -#if __MACOS8__ - if (bitsBuf2) CFAllocatorDeallocate(NULL, bitsBuf2); -#endif __MACOS8__ - return false; - } - } else { - __CFCSetGetBitmap(subSet2, bitsBuf); - if (!__CFCSetIsEqualBitmap((const UInt32 *)bitsBuf, (const UInt32 *)-1)) { -#if __MACOS8__ - if (bitsBuf2) CFAllocatorDeallocate(NULL, bitsBuf2); -#endif __MACOS8__ - return false; - } - } - } else if (subSet2 == NULL) { - if (__CFCSetIsBitmap(subSet1)) { - if (!__CFCSetIsEqualBitmap((const UInt32 *)__CFCSetBitmapBits(subSet1), (const UInt32 *)-1)) { -#if __MACOS8__ - if (bitsBuf2) CFAllocatorDeallocate(NULL, bitsBuf2); -#endif __MACOS8__ - return false; - } - } else { - __CFCSetGetBitmap(subSet1, bitsBuf); - if (!__CFCSetIsEqualBitmap((const UInt32 *)bitsBuf, (const UInt32 *)-1)) { -#if __MACOS8__ - if (bitsBuf2) CFAllocatorDeallocate(NULL, bitsBuf2); -#endif __MACOS8__ - return false; - } - } - } else { - Boolean isBitmap1 = __CFCSetIsBitmap(subSet1); - Boolean isBitmap2 = __CFCSetIsBitmap(subSet2); - - if (isBitmap1 && isBitmap2) { - if (!__CFCSetIsEqualBitmapInverted((const UInt32 *)__CFCSetBitmapBits(subSet1), (const UInt32 *)__CFCSetBitmapBits(subSet2))) { -#if __MACOS8__ - if (bitsBuf2) CFAllocatorDeallocate(NULL, bitsBuf2); -#endif __MACOS8__ - return false; - } - } else if (!isBitmap1 && !isBitmap2) { - __CFCSetGetBitmap(subSet1, bitsBuf); -#if __MACOS8__ - if (bitsBuf2 == NULL) bitsBuf2 = (UInt32 *)CFAllocatorAllocate(NULL, __kCFBitmapSize, 0); -#endif __MACOS8__ - __CFCSetGetBitmap(subSet2, bitsBuf2); - if (!__CFCSetIsEqualBitmapInverted((const UInt32 *)bitsBuf, (const UInt32 *)bitsBuf2)) { -#if __MACOS8__ - CFAllocatorDeallocate(NULL, bitsBuf2); -#endif __MACOS8__ - return false; - } - } else { - if (isBitmap2) { - CFCharacterSetRef tmp = subSet2; - subSet2 = subSet1; - subSet1 = tmp; - } - __CFCSetGetBitmap(subSet2, bitsBuf); - if (!__CFCSetIsEqualBitmapInverted((const UInt32 *)__CFCSetBitmapBits(subSet1), (const UInt32 *)bitsBuf)) { -#if __MACOS8__ - if (bitsBuf2) CFAllocatorDeallocate(NULL, bitsBuf2); -#endif __MACOS8__ - return false; - } - } - } - } - } - return true; -} - -/* Compact bitmap -*/ -static uint8_t *__CFCreateCompactBitmap(CFAllocatorRef allocator, const uint8_t *bitmap) { - const uint8_t *src; - uint8_t *dst; - int i; - int numPages = 0; - uint8_t header[__kCFCompactBitmapNumPages]; - - src = bitmap; - for (i = 0;i < __kCFCompactBitmapNumPages;i++) { - header[i] = __CFCSetGetHeaderValue(src, &numPages); - - // Allocating more pages is probably not interesting enough to be compact - if (numPages > __kCFCompactBitmapMaxPages) return NULL; - src += __kCFCompactBitmapPageSize; - } - - dst = (uint8_t *)CFAllocatorAllocate(allocator, __kCFCompactBitmapNumPages + (__kCFCompactBitmapPageSize * numPages), AUTO_MEMORY_UNSCANNED); - - if (numPages > 0) { - uint8_t *dstBody = dst + __kCFCompactBitmapNumPages; - - src = bitmap; - for (i = 0;i < __kCFCompactBitmapNumPages;i++) { - dst[i] = header[i]; - - if ((dst[i] != 0) && (dst[i] != UINT8_MAX)) { - memmove(dstBody, src, __kCFCompactBitmapPageSize); - dstBody += __kCFCompactBitmapPageSize; - } - src += __kCFCompactBitmapPageSize; - } - } else { - memmove(dst, header, __kCFCompactBitmapNumPages); - } - - return dst; -} - -static void __CFCSetMakeCompact(CFMutableCharacterSetRef cset) { - if (__CFCSetIsBitmap(cset) && __CFCSetBitmapBits(cset)) { - uint8_t *bitmap = __CFCSetBitmapBits(cset); - uint8_t *cBitmap = __CFCreateCompactBitmap(CFGetAllocator(cset), bitmap); - - if (cBitmap) { - CFAllocatorDeallocate(CFGetAllocator(cset), bitmap); - __CFCSetPutClassType(cset, __kCFCharSetClassCompactBitmap); - __CFCSetPutCompactBitmapBits(cset, cBitmap); - } - } -} - -static void __CFCSetAddNonBMPPlanesInRange(CFMutableCharacterSetRef cset, CFRange range) { - int firstChar = (range.location & 0xFFFF); - int maxChar = range.location + range.length; - int idx = range.location >> 16; // first plane - int maxPlane = (maxChar - 1) >> 16; // last plane - CFRange planeRange; - CFMutableCharacterSetRef annexPlane; - - maxChar &= 0xFFFF; - - for (idx = (idx ? idx : 1);idx <= maxPlane;idx++) { - planeRange.location = __CFMax(firstChar, 0); - planeRange.length = (idx == maxPlane && maxChar ? maxChar : 0x10000) - planeRange.location; - if (__CFCSetAnnexIsInverted(cset)) { - if ((annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(cset, idx))) { - CFCharacterSetRemoveCharactersInRange(annexPlane, planeRange); - if (__CFCSetIsEmpty(annexPlane) && !__CFCSetIsInverted(annexPlane)) { - CFRelease(annexPlane); - __CFCSetAnnexBitmapClearPlane(cset->_annex->_validEntriesBitmap, idx); - } - } - } else { - CFCharacterSetAddCharactersInRange((CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(cset, idx), planeRange); - } - } - if (!__CFCSetHasNonBMPPlane(cset) && !__CFCSetAnnexIsInverted(cset)) __CFCSetDeallocateAnnexPlane(cset); -} - -static void __CFCSetRemoveNonBMPPlanesInRange(CFMutableCharacterSetRef cset, CFRange range) { - int firstChar = (range.location & 0xFFFF); - int maxChar = range.location + range.length; - int idx = range.location >> 16; // first plane - int maxPlane = (maxChar - 1) >> 16; // last plane - CFRange planeRange; - CFMutableCharacterSetRef annexPlane; - - maxChar &= 0xFFFF; - - for (idx = (idx ? idx : 1);idx <= maxPlane;idx++) { - planeRange.location = __CFMax(firstChar, 0); - planeRange.length = (idx == maxPlane && maxChar ? maxChar : 0x10000) - planeRange.location; - if (__CFCSetAnnexIsInverted(cset)) { - CFCharacterSetAddCharactersInRange((CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(cset, idx), planeRange); - } else { - if ((annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(cset, idx))) { - CFCharacterSetRemoveCharactersInRange(annexPlane, planeRange); - if(__CFCSetIsEmpty(annexPlane) && !__CFCSetIsInverted(annexPlane)) { - CFRelease(annexPlane); - __CFCSetAnnexBitmapClearPlane(cset->_annex->_validEntriesBitmap, idx); - } - } - } - } - if (!__CFCSetHasNonBMPPlane(cset) && !__CFCSetAnnexIsInverted(cset)) __CFCSetDeallocateAnnexPlane(cset); -} - -static void __CFCSetMakeBitmap(CFMutableCharacterSetRef cset) { - if (!__CFCSetIsBitmap(cset) || !__CFCSetBitmapBits(cset)) { - CFAllocatorRef allocator = CFGetAllocator(cset); - uint8_t *bitmap = CFAllocatorAllocate(allocator, __kCFBitmapSize, AUTO_MEMORY_UNSCANNED); - __CFCSetGetBitmap(cset, bitmap); - - if (__CFCSetIsBuiltin(cset)) { - CFIndex numPlanes = CFUniCharGetNumberOfPlanes(__CFCSetBuiltinType(cset)); - - if (numPlanes > 1) { - CFMutableCharacterSetRef annexSet; - uint8_t *annexBitmap = NULL; - int idx; - UInt8 result; - - __CFCSetAllocateAnnexForPlane(cset, numPlanes - 1); - for (idx = 1;idx < numPlanes;idx++) { - if (NULL == annexBitmap) { - annexBitmap = CFAllocatorAllocate(allocator, __kCFBitmapSize, AUTO_MEMORY_UNSCANNED); - } - result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(cset), idx, annexBitmap, false); - if (result == kCFUniCharBitmapEmpty) continue; - if (result == kCFUniCharBitmapAll) { - CFIndex bitmapLength = __kCFBitmapSize; - uint8_t *bytes = annexBitmap; - while (bitmapLength-- > 0) *(bytes++) = (uint8_t)0xFF; - } - annexSet = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(cset, idx); - __CFCSetPutClassType(annexSet, __kCFCharSetClassBitmap); - __CFCSetPutBitmapBits(annexSet, annexBitmap); - __CFCSetPutIsInverted(annexSet, false); - __CFCSetPutHasHashValue(annexSet, false); - annexBitmap = NULL; - } - if (annexBitmap) CFAllocatorDeallocate(allocator, annexBitmap); - } - } else if (__CFCSetIsCompactBitmap(cset) && __CFCSetCompactBitmapBits(cset)) { - CFAllocatorDeallocate(allocator, __CFCSetCompactBitmapBits(cset)); - __CFCSetPutCompactBitmapBits(cset, NULL); - } else if (__CFCSetIsString(cset) && __CFCSetStringBuffer(cset)) { - CFAllocatorDeallocate(allocator, __CFCSetStringBuffer(cset)); - __CFCSetPutStringBuffer(cset, NULL); - } else if (__CFCSetIsRange(cset)) { // We may have to allocate annex here - Boolean needsToInvert = (!__CFCSetHasNonBMPPlane(cset) && __CFCSetIsInverted(cset) ? true : false); - __CFCSetAddNonBMPPlanesInRange(cset, CFRangeMake(__CFCSetRangeFirstChar(cset), __CFCSetRangeLength(cset))); - if (needsToInvert) __CFCSetAnnexSetIsInverted(cset, true); - } - __CFCSetPutClassType(cset, __kCFCharSetClassBitmap); - __CFCSetPutBitmapBits(cset, bitmap); - __CFCSetPutIsInverted(cset, false); - } -} - -CF_INLINE CFMutableCharacterSetRef __CFCSetGenericCreate(CFAllocatorRef allocator, UInt32 flags) { - CFMutableCharacterSetRef cset; - CFIndex size = sizeof(struct __CFCharacterSet) - sizeof(CFRuntimeBase); - - cset = (CFMutableCharacterSetRef)_CFRuntimeCreateInstance(allocator, CFCharacterSetGetTypeID(), size, NULL); - if (NULL == cset) return NULL; - - cset->_base._info |= flags; - cset->_hashValue = 0; - cset->_annex = NULL; - - return cset; -} - -/* Bsearch theChar for __kCFCharSetClassString -*/ -CF_INLINE Boolean __CFCSetBsearchUniChar(const UniChar *theTable, CFIndex length, UniChar theChar) { - const UniChar *p, *q, *divider; - - if ((theChar < theTable[0]) || (theChar > theTable[length - 1])) return false; - - p = theTable; - q = p + (length - 1); - while (p <= q) { - divider = p + ((q - p) >> 1); /* divide by 2 */ - if (theChar < *divider) q = divider - 1; - else if (theChar > *divider) p = divider + 1; - else return true; - } - return false; -} - -/* Predefined cset names - Need to add entry here for new builtin types -*/ -CONST_STRING_DECL(__kCFCSetNameControl, "") -CONST_STRING_DECL(__kCFCSetNameWhitespace, "") -CONST_STRING_DECL(__kCFCSetNameWhitespaceAndNewline, "") -CONST_STRING_DECL(__kCFCSetNameDecimalDigit, "") -CONST_STRING_DECL(__kCFCSetNameLetter, "") -CONST_STRING_DECL(__kCFCSetNameLowercaseLetter, "") -CONST_STRING_DECL(__kCFCSetNameUppercaseLetter, "") -CONST_STRING_DECL(__kCFCSetNameNonBase, "") -CONST_STRING_DECL(__kCFCSetNameDecomposable, "") -CONST_STRING_DECL(__kCFCSetNameAlphaNumeric, "") -CONST_STRING_DECL(__kCFCSetNamePunctuation, "") -CONST_STRING_DECL(__kCFCSetNameIllegal, "") -CONST_STRING_DECL(__kCFCSetNameCapitalizedLetter, "") -CONST_STRING_DECL(__kCFCSetNameSymbol, "") - -CONST_STRING_DECL(__kCFCSetNameStringTypeFormat, "_hashValue != ((CFCharacterSetRef)cf2)->_hashValue) return false; - if (__CFCSetIsEmpty(cf1) && __CFCSetIsEmpty(cf2) && !isInvertStateIdentical) return false; - - if (__CFCSetClassType(cf1) == __CFCSetClassType(cf2)) { // Types are identical, we can do it fast - switch (__CFCSetClassType(cf1)) { - case __kCFCharSetClassBuiltin: - return (__CFCSetBuiltinType(cf1) == __CFCSetBuiltinType(cf2) && isInvertStateIdentical ? true : false); - - case __kCFCharSetClassRange: - return (__CFCSetRangeFirstChar(cf1) == __CFCSetRangeFirstChar(cf2) && __CFCSetRangeLength(cf1) && __CFCSetRangeLength(cf2) && isInvertStateIdentical ? true : false); - - case __kCFCharSetClassString: - if (__CFCSetStringLength(cf1) == __CFCSetStringLength(cf2) && isInvertStateIdentical) { - const UniChar *buf1 = __CFCSetStringBuffer(cf1); - const UniChar *buf2 = __CFCSetStringBuffer(cf2); - CFIndex length = __CFCSetStringLength(cf1); - - while (length--) if (*buf1++ != *buf2++) return false; - } else { - return false; - } - break; - - case __kCFCharSetClassBitmap: - if (!__CFCSetIsEqualBitmap((const UInt32 *)__CFCSetBitmapBits(cf1), (const UInt32 *)__CFCSetBitmapBits(cf2))) return false; - break; - } - return __CFCSetIsEqualAnnex(cf1, cf2); - } - - // Check for easy empty cases - if (__CFCSetIsEmpty(cf1) || __CFCSetIsEmpty(cf2)) { - CFCharacterSetRef emptySet = (__CFCSetIsEmpty(cf1) ? cf1 : cf2); - CFCharacterSetRef nonEmptySet = (emptySet == cf1 ? cf2 : cf1); - - if (__CFCSetIsBuiltin(nonEmptySet)) { - return false; - } else if (__CFCSetIsRange(nonEmptySet)) { - if (isInvertStateIdentical) { - return (__CFCSetRangeLength(nonEmptySet) ? false : true); - } else { - return (__CFCSetRangeLength(nonEmptySet) == 0x110000 ? true : false); - } - } else { - if (__CFCSetAnnexIsInverted(nonEmptySet)) { - if (__CFCSetAnnexValidEntriesBitmap(nonEmptySet) != 0x1FFFE) return false; - } else { - if (__CFCSetAnnexValidEntriesBitmap(nonEmptySet)) return false; - } - - if (__CFCSetIsBitmap(nonEmptySet)) { - bits = __CFCSetBitmapBits(nonEmptySet); - } else { - bits = bitsBuf; - __CFCSetGetBitmap(nonEmptySet, bitsBuf); - } - - if (__CFCSetIsEqualBitmap(NULL, (const UInt32 *)bits)) { - if (!__CFCSetAnnexIsInverted(nonEmptySet)) return true; - } else { - return false; - } - - // Annex set has to be CFRangeMake(0x10000, 0xfffff) - for (idx = 1;idx < MAX_ANNEX_PLANE;idx++) { - if (__CFCSetIsBitmap(nonEmptySet)) { - if (!__CFCSetIsEqualBitmap((__CFCSetAnnexIsInverted(nonEmptySet) ? NULL : (const UInt32 *)-1), (const UInt32 *)bitsBuf)) return false; - } else { - __CFCSetGetBitmap(__CFCSetGetAnnexPlaneCharacterSetNoAlloc(nonEmptySet, idx), bitsBuf); - if (!__CFCSetIsEqualBitmap((const UInt32 *)-1, (const UInt32 *)bitsBuf)) return false; - } - } - return true; - } - } - - if (__CFCSetIsBuiltin(cf1) || __CFCSetIsBuiltin(cf2)) { - CFCharacterSetRef builtinSet = (__CFCSetIsBuiltin(cf1) ? cf1 : cf2); - CFCharacterSetRef nonBuiltinSet = (builtinSet == cf1 ? cf2 : cf1); - - - if (__CFCSetIsRange(nonBuiltinSet)) { - UTF32Char firstChar = __CFCSetRangeFirstChar(nonBuiltinSet); - UTF32Char lastChar = (firstChar + __CFCSetRangeLength(nonBuiltinSet) - 1); - uint8_t firstPlane = (firstChar >> 16) & 0xFF; - uint8_t lastPlane = (lastChar >> 16) & 0xFF; - uint8_t result; - - for (idx = 0;idx < MAX_ANNEX_PLANE;idx++) { - result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(builtinSet), idx, bitsBuf, isInvertStateIdentical); - - if (idx < firstPlane || idx > lastPlane) { - if (result == kCFUniCharBitmapAll) { - return false; - } else if (result == kCFUniCharBitmapFilled) { - if (!__CFCSetIsEqualBitmap(NULL, (const UInt32 *)bitsBuf)) return false; - } - } else if (idx > firstPlane && idx < lastPlane) { - if (result == kCFUniCharBitmapEmpty) { - return false; - } else if (result == kCFUniCharBitmapFilled) { - if (!__CFCSetIsEqualBitmap((const UInt32 *)-1, (const UInt32 *)bitsBuf)) return false; - } - } else { - if (result == kCFUniCharBitmapEmpty) { - return false; - } else if (result == kCFUniCharBitmapAll) { - if (idx == firstPlane) { - if (((firstChar & 0xFFFF) != 0) || (firstPlane == lastPlane && ((lastChar & 0xFFFF) != 0xFFFF))) return false; - } else { - if (((lastChar & 0xFFFF) != 0xFFFF) || (firstPlane == lastPlane && ((firstChar & 0xFFFF) != 0))) return false; - } - } else { - if (idx == firstPlane) { - if (!__CFCSetIsBitmapEqualToRange((const UInt32 *)bitsBuf, firstChar & 0xFFFF, (firstPlane == lastPlane ? lastChar & 0xFFFF : 0xFFFF), false)) return false; - } else { - if (!__CFCSetIsBitmapEqualToRange((const UInt32 *)bitsBuf, (firstPlane == lastPlane ? firstChar & 0xFFFF : 0), lastChar & 0xFFFF, false)) return false; - } - } - } - } - return true; - } else { -#if __MACOS8__ - uint8_t *bitsBuf2 = NULL; -#else __MACOS8__ - uint8_t bitsBuf2[__kCFBitmapSize]; -#endif __MACOS8__ - uint8_t result; - - result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(builtinSet), 0, bitsBuf, __CFCSetIsInverted(builtinSet)); - if (result == kCFUniCharBitmapFilled) { - if (__CFCSetIsBitmap(nonBuiltinSet)) { - if (!__CFCSetIsEqualBitmap((const UInt32 *)bitsBuf, (const UInt32 *)__CFCSetBitmapBits(nonBuiltinSet))) return false; - } else { -#if __MACOS8__ - bitsBuf2 = CFAllocatorAllocate(CFGetAllocator(nonBuiltinSet), __kCFBitmapSize, 0); -#endif __MACOS8__ - - __CFCSetGetBitmap(nonBuiltinSet, bitsBuf2); - if (!__CFCSetIsEqualBitmap((const UInt32 *)bitsBuf, (const UInt32 *)bitsBuf2)) { -#if __MACOS8__ - CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet), bitsBuf2); -#endif __MACOS8__ - return false; - } - } - } else { - if (__CFCSetIsBitmap(nonBuiltinSet)) { - if (!__CFCSetIsEqualBitmap((result == kCFUniCharBitmapAll ? (const UInt32*)-1 : NULL), (const UInt32 *)__CFCSetBitmapBits(nonBuiltinSet))) return false; - } else { - __CFCSetGetBitmap(nonBuiltinSet, bitsBuf); - if (!__CFCSetIsEqualBitmap((result == kCFUniCharBitmapAll ? (const UInt32*)-1: NULL), (const UInt32 *)bitsBuf)) return false; - } - } - - isInvertStateIdentical = (__CFCSetIsInverted(builtinSet) == __CFCSetAnnexIsInverted(nonBuiltinSet) ? true : false); - - for (idx = 1;idx < MAX_ANNEX_PLANE;idx++) { - result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(builtinSet), idx, bitsBuf, !isInvertStateIdentical); - subSet1 = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(nonBuiltinSet, idx); - - if (result == kCFUniCharBitmapFilled) { - if (NULL == subSet1) { -#if __MACOS8__ - if (bitsBuf2) CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet), bitsBuf2); -#endif __MACOS8__ - return false; - } else if (__CFCSetIsBitmap(subSet1)) { - if (!__CFCSetIsEqualBitmap((const UInt32*)bitsBuf, (const UInt32*)__CFCSetBitmapBits(subSet1))) { -#if __MACOS8__ - if (bitsBuf2) CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet), bitsBuf2); -#endif __MACOS8__ - return false; - } - } else { -#if __MACOS8__ - if (NULL == bitsBuf2) bitsBuf2 = CFAllocatorAllocate(CFGetAllocator(nonBuiltinSet), __kCFBitmapSize, 0); -#endif __MACOS8__ - - __CFCSetGetBitmap(subSet1, bitsBuf2); - if (!__CFCSetIsEqualBitmap((const UInt32*)bitsBuf, (const UInt32*)bitsBuf2)) { -#if __MACOS8__ - CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet), bitsBuf2); -#endif __MACOS8__ - return false; - } - } - } else { - if (NULL == subSet1) { - if (result == kCFUniCharBitmapAll) { -#if __MACOS8__ - if (bitsBuf2) CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet), bitsBuf2); -#endif __MACOS8__ - return false; - } - } else if (__CFCSetIsBitmap(subSet1)) { - if (!__CFCSetIsEqualBitmap((result == kCFUniCharBitmapAll ? (const UInt32*)-1: NULL), (const UInt32*)__CFCSetBitmapBits(subSet1))) { -#if __MACOS8__ - if (bitsBuf2) CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet), bitsBuf2); -#endif __MACOS8__ - return false; - } - } else { - __CFCSetGetBitmap(subSet1, bitsBuf); - if (!__CFCSetIsEqualBitmap((result == kCFUniCharBitmapAll ? (const UInt32*)-1: NULL), (const UInt32*)bitsBuf)) { -#if __MACOS8__ - if (bitsBuf2) CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet), bitsBuf2); -#endif __MACOS8__ - return false; - } - } - } - } -#if __MACOS8__ - if (bitsBuf2) CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet), bitsBuf2); -#endif __MACOS8__ - return true; - } - } - - if (__CFCSetIsRange(cf1) || __CFCSetIsRange(cf2)) { - CFCharacterSetRef rangeSet = (__CFCSetIsRange(cf1) ? cf1 : cf2); - CFCharacterSetRef nonRangeSet = (rangeSet == cf1 ? cf2 : cf1); - UTF32Char firstChar = __CFCSetRangeFirstChar(rangeSet); - UTF32Char lastChar = (firstChar + __CFCSetRangeLength(rangeSet) - 1); - uint8_t firstPlane = (firstChar >> 16) & 0xFF; - uint8_t lastPlane = (lastChar >> 16) & 0xFF; - Boolean isRangeSetInverted = __CFCSetIsInverted(rangeSet); - - if (__CFCSetIsBitmap(nonRangeSet)) { - bits = __CFCSetBitmapBits(nonRangeSet); - } else { - bits = bitsBuf; - __CFCSetGetBitmap(nonRangeSet, bitsBuf); - } - if (firstPlane == 0) { - if (!__CFCSetIsBitmapEqualToRange((const UInt32*)bits, firstChar, (lastPlane == 0 ? lastChar : 0xFFFF), isRangeSetInverted)) return false; - firstPlane = 1; - firstChar = 0; - } else { - if (!__CFCSetIsEqualBitmap((const UInt32*)bits, (isRangeSetInverted ? (const UInt32 *)-1 : NULL))) return false; - firstChar &= 0xFFFF; - } - - lastChar &= 0xFFFF; - - isAnnexInvertStateIdentical = (isRangeSetInverted == __CFCSetAnnexIsInverted(nonRangeSet) ? true : false); - - for (idx = 1;idx < MAX_ANNEX_PLANE;idx++) { - subSet1 = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(nonRangeSet, idx); - if (NULL == subSet1) { - if (idx < firstPlane || idx > lastPlane) { - if (!isAnnexInvertStateIdentical) return false; - } else if (idx > firstPlane && idx < lastPlane) { - if (isAnnexInvertStateIdentical) return false; - } else if (idx == firstPlane) { - if (isAnnexInvertStateIdentical || firstChar || (idx == lastPlane && lastChar != 0xFFFF)) return false; - } else if (idx == lastPlane) { - if (isAnnexInvertStateIdentical || (idx == firstPlane && firstChar) || (lastChar != 0xFFFF)) return false; - } - } else { - if (__CFCSetIsBitmap(subSet1)) { - bits = __CFCSetBitmapBits(subSet1); - } else { - __CFCSetGetBitmap(subSet1, bitsBuf); - bits = bitsBuf; - } - - if (idx < firstPlane || idx > lastPlane) { - if (!__CFCSetIsEqualBitmap((const UInt32*)bits, (isAnnexInvertStateIdentical ? NULL : (const UInt32 *)-1))) return false; - } else if (idx > firstPlane && idx < lastPlane) { - if (!__CFCSetIsEqualBitmap((const UInt32*)bits, (isAnnexInvertStateIdentical ? (const UInt32 *)-1 : NULL))) return false; - } else if (idx == firstPlane) { - if (!__CFCSetIsBitmapEqualToRange((const UInt32*)bits, firstChar, (idx == lastPlane ? lastChar : 0xFFFF), !isAnnexInvertStateIdentical)) return false; - } else if (idx == lastPlane) { - if (!__CFCSetIsBitmapEqualToRange((const UInt32*)bits, (idx == firstPlane ? firstChar : 0), lastChar, !isAnnexInvertStateIdentical)) return false; - } - } - } - return true; - } - - isBitmap1 = __CFCSetIsBitmap(cf1); - isBitmap2 = __CFCSetIsBitmap(cf2); - - if (isBitmap1 && isBitmap2) { - if (!__CFCSetIsEqualBitmap((const UInt32*)__CFCSetBitmapBits(cf1), (const UInt32*)__CFCSetBitmapBits(cf2))) return false; - } else if (!isBitmap1 && !isBitmap2) { -#if __MACOS8__ - uint8_t *bitsBuf2 = (uint8_t *)CFAllocatorAllocate(NULL, __kCFBitmapSize, 0); -#else __MACOS8__ - uint8_t bitsBuf2[__kCFBitmapSize]; -#endif __MACOS8__ - - __CFCSetGetBitmap(cf1, bitsBuf); - __CFCSetGetBitmap(cf2, bitsBuf2); - - if (!__CFCSetIsEqualBitmap((const UInt32*)bitsBuf, (const UInt32*)bitsBuf2)) { -#if __MACOS8__ - CFAllocatorDeallocate(NULL, bitsBuf2); -#endif __MACOS8__ - return false; - } -#if __MACOS8__ - CFAllocatorDeallocate(NULL, bitsBuf2); -#endif __MACOS8__ - } else { - if (isBitmap2) { - CFCharacterSetRef tmp = cf2; - cf2 = cf1; - cf1 = tmp; - } - - __CFCSetGetBitmap(cf2, bitsBuf); - - if (!__CFCSetIsEqualBitmap((const UInt32*)__CFCSetBitmapBits(cf1), (const UInt32*)bitsBuf)) return false; - } - return __CFCSetIsEqualAnnex(cf1, cf2); -} - -static CFHashCode __CFCharacterSetHash(CFTypeRef cf) { - if (!__CFCSetHasHashValue(cf)) { - if (__CFCSetIsEmpty(cf)) { - ((CFMutableCharacterSetRef)cf)->_hashValue = (__CFCSetIsInverted(cf) ? 0xFFFFFFFF : 0); - } else if (__CFCSetIsBitmap(cf)) { - ((CFMutableCharacterSetRef)cf)->_hashValue = CFHashBytes(__CFCSetBitmapBits(cf), __kCFBitmapSize); - } else { - uint8_t bitsBuf[__kCFBitmapSize]; - __CFCSetGetBitmap(cf, bitsBuf); - ((CFMutableCharacterSetRef)cf)->_hashValue = CFHashBytes(bitsBuf, __kCFBitmapSize); - } - __CFCSetPutHasHashValue((CFMutableCharacterSetRef)cf, true); - } - return ((CFCharacterSetRef)cf)->_hashValue; -} - -static CFStringRef __CFCharacterSetCopyDescription(CFTypeRef cf) { - CFMutableStringRef string; - CFIndex idx; - CFIndex length; - - if (__CFCSetIsEmpty(cf)) { - return (__CFCSetIsInverted(cf) ? CFRetain(CFSTR("")) : CFRetain(CFSTR(""))); - } - - switch (__CFCSetClassType(cf)) { - case __kCFCharSetClassBuiltin: - switch (__CFCSetBuiltinType(cf)) { - case kCFCharacterSetControl: return CFRetain(__kCFCSetNameControl); - case kCFCharacterSetWhitespace : return CFRetain(__kCFCSetNameWhitespace); - case kCFCharacterSetWhitespaceAndNewline: return CFRetain(__kCFCSetNameWhitespaceAndNewline); - case kCFCharacterSetDecimalDigit: return CFRetain(__kCFCSetNameDecimalDigit); - case kCFCharacterSetLetter: return CFRetain(__kCFCSetNameLetter); - case kCFCharacterSetLowercaseLetter: return CFRetain(__kCFCSetNameLowercaseLetter); - case kCFCharacterSetUppercaseLetter: return CFRetain(__kCFCSetNameUppercaseLetter); - case kCFCharacterSetNonBase: return CFRetain(__kCFCSetNameNonBase); - case kCFCharacterSetDecomposable: return CFRetain(__kCFCSetNameDecomposable); - case kCFCharacterSetAlphaNumeric: return CFRetain(__kCFCSetNameAlphaNumeric); - case kCFCharacterSetPunctuation: return CFRetain(__kCFCSetNamePunctuation); - case kCFCharacterSetIllegal: return CFRetain(__kCFCSetNameIllegal); - case kCFCharacterSetCapitalizedLetter: return CFRetain(__kCFCSetNameCapitalizedLetter); - case kCFCharacterSetSymbol: return CFRetain(__kCFCSetNameSymbol); - } - break; - - case __kCFCharSetClassRange: - return CFStringCreateWithFormat(CFGetAllocator(cf), NULL, CFSTR(""), __CFCSetRangeFirstChar(cf), __CFCSetRangeLength(cf)); - - case __kCFCharSetClassString: - length = __CFCSetStringLength(cf); - string = CFStringCreateMutable(CFGetAllocator(cf), CFStringGetLength(__kCFCSetNameStringTypeFormat) + 7 * length + 2); // length of__kCFCSetNameStringTypeFormat + "U+XXXX "(7) * length + ")>"(2) - CFStringAppend(string, __kCFCSetNameStringTypeFormat); - for (idx = 0;idx < length;idx++) { - CFStringAppendFormat(string, NULL, CFSTR("%sU+%04X"), (idx > 0 ? " " : ""), (UInt32)((__CFCSetStringBuffer(cf))[idx])); - } - CFStringAppend(string, CFSTR(")>")); - return string; - - case __kCFCharSetClassBitmap: - case __kCFCharSetClassCompactBitmap: - return CFRetain(CFSTR("")); // ??? Should generate description for 8k bitmap ? - } - CFAssert1(0, __kCFLogAssertion, "%s: Internal inconsistency error: unknown character set type", __PRETTY_FUNCTION__); // We should never come here - return NULL; -} - -static void __CFCharacterSetDeallocate(CFTypeRef cf) { - CFAllocatorRef allocator = CFGetAllocator(cf); - - if (__CFCSetIsBuiltin(cf) && !__CFCSetIsMutable(cf) && !__CFCSetIsInverted(cf)) { - CFCharacterSetRef sharedSet = CFCharacterSetGetPredefined(__CFCSetBuiltinType(cf)); - if (sharedSet == cf) { // We're trying to dealloc the builtin set - CFAssert1(0, __kCFLogAssertion, "%s: Trying to deallocate predefined set", __PRETTY_FUNCTION__); - return; // We never deallocate builtin set - } - } - - if (__CFCSetIsString(cf) && __CFCSetStringBuffer(cf)) CFAllocatorDeallocate(allocator, __CFCSetStringBuffer(cf)); - else if (__CFCSetIsBitmap(cf) && __CFCSetBitmapBits(cf)) CFAllocatorDeallocate(allocator, __CFCSetBitmapBits(cf)); - else if (__CFCSetIsCompactBitmap(cf) && __CFCSetCompactBitmapBits(cf)) CFAllocatorDeallocate(allocator, __CFCSetCompactBitmapBits(cf)); - __CFCSetDeallocateAnnexPlane(cf); -} - -static CFTypeID __kCFCharacterSetTypeID = _kCFRuntimeNotATypeID; - -static const CFRuntimeClass __CFCharacterSetClass = { - 0, - "CFCharacterSet", - NULL, // init - NULL, // copy - __CFCharacterSetDeallocate, - __CFCharacterSetEqual, - __CFCharacterSetHash, - NULL, // - __CFCharacterSetCopyDescription -}; - -static bool __CFCheckForExapendedSet = false; - -__private_extern__ void __CFCharacterSetInitialize(void) { - const char *checkForExpandedSet = getenv("__CF_DEBUG_EXPANDED_SET"); - - __kCFCharacterSetTypeID = _CFRuntimeRegisterClass(&__CFCharacterSetClass); - - if (checkForExpandedSet && (*checkForExpandedSet == 'Y')) __CFCheckForExapendedSet = true; -} - -/* Public functions -*/ -#if defined(__MACOS8__) -CFTypeID CFCharacterSetTypeID(void) { -#ifdef DEBUG - CFLog(__kCFLogAssertion, CFSTR("CFCharacterSetTypeID should be CFCharacterSetGetTypeID")); -#endif /* DEBUG */ - return __kCFCharacterSetTypeID; -} -#endif /* __MACOS8__ */ - -CFTypeID CFCharacterSetGetTypeID(void) { - return __kCFCharacterSetTypeID; -} - -/*** CharacterSet creation ***/ -/* Functions to create basic immutable characterset. -*/ -CFCharacterSetRef CFCharacterSetGetPredefined(CFCharacterSetPredefinedSet theSetIdentifier) { - CFMutableCharacterSetRef cset; - - __CFCSetValidateBuiltinType(theSetIdentifier, __PRETTY_FUNCTION__); - - if (__CFBuiltinSets && __CFBuiltinSets[theSetIdentifier - 1]) return __CFBuiltinSets[theSetIdentifier - 1]; - - if (!(cset = __CFCSetGenericCreate(kCFAllocatorSystemDefault, __kCFCharSetClassBuiltin))) return NULL; - __CFCSetPutBuiltinType(cset, theSetIdentifier); - - if (!__CFBuiltinSets) { - __CFSpinLock(&__CFCharacterSetLock); - __CFBuiltinSets = (CFCharacterSetRef *)CFAllocatorAllocate(CFRetain(__CFGetDefaultAllocator()), sizeof(CFCharacterSetRef) * __kCFLastBuiltinSetID, 0); - memset(__CFBuiltinSets, 0, sizeof(CFCharacterSetRef) * __kCFLastBuiltinSetID); - __CFSpinUnlock(&__CFCharacterSetLock); - } - - __CFBuiltinSets[theSetIdentifier - 1] = cset; - - return cset; -} - -CFCharacterSetRef CFCharacterSetCreateWithCharactersInRange(CFAllocatorRef allocator, CFRange theRange) { - CFMutableCharacterSetRef cset; - - __CFCSetValidateRange(theRange, __PRETTY_FUNCTION__); - - if (theRange.length) { - if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassRange))) return NULL; - __CFCSetPutRangeFirstChar(cset, theRange.location); - __CFCSetPutRangeLength(cset, theRange.length); - } else { - if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassBitmap))) return NULL; - __CFCSetPutBitmapBits(cset, NULL); - __CFCSetPutHasHashValue(cset, true); // _hashValue is 0 - } - - return cset; -} - -static int chcompar(const void *a, const void *b) { - return -(int)(*(UniChar *)b - *(UniChar *)a); -} - -CFCharacterSetRef CFCharacterSetCreateWithCharactersInString(CFAllocatorRef allocator, CFStringRef theString) { - CFIndex length; - - length = CFStringGetLength(theString); - if (length < __kCFStringCharSetMax) { - CFMutableCharacterSetRef cset; - - if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassString))) return NULL; - __CFCSetPutStringBuffer(cset, CFAllocatorAllocate(CFGetAllocator(cset), __kCFStringCharSetMax * sizeof(UniChar), AUTO_MEMORY_UNSCANNED)); - __CFCSetPutStringLength(cset, length); - CFStringGetCharacters(theString, CFRangeMake(0, length), __CFCSetStringBuffer(cset)); - qsort(__CFCSetStringBuffer(cset), length, sizeof(UniChar), chcompar); - if (!length) __CFCSetPutHasHashValue(cset, true); // _hashValue is 0 - return cset; - } else { - CFMutableCharacterSetRef mcset = CFCharacterSetCreateMutable(allocator); - CFCharacterSetAddCharactersInString(mcset, theString); - __CFCSetMakeCompact(mcset); - __CFCSetPutIsMutable(mcset, false); - return mcset; - } -} - -#if defined(__MACOS8__) -CFCharacterSetRef CFCharacterSetCreateWithBitmapReresentation(CFAllocatorRef allocator, CFDataRef theData) { -#ifdef DEBUG - CFLog(__kCFLogAssertion, CFSTR("CFCharacterSetCreateWithBitmapReresentation should be CFCharacterSetCreateWithBitmapRepresentation")); -#endif /* DEBUG */ - return CFCharacterSetCreateWithBitmapRepresentation(allocator, theData); -} -#endif /* __MACOS8__ */ - -CFCharacterSetRef CFCharacterSetCreateWithBitmapRepresentation(CFAllocatorRef allocator, CFDataRef theData) { - CFMutableCharacterSetRef cset; - CFIndex length; - - if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassBitmap))) return NULL; - - if (theData && (length = CFDataGetLength(theData)) > 0) { - uint8_t *bitmap; - uint8_t *cBitmap; - - if (length < __kCFBitmapSize) { - bitmap = (uint8_t *)CFAllocatorAllocate(allocator, __kCFBitmapSize, AUTO_MEMORY_UNSCANNED); - memmove(bitmap, CFDataGetBytePtr(theData), length); - memset(bitmap + length, 0, __kCFBitmapSize - length); - - cBitmap = __CFCreateCompactBitmap(allocator, bitmap); - - if (cBitmap == NULL) { - __CFCSetPutBitmapBits(cset, bitmap); - } else { - CFAllocatorDeallocate(allocator, bitmap); - __CFCSetPutCompactBitmapBits(cset, cBitmap); - __CFCSetPutClassType(cset, __kCFCharSetClassCompactBitmap); - } - } else { - cBitmap = __CFCreateCompactBitmap(allocator, CFDataGetBytePtr(theData)); - - if (cBitmap == NULL) { - bitmap = (uint8_t *)CFAllocatorAllocate(allocator, __kCFBitmapSize, AUTO_MEMORY_UNSCANNED); - memmove(bitmap, CFDataGetBytePtr(theData), __kCFBitmapSize); - - __CFCSetPutBitmapBits(cset, bitmap); - } else { - __CFCSetPutCompactBitmapBits(cset, cBitmap); - __CFCSetPutClassType(cset, __kCFCharSetClassCompactBitmap); - } - - if (length > __kCFBitmapSize) { - CFMutableCharacterSetRef annexSet; - const char *bytes = CFDataGetBytePtr(theData) + __kCFBitmapSize; - - length -= __kCFBitmapSize; - - while (length > 1) { - annexSet = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(cset, *(bytes++)); - --length; // Decrement the plane no byte - - if (length < __kCFBitmapSize) { - bitmap = (uint8_t *)CFAllocatorAllocate(allocator, __kCFBitmapSize, AUTO_MEMORY_UNSCANNED); - memmove(bitmap, bytes, length); - memset(bitmap + length, 0, __kCFBitmapSize - length); - - cBitmap = __CFCreateCompactBitmap(allocator, bitmap); - - if (cBitmap == NULL) { - __CFCSetPutBitmapBits(annexSet, bitmap); - } else { - CFAllocatorDeallocate(allocator, bitmap); - __CFCSetPutCompactBitmapBits(annexSet, cBitmap); - __CFCSetPutClassType(annexSet, __kCFCharSetClassCompactBitmap); - } - } else { - cBitmap = __CFCreateCompactBitmap(allocator, bytes); - - if (cBitmap == NULL) { - bitmap = (uint8_t *)CFAllocatorAllocate(allocator, __kCFBitmapSize, AUTO_MEMORY_UNSCANNED); - memmove(bitmap, bytes, __kCFBitmapSize); - - __CFCSetPutBitmapBits(annexSet, bitmap); - } else { - __CFCSetPutCompactBitmapBits(annexSet, cBitmap); - __CFCSetPutClassType(annexSet, __kCFCharSetClassCompactBitmap); - } - } - length -= __kCFBitmapSize; - bytes += __kCFBitmapSize; - } - } - } - } else { - __CFCSetPutBitmapBits(cset, NULL); - __CFCSetPutHasHashValue(cset, true); // Hash value is 0 - } - - return cset; -} - -CFCharacterSetRef CFCharacterSetCreateInvertedSet(CFAllocatorRef alloc, CFCharacterSetRef theSet) { - CFMutableCharacterSetRef cset; - - CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID, CFCharacterSetRef , theSet, "invertedSet"); - - cset = CFCharacterSetCreateMutableCopy(alloc, theSet); - CFCharacterSetInvert(cset); - __CFCSetPutIsMutable(cset, false); - - return cset; -} - -/* Functions to create mutable characterset. -*/ -CFMutableCharacterSetRef CFCharacterSetCreateMutable(CFAllocatorRef allocator) { - CFMutableCharacterSetRef cset; - - if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassBitmap| __kCFCharSetIsMutable))) return NULL; - __CFCSetPutBitmapBits(cset, NULL); - __CFCSetPutHasHashValue(cset, true); // Hash value is 0 - - return cset; -} - -CFMutableCharacterSetRef __CFCharacterSetCreateCopy(CFAllocatorRef alloc, CFCharacterSetRef theSet, bool isMutable) { - CFMutableCharacterSetRef cset; - - CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID, CFMutableCharacterSetRef , theSet, "mutableCopy"); - - __CFGenericValidateType(theSet, __kCFCharacterSetTypeID); - - if (!isMutable && !__CFCSetIsMutable(theSet)) { - return (CFMutableCharacterSetRef)CFRetain(theSet); - } - - cset = CFCharacterSetCreateMutable(alloc); - - __CFCSetPutClassType(cset, __CFCSetClassType(theSet)); - __CFCSetPutHasHashValue(cset, __CFCSetHasHashValue(theSet)); - __CFCSetPutIsInverted(cset, __CFCSetIsInverted(theSet)); - cset->_hashValue = theSet->_hashValue; - - switch (__CFCSetClassType(theSet)) { - case __kCFCharSetClassBuiltin: - __CFCSetPutBuiltinType(cset, __CFCSetBuiltinType(theSet)); - break; - - case __kCFCharSetClassRange: - __CFCSetPutRangeFirstChar(cset, __CFCSetRangeFirstChar(theSet)); - __CFCSetPutRangeLength(cset, __CFCSetRangeLength(theSet)); - break; - - case __kCFCharSetClassString: - __CFCSetPutStringBuffer(cset, CFAllocatorAllocate(alloc, __kCFStringCharSetMax * sizeof(UniChar), AUTO_MEMORY_UNSCANNED)); - __CFCSetPutStringLength(cset, __CFCSetStringLength(theSet)); - memmove(__CFCSetStringBuffer(cset), __CFCSetStringBuffer(theSet), __CFCSetStringLength(theSet) * sizeof(UniChar)); - break; - - case __kCFCharSetClassBitmap: - if (__CFCSetBitmapBits(theSet)) { - uint8_t * bitmap = (isMutable ? NULL : __CFCreateCompactBitmap(alloc, __CFCSetBitmapBits(theSet))); - - if (bitmap == NULL) { - bitmap = (uint8_t *)CFAllocatorAllocate(alloc, sizeof(uint8_t) * __kCFBitmapSize, AUTO_MEMORY_UNSCANNED); - memmove(bitmap, __CFCSetBitmapBits(theSet), __kCFBitmapSize); - __CFCSetPutBitmapBits(cset, bitmap); - } else { - __CFCSetPutCompactBitmapBits(cset, bitmap); - __CFCSetPutClassType(cset, __kCFCharSetClassCompactBitmap); - } - } else { - __CFCSetPutBitmapBits(cset, NULL); - } - break; - - case __kCFCharSetClassCompactBitmap: { - const uint8_t *compactBitmap = __CFCSetCompactBitmapBits(theSet); - - if (compactBitmap) { - uint32_t size = __CFCSetGetCompactBitmapSize(compactBitmap); - uint8_t *newBitmap = (uint8_t *)CFAllocatorAllocate(alloc, size, AUTO_MEMORY_UNSCANNED); - - memmove(newBitmap, compactBitmap, size); - __CFCSetPutCompactBitmapBits(cset, newBitmap); - } - } - break; - - default: - CFAssert1(0, __kCFLogAssertion, "%s: Internal inconsistency error: unknown character set type", __PRETTY_FUNCTION__); // We should never come here - } - if (__CFCSetHasNonBMPPlane(theSet)) { - CFMutableCharacterSetRef annexPlane; - int idx; - - for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { - if ((annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx))) { - annexPlane = __CFCharacterSetCreateCopy(alloc, annexPlane, isMutable); - __CFCSetPutCharacterSetToAnnexPlane(cset, annexPlane, idx); - CFRelease(annexPlane); - } - } - __CFCSetAnnexSetIsInverted(cset, __CFCSetAnnexIsInverted(theSet)); - } else if (__CFCSetAnnexIsInverted(theSet)) { - __CFCSetAllocateAnnexForPlane(cset, 0); // We need to alloc annex to invert - __CFCSetAnnexSetIsInverted(cset, true); - } - - return cset; -} - -CFCharacterSetRef CFCharacterSetCreateCopy(CFAllocatorRef alloc, CFCharacterSetRef theSet) { - return __CFCharacterSetCreateCopy(alloc, theSet, false); -} - -CFMutableCharacterSetRef CFCharacterSetCreateMutableCopy(CFAllocatorRef alloc, CFCharacterSetRef theSet) { - return __CFCharacterSetCreateCopy(alloc, theSet, true); -} - -/*** Basic accessors ***/ -Boolean CFCharacterSetIsCharacterMember(CFCharacterSetRef theSet, UniChar theChar) { - return CFCharacterSetIsLongCharacterMember(theSet, theChar); -} - -Boolean CFCharacterSetIsLongCharacterMember(CFCharacterSetRef theSet, UTF32Char theChar) { - CFIndex length; - UInt32 plane = (theChar >> 16); - Boolean isAnnexInverted = false; - Boolean isInverted; - Boolean result = false; - - CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, Boolean, theSet, "longCharacterIsMember:", theChar); - - __CFGenericValidateType(theSet, __kCFCharacterSetTypeID); - - if (plane) { - CFCharacterSetRef annexPlane; - - if (__CFCSetIsBuiltin(theSet)) { - isInverted = __CFCSetIsInverted(theSet); - return (CFUniCharIsMemberOf(theChar, __CFCSetBuiltinType(theSet)) ? !isInverted : isInverted); - } - - isAnnexInverted = __CFCSetAnnexIsInverted(theSet); - - if ((annexPlane = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, plane)) == NULL) { - if (!__CFCSetHasNonBMPPlane(theSet) && __CFCSetIsRange(theSet)) { - isInverted = __CFCSetIsInverted(theSet); - length = __CFCSetRangeLength(theSet); - return (length && __CFCSetRangeFirstChar(theSet) <= theChar && theChar < __CFCSetRangeFirstChar(theSet) + length ? !isInverted : isInverted); - } else { - return (isAnnexInverted ? true : false); - } - } else { - theSet = annexPlane; - theChar &= 0xFFFF; - } - } - - isInverted = __CFCSetIsInverted(theSet); - - switch (__CFCSetClassType(theSet)) { - case __kCFCharSetClassBuiltin: - result = (CFUniCharIsMemberOf(theChar, __CFCSetBuiltinType(theSet)) ? !isInverted : isInverted); - break; - - case __kCFCharSetClassRange: - length = __CFCSetRangeLength(theSet); - result = (length && __CFCSetRangeFirstChar(theSet) <= theChar && theChar < __CFCSetRangeFirstChar(theSet) + length ? !isInverted : isInverted); - break; - - case __kCFCharSetClassString: - result = ((length = __CFCSetStringLength(theSet)) ? (__CFCSetBsearchUniChar(__CFCSetStringBuffer(theSet), length, theChar) ? !isInverted : isInverted) : isInverted); - break; - - case __kCFCharSetClassBitmap: - result = (__CFCSetCompactBitmapBits(theSet) ? (__CFCSetIsMemberBitmap(__CFCSetBitmapBits(theSet), theChar) ? true : false) : isInverted); - break; - - case __kCFCharSetClassCompactBitmap: - result = (__CFCSetCompactBitmapBits(theSet) ? (__CFCSetIsMemberInCompactBitmap(__CFCSetCompactBitmapBits(theSet), theChar) ? true : false) : isInverted); - break; - - default: - CFAssert1(0, __kCFLogAssertion, "%s: Internal inconsistency error: unknown character set type", __PRETTY_FUNCTION__); // We should never come here - return false; // To make compiler happy - } - - return (result ? !isAnnexInverted : isAnnexInverted); -} - -Boolean CFCharacterSetIsSurrogatePairMember(CFCharacterSetRef theSet, UniChar surrogateHigh, UniChar surrogateLow) { - return CFCharacterSetIsLongCharacterMember(theSet, CFCharacterSetGetLongCharacterForSurrogatePair(surrogateHigh, surrogateLow)); -} - - -static CFCharacterSetRef __CFCharacterSetGetExpandedSetForNSCharacterSet(const void *characterSet) { - CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID, CFCharacterSetRef , characterSet, "_expandedCFCharacterSet"); - return NULL; -} - -Boolean CFCharacterSetIsSupersetOfSet(CFCharacterSetRef theSet, CFCharacterSetRef theOtherSet) { - CFMutableCharacterSetRef copy; - CFCharacterSetRef expandedSet = NULL; - CFCharacterSetRef expandedOtherSet = NULL; - Boolean result; - - if ((!CF_IS_OBJC(__kCFCharacterSetTypeID, theSet) || (expandedSet = __CFCharacterSetGetExpandedSetForNSCharacterSet(theSet))) && (!CF_IS_OBJC(__kCFCharacterSetTypeID, theOtherSet) || (expandedOtherSet = __CFCharacterSetGetExpandedSetForNSCharacterSet(theOtherSet)))) { // Really CF, we can do some trick here - if (expandedSet) theSet = expandedSet; - if (expandedOtherSet) theOtherSet = expandedOtherSet; - - __CFGenericValidateType(theSet, __kCFCharacterSetTypeID); - __CFGenericValidateType(theOtherSet, __kCFCharacterSetTypeID); - - if (__CFCSetIsEmpty(theSet)) { - if (__CFCSetIsInverted(theSet)) { - return TRUE; // Inverted empty set covers all range - } else if (!__CFCSetIsEmpty(theOtherSet) || __CFCSetIsInverted(theOtherSet)) { - return FALSE; - } - } else if (__CFCSetIsEmpty(theOtherSet) && !__CFCSetIsInverted(theOtherSet)) { - return TRUE; - } else { - if (__CFCSetIsBuiltin(theSet) || __CFCSetIsBuiltin(theOtherSet)) { - if (__CFCSetClassType(theSet) == __CFCSetClassType(theOtherSet) && __CFCSetBuiltinType(theSet) == __CFCSetBuiltinType(theOtherSet) && !__CFCSetIsInverted(theSet) && !__CFCSetIsInverted(theOtherSet)) return TRUE; - } else if (__CFCSetIsRange(theSet) || __CFCSetIsRange(theOtherSet)) { - if (__CFCSetClassType(theSet) == __CFCSetClassType(theOtherSet)) { - if (__CFCSetIsInverted(theSet)) { - if (__CFCSetIsInverted(theOtherSet)) { - return (__CFCSetRangeFirstChar(theOtherSet) > __CFCSetRangeFirstChar(theSet) || (__CFCSetRangeFirstChar(theSet) + __CFCSetRangeLength(theSet)) > (__CFCSetRangeFirstChar(theOtherSet) + __CFCSetRangeLength(theOtherSet)) ? FALSE : TRUE); - } else { - return ((__CFCSetRangeFirstChar(theOtherSet) + __CFCSetRangeLength(theOtherSet)) <= __CFCSetRangeFirstChar(theSet) || (__CFCSetRangeFirstChar(theSet) + __CFCSetRangeLength(theSet)) <= __CFCSetRangeFirstChar(theOtherSet) ? TRUE : FALSE); - } - } else { - if (__CFCSetIsInverted(theOtherSet)) { - return ((__CFCSetRangeFirstChar(theSet) == 0 && __CFCSetRangeLength(theSet) == 0x110000) || (__CFCSetRangeFirstChar(theOtherSet) == 0 && (UInt32)__CFCSetRangeLength(theOtherSet) <= __CFCSetRangeFirstChar(theSet)) || ((__CFCSetRangeFirstChar(theSet) + __CFCSetRangeLength(theSet)) <= __CFCSetRangeFirstChar(theOtherSet) && (__CFCSetRangeFirstChar(theOtherSet) + __CFCSetRangeLength(theOtherSet)) == 0x110000) ? TRUE : FALSE); - } else { - return (__CFCSetRangeFirstChar(theOtherSet) < __CFCSetRangeFirstChar(theSet) || (__CFCSetRangeFirstChar(theSet) + __CFCSetRangeLength(theSet)) < (__CFCSetRangeFirstChar(theOtherSet) + __CFCSetRangeLength(theOtherSet)) ? FALSE : TRUE); - } - } - } - } else { - UInt32 theSetAnnexMask = __CFCSetAnnexValidEntriesBitmap(theSet); - UInt32 theOtherSetAnnexMask = __CFCSetAnnexValidEntriesBitmap(theOtherSet); - Boolean isTheSetAnnexInverted = __CFCSetAnnexIsInverted(theSet); - Boolean isTheOtherSetAnnexInverted = __CFCSetAnnexIsInverted(theOtherSet); - uint8_t theSetBuffer[__kCFBitmapSize]; - uint8_t theOtherSetBuffer[__kCFBitmapSize]; - - // We mask plane 1 to plane 16 - if (isTheSetAnnexInverted) theSetAnnexMask = (~theSetAnnexMask) & (0xFFFF < 1); - if (isTheOtherSetAnnexInverted) theOtherSetAnnexMask = (~theOtherSetAnnexMask) & (0xFFFF < 1); - - __CFCSetGetBitmap(theSet, theSetBuffer); - __CFCSetGetBitmap(theOtherSet, theOtherSetBuffer); - - if (!__CFCSetIsBitmapSupersetOfBitmap((const UInt32 *)theSetBuffer, (const UInt32 *)theOtherSetBuffer, FALSE, FALSE)) return FALSE; - - if (theOtherSetAnnexMask) { - CFCharacterSetRef theSetAnnex; - CFCharacterSetRef theOtherSetAnnex; - uint32_t idx; - - if ((theSetAnnexMask & theOtherSetAnnexMask) != theOtherSetAnnexMask) return FALSE; - - for (idx = 1;idx <= 16;idx++) { - theSetAnnex = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx); - if (NULL == theSetAnnex) continue; // This case is already handled by the mask above - - theOtherSetAnnex = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theOtherSet, idx); - - if (NULL == theOtherSetAnnex) { - if (isTheOtherSetAnnexInverted) { - __CFCSetGetBitmap(theSetAnnex, theSetBuffer); - if (!__CFCSetIsEqualBitmap((const UInt32 *)theSetBuffer, (isTheSetAnnexInverted ? NULL : (const UInt32 *)-1))) return FALSE; - } - } else { - __CFCSetGetBitmap(theSetAnnex, theSetBuffer); - __CFCSetGetBitmap(theOtherSetAnnex, theOtherSetBuffer); - if (!__CFCSetIsBitmapSupersetOfBitmap((const UInt32 *)theSetBuffer, (const UInt32 *)theOtherSetBuffer, isTheSetAnnexInverted, isTheOtherSetAnnexInverted)) return FALSE; - } - } - } - - return TRUE; - } - } - } - - copy = CFCharacterSetCreateMutableCopy(NULL, theSet); - CFCharacterSetIntersect(copy, theOtherSet); - result = __CFCharacterSetEqual(copy, theOtherSet); - CFRelease(copy); - - return result; -} - -Boolean CFCharacterSetHasMemberInPlane(CFCharacterSetRef theSet, CFIndex thePlane) { - Boolean isInverted = __CFCSetIsInverted(theSet); - - CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, Boolean, theSet, "hasMemberInPlane:", thePlane); - - if (__CFCSetIsEmpty(theSet)) { - return (isInverted ? TRUE : FALSE); - } else if (__CFCSetIsBuiltin(theSet)) { - CFCharacterSetPredefinedSet type = __CFCSetBuiltinType(theSet); - - if (type == kCFCharacterSetControl) { - if (isInverted || (thePlane == 14)) { - return TRUE; // There is no plane that covers all values || Plane 14 has language tags - } else { - return (CFUniCharGetBitmapPtrForPlane(type, thePlane) ? TRUE : FALSE); - } - } else if (type < kCFCharacterSetDecimalDigit) { - return (thePlane && !isInverted ? FALSE : TRUE); - } else if (__CFCSetBuiltinType(theSet) == kCFCharacterSetIllegal) { - return (isInverted ? (thePlane < 3 || thePlane > 13 ? TRUE : FALSE) : TRUE); // This is according to Unicode 3.1 - } else { - if (isInverted) { - return TRUE; // There is no plane that covers all values - } else { - return (CFUniCharGetBitmapPtrForPlane(type, thePlane) ? TRUE : FALSE); - } - } - } else if (__CFCSetIsRange(theSet)) { - UTF32Char firstChar = __CFCSetRangeFirstChar(theSet); - UTF32Char lastChar = (firstChar + __CFCSetRangeLength(theSet) - 1); - CFIndex firstPlane = firstChar >> 16; - CFIndex lastPlane = lastChar >> 16; - - if (isInverted) { - if (thePlane < firstPlane || thePlane > lastPlane) { - return TRUE; - } else if (thePlane > firstPlane && thePlane < lastPlane) { - return FALSE; - } else { - firstChar &= 0xFFFF; - lastChar &= 0xFFFF; - if (thePlane == firstPlane) { - return (firstChar || (firstPlane == lastPlane && lastChar != 0xFFFF) ? TRUE : FALSE); - } else { - return (lastChar != 0xFFFF || (firstPlane == lastPlane && firstChar) ? TRUE : FALSE); - } - } - } else { - return (thePlane < firstPlane || thePlane > lastPlane ? FALSE : TRUE); - } - } else { - if (thePlane == 0) { - switch (__CFCSetClassType(theSet)) { - case __kCFCharSetClassString: if (!__CFCSetStringLength(theSet)) return isInverted; break; - case __kCFCharSetClassCompactBitmap: return (__CFCSetCompactBitmapBits(theSet) ? TRUE : FALSE); break; - case __kCFCharSetClassBitmap: return (__CFCSetBitmapBits(theSet) ? TRUE : FALSE); break; - } - return TRUE; - } else { - CFCharacterSetRef annex = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, thePlane); - if (annex) { - if (__CFCSetIsRange(annex)) { - return (__CFCSetAnnexIsInverted(theSet) && (__CFCSetRangeFirstChar(annex) == 0) && (__CFCSetRangeLength(annex) == 0x10000) ? FALSE : TRUE); - } else if (__CFCSetIsBitmap(annex)) { - return (__CFCSetAnnexIsInverted(theSet) && __CFCSetIsEqualBitmap((const UInt32 *)__CFCSetBitmapBits(annex), (const UInt32 *)-1) ? FALSE : TRUE); - } else { - uint8_t bitsBuf[__kCFBitmapSize]; - __CFCSetGetBitmap(annex, bitsBuf); - return (__CFCSetAnnexIsInverted(theSet) && __CFCSetIsEqualBitmap((const UInt32 *)bitsBuf, (const UInt32 *)-1) ? FALSE : TRUE); - } - } else { - return __CFCSetAnnexIsInverted(theSet); - } - } - } - - return FALSE; -} - - -CFDataRef CFCharacterSetCreateBitmapRepresentation(CFAllocatorRef alloc, CFCharacterSetRef theSet) { - CFMutableDataRef data; - int numNonBMPPlanes = 0; - int planeIndices[MAX_ANNEX_PLANE]; - int idx; - int length; - bool isAnnexInverted; - - CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID, CFDataRef , theSet, "_retainedBitmapRepresentation"); - - __CFGenericValidateType(theSet, __kCFCharacterSetTypeID); - - isAnnexInverted = __CFCSetAnnexIsInverted(theSet); - - if (__CFCSetHasNonBMPPlane(theSet)) { - for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { - if (isAnnexInverted || __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx)) { - planeIndices[numNonBMPPlanes++] = idx; - } - } - } else if (__CFCSetIsBuiltin(theSet)) { - numNonBMPPlanes = (__CFCSetIsInverted(theSet) ? MAX_ANNEX_PLANE : CFUniCharGetNumberOfPlanes(__CFCSetBuiltinType(theSet)) - 1); - } else if (__CFCSetIsRange(theSet)) { - UInt32 firstChar = __CFCSetRangeFirstChar(theSet); - UInt32 lastChar = __CFCSetRangeFirstChar(theSet) + __CFCSetRangeLength(theSet) - 1; - int firstPlane = (firstChar >> 16); - int lastPlane = (lastChar >> 16); - bool isInverted = __CFCSetIsInverted(theSet); - - if (lastPlane > 0) { - if (firstPlane == 0) { - firstPlane = 1; - firstChar = 0x10000; - } - numNonBMPPlanes = (lastPlane - firstPlane) + 1; - if (isInverted) { - numNonBMPPlanes = MAX_ANNEX_PLANE - numNonBMPPlanes; - if (firstPlane == lastPlane) { - if (((firstChar & 0xFFFF) > 0) || ((lastChar & 0xFFFF) < 0xFFFF)) ++numNonBMPPlanes; - } else { - if ((firstChar & 0xFFFF) > 0) ++numNonBMPPlanes; - if ((lastChar & 0xFFFF) < 0xFFFF) ++numNonBMPPlanes; - } - } - } else if (isInverted) { - numNonBMPPlanes = MAX_ANNEX_PLANE; - } - } else if (isAnnexInverted) { - numNonBMPPlanes = MAX_ANNEX_PLANE; - } - - length = __kCFBitmapSize + ((__kCFBitmapSize + 1) * numNonBMPPlanes); - data = CFDataCreateMutable(alloc, length); - CFDataSetLength(data, length); - __CFCSetGetBitmap(theSet, CFDataGetMutableBytePtr(data)); - - if (numNonBMPPlanes > 0) { - char *bytes = CFDataGetMutableBytePtr(data) + __kCFBitmapSize; - - if (__CFCSetHasNonBMPPlane(theSet)) { - CFCharacterSetRef subset; - - for (idx = 0;idx < numNonBMPPlanes;idx++) { - *(bytes++) = planeIndices[idx]; - if ((subset = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, planeIndices[idx])) == NULL) { - __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, (isAnnexInverted ? 0xFF : 0)); - } else { - __CFCSetGetBitmap(subset, bytes); - if (isAnnexInverted) { - uint32_t count = __kCFBitmapSize / sizeof(uint32_t); - uint32_t *bits = (uint32_t *)bytes; - - while (count-- > 0) { - *bits = ~(*bits); - ++bits; - } - } - } - bytes += __kCFBitmapSize; - } - } else if (__CFCSetIsBuiltin(theSet)) { - UInt8 result; - Boolean isInverted = __CFCSetIsInverted(theSet); - - for (idx = 0;idx < numNonBMPPlanes;idx++) { - if ((result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(theSet), idx + 1, bytes + 1, isInverted)) == kCFUniCharBitmapEmpty) continue; - *(bytes++) = idx + 1; - if (result == kCFUniCharBitmapAll) { - CFIndex bitmapLength = __kCFBitmapSize; - while (bitmapLength-- > 0) *(bytes++) = (uint8_t)0xFF; - } else { - bytes += __kCFBitmapSize; - } - } - if (bytes - (const char *)CFDataGetBytePtr(data) < length) CFDataSetLength(data, bytes - (const char *)CFDataGetBytePtr(data)); - } else if (__CFCSetIsRange(theSet)) { - UInt32 firstChar = __CFCSetRangeFirstChar(theSet); - UInt32 lastChar = __CFCSetRangeFirstChar(theSet) + __CFCSetRangeLength(theSet) - 1; - int firstPlane = (firstChar >> 16); - int lastPlane = (lastChar >> 16); - - if (firstPlane == 0) { - firstPlane = 1; - firstChar = 0x10000; - } - if (__CFCSetIsInverted(theSet)) { - // Mask out the plane byte - firstChar &= 0xFFFF; - lastChar &= 0xFFFF; - - for (idx = 1;idx < firstPlane;idx++) { // Fill up until the first plane - *(bytes++) = idx; - __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0xFF); - bytes += __kCFBitmapSize; - } - if (firstPlane == lastPlane) { - if ((firstChar > 0) || (lastChar < 0xFFFF)) { - *(bytes++) = idx; - __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0xFF); - __CFCSetBitmapRemoveCharactersInRange(bytes, firstChar, lastChar); - bytes += __kCFBitmapSize; - } - } else if (firstPlane < lastPlane) { - if (firstChar > 0) { - *(bytes++) = idx; - __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0); - __CFCSetBitmapAddCharactersInRange(bytes, 0, firstChar - 1); - bytes += __kCFBitmapSize; - } - if (lastChar < 0xFFFF) { - *(bytes++) = idx; - __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0); - __CFCSetBitmapAddCharactersInRange(bytes, lastChar, 0xFFFF); - bytes += __kCFBitmapSize; - } - } - for (idx = lastPlane + 1;idx <= MAX_ANNEX_PLANE;idx++) { - *(bytes++) = idx; - __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0xFF); - bytes += __kCFBitmapSize; - } - } else { - for (idx = firstPlane;idx <= lastPlane;idx++) { - *(bytes++) = idx; - __CFCSetBitmapAddCharactersInRange(bytes, (idx == firstPlane ? firstChar : 0), (idx == lastPlane ? lastChar : 0xFFFF)); - bytes += __kCFBitmapSize; - } - } - } else if (isAnnexInverted) { - for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { - *(bytes++) = idx; - __CFCSetBitmapFastFillWithValue((UInt32 *)bytes, 0xFF); - bytes += __kCFBitmapSize; - } - } - } - - return data; -} - -/*** MutableCharacterSet functions ***/ -void CFCharacterSetAddCharactersInRange(CFMutableCharacterSetRef theSet, CFRange theRange) { - CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, void, theSet, "addCharactersInRange:", theRange); - - __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__); - __CFCSetValidateRange(theRange, __PRETTY_FUNCTION__); - - if (!theRange.length || (__CFCSetIsInverted(theSet) && __CFCSetIsEmpty(theSet))) return; // Inverted && empty set contains all char - - if (!__CFCSetIsInverted(theSet)) { - if (__CFCSetIsEmpty(theSet)) { - __CFCSetPutClassType(theSet, __kCFCharSetClassRange); - __CFCSetPutRangeFirstChar(theSet, theRange.location); - __CFCSetPutRangeLength(theSet, theRange.length); - __CFCSetPutHasHashValue(theSet, false); - return; - } else if (__CFCSetIsRange(theSet)) { - CFIndex firstChar = __CFCSetRangeFirstChar(theSet); - CFIndex length = __CFCSetRangeLength(theSet); - - if (firstChar == theRange.location) { - __CFCSetPutRangeLength(theSet, __CFMin(length, theRange.length)); - __CFCSetPutHasHashValue(theSet, false); - return; - } else if (firstChar < theRange.location && theRange.location <= firstChar + length) { - if (firstChar + length < theRange.location + theRange.length) __CFCSetPutRangeLength(theSet, theRange.length + (theRange.location - firstChar)); - __CFCSetPutHasHashValue(theSet, false); - return; - } else if (theRange.location < firstChar && firstChar <= theRange.location + theRange.length) { - __CFCSetPutRangeFirstChar(theSet, theRange.location); - __CFCSetPutRangeLength(theSet, length + (firstChar - theRange.location)); - __CFCSetPutHasHashValue(theSet, false); - return; - } - } else if (__CFCSetIsString(theSet) && __CFCSetStringLength(theSet) + theRange.length < __kCFStringCharSetMax) { - UniChar *buffer; - if (!__CFCSetStringBuffer(theSet)) - __CFCSetPutStringBuffer(theSet, CFAllocatorAllocate(CFGetAllocator(theSet), __kCFStringCharSetMax * sizeof(UniChar), AUTO_MEMORY_UNSCANNED)); - buffer = __CFCSetStringBuffer(theSet) + __CFCSetStringLength(theSet); - __CFCSetPutStringLength(theSet, __CFCSetStringLength(theSet) + theRange.length); - while (theRange.length--) *buffer++ = theRange.location++; - qsort(__CFCSetStringBuffer(theSet), __CFCSetStringLength(theSet), sizeof(UniChar), chcompar); - __CFCSetPutHasHashValue(theSet, false); - return; - } - } - - // OK, I have to be a bitmap - __CFCSetMakeBitmap(theSet); - __CFCSetAddNonBMPPlanesInRange(theSet, theRange); - if (theRange.location < 0x10000) { // theRange is in BMP - if (theRange.location + theRange.length >= NUMCHARACTERS) theRange.length = NUMCHARACTERS - theRange.location; - __CFCSetBitmapAddCharactersInRange(__CFCSetBitmapBits(theSet), theRange.location, theRange.location + theRange.length - 1); - } - __CFCSetPutHasHashValue(theSet, false); - - if (__CFCheckForExapendedSet) __CFCheckForExpandedSet(theSet); -} - -void CFCharacterSetRemoveCharactersInRange(CFMutableCharacterSetRef theSet, CFRange theRange) { - CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, void, theSet, "removeCharactersInRange:", theRange); - - __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__); - __CFCSetValidateRange(theRange, __PRETTY_FUNCTION__); - - if (!theRange.length || (!__CFCSetIsInverted(theSet) && __CFCSetIsEmpty(theSet))) return; // empty set - - if (__CFCSetIsInverted(theSet)) { - if (__CFCSetIsEmpty(theSet)) { - __CFCSetPutClassType(theSet, __kCFCharSetClassRange); - __CFCSetPutRangeFirstChar(theSet, theRange.location); - __CFCSetPutRangeLength(theSet, theRange.length); - __CFCSetPutHasHashValue(theSet, false); - return; - } else if (__CFCSetIsRange(theSet)) { - CFIndex firstChar = __CFCSetRangeFirstChar(theSet); - CFIndex length = __CFCSetRangeLength(theSet); - - if (firstChar == theRange.location) { - __CFCSetPutRangeLength(theSet, __CFMin(length, theRange.length)); - __CFCSetPutHasHashValue(theSet, false); - return; - } else if (firstChar < theRange.location && theRange.location <= firstChar + length) { - if (firstChar + length < theRange.location + theRange.length) __CFCSetPutRangeLength(theSet, theRange.length + (theRange.location - firstChar)); - __CFCSetPutHasHashValue(theSet, false); - return; - } else if (theRange.location < firstChar && firstChar <= theRange.location + theRange.length) { - __CFCSetPutRangeFirstChar(theSet, theRange.location); - __CFCSetPutRangeLength(theSet, length + (firstChar - theRange.location)); - __CFCSetPutHasHashValue(theSet, false); - return; - } - } else if (__CFCSetIsString(theSet) && __CFCSetStringLength(theSet) + theRange.length < __kCFStringCharSetMax) { - UniChar *buffer; - if (!__CFCSetStringBuffer(theSet)) - __CFCSetPutStringBuffer(theSet, CFAllocatorAllocate(CFGetAllocator(theSet), __kCFStringCharSetMax * sizeof(UniChar), AUTO_MEMORY_UNSCANNED)); - buffer = __CFCSetStringBuffer(theSet) + __CFCSetStringLength(theSet); - __CFCSetPutStringLength(theSet, __CFCSetStringLength(theSet) + theRange.length); - while (theRange.length--) *buffer++ = theRange.location++; - qsort(__CFCSetStringBuffer(theSet), __CFCSetStringLength(theSet), sizeof(UniChar), chcompar); - __CFCSetPutHasHashValue(theSet, false); - return; - } - } - - // OK, I have to be a bitmap - __CFCSetMakeBitmap(theSet); - __CFCSetRemoveNonBMPPlanesInRange(theSet, theRange); - if (theRange.location < 0x10000) { // theRange is in BMP - if (theRange.location + theRange.length > NUMCHARACTERS) theRange.length = NUMCHARACTERS - theRange.location; - if (theRange.location == 0 && theRange.length == NUMCHARACTERS) { // Remove all - CFAllocatorDeallocate(CFGetAllocator(theSet), __CFCSetBitmapBits(theSet)); - __CFCSetPutBitmapBits(theSet, NULL); - } else { - __CFCSetBitmapRemoveCharactersInRange(__CFCSetBitmapBits(theSet), theRange.location, theRange.location + theRange.length - 1); - } - } - - __CFCSetPutHasHashValue(theSet, false); - if (__CFCheckForExapendedSet) __CFCheckForExpandedSet(theSet); -} - -void CFCharacterSetAddCharactersInString(CFMutableCharacterSetRef theSet, CFStringRef theString) { - const UniChar *buffer; - CFIndex length; - - CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, void, theSet, "addCharactersInString:", theString); - - __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__); - - if ((__CFCSetIsEmpty(theSet) && __CFCSetIsInverted(theSet)) || !(length = CFStringGetLength(theString))) return; - - if (!__CFCSetIsInverted(theSet)) { - CFIndex newLength = length + (__CFCSetIsEmpty(theSet) ? 0 : (__CFCSetIsString(theSet) ? __CFCSetStringLength(theSet) : __kCFStringCharSetMax)); - - if (newLength < __kCFStringCharSetMax) { - if (__CFCSetIsEmpty(theSet)) __CFCSetPutStringLength(theSet, 0); // Make sure to reset this - - if (!__CFCSetStringBuffer(theSet)) - __CFCSetPutStringBuffer(theSet, CFAllocatorAllocate(CFGetAllocator(theSet), __kCFStringCharSetMax * sizeof(UniChar), AUTO_MEMORY_UNSCANNED)); - buffer = __CFCSetStringBuffer(theSet) + __CFCSetStringLength(theSet); - - __CFCSetPutClassType(theSet, __kCFCharSetClassString); - __CFCSetPutStringLength(theSet, newLength); - CFStringGetCharacters(theString, CFRangeMake(0, length), (UniChar*)buffer); - qsort(__CFCSetStringBuffer(theSet), newLength, sizeof(UniChar), chcompar); - __CFCSetPutHasHashValue(theSet, false); - return; - } - } - - // OK, I have to be a bitmap - __CFCSetMakeBitmap(theSet); - if ((buffer = CFStringGetCharactersPtr(theString))) { - while (length--) __CFCSetBitmapAddCharacter(__CFCSetBitmapBits(theSet), *buffer++); - } else { - CFStringInlineBuffer inlineBuffer; - CFIndex idx; - - CFStringInitInlineBuffer(theString, &inlineBuffer, CFRangeMake(0, length)); - for (idx = 0;idx < length;idx++) __CFCSetBitmapAddCharacter(__CFCSetBitmapBits(theSet), __CFStringGetCharacterFromInlineBufferQuick(&inlineBuffer, idx)); - } - __CFCSetPutHasHashValue(theSet, false); - if (__CFCheckForExapendedSet) __CFCheckForExpandedSet(theSet); -} - -void CFCharacterSetRemoveCharactersInString(CFMutableCharacterSetRef theSet, CFStringRef theString) { - const UniChar *buffer; - CFIndex length; - - CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, void, theSet, "removeCharactersInString:", theString); - - __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__); - - if ((__CFCSetIsEmpty(theSet) && !__CFCSetIsInverted(theSet)) || !(length = CFStringGetLength(theString))) return; - - if (__CFCSetIsInverted(theSet)) { - CFIndex newLength = length + (__CFCSetIsEmpty(theSet) ? 0 : (__CFCSetIsString(theSet) ? __CFCSetStringLength(theSet) : __kCFStringCharSetMax)); - - if (newLength < __kCFStringCharSetMax) { - if (__CFCSetIsEmpty(theSet)) __CFCSetPutStringLength(theSet, 0); // Make sure to reset this - - if (!__CFCSetStringBuffer(theSet)) - __CFCSetPutStringBuffer(theSet, CFAllocatorAllocate(CFGetAllocator(theSet), __kCFStringCharSetMax * sizeof(UniChar), AUTO_MEMORY_UNSCANNED)); - buffer = __CFCSetStringBuffer(theSet) + __CFCSetStringLength(theSet); - - __CFCSetPutClassType(theSet, __kCFCharSetClassString); - __CFCSetPutStringLength(theSet, newLength); - CFStringGetCharacters(theString, CFRangeMake(0, length), (UniChar *)buffer); - qsort(__CFCSetStringBuffer(theSet), newLength, sizeof(UniChar), chcompar); - __CFCSetPutHasHashValue(theSet, false); - return; - } - } - - // OK, I have to be a bitmap - __CFCSetMakeBitmap(theSet); - if ((buffer = CFStringGetCharactersPtr(theString))) { - while (length--) __CFCSetBitmapRemoveCharacter(__CFCSetBitmapBits(theSet), *buffer++); - } else { - CFStringInlineBuffer inlineBuffer; - CFIndex idx; - - CFStringInitInlineBuffer(theString, &inlineBuffer, CFRangeMake(0, length)); - for (idx = 0;idx < length;idx++) __CFCSetBitmapRemoveCharacter(__CFCSetBitmapBits(theSet), __CFStringGetCharacterFromInlineBufferQuick(&inlineBuffer, idx)); - } - __CFCSetPutHasHashValue(theSet, false); - if (__CFCheckForExapendedSet) __CFCheckForExpandedSet(theSet); -} - -void CFCharacterSetUnion(CFMutableCharacterSetRef theSet, CFCharacterSetRef theOtherSet) { - CFCharacterSetRef expandedSet = NULL; - - CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, void, theSet, "formUnionWithCharacterSet:", theOtherSet); - - __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__); - - if (__CFCSetIsEmpty(theSet) && __CFCSetIsInverted(theSet)) return; // Inverted empty set contains all char - - if (!CF_IS_OBJC(__kCFCharacterSetTypeID, theOtherSet) || (expandedSet = __CFCharacterSetGetExpandedSetForNSCharacterSet(theOtherSet))) { // Really CF, we can do some trick here - if (expandedSet) theOtherSet = expandedSet; - - if (__CFCSetIsEmpty(theOtherSet)) { - if (__CFCSetIsInverted(theOtherSet)) { - if (__CFCSetIsString(theSet) && __CFCSetStringBuffer(theSet)) { - CFAllocatorDeallocate(CFGetAllocator(theSet), __CFCSetStringBuffer(theSet)); - } else if (__CFCSetIsBitmap(theSet) && __CFCSetBitmapBits(theSet)) { - CFAllocatorDeallocate(CFGetAllocator(theSet), __CFCSetBitmapBits(theSet)); - } else if (__CFCSetIsCompactBitmap(theSet) && __CFCSetCompactBitmapBits(theSet)) { - CFAllocatorDeallocate(CFGetAllocator(theSet), __CFCSetCompactBitmapBits(theSet)); - } - __CFCSetPutClassType(theSet, __kCFCharSetClassRange); - __CFCSetPutRangeLength(theSet, 0); - __CFCSetPutIsInverted(theSet, true); - __CFCSetPutHasHashValue(theSet, false); - __CFCSetDeallocateAnnexPlane(theSet); - } else { - return; // Nothing to do here - } - } - - if (__CFCSetIsBuiltin(theOtherSet) && __CFCSetIsEmpty(theSet)) { // theSet can be builtin set - __CFCSetPutClassType(theSet, __kCFCharSetClassBuiltin); - __CFCSetPutBuiltinType(theSet, __CFCSetBuiltinType(theOtherSet)); - __CFCSetPutHasHashValue(theSet, false); - } else if (__CFCSetIsRange(theOtherSet)) { - if (__CFCSetIsInverted(theOtherSet)) { - UTF32Char firstChar = __CFCSetRangeFirstChar(theOtherSet); - CFIndex length = __CFCSetRangeLength(theOtherSet); - - if (firstChar > 0) CFCharacterSetAddCharactersInRange(theSet, CFRangeMake(0, firstChar)); - firstChar += length; - length = 0x110000 - firstChar; - CFCharacterSetAddCharactersInRange(theSet, CFRangeMake(firstChar, length)); - } else { - CFCharacterSetAddCharactersInRange(theSet, CFRangeMake(__CFCSetRangeFirstChar(theOtherSet), __CFCSetRangeLength(theOtherSet))); - } - } else if (__CFCSetIsString(theOtherSet)) { - CFStringRef string = CFStringCreateWithCharactersNoCopy(CFGetAllocator(theSet), __CFCSetStringBuffer(theOtherSet), __CFCSetStringLength(theOtherSet), kCFAllocatorNull); - CFCharacterSetAddCharactersInString(theSet, string); - CFRelease(string); - } else { - __CFCSetMakeBitmap(theSet); - if (__CFCSetIsBitmap(theOtherSet)) { - UInt32 *bitmap1 = (UInt32*)__CFCSetBitmapBits(theSet); - UInt32 *bitmap2 = (UInt32*)__CFCSetBitmapBits(theOtherSet); - CFIndex length = __kCFBitmapSize / sizeof(UInt32); - while (length--) *bitmap1++ |= *bitmap2++; - } else { - UInt32 *bitmap1 = (UInt32*)__CFCSetBitmapBits(theSet); - UInt32 *bitmap2; - CFIndex length = __kCFBitmapSize / sizeof(UInt32); - uint8_t bitmapBuffer[__kCFBitmapSize]; - __CFCSetGetBitmap(theOtherSet, bitmapBuffer); - bitmap2 = (UInt32*)bitmapBuffer; - while (length--) *bitmap1++ |= *bitmap2++; - } - __CFCSetPutHasHashValue(theSet, false); - } - if (__CFCSetHasNonBMPPlane(theOtherSet)) { - CFMutableCharacterSetRef otherSetPlane; - int idx; - - for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { - if ((otherSetPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theOtherSet, idx))) { - CFCharacterSetUnion((CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx), otherSetPlane); - } - } - } else if (__CFCSetIsBuiltin(theOtherSet)) { - CFMutableCharacterSetRef annexPlane; - uint8_t bitmapBuffer[__kCFBitmapSize]; - uint8_t result; - int planeIndex; - Boolean isOtherAnnexPlaneInverted = __CFCSetAnnexIsInverted(theOtherSet); - UInt32 *bitmap1; - UInt32 *bitmap2; - CFIndex length; - - for (planeIndex = 1;planeIndex <= MAX_ANNEX_PLANE;planeIndex++) { - result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(theOtherSet), planeIndex, bitmapBuffer, isOtherAnnexPlaneInverted); - if (result != kCFUniCharBitmapEmpty) { - annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, planeIndex); - if (result == kCFUniCharBitmapAll) { - CFCharacterSetAddCharactersInRange(annexPlane, CFRangeMake(0x0000, 0x10000)); - } else { - __CFCSetMakeBitmap(annexPlane); - bitmap1 = (UInt32 *)__CFCSetBitmapBits(annexPlane); - length = __kCFBitmapSize / sizeof(UInt32); - bitmap2 = (UInt32*)bitmapBuffer; - while (length--) *bitmap1++ |= *bitmap2++; - } - } - } - } - if (__CFCheckForExapendedSet) __CFCheckForExpandedSet(theSet); - } else { // It's NSCharacterSet - CFDataRef bitmapRep = CFCharacterSetCreateBitmapRepresentation(NULL, theOtherSet); - const UInt32 *bitmap2 = (bitmapRep && CFDataGetLength(bitmapRep) ? (const UInt32 *)CFDataGetBytePtr(bitmapRep) : NULL); - if (bitmap2) { - UInt32 *bitmap1; - CFIndex length = __kCFBitmapSize / sizeof(UInt32); - __CFCSetMakeBitmap(theSet); - bitmap1 = (UInt32*)__CFCSetBitmapBits(theSet); - while (length--) *bitmap1++ |= *bitmap2++; - __CFCSetPutHasHashValue(theSet, false); - } - CFRelease(bitmapRep); - } -} - -void CFCharacterSetIntersect(CFMutableCharacterSetRef theSet, CFCharacterSetRef theOtherSet) { - CFCharacterSetRef expandedSet = NULL; - - CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, void, theSet, "formIntersectionWithCharacterSet:", theOtherSet); - - __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__); - - if (__CFCSetIsEmpty(theSet) && !__CFCSetIsInverted(theSet)) return; // empty set - - if (!CF_IS_OBJC(__kCFCharacterSetTypeID, theOtherSet) || (expandedSet = __CFCharacterSetGetExpandedSetForNSCharacterSet(theOtherSet))) { // Really CF, we can do some trick here - if (expandedSet) theOtherSet = expandedSet; - - if (__CFCSetIsEmpty(theOtherSet)) { - if (!__CFCSetIsInverted(theOtherSet)) { - if (__CFCSetIsString(theSet) && __CFCSetStringBuffer(theSet)) { - CFAllocatorDeallocate(CFGetAllocator(theSet), __CFCSetStringBuffer(theSet)); - } else if (__CFCSetIsBitmap(theSet) && __CFCSetBitmapBits(theSet)) { - CFAllocatorDeallocate(CFGetAllocator(theSet), __CFCSetBitmapBits(theSet)); - } else if (__CFCSetIsCompactBitmap(theSet) && __CFCSetCompactBitmapBits(theSet)) { - CFAllocatorDeallocate(CFGetAllocator(theSet), __CFCSetCompactBitmapBits(theSet)); - } - __CFCSetPutClassType(theSet, __kCFCharSetClassBitmap); - __CFCSetPutBitmapBits(theSet, NULL); - __CFCSetPutIsInverted(theSet, false); - theSet->_hashValue = 0; - __CFCSetPutHasHashValue(theSet, true); - __CFCSetDeallocateAnnexPlane(theSet); - } - } else if (__CFCSetIsEmpty(theSet)) { // non inverted empty set contains all character - __CFCSetPutClassType(theSet, __CFCSetClassType(theOtherSet)); - __CFCSetPutHasHashValue(theSet, __CFCSetHasHashValue(theOtherSet)); - __CFCSetPutIsInverted(theSet, __CFCSetIsInverted(theOtherSet)); - theSet->_hashValue = theOtherSet->_hashValue; - if (__CFCSetHasNonBMPPlane(theOtherSet)) { - CFMutableCharacterSetRef otherSetPlane; - int idx; - for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { - if ((otherSetPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theOtherSet, idx))) { - otherSetPlane = (CFMutableCharacterSetRef)CFCharacterSetCreateMutableCopy(CFGetAllocator(theSet), otherSetPlane); - __CFCSetPutCharacterSetToAnnexPlane(theSet, otherSetPlane, idx); - CFRelease(otherSetPlane); - } - } - __CFCSetAnnexSetIsInverted(theSet, __CFCSetAnnexIsInverted(theOtherSet)); - } - - switch (__CFCSetClassType(theOtherSet)) { - case __kCFCharSetClassBuiltin: - __CFCSetPutBuiltinType(theSet, __CFCSetBuiltinType(theOtherSet)); - break; - - case __kCFCharSetClassRange: - __CFCSetPutRangeFirstChar(theSet, __CFCSetRangeFirstChar(theOtherSet)); - __CFCSetPutRangeLength(theSet, __CFCSetRangeLength(theOtherSet)); - break; - - case __kCFCharSetClassString: - __CFCSetPutStringLength(theSet, __CFCSetStringLength(theOtherSet)); - if (!__CFCSetStringBuffer(theSet)) - __CFCSetPutStringBuffer(theSet, CFAllocatorAllocate(CFGetAllocator(theSet), __kCFStringCharSetMax * sizeof(UniChar), AUTO_MEMORY_UNSCANNED)); - memmove(__CFCSetStringBuffer(theSet), __CFCSetStringBuffer(theOtherSet), __CFCSetStringLength(theSet) * sizeof(UniChar)); - break; - - case __kCFCharSetClassBitmap: - __CFCSetPutBitmapBits(theSet, CFAllocatorAllocate(CFGetAllocator(theSet), sizeof(uint8_t) * __kCFBitmapSize, AUTO_MEMORY_UNSCANNED)); - memmove(__CFCSetBitmapBits(theSet), __CFCSetBitmapBits(theOtherSet), __kCFBitmapSize); - break; - - case __kCFCharSetClassCompactBitmap: { - const uint8_t *cBitmap = __CFCSetCompactBitmapBits(theOtherSet); - uint8_t *newBitmap; - uint32_t size = __CFCSetGetCompactBitmapSize(cBitmap); - newBitmap = (uint8_t *)CFAllocatorAllocate(CFGetAllocator(theSet), sizeof(uint8_t) * size, AUTO_MEMORY_UNSCANNED); - __CFCSetPutBitmapBits(theSet, newBitmap); - memmove(newBitmap, cBitmap, size); - } - break; - - default: - CFAssert1(0, __kCFLogAssertion, "%s: Internal inconsistency error: unknown character set type", __PRETTY_FUNCTION__); // We should never come here - } - } else { - __CFCSetMakeBitmap(theSet); - if (__CFCSetIsBitmap(theOtherSet)) { - UInt32 *bitmap1 = (UInt32*)__CFCSetBitmapBits(theSet); - UInt32 *bitmap2 = (UInt32*)__CFCSetBitmapBits(theOtherSet); - CFIndex length = __kCFBitmapSize / sizeof(UInt32); - while (length--) *bitmap1++ &= *bitmap2++; - } else { - UInt32 *bitmap1 = (UInt32*)__CFCSetBitmapBits(theSet); - UInt32 *bitmap2; - CFIndex length = __kCFBitmapSize / sizeof(UInt32); - uint8_t bitmapBuffer[__kCFBitmapSize]; - __CFCSetGetBitmap(theOtherSet, bitmapBuffer); - bitmap2 = (UInt32*)bitmapBuffer; - while (length--) *bitmap1++ &= *bitmap2++; - } - __CFCSetPutHasHashValue(theSet, false); - if (__CFCSetHasNonBMPPlane(theOtherSet)) { - CFMutableCharacterSetRef annexPlane; - CFMutableCharacterSetRef otherSetPlane; - int idx; - for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { - if ((otherSetPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theOtherSet, idx))) { - annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx); - CFCharacterSetIntersect(annexPlane, otherSetPlane); - if (__CFCSetIsEmpty(annexPlane) && !__CFCSetIsInverted(annexPlane)) __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx); - } else if (__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx)) { - __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx); - } - } - if (!__CFCSetHasNonBMPPlane(theSet)) __CFCSetDeallocateAnnexPlane(theSet); - } else if (__CFCSetIsBuiltin(theOtherSet)) { - CFMutableCharacterSetRef annexPlane; - uint8_t bitmapBuffer[__kCFBitmapSize]; - uint8_t result; - int planeIndex; - Boolean isOtherAnnexPlaneInverted = __CFCSetAnnexIsInverted(theOtherSet); - UInt32 *bitmap1; - UInt32 *bitmap2; - CFIndex length; - - for (planeIndex = 1;planeIndex <= MAX_ANNEX_PLANE;planeIndex++) { - annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, planeIndex); - if (annexPlane) { - result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(theOtherSet), planeIndex, bitmapBuffer, isOtherAnnexPlaneInverted); - if (result == kCFUniCharBitmapEmpty) { - __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, planeIndex); - } else if (result == kCFUniCharBitmapFilled) { - Boolean isEmpty = true; - - __CFCSetMakeBitmap(annexPlane); - bitmap1 = (UInt32 *)__CFCSetBitmapBits(annexPlane); - length = __kCFBitmapSize / sizeof(UInt32); - bitmap2 = (UInt32*)bitmapBuffer; - - while (length--) { - if ((*bitmap1++ &= *bitmap2++)) isEmpty = false; - } - if (isEmpty) __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, planeIndex); - } - } - } - if (!__CFCSetHasNonBMPPlane(theSet)) __CFCSetDeallocateAnnexPlane(theSet); - } else if (__CFCSetIsRange(theOtherSet)) { - CFMutableCharacterSetRef tempOtherSet = CFCharacterSetCreateMutable(CFGetAllocator(theSet)); - CFMutableCharacterSetRef annexPlane; - CFMutableCharacterSetRef otherSetPlane; - int idx; - - __CFCSetAddNonBMPPlanesInRange(tempOtherSet, CFRangeMake(__CFCSetRangeFirstChar(theOtherSet), __CFCSetRangeLength(theOtherSet))); - - for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { - if ((otherSetPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(tempOtherSet, idx))) { - annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx); - CFCharacterSetIntersect(annexPlane, otherSetPlane); - if (__CFCSetIsEmpty(annexPlane) && !__CFCSetIsInverted(annexPlane)) __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx); - } else if (__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx)) { - __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx); - } - } - if (!__CFCSetHasNonBMPPlane(theSet)) __CFCSetDeallocateAnnexPlane(theSet); - CFRelease(tempOtherSet); - } else if (__CFCSetHasNonBMPPlane(theSet)) { - __CFCSetDeallocateAnnexPlane(theSet); - } - } - if (__CFCheckForExapendedSet) __CFCheckForExpandedSet(theSet); - } else { // It's NSCharacterSet - CFDataRef bitmapRep = CFCharacterSetCreateBitmapRepresentation(NULL, theOtherSet); - const UInt32 *bitmap2 = (bitmapRep && CFDataGetLength(bitmapRep) ? (const UInt32 *)CFDataGetBytePtr(bitmapRep) : NULL); - if (bitmap2) { - UInt32 *bitmap1; - CFIndex length = __kCFBitmapSize / sizeof(UInt32); - __CFCSetMakeBitmap(theSet); - bitmap1 = (UInt32*)__CFCSetBitmapBits(theSet); - while (length--) *bitmap1++ &= *bitmap2++; - __CFCSetPutHasHashValue(theSet, false); - } - CFRelease(bitmapRep); - } -} - -void CFCharacterSetInvert(CFMutableCharacterSetRef theSet) { - - CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID, void, theSet, "invert"); - - __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__); - - __CFCSetPutHasHashValue(theSet, false); - - if (__CFCSetClassType(theSet) == __kCFCharSetClassBitmap) { - CFIndex idx; - CFIndex count = __kCFBitmapSize / sizeof(UInt32); - UInt32 *bitmap = (UInt32*) __CFCSetBitmapBits(theSet); - - if (NULL == bitmap) { - bitmap = (UInt32 *)CFAllocatorAllocate(CFGetAllocator(theSet), __kCFBitmapSize, AUTO_MEMORY_UNSCANNED); - __CFCSetPutBitmapBits(theSet, (uint8_t *)bitmap); - for (idx = 0;idx < count;idx++) bitmap[idx] = 0xFFFFFFFF; - } else { - for (idx = 0;idx < count;idx++) bitmap[idx] = ~(bitmap[idx]); - } - __CFCSetAllocateAnnexForPlane(theSet, 0); // We need to alloc annex to invert - } else if (__CFCSetClassType(theSet) == __kCFCharSetClassCompactBitmap) { - uint8_t *bitmap = __CFCSetCompactBitmapBits(theSet); - int idx; - int length = 0; - uint8_t value; - - for (idx = 0;idx < __kCFCompactBitmapNumPages;idx++) { - value = bitmap[idx]; - - if (value == 0) { - bitmap[idx] = UINT8_MAX; - } else if (value == UINT8_MAX) { - bitmap[idx] = 0; - } else { - length += __kCFCompactBitmapPageSize; - } - } - bitmap += __kCFCompactBitmapNumPages; - for (idx = 0;idx < length;idx++) bitmap[idx] = ~(bitmap[idx]); - __CFCSetAllocateAnnexForPlane(theSet, 0); // We need to alloc annex to invert - } else { - __CFCSetPutIsInverted(theSet, !__CFCSetIsInverted(theSet)); - } - __CFCSetAnnexSetIsInverted(theSet, !__CFCSetAnnexIsInverted(theSet)); -} - -void CFCharacterSetCompact(CFMutableCharacterSetRef theSet) { - if (__CFCSetIsBitmap(theSet) && __CFCSetBitmapBits(theSet)) __CFCSetMakeCompact(theSet); - if (__CFCSetHasNonBMPPlane(theSet)) { - CFMutableCharacterSetRef annex; - int idx; - - for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { - if ((annex = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx)) && __CFCSetIsBitmap(annex) && __CFCSetBitmapBits(annex)) { - __CFCSetMakeCompact(annex); - } - } - } -} - -void CFCharacterSetFast(CFMutableCharacterSetRef theSet) { - if (__CFCSetIsCompactBitmap(theSet) && __CFCSetCompactBitmapBits(theSet)) __CFCSetMakeBitmap(theSet); - if (__CFCSetHasNonBMPPlane(theSet)) { - CFMutableCharacterSetRef annex; - int idx; - - for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) { - if ((annex = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx)) && __CFCSetIsCompactBitmap(annex) && __CFCSetCompactBitmapBits(annex)) { - __CFCSetMakeBitmap(annex); - } - } - } -} - -/* Keyed-coding support -*/ -CFCharacterSetKeyedCodingType _CFCharacterSetGetKeyedCodingType(CFCharacterSetRef cset) { - switch (__CFCSetClassType(cset)) { - case __kCFCharSetClassBuiltin: return ((__CFCSetBuiltinType(cset) < kCFCharacterSetSymbol) ? kCFCharacterSetKeyedCodingTypeBuiltin : kCFCharacterSetKeyedCodingTypeBitmap); - case __kCFCharSetClassRange: return kCFCharacterSetKeyedCodingTypeRange; - - case __kCFCharSetClassString: // We have to check if we have non-BMP here - if (!__CFCSetHasNonBMPPlane(cset)) return kCFCharacterSetKeyedCodingTypeString; // BMP only. we can archive the string - /* fallthrough */ - - default: - return kCFCharacterSetKeyedCodingTypeBitmap; - } -} - -CFCharacterSetPredefinedSet _CFCharacterSetGetKeyedCodingBuiltinType(CFCharacterSetRef cset) { return __CFCSetBuiltinType(cset); } -CFRange _CFCharacterSetGetKeyedCodingRange(CFCharacterSetRef cset) { return CFRangeMake(__CFCSetRangeFirstChar(cset), __CFCSetRangeLength(cset)); } -CFStringRef _CFCharacterSetCreateKeyedCodingString(CFCharacterSetRef cset) { return CFStringCreateWithCharacters(NULL, __CFCSetStringBuffer(cset), __CFCSetStringLength(cset)); } - -bool _CFCharacterSetIsInverted(CFCharacterSetRef cset) { return __CFCSetIsInverted(cset); } -void _CFCharacterSetSetIsInverted(CFCharacterSetRef cset, bool flag) { __CFCSetPutIsInverted((CFMutableCharacterSetRef)cset, flag); } - -