extern pascal OSStatus CFQDictionaryCreateWithArrayOfKeysAndValues(CFArrayRef keys, CFArrayRef values, CFDictionaryRef *result) // See comment in header. { OSStatus err; CFIndex count; CFTypeRef * keysBuffer; CFTypeRef * valuesBuffer; assert(keys != NULL); assert(values != NULL); assert( CFArrayGetCount(keys) == CFArrayGetCount(values) ); assert( result != NULL); assert(*result == NULL); keysBuffer = NULL; valuesBuffer = NULL; // Check that the arrays are of a like size. err = noErr; count = CFArrayGetCount(keys); if ( count != CFArrayGetCount(values) ) { err = paramErr; } // Allocate a buffer for both keys and values. if (err == noErr) { err = CFQAllocate(sizeof(CFTypeRef) * count, (void **) &keysBuffer); } if (err == noErr) { err = CFQAllocate(sizeof(CFTypeRef) * count, (void **) &valuesBuffer); } // Get the keys and values into their buffers, and create a // dictionary based on the buffer. if (err == noErr) { CFArrayGetValues(keys, CFRangeMake(0, count), keysBuffer); CFArrayGetValues(values, CFRangeMake(0, count), valuesBuffer); *result = CFDictionaryCreate(NULL, keysBuffer, valuesBuffer, count, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (*result == NULL) { err = coreFoundationUnknownErr; } } // Clean up. CFQDeallocate(keysBuffer); CFQDeallocate(valuesBuffer); return err; }
static OSStatus PathArrayHelper(CFArrayRef path, CFTypeRef **pathElements) // pathElements is a pointer to an array of CFTypeRefs. // On return, *pathElements is set to a newly allocated // array which you must free using "free". { OSStatus err; CFIndex pathElementCount; assert(path != NULL); assert(pathElements != NULL); // We don't assert that *pathElements is NULL because part of // our semantics is that we always set it to NULL. pathElementCount = CFArrayGetCount(path); assert(pathElementCount > 0); err = noErr; *pathElements = (CFTypeRef *) malloc(sizeof(CFTypeRef) * pathElementCount); // pathElementCount > 0, so malloc(0) not possible if (*pathElements == NULL) { err = memFullErr; } if (err == noErr) { CFArrayGetValues(path, CFRangeMake(0, pathElementCount), *pathElements); } assert( (err == noErr) == (*pathElements != NULL) ); return err; }
extern CFIndex INXRetrieveStrings(CFArrayRef argv, CFIndex maxArguments, CFStringRef* storage) { memset(storage, 0, maxArguments*sizeof(*storage)); CFIndex count = CFArrayGetCount(argv); if (count <= 1) return 0; CFIndex argsGot = count-1; if (argsGot > maxArguments) argsGot = maxArguments; CFArrayGetValues(argv, CFRangeMake(1, argsGot), (const void**)storage); return argsGot; }
void encode(ArgumentEncoder* encoder, CFArrayRef array) { CFIndex size = CFArrayGetCount(array); Vector<CFTypeRef, 32> values(size); CFArrayGetValues(array, CFRangeMake(0, size), values.data()); encoder->encodeUInt64(size); for (CFIndex i = 0; i < size; ++i) { ASSERT(values[i]); encode(encoder, values[i]); } }
__private_extern__ void _CFArraySortValues(CFMutableArrayRef array, CFComparatorFunction comparator, void *context) { CFRange range = {0, CFArrayGetCount(array)}; if (range.length < 2) { return; } // implemented abstractly, careful! const void **values, *buffer[256]; values = (range.length <= 256) ? (const void **)buffer : (const void **)CFAllocatorAllocate(kCFAllocatorSystemDefault, range.length * sizeof(void *), 0); // GC OK CFArrayGetValues(array, range, values); struct _acompareContext ctx; ctx.func = comparator; ctx.context = context; CFQSortArray(values, range.length, sizeof(void *), (CFComparatorFunction)__CFArrayCompareValues, &ctx); CFArrayReplaceValues(array, range, values, range.length); if (values != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, values); }
static void encodeCertificateChain(Encoder& encoder, CFArrayRef certificateChain) { CFIndex size = CFArrayGetCount(certificateChain); Vector<CFTypeRef, 32> values(size); CFArrayGetValues(certificateChain, CFRangeMake(0, size), values.data()); encoder << static_cast<uint64_t>(size); for (CFIndex i = 0; i < size; ++i) { ASSERT(values[i]); ASSERT(CFGetTypeID(values[i]) == SecCertificateGetTypeID()); auto data = adoptCF(SecCertificateCopyData((SecCertificateRef)values[i])); encodeCFData(encoder, data.get()); } }
void CFArraySortValues(CFMutableArrayRef array, CFRange range, CFComparatorFunction comparator, void *context) { FAULT_CALLBACK((void **)&(comparator)); __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CFAssert1(NULL != comparator, __kCFLogAssertion, "%s(): pointer to comparator function may not be NULL", __PRETTY_FUNCTION__); Boolean immutable = false; if (CF_IS_OBJC(__kCFArrayTypeID, array)) { BOOL result; CF_OBJC_CALL1(BOOL, result, array, "isKindOfClass:", objc_lookUpClass("NSMutableArray")); immutable = !result; } else if (__kCFArrayImmutable == __CFArrayGetType(array)) { immutable = true; } const CFArrayCallBacks *cb = NULL; if (CF_IS_OBJC(__kCFArrayTypeID, array)) { cb = &kCFTypeArrayCallBacks; } else { cb = __CFArrayGetCallBacks(array); } if (!immutable && ((cb->retain && !cb->release) || (!cb->retain && cb->release))) { __CFZSort(array, range, comparator, context); return; } if (range.length < 2) { return; } // implemented abstractly, careful! const void **values, *buffer[256]; values = (range.length <= 256) ? (const void **)buffer : (const void **)CFAllocatorAllocate(kCFAllocatorSystemDefault, range.length * sizeof(void *), 0); // GC OK CFArrayGetValues(array, range, values); struct _acompareContext ctx; ctx.func = comparator; ctx.context = context; CFQSortArray(values, range.length, sizeof(void *), (CFComparatorFunction)__CFArrayCompareValues, &ctx); if (!immutable) CFArrayReplaceValues(array, range, values, range.length); if (values != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, values); }
CFStringRef _SCCopyDescription(CFTypeRef cf, CFDictionaryRef formatOptions) { #ifdef ENABLE_SC_FORMATTING CFMutableDictionaryRef nFormatOptions; CFStringRef prefix1; CFStringRef prefix2; CFTypeID type = CFGetTypeID(cf); if (!formatOptions || !CFDictionaryGetValueIfPresent(formatOptions, CFSTR("PREFIX1"), (const void **)&prefix1)) { prefix1 = CFSTR(""); } if (type == CFStringGetTypeID()) { return CFStringCreateWithFormat(NULL, formatOptions, CFSTR("%@%@"), prefix1, cf); } if (type == CFBooleanGetTypeID()) { return CFStringCreateWithFormat(NULL, formatOptions, CFSTR("%@%s"), prefix1, CFBooleanGetValue(cf) ? "TRUE" : "FALSE"); } if (type == CFDataGetTypeID()) { const uint8_t *data; CFIndex dataLen; CFIndex i; CFMutableStringRef str; str = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(str, formatOptions, CFSTR("%@<data> 0x"), prefix1); data = CFDataGetBytePtr(cf); dataLen = CFDataGetLength(cf); for (i = 0; i < dataLen; i++) { CFStringAppendFormat(str, NULL, CFSTR("%02x"), data[i]); } return str; } if (type == CFNumberGetTypeID()) { return CFStringCreateWithFormat(NULL, formatOptions, CFSTR("%@%@"), prefix1, cf); } if (type == CFDateGetTypeID()) { CFCalendarRef calendar; CFStringRef str; CFTimeZoneRef tz; int MM, DD, YYYY, hh, mm, ss; calendar = CFCalendarCreateWithIdentifier(NULL, kCFGregorianCalendar); tz = CFTimeZoneCopySystem(); CFCalendarSetTimeZone(calendar, tz); CFRelease(tz); CFCalendarDecomposeAbsoluteTime(calendar, CFDateGetAbsoluteTime(cf), "MdyHms", &MM, &DD, &YYYY, &hh, &mm, &ss); CFRelease(calendar); str = CFStringCreateWithFormat(NULL, formatOptions, CFSTR("%@%02d/%02d/%04d %02d:%02d:%02d"), prefix1, MM, DD, YYYY, hh, mm, ss); return str; } if ((formatOptions == NULL) || !CFDictionaryGetValueIfPresent(formatOptions, CFSTR("PREFIX2"), (const void **)&prefix2)) { prefix2 = prefix1; } if (formatOptions != NULL) { nFormatOptions = CFDictionaryCreateMutableCopy(NULL, 0, formatOptions); } else { nFormatOptions = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } assert(nFormatOptions != NULL); #define N_QUICK 32 if (type == CFArrayGetTypeID()) { const void * elements_q[N_QUICK]; const void ** elements = elements_q; CFIndex i; CFIndex nElements; CFMutableStringRef str; str = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(str, formatOptions, CFSTR("%@<array> {"), prefix1); nElements = CFArrayGetCount(cf); if (nElements > 0) { if (nElements > (CFIndex)(sizeof(elements_q)/sizeof(CFTypeRef))) elements = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0); CFArrayGetValues(cf, CFRangeMake(0, nElements), elements); for (i = 0; i < nElements; i++) { CFMutableStringRef nPrefix1; CFMutableStringRef nPrefix2; CFStringRef nStr; CFStringRef vStr; nStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), i); nPrefix1 = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(nPrefix1, formatOptions, CFSTR("%@ %@ : "), prefix2, nStr); nPrefix2 = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(nPrefix2, formatOptions, CFSTR("%@ "), prefix2); CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX1"), nPrefix1); CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX2"), nPrefix2); CFRelease(nPrefix1); CFRelease(nPrefix2); CFRelease(nStr); vStr = _SCCopyDescription((CFTypeRef)elements[i], nFormatOptions); CFStringAppendFormat(str, formatOptions, CFSTR("\n%@"), vStr); CFRelease(vStr); } if (elements != elements_q) CFAllocatorDeallocate(NULL, elements); } CFStringAppendFormat(str, formatOptions, CFSTR("\n%@}"), prefix2); CFRelease(nFormatOptions); return str; } if (type == CFDictionaryGetTypeID()) { const void * keys_q[N_QUICK]; const void ** keys = keys_q; CFIndex i; CFIndex nElements; CFMutableStringRef nPrefix1; CFMutableStringRef nPrefix2; CFMutableStringRef str; str = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(str, formatOptions, CFSTR("%@<dictionary> {"), prefix1); nElements = CFDictionaryGetCount(cf); if (nElements > 0) { CFComparatorFunction compFunc = NULL; CFMutableArrayRef sortedKeys; if (nElements > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) { keys = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0); } CFDictionaryGetKeysAndValues(cf, keys, NULL); sortedKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for (i = 0; i < nElements; i++) { CFArrayAppendValue(sortedKeys, (CFStringRef)keys[i]); } if (isA_CFString(keys[0])) { compFunc = (CFComparatorFunction)CFStringCompare; } else if (isA_CFNumber(keys[0])) { compFunc = (CFComparatorFunction)CFNumberCompare; } else if (isA_CFDate(keys[0])) { compFunc = (CFComparatorFunction)CFDateCompare; } if (compFunc != NULL) { CFArraySortValues(sortedKeys, CFRangeMake(0, nElements), compFunc, NULL); } for (i = 0; i < nElements; i++) { CFStringRef key; CFStringRef kStr; CFTypeRef val; CFStringRef vStr; key = CFArrayGetValueAtIndex(sortedKeys, i); kStr = _SCCopyDescription((CFTypeRef)key, NULL); nPrefix1 = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(nPrefix1, formatOptions, CFSTR("%@ %@ : "), prefix2, kStr); nPrefix2 = CFStringCreateMutable(NULL, 0); CFStringAppendFormat(nPrefix2, formatOptions, CFSTR("%@ "), prefix2); CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX1"), nPrefix1); CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX2"), nPrefix2); CFRelease(nPrefix1); CFRelease(nPrefix2); CFRelease(kStr); val = CFDictionaryGetValue(cf, key); vStr = _SCCopyDescription((CFTypeRef)val, nFormatOptions); CFStringAppendFormat(str, formatOptions, CFSTR("\n%@"), vStr); CFRelease(vStr); } CFRelease(sortedKeys); if (keys != keys_q) { CFAllocatorDeallocate(NULL, keys); } } CFStringAppendFormat(str, formatOptions, CFSTR("\n%@}"), prefix2); CFRelease(nFormatOptions); return str; } CFRelease(nFormatOptions); #endif /* ENABLE_SC_FORMATTING */ return CFStringCreateWithFormat(NULL, formatOptions, CFSTR("%@%@"), prefix1, cf); }