static Boolean __CFDataEqual(CFTypeRef cf1, CFTypeRef cf2) {
    CFDataRef data1 = (CFDataRef)cf1;
    CFDataRef data2 = (CFDataRef)cf2;
    CFIndex length;
    length = __CFDataLength(data1);
    if (length != __CFDataLength(data2)) return false;
    const uint8_t *bytePtr1 = CFDataGetBytePtr(data1);
    const uint8_t *bytePtr2 = CFDataGetBytePtr(data2);
    return 0 == memcmp(bytePtr1, bytePtr2, length);
}
void CFDataSetLength(CFMutableDataRef data, CFIndex newLength) {
    CFIndex oldLength, capacity;
    Boolean isGrowable;
    CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, void, (NSMutableData *)data, setLength:(NSUInteger)newLength);
    CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
    oldLength = __CFDataLength(data);
    capacity = __CFDataCapacity(data);
    isGrowable = __CFDataIsGrowable(data);
    if (__CFDataIsMutable(data)) {
	if (newLength < 0) {
	    if (isGrowable) {
		__CFDataHandleOutOfMemory(data, newLength);
	    } else {
		HALT;
	    }
	} else if (capacity < newLength) {
	    if (isGrowable) {
		__CFDataGrow(data, newLength - oldLength, true);
	    } else {
		CFAssert1(newLength <= __CFDataCapacity(data), __kCFLogAssertion, "%s(): fixed-capacity data is full", __PRETTY_FUNCTION__);
	    }
	} else if (oldLength < newLength && __CFDataNeedsToZero(data)) {
	    memset(CFDataGetMutableBytePtr(data) + oldLength, 0, newLength - oldLength);
	} else if (newLength < oldLength) {
	    __CFDataSetNeedsToZero(data, true);
	}
    }
    __CFDataSetLength(data, newLength);
    __CFDataSetNumBytesUsed(data, newLength);
}
/* Allocates new block of data with at least numNewValues more bytes than the current length. If clear is true, the new bytes up to at least the new length with be zeroed. */
static void __CFDataGrow(CFMutableDataRef data, CFIndex numNewValues, Boolean clear) {
    CFIndex oldLength = __CFDataLength(data);
    CFIndex newLength = oldLength + numNewValues;
    if (newLength > CFDATA_MAX_SIZE || newLength < 0) __CFDataHandleOutOfMemory(data, newLength * sizeof(uint8_t));
    CFIndex capacity = __CFDataRoundUpCapacity(newLength);
    CFIndex numBytes = __CFDataNumBytesForCapacity(capacity);
    CFAllocatorRef allocator = CFGetAllocator(data);
    void *bytes = NULL;
    void *oldBytes = data->_bytes;
    Boolean allocateCleared = clear && __CFDataShouldAllocateCleared(data, numBytes);
    if (allocateCleared && !__CFDataUseAllocator(data) && (oldLength == 0 || (newLength / oldLength) > 4)) {
	// If the length that needs to be zeroed is significantly greater than the length of the data, then calloc/memmove is probably more efficient than realloc/memset.
	bytes = __CFDataAllocate(data, numBytes * sizeof(uint8_t), true);
	if (NULL != bytes) {
	    memmove(bytes, oldBytes, oldLength);
	    __CFDataDeallocate(data);
	}
    }
    if (bytes == NULL) {
	// If the calloc/memmove approach either failed or was never attempted, then realloc.
	allocateCleared = false;
	if (__CFDataUseAllocator(data)) {
	    bytes = CFAllocatorReallocate(allocator, oldBytes, numBytes * sizeof(uint8_t), 0);
	} else {
	    bytes = realloc(oldBytes, numBytes * sizeof(uint8_t));
	}
    }
    if (NULL == bytes) __CFDataHandleOutOfMemory(data, numBytes * sizeof(uint8_t));
    __CFDataSetCapacity(data, capacity);
    __CFDataSetNumBytes(data, numBytes);
    if (clear && !allocateCleared && oldLength < newLength) memset((uint8_t *)bytes + oldLength, 0, newLength - oldLength);
    __CFDataSetNeedsToZero(data, !allocateCleared);
    __CFAssignWithWriteBarrier((void **)&data->_bytes, bytes);
    if (__CFOASafe) __CFSetLastAllocationEventName(data->_bytes, "CFData (store)");
}
static CFStringRef __CFDataCopyDescription(CFTypeRef cf) {
    CFDataRef data = (CFDataRef)cf;
    CFMutableStringRef result;
    CFIndex idx;
    CFIndex len;
    const uint8_t *bytes;
    len = __CFDataLength(data);
    bytes = CFDataGetBytePtr(data);
    result = CFStringCreateMutable(CFGetAllocator(data), 0);
    CFStringAppendFormat(result, NULL, CFSTR("<CFData %p [%p]>{length = %u, capacity = %u, bytes = 0x"), cf, CFGetAllocator(data), len, __CFDataCapacity(data));
    if (24 < len) {
        for (idx = 0; idx < 16; idx += 4) {
	    CFStringAppendFormat(result, NULL, CFSTR("%02x%02x%02x%02x"), bytes[idx], bytes[idx + 1], bytes[idx + 2], bytes[idx + 3]);
	}
        CFStringAppend(result, CFSTR(" ... "));
        for (idx = len - 8; idx < len; idx += 4) {
	    CFStringAppendFormat(result, NULL, CFSTR("%02x%02x%02x%02x"), bytes[idx], bytes[idx + 1], bytes[idx + 2], bytes[idx + 3]);
	}
    } else {
        for (idx = 0; idx < len; idx++) {
	    CFStringAppendFormat(result, NULL, CFSTR("%02x"), bytes[idx]);
	}
    }
    CFStringAppend(result, CFSTR("}"));
    return result;
}
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);
}
void CFDataAppendBytes(CFMutableDataRef data, const uint8_t *bytes, CFIndex length) {
    CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, void, (NSMutableData *)data, appendBytes:(const void *)bytes length:(NSUInteger)length);
    CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
    CFDataReplaceBytes(data, CFRangeMake(__CFDataLength(data), 0), bytes, length); 
}
void CFDataIncreaseLength(CFMutableDataRef data, CFIndex extraLength) {
    CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, void, (NSMutableData *)data, increaseLengthBy:(NSUInteger)extraLength);
    CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
    if (extraLength < 0) HALT; // Avoid integer overflow.
    CFDataSetLength(data, __CFDataLength(data) + extraLength);
}
CFIndex CFDataGetLength(CFDataRef data) {
    CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, CFIndex, (NSData *)data, length);
    __CFGenericValidateType(data, __kCFDataTypeID);
    return __CFDataLength(data);
}
static CFHashCode __CFDataHash(CFTypeRef cf) {
    CFDataRef data = (CFDataRef)cf;
    return CFHashBytes((uint8_t *)CFDataGetBytePtr(data), __CFMin(__CFDataLength(data), 80));
}
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);
}
예제 #11
0
CFIndex CFDataGetLength(CFDataRef data) {
    CF_OBJC_FUNCDISPATCH0(__kCFDataTypeID, CFIndex, data, "length");
    __CFGenericValidateType(data, __kCFDataTypeID);
    return __CFDataLength(data);
}