void CFCharacterSetIntersect()

in CoreFoundation/String.subproj/CFCharacterSet.c [2737:2979]


void CFCharacterSetIntersect(CFMutableCharacterSetRef theSet, CFCharacterSetRef theOtherSet) {
    CFCharacterSetRef expandedSet = NULL;

    CF_OBJC_FUNCDISPATCHV(_kCFRuntimeIDCFCharacterSet, void, (NSMutableCharacterSet *)theSet, formIntersectionWithCharacterSet:(NSCharacterSet *)theOtherSet);

    __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
    
    if (__CFCSetIsBuiltin((CFCharacterSetRef)theSet) && !__CFCSetIsMutable((CFCharacterSetRef)theSet) && !__CFCSetIsInverted((CFCharacterSetRef)theSet)) {
        CFCharacterSetRef sharedSet = CFCharacterSetGetPredefined(__CFCSetBuiltinType((CFCharacterSetRef)theSet));
        if (sharedSet == theSet) { // We're trying to dealloc the builtin set
            CFAssert1(0, __kCFLogAssertion, "%s: Trying to mutable predefined set.", __PRETTY_FUNCTION__);
            return; // We don't mutate builtin set
        }
    }

    if (__CFCSetIsEmpty(theSet) && !__CFCSetIsInverted(theSet)) return; // empty set

    if (!CF_IS_OBJC(_kCFRuntimeIDCFCharacterSet, theOtherSet) || (expandedSet = __CFCharacterSetGetExpandedSetForNSCharacterSet(theOtherSet))) { // Really CF, we can do some trick here
        if (expandedSet) theOtherSet = expandedSet;

        if (__CFCSetIsEmpty(theOtherSet)) {
           if (!__CFCSetIsInverted(theOtherSet)) {
                if (__CFCSetIsString(theSet) && __CFCSetStringBuffer(theSet)) {
                    CFAllocatorDeallocate(CFGetAllocator(theSet), __CFCSetStringBuffer(theSet));
                } else if (__CFCSetIsBitmap(theSet) && __CFCSetBitmapBits(theSet)) {
                    CFAllocatorDeallocate(CFGetAllocator(theSet), __CFCSetBitmapBits(theSet));
                } else if (__CFCSetIsCompactBitmap(theSet) && __CFCSetCompactBitmapBits(theSet)) {
                    CFAllocatorDeallocate(CFGetAllocator(theSet), __CFCSetCompactBitmapBits(theSet));
                }
                __CFCSetPutClassType(theSet, __kCFCharSetClassBitmap);
                __CFCSetPutBitmapBits(theSet, NULL);
                __CFCSetPutIsInverted(theSet, false);
                theSet->_hashValue = 0;
                __CFCSetPutHasHashValue(theSet, true);
                __CFCSetDeallocateAnnexPlane(theSet);
            }
        } else if (__CFCSetIsEmpty(theSet)) { // non inverted empty set contains all character
            __CFCSetPutClassType(theSet, __CFCSetClassType(theOtherSet));
            __CFCSetPutHasHashValue(theSet, __CFCSetHasHashValue(theOtherSet));
            __CFCSetPutIsInverted(theSet, __CFCSetIsInverted(theOtherSet));
            theSet->_hashValue = theOtherSet->_hashValue;
            if (__CFCSetHasNonBMPPlane(theOtherSet)) {
                CFMutableCharacterSetRef otherSetPlane;
                int idx;
                for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) {
                    if ((otherSetPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theOtherSet, idx))) {
                        otherSetPlane = (CFMutableCharacterSetRef)CFCharacterSetCreateMutableCopy(CFGetAllocator(theSet), otherSetPlane);
                        __CFCSetPutCharacterSetToAnnexPlane(theSet, otherSetPlane, idx);
                        CFRelease(otherSetPlane);
                    }
                }
                __CFCSetAnnexSetIsInverted(theSet, __CFCSetAnnexIsInverted(theOtherSet));
            }

            switch (__CFCSetClassType(theOtherSet)) {
                case __kCFCharSetClassBuiltin:
                    __CFCSetPutBuiltinType(theSet, __CFCSetBuiltinType(theOtherSet));
                    break;

                case __kCFCharSetClassRange:
                    __CFCSetPutRangeFirstChar(theSet, __CFCSetRangeFirstChar(theOtherSet));
                    __CFCSetPutRangeLength(theSet, __CFCSetRangeLength(theOtherSet));
                    break;

                case __kCFCharSetClassString:
                    __CFCSetPutStringLength(theSet, __CFCSetStringLength(theOtherSet));
                    if (!__CFCSetStringBuffer(theSet)) __CFCSetPutStringBuffer(theSet, (UniChar *)CFAllocatorAllocate(CFGetAllocator(theSet), __kCFStringCharSetMax * sizeof(UniChar), 0));
                    memmove(__CFCSetStringBuffer(theSet), __CFCSetStringBuffer(theOtherSet), __CFCSetStringLength(theSet) * sizeof(UniChar));
                    break;

                case __kCFCharSetClassBitmap:
                    __CFCSetPutBitmapBits(theSet, (uint8_t *)CFAllocatorAllocate(CFGetAllocator(theSet), sizeof(uint8_t) * __kCFBitmapSize, 0));
                    memmove(__CFCSetBitmapBits(theSet), __CFCSetBitmapBits(theOtherSet), __kCFBitmapSize);
                    break;

                case __kCFCharSetClassCompactBitmap: {
                    const uint8_t *cBitmap = __CFCSetCompactBitmapBits(theOtherSet);
                    uint8_t *newBitmap;
                    uint32_t size = __CFCSetGetCompactBitmapSize(cBitmap);
                    newBitmap = (uint8_t *)CFAllocatorAllocate(CFGetAllocator(theSet), sizeof(uint8_t) * size, 0);
                    __CFCSetPutBitmapBits(theSet, newBitmap);
                    memmove(newBitmap, cBitmap, size);
                    }
                    break;

                default:
                    CFAssert1(0, __kCFLogAssertion, "%s: Internal inconsistency error: unknown character set type", __PRETTY_FUNCTION__); // We should never come here
            }
        } else {
            __CFCSetMakeBitmap(theSet);
            if (__CFCSetIsBitmap(theOtherSet)) {
                UInt32 *bitmap1 = (UInt32*)__CFCSetBitmapBits(theSet);
                UInt32 *bitmap2 = (UInt32*)__CFCSetBitmapBits(theOtherSet);
                CFIndex length = __kCFBitmapSize / sizeof(UInt32);
                while (length--) *bitmap1++ &= *bitmap2++;
            } else {
                UInt32 *bitmap1 = (UInt32*)__CFCSetBitmapBits(theSet);
                UInt32 *bitmap2;
                CFIndex length = __kCFBitmapSize / sizeof(UInt32);
                uint8_t bitmapBuffer[__kCFBitmapSize];
                __CFCSetGetBitmap(theOtherSet, bitmapBuffer);
                bitmap2 = (UInt32*)bitmapBuffer;
                while (length--) *bitmap1++ &= *bitmap2++;
            }
            __CFCSetPutHasHashValue(theSet, false);
            if (__CFCSetHasNonBMPPlane(theOtherSet)) {
                CFMutableCharacterSetRef annexPlane;
                CFMutableCharacterSetRef otherSetPlane;
                CFMutableCharacterSetRef emptySet = CFCharacterSetCreateMutable(NULL);
                int idx;
                for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) {
                    if ((otherSetPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theOtherSet, idx))) {
                        if (__CFCSetAnnexIsInverted(theOtherSet)) CFCharacterSetInvert(otherSetPlane);
                        annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx);
                        if (__CFCSetAnnexIsInverted(theSet)) CFCharacterSetInvert(annexPlane);
                        CFCharacterSetIntersect(annexPlane, otherSetPlane);
                        if (__CFCSetAnnexIsInverted(theSet)) CFCharacterSetInvert(annexPlane);
                        if (__CFCSetAnnexIsInverted(theOtherSet)) CFCharacterSetInvert(otherSetPlane);
                        if (__CFCSetIsEmpty(annexPlane) && !__CFCSetIsInverted(annexPlane)) __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx);
                    } else if ((annexPlane = (CFMutableCharacterSetRef) __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx))) {
                        if (__CFCSetAnnexIsInverted(theSet)) { // if the annexPlane is inverted, we need to set the plane to empty
                            CFCharacterSetInvert(annexPlane);
                            CFCharacterSetIntersect(annexPlane, emptySet);
                            CFCharacterSetInvert(annexPlane);
                        } else {  // the annexPlane is not inverted, we can clear the plane
                            __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx);
                        }
                    } else if ((__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx) == NULL) && __CFCSetAnnexIsInverted(theSet)) {
                        // the set has no such annex plane and the annex plane is inverted, it means the set contains everything in the annex plane
                        annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx);
                        if (__CFCSetAnnexIsInverted(theSet)) CFCharacterSetInvert(annexPlane);
                        CFCharacterSetIntersect(annexPlane, emptySet);
                        if (__CFCSetAnnexIsInverted(theSet)) CFCharacterSetInvert(annexPlane);
                    }
                }
                CFRelease(emptySet);
                if (!__CFCSetHasNonBMPPlane(theSet)) __CFCSetDeallocateAnnexPlane(theSet);
            } else if (__CFCSetIsBuiltin(theOtherSet) && !__CFCSetAnnexIsInverted(theOtherSet)) {
                CFMutableCharacterSetRef annexPlane;
                uint8_t bitmapBuffer[__kCFBitmapSize];
                uint8_t result;
                unsigned char planeIndex;
                UInt32 *bitmap1;
                UInt32 *bitmap2;
                CFIndex length;

                for (planeIndex = 1;planeIndex <= MAX_ANNEX_PLANE;planeIndex++) {
                    annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, planeIndex);
                    if (annexPlane) {
                        result = CFUniCharGetBitmapForPlane(__CFCSetBuiltinType(theOtherSet), planeIndex, bitmapBuffer, false);
                        if (result == kCFUniCharBitmapEmpty) {
                            __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, planeIndex);
                        } else if (result == kCFUniCharBitmapFilled) {
                            Boolean isEmpty = true;

                            __CFCSetMakeBitmap(annexPlane);
                            bitmap1 = (UInt32 *)__CFCSetBitmapBits(annexPlane);
                            length = __kCFBitmapSize / sizeof(UInt32);
                            bitmap2 = (UInt32*)bitmapBuffer;

                            while (length--) {
                                if ((*bitmap1++ &= *bitmap2++)) isEmpty = false;
                            }
                            if (isEmpty) __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, planeIndex);
                        }
                    }
                }
                if (!__CFCSetHasNonBMPPlane(theSet)) __CFCSetDeallocateAnnexPlane(theSet);
            } else if (__CFCSetIsRange(theOtherSet)) {
                CFMutableCharacterSetRef tempOtherSet = CFCharacterSetCreateMutable(CFGetAllocator(theSet));
                CFMutableCharacterSetRef annexPlane;
                CFMutableCharacterSetRef otherSetPlane;
                CFMutableCharacterSetRef emptySet = CFCharacterSetCreateMutable(NULL);
                int idx;

                __CFCSetAddNonBMPPlanesInRange(tempOtherSet, CFRangeMake(__CFCSetRangeFirstChar(theOtherSet), __CFCSetRangeLength(theOtherSet)));
                
                Boolean const theSet_annexInverted = __CFCSetAnnexIsInverted(theSet);
                Boolean const otherSet_annexInverted = __CFCSetAnnexIsInverted(tempOtherSet);
                
                for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) {

                    otherSetPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(tempOtherSet, idx);
                    if (otherSetPlane) {
                        annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx);
                        
                        if (otherSet_annexInverted) {
                            CFCharacterSetInvert(otherSetPlane);
                        }
                        if (theSet_annexInverted) {
                            CFCharacterSetInvert(annexPlane);
                        }
                        
                        CFCharacterSetIntersect(annexPlane, otherSetPlane);
                        
                        if (theSet_annexInverted) {
                            CFCharacterSetInvert(annexPlane);
                        }
                        if (otherSet_annexInverted) {
                            CFCharacterSetInvert(otherSetPlane);
                        }
                        
                        if (__CFCSetIsEmpty(annexPlane) && !__CFCSetIsInverted(annexPlane)) {
                            __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx);
                        }
                    } else if ((annexPlane = (CFMutableCharacterSetRef) __CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx))) {
                        if (theSet_annexInverted) {
                            CFCharacterSetInvert(annexPlane);
                            CFCharacterSetIntersect(annexPlane, emptySet);
                            CFCharacterSetInvert(annexPlane);
                        } else {
                            __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx);
                        }
                    } else if ((__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx) == NULL) && theSet_annexInverted) {
                        // the set has no such annex plane and the annex plane is inverted, it means the set contains everything in the annex plane
                        annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx);
                        if (theSet_annexInverted) CFCharacterSetInvert(annexPlane);
                        CFCharacterSetIntersect(annexPlane, emptySet);
                        if (theSet_annexInverted) CFCharacterSetInvert(annexPlane);
                    }
                }
                if (!__CFCSetHasNonBMPPlane(theSet)) __CFCSetDeallocateAnnexPlane(theSet);
                CFRelease(tempOtherSet);
                CFRelease(emptySet);
            } else if ((__CFCSetHasNonBMPPlane(theSet) || __CFCSetAnnexIsInverted(theSet)) && !__CFCSetAnnexIsInverted(theOtherSet)) {
                __CFCSetDeallocateAnnexPlane(theSet);
            }
        }
        if (__CFCheckForExapendedSet) __CFCheckForExpandedSet(theSet);
    } else { // It's NSCharacterSet
        CFDataRef bitmapRep = CFCharacterSetCreateBitmapRepresentation(kCFAllocatorSystemDefault, theOtherSet);
        const UInt32 *bitmap2 = (bitmapRep && CFDataGetLength(bitmapRep) ? (const UInt32 *)CFDataGetBytePtr(bitmapRep) : NULL);
        if (bitmap2) {
            UInt32 *bitmap1;
            CFIndex length = __kCFBitmapSize / sizeof(UInt32);
            __CFCSetMakeBitmap(theSet);
            bitmap1 = (UInt32*)__CFCSetBitmapBits(theSet);
            while (length--) *bitmap1++ &= *bitmap2++;
            __CFCSetPutHasHashValue(theSet, false);
        }
        if (bitmapRep) { CFRelease(bitmapRep); }
    }
}