in Frameworks/CoreFoundation/String.subproj/CFCharacterSet.c [891:1185]
static Boolean __CFCharacterSetEqual(CFTypeRef cf1, CFTypeRef cf2) {
Boolean isInvertStateIdentical = (__CFCSetIsInverted((CFCharacterSetRef)cf1) == __CFCSetIsInverted((CFCharacterSetRef)cf2) ? true: false);
Boolean isAnnexInvertStateIdentical = (__CFCSetAnnexIsInverted((CFCharacterSetRef)cf1) == __CFCSetAnnexIsInverted((CFCharacterSetRef)cf2) ? true: false);
CFIndex idx;
CFCharacterSetRef subSet1;
uint8_t bitsBuf[__kCFBitmapSize];
uint8_t *bits;
Boolean isBitmap1;
Boolean isBitmap2;
if (__CFCSetHasHashValue((CFCharacterSetRef)cf1) && __CFCSetHasHashValue((CFCharacterSetRef)cf2) && ((CFCharacterSetRef)cf1)->_hashValue != ((CFCharacterSetRef)cf2)->_hashValue) return false;
if (__CFCSetIsEmpty((CFCharacterSetRef)cf1) && __CFCSetIsEmpty((CFCharacterSetRef)cf2) && !isInvertStateIdentical) return false;
if ((__CFCSetClassType((CFCharacterSetRef)cf1) == __CFCSetClassType((CFCharacterSetRef)cf2)) && !__CFCSetIsCompactBitmap((CFCharacterSetRef)cf1)) { // Types are identical, we can do it fast
switch (__CFCSetClassType((CFCharacterSetRef)cf1)) {
case __kCFCharSetClassBuiltin:
return (__CFCSetBuiltinType((CFCharacterSetRef)cf1) == __CFCSetBuiltinType((CFCharacterSetRef)cf2) && isInvertStateIdentical ? true : false);
case __kCFCharSetClassRange:
return (__CFCSetRangeFirstChar((CFCharacterSetRef)cf1) == __CFCSetRangeFirstChar((CFCharacterSetRef)cf2) && __CFCSetRangeLength((CFCharacterSetRef)cf1) && __CFCSetRangeLength((CFCharacterSetRef)cf2) && isInvertStateIdentical ? true : false);
case __kCFCharSetClassString:
if (isInvertStateIdentical) {
const UniChar *buf1 = __CFCSetStringBuffer((CFCharacterSetRef)cf1);
const UniChar *buf1End = buf1 + __CFCSetStringLength((CFCharacterSetRef)cf1);
const UniChar *buf2 = __CFCSetStringBuffer((CFCharacterSetRef)cf2);
const UniChar *buf2End = buf2 + __CFCSetStringLength((CFCharacterSetRef)cf2);
while ((buf1 < buf1End) && (buf2 < buf2End)) {
UniChar char1 = *buf1;
UniChar char2 = *buf2;
if (char1 != char2) return false;
do { ++buf1; } while ((buf1 < buf1End) && (char1 == *buf1));
do { ++buf2; } while ((buf2 < buf2End) && (char2 == *buf2));
}
} else {
return false;
}
break;
case __kCFCharSetClassBitmap:
if (!__CFCSetIsEqualBitmap((const UInt32 *)__CFCSetBitmapBits((CFCharacterSetRef)cf1), (const UInt32 *)__CFCSetBitmapBits((CFCharacterSetRef)cf2))) return false;
break;
}
return __CFCSetIsEqualAnnex((CFCharacterSetRef)cf1, (CFCharacterSetRef)cf2);
}
// Check for easy empty cases
if (__CFCSetIsEmpty((CFCharacterSetRef)cf1) || __CFCSetIsEmpty((CFCharacterSetRef)cf2)) {
CFCharacterSetRef emptySet = (__CFCSetIsEmpty((CFCharacterSetRef)cf1) ? (CFCharacterSetRef)cf1 : (CFCharacterSetRef)cf2);
CFCharacterSetRef nonEmptySet = (emptySet == cf1 ? (CFCharacterSetRef)cf2 : (CFCharacterSetRef)cf1);
if (__CFCSetIsBuiltin(nonEmptySet)) {
return false;
} else if (__CFCSetIsRange(nonEmptySet)) {
if (isInvertStateIdentical) {
return (__CFCSetRangeLength(nonEmptySet) ? false : true);
} else {
return (__CFCSetRangeLength(nonEmptySet) == 0x110000 ? true : false);
}
} else {
if (__CFCSetAnnexIsInverted(nonEmptySet)) {
if (__CFCSetAnnexValidEntriesBitmap(nonEmptySet) != 0x1FFFE) return false;
} else {
if (__CFCSetAnnexValidEntriesBitmap(nonEmptySet)) return false;
}
if (__CFCSetIsBitmap(nonEmptySet)) {
bits = __CFCSetBitmapBits(nonEmptySet);
} else {
bits = bitsBuf;
__CFCSetGetBitmap(nonEmptySet, bitsBuf);
}
if (__CFCSetIsEqualBitmap(NULL, (const UInt32 *)bits)) {
if (!__CFCSetAnnexIsInverted(nonEmptySet)) return true;
} else {
return false;
}
// Annex set has to be CFRangeMake(0x10000, 0xfffff)
for (idx = 1;idx < MAX_ANNEX_PLANE;idx++) {
if (__CFCSetIsBitmap(nonEmptySet)) {
if (!__CFCSetIsEqualBitmap((__CFCSetAnnexIsInverted(nonEmptySet) ? NULL : (const UInt32 *)-1), (const UInt32 *)bitsBuf)) return false;
} else {
__CFCSetGetBitmap(__CFCSetGetAnnexPlaneCharacterSetNoAlloc(nonEmptySet, idx), bitsBuf);
if (!__CFCSetIsEqualBitmap((const UInt32 *)-1, (const UInt32 *)bitsBuf)) return false;
}
}
return true;
}
}
if (__CFCSetIsBuiltin((CFCharacterSetRef)cf1) || __CFCSetIsBuiltin((CFCharacterSetRef)cf2)) {
CFCharacterSetRef builtinSet = (__CFCSetIsBuiltin((CFCharacterSetRef)cf1) ? (CFCharacterSetRef)cf1 : (CFCharacterSetRef)cf2);
CFCharacterSetRef nonBuiltinSet = (builtinSet == cf1 ? (CFCharacterSetRef)cf2 : (CFCharacterSetRef)cf1);
if (__CFCSetIsRange(nonBuiltinSet)) {
UTF32Char firstChar = __CFCSetRangeFirstChar(nonBuiltinSet);
UTF32Char lastChar = (firstChar + __CFCSetRangeLength(nonBuiltinSet) - 1);
uint8_t firstPlane = (firstChar >> 16) & 0xFF;
uint8_t lastPlane = (lastChar >> 16) & 0xFF;
uint8_t result;
for (idx = 0;idx < MAX_ANNEX_PLANE;idx++) {
result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(builtinSet), idx, bitsBuf, (isInvertStateIdentical != 0));
if (idx < firstPlane || idx > lastPlane) {
if (result == kCFUniCharBitmapAll) {
return false;
} else if (result == kCFUniCharBitmapFilled) {
if (!__CFCSetIsEqualBitmap(NULL, (const UInt32 *)bitsBuf)) return false;
}
} else if (idx > firstPlane && idx < lastPlane) {
if (result == kCFUniCharBitmapEmpty) {
return false;
} else if (result == kCFUniCharBitmapFilled) {
if (!__CFCSetIsEqualBitmap((const UInt32 *)-1, (const UInt32 *)bitsBuf)) return false;
}
} else {
if (result == kCFUniCharBitmapEmpty) {
return false;
} else if (result == kCFUniCharBitmapAll) {
if (idx == firstPlane) {
if (((firstChar & 0xFFFF) != 0) || (firstPlane == lastPlane && ((lastChar & 0xFFFF) != 0xFFFF))) return false;
} else {
if (((lastChar & 0xFFFF) != 0xFFFF) || (firstPlane == lastPlane && ((firstChar & 0xFFFF) != 0))) return false;
}
} else {
if (idx == firstPlane) {
if (!__CFCSetIsBitmapEqualToRange((const UInt32 *)bitsBuf, firstChar & 0xFFFF, (firstPlane == lastPlane ? lastChar & 0xFFFF : 0xFFFF), false)) return false;
} else {
if (!__CFCSetIsBitmapEqualToRange((const UInt32 *)bitsBuf, (firstPlane == lastPlane ? firstChar & 0xFFFF : 0), lastChar & 0xFFFF, false)) return false;
}
}
}
}
return true;
} else {
uint8_t bitsBuf2[__kCFBitmapSize];
uint8_t result;
result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(builtinSet), 0, bitsBuf, (__CFCSetIsInverted(builtinSet) != 0));
if (result == kCFUniCharBitmapFilled) {
if (__CFCSetIsBitmap(nonBuiltinSet)) {
if (!__CFCSetIsEqualBitmap((const UInt32 *)bitsBuf, (const UInt32 *)__CFCSetBitmapBits(nonBuiltinSet))) return false;
} else {
__CFCSetGetBitmap(nonBuiltinSet, bitsBuf2);
if (!__CFCSetIsEqualBitmap((const UInt32 *)bitsBuf, (const UInt32 *)bitsBuf2)) {
return false;
}
}
} else {
if (__CFCSetIsBitmap(nonBuiltinSet)) {
if (!__CFCSetIsEqualBitmap((result == kCFUniCharBitmapAll ? (const UInt32*)-1 : NULL), (const UInt32 *)__CFCSetBitmapBits(nonBuiltinSet))) return false;
} else {
__CFCSetGetBitmap(nonBuiltinSet, bitsBuf);
if (!__CFCSetIsEqualBitmap((result == kCFUniCharBitmapAll ? (const UInt32*)-1: NULL), (const UInt32 *)bitsBuf)) return false;
}
}
isInvertStateIdentical = (__CFCSetIsInverted(builtinSet) == __CFCSetAnnexIsInverted(nonBuiltinSet) ? true : false);
for (idx = 1;idx < MAX_ANNEX_PLANE;idx++) {
result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(builtinSet), idx, bitsBuf, !isInvertStateIdentical);
subSet1 = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(nonBuiltinSet, idx);
if (result == kCFUniCharBitmapFilled) {
if (NULL == subSet1) {
return false;
} else if (__CFCSetIsBitmap(subSet1)) {
if (!__CFCSetIsEqualBitmap((const UInt32*)bitsBuf, (const UInt32*)__CFCSetBitmapBits(subSet1))) {
return false;
}
} else {
__CFCSetGetBitmap(subSet1, bitsBuf2);
if (!__CFCSetIsEqualBitmap((const UInt32*)bitsBuf, (const UInt32*)bitsBuf2)) {
return false;
}
}
} else {
if (NULL == subSet1) {
if (result == kCFUniCharBitmapAll) {
return false;
}
} else if (__CFCSetIsBitmap(subSet1)) {
if (!__CFCSetIsEqualBitmap((result == kCFUniCharBitmapAll ? (const UInt32*)-1: NULL), (const UInt32*)__CFCSetBitmapBits(subSet1))) {
return false;
}
} else {
__CFCSetGetBitmap(subSet1, bitsBuf);
if (!__CFCSetIsEqualBitmap((result == kCFUniCharBitmapAll ? (const UInt32*)-1: NULL), (const UInt32*)bitsBuf)) {
return false;
}
}
}
}
return true;
}
}
if (__CFCSetIsRange((CFCharacterSetRef)cf1) || __CFCSetIsRange((CFCharacterSetRef)cf2)) {
CFCharacterSetRef rangeSet = (__CFCSetIsRange((CFCharacterSetRef)cf1) ? (CFCharacterSetRef)cf1 : (CFCharacterSetRef)cf2);
CFCharacterSetRef nonRangeSet = (rangeSet == cf1 ? (CFCharacterSetRef)cf2 : (CFCharacterSetRef)cf1);
UTF32Char firstChar = __CFCSetRangeFirstChar(rangeSet);
UTF32Char lastChar = (firstChar + __CFCSetRangeLength(rangeSet) - 1);
uint8_t firstPlane = (firstChar >> 16) & 0xFF;
uint8_t lastPlane = (lastChar >> 16) & 0xFF;
Boolean isRangeSetInverted = __CFCSetIsInverted(rangeSet);
if (__CFCSetIsBitmap(nonRangeSet)) {
bits = __CFCSetBitmapBits(nonRangeSet);
} else {
bits = bitsBuf;
__CFCSetGetBitmap(nonRangeSet, bitsBuf);
}
if (firstPlane == 0) {
if (!__CFCSetIsBitmapEqualToRange((const UInt32*)bits, firstChar, (lastPlane == 0 ? lastChar : 0xFFFF), isRangeSetInverted)) return false;
firstPlane = 1;
firstChar = 0;
} else {
if (!__CFCSetIsEqualBitmap((const UInt32*)bits, (isRangeSetInverted ? (const UInt32 *)-1 : NULL))) return false;
firstChar &= 0xFFFF;
}
lastChar &= 0xFFFF;
isAnnexInvertStateIdentical = (isRangeSetInverted == __CFCSetAnnexIsInverted(nonRangeSet) ? true : false);
for (idx = 1;idx < MAX_ANNEX_PLANE;idx++) {
subSet1 = __CFCSetGetAnnexPlaneCharacterSetNoAlloc(nonRangeSet, idx);
if (NULL == subSet1) {
if (idx < firstPlane || idx > lastPlane) {
if (!isAnnexInvertStateIdentical) return false;
} else if (idx > firstPlane && idx < lastPlane) {
if (isAnnexInvertStateIdentical) return false;
} else if (idx == firstPlane) {
if (isAnnexInvertStateIdentical || firstChar || (idx == lastPlane && lastChar != 0xFFFF)) return false;
} else if (idx == lastPlane) {
if (isAnnexInvertStateIdentical || (idx == firstPlane && firstChar) || (lastChar != 0xFFFF)) return false;
}
} else {
if (__CFCSetIsBitmap(subSet1)) {
bits = __CFCSetBitmapBits(subSet1);
} else {
__CFCSetGetBitmap(subSet1, bitsBuf);
bits = bitsBuf;
}
if (idx < firstPlane || idx > lastPlane) {
if (!__CFCSetIsEqualBitmap((const UInt32*)bits, (isAnnexInvertStateIdentical ? NULL : (const UInt32 *)-1))) return false;
} else if (idx > firstPlane && idx < lastPlane) {
if (!__CFCSetIsEqualBitmap((const UInt32*)bits, (isAnnexInvertStateIdentical ? (const UInt32 *)-1 : NULL))) return false;
} else if (idx == firstPlane) {
if (!__CFCSetIsBitmapEqualToRange((const UInt32*)bits, firstChar, (idx == lastPlane ? lastChar : 0xFFFF), !isAnnexInvertStateIdentical)) return false;
} else if (idx == lastPlane) {
if (!__CFCSetIsBitmapEqualToRange((const UInt32*)bits, (idx == firstPlane ? firstChar : 0), lastChar, !isAnnexInvertStateIdentical)) return false;
}
}
}
return true;
}
isBitmap1 = __CFCSetIsBitmap((CFCharacterSetRef)cf1);
isBitmap2 = __CFCSetIsBitmap((CFCharacterSetRef)cf2);
if (isBitmap1 && isBitmap2) {
if (!__CFCSetIsEqualBitmap((const UInt32 *)__CFCSetBitmapBits((CFCharacterSetRef)cf1), (const UInt32 *)__CFCSetBitmapBits((CFCharacterSetRef)cf2))) return false;
} else if (!isBitmap1 && !isBitmap2) {
uint8_t bitsBuf2[__kCFBitmapSize];
__CFCSetGetBitmap((CFCharacterSetRef)cf1, bitsBuf);
__CFCSetGetBitmap((CFCharacterSetRef)cf2, bitsBuf2);
if (!__CFCSetIsEqualBitmap((const UInt32*)bitsBuf, (const UInt32*)bitsBuf2)) {
return false;
}
} else {
if (isBitmap2) {
CFCharacterSetRef tmp = (CFCharacterSetRef)cf2;
cf2 = cf1;
cf1 = tmp;
}
__CFCSetGetBitmap((CFCharacterSetRef)cf2, bitsBuf);
if (!__CFCSetIsEqualBitmap((const UInt32 *)__CFCSetBitmapBits((CFCharacterSetRef)cf1), (const UInt32 *)bitsBuf)) return false;
}
return __CFCSetIsEqualAnnex((CFCharacterSetRef)cf1, (CFCharacterSetRef)cf2);
}