2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 Copyright 1999-2002, Apple, Inc. All rights reserved.
25 Responsibility: Aki Inoue
28 #include <CoreFoundation/CFCharacterSet.h>
29 #include <CoreFoundation/CFByteOrder.h>
30 #include "CFCharacterSetPriv.h"
31 #include <CoreFoundation/CFData.h>
32 #include <CoreFoundation/CFString.h>
33 #include "CFInternal.h"
34 #include "CFUniChar.h"
35 #include "CFUniCharPriv.h"
39 #if !defined(__MACOS8__)
43 #define BITSPERBYTE 8 /* (CHAR_BIT * sizeof(unsigned char)) */
46 #define NUMCHARACTERS 65536
48 #define MAX_ANNEX_PLANE (16)
50 /* Number of things in the array keeping the bits.
52 #define __kCFBitmapSize (NUMCHARACTERS / BITSPERBYTE)
54 /* How many elements max can be in an __kCFCharSetClassString CFCharacterSet
56 #define __kCFStringCharSetMax 64
58 /* The last builtin set ID number
60 #define __kCFLastBuiltinSetID kCFCharacterSetSymbol
62 /* How many elements in the "singles" array before we use binary search.
64 #define __kCFSetBreakeven 10
66 /* 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.
68 #define __CFCSetBitsInRange(n, i) (i[n>>15] & (1L << ((n>>10) % 32)))
70 /* Compact bitmap params
72 #define __kCFCompactBitmapNumPages (256)
74 #define __kCFCompactBitmapMaxPages (128) // the max pages allocated
76 #define __kCFCompactBitmapPageSize (__kCFBitmapSize / __kCFCompactBitmapNumPages)
79 CFCharacterSetRef
*_nonBMPPlanes
;
80 unsigned int _validEntriesBitmap
;
81 unsigned char _numOfAllocEntries
;
82 unsigned char _isAnnexInverted
;
84 } CFCharSetAnnexStruct
;
86 struct __CFCharacterSet
{
88 CFHashCode _hashValue
;
108 CFCharSetAnnexStruct
*_annex
;
111 /* _base._info values interesting for CFCharacterSet
114 __kCFCharSetClassTypeMask
= 0x0070,
115 __kCFCharSetClassBuiltin
= 0x0000,
116 __kCFCharSetClassRange
= 0x0010,
117 __kCFCharSetClassString
= 0x0020,
118 __kCFCharSetClassBitmap
= 0x0030,
119 __kCFCharSetClassSet
= 0x0040,
120 __kCFCharSetClassCompactBitmap
= 0x0040,
122 __kCFCharSetIsInvertedMask
= 0x0008,
123 __kCFCharSetIsInverted
= 0x0008,
125 __kCFCharSetHasHashValueMask
= 0x00004,
126 __kCFCharSetHasHashValue
= 0x0004,
128 /* Generic CFBase values */
129 __kCFCharSetIsMutableMask
= 0x0001,
130 __kCFCharSetIsMutable
= 0x0001,
133 /* Inline accessor macros for _base._info
135 CF_INLINE Boolean
__CFCSetIsMutable(CFCharacterSetRef cset
) {return (cset
->_base
._info
& __kCFCharSetIsMutableMask
) == __kCFCharSetIsMutable
;}
136 CF_INLINE Boolean
__CFCSetIsBuiltin(CFCharacterSetRef cset
) {return (cset
->_base
._info
& __kCFCharSetClassTypeMask
) == __kCFCharSetClassBuiltin
;}
137 CF_INLINE Boolean
__CFCSetIsRange(CFCharacterSetRef cset
) {return (cset
->_base
._info
& __kCFCharSetClassTypeMask
) == __kCFCharSetClassRange
;}
138 CF_INLINE Boolean
__CFCSetIsString(CFCharacterSetRef cset
) {return (cset
->_base
._info
& __kCFCharSetClassTypeMask
) == __kCFCharSetClassString
;}
139 CF_INLINE Boolean
__CFCSetIsBitmap(CFCharacterSetRef cset
) {return (cset
->_base
._info
& __kCFCharSetClassTypeMask
) == __kCFCharSetClassBitmap
;}
140 CF_INLINE Boolean
__CFCSetIsCompactBitmap(CFCharacterSetRef cset
) {return (cset
->_base
._info
& __kCFCharSetClassTypeMask
) == __kCFCharSetClassCompactBitmap
;}
141 CF_INLINE Boolean
__CFCSetIsInverted(CFCharacterSetRef cset
) {return (cset
->_base
._info
& __kCFCharSetIsInvertedMask
) == __kCFCharSetIsInverted
;}
142 CF_INLINE Boolean
__CFCSetHasHashValue(CFCharacterSetRef cset
) {return (cset
->_base
._info
& __kCFCharSetHasHashValueMask
) == __kCFCharSetHasHashValue
;}
143 CF_INLINE UInt32
__CFCSetClassType(CFCharacterSetRef cset
) {return (cset
->_base
._info
& __kCFCharSetClassTypeMask
);}
145 CF_INLINE
void __CFCSetPutIsMutable(CFMutableCharacterSetRef cset
, Boolean isMutable
) {(isMutable
? (cset
->_base
._info
|= __kCFCharSetIsMutable
) : (cset
->_base
._info
&= ~ __kCFCharSetIsMutable
));}
146 CF_INLINE
void __CFCSetPutIsInverted(CFMutableCharacterSetRef cset
, Boolean isInverted
) {(isInverted
? (cset
->_base
._info
|= __kCFCharSetIsInverted
) : (cset
->_base
._info
&= ~__kCFCharSetIsInverted
));}
147 CF_INLINE
void __CFCSetPutHasHashValue(CFMutableCharacterSetRef cset
, Boolean hasHash
) {(hasHash
? (cset
->_base
._info
|= __kCFCharSetHasHashValue
) : (cset
->_base
._info
&= ~__kCFCharSetHasHashValue
));}
148 CF_INLINE
void __CFCSetPutClassType(CFMutableCharacterSetRef cset
, UInt32 classType
) {cset
->_base
._info
&= ~__kCFCharSetClassTypeMask
; cset
->_base
._info
|= classType
;}
151 /* Inline contents accessor macros
153 CF_INLINE CFCharacterSetPredefinedSet
__CFCSetBuiltinType(CFCharacterSetRef cset
) {return cset
->_variants
._builtin
._type
;}
154 CF_INLINE UInt32
__CFCSetRangeFirstChar(CFCharacterSetRef cset
) {return cset
->_variants
._range
._firstChar
;}
155 CF_INLINE CFIndex
__CFCSetRangeLength(CFCharacterSetRef cset
) {return cset
->_variants
._range
._length
;}
156 CF_INLINE UniChar
*__CFCSetStringBuffer(CFCharacterSetRef cset
) {return (UniChar
*)(cset
->_variants
._string
._buffer
);}
157 CF_INLINE CFIndex
__CFCSetStringLength(CFCharacterSetRef cset
) {return cset
->_variants
._string
._length
;}
158 CF_INLINE
uint8_t *__CFCSetBitmapBits(CFCharacterSetRef cset
) {return cset
->_variants
._bitmap
._bits
;}
159 CF_INLINE
uint8_t *__CFCSetCompactBitmapBits(CFCharacterSetRef cset
) {return cset
->_variants
._compactBitmap
._cBits
;}
161 CF_INLINE
void __CFCSetPutBuiltinType(CFMutableCharacterSetRef cset
, CFCharacterSetPredefinedSet type
) {cset
->_variants
._builtin
._type
= type
;}
162 CF_INLINE
void __CFCSetPutRangeFirstChar(CFMutableCharacterSetRef cset
, UInt32 first
) {cset
->_variants
._range
._firstChar
= first
;}
163 CF_INLINE
void __CFCSetPutRangeLength(CFMutableCharacterSetRef cset
, CFIndex length
) {cset
->_variants
._range
._length
= length
;}
164 CF_INLINE
void __CFCSetPutStringBuffer(CFMutableCharacterSetRef cset
, UniChar
*theBuffer
) {cset
->_variants
._string
._buffer
= theBuffer
;}
165 CF_INLINE
void __CFCSetPutStringLength(CFMutableCharacterSetRef cset
, CFIndex length
) {cset
->_variants
._string
._length
= length
;}
166 CF_INLINE
void __CFCSetPutBitmapBits(CFMutableCharacterSetRef cset
, uint8_t *bits
) {cset
->_variants
._bitmap
._bits
= bits
;}
167 CF_INLINE
void __CFCSetPutCompactBitmapBits(CFMutableCharacterSetRef cset
, uint8_t *bits
) {cset
->_variants
._compactBitmap
._cBits
= bits
;}
171 #if defined(CF_ENABLE_ASSERTIONS)
172 CF_INLINE
void __CFCSetValidateBuiltinType(CFCharacterSetPredefinedSet type
, const char *func
) {
173 CFAssert2(type
> 0 && type
<= __kCFLastBuiltinSetID
, __kCFLogAssertion
, "%s: Unknowen builtin type %d", func
, type
);
175 CF_INLINE
void __CFCSetValidateRange(CFRange theRange
, const char *func
) {
176 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
);
178 CF_INLINE
void __CFCSetValidateTypeAndMutability(CFCharacterSetRef cset
, const char *func
) {
179 __CFGenericValidateType(cset
, __kCFCharacterSetTypeID
);
180 CFAssert1(__CFCSetIsMutable(cset
), __kCFLogAssertion
, "%s: Immutable character set passed to mutable function", func
);
183 #define __CFCSetValidateBuiltinType(t,f)
184 #define __CFCSetValidateRange(r,f)
185 #define __CFCSetValidateTypeAndMutability(r,f)
188 /* Inline utility funcs
190 static Boolean
__CFCSetIsEqualBitmap(const UInt32
*bits1
, const UInt32
*bits2
) {
191 CFIndex length
= __kCFBitmapSize
/ sizeof(UInt32
);
193 if (bits1
== bits2
) {
195 } else if (bits1
&& bits2
) {
196 if (bits1
== (const UInt32
*)-1) {
197 while (length
--) if ((UInt32
)-1 != *bits2
++) return false;
198 } else if (bits2
== (const UInt32
*)-1) {
199 while (length
--) if ((UInt32
)-1 != *bits1
++) return false;
201 while (length
--) if (*bits1
++ != *bits2
++) return false;
204 } else if (!bits1
&& !bits2
) { // empty set
207 if (bits2
) bits1
= bits2
;
208 if (bits1
== (const UInt32
*)-1) return false;
209 while (length
--) if (*bits1
++) return false;
214 CF_INLINE Boolean
__CFCSetIsEqualBitmapInverted(const UInt32
*bits1
, const UInt32
*bits2
) {
215 CFIndex length
= __kCFBitmapSize
/ sizeof(UInt32
);
217 while (length
--) if (*bits1
++ != ~(*(bits2
++))) return false;
221 static Boolean
__CFCSetIsBitmapEqualToRange(const UInt32
*bits
, UniChar firstChar
, UniChar lastChar
, Boolean isInverted
) {
222 CFIndex firstCharIndex
= firstChar
>> LOG_BPB
;
223 CFIndex lastCharIndex
= lastChar
>> LOG_BPB
;
227 if (firstCharIndex
== lastCharIndex
) {
228 value
= ((((UInt32
)0xFF) << (firstChar
& (BITSPERBYTE
- 1))) & (((UInt32
)0xFF) >> ((BITSPERBYTE
- 1) - (lastChar
& (BITSPERBYTE
- 1))))) << (((sizeof(UInt32
) - 1) - (firstCharIndex
% sizeof(UInt32
))) * BITSPERBYTE
);
229 value
= CFSwapInt32HostToBig(value
);
230 firstCharIndex
= lastCharIndex
= firstChar
>> LOG_BPLW
;
231 if (*(bits
+ firstCharIndex
) != (isInverted
? ~value
: value
)) return FALSE
;
233 UInt32 firstCharMask
;
236 length
= firstCharIndex
% sizeof(UInt32
);
237 firstCharMask
= (((((UInt32
)0xFF) << (firstChar
& (BITSPERBYTE
- 1))) & 0xFF) << (((sizeof(UInt32
) - 1) - length
) * BITSPERBYTE
)) | (0xFFFFFFFF >> ((length
+ 1) * BITSPERBYTE
));
239 length
= lastCharIndex
% sizeof(UInt32
);
240 lastCharMask
= ((((UInt32
)0xFF) >> ((BITSPERBYTE
- 1) - (lastChar
& (BITSPERBYTE
- 1)))) << (((sizeof(UInt32
) - 1) - length
) * BITSPERBYTE
)) | (0xFFFFFFFF << ((sizeof(UInt32
) - length
) * BITSPERBYTE
));
242 firstCharIndex
= firstChar
>> LOG_BPLW
;
243 lastCharIndex
= lastChar
>> LOG_BPLW
;
245 if (firstCharIndex
== lastCharIndex
) {
246 firstCharMask
&= lastCharMask
;
247 value
= CFSwapInt32HostToBig(firstCharMask
& lastCharMask
);
248 if (*(bits
+ firstCharIndex
) != (isInverted
? ~value
: value
)) return FALSE
;
250 value
= CFSwapInt32HostToBig(firstCharMask
);
251 if (*(bits
+ firstCharIndex
) != (isInverted
? ~value
: value
)) return FALSE
;
253 value
= CFSwapInt32HostToBig(lastCharMask
);
254 if (*(bits
+ lastCharIndex
) != (isInverted
? ~value
: value
)) return FALSE
;
258 length
= firstCharIndex
;
259 value
= (isInverted
? 0xFFFFFFFF : 0);
261 if (*(bits
++) != value
) return FALSE
;
264 ++bits
; // Skip firstCharIndex
265 length
= (lastCharIndex
- (firstCharIndex
+ 1));
266 value
= (isInverted
? 0 : 0xFFFFFFFF);
267 while (length
-- > 0) {
268 if (*(bits
++) != value
) return FALSE
;
270 if (firstCharIndex
!= lastCharIndex
) ++bits
;
272 length
= (0xFFFF >> LOG_BPLW
) - lastCharIndex
;
273 value
= (isInverted
? 0xFFFFFFFF : 0);
275 if (*(bits
++) != value
) return FALSE
;
281 CF_INLINE Boolean
__CFCSetIsBitmapSupersetOfBitmap(const UInt32
*bits1
, const UInt32
*bits2
, Boolean isInverted1
, Boolean isInverted2
) {
282 CFIndex length
= __kCFBitmapSize
/ sizeof(UInt32
);
286 val2
= (isInverted2
? ~(*(bits2
++)) : *(bits2
++));
287 val1
= (isInverted1
? ~(*(bits1
++)) : *(bits1
++)) & val2
;
288 if (val1
!= val2
) return false;
294 CF_INLINE Boolean
__CFCSetHasNonBMPPlane(CFCharacterSetRef cset
) { return ((cset
)->_annex
&& (cset
)->_annex
->_validEntriesBitmap
? true : false); }
295 CF_INLINE Boolean
__CFCSetAnnexIsInverted (CFCharacterSetRef cset
) { return ((cset
)->_annex
&& (cset
)->_annex
->_isAnnexInverted
? true : false); }
296 CF_INLINE UInt32
__CFCSetAnnexValidEntriesBitmap(CFCharacterSetRef cset
) { return ((cset
)->_annex
&& (cset
)->_annex
->_validEntriesBitmap
? (cset
)->_annex
->_validEntriesBitmap
: 0); }
298 CF_INLINE Boolean
__CFCSetIsEmpty(CFCharacterSetRef cset
) {
299 if (__CFCSetHasNonBMPPlane(cset
) || __CFCSetAnnexIsInverted(cset
)) return false;
301 switch (__CFCSetClassType(cset
)) {
302 case __kCFCharSetClassRange
: if (!__CFCSetRangeLength(cset
)) return true; break;
303 case __kCFCharSetClassString
: if (!__CFCSetStringLength(cset
)) return true; break;
304 case __kCFCharSetClassBitmap
: if (!__CFCSetBitmapBits(cset
)) return true; break;
305 case __kCFCharSetClassCompactBitmap
: if (!__CFCSetCompactBitmapBits(cset
)) return true; break;
310 CF_INLINE
void __CFCSetBitmapAddCharacter(uint8_t *bitmap
, UniChar theChar
) {
311 bitmap
[(theChar
) >> LOG_BPB
] |= (((unsigned)1) << (theChar
& (BITSPERBYTE
- 1)));
314 CF_INLINE
void __CFCSetBitmapRemoveCharacter(uint8_t *bitmap
, UniChar theChar
) {
315 bitmap
[(theChar
) >> LOG_BPB
] &= ~(((unsigned)1) << (theChar
& (BITSPERBYTE
- 1)));
318 CF_INLINE Boolean
__CFCSetIsMemberBitmap(const uint8_t *bitmap
, UniChar theChar
) {
319 return ((bitmap
[(theChar
) >> LOG_BPB
] & (((unsigned)1) << (theChar
& (BITSPERBYTE
- 1)))) ? true : false);
322 #define NUM_32BIT_SLOTS (NUMCHARACTERS / 32)
324 CF_INLINE
void __CFCSetBitmapFastFillWithValue(UInt32
*bitmap
, uint8_t value
) {
325 UInt32 mask
= (value
<< 24) | (value
<< 16) | (value
<< 8) | value
;
326 UInt32 numSlots
= NUMCHARACTERS
/ 32;
328 while (numSlots
--) *(bitmap
++) = mask
;
331 CF_INLINE
void __CFCSetBitmapAddCharactersInRange(uint8_t *bitmap
, UniChar firstChar
, UniChar lastChar
) {
332 if (firstChar
== lastChar
) {
333 bitmap
[firstChar
>> LOG_BPB
] |= (((unsigned)1) << (firstChar
& (BITSPERBYTE
- 1)));
335 UInt32 idx
= firstChar
>> LOG_BPB
;
336 UInt32 max
= lastChar
>> LOG_BPB
;
339 bitmap
[idx
] |= (((unsigned)0xFF) << (firstChar
& (BITSPERBYTE
- 1))) & (((unsigned)0xFF) >> ((BITSPERBYTE
- 1) - (lastChar
& (BITSPERBYTE
- 1))));
341 bitmap
[idx
] |= (((unsigned)0xFF) << (firstChar
& (BITSPERBYTE
- 1)));
342 bitmap
[max
] |= (((unsigned)0xFF) >> ((BITSPERBYTE
- 1) - (lastChar
& (BITSPERBYTE
- 1))));
345 while (idx
< max
) bitmap
[idx
++] = 0xFF;
350 CF_INLINE
void __CFCSetBitmapRemoveCharactersInRange(uint8_t *bitmap
, UniChar firstChar
, UniChar lastChar
) {
351 UInt32 idx
= firstChar
>> LOG_BPB
;
352 UInt32 max
= lastChar
>> LOG_BPB
;
355 bitmap
[idx
] &= ~((((unsigned)0xFF) << (firstChar
& (BITSPERBYTE
- 1))) & (((unsigned)0xFF) >> ((BITSPERBYTE
- 1) - (lastChar
& (BITSPERBYTE
- 1)))));
357 bitmap
[idx
] &= ~(((unsigned)0xFF) << (firstChar
& (BITSPERBYTE
- 1)));
358 bitmap
[max
] &= ~(((unsigned)0xFF) >> ((BITSPERBYTE
- 1) - (lastChar
& (BITSPERBYTE
- 1))));
361 while (idx
< max
) bitmap
[idx
++] = 0;
365 #define __CFCSetAnnexBitmapSetPlane(bitmap,plane) ((bitmap) |= (1 << (plane)))
366 #define __CFCSetAnnexBitmapClearPlane(bitmap,plane) ((bitmap) &= (~(1 << (plane))))
367 #define __CFCSetAnnexBitmapGetPlane(bitmap,plane) ((bitmap) & (1 << (plane)))
369 CF_INLINE
void __CFCSetAnnexSetIsInverted(CFCharacterSetRef cset
, Boolean flag
) {
370 if (cset
->_annex
) ((CFMutableCharacterSetRef
)cset
)->_annex
->_isAnnexInverted
= flag
;
373 CF_INLINE
void __CFCSetAllocateAnnexForPlane(CFCharacterSetRef cset
, int plane
) {
374 if (cset
->_annex
== NULL
) {
375 ((CFMutableCharacterSetRef
)cset
)->_annex
= (CFCharSetAnnexStruct
*)CFAllocatorAllocate(CFGetAllocator(cset
), sizeof(CFCharSetAnnexStruct
), 0);
376 cset
->_annex
->_numOfAllocEntries
= plane
;
377 cset
->_annex
->_isAnnexInverted
= false;
378 cset
->_annex
->_validEntriesBitmap
= 0;
379 cset
->_annex
->_nonBMPPlanes
= (CFCharacterSetRef
*)CFAllocatorAllocate(CFGetAllocator(cset
), sizeof(CFCharacterSetRef
) * plane
, 0);
380 } else if (cset
->_annex
->_numOfAllocEntries
< plane
) {
381 cset
->_annex
->_numOfAllocEntries
= plane
;
382 cset
->_annex
->_nonBMPPlanes
= (CFCharacterSetRef
*)CFAllocatorReallocate(CFGetAllocator(cset
), (void *)cset
->_annex
->_nonBMPPlanes
, sizeof(CFCharacterSetRef
) * plane
, 0);
386 CF_INLINE
void __CFCSetPutCharacterSetToAnnexPlane(CFCharacterSetRef cset
, CFCharacterSetRef annexCSet
, int plane
) {
387 __CFCSetAllocateAnnexForPlane(cset
, plane
);
388 if (__CFCSetAnnexBitmapGetPlane(cset
->_annex
->_validEntriesBitmap
, plane
)) CFRelease(cset
->_annex
->_nonBMPPlanes
[plane
- 1]);
390 cset
->_annex
->_nonBMPPlanes
[plane
- 1] = CFRetain(annexCSet
);
391 __CFCSetAnnexBitmapSetPlane(cset
->_annex
->_validEntriesBitmap
, plane
);
393 __CFCSetAnnexBitmapClearPlane(cset
->_annex
->_validEntriesBitmap
, plane
);
397 CF_INLINE CFCharacterSetRef
__CFCSetGetAnnexPlaneCharacterSet(CFCharacterSetRef cset
, int plane
) {
398 __CFCSetAllocateAnnexForPlane(cset
, plane
);
399 if (!__CFCSetAnnexBitmapGetPlane(cset
->_annex
->_validEntriesBitmap
, plane
)) {
400 cset
->_annex
->_nonBMPPlanes
[plane
- 1] = (CFCharacterSetRef
)CFCharacterSetCreateMutable(CFGetAllocator(cset
));
401 __CFCSetAnnexBitmapSetPlane(cset
->_annex
->_validEntriesBitmap
, plane
);
403 return cset
->_annex
->_nonBMPPlanes
[plane
- 1];
406 CF_INLINE CFCharacterSetRef
__CFCSetGetAnnexPlaneCharacterSetNoAlloc(CFCharacterSetRef cset
, int plane
) {
407 return (cset
->_annex
&& __CFCSetAnnexBitmapGetPlane(cset
->_annex
->_validEntriesBitmap
, plane
) ? cset
->_annex
->_nonBMPPlanes
[plane
- 1] : NULL
);
410 CF_INLINE
void __CFCSetDeallocateAnnexPlane(CFCharacterSetRef cset
) {
414 for (idx
= 0;idx
< MAX_ANNEX_PLANE
;idx
++) {
415 if (__CFCSetAnnexBitmapGetPlane(cset
->_annex
->_validEntriesBitmap
, idx
+ 1)) {
416 CFRelease(cset
->_annex
->_nonBMPPlanes
[idx
]);
419 CFAllocatorDeallocate(CFGetAllocator(cset
), cset
->_annex
->_nonBMPPlanes
);
420 CFAllocatorDeallocate(CFGetAllocator(cset
), cset
->_annex
);
421 ((CFMutableCharacterSetRef
)cset
)->_annex
= NULL
;
425 CF_INLINE
uint8_t __CFCSetGetHeaderValue(const uint8_t *bitmap
, int *numPages
) {
426 uint8_t value
= *bitmap
;
428 if ((value
== 0) || (value
== UINT8_MAX
)) {
429 int numBytes
= __kCFCompactBitmapPageSize
- 1;
431 while (numBytes
> 0) {
432 if (*(++bitmap
) != value
) break;
435 if (numBytes
== 0) return value
;
437 return (uint8_t)(++(*numPages
));
440 CF_INLINE
bool __CFCSetIsMemberInCompactBitmap(const uint8_t *compactBitmap
, UTF16Char character
) {
441 uint8_t value
= compactBitmap
[(character
>> 8)]; // Assuming __kCFCompactBitmapNumPages == 256
445 } else if (value
== UINT8_MAX
) {
448 compactBitmap
+= (__kCFCompactBitmapNumPages
+ (__kCFCompactBitmapPageSize
* (value
- 1)));
449 character
&= 0xFF; // Assuming __kCFCompactBitmapNumPages == 256
450 return ((compactBitmap
[(character
/ BITSPERBYTE
)] & (1 << (character
% BITSPERBYTE
))) ? true : false);
454 CF_INLINE
uint32_t __CFCSetGetCompactBitmapSize(const uint8_t *compactBitmap
) {
455 uint32_t length
= __kCFCompactBitmapNumPages
;
456 uint32_t size
= __kCFCompactBitmapNumPages
;
459 while (length
-- > 0) {
460 value
= *(compactBitmap
++);
461 if ((value
!= 0) && (value
!= UINT8_MAX
)) size
+= __kCFCompactBitmapPageSize
;
466 /* Take a private "set" structure and make a bitmap from it. Return the bitmap. THE CALLER MUST RELEASE THE RETURNED MEMORY as necessary.
469 CF_INLINE
void __CFCSetBitmapProcessManyCharacters(unsigned char *map
, unsigned n
, unsigned m
, Boolean isInverted
) {
471 __CFCSetBitmapRemoveCharactersInRange(map
, n
, m
);
473 __CFCSetBitmapAddCharactersInRange(map
, n
, m
);
477 CF_INLINE
void __CFExpandCompactBitmap(const uint8_t *src
, uint8_t *dst
) {
478 const uint8_t *srcBody
= src
+ __kCFCompactBitmapNumPages
;
482 for (i
= 0;i
< __kCFCompactBitmapNumPages
;i
++) {
484 if ((value
== 0) || (value
== UINT8_MAX
)) {
485 memset(dst
, value
, __kCFCompactBitmapPageSize
);
487 memmove(dst
, srcBody
, __kCFCompactBitmapPageSize
);
488 srcBody
+= __kCFCompactBitmapPageSize
;
490 dst
+= __kCFCompactBitmapPageSize
;
495 static void __CFCheckForExpandedSet(CFCharacterSetRef cset
) {
496 static int8_t __CFNumberOfPlanesForLogging
= -1;
497 static bool warnedOnce
= false;
499 if (0 > __CFNumberOfPlanesForLogging
) {
500 const char *envVar
= getenv("CFCharacterSetCheckForExpandedSet");
501 long value
= (envVar
? strtol(envVar
, NULL
, 0) : 0);
502 __CFNumberOfPlanesForLogging
= (((value
> 0) && (value
<= 16)) ? value
: 0);
505 if (__CFNumberOfPlanesForLogging
) {
506 uint32_t entries
= __CFCSetAnnexValidEntriesBitmap(cset
);
510 if ((entries
& 1) && (++count
>= __CFNumberOfPlanesForLogging
)) {
512 CFLog(0, CFSTR("An expanded CFMutableCharacter has been detected. Recommend to compact with CFCharacterSetCreateCopy"));
522 static void __CFCSetGetBitmap(CFCharacterSetRef cset
, uint8_t *bits
) {
524 CFIndex length
= __kCFBitmapSize
;
526 if (__CFCSetIsBitmap(cset
) && (bitmap
= __CFCSetBitmapBits(cset
))) {
527 memmove(bits
, bitmap
, __kCFBitmapSize
);
529 Boolean isInverted
= __CFCSetIsInverted(cset
);
530 uint8_t value
= (isInverted
? (uint8_t)-1 : 0);
533 while (length
--) *bitmap
++ = value
; // Initialize the buffer
535 if (!__CFCSetIsEmpty(cset
)) {
536 switch (__CFCSetClassType(cset
)) {
537 case __kCFCharSetClassBuiltin
: {
538 UInt8 result
= CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(cset
), 0, bits
, isInverted
);
539 if (result
== kCFUniCharBitmapEmpty
&& isInverted
) {
540 length
= __kCFBitmapSize
;
542 while (length
--) *bitmap
++ = 0;
543 } else if (result
== kCFUniCharBitmapAll
&& !isInverted
) {
544 length
= __kCFBitmapSize
;
546 while (length
--) *bitmap
++ = (UInt8
)0xFF;
551 case __kCFCharSetClassRange
: {
552 UInt32 theChar
= __CFCSetRangeFirstChar(cset
);
553 if (theChar
< NUMCHARACTERS
) { // the range starts in BMP
554 length
= __CFCSetRangeLength(cset
);
555 if (theChar
+ length
>= NUMCHARACTERS
) length
= NUMCHARACTERS
- theChar
;
557 __CFCSetBitmapRemoveCharactersInRange(bits
, theChar
, (theChar
+ length
) - 1);
559 __CFCSetBitmapAddCharactersInRange(bits
, theChar
, (theChar
+ length
) - 1);
565 case __kCFCharSetClassString
: {
566 const UniChar
*buffer
= __CFCSetStringBuffer(cset
);
567 length
= __CFCSetStringLength(cset
);
568 while (length
--) (isInverted
? __CFCSetBitmapRemoveCharacter(bits
, *buffer
++) : __CFCSetBitmapAddCharacter(bits
, *buffer
++));
572 case __kCFCharSetClassCompactBitmap
:
573 __CFExpandCompactBitmap(__CFCSetCompactBitmapBits(cset
), bits
);
580 static Boolean
__CFCharacterSetEqual(CFTypeRef cf1
, CFTypeRef cf2
);
582 static Boolean
__CFCSetIsEqualAnnex(CFCharacterSetRef cf1
, CFCharacterSetRef cf2
) {
583 CFCharacterSetRef subSet1
;
584 CFCharacterSetRef subSet2
;
585 Boolean isAnnexInvertStateIdentical
= (__CFCSetAnnexIsInverted(cf1
) == __CFCSetAnnexIsInverted(cf2
) ? true: false);
588 if (isAnnexInvertStateIdentical
) {
589 if (__CFCSetAnnexValidEntriesBitmap(cf1
) != __CFCSetAnnexValidEntriesBitmap(cf2
)) return false;
590 for (idx
= 1;idx
<= MAX_ANNEX_PLANE
;idx
++) {
591 subSet1
= __CFCSetGetAnnexPlaneCharacterSetNoAlloc(cf1
, idx
);
592 subSet2
= __CFCSetGetAnnexPlaneCharacterSetNoAlloc(cf2
, idx
);
594 if (subSet1
&& !__CFCharacterSetEqual(subSet1
, subSet2
)) return false;
597 uint8_t bitsBuf
[__kCFBitmapSize
];
599 uint8_t *bitsBuf2
= NULL
;
601 uint8_t bitsBuf2
[__kCFBitmapSize
];
604 for (idx
= 1;idx
<= MAX_ANNEX_PLANE
;idx
++) {
605 subSet1
= __CFCSetGetAnnexPlaneCharacterSetNoAlloc(cf1
, idx
);
606 subSet2
= __CFCSetGetAnnexPlaneCharacterSetNoAlloc(cf2
, idx
);
608 if (subSet1
== NULL
&& subSet2
== NULL
) {
610 if (bitsBuf2
) CFAllocatorDeallocate(NULL
, bitsBuf2
);
613 } else if (subSet1
== NULL
) {
614 if (__CFCSetIsBitmap(subSet2
)) {
615 if (!__CFCSetIsEqualBitmap((const UInt32
*)__CFCSetBitmapBits(subSet2
), (const UInt32
*)-1)) {
617 if (bitsBuf2
) CFAllocatorDeallocate(NULL
, bitsBuf2
);
622 __CFCSetGetBitmap(subSet2
, bitsBuf
);
623 if (!__CFCSetIsEqualBitmap((const UInt32
*)bitsBuf
, (const UInt32
*)-1)) {
625 if (bitsBuf2
) CFAllocatorDeallocate(NULL
, bitsBuf2
);
630 } else if (subSet2
== NULL
) {
631 if (__CFCSetIsBitmap(subSet1
)) {
632 if (!__CFCSetIsEqualBitmap((const UInt32
*)__CFCSetBitmapBits(subSet1
), (const UInt32
*)-1)) {
634 if (bitsBuf2
) CFAllocatorDeallocate(NULL
, bitsBuf2
);
639 __CFCSetGetBitmap(subSet1
, bitsBuf
);
640 if (!__CFCSetIsEqualBitmap((const UInt32
*)bitsBuf
, (const UInt32
*)-1)) {
642 if (bitsBuf2
) CFAllocatorDeallocate(NULL
, bitsBuf2
);
648 Boolean isBitmap1
= __CFCSetIsBitmap(subSet1
);
649 Boolean isBitmap2
= __CFCSetIsBitmap(subSet2
);
651 if (isBitmap1
&& isBitmap2
) {
652 if (!__CFCSetIsEqualBitmapInverted((const UInt32
*)__CFCSetBitmapBits(subSet1
), (const UInt32
*)__CFCSetBitmapBits(subSet2
))) {
654 if (bitsBuf2
) CFAllocatorDeallocate(NULL
, bitsBuf2
);
658 } else if (!isBitmap1
&& !isBitmap2
) {
659 __CFCSetGetBitmap(subSet1
, bitsBuf
);
661 if (bitsBuf2
== NULL
) bitsBuf2
= (UInt32
*)CFAllocatorAllocate(NULL
, __kCFBitmapSize
, 0);
663 __CFCSetGetBitmap(subSet2
, bitsBuf2
);
664 if (!__CFCSetIsEqualBitmapInverted((const UInt32
*)bitsBuf
, (const UInt32
*)bitsBuf2
)) {
666 CFAllocatorDeallocate(NULL
, bitsBuf2
);
672 CFCharacterSetRef tmp
= subSet2
;
676 __CFCSetGetBitmap(subSet2
, bitsBuf
);
677 if (!__CFCSetIsEqualBitmapInverted((const UInt32
*)__CFCSetBitmapBits(subSet1
), (const UInt32
*)bitsBuf
)) {
679 if (bitsBuf2
) CFAllocatorDeallocate(NULL
, bitsBuf2
);
692 static uint8_t *__CFCreateCompactBitmap(CFAllocatorRef allocator
, const uint8_t *bitmap
) {
697 uint8_t header
[__kCFCompactBitmapNumPages
];
700 for (i
= 0;i
< __kCFCompactBitmapNumPages
;i
++) {
701 header
[i
] = __CFCSetGetHeaderValue(src
, &numPages
);
703 // Allocating more pages is probably not interesting enough to be compact
704 if (numPages
> __kCFCompactBitmapMaxPages
) return NULL
;
705 src
+= __kCFCompactBitmapPageSize
;
708 dst
= (uint8_t *)CFAllocatorAllocate(allocator
, __kCFCompactBitmapNumPages
+ (__kCFCompactBitmapPageSize
* numPages
), AUTO_MEMORY_UNSCANNED
);
711 uint8_t *dstBody
= dst
+ __kCFCompactBitmapNumPages
;
714 for (i
= 0;i
< __kCFCompactBitmapNumPages
;i
++) {
717 if ((dst
[i
] != 0) && (dst
[i
] != UINT8_MAX
)) {
718 memmove(dstBody
, src
, __kCFCompactBitmapPageSize
);
719 dstBody
+= __kCFCompactBitmapPageSize
;
721 src
+= __kCFCompactBitmapPageSize
;
724 memmove(dst
, header
, __kCFCompactBitmapNumPages
);
730 static void __CFCSetMakeCompact(CFMutableCharacterSetRef cset
) {
731 if (__CFCSetIsBitmap(cset
) && __CFCSetBitmapBits(cset
)) {
732 uint8_t *bitmap
= __CFCSetBitmapBits(cset
);
733 uint8_t *cBitmap
= __CFCreateCompactBitmap(CFGetAllocator(cset
), bitmap
);
736 CFAllocatorDeallocate(CFGetAllocator(cset
), bitmap
);
737 __CFCSetPutClassType(cset
, __kCFCharSetClassCompactBitmap
);
738 __CFCSetPutCompactBitmapBits(cset
, cBitmap
);
743 static void __CFCSetAddNonBMPPlanesInRange(CFMutableCharacterSetRef cset
, CFRange range
) {
744 int firstChar
= (range
.location
& 0xFFFF);
745 int maxChar
= range
.location
+ range
.length
;
746 int idx
= range
.location
>> 16; // first plane
747 int maxPlane
= (maxChar
- 1) >> 16; // last plane
749 CFMutableCharacterSetRef annexPlane
;
753 for (idx
= (idx
? idx
: 1);idx
<= maxPlane
;idx
++) {
754 planeRange
.location
= __CFMax(firstChar
, 0);
755 planeRange
.length
= (idx
== maxPlane
&& maxChar
? maxChar
: 0x10000) - planeRange
.location
;
756 if (__CFCSetAnnexIsInverted(cset
)) {
757 if ((annexPlane
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(cset
, idx
))) {
758 CFCharacterSetRemoveCharactersInRange(annexPlane
, planeRange
);
759 if (__CFCSetIsEmpty(annexPlane
) && !__CFCSetIsInverted(annexPlane
)) {
760 CFRelease(annexPlane
);
761 __CFCSetAnnexBitmapClearPlane(cset
->_annex
->_validEntriesBitmap
, idx
);
765 CFCharacterSetAddCharactersInRange((CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSet(cset
, idx
), planeRange
);
768 if (!__CFCSetHasNonBMPPlane(cset
) && !__CFCSetAnnexIsInverted(cset
)) __CFCSetDeallocateAnnexPlane(cset
);
771 static void __CFCSetRemoveNonBMPPlanesInRange(CFMutableCharacterSetRef cset
, CFRange range
) {
772 int firstChar
= (range
.location
& 0xFFFF);
773 int maxChar
= range
.location
+ range
.length
;
774 int idx
= range
.location
>> 16; // first plane
775 int maxPlane
= (maxChar
- 1) >> 16; // last plane
777 CFMutableCharacterSetRef annexPlane
;
781 for (idx
= (idx
? idx
: 1);idx
<= maxPlane
;idx
++) {
782 planeRange
.location
= __CFMax(firstChar
, 0);
783 planeRange
.length
= (idx
== maxPlane
&& maxChar
? maxChar
: 0x10000) - planeRange
.location
;
784 if (__CFCSetAnnexIsInverted(cset
)) {
785 CFCharacterSetAddCharactersInRange((CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSet(cset
, idx
), planeRange
);
787 if ((annexPlane
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(cset
, idx
))) {
788 CFCharacterSetRemoveCharactersInRange(annexPlane
, planeRange
);
789 if(__CFCSetIsEmpty(annexPlane
) && !__CFCSetIsInverted(annexPlane
)) {
790 CFRelease(annexPlane
);
791 __CFCSetAnnexBitmapClearPlane(cset
->_annex
->_validEntriesBitmap
, idx
);
796 if (!__CFCSetHasNonBMPPlane(cset
) && !__CFCSetAnnexIsInverted(cset
)) __CFCSetDeallocateAnnexPlane(cset
);
799 static void __CFCSetMakeBitmap(CFMutableCharacterSetRef cset
) {
800 if (!__CFCSetIsBitmap(cset
) || !__CFCSetBitmapBits(cset
)) {
801 CFAllocatorRef allocator
= CFGetAllocator(cset
);
802 uint8_t *bitmap
= CFAllocatorAllocate(allocator
, __kCFBitmapSize
, AUTO_MEMORY_UNSCANNED
);
803 __CFCSetGetBitmap(cset
, bitmap
);
805 if (__CFCSetIsBuiltin(cset
)) {
806 CFIndex numPlanes
= CFUniCharGetNumberOfPlanes(__CFCSetBuiltinType(cset
));
809 CFMutableCharacterSetRef annexSet
;
810 uint8_t *annexBitmap
= NULL
;
814 __CFCSetAllocateAnnexForPlane(cset
, numPlanes
- 1);
815 for (idx
= 1;idx
< numPlanes
;idx
++) {
816 if (NULL
== annexBitmap
) {
817 annexBitmap
= CFAllocatorAllocate(allocator
, __kCFBitmapSize
, AUTO_MEMORY_UNSCANNED
);
819 result
= CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(cset
), idx
, annexBitmap
, false);
820 if (result
== kCFUniCharBitmapEmpty
) continue;
821 if (result
== kCFUniCharBitmapAll
) {
822 CFIndex bitmapLength
= __kCFBitmapSize
;
823 uint8_t *bytes
= annexBitmap
;
824 while (bitmapLength
-- > 0) *(bytes
++) = (uint8_t)0xFF;
826 annexSet
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSet(cset
, idx
);
827 __CFCSetPutClassType(annexSet
, __kCFCharSetClassBitmap
);
828 __CFCSetPutBitmapBits(annexSet
, annexBitmap
);
829 __CFCSetPutIsInverted(annexSet
, false);
830 __CFCSetPutHasHashValue(annexSet
, false);
833 if (annexBitmap
) CFAllocatorDeallocate(allocator
, annexBitmap
);
835 } else if (__CFCSetIsCompactBitmap(cset
) && __CFCSetCompactBitmapBits(cset
)) {
836 CFAllocatorDeallocate(allocator
, __CFCSetCompactBitmapBits(cset
));
837 __CFCSetPutCompactBitmapBits(cset
, NULL
);
838 } else if (__CFCSetIsString(cset
) && __CFCSetStringBuffer(cset
)) {
839 CFAllocatorDeallocate(allocator
, __CFCSetStringBuffer(cset
));
840 __CFCSetPutStringBuffer(cset
, NULL
);
841 } else if (__CFCSetIsRange(cset
)) { // We may have to allocate annex here
842 Boolean needsToInvert
= (!__CFCSetHasNonBMPPlane(cset
) && __CFCSetIsInverted(cset
) ? true : false);
843 __CFCSetAddNonBMPPlanesInRange(cset
, CFRangeMake(__CFCSetRangeFirstChar(cset
), __CFCSetRangeLength(cset
)));
844 if (needsToInvert
) __CFCSetAnnexSetIsInverted(cset
, true);
846 __CFCSetPutClassType(cset
, __kCFCharSetClassBitmap
);
847 __CFCSetPutBitmapBits(cset
, bitmap
);
848 __CFCSetPutIsInverted(cset
, false);
852 CF_INLINE CFMutableCharacterSetRef
__CFCSetGenericCreate(CFAllocatorRef allocator
, UInt32 flags
) {
853 CFMutableCharacterSetRef cset
;
854 CFIndex size
= sizeof(struct __CFCharacterSet
) - sizeof(CFRuntimeBase
);
856 cset
= (CFMutableCharacterSetRef
)_CFRuntimeCreateInstance(allocator
, CFCharacterSetGetTypeID(), size
, NULL
);
857 if (NULL
== cset
) return NULL
;
859 cset
->_base
._info
|= flags
;
860 cset
->_hashValue
= 0;
866 /* Bsearch theChar for __kCFCharSetClassString
868 CF_INLINE Boolean
__CFCSetBsearchUniChar(const UniChar
*theTable
, CFIndex length
, UniChar theChar
) {
869 const UniChar
*p
, *q
, *divider
;
871 if ((theChar
< theTable
[0]) || (theChar
> theTable
[length
- 1])) return false;
874 q
= p
+ (length
- 1);
876 divider
= p
+ ((q
- p
) >> 1); /* divide by 2 */
877 if (theChar
< *divider
) q
= divider
- 1;
878 else if (theChar
> *divider
) p
= divider
+ 1;
884 /* Predefined cset names
885 Need to add entry here for new builtin types
887 CONST_STRING_DECL(__kCFCSetNameControl
, "<CFCharacterSet Predefined Control Set>")
888 CONST_STRING_DECL(__kCFCSetNameWhitespace
, "<CFCharacterSet Predefined Whitespace Set>")
889 CONST_STRING_DECL(__kCFCSetNameWhitespaceAndNewline
, "<CFCharacterSet Predefined WhitespaceAndNewline Set>")
890 CONST_STRING_DECL(__kCFCSetNameDecimalDigit
, "<CFCharacterSet Predefined DecimalDigit Set>")
891 CONST_STRING_DECL(__kCFCSetNameLetter
, "<CFCharacterSet Predefined Letter Set>")
892 CONST_STRING_DECL(__kCFCSetNameLowercaseLetter
, "<CFCharacterSet Predefined LowercaseLetter Set>")
893 CONST_STRING_DECL(__kCFCSetNameUppercaseLetter
, "<CFCharacterSet Predefined UppercaseLetter Set>")
894 CONST_STRING_DECL(__kCFCSetNameNonBase
, "<CFCharacterSet Predefined NonBase Set>")
895 CONST_STRING_DECL(__kCFCSetNameDecomposable
, "<CFCharacterSet Predefined Decomposable Set>")
896 CONST_STRING_DECL(__kCFCSetNameAlphaNumeric
, "<CFCharacterSet Predefined AlphaNumeric Set>")
897 CONST_STRING_DECL(__kCFCSetNamePunctuation
, "<CFCharacterSet Predefined Punctuation Set>")
898 CONST_STRING_DECL(__kCFCSetNameIllegal
, "<CFCharacterSet Predefined Illegal Set>")
899 CONST_STRING_DECL(__kCFCSetNameCapitalizedLetter
, "<CFCharacterSet Predefined CapitalizedLetter Set>")
900 CONST_STRING_DECL(__kCFCSetNameSymbol
, "<CFCharacterSet Predefined Symbol Set>")
902 CONST_STRING_DECL(__kCFCSetNameStringTypeFormat
, "<CFCharacterSet Items(")
904 /* Array of instantiated builtin set. Note builtin set ID starts with 1 so the array index is ID - 1
906 static CFCharacterSetRef
*__CFBuiltinSets
= NULL
;
908 /* Global lock for character set
910 static CFSpinLock_t __CFCharacterSetLock
= 0;
912 /* CFBase API functions
914 static Boolean
__CFCharacterSetEqual(CFTypeRef cf1
, CFTypeRef cf2
) {
915 Boolean isInvertStateIdentical
= (__CFCSetIsInverted(cf1
) == __CFCSetIsInverted(cf2
) ? true: false);
916 Boolean isAnnexInvertStateIdentical
= (__CFCSetAnnexIsInverted(cf1
) == __CFCSetAnnexIsInverted(cf2
) ? true: false);
918 CFCharacterSetRef subSet1
;
919 uint8_t bitsBuf
[__kCFBitmapSize
];
924 if (__CFCSetHasHashValue(cf1
) && __CFCSetHasHashValue(cf2
) && ((CFCharacterSetRef
)cf1
)->_hashValue
!= ((CFCharacterSetRef
)cf2
)->_hashValue
) return false;
925 if (__CFCSetIsEmpty(cf1
) && __CFCSetIsEmpty(cf2
) && !isInvertStateIdentical
) return false;
927 if (__CFCSetClassType(cf1
) == __CFCSetClassType(cf2
)) { // Types are identical, we can do it fast
928 switch (__CFCSetClassType(cf1
)) {
929 case __kCFCharSetClassBuiltin
:
930 return (__CFCSetBuiltinType(cf1
) == __CFCSetBuiltinType(cf2
) && isInvertStateIdentical
? true : false);
932 case __kCFCharSetClassRange
:
933 return (__CFCSetRangeFirstChar(cf1
) == __CFCSetRangeFirstChar(cf2
) && __CFCSetRangeLength(cf1
) && __CFCSetRangeLength(cf2
) && isInvertStateIdentical
? true : false);
935 case __kCFCharSetClassString
:
936 if (__CFCSetStringLength(cf1
) == __CFCSetStringLength(cf2
) && isInvertStateIdentical
) {
937 const UniChar
*buf1
= __CFCSetStringBuffer(cf1
);
938 const UniChar
*buf2
= __CFCSetStringBuffer(cf2
);
939 CFIndex length
= __CFCSetStringLength(cf1
);
941 while (length
--) if (*buf1
++ != *buf2
++) return false;
947 case __kCFCharSetClassBitmap
:
948 if (!__CFCSetIsEqualBitmap((const UInt32
*)__CFCSetBitmapBits(cf1
), (const UInt32
*)__CFCSetBitmapBits(cf2
))) return false;
951 return __CFCSetIsEqualAnnex(cf1
, cf2
);
954 // Check for easy empty cases
955 if (__CFCSetIsEmpty(cf1
) || __CFCSetIsEmpty(cf2
)) {
956 CFCharacterSetRef emptySet
= (__CFCSetIsEmpty(cf1
) ? cf1
: cf2
);
957 CFCharacterSetRef nonEmptySet
= (emptySet
== cf1
? cf2
: cf1
);
959 if (__CFCSetIsBuiltin(nonEmptySet
)) {
961 } else if (__CFCSetIsRange(nonEmptySet
)) {
962 if (isInvertStateIdentical
) {
963 return (__CFCSetRangeLength(nonEmptySet
) ? false : true);
965 return (__CFCSetRangeLength(nonEmptySet
) == 0x110000 ? true : false);
968 if (__CFCSetAnnexIsInverted(nonEmptySet
)) {
969 if (__CFCSetAnnexValidEntriesBitmap(nonEmptySet
) != 0x1FFFE) return false;
971 if (__CFCSetAnnexValidEntriesBitmap(nonEmptySet
)) return false;
974 if (__CFCSetIsBitmap(nonEmptySet
)) {
975 bits
= __CFCSetBitmapBits(nonEmptySet
);
978 __CFCSetGetBitmap(nonEmptySet
, bitsBuf
);
981 if (__CFCSetIsEqualBitmap(NULL
, (const UInt32
*)bits
)) {
982 if (!__CFCSetAnnexIsInverted(nonEmptySet
)) return true;
987 // Annex set has to be CFRangeMake(0x10000, 0xfffff)
988 for (idx
= 1;idx
< MAX_ANNEX_PLANE
;idx
++) {
989 if (__CFCSetIsBitmap(nonEmptySet
)) {
990 if (!__CFCSetIsEqualBitmap((__CFCSetAnnexIsInverted(nonEmptySet
) ? NULL
: (const UInt32
*)-1), (const UInt32
*)bitsBuf
)) return false;
992 __CFCSetGetBitmap(__CFCSetGetAnnexPlaneCharacterSetNoAlloc(nonEmptySet
, idx
), bitsBuf
);
993 if (!__CFCSetIsEqualBitmap((const UInt32
*)-1, (const UInt32
*)bitsBuf
)) return false;
1000 if (__CFCSetIsBuiltin(cf1
) || __CFCSetIsBuiltin(cf2
)) {
1001 CFCharacterSetRef builtinSet
= (__CFCSetIsBuiltin(cf1
) ? cf1
: cf2
);
1002 CFCharacterSetRef nonBuiltinSet
= (builtinSet
== cf1
? cf2
: cf1
);
1005 if (__CFCSetIsRange(nonBuiltinSet
)) {
1006 UTF32Char firstChar
= __CFCSetRangeFirstChar(nonBuiltinSet
);
1007 UTF32Char lastChar
= (firstChar
+ __CFCSetRangeLength(nonBuiltinSet
) - 1);
1008 uint8_t firstPlane
= (firstChar
>> 16) & 0xFF;
1009 uint8_t lastPlane
= (lastChar
>> 16) & 0xFF;
1012 for (idx
= 0;idx
< MAX_ANNEX_PLANE
;idx
++) {
1013 result
= CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(builtinSet
), idx
, bitsBuf
, isInvertStateIdentical
);
1015 if (idx
< firstPlane
|| idx
> lastPlane
) {
1016 if (result
== kCFUniCharBitmapAll
) {
1018 } else if (result
== kCFUniCharBitmapFilled
) {
1019 if (!__CFCSetIsEqualBitmap(NULL
, (const UInt32
*)bitsBuf
)) return false;
1021 } else if (idx
> firstPlane
&& idx
< lastPlane
) {
1022 if (result
== kCFUniCharBitmapEmpty
) {
1024 } else if (result
== kCFUniCharBitmapFilled
) {
1025 if (!__CFCSetIsEqualBitmap((const UInt32
*)-1, (const UInt32
*)bitsBuf
)) return false;
1028 if (result
== kCFUniCharBitmapEmpty
) {
1030 } else if (result
== kCFUniCharBitmapAll
) {
1031 if (idx
== firstPlane
) {
1032 if (((firstChar
& 0xFFFF) != 0) || (firstPlane
== lastPlane
&& ((lastChar
& 0xFFFF) != 0xFFFF))) return false;
1034 if (((lastChar
& 0xFFFF) != 0xFFFF) || (firstPlane
== lastPlane
&& ((firstChar
& 0xFFFF) != 0))) return false;
1037 if (idx
== firstPlane
) {
1038 if (!__CFCSetIsBitmapEqualToRange((const UInt32
*)bitsBuf
, firstChar
& 0xFFFF, (firstPlane
== lastPlane
? lastChar
& 0xFFFF : 0xFFFF), false)) return false;
1040 if (!__CFCSetIsBitmapEqualToRange((const UInt32
*)bitsBuf
, (firstPlane
== lastPlane
? firstChar
& 0xFFFF : 0), lastChar
& 0xFFFF, false)) return false;
1048 uint8_t *bitsBuf2
= NULL
;
1050 uint8_t bitsBuf2
[__kCFBitmapSize
];
1054 result
= CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(builtinSet
), 0, bitsBuf
, __CFCSetIsInverted(builtinSet
));
1055 if (result
== kCFUniCharBitmapFilled
) {
1056 if (__CFCSetIsBitmap(nonBuiltinSet
)) {
1057 if (!__CFCSetIsEqualBitmap((const UInt32
*)bitsBuf
, (const UInt32
*)__CFCSetBitmapBits(nonBuiltinSet
))) return false;
1060 bitsBuf2
= CFAllocatorAllocate(CFGetAllocator(nonBuiltinSet
), __kCFBitmapSize
, 0);
1063 __CFCSetGetBitmap(nonBuiltinSet
, bitsBuf2
);
1064 if (!__CFCSetIsEqualBitmap((const UInt32
*)bitsBuf
, (const UInt32
*)bitsBuf2
)) {
1066 CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet
), bitsBuf2
);
1072 if (__CFCSetIsBitmap(nonBuiltinSet
)) {
1073 if (!__CFCSetIsEqualBitmap((result
== kCFUniCharBitmapAll
? (const UInt32
*)-1 : NULL
), (const UInt32
*)__CFCSetBitmapBits(nonBuiltinSet
))) return false;
1075 __CFCSetGetBitmap(nonBuiltinSet
, bitsBuf
);
1076 if (!__CFCSetIsEqualBitmap((result
== kCFUniCharBitmapAll
? (const UInt32
*)-1: NULL
), (const UInt32
*)bitsBuf
)) return false;
1080 isInvertStateIdentical
= (__CFCSetIsInverted(builtinSet
) == __CFCSetAnnexIsInverted(nonBuiltinSet
) ? true : false);
1082 for (idx
= 1;idx
< MAX_ANNEX_PLANE
;idx
++) {
1083 result
= CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(builtinSet
), idx
, bitsBuf
, !isInvertStateIdentical
);
1084 subSet1
= __CFCSetGetAnnexPlaneCharacterSetNoAlloc(nonBuiltinSet
, idx
);
1086 if (result
== kCFUniCharBitmapFilled
) {
1087 if (NULL
== subSet1
) {
1089 if (bitsBuf2
) CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet
), bitsBuf2
);
1092 } else if (__CFCSetIsBitmap(subSet1
)) {
1093 if (!__CFCSetIsEqualBitmap((const UInt32
*)bitsBuf
, (const UInt32
*)__CFCSetBitmapBits(subSet1
))) {
1095 if (bitsBuf2
) CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet
), bitsBuf2
);
1101 if (NULL
== bitsBuf2
) bitsBuf2
= CFAllocatorAllocate(CFGetAllocator(nonBuiltinSet
), __kCFBitmapSize
, 0);
1104 __CFCSetGetBitmap(subSet1
, bitsBuf2
);
1105 if (!__CFCSetIsEqualBitmap((const UInt32
*)bitsBuf
, (const UInt32
*)bitsBuf2
)) {
1107 CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet
), bitsBuf2
);
1113 if (NULL
== subSet1
) {
1114 if (result
== kCFUniCharBitmapAll
) {
1116 if (bitsBuf2
) CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet
), bitsBuf2
);
1120 } else if (__CFCSetIsBitmap(subSet1
)) {
1121 if (!__CFCSetIsEqualBitmap((result
== kCFUniCharBitmapAll
? (const UInt32
*)-1: NULL
), (const UInt32
*)__CFCSetBitmapBits(subSet1
))) {
1123 if (bitsBuf2
) CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet
), bitsBuf2
);
1128 __CFCSetGetBitmap(subSet1
, bitsBuf
);
1129 if (!__CFCSetIsEqualBitmap((result
== kCFUniCharBitmapAll
? (const UInt32
*)-1: NULL
), (const UInt32
*)bitsBuf
)) {
1131 if (bitsBuf2
) CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet
), bitsBuf2
);
1139 if (bitsBuf2
) CFAllocatorDeallocate(CFGetAllocator(nonBuiltinSet
), bitsBuf2
);
1145 if (__CFCSetIsRange(cf1
) || __CFCSetIsRange(cf2
)) {
1146 CFCharacterSetRef rangeSet
= (__CFCSetIsRange(cf1
) ? cf1
: cf2
);
1147 CFCharacterSetRef nonRangeSet
= (rangeSet
== cf1
? cf2
: cf1
);
1148 UTF32Char firstChar
= __CFCSetRangeFirstChar(rangeSet
);
1149 UTF32Char lastChar
= (firstChar
+ __CFCSetRangeLength(rangeSet
) - 1);
1150 uint8_t firstPlane
= (firstChar
>> 16) & 0xFF;
1151 uint8_t lastPlane
= (lastChar
>> 16) & 0xFF;
1152 Boolean isRangeSetInverted
= __CFCSetIsInverted(rangeSet
);
1154 if (__CFCSetIsBitmap(nonRangeSet
)) {
1155 bits
= __CFCSetBitmapBits(nonRangeSet
);
1158 __CFCSetGetBitmap(nonRangeSet
, bitsBuf
);
1160 if (firstPlane
== 0) {
1161 if (!__CFCSetIsBitmapEqualToRange((const UInt32
*)bits
, firstChar
, (lastPlane
== 0 ? lastChar
: 0xFFFF), isRangeSetInverted
)) return false;
1165 if (!__CFCSetIsEqualBitmap((const UInt32
*)bits
, (isRangeSetInverted
? (const UInt32
*)-1 : NULL
))) return false;
1166 firstChar
&= 0xFFFF;
1171 isAnnexInvertStateIdentical
= (isRangeSetInverted
== __CFCSetAnnexIsInverted(nonRangeSet
) ? true : false);
1173 for (idx
= 1;idx
< MAX_ANNEX_PLANE
;idx
++) {
1174 subSet1
= __CFCSetGetAnnexPlaneCharacterSetNoAlloc(nonRangeSet
, idx
);
1175 if (NULL
== subSet1
) {
1176 if (idx
< firstPlane
|| idx
> lastPlane
) {
1177 if (!isAnnexInvertStateIdentical
) return false;
1178 } else if (idx
> firstPlane
&& idx
< lastPlane
) {
1179 if (isAnnexInvertStateIdentical
) return false;
1180 } else if (idx
== firstPlane
) {
1181 if (isAnnexInvertStateIdentical
|| firstChar
|| (idx
== lastPlane
&& lastChar
!= 0xFFFF)) return false;
1182 } else if (idx
== lastPlane
) {
1183 if (isAnnexInvertStateIdentical
|| (idx
== firstPlane
&& firstChar
) || (lastChar
!= 0xFFFF)) return false;
1186 if (__CFCSetIsBitmap(subSet1
)) {
1187 bits
= __CFCSetBitmapBits(subSet1
);
1189 __CFCSetGetBitmap(subSet1
, bitsBuf
);
1193 if (idx
< firstPlane
|| idx
> lastPlane
) {
1194 if (!__CFCSetIsEqualBitmap((const UInt32
*)bits
, (isAnnexInvertStateIdentical
? NULL
: (const UInt32
*)-1))) return false;
1195 } else if (idx
> firstPlane
&& idx
< lastPlane
) {
1196 if (!__CFCSetIsEqualBitmap((const UInt32
*)bits
, (isAnnexInvertStateIdentical
? (const UInt32
*)-1 : NULL
))) return false;
1197 } else if (idx
== firstPlane
) {
1198 if (!__CFCSetIsBitmapEqualToRange((const UInt32
*)bits
, firstChar
, (idx
== lastPlane
? lastChar
: 0xFFFF), !isAnnexInvertStateIdentical
)) return false;
1199 } else if (idx
== lastPlane
) {
1200 if (!__CFCSetIsBitmapEqualToRange((const UInt32
*)bits
, (idx
== firstPlane
? firstChar
: 0), lastChar
, !isAnnexInvertStateIdentical
)) return false;
1207 isBitmap1
= __CFCSetIsBitmap(cf1
);
1208 isBitmap2
= __CFCSetIsBitmap(cf2
);
1210 if (isBitmap1
&& isBitmap2
) {
1211 if (!__CFCSetIsEqualBitmap((const UInt32
*)__CFCSetBitmapBits(cf1
), (const UInt32
*)__CFCSetBitmapBits(cf2
))) return false;
1212 } else if (!isBitmap1
&& !isBitmap2
) {
1214 uint8_t *bitsBuf2
= (uint8_t *)CFAllocatorAllocate(NULL
, __kCFBitmapSize
, 0);
1216 uint8_t bitsBuf2
[__kCFBitmapSize
];
1219 __CFCSetGetBitmap(cf1
, bitsBuf
);
1220 __CFCSetGetBitmap(cf2
, bitsBuf2
);
1222 if (!__CFCSetIsEqualBitmap((const UInt32
*)bitsBuf
, (const UInt32
*)bitsBuf2
)) {
1224 CFAllocatorDeallocate(NULL
, bitsBuf2
);
1229 CFAllocatorDeallocate(NULL
, bitsBuf2
);
1233 CFCharacterSetRef tmp
= cf2
;
1238 __CFCSetGetBitmap(cf2
, bitsBuf
);
1240 if (!__CFCSetIsEqualBitmap((const UInt32
*)__CFCSetBitmapBits(cf1
), (const UInt32
*)bitsBuf
)) return false;
1242 return __CFCSetIsEqualAnnex(cf1
, cf2
);
1245 static CFHashCode
__CFCharacterSetHash(CFTypeRef cf
) {
1246 if (!__CFCSetHasHashValue(cf
)) {
1247 if (__CFCSetIsEmpty(cf
)) {
1248 ((CFMutableCharacterSetRef
)cf
)->_hashValue
= (__CFCSetIsInverted(cf
) ? 0xFFFFFFFF : 0);
1249 } else if (__CFCSetIsBitmap(cf
)) {
1250 ((CFMutableCharacterSetRef
)cf
)->_hashValue
= CFHashBytes(__CFCSetBitmapBits(cf
), __kCFBitmapSize
);
1252 uint8_t bitsBuf
[__kCFBitmapSize
];
1253 __CFCSetGetBitmap(cf
, bitsBuf
);
1254 ((CFMutableCharacterSetRef
)cf
)->_hashValue
= CFHashBytes(bitsBuf
, __kCFBitmapSize
);
1256 __CFCSetPutHasHashValue((CFMutableCharacterSetRef
)cf
, true);
1258 return ((CFCharacterSetRef
)cf
)->_hashValue
;
1261 static CFStringRef
__CFCharacterSetCopyDescription(CFTypeRef cf
) {
1262 CFMutableStringRef string
;
1266 if (__CFCSetIsEmpty(cf
)) {
1267 return (__CFCSetIsInverted(cf
) ? CFRetain(CFSTR("<CFCharacterSet All>")) : CFRetain(CFSTR("<CFCharacterSet Empty>")));
1270 switch (__CFCSetClassType(cf
)) {
1271 case __kCFCharSetClassBuiltin
:
1272 switch (__CFCSetBuiltinType(cf
)) {
1273 case kCFCharacterSetControl
: return CFRetain(__kCFCSetNameControl
);
1274 case kCFCharacterSetWhitespace
: return CFRetain(__kCFCSetNameWhitespace
);
1275 case kCFCharacterSetWhitespaceAndNewline
: return CFRetain(__kCFCSetNameWhitespaceAndNewline
);
1276 case kCFCharacterSetDecimalDigit
: return CFRetain(__kCFCSetNameDecimalDigit
);
1277 case kCFCharacterSetLetter
: return CFRetain(__kCFCSetNameLetter
);
1278 case kCFCharacterSetLowercaseLetter
: return CFRetain(__kCFCSetNameLowercaseLetter
);
1279 case kCFCharacterSetUppercaseLetter
: return CFRetain(__kCFCSetNameUppercaseLetter
);
1280 case kCFCharacterSetNonBase
: return CFRetain(__kCFCSetNameNonBase
);
1281 case kCFCharacterSetDecomposable
: return CFRetain(__kCFCSetNameDecomposable
);
1282 case kCFCharacterSetAlphaNumeric
: return CFRetain(__kCFCSetNameAlphaNumeric
);
1283 case kCFCharacterSetPunctuation
: return CFRetain(__kCFCSetNamePunctuation
);
1284 case kCFCharacterSetIllegal
: return CFRetain(__kCFCSetNameIllegal
);
1285 case kCFCharacterSetCapitalizedLetter
: return CFRetain(__kCFCSetNameCapitalizedLetter
);
1286 case kCFCharacterSetSymbol
: return CFRetain(__kCFCSetNameSymbol
);
1290 case __kCFCharSetClassRange
:
1291 return CFStringCreateWithFormat(CFGetAllocator(cf
), NULL
, CFSTR("<CFCharacterSet Range(%d, %d)>"), __CFCSetRangeFirstChar(cf
), __CFCSetRangeLength(cf
));
1293 case __kCFCharSetClassString
:
1294 length
= __CFCSetStringLength(cf
);
1295 string
= CFStringCreateMutable(CFGetAllocator(cf
), CFStringGetLength(__kCFCSetNameStringTypeFormat
) + 7 * length
+ 2); // length of__kCFCSetNameStringTypeFormat + "U+XXXX "(7) * length + ")>"(2)
1296 CFStringAppend(string
, __kCFCSetNameStringTypeFormat
);
1297 for (idx
= 0;idx
< length
;idx
++) {
1298 CFStringAppendFormat(string
, NULL
, CFSTR("%sU+%04X"), (idx
> 0 ? " " : ""), (UInt32
)((__CFCSetStringBuffer(cf
))[idx
]));
1300 CFStringAppend(string
, CFSTR(")>"));
1303 case __kCFCharSetClassBitmap
:
1304 case __kCFCharSetClassCompactBitmap
:
1305 return CFRetain(CFSTR("<CFCharacterSet Bitmap>")); // ??? Should generate description for 8k bitmap ?
1307 CFAssert1(0, __kCFLogAssertion
, "%s: Internal inconsistency error: unknown character set type", __PRETTY_FUNCTION__
); // We should never come here
1311 static void __CFCharacterSetDeallocate(CFTypeRef cf
) {
1312 CFAllocatorRef allocator
= CFGetAllocator(cf
);
1314 if (__CFCSetIsBuiltin(cf
) && !__CFCSetIsMutable(cf
) && !__CFCSetIsInverted(cf
)) {
1315 CFCharacterSetRef sharedSet
= CFCharacterSetGetPredefined(__CFCSetBuiltinType(cf
));
1316 if (sharedSet
== cf
) { // We're trying to dealloc the builtin set
1317 CFAssert1(0, __kCFLogAssertion
, "%s: Trying to deallocate predefined set", __PRETTY_FUNCTION__
);
1318 return; // We never deallocate builtin set
1322 if (__CFCSetIsString(cf
) && __CFCSetStringBuffer(cf
)) CFAllocatorDeallocate(allocator
, __CFCSetStringBuffer(cf
));
1323 else if (__CFCSetIsBitmap(cf
) && __CFCSetBitmapBits(cf
)) CFAllocatorDeallocate(allocator
, __CFCSetBitmapBits(cf
));
1324 else if (__CFCSetIsCompactBitmap(cf
) && __CFCSetCompactBitmapBits(cf
)) CFAllocatorDeallocate(allocator
, __CFCSetCompactBitmapBits(cf
));
1325 __CFCSetDeallocateAnnexPlane(cf
);
1328 static CFTypeID __kCFCharacterSetTypeID
= _kCFRuntimeNotATypeID
;
1330 static const CFRuntimeClass __CFCharacterSetClass
= {
1335 __CFCharacterSetDeallocate
,
1336 __CFCharacterSetEqual
,
1337 __CFCharacterSetHash
,
1339 __CFCharacterSetCopyDescription
1342 static bool __CFCheckForExapendedSet
= false;
1344 __private_extern__
void __CFCharacterSetInitialize(void) {
1345 const char *checkForExpandedSet
= getenv("__CF_DEBUG_EXPANDED_SET");
1347 __kCFCharacterSetTypeID
= _CFRuntimeRegisterClass(&__CFCharacterSetClass
);
1349 if (checkForExpandedSet
&& (*checkForExpandedSet
== 'Y')) __CFCheckForExapendedSet
= true;
1354 #if defined(__MACOS8__)
1355 CFTypeID
CFCharacterSetTypeID(void) {
1357 CFLog(__kCFLogAssertion
, CFSTR("CFCharacterSetTypeID should be CFCharacterSetGetTypeID"));
1359 return __kCFCharacterSetTypeID
;
1361 #endif /* __MACOS8__ */
1363 CFTypeID
CFCharacterSetGetTypeID(void) {
1364 return __kCFCharacterSetTypeID
;
1367 /*** CharacterSet creation ***/
1368 /* Functions to create basic immutable characterset.
1370 CFCharacterSetRef
CFCharacterSetGetPredefined(CFCharacterSetPredefinedSet theSetIdentifier
) {
1371 CFMutableCharacterSetRef cset
;
1373 __CFCSetValidateBuiltinType(theSetIdentifier
, __PRETTY_FUNCTION__
);
1375 if (__CFBuiltinSets
&& __CFBuiltinSets
[theSetIdentifier
- 1]) return __CFBuiltinSets
[theSetIdentifier
- 1];
1377 if (!(cset
= __CFCSetGenericCreate(kCFAllocatorSystemDefault
, __kCFCharSetClassBuiltin
))) return NULL
;
1378 __CFCSetPutBuiltinType(cset
, theSetIdentifier
);
1380 if (!__CFBuiltinSets
) {
1381 __CFSpinLock(&__CFCharacterSetLock
);
1382 __CFBuiltinSets
= (CFCharacterSetRef
*)CFAllocatorAllocate(CFRetain(__CFGetDefaultAllocator()), sizeof(CFCharacterSetRef
) * __kCFLastBuiltinSetID
, 0);
1383 memset(__CFBuiltinSets
, 0, sizeof(CFCharacterSetRef
) * __kCFLastBuiltinSetID
);
1384 __CFSpinUnlock(&__CFCharacterSetLock
);
1387 __CFBuiltinSets
[theSetIdentifier
- 1] = cset
;
1392 CFCharacterSetRef
CFCharacterSetCreateWithCharactersInRange(CFAllocatorRef allocator
, CFRange theRange
) {
1393 CFMutableCharacterSetRef cset
;
1395 __CFCSetValidateRange(theRange
, __PRETTY_FUNCTION__
);
1397 if (theRange
.length
) {
1398 if (!(cset
= __CFCSetGenericCreate(allocator
, __kCFCharSetClassRange
))) return NULL
;
1399 __CFCSetPutRangeFirstChar(cset
, theRange
.location
);
1400 __CFCSetPutRangeLength(cset
, theRange
.length
);
1402 if (!(cset
= __CFCSetGenericCreate(allocator
, __kCFCharSetClassBitmap
))) return NULL
;
1403 __CFCSetPutBitmapBits(cset
, NULL
);
1404 __CFCSetPutHasHashValue(cset
, true); // _hashValue is 0
1410 static int chcompar(const void *a
, const void *b
) {
1411 return -(int)(*(UniChar
*)b
- *(UniChar
*)a
);
1414 CFCharacterSetRef
CFCharacterSetCreateWithCharactersInString(CFAllocatorRef allocator
, CFStringRef theString
) {
1417 length
= CFStringGetLength(theString
);
1418 if (length
< __kCFStringCharSetMax
) {
1419 CFMutableCharacterSetRef cset
;
1421 if (!(cset
= __CFCSetGenericCreate(allocator
, __kCFCharSetClassString
))) return NULL
;
1422 __CFCSetPutStringBuffer(cset
, CFAllocatorAllocate(CFGetAllocator(cset
), __kCFStringCharSetMax
* sizeof(UniChar
), AUTO_MEMORY_UNSCANNED
));
1423 __CFCSetPutStringLength(cset
, length
);
1424 CFStringGetCharacters(theString
, CFRangeMake(0, length
), __CFCSetStringBuffer(cset
));
1425 qsort(__CFCSetStringBuffer(cset
), length
, sizeof(UniChar
), chcompar
);
1426 if (!length
) __CFCSetPutHasHashValue(cset
, true); // _hashValue is 0
1429 CFMutableCharacterSetRef mcset
= CFCharacterSetCreateMutable(allocator
);
1430 CFCharacterSetAddCharactersInString(mcset
, theString
);
1431 __CFCSetMakeCompact(mcset
);
1432 __CFCSetPutIsMutable(mcset
, false);
1437 #if defined(__MACOS8__)
1438 CFCharacterSetRef
CFCharacterSetCreateWithBitmapReresentation(CFAllocatorRef allocator
, CFDataRef theData
) {
1440 CFLog(__kCFLogAssertion
, CFSTR("CFCharacterSetCreateWithBitmapReresentation should be CFCharacterSetCreateWithBitmapRepresentation"));
1442 return CFCharacterSetCreateWithBitmapRepresentation(allocator
, theData
);
1444 #endif /* __MACOS8__ */
1446 CFCharacterSetRef
CFCharacterSetCreateWithBitmapRepresentation(CFAllocatorRef allocator
, CFDataRef theData
) {
1447 CFMutableCharacterSetRef cset
;
1450 if (!(cset
= __CFCSetGenericCreate(allocator
, __kCFCharSetClassBitmap
))) return NULL
;
1452 if (theData
&& (length
= CFDataGetLength(theData
)) > 0) {
1456 if (length
< __kCFBitmapSize
) {
1457 bitmap
= (uint8_t *)CFAllocatorAllocate(allocator
, __kCFBitmapSize
, AUTO_MEMORY_UNSCANNED
);
1458 memmove(bitmap
, CFDataGetBytePtr(theData
), length
);
1459 memset(bitmap
+ length
, 0, __kCFBitmapSize
- length
);
1461 cBitmap
= __CFCreateCompactBitmap(allocator
, bitmap
);
1463 if (cBitmap
== NULL
) {
1464 __CFCSetPutBitmapBits(cset
, bitmap
);
1466 CFAllocatorDeallocate(allocator
, bitmap
);
1467 __CFCSetPutCompactBitmapBits(cset
, cBitmap
);
1468 __CFCSetPutClassType(cset
, __kCFCharSetClassCompactBitmap
);
1471 cBitmap
= __CFCreateCompactBitmap(allocator
, CFDataGetBytePtr(theData
));
1473 if (cBitmap
== NULL
) {
1474 bitmap
= (uint8_t *)CFAllocatorAllocate(allocator
, __kCFBitmapSize
, AUTO_MEMORY_UNSCANNED
);
1475 memmove(bitmap
, CFDataGetBytePtr(theData
), __kCFBitmapSize
);
1477 __CFCSetPutBitmapBits(cset
, bitmap
);
1479 __CFCSetPutCompactBitmapBits(cset
, cBitmap
);
1480 __CFCSetPutClassType(cset
, __kCFCharSetClassCompactBitmap
);
1483 if (length
> __kCFBitmapSize
) {
1484 CFMutableCharacterSetRef annexSet
;
1485 const char *bytes
= CFDataGetBytePtr(theData
) + __kCFBitmapSize
;
1487 length
-= __kCFBitmapSize
;
1489 while (length
> 1) {
1490 annexSet
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSet(cset
, *(bytes
++));
1491 --length
; // Decrement the plane no byte
1493 if (length
< __kCFBitmapSize
) {
1494 bitmap
= (uint8_t *)CFAllocatorAllocate(allocator
, __kCFBitmapSize
, AUTO_MEMORY_UNSCANNED
);
1495 memmove(bitmap
, bytes
, length
);
1496 memset(bitmap
+ length
, 0, __kCFBitmapSize
- length
);
1498 cBitmap
= __CFCreateCompactBitmap(allocator
, bitmap
);
1500 if (cBitmap
== NULL
) {
1501 __CFCSetPutBitmapBits(annexSet
, bitmap
);
1503 CFAllocatorDeallocate(allocator
, bitmap
);
1504 __CFCSetPutCompactBitmapBits(annexSet
, cBitmap
);
1505 __CFCSetPutClassType(annexSet
, __kCFCharSetClassCompactBitmap
);
1508 cBitmap
= __CFCreateCompactBitmap(allocator
, bytes
);
1510 if (cBitmap
== NULL
) {
1511 bitmap
= (uint8_t *)CFAllocatorAllocate(allocator
, __kCFBitmapSize
, AUTO_MEMORY_UNSCANNED
);
1512 memmove(bitmap
, bytes
, __kCFBitmapSize
);
1514 __CFCSetPutBitmapBits(annexSet
, bitmap
);
1516 __CFCSetPutCompactBitmapBits(annexSet
, cBitmap
);
1517 __CFCSetPutClassType(annexSet
, __kCFCharSetClassCompactBitmap
);
1520 length
-= __kCFBitmapSize
;
1521 bytes
+= __kCFBitmapSize
;
1526 __CFCSetPutBitmapBits(cset
, NULL
);
1527 __CFCSetPutHasHashValue(cset
, true); // Hash value is 0
1533 CFCharacterSetRef
CFCharacterSetCreateInvertedSet(CFAllocatorRef alloc
, CFCharacterSetRef theSet
) {
1534 CFMutableCharacterSetRef cset
;
1536 CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID
, CFCharacterSetRef
, theSet
, "invertedSet");
1538 cset
= CFCharacterSetCreateMutableCopy(alloc
, theSet
);
1539 CFCharacterSetInvert(cset
);
1540 __CFCSetPutIsMutable(cset
, false);
1545 /* Functions to create mutable characterset.
1547 CFMutableCharacterSetRef
CFCharacterSetCreateMutable(CFAllocatorRef allocator
) {
1548 CFMutableCharacterSetRef cset
;
1550 if (!(cset
= __CFCSetGenericCreate(allocator
, __kCFCharSetClassBitmap
| __kCFCharSetIsMutable
))) return NULL
;
1551 __CFCSetPutBitmapBits(cset
, NULL
);
1552 __CFCSetPutHasHashValue(cset
, true); // Hash value is 0
1557 CFMutableCharacterSetRef
__CFCharacterSetCreateCopy(CFAllocatorRef alloc
, CFCharacterSetRef theSet
, bool isMutable
) {
1558 CFMutableCharacterSetRef cset
;
1560 CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID
, CFMutableCharacterSetRef
, theSet
, "mutableCopy");
1562 __CFGenericValidateType(theSet
, __kCFCharacterSetTypeID
);
1564 if (!isMutable
&& !__CFCSetIsMutable(theSet
)) {
1565 return (CFMutableCharacterSetRef
)CFRetain(theSet
);
1568 cset
= CFCharacterSetCreateMutable(alloc
);
1570 __CFCSetPutClassType(cset
, __CFCSetClassType(theSet
));
1571 __CFCSetPutHasHashValue(cset
, __CFCSetHasHashValue(theSet
));
1572 __CFCSetPutIsInverted(cset
, __CFCSetIsInverted(theSet
));
1573 cset
->_hashValue
= theSet
->_hashValue
;
1575 switch (__CFCSetClassType(theSet
)) {
1576 case __kCFCharSetClassBuiltin
:
1577 __CFCSetPutBuiltinType(cset
, __CFCSetBuiltinType(theSet
));
1580 case __kCFCharSetClassRange
:
1581 __CFCSetPutRangeFirstChar(cset
, __CFCSetRangeFirstChar(theSet
));
1582 __CFCSetPutRangeLength(cset
, __CFCSetRangeLength(theSet
));
1585 case __kCFCharSetClassString
:
1586 __CFCSetPutStringBuffer(cset
, CFAllocatorAllocate(alloc
, __kCFStringCharSetMax
* sizeof(UniChar
), AUTO_MEMORY_UNSCANNED
));
1587 __CFCSetPutStringLength(cset
, __CFCSetStringLength(theSet
));
1588 memmove(__CFCSetStringBuffer(cset
), __CFCSetStringBuffer(theSet
), __CFCSetStringLength(theSet
) * sizeof(UniChar
));
1591 case __kCFCharSetClassBitmap
:
1592 if (__CFCSetBitmapBits(theSet
)) {
1593 uint8_t * bitmap
= (isMutable
? NULL
: __CFCreateCompactBitmap(alloc
, __CFCSetBitmapBits(theSet
)));
1595 if (bitmap
== NULL
) {
1596 bitmap
= (uint8_t *)CFAllocatorAllocate(alloc
, sizeof(uint8_t) * __kCFBitmapSize
, AUTO_MEMORY_UNSCANNED
);
1597 memmove(bitmap
, __CFCSetBitmapBits(theSet
), __kCFBitmapSize
);
1598 __CFCSetPutBitmapBits(cset
, bitmap
);
1600 __CFCSetPutCompactBitmapBits(cset
, bitmap
);
1601 __CFCSetPutClassType(cset
, __kCFCharSetClassCompactBitmap
);
1604 __CFCSetPutBitmapBits(cset
, NULL
);
1608 case __kCFCharSetClassCompactBitmap
: {
1609 const uint8_t *compactBitmap
= __CFCSetCompactBitmapBits(theSet
);
1611 if (compactBitmap
) {
1612 uint32_t size
= __CFCSetGetCompactBitmapSize(compactBitmap
);
1613 uint8_t *newBitmap
= (uint8_t *)CFAllocatorAllocate(alloc
, size
, AUTO_MEMORY_UNSCANNED
);
1615 memmove(newBitmap
, compactBitmap
, size
);
1616 __CFCSetPutCompactBitmapBits(cset
, newBitmap
);
1622 CFAssert1(0, __kCFLogAssertion
, "%s: Internal inconsistency error: unknown character set type", __PRETTY_FUNCTION__
); // We should never come here
1624 if (__CFCSetHasNonBMPPlane(theSet
)) {
1625 CFMutableCharacterSetRef annexPlane
;
1628 for (idx
= 1;idx
<= MAX_ANNEX_PLANE
;idx
++) {
1629 if ((annexPlane
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet
, idx
))) {
1630 annexPlane
= __CFCharacterSetCreateCopy(alloc
, annexPlane
, isMutable
);
1631 __CFCSetPutCharacterSetToAnnexPlane(cset
, annexPlane
, idx
);
1632 CFRelease(annexPlane
);
1635 __CFCSetAnnexSetIsInverted(cset
, __CFCSetAnnexIsInverted(theSet
));
1636 } else if (__CFCSetAnnexIsInverted(theSet
)) {
1637 __CFCSetAllocateAnnexForPlane(cset
, 0); // We need to alloc annex to invert
1638 __CFCSetAnnexSetIsInverted(cset
, true);
1644 CFCharacterSetRef
CFCharacterSetCreateCopy(CFAllocatorRef alloc
, CFCharacterSetRef theSet
) {
1645 return __CFCharacterSetCreateCopy(alloc
, theSet
, false);
1648 CFMutableCharacterSetRef
CFCharacterSetCreateMutableCopy(CFAllocatorRef alloc
, CFCharacterSetRef theSet
) {
1649 return __CFCharacterSetCreateCopy(alloc
, theSet
, true);
1652 /*** Basic accessors ***/
1653 Boolean
CFCharacterSetIsCharacterMember(CFCharacterSetRef theSet
, UniChar theChar
) {
1654 return CFCharacterSetIsLongCharacterMember(theSet
, theChar
);
1657 Boolean
CFCharacterSetIsLongCharacterMember(CFCharacterSetRef theSet
, UTF32Char theChar
) {
1659 UInt32 plane
= (theChar
>> 16);
1660 Boolean isAnnexInverted
= false;
1662 Boolean result
= false;
1664 CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID
, Boolean
, theSet
, "longCharacterIsMember:", theChar
);
1666 __CFGenericValidateType(theSet
, __kCFCharacterSetTypeID
);
1669 CFCharacterSetRef annexPlane
;
1671 if (__CFCSetIsBuiltin(theSet
)) {
1672 isInverted
= __CFCSetIsInverted(theSet
);
1673 return (CFUniCharIsMemberOf(theChar
, __CFCSetBuiltinType(theSet
)) ? !isInverted
: isInverted
);
1676 isAnnexInverted
= __CFCSetAnnexIsInverted(theSet
);
1678 if ((annexPlane
= __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet
, plane
)) == NULL
) {
1679 if (!__CFCSetHasNonBMPPlane(theSet
) && __CFCSetIsRange(theSet
)) {
1680 isInverted
= __CFCSetIsInverted(theSet
);
1681 length
= __CFCSetRangeLength(theSet
);
1682 return (length
&& __CFCSetRangeFirstChar(theSet
) <= theChar
&& theChar
< __CFCSetRangeFirstChar(theSet
) + length
? !isInverted
: isInverted
);
1684 return (isAnnexInverted
? true : false);
1687 theSet
= annexPlane
;
1692 isInverted
= __CFCSetIsInverted(theSet
);
1694 switch (__CFCSetClassType(theSet
)) {
1695 case __kCFCharSetClassBuiltin
:
1696 result
= (CFUniCharIsMemberOf(theChar
, __CFCSetBuiltinType(theSet
)) ? !isInverted
: isInverted
);
1699 case __kCFCharSetClassRange
:
1700 length
= __CFCSetRangeLength(theSet
);
1701 result
= (length
&& __CFCSetRangeFirstChar(theSet
) <= theChar
&& theChar
< __CFCSetRangeFirstChar(theSet
) + length
? !isInverted
: isInverted
);
1704 case __kCFCharSetClassString
:
1705 result
= ((length
= __CFCSetStringLength(theSet
)) ? (__CFCSetBsearchUniChar(__CFCSetStringBuffer(theSet
), length
, theChar
) ? !isInverted
: isInverted
) : isInverted
);
1708 case __kCFCharSetClassBitmap
:
1709 result
= (__CFCSetCompactBitmapBits(theSet
) ? (__CFCSetIsMemberBitmap(__CFCSetBitmapBits(theSet
), theChar
) ? true : false) : isInverted
);
1712 case __kCFCharSetClassCompactBitmap
:
1713 result
= (__CFCSetCompactBitmapBits(theSet
) ? (__CFCSetIsMemberInCompactBitmap(__CFCSetCompactBitmapBits(theSet
), theChar
) ? true : false) : isInverted
);
1717 CFAssert1(0, __kCFLogAssertion
, "%s: Internal inconsistency error: unknown character set type", __PRETTY_FUNCTION__
); // We should never come here
1718 return false; // To make compiler happy
1721 return (result
? !isAnnexInverted
: isAnnexInverted
);
1724 Boolean
CFCharacterSetIsSurrogatePairMember(CFCharacterSetRef theSet
, UniChar surrogateHigh
, UniChar surrogateLow
) {
1725 return CFCharacterSetIsLongCharacterMember(theSet
, CFCharacterSetGetLongCharacterForSurrogatePair(surrogateHigh
, surrogateLow
));
1729 static CFCharacterSetRef
__CFCharacterSetGetExpandedSetForNSCharacterSet(const void *characterSet
) {
1730 CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID
, CFCharacterSetRef
, characterSet
, "_expandedCFCharacterSet");
1734 Boolean
CFCharacterSetIsSupersetOfSet(CFCharacterSetRef theSet
, CFCharacterSetRef theOtherSet
) {
1735 CFMutableCharacterSetRef copy
;
1736 CFCharacterSetRef expandedSet
= NULL
;
1737 CFCharacterSetRef expandedOtherSet
= NULL
;
1740 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
1741 if (expandedSet
) theSet
= expandedSet
;
1742 if (expandedOtherSet
) theOtherSet
= expandedOtherSet
;
1744 __CFGenericValidateType(theSet
, __kCFCharacterSetTypeID
);
1745 __CFGenericValidateType(theOtherSet
, __kCFCharacterSetTypeID
);
1747 if (__CFCSetIsEmpty(theSet
)) {
1748 if (__CFCSetIsInverted(theSet
)) {
1749 return TRUE
; // Inverted empty set covers all range
1750 } else if (!__CFCSetIsEmpty(theOtherSet
) || __CFCSetIsInverted(theOtherSet
)) {
1753 } else if (__CFCSetIsEmpty(theOtherSet
) && !__CFCSetIsInverted(theOtherSet
)) {
1756 if (__CFCSetIsBuiltin(theSet
) || __CFCSetIsBuiltin(theOtherSet
)) {
1757 if (__CFCSetClassType(theSet
) == __CFCSetClassType(theOtherSet
) && __CFCSetBuiltinType(theSet
) == __CFCSetBuiltinType(theOtherSet
) && !__CFCSetIsInverted(theSet
) && !__CFCSetIsInverted(theOtherSet
)) return TRUE
;
1758 } else if (__CFCSetIsRange(theSet
) || __CFCSetIsRange(theOtherSet
)) {
1759 if (__CFCSetClassType(theSet
) == __CFCSetClassType(theOtherSet
)) {
1760 if (__CFCSetIsInverted(theSet
)) {
1761 if (__CFCSetIsInverted(theOtherSet
)) {
1762 return (__CFCSetRangeFirstChar(theOtherSet
) > __CFCSetRangeFirstChar(theSet
) || (__CFCSetRangeFirstChar(theSet
) + __CFCSetRangeLength(theSet
)) > (__CFCSetRangeFirstChar(theOtherSet
) + __CFCSetRangeLength(theOtherSet
)) ? FALSE
: TRUE
);
1764 return ((__CFCSetRangeFirstChar(theOtherSet
) + __CFCSetRangeLength(theOtherSet
)) <= __CFCSetRangeFirstChar(theSet
) || (__CFCSetRangeFirstChar(theSet
) + __CFCSetRangeLength(theSet
)) <= __CFCSetRangeFirstChar(theOtherSet
) ? TRUE
: FALSE
);
1767 if (__CFCSetIsInverted(theOtherSet
)) {
1768 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
);
1770 return (__CFCSetRangeFirstChar(theOtherSet
) < __CFCSetRangeFirstChar(theSet
) || (__CFCSetRangeFirstChar(theSet
) + __CFCSetRangeLength(theSet
)) < (__CFCSetRangeFirstChar(theOtherSet
) + __CFCSetRangeLength(theOtherSet
)) ? FALSE
: TRUE
);
1775 UInt32 theSetAnnexMask
= __CFCSetAnnexValidEntriesBitmap(theSet
);
1776 UInt32 theOtherSetAnnexMask
= __CFCSetAnnexValidEntriesBitmap(theOtherSet
);
1777 Boolean isTheSetAnnexInverted
= __CFCSetAnnexIsInverted(theSet
);
1778 Boolean isTheOtherSetAnnexInverted
= __CFCSetAnnexIsInverted(theOtherSet
);
1779 uint8_t theSetBuffer
[__kCFBitmapSize
];
1780 uint8_t theOtherSetBuffer
[__kCFBitmapSize
];
1782 // We mask plane 1 to plane 16
1783 if (isTheSetAnnexInverted
) theSetAnnexMask
= (~theSetAnnexMask
) & (0xFFFF < 1);
1784 if (isTheOtherSetAnnexInverted
) theOtherSetAnnexMask
= (~theOtherSetAnnexMask
) & (0xFFFF < 1);
1786 __CFCSetGetBitmap(theSet
, theSetBuffer
);
1787 __CFCSetGetBitmap(theOtherSet
, theOtherSetBuffer
);
1789 if (!__CFCSetIsBitmapSupersetOfBitmap((const UInt32
*)theSetBuffer
, (const UInt32
*)theOtherSetBuffer
, FALSE
, FALSE
)) return FALSE
;
1791 if (theOtherSetAnnexMask
) {
1792 CFCharacterSetRef theSetAnnex
;
1793 CFCharacterSetRef theOtherSetAnnex
;
1796 if ((theSetAnnexMask
& theOtherSetAnnexMask
) != theOtherSetAnnexMask
) return FALSE
;
1798 for (idx
= 1;idx
<= 16;idx
++) {
1799 theSetAnnex
= __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet
, idx
);
1800 if (NULL
== theSetAnnex
) continue; // This case is already handled by the mask above
1802 theOtherSetAnnex
= __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theOtherSet
, idx
);
1804 if (NULL
== theOtherSetAnnex
) {
1805 if (isTheOtherSetAnnexInverted
) {
1806 __CFCSetGetBitmap(theSetAnnex
, theSetBuffer
);
1807 if (!__CFCSetIsEqualBitmap((const UInt32
*)theSetBuffer
, (isTheSetAnnexInverted
? NULL
: (const UInt32
*)-1))) return FALSE
;
1810 __CFCSetGetBitmap(theSetAnnex
, theSetBuffer
);
1811 __CFCSetGetBitmap(theOtherSetAnnex
, theOtherSetBuffer
);
1812 if (!__CFCSetIsBitmapSupersetOfBitmap((const UInt32
*)theSetBuffer
, (const UInt32
*)theOtherSetBuffer
, isTheSetAnnexInverted
, isTheOtherSetAnnexInverted
)) return FALSE
;
1822 copy
= CFCharacterSetCreateMutableCopy(NULL
, theSet
);
1823 CFCharacterSetIntersect(copy
, theOtherSet
);
1824 result
= __CFCharacterSetEqual(copy
, theOtherSet
);
1830 Boolean
CFCharacterSetHasMemberInPlane(CFCharacterSetRef theSet
, CFIndex thePlane
) {
1831 Boolean isInverted
= __CFCSetIsInverted(theSet
);
1833 CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID
, Boolean
, theSet
, "hasMemberInPlane:", thePlane
);
1835 if (__CFCSetIsEmpty(theSet
)) {
1836 return (isInverted
? TRUE
: FALSE
);
1837 } else if (__CFCSetIsBuiltin(theSet
)) {
1838 CFCharacterSetPredefinedSet type
= __CFCSetBuiltinType(theSet
);
1840 if (type
== kCFCharacterSetControl
) {
1841 if (isInverted
|| (thePlane
== 14)) {
1842 return TRUE
; // There is no plane that covers all values || Plane 14 has language tags
1844 return (CFUniCharGetBitmapPtrForPlane(type
, thePlane
) ? TRUE
: FALSE
);
1846 } else if (type
< kCFCharacterSetDecimalDigit
) {
1847 return (thePlane
&& !isInverted
? FALSE
: TRUE
);
1848 } else if (__CFCSetBuiltinType(theSet
) == kCFCharacterSetIllegal
) {
1849 return (isInverted
? (thePlane
< 3 || thePlane
> 13 ? TRUE
: FALSE
) : TRUE
); // This is according to Unicode 3.1
1852 return TRUE
; // There is no plane that covers all values
1854 return (CFUniCharGetBitmapPtrForPlane(type
, thePlane
) ? TRUE
: FALSE
);
1857 } else if (__CFCSetIsRange(theSet
)) {
1858 UTF32Char firstChar
= __CFCSetRangeFirstChar(theSet
);
1859 UTF32Char lastChar
= (firstChar
+ __CFCSetRangeLength(theSet
) - 1);
1860 CFIndex firstPlane
= firstChar
>> 16;
1861 CFIndex lastPlane
= lastChar
>> 16;
1864 if (thePlane
< firstPlane
|| thePlane
> lastPlane
) {
1866 } else if (thePlane
> firstPlane
&& thePlane
< lastPlane
) {
1869 firstChar
&= 0xFFFF;
1871 if (thePlane
== firstPlane
) {
1872 return (firstChar
|| (firstPlane
== lastPlane
&& lastChar
!= 0xFFFF) ? TRUE
: FALSE
);
1874 return (lastChar
!= 0xFFFF || (firstPlane
== lastPlane
&& firstChar
) ? TRUE
: FALSE
);
1878 return (thePlane
< firstPlane
|| thePlane
> lastPlane
? FALSE
: TRUE
);
1881 if (thePlane
== 0) {
1882 switch (__CFCSetClassType(theSet
)) {
1883 case __kCFCharSetClassString
: if (!__CFCSetStringLength(theSet
)) return isInverted
; break;
1884 case __kCFCharSetClassCompactBitmap
: return (__CFCSetCompactBitmapBits(theSet
) ? TRUE
: FALSE
); break;
1885 case __kCFCharSetClassBitmap
: return (__CFCSetBitmapBits(theSet
) ? TRUE
: FALSE
); break;
1889 CFCharacterSetRef annex
= __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet
, thePlane
);
1891 if (__CFCSetIsRange(annex
)) {
1892 return (__CFCSetAnnexIsInverted(theSet
) && (__CFCSetRangeFirstChar(annex
) == 0) && (__CFCSetRangeLength(annex
) == 0x10000) ? FALSE
: TRUE
);
1893 } else if (__CFCSetIsBitmap(annex
)) {
1894 return (__CFCSetAnnexIsInverted(theSet
) && __CFCSetIsEqualBitmap((const UInt32
*)__CFCSetBitmapBits(annex
), (const UInt32
*)-1) ? FALSE
: TRUE
);
1896 uint8_t bitsBuf
[__kCFBitmapSize
];
1897 __CFCSetGetBitmap(annex
, bitsBuf
);
1898 return (__CFCSetAnnexIsInverted(theSet
) && __CFCSetIsEqualBitmap((const UInt32
*)bitsBuf
, (const UInt32
*)-1) ? FALSE
: TRUE
);
1901 return __CFCSetAnnexIsInverted(theSet
);
1910 CFDataRef
CFCharacterSetCreateBitmapRepresentation(CFAllocatorRef alloc
, CFCharacterSetRef theSet
) {
1911 CFMutableDataRef data
;
1912 int numNonBMPPlanes
= 0;
1913 int planeIndices
[MAX_ANNEX_PLANE
];
1916 bool isAnnexInverted
;
1918 CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID
, CFDataRef
, theSet
, "_retainedBitmapRepresentation");
1920 __CFGenericValidateType(theSet
, __kCFCharacterSetTypeID
);
1922 isAnnexInverted
= __CFCSetAnnexIsInverted(theSet
);
1924 if (__CFCSetHasNonBMPPlane(theSet
)) {
1925 for (idx
= 1;idx
<= MAX_ANNEX_PLANE
;idx
++) {
1926 if (isAnnexInverted
|| __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet
, idx
)) {
1927 planeIndices
[numNonBMPPlanes
++] = idx
;
1930 } else if (__CFCSetIsBuiltin(theSet
)) {
1931 numNonBMPPlanes
= (__CFCSetIsInverted(theSet
) ? MAX_ANNEX_PLANE
: CFUniCharGetNumberOfPlanes(__CFCSetBuiltinType(theSet
)) - 1);
1932 } else if (__CFCSetIsRange(theSet
)) {
1933 UInt32 firstChar
= __CFCSetRangeFirstChar(theSet
);
1934 UInt32 lastChar
= __CFCSetRangeFirstChar(theSet
) + __CFCSetRangeLength(theSet
) - 1;
1935 int firstPlane
= (firstChar
>> 16);
1936 int lastPlane
= (lastChar
>> 16);
1937 bool isInverted
= __CFCSetIsInverted(theSet
);
1939 if (lastPlane
> 0) {
1940 if (firstPlane
== 0) {
1942 firstChar
= 0x10000;
1944 numNonBMPPlanes
= (lastPlane
- firstPlane
) + 1;
1946 numNonBMPPlanes
= MAX_ANNEX_PLANE
- numNonBMPPlanes
;
1947 if (firstPlane
== lastPlane
) {
1948 if (((firstChar
& 0xFFFF) > 0) || ((lastChar
& 0xFFFF) < 0xFFFF)) ++numNonBMPPlanes
;
1950 if ((firstChar
& 0xFFFF) > 0) ++numNonBMPPlanes
;
1951 if ((lastChar
& 0xFFFF) < 0xFFFF) ++numNonBMPPlanes
;
1954 } else if (isInverted
) {
1955 numNonBMPPlanes
= MAX_ANNEX_PLANE
;
1957 } else if (isAnnexInverted
) {
1958 numNonBMPPlanes
= MAX_ANNEX_PLANE
;
1961 length
= __kCFBitmapSize
+ ((__kCFBitmapSize
+ 1) * numNonBMPPlanes
);
1962 data
= CFDataCreateMutable(alloc
, length
);
1963 CFDataSetLength(data
, length
);
1964 __CFCSetGetBitmap(theSet
, CFDataGetMutableBytePtr(data
));
1966 if (numNonBMPPlanes
> 0) {
1967 char *bytes
= CFDataGetMutableBytePtr(data
) + __kCFBitmapSize
;
1969 if (__CFCSetHasNonBMPPlane(theSet
)) {
1970 CFCharacterSetRef subset
;
1972 for (idx
= 0;idx
< numNonBMPPlanes
;idx
++) {
1973 *(bytes
++) = planeIndices
[idx
];
1974 if ((subset
= __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet
, planeIndices
[idx
])) == NULL
) {
1975 __CFCSetBitmapFastFillWithValue((UInt32
*)bytes
, (isAnnexInverted
? 0xFF : 0));
1977 __CFCSetGetBitmap(subset
, bytes
);
1978 if (isAnnexInverted
) {
1979 uint32_t count
= __kCFBitmapSize
/ sizeof(uint32_t);
1980 uint32_t *bits
= (uint32_t *)bytes
;
1982 while (count
-- > 0) {
1988 bytes
+= __kCFBitmapSize
;
1990 } else if (__CFCSetIsBuiltin(theSet
)) {
1992 Boolean isInverted
= __CFCSetIsInverted(theSet
);
1994 for (idx
= 0;idx
< numNonBMPPlanes
;idx
++) {
1995 if ((result
= CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(theSet
), idx
+ 1, bytes
+ 1, isInverted
)) == kCFUniCharBitmapEmpty
) continue;
1996 *(bytes
++) = idx
+ 1;
1997 if (result
== kCFUniCharBitmapAll
) {
1998 CFIndex bitmapLength
= __kCFBitmapSize
;
1999 while (bitmapLength
-- > 0) *(bytes
++) = (uint8_t)0xFF;
2001 bytes
+= __kCFBitmapSize
;
2004 if (bytes
- (const char *)CFDataGetBytePtr(data
) < length
) CFDataSetLength(data
, bytes
- (const char *)CFDataGetBytePtr(data
));
2005 } else if (__CFCSetIsRange(theSet
)) {
2006 UInt32 firstChar
= __CFCSetRangeFirstChar(theSet
);
2007 UInt32 lastChar
= __CFCSetRangeFirstChar(theSet
) + __CFCSetRangeLength(theSet
) - 1;
2008 int firstPlane
= (firstChar
>> 16);
2009 int lastPlane
= (lastChar
>> 16);
2011 if (firstPlane
== 0) {
2013 firstChar
= 0x10000;
2015 if (__CFCSetIsInverted(theSet
)) {
2016 // Mask out the plane byte
2017 firstChar
&= 0xFFFF;
2020 for (idx
= 1;idx
< firstPlane
;idx
++) { // Fill up until the first plane
2022 __CFCSetBitmapFastFillWithValue((UInt32
*)bytes
, 0xFF);
2023 bytes
+= __kCFBitmapSize
;
2025 if (firstPlane
== lastPlane
) {
2026 if ((firstChar
> 0) || (lastChar
< 0xFFFF)) {
2028 __CFCSetBitmapFastFillWithValue((UInt32
*)bytes
, 0xFF);
2029 __CFCSetBitmapRemoveCharactersInRange(bytes
, firstChar
, lastChar
);
2030 bytes
+= __kCFBitmapSize
;
2032 } else if (firstPlane
< lastPlane
) {
2033 if (firstChar
> 0) {
2035 __CFCSetBitmapFastFillWithValue((UInt32
*)bytes
, 0);
2036 __CFCSetBitmapAddCharactersInRange(bytes
, 0, firstChar
- 1);
2037 bytes
+= __kCFBitmapSize
;
2039 if (lastChar
< 0xFFFF) {
2041 __CFCSetBitmapFastFillWithValue((UInt32
*)bytes
, 0);
2042 __CFCSetBitmapAddCharactersInRange(bytes
, lastChar
, 0xFFFF);
2043 bytes
+= __kCFBitmapSize
;
2046 for (idx
= lastPlane
+ 1;idx
<= MAX_ANNEX_PLANE
;idx
++) {
2048 __CFCSetBitmapFastFillWithValue((UInt32
*)bytes
, 0xFF);
2049 bytes
+= __kCFBitmapSize
;
2052 for (idx
= firstPlane
;idx
<= lastPlane
;idx
++) {
2054 __CFCSetBitmapAddCharactersInRange(bytes
, (idx
== firstPlane
? firstChar
: 0), (idx
== lastPlane
? lastChar
: 0xFFFF));
2055 bytes
+= __kCFBitmapSize
;
2058 } else if (isAnnexInverted
) {
2059 for (idx
= 1;idx
<= MAX_ANNEX_PLANE
;idx
++) {
2061 __CFCSetBitmapFastFillWithValue((UInt32
*)bytes
, 0xFF);
2062 bytes
+= __kCFBitmapSize
;
2070 /*** MutableCharacterSet functions ***/
2071 void CFCharacterSetAddCharactersInRange(CFMutableCharacterSetRef theSet
, CFRange theRange
) {
2072 CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID
, void, theSet
, "addCharactersInRange:", theRange
);
2074 __CFCSetValidateTypeAndMutability(theSet
, __PRETTY_FUNCTION__
);
2075 __CFCSetValidateRange(theRange
, __PRETTY_FUNCTION__
);
2077 if (!theRange
.length
|| (__CFCSetIsInverted(theSet
) && __CFCSetIsEmpty(theSet
))) return; // Inverted && empty set contains all char
2079 if (!__CFCSetIsInverted(theSet
)) {
2080 if (__CFCSetIsEmpty(theSet
)) {
2081 __CFCSetPutClassType(theSet
, __kCFCharSetClassRange
);
2082 __CFCSetPutRangeFirstChar(theSet
, theRange
.location
);
2083 __CFCSetPutRangeLength(theSet
, theRange
.length
);
2084 __CFCSetPutHasHashValue(theSet
, false);
2086 } else if (__CFCSetIsRange(theSet
)) {
2087 CFIndex firstChar
= __CFCSetRangeFirstChar(theSet
);
2088 CFIndex length
= __CFCSetRangeLength(theSet
);
2090 if (firstChar
== theRange
.location
) {
2091 __CFCSetPutRangeLength(theSet
, __CFMin(length
, theRange
.length
));
2092 __CFCSetPutHasHashValue(theSet
, false);
2094 } else if (firstChar
< theRange
.location
&& theRange
.location
<= firstChar
+ length
) {
2095 if (firstChar
+ length
< theRange
.location
+ theRange
.length
) __CFCSetPutRangeLength(theSet
, theRange
.length
+ (theRange
.location
- firstChar
));
2096 __CFCSetPutHasHashValue(theSet
, false);
2098 } else if (theRange
.location
< firstChar
&& firstChar
<= theRange
.location
+ theRange
.length
) {
2099 __CFCSetPutRangeFirstChar(theSet
, theRange
.location
);
2100 __CFCSetPutRangeLength(theSet
, length
+ (firstChar
- theRange
.location
));
2101 __CFCSetPutHasHashValue(theSet
, false);
2104 } else if (__CFCSetIsString(theSet
) && __CFCSetStringLength(theSet
) + theRange
.length
< __kCFStringCharSetMax
) {
2106 if (!__CFCSetStringBuffer(theSet
))
2107 __CFCSetPutStringBuffer(theSet
, CFAllocatorAllocate(CFGetAllocator(theSet
), __kCFStringCharSetMax
* sizeof(UniChar
), AUTO_MEMORY_UNSCANNED
));
2108 buffer
= __CFCSetStringBuffer(theSet
) + __CFCSetStringLength(theSet
);
2109 __CFCSetPutStringLength(theSet
, __CFCSetStringLength(theSet
) + theRange
.length
);
2110 while (theRange
.length
--) *buffer
++ = theRange
.location
++;
2111 qsort(__CFCSetStringBuffer(theSet
), __CFCSetStringLength(theSet
), sizeof(UniChar
), chcompar
);
2112 __CFCSetPutHasHashValue(theSet
, false);
2117 // OK, I have to be a bitmap
2118 __CFCSetMakeBitmap(theSet
);
2119 __CFCSetAddNonBMPPlanesInRange(theSet
, theRange
);
2120 if (theRange
.location
< 0x10000) { // theRange is in BMP
2121 if (theRange
.location
+ theRange
.length
>= NUMCHARACTERS
) theRange
.length
= NUMCHARACTERS
- theRange
.location
;
2122 __CFCSetBitmapAddCharactersInRange(__CFCSetBitmapBits(theSet
), theRange
.location
, theRange
.location
+ theRange
.length
- 1);
2124 __CFCSetPutHasHashValue(theSet
, false);
2126 if (__CFCheckForExapendedSet
) __CFCheckForExpandedSet(theSet
);
2129 void CFCharacterSetRemoveCharactersInRange(CFMutableCharacterSetRef theSet
, CFRange theRange
) {
2130 CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID
, void, theSet
, "removeCharactersInRange:", theRange
);
2132 __CFCSetValidateTypeAndMutability(theSet
, __PRETTY_FUNCTION__
);
2133 __CFCSetValidateRange(theRange
, __PRETTY_FUNCTION__
);
2135 if (!theRange
.length
|| (!__CFCSetIsInverted(theSet
) && __CFCSetIsEmpty(theSet
))) return; // empty set
2137 if (__CFCSetIsInverted(theSet
)) {
2138 if (__CFCSetIsEmpty(theSet
)) {
2139 __CFCSetPutClassType(theSet
, __kCFCharSetClassRange
);
2140 __CFCSetPutRangeFirstChar(theSet
, theRange
.location
);
2141 __CFCSetPutRangeLength(theSet
, theRange
.length
);
2142 __CFCSetPutHasHashValue(theSet
, false);
2144 } else if (__CFCSetIsRange(theSet
)) {
2145 CFIndex firstChar
= __CFCSetRangeFirstChar(theSet
);
2146 CFIndex length
= __CFCSetRangeLength(theSet
);
2148 if (firstChar
== theRange
.location
) {
2149 __CFCSetPutRangeLength(theSet
, __CFMin(length
, theRange
.length
));
2150 __CFCSetPutHasHashValue(theSet
, false);
2152 } else if (firstChar
< theRange
.location
&& theRange
.location
<= firstChar
+ length
) {
2153 if (firstChar
+ length
< theRange
.location
+ theRange
.length
) __CFCSetPutRangeLength(theSet
, theRange
.length
+ (theRange
.location
- firstChar
));
2154 __CFCSetPutHasHashValue(theSet
, false);
2156 } else if (theRange
.location
< firstChar
&& firstChar
<= theRange
.location
+ theRange
.length
) {
2157 __CFCSetPutRangeFirstChar(theSet
, theRange
.location
);
2158 __CFCSetPutRangeLength(theSet
, length
+ (firstChar
- theRange
.location
));
2159 __CFCSetPutHasHashValue(theSet
, false);
2162 } else if (__CFCSetIsString(theSet
) && __CFCSetStringLength(theSet
) + theRange
.length
< __kCFStringCharSetMax
) {
2164 if (!__CFCSetStringBuffer(theSet
))
2165 __CFCSetPutStringBuffer(theSet
, CFAllocatorAllocate(CFGetAllocator(theSet
), __kCFStringCharSetMax
* sizeof(UniChar
), AUTO_MEMORY_UNSCANNED
));
2166 buffer
= __CFCSetStringBuffer(theSet
) + __CFCSetStringLength(theSet
);
2167 __CFCSetPutStringLength(theSet
, __CFCSetStringLength(theSet
) + theRange
.length
);
2168 while (theRange
.length
--) *buffer
++ = theRange
.location
++;
2169 qsort(__CFCSetStringBuffer(theSet
), __CFCSetStringLength(theSet
), sizeof(UniChar
), chcompar
);
2170 __CFCSetPutHasHashValue(theSet
, false);
2175 // OK, I have to be a bitmap
2176 __CFCSetMakeBitmap(theSet
);
2177 __CFCSetRemoveNonBMPPlanesInRange(theSet
, theRange
);
2178 if (theRange
.location
< 0x10000) { // theRange is in BMP
2179 if (theRange
.location
+ theRange
.length
> NUMCHARACTERS
) theRange
.length
= NUMCHARACTERS
- theRange
.location
;
2180 if (theRange
.location
== 0 && theRange
.length
== NUMCHARACTERS
) { // Remove all
2181 CFAllocatorDeallocate(CFGetAllocator(theSet
), __CFCSetBitmapBits(theSet
));
2182 __CFCSetPutBitmapBits(theSet
, NULL
);
2184 __CFCSetBitmapRemoveCharactersInRange(__CFCSetBitmapBits(theSet
), theRange
.location
, theRange
.location
+ theRange
.length
- 1);
2188 __CFCSetPutHasHashValue(theSet
, false);
2189 if (__CFCheckForExapendedSet
) __CFCheckForExpandedSet(theSet
);
2192 void CFCharacterSetAddCharactersInString(CFMutableCharacterSetRef theSet
, CFStringRef theString
) {
2193 const UniChar
*buffer
;
2196 CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID
, void, theSet
, "addCharactersInString:", theString
);
2198 __CFCSetValidateTypeAndMutability(theSet
, __PRETTY_FUNCTION__
);
2200 if ((__CFCSetIsEmpty(theSet
) && __CFCSetIsInverted(theSet
)) || !(length
= CFStringGetLength(theString
))) return;
2202 if (!__CFCSetIsInverted(theSet
)) {
2203 CFIndex newLength
= length
+ (__CFCSetIsEmpty(theSet
) ? 0 : (__CFCSetIsString(theSet
) ? __CFCSetStringLength(theSet
) : __kCFStringCharSetMax
));
2205 if (newLength
< __kCFStringCharSetMax
) {
2206 if (__CFCSetIsEmpty(theSet
)) __CFCSetPutStringLength(theSet
, 0); // Make sure to reset this
2208 if (!__CFCSetStringBuffer(theSet
))
2209 __CFCSetPutStringBuffer(theSet
, CFAllocatorAllocate(CFGetAllocator(theSet
), __kCFStringCharSetMax
* sizeof(UniChar
), AUTO_MEMORY_UNSCANNED
));
2210 buffer
= __CFCSetStringBuffer(theSet
) + __CFCSetStringLength(theSet
);
2212 __CFCSetPutClassType(theSet
, __kCFCharSetClassString
);
2213 __CFCSetPutStringLength(theSet
, newLength
);
2214 CFStringGetCharacters(theString
, CFRangeMake(0, length
), (UniChar
*)buffer
);
2215 qsort(__CFCSetStringBuffer(theSet
), newLength
, sizeof(UniChar
), chcompar
);
2216 __CFCSetPutHasHashValue(theSet
, false);
2221 // OK, I have to be a bitmap
2222 __CFCSetMakeBitmap(theSet
);
2223 if ((buffer
= CFStringGetCharactersPtr(theString
))) {
2224 while (length
--) __CFCSetBitmapAddCharacter(__CFCSetBitmapBits(theSet
), *buffer
++);
2226 CFStringInlineBuffer inlineBuffer
;
2229 CFStringInitInlineBuffer(theString
, &inlineBuffer
, CFRangeMake(0, length
));
2230 for (idx
= 0;idx
< length
;idx
++) __CFCSetBitmapAddCharacter(__CFCSetBitmapBits(theSet
), __CFStringGetCharacterFromInlineBufferQuick(&inlineBuffer
, idx
));
2232 __CFCSetPutHasHashValue(theSet
, false);
2233 if (__CFCheckForExapendedSet
) __CFCheckForExpandedSet(theSet
);
2236 void CFCharacterSetRemoveCharactersInString(CFMutableCharacterSetRef theSet
, CFStringRef theString
) {
2237 const UniChar
*buffer
;
2240 CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID
, void, theSet
, "removeCharactersInString:", theString
);
2242 __CFCSetValidateTypeAndMutability(theSet
, __PRETTY_FUNCTION__
);
2244 if ((__CFCSetIsEmpty(theSet
) && !__CFCSetIsInverted(theSet
)) || !(length
= CFStringGetLength(theString
))) return;
2246 if (__CFCSetIsInverted(theSet
)) {
2247 CFIndex newLength
= length
+ (__CFCSetIsEmpty(theSet
) ? 0 : (__CFCSetIsString(theSet
) ? __CFCSetStringLength(theSet
) : __kCFStringCharSetMax
));
2249 if (newLength
< __kCFStringCharSetMax
) {
2250 if (__CFCSetIsEmpty(theSet
)) __CFCSetPutStringLength(theSet
, 0); // Make sure to reset this
2252 if (!__CFCSetStringBuffer(theSet
))
2253 __CFCSetPutStringBuffer(theSet
, CFAllocatorAllocate(CFGetAllocator(theSet
), __kCFStringCharSetMax
* sizeof(UniChar
), AUTO_MEMORY_UNSCANNED
));
2254 buffer
= __CFCSetStringBuffer(theSet
) + __CFCSetStringLength(theSet
);
2256 __CFCSetPutClassType(theSet
, __kCFCharSetClassString
);
2257 __CFCSetPutStringLength(theSet
, newLength
);
2258 CFStringGetCharacters(theString
, CFRangeMake(0, length
), (UniChar
*)buffer
);
2259 qsort(__CFCSetStringBuffer(theSet
), newLength
, sizeof(UniChar
), chcompar
);
2260 __CFCSetPutHasHashValue(theSet
, false);
2265 // OK, I have to be a bitmap
2266 __CFCSetMakeBitmap(theSet
);
2267 if ((buffer
= CFStringGetCharactersPtr(theString
))) {
2268 while (length
--) __CFCSetBitmapRemoveCharacter(__CFCSetBitmapBits(theSet
), *buffer
++);
2270 CFStringInlineBuffer inlineBuffer
;
2273 CFStringInitInlineBuffer(theString
, &inlineBuffer
, CFRangeMake(0, length
));
2274 for (idx
= 0;idx
< length
;idx
++) __CFCSetBitmapRemoveCharacter(__CFCSetBitmapBits(theSet
), __CFStringGetCharacterFromInlineBufferQuick(&inlineBuffer
, idx
));
2276 __CFCSetPutHasHashValue(theSet
, false);
2277 if (__CFCheckForExapendedSet
) __CFCheckForExpandedSet(theSet
);
2280 void CFCharacterSetUnion(CFMutableCharacterSetRef theSet
, CFCharacterSetRef theOtherSet
) {
2281 CFCharacterSetRef expandedSet
= NULL
;
2283 CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID
, void, theSet
, "formUnionWithCharacterSet:", theOtherSet
);
2285 __CFCSetValidateTypeAndMutability(theSet
, __PRETTY_FUNCTION__
);
2287 if (__CFCSetIsEmpty(theSet
) && __CFCSetIsInverted(theSet
)) return; // Inverted empty set contains all char
2289 if (!CF_IS_OBJC(__kCFCharacterSetTypeID
, theOtherSet
) || (expandedSet
= __CFCharacterSetGetExpandedSetForNSCharacterSet(theOtherSet
))) { // Really CF, we can do some trick here
2290 if (expandedSet
) theOtherSet
= expandedSet
;
2292 if (__CFCSetIsEmpty(theOtherSet
)) {
2293 if (__CFCSetIsInverted(theOtherSet
)) {
2294 if (__CFCSetIsString(theSet
) && __CFCSetStringBuffer(theSet
)) {
2295 CFAllocatorDeallocate(CFGetAllocator(theSet
), __CFCSetStringBuffer(theSet
));
2296 } else if (__CFCSetIsBitmap(theSet
) && __CFCSetBitmapBits(theSet
)) {
2297 CFAllocatorDeallocate(CFGetAllocator(theSet
), __CFCSetBitmapBits(theSet
));
2298 } else if (__CFCSetIsCompactBitmap(theSet
) && __CFCSetCompactBitmapBits(theSet
)) {
2299 CFAllocatorDeallocate(CFGetAllocator(theSet
), __CFCSetCompactBitmapBits(theSet
));
2301 __CFCSetPutClassType(theSet
, __kCFCharSetClassRange
);
2302 __CFCSetPutRangeLength(theSet
, 0);
2303 __CFCSetPutIsInverted(theSet
, true);
2304 __CFCSetPutHasHashValue(theSet
, false);
2305 __CFCSetDeallocateAnnexPlane(theSet
);
2307 return; // Nothing to do here
2311 if (__CFCSetIsBuiltin(theOtherSet
) && __CFCSetIsEmpty(theSet
)) { // theSet can be builtin set
2312 __CFCSetPutClassType(theSet
, __kCFCharSetClassBuiltin
);
2313 __CFCSetPutBuiltinType(theSet
, __CFCSetBuiltinType(theOtherSet
));
2314 __CFCSetPutHasHashValue(theSet
, false);
2315 } else if (__CFCSetIsRange(theOtherSet
)) {
2316 if (__CFCSetIsInverted(theOtherSet
)) {
2317 UTF32Char firstChar
= __CFCSetRangeFirstChar(theOtherSet
);
2318 CFIndex length
= __CFCSetRangeLength(theOtherSet
);
2320 if (firstChar
> 0) CFCharacterSetAddCharactersInRange(theSet
, CFRangeMake(0, firstChar
));
2321 firstChar
+= length
;
2322 length
= 0x110000 - firstChar
;
2323 CFCharacterSetAddCharactersInRange(theSet
, CFRangeMake(firstChar
, length
));
2325 CFCharacterSetAddCharactersInRange(theSet
, CFRangeMake(__CFCSetRangeFirstChar(theOtherSet
), __CFCSetRangeLength(theOtherSet
)));
2327 } else if (__CFCSetIsString(theOtherSet
)) {
2328 CFStringRef string
= CFStringCreateWithCharactersNoCopy(CFGetAllocator(theSet
), __CFCSetStringBuffer(theOtherSet
), __CFCSetStringLength(theOtherSet
), kCFAllocatorNull
);
2329 CFCharacterSetAddCharactersInString(theSet
, string
);
2332 __CFCSetMakeBitmap(theSet
);
2333 if (__CFCSetIsBitmap(theOtherSet
)) {
2334 UInt32
*bitmap1
= (UInt32
*)__CFCSetBitmapBits(theSet
);
2335 UInt32
*bitmap2
= (UInt32
*)__CFCSetBitmapBits(theOtherSet
);
2336 CFIndex length
= __kCFBitmapSize
/ sizeof(UInt32
);
2337 while (length
--) *bitmap1
++ |= *bitmap2
++;
2339 UInt32
*bitmap1
= (UInt32
*)__CFCSetBitmapBits(theSet
);
2341 CFIndex length
= __kCFBitmapSize
/ sizeof(UInt32
);
2342 uint8_t bitmapBuffer
[__kCFBitmapSize
];
2343 __CFCSetGetBitmap(theOtherSet
, bitmapBuffer
);
2344 bitmap2
= (UInt32
*)bitmapBuffer
;
2345 while (length
--) *bitmap1
++ |= *bitmap2
++;
2347 __CFCSetPutHasHashValue(theSet
, false);
2349 if (__CFCSetHasNonBMPPlane(theOtherSet
)) {
2350 CFMutableCharacterSetRef otherSetPlane
;
2353 for (idx
= 1;idx
<= MAX_ANNEX_PLANE
;idx
++) {
2354 if ((otherSetPlane
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theOtherSet
, idx
))) {
2355 CFCharacterSetUnion((CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSet(theSet
, idx
), otherSetPlane
);
2358 } else if (__CFCSetIsBuiltin(theOtherSet
)) {
2359 CFMutableCharacterSetRef annexPlane
;
2360 uint8_t bitmapBuffer
[__kCFBitmapSize
];
2363 Boolean isOtherAnnexPlaneInverted
= __CFCSetAnnexIsInverted(theOtherSet
);
2368 for (planeIndex
= 1;planeIndex
<= MAX_ANNEX_PLANE
;planeIndex
++) {
2369 result
= CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(theOtherSet
), planeIndex
, bitmapBuffer
, isOtherAnnexPlaneInverted
);
2370 if (result
!= kCFUniCharBitmapEmpty
) {
2371 annexPlane
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSet(theSet
, planeIndex
);
2372 if (result
== kCFUniCharBitmapAll
) {
2373 CFCharacterSetAddCharactersInRange(annexPlane
, CFRangeMake(0x0000, 0x10000));
2375 __CFCSetMakeBitmap(annexPlane
);
2376 bitmap1
= (UInt32
*)__CFCSetBitmapBits(annexPlane
);
2377 length
= __kCFBitmapSize
/ sizeof(UInt32
);
2378 bitmap2
= (UInt32
*)bitmapBuffer
;
2379 while (length
--) *bitmap1
++ |= *bitmap2
++;
2384 if (__CFCheckForExapendedSet
) __CFCheckForExpandedSet(theSet
);
2385 } else { // It's NSCharacterSet
2386 CFDataRef bitmapRep
= CFCharacterSetCreateBitmapRepresentation(NULL
, theOtherSet
);
2387 const UInt32
*bitmap2
= (bitmapRep
&& CFDataGetLength(bitmapRep
) ? (const UInt32
*)CFDataGetBytePtr(bitmapRep
) : NULL
);
2390 CFIndex length
= __kCFBitmapSize
/ sizeof(UInt32
);
2391 __CFCSetMakeBitmap(theSet
);
2392 bitmap1
= (UInt32
*)__CFCSetBitmapBits(theSet
);
2393 while (length
--) *bitmap1
++ |= *bitmap2
++;
2394 __CFCSetPutHasHashValue(theSet
, false);
2396 CFRelease(bitmapRep
);
2400 void CFCharacterSetIntersect(CFMutableCharacterSetRef theSet
, CFCharacterSetRef theOtherSet
) {
2401 CFCharacterSetRef expandedSet
= NULL
;
2403 CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID
, void, theSet
, "formIntersectionWithCharacterSet:", theOtherSet
);
2405 __CFCSetValidateTypeAndMutability(theSet
, __PRETTY_FUNCTION__
);
2407 if (__CFCSetIsEmpty(theSet
) && !__CFCSetIsInverted(theSet
)) return; // empty set
2409 if (!CF_IS_OBJC(__kCFCharacterSetTypeID
, theOtherSet
) || (expandedSet
= __CFCharacterSetGetExpandedSetForNSCharacterSet(theOtherSet
))) { // Really CF, we can do some trick here
2410 if (expandedSet
) theOtherSet
= expandedSet
;
2412 if (__CFCSetIsEmpty(theOtherSet
)) {
2413 if (!__CFCSetIsInverted(theOtherSet
)) {
2414 if (__CFCSetIsString(theSet
) && __CFCSetStringBuffer(theSet
)) {
2415 CFAllocatorDeallocate(CFGetAllocator(theSet
), __CFCSetStringBuffer(theSet
));
2416 } else if (__CFCSetIsBitmap(theSet
) && __CFCSetBitmapBits(theSet
)) {
2417 CFAllocatorDeallocate(CFGetAllocator(theSet
), __CFCSetBitmapBits(theSet
));
2418 } else if (__CFCSetIsCompactBitmap(theSet
) && __CFCSetCompactBitmapBits(theSet
)) {
2419 CFAllocatorDeallocate(CFGetAllocator(theSet
), __CFCSetCompactBitmapBits(theSet
));
2421 __CFCSetPutClassType(theSet
, __kCFCharSetClassBitmap
);
2422 __CFCSetPutBitmapBits(theSet
, NULL
);
2423 __CFCSetPutIsInverted(theSet
, false);
2424 theSet
->_hashValue
= 0;
2425 __CFCSetPutHasHashValue(theSet
, true);
2426 __CFCSetDeallocateAnnexPlane(theSet
);
2428 } else if (__CFCSetIsEmpty(theSet
)) { // non inverted empty set contains all character
2429 __CFCSetPutClassType(theSet
, __CFCSetClassType(theOtherSet
));
2430 __CFCSetPutHasHashValue(theSet
, __CFCSetHasHashValue(theOtherSet
));
2431 __CFCSetPutIsInverted(theSet
, __CFCSetIsInverted(theOtherSet
));
2432 theSet
->_hashValue
= theOtherSet
->_hashValue
;
2433 if (__CFCSetHasNonBMPPlane(theOtherSet
)) {
2434 CFMutableCharacterSetRef otherSetPlane
;
2436 for (idx
= 1;idx
<= MAX_ANNEX_PLANE
;idx
++) {
2437 if ((otherSetPlane
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theOtherSet
, idx
))) {
2438 otherSetPlane
= (CFMutableCharacterSetRef
)CFCharacterSetCreateMutableCopy(CFGetAllocator(theSet
), otherSetPlane
);
2439 __CFCSetPutCharacterSetToAnnexPlane(theSet
, otherSetPlane
, idx
);
2440 CFRelease(otherSetPlane
);
2443 __CFCSetAnnexSetIsInverted(theSet
, __CFCSetAnnexIsInverted(theOtherSet
));
2446 switch (__CFCSetClassType(theOtherSet
)) {
2447 case __kCFCharSetClassBuiltin
:
2448 __CFCSetPutBuiltinType(theSet
, __CFCSetBuiltinType(theOtherSet
));
2451 case __kCFCharSetClassRange
:
2452 __CFCSetPutRangeFirstChar(theSet
, __CFCSetRangeFirstChar(theOtherSet
));
2453 __CFCSetPutRangeLength(theSet
, __CFCSetRangeLength(theOtherSet
));
2456 case __kCFCharSetClassString
:
2457 __CFCSetPutStringLength(theSet
, __CFCSetStringLength(theOtherSet
));
2458 if (!__CFCSetStringBuffer(theSet
))
2459 __CFCSetPutStringBuffer(theSet
, CFAllocatorAllocate(CFGetAllocator(theSet
), __kCFStringCharSetMax
* sizeof(UniChar
), AUTO_MEMORY_UNSCANNED
));
2460 memmove(__CFCSetStringBuffer(theSet
), __CFCSetStringBuffer(theOtherSet
), __CFCSetStringLength(theSet
) * sizeof(UniChar
));
2463 case __kCFCharSetClassBitmap
:
2464 __CFCSetPutBitmapBits(theSet
, CFAllocatorAllocate(CFGetAllocator(theSet
), sizeof(uint8_t) * __kCFBitmapSize
, AUTO_MEMORY_UNSCANNED
));
2465 memmove(__CFCSetBitmapBits(theSet
), __CFCSetBitmapBits(theOtherSet
), __kCFBitmapSize
);
2468 case __kCFCharSetClassCompactBitmap
: {
2469 const uint8_t *cBitmap
= __CFCSetCompactBitmapBits(theOtherSet
);
2471 uint32_t size
= __CFCSetGetCompactBitmapSize(cBitmap
);
2472 newBitmap
= (uint8_t *)CFAllocatorAllocate(CFGetAllocator(theSet
), sizeof(uint8_t) * size
, AUTO_MEMORY_UNSCANNED
);
2473 __CFCSetPutBitmapBits(theSet
, newBitmap
);
2474 memmove(newBitmap
, cBitmap
, size
);
2479 CFAssert1(0, __kCFLogAssertion
, "%s: Internal inconsistency error: unknown character set type", __PRETTY_FUNCTION__
); // We should never come here
2482 __CFCSetMakeBitmap(theSet
);
2483 if (__CFCSetIsBitmap(theOtherSet
)) {
2484 UInt32
*bitmap1
= (UInt32
*)__CFCSetBitmapBits(theSet
);
2485 UInt32
*bitmap2
= (UInt32
*)__CFCSetBitmapBits(theOtherSet
);
2486 CFIndex length
= __kCFBitmapSize
/ sizeof(UInt32
);
2487 while (length
--) *bitmap1
++ &= *bitmap2
++;
2489 UInt32
*bitmap1
= (UInt32
*)__CFCSetBitmapBits(theSet
);
2491 CFIndex length
= __kCFBitmapSize
/ sizeof(UInt32
);
2492 uint8_t bitmapBuffer
[__kCFBitmapSize
];
2493 __CFCSetGetBitmap(theOtherSet
, bitmapBuffer
);
2494 bitmap2
= (UInt32
*)bitmapBuffer
;
2495 while (length
--) *bitmap1
++ &= *bitmap2
++;
2497 __CFCSetPutHasHashValue(theSet
, false);
2498 if (__CFCSetHasNonBMPPlane(theOtherSet
)) {
2499 CFMutableCharacterSetRef annexPlane
;
2500 CFMutableCharacterSetRef otherSetPlane
;
2502 for (idx
= 1;idx
<= MAX_ANNEX_PLANE
;idx
++) {
2503 if ((otherSetPlane
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theOtherSet
, idx
))) {
2504 annexPlane
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSet(theSet
, idx
);
2505 CFCharacterSetIntersect(annexPlane
, otherSetPlane
);
2506 if (__CFCSetIsEmpty(annexPlane
) && !__CFCSetIsInverted(annexPlane
)) __CFCSetPutCharacterSetToAnnexPlane(theSet
, NULL
, idx
);
2507 } else if (__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet
, idx
)) {
2508 __CFCSetPutCharacterSetToAnnexPlane(theSet
, NULL
, idx
);
2511 if (!__CFCSetHasNonBMPPlane(theSet
)) __CFCSetDeallocateAnnexPlane(theSet
);
2512 } else if (__CFCSetIsBuiltin(theOtherSet
)) {
2513 CFMutableCharacterSetRef annexPlane
;
2514 uint8_t bitmapBuffer
[__kCFBitmapSize
];
2517 Boolean isOtherAnnexPlaneInverted
= __CFCSetAnnexIsInverted(theOtherSet
);
2522 for (planeIndex
= 1;planeIndex
<= MAX_ANNEX_PLANE
;planeIndex
++) {
2523 annexPlane
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet
, planeIndex
);
2525 result
= CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(theOtherSet
), planeIndex
, bitmapBuffer
, isOtherAnnexPlaneInverted
);
2526 if (result
== kCFUniCharBitmapEmpty
) {
2527 __CFCSetPutCharacterSetToAnnexPlane(theSet
, NULL
, planeIndex
);
2528 } else if (result
== kCFUniCharBitmapFilled
) {
2529 Boolean isEmpty
= true;
2531 __CFCSetMakeBitmap(annexPlane
);
2532 bitmap1
= (UInt32
*)__CFCSetBitmapBits(annexPlane
);
2533 length
= __kCFBitmapSize
/ sizeof(UInt32
);
2534 bitmap2
= (UInt32
*)bitmapBuffer
;
2537 if ((*bitmap1
++ &= *bitmap2
++)) isEmpty
= false;
2539 if (isEmpty
) __CFCSetPutCharacterSetToAnnexPlane(theSet
, NULL
, planeIndex
);
2543 if (!__CFCSetHasNonBMPPlane(theSet
)) __CFCSetDeallocateAnnexPlane(theSet
);
2544 } else if (__CFCSetIsRange(theOtherSet
)) {
2545 CFMutableCharacterSetRef tempOtherSet
= CFCharacterSetCreateMutable(CFGetAllocator(theSet
));
2546 CFMutableCharacterSetRef annexPlane
;
2547 CFMutableCharacterSetRef otherSetPlane
;
2550 __CFCSetAddNonBMPPlanesInRange(tempOtherSet
, CFRangeMake(__CFCSetRangeFirstChar(theOtherSet
), __CFCSetRangeLength(theOtherSet
)));
2552 for (idx
= 1;idx
<= MAX_ANNEX_PLANE
;idx
++) {
2553 if ((otherSetPlane
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(tempOtherSet
, idx
))) {
2554 annexPlane
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSet(theSet
, idx
);
2555 CFCharacterSetIntersect(annexPlane
, otherSetPlane
);
2556 if (__CFCSetIsEmpty(annexPlane
) && !__CFCSetIsInverted(annexPlane
)) __CFCSetPutCharacterSetToAnnexPlane(theSet
, NULL
, idx
);
2557 } else if (__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet
, idx
)) {
2558 __CFCSetPutCharacterSetToAnnexPlane(theSet
, NULL
, idx
);
2561 if (!__CFCSetHasNonBMPPlane(theSet
)) __CFCSetDeallocateAnnexPlane(theSet
);
2562 CFRelease(tempOtherSet
);
2563 } else if (__CFCSetHasNonBMPPlane(theSet
)) {
2564 __CFCSetDeallocateAnnexPlane(theSet
);
2567 if (__CFCheckForExapendedSet
) __CFCheckForExpandedSet(theSet
);
2568 } else { // It's NSCharacterSet
2569 CFDataRef bitmapRep
= CFCharacterSetCreateBitmapRepresentation(NULL
, theOtherSet
);
2570 const UInt32
*bitmap2
= (bitmapRep
&& CFDataGetLength(bitmapRep
) ? (const UInt32
*)CFDataGetBytePtr(bitmapRep
) : NULL
);
2573 CFIndex length
= __kCFBitmapSize
/ sizeof(UInt32
);
2574 __CFCSetMakeBitmap(theSet
);
2575 bitmap1
= (UInt32
*)__CFCSetBitmapBits(theSet
);
2576 while (length
--) *bitmap1
++ &= *bitmap2
++;
2577 __CFCSetPutHasHashValue(theSet
, false);
2579 CFRelease(bitmapRep
);
2583 void CFCharacterSetInvert(CFMutableCharacterSetRef theSet
) {
2585 CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID
, void, theSet
, "invert");
2587 __CFCSetValidateTypeAndMutability(theSet
, __PRETTY_FUNCTION__
);
2589 __CFCSetPutHasHashValue(theSet
, false);
2591 if (__CFCSetClassType(theSet
) == __kCFCharSetClassBitmap
) {
2593 CFIndex count
= __kCFBitmapSize
/ sizeof(UInt32
);
2594 UInt32
*bitmap
= (UInt32
*) __CFCSetBitmapBits(theSet
);
2596 if (NULL
== bitmap
) {
2597 bitmap
= (UInt32
*)CFAllocatorAllocate(CFGetAllocator(theSet
), __kCFBitmapSize
, AUTO_MEMORY_UNSCANNED
);
2598 __CFCSetPutBitmapBits(theSet
, (uint8_t *)bitmap
);
2599 for (idx
= 0;idx
< count
;idx
++) bitmap
[idx
] = 0xFFFFFFFF;
2601 for (idx
= 0;idx
< count
;idx
++) bitmap
[idx
] = ~(bitmap
[idx
]);
2603 __CFCSetAllocateAnnexForPlane(theSet
, 0); // We need to alloc annex to invert
2604 } else if (__CFCSetClassType(theSet
) == __kCFCharSetClassCompactBitmap
) {
2605 uint8_t *bitmap
= __CFCSetCompactBitmapBits(theSet
);
2610 for (idx
= 0;idx
< __kCFCompactBitmapNumPages
;idx
++) {
2611 value
= bitmap
[idx
];
2614 bitmap
[idx
] = UINT8_MAX
;
2615 } else if (value
== UINT8_MAX
) {
2618 length
+= __kCFCompactBitmapPageSize
;
2621 bitmap
+= __kCFCompactBitmapNumPages
;
2622 for (idx
= 0;idx
< length
;idx
++) bitmap
[idx
] = ~(bitmap
[idx
]);
2623 __CFCSetAllocateAnnexForPlane(theSet
, 0); // We need to alloc annex to invert
2625 __CFCSetPutIsInverted(theSet
, !__CFCSetIsInverted(theSet
));
2627 __CFCSetAnnexSetIsInverted(theSet
, !__CFCSetAnnexIsInverted(theSet
));
2630 void CFCharacterSetCompact(CFMutableCharacterSetRef theSet
) {
2631 if (__CFCSetIsBitmap(theSet
) && __CFCSetBitmapBits(theSet
)) __CFCSetMakeCompact(theSet
);
2632 if (__CFCSetHasNonBMPPlane(theSet
)) {
2633 CFMutableCharacterSetRef annex
;
2636 for (idx
= 1;idx
<= MAX_ANNEX_PLANE
;idx
++) {
2637 if ((annex
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet
, idx
)) && __CFCSetIsBitmap(annex
) && __CFCSetBitmapBits(annex
)) {
2638 __CFCSetMakeCompact(annex
);
2644 void CFCharacterSetFast(CFMutableCharacterSetRef theSet
) {
2645 if (__CFCSetIsCompactBitmap(theSet
) && __CFCSetCompactBitmapBits(theSet
)) __CFCSetMakeBitmap(theSet
);
2646 if (__CFCSetHasNonBMPPlane(theSet
)) {
2647 CFMutableCharacterSetRef annex
;
2650 for (idx
= 1;idx
<= MAX_ANNEX_PLANE
;idx
++) {
2651 if ((annex
= (CFMutableCharacterSetRef
)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet
, idx
)) && __CFCSetIsCompactBitmap(annex
) && __CFCSetCompactBitmapBits(annex
)) {
2652 __CFCSetMakeBitmap(annex
);
2658 /* Keyed-coding support
2660 CFCharacterSetKeyedCodingType
_CFCharacterSetGetKeyedCodingType(CFCharacterSetRef cset
) {
2661 switch (__CFCSetClassType(cset
)) {
2662 case __kCFCharSetClassBuiltin
: return ((__CFCSetBuiltinType(cset
) < kCFCharacterSetSymbol
) ? kCFCharacterSetKeyedCodingTypeBuiltin
: kCFCharacterSetKeyedCodingTypeBitmap
);
2663 case __kCFCharSetClassRange
: return kCFCharacterSetKeyedCodingTypeRange
;
2665 case __kCFCharSetClassString
: // We have to check if we have non-BMP here
2666 if (!__CFCSetHasNonBMPPlane(cset
)) return kCFCharacterSetKeyedCodingTypeString
; // BMP only. we can archive the string
2670 return kCFCharacterSetKeyedCodingTypeBitmap
;
2674 CFCharacterSetPredefinedSet
_CFCharacterSetGetKeyedCodingBuiltinType(CFCharacterSetRef cset
) { return __CFCSetBuiltinType(cset
); }
2675 CFRange
_CFCharacterSetGetKeyedCodingRange(CFCharacterSetRef cset
) { return CFRangeMake(__CFCSetRangeFirstChar(cset
), __CFCSetRangeLength(cset
)); }
2676 CFStringRef
_CFCharacterSetCreateKeyedCodingString(CFCharacterSetRef cset
) { return CFStringCreateWithCharacters(NULL
, __CFCSetStringBuffer(cset
), __CFCSetStringLength(cset
)); }
2678 bool _CFCharacterSetIsInverted(CFCharacterSetRef cset
) { return __CFCSetIsInverted(cset
); }
2679 void _CFCharacterSetSetIsInverted(CFCharacterSetRef cset
, bool flag
) { __CFCSetPutIsInverted((CFMutableCharacterSetRef
)cset
, flag
); }