static CFHashCode __CFXMLNodeHash(CFTypeRef cf) { CFXMLNodeRef node = (CFXMLNodeRef)cf; if (node->dataString) { return CFHash(node->dataString); } if (node->dataTypeID == kCFXMLNodeTypeDocument) { CFURLRef url = ((CFXMLDocumentInfo *)node->additionalData)->sourceURL; return url ? CFHash(url) : (CFHashCode)cf; } else { CFAssert2(false, __kCFLogAssertion, "%s(): Saw unexpected XML type code %d", __PRETTY_FUNCTION__, node->dataTypeID); return CFHash(cf); } }
void CFSetSetValue(CFMutableSetRef set, const void *value) { struct __CFSetBucket *match, *nomatch; const CFSetCallBacks *cb; const void *newValue; CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, void, set, "_setObject:", value); __CFGenericValidateType(set, __kCFSetTypeID); switch (__CFSetGetType(set)) { case __kCFSetMutable: if (set->_bucketsUsed == set->_capacity || NULL == set->_buckets) { __CFSetGrow(set, 1); } break; case __kCFSetFixedMutable: break; default: CFAssert2(__CFSetGetType(set) != __kCFSetImmutable, __kCFLogAssertion, "%s(): immutable set %p passed to mutating operation", __PRETTY_FUNCTION__, set); break; } __CFSetFindBuckets2(set, value, &match, &nomatch); cb = __CFSetGetCallBacks(set); if (cb->retain) { newValue = (void *)INVOKE_CALLBACK3(((const void *(*)(CFAllocatorRef, const void *, void *))cb->retain), __CFGetAllocator(set), value, set->_context); } else { newValue = value; } if (match) { if (cb->release) { INVOKE_CALLBACK3(((void (*)(CFAllocatorRef, const void *, void *))cb->release), __CFGetAllocator(set), match->_key, set->_context); match->_key = set->_deletedMarker; } if (set->_emptyMarker == newValue) { __CFSetFindNewEmptyMarker(set); } if (set->_deletedMarker == newValue) { __CFSetFindNewDeletedMarker(set); } match->_key = newValue; } else { CFAssert3(__kCFSetFixedMutable != __CFSetGetType(set) || set->_count < set->_capacity, __kCFLogAssertion, "%s(): capacity exceeded on fixed-capacity set %p (capacity = %d)", __PRETTY_FUNCTION__, set, set->_capacity); if (set->_emptyMarker == newValue) { __CFSetFindNewEmptyMarker(set); } if (set->_deletedMarker == newValue) { __CFSetFindNewDeletedMarker(set); } nomatch->_key = newValue; set->_bucketsUsed++; set->_count++; } }
CFSetRef CFSetCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFSetCallBacks *callBacks) { CFSetRef result; UInt32 flags; CFIndex idx; CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%d) cannot be less than zero", __PRETTY_FUNCTION__, numValues); result = __CFSetInit(allocator, __kCFSetImmutable, numValues, callBacks); flags = __CFBitfieldGetValue(((const CFRuntimeBase *)result)->_info, 1, 0); if (flags == __kCFSetImmutable) { __CFBitfieldSetValue(((CFRuntimeBase *)result)->_info, 1, 0, __kCFSetFixedMutable); } for (idx = 0; idx < numValues; idx++) { CFSetAddValue((CFMutableSetRef)result, values[idx]); } __CFBitfieldSetValue(((CFRuntimeBase *)result)->_info, 1, 0, flags); return result; }
__private_extern__ CFArrayRef __CFArrayCreateTransfer(CFAllocatorRef allocator, const void **values, CFIndex numValues) { CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%d) cannot be less than zero", __PRETTY_FUNCTION__, numValues); UInt32 flags = __kCFArrayImmutable; __CFBitfieldSetValue(flags, 31, 2, 0); __CFBitfieldSetValue(flags, 3, 2, __kCFArrayHasCFTypeCallBacks); UInt32 size = __CFArrayGetSizeOfType(flags) - sizeof(CFRuntimeBase); size += numValues * sizeof(struct __CFArrayBucket); struct __CFArray *memory = (struct __CFArray*)_CFRuntimeCreateInstance(allocator, __kCFArrayTypeID, size, NULL); if (NULL == memory) { return NULL; } __CFBitfieldSetValue(memory->_base._cfinfo[CF_INFO_BITS], 6, 0, flags); __CFArraySetCount(memory, numValues); memmove(__CFArrayGetBucketsPtr(memory), values, sizeof(void *) * numValues); if (__CFOASafe) __CFSetLastAllocationEventName(memory, "CFArray (immutable)"); return (CFArrayRef)memory; }
void CFDataReplaceBytes(CFMutableDataRef data, CFRange range, const uint8_t *newBytes, CFIndex newLength) { CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, void, (NSMutableData *)data, replaceBytesInRange:NSMakeRange(range.location, range.length) withBytes:(const void *)newBytes length:(NSUInteger)newLength); __CFGenericValidateType(data, __kCFDataTypeID); __CFDataValidateRange(data, range, __PRETTY_FUNCTION__); CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__); CFAssert2(0 <= newLength, __kCFLogAssertion, "%s(): newLength (%d) cannot be less than zero", __PRETTY_FUNCTION__, newLength); CFIndex len = __CFDataLength(data); if (len < 0 || range.length < 0 || newLength < 0) HALT; CFIndex newCount = len - range.length + newLength; if (newCount < 0) HALT; uint8_t *bytePtr = (uint8_t *)CFDataGetMutableBytePtr(data); uint8_t *srcBuf = (uint8_t *)newBytes; switch (__CFMutableVariety(data)) { case kCFMutable: if (__CFDataNumBytes(data) < newCount) { if (bytePtr && newBytes && newBytes < bytePtr + __CFDataCapacity(data) && bytePtr < newBytes + newLength) { srcBuf = (uint8_t *)malloc(newLength * sizeof(uint8_t)); memmove(srcBuf, newBytes, newLength * sizeof(uint8_t)); } __CFDataGrow(data, newLength - range.length, false); bytePtr = (uint8_t *)CFDataGetMutableBytePtr(data); } break; case kCFFixedMutable: CFAssert1(newCount <= __CFDataCapacity(data), __kCFLogAssertion, "%s(): fixed-capacity data is full", __PRETTY_FUNCTION__); // Continuing after this could cause buffer overruns. if (newCount > __CFDataCapacity(data)) HALT; break; } if (newLength != range.length && range.location + range.length < len) { memmove(bytePtr + range.location + newLength, bytePtr + range.location + range.length, (len - range.location - range.length) * sizeof(uint8_t)); } if (0 < newLength) { memmove(bytePtr + range.location, srcBuf, newLength * sizeof(uint8_t)); } if (srcBuf != newBytes) free(srcBuf); __CFDataSetNumBytesUsed(data, newCount); __CFDataSetLength(data, newCount); }
__private_extern__ const void *__CFSetAddValueAndReturn(CFMutableSetRef set, const void *value) { struct __CFSetBucket *match, *nomatch; const CFSetCallBacks *cb; const void *newValue; // #warning not toll-free bridged, but internal __CFGenericValidateType(set, __kCFSetTypeID); switch (__CFSetGetType(set)) { case __kCFSetMutable: if (set->_bucketsUsed == set->_capacity || NULL == set->_buckets) { __CFSetGrow(set, 1); } break; case __kCFSetFixedMutable: CFAssert3(set->_count < set->_capacity, __kCFLogAssertion, "%s(): capacity exceeded on fixed-capacity set %p (capacity = %d)", __PRETTY_FUNCTION__, set, set->_capacity); break; default: CFAssert2(__CFSetGetType(set) != __kCFSetImmutable, __kCFLogAssertion, "%s(): immutable set %p passed to mutating operation", __PRETTY_FUNCTION__, set); break; } __CFSetFindBuckets2(set, value, &match, &nomatch); if (match) { return match->_key; } else { cb = __CFSetGetCallBacks(set); if (cb->retain) { newValue = (void *)INVOKE_CALLBACK3(((const void *(*)(CFAllocatorRef, const void *, void *))cb->retain), __CFGetAllocator(set), value, set->_context); } else { newValue = value; } if (set->_emptyMarker == newValue) { __CFSetFindNewEmptyMarker(set); } if (set->_deletedMarker == newValue) { __CFSetFindNewDeletedMarker(set); } nomatch->_key = newValue; set->_bucketsUsed++; set->_count++; return newValue; } }
// NULL bytesDeallocator to this function does not mean the default allocator, it means // that there should be no deallocator, and the bytes should be copied. static CFMutableDataRef __CFDataInit(CFAllocatorRef allocator, CFOptionFlags flags, CFIndex capacity, const uint8_t *bytes, CFIndex length, CFAllocatorRef bytesDeallocator) { CFMutableDataRef memory; __CFGenericValidateMutabilityFlags(flags); CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%d) cannot be less than zero", __PRETTY_FUNCTION__, capacity); CFAssert3(kCFFixedMutable != __CFMutableVarietyFromFlags(flags) || length <= capacity, __kCFLogAssertion, "%s(): for kCFFixedMutable type, capacity (%d) must be greater than or equal to number of initial elements (%d)", __PRETTY_FUNCTION__, capacity, length); CFAssert2(0 <= length, __kCFLogAssertion, "%s(): length (%d) cannot be less than zero", __PRETTY_FUNCTION__, length); Boolean collectableMemory = CF_IS_COLLECTABLE_ALLOCATOR(allocator); Boolean noCopy = bytesDeallocator != NULL; Boolean isMutable = ((flags & __kCFMutable) != 0); Boolean isGrowable = ((flags & __kCFGrowable) != 0); Boolean allocateInline = !isGrowable && !noCopy && capacity < INLINE_BYTES_THRESHOLD; allocator = (allocator == NULL) ? __CFGetDefaultAllocator() : allocator; Boolean useAllocator = (allocator != kCFAllocatorSystemDefault && allocator != kCFAllocatorMalloc && allocator != kCFAllocatorMallocZone); CFIndex size = sizeof(struct __CFData) - sizeof(CFRuntimeBase); if (allocateInline) { size += sizeof(uint8_t) * __CFDataNumBytesForCapacity(capacity) + sizeof(uint8_t) * 15; // for 16-byte alignment fixup } memory = (CFMutableDataRef)_CFRuntimeCreateInstance(allocator, __kCFDataTypeID, size, NULL); if (NULL == memory) { return NULL; } __CFDataSetNumBytesUsed(memory, 0); __CFDataSetLength(memory, 0); __CFDataSetInfoBits(memory, (allocateInline ? __kCFBytesInline : 0) | (useAllocator ? __kCFUseAllocator : 0) | (collectableMemory ? __kCFAllocatesCollectable : 0)); BOOL finalize = YES; BOOL scan = YES; if (collectableMemory) { if (allocateInline) { // We have no pointer to anything that needs to be reclaimed, so don't scan or finalize. scan = NO; finalize = NO; } else if (noCopy) { if (CF_IS_COLLECTABLE_ALLOCATOR(bytesDeallocator)) { // We're taking responsibility for externally GC-allocated memory, so scan us, but we don't need to finalize. finalize = NO; } else if (bytesDeallocator == kCFAllocatorNull) { // We don't have responsibility for these bytes, so there's no need to be scanned and we don't need to finalize. scan = NO; finalize = NO; } else { // We have a pointer to non-GC-allocated memory, so don't scan, but do finalize. scan = NO; } } if (!scan) auto_zone_set_unscanned(objc_collectableZone(), memory); if (!finalize) auto_zone_set_nofinalize(objc_collectableZone(), memory); } if (isMutable && isGrowable) { __CFDataSetCapacity(memory, __CFDataRoundUpCapacity(1)); __CFDataSetNumBytes(memory, __CFDataNumBytesForCapacity(__CFDataRoundUpCapacity(1))); __CFSetMutableVariety(memory, kCFMutable); } else { /* Don't round up capacity */ __CFDataSetCapacity(memory, capacity); __CFDataSetNumBytes(memory, __CFDataNumBytesForCapacity(capacity)); __CFSetMutableVariety(memory, kCFFixedMutable); } if (noCopy) { __CFAssignWithWriteBarrier((void **)&memory->_bytes, (uint8_t *)bytes); if (finalize) { if (_CFAllocatorIsGCRefZero(bytesDeallocator)) { memory->_bytesDeallocator = bytesDeallocator; } else { memory->_bytesDeallocator = (CFAllocatorRef)CFRetain(_CFConvertAllocatorToNonGCRefZeroEquivalent(bytesDeallocator)); } } if (CF_IS_COLLECTABLE_ALLOCATOR(bytesDeallocator) && !_CFAllocatorIsGCRefZero(bytesDeallocator)) { // When given a GC allocator which is not one of the GCRefZero ones as the deallocator, we assume that the no-copy memory is GC-allocated with a retain count of (at least) 1 and we should release it now instead of waiting until __CFDataDeallocate. auto_zone_release(objc_collectableZone(), memory->_bytes); } __CFDataSetNumBytesUsed(memory, length); __CFDataSetLength(memory, length); // Mutable no-copy datas are not allowed, so don't bother setting needsToZero flag. } else { Boolean cleared = (isMutable && !isGrowable && !_CFExecutableLinkedOnOrAfter(CFSystemVersionSnowLeopard)); if (!allocateInline) { // assume that allocators give 16-byte aligned memory back -- it is their responsibility __CFAssignWithWriteBarrier((void **)&memory->_bytes, __CFDataAllocate(memory, __CFDataNumBytes(memory) * sizeof(uint8_t), cleared)); if (__CFOASafe) __CFSetLastAllocationEventName(memory->_bytes, "CFData (store)"); if (NULL == memory->_bytes) { CFRelease(memory); return NULL; } } else { if (length == 0 && !isMutable) { // NSData sets its bytes pointer to NULL when its length is zero. Starting in 10.7 we do the same for CFData. memory->_bytes = NULL; // It is important to set this data as not inlined, so we do not recalculate a bytes pointer from null. __CFDataSetInline(memory, false); } cleared = true; } __CFDataSetNeedsToZero(memory, !cleared); memory->_bytesDeallocator = NULL; CFDataReplaceBytes(memory, CFRangeMake(0, 0), bytes, length); } __CFSetMutableVariety(memory, __CFMutableVarietyFromFlags(flags)); return memory; }
CF_INLINE void __CFDataValidateRange(CFDataRef data, CFRange range, const char *func) { CFAssert2(0 <= range.location && range.location <= __CFDataLength(data), __kCFLogAssertion, "%s(): range.location index (%d) out of bounds", func, range.location); CFAssert2(0 <= range.length, __kCFLogAssertion, "%s(): length (%d) cannot be less than zero", func, range.length); CFAssert2(range.location + range.length <= __CFDataLength(data), __kCFLogAssertion, "%s(): ending index (%d) out of bounds", func, range.location + range.length); }
CFMutableSetRef CFSetCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFSetCallBacks *callBacks) { CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%d) cannot be less than zero", __PRETTY_FUNCTION__, capacity); return (CFMutableSetRef)__CFSetInit(allocator, (0 == capacity) ? __kCFSetMutable : __kCFSetFixedMutable, capacity, callBacks); }
static void _copyAddlDataForType(CFAllocatorRef alloc, CFXMLNodeTypeCode xmlType, const void *src, void *dest) { switch(xmlType) { case kCFXMLNodeTypeDocument: { CFXMLDocumentInfo *srcData = (CFXMLDocumentInfo *)src; CFXMLDocumentInfo *destData = (CFXMLDocumentInfo *)dest; destData->sourceURL = srcData->sourceURL ? (CFURLRef)CFRetain(srcData->sourceURL) : NULL; destData->encoding = srcData->encoding; break; } case kCFXMLNodeTypeElement: { CFXMLElementInfo *srcData = (CFXMLElementInfo *)src; CFXMLElementInfo *destData = (CFXMLElementInfo *)dest; if (srcData->attributes && CFDictionaryGetCount(srcData->attributes) != 0) { destData->attributes = (CFDictionaryRef)CFPropertyListCreateDeepCopy(alloc, srcData->attributes, kCFPropertyListImmutable); destData->attributeOrder = (CFArrayRef)CFPropertyListCreateDeepCopy(alloc, srcData->attributeOrder, kCFPropertyListImmutable); } else { destData->attributes = NULL; destData->attributeOrder = NULL; } destData->isEmpty = srcData->isEmpty; break; } case kCFXMLNodeTypeProcessingInstruction: { CFXMLProcessingInstructionInfo *srcData = (CFXMLProcessingInstructionInfo *)src; CFXMLProcessingInstructionInfo *destData = (CFXMLProcessingInstructionInfo *)dest; destData->dataString = srcData->dataString ? (CFStringRef)CFStringCreateCopy(alloc, srcData->dataString) : NULL; break; } case kCFXMLNodeTypeEntity: { CFXMLEntityInfo *sourceData = (CFXMLEntityInfo *)src; CFXMLEntityInfo *destData = (CFXMLEntityInfo *)dest; destData->entityType = sourceData->entityType; destData->replacementText = sourceData->replacementText ? (CFStringRef)CFStringCreateCopy(alloc, sourceData->replacementText) : NULL; destData->entityID.systemID = sourceData->entityID.systemID ? (CFURLRef)CFRetain(sourceData->entityID.systemID) : NULL; destData->entityID.publicID = sourceData->entityID.publicID ? (CFStringRef)CFStringCreateCopy(alloc, sourceData->entityID.publicID) : NULL; destData->notationName = sourceData->notationName ? (CFStringRef)CFStringCreateCopy(alloc, sourceData->notationName) : NULL; break; } case kCFXMLNodeTypeEntityReference: { CFXMLEntityReferenceInfo *srcData = (CFXMLEntityReferenceInfo *)src; CFXMLEntityReferenceInfo *destData = (CFXMLEntityReferenceInfo *)dest; destData->entityType = srcData->entityType; break; } case kCFXMLNodeTypeDocumentType: case kCFXMLNodeTypeNotation: { // We can get away with this because the structures of CFXMLNotationInfo and CFXMLDocumentTypeInfo match. -- REW, 3/8/2000 CFXMLNotationInfo *srcData = (CFXMLNotationInfo *)src; CFXMLNotationInfo *destData = (CFXMLNotationInfo *)dest; destData->externalID.systemID = srcData->externalID.systemID ? (CFURLRef)CFRetain(srcData->externalID.systemID) : NULL; destData->externalID.publicID = srcData->externalID.publicID ? (CFStringRef)CFStringCreateCopy(alloc, srcData->externalID.publicID) : NULL; break; } case kCFXMLNodeTypeElementTypeDeclaration: { CFXMLElementTypeDeclarationInfo *srcData = (CFXMLElementTypeDeclarationInfo *)src; CFXMLElementTypeDeclarationInfo *destData = (CFXMLElementTypeDeclarationInfo *)dest; destData->contentDescription = srcData->contentDescription ? (CFStringRef)CFStringCreateCopy(alloc, srcData->contentDescription) : NULL; break; } case kCFXMLNodeTypeAttributeListDeclaration: { CFXMLAttributeListDeclarationInfo *sourceData = (CFXMLAttributeListDeclarationInfo *)src; CFXMLAttributeListDeclarationInfo *destData = (CFXMLAttributeListDeclarationInfo *)dest; CFIndex idx; destData->numberOfAttributes = sourceData->numberOfAttributes; destData->attributes = sourceData->numberOfAttributes ? (CFXMLAttributeDeclarationInfo *)CFAllocatorAllocate(alloc, sizeof(CFXMLAttributeDeclarationInfo)*sourceData->numberOfAttributes, 0) : NULL; for (idx = 0; idx < sourceData->numberOfAttributes; idx ++) { CFXMLAttributeDeclarationInfo sourceAttr = sourceData->attributes[idx]; CFXMLAttributeDeclarationInfo *destAttr = &(destData->attributes[idx]); destAttr->attributeName = (CFStringRef)CFStringCreateCopy(alloc, sourceAttr.attributeName); destAttr->typeString = (CFStringRef)CFStringCreateCopy(alloc, sourceAttr.typeString); destAttr->defaultString = (CFStringRef)CFStringCreateCopy(alloc, sourceAttr.defaultString); } break; } default: CFAssert2(false, __kCFLogAssertion, "%s(): Encountered unexpected typeID %d (additionalData should be empty)", __PRETTY_FUNCTION__, xmlType); } }
CF_INLINE void __CFArrayValidateRange(CFArrayRef array, CFRange range, const char *func) { CFAssert3(0 <= range.location && range.location <= CFArrayGetCount(array), __kCFLogAssertion, "%s(): range.location index (%d) out of bounds (0, %d)", func, range.location, CFArrayGetCount(array)); CFAssert2(0 <= range.length, __kCFLogAssertion, "%s(): range.length (%d) cannot be less than zero", func, range.length); CFAssert3(range.location + range.length <= CFArrayGetCount(array), __kCFLogAssertion, "%s(): ending index (%d) out of bounds (0, %d)", func, range.location + range.length, CFArrayGetCount(array)); }
CFStringRef CFCopyTypeIDDescription(CFTypeID type) { CFAssert2((NULL != __CFRuntimeClassTable[type]) && __kCFNotATypeTypeID != type && __kCFTypeTypeID != type, __kCFLogAssertion, "%s(): type %d is not a CF type ID", __PRETTY_FUNCTION__, type); return CFStringCreateWithCString(kCFAllocatorSystemDefault, __CFRuntimeClassTable[type]->className, kCFStringEncodingASCII); }
__private_extern__ CFMutableArrayRef __CFArrayCreateMutable0(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks) { CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%d) cannot be less than zero", __PRETTY_FUNCTION__, capacity); CFAssert2(capacity <= LONG_MAX / sizeof(void *), __kCFLogAssertion, "%s(): capacity (%d) is too large for this architecture", __PRETTY_FUNCTION__, capacity); return (CFMutableArrayRef)__CFArrayInit(allocator, __kCFArrayDeque, capacity, callBacks); }