void CFArrayAppendArray(CFMutableArrayRef array, CFArrayRef otherArray, CFRange otherRange) { __CFArrayValidateRange(otherArray, otherRange, __PRETTY_FUNCTION__); // implemented abstractly, careful! for (CFIndex idx = otherRange.location; idx < otherRange.location + otherRange.length; idx++) { CFArrayAppendValue(array, CFArrayGetValueAtIndex(otherArray, idx)); } }
CFIndex CFArrayBSearchValues(CFArrayRef array, CFRange range, const void *value, 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__); // implemented abstractly, careful! if (range.length <= 0) return range.location; const void *item = CFArrayGetValueAtIndex(array, range.location + range.length - 1); if ((CFComparisonResult)(INVOKE_CALLBACK3(comparator, item, value, context)) < 0) { return range.location + range.length; } item = CFArrayGetValueAtIndex(array, range.location); if ((CFComparisonResult)(INVOKE_CALLBACK3(comparator, value, item, context)) < 0) { return range.location; } SInt32 lg = flsl(range.length) - 1; // lg2(range.length) item = CFArrayGetValueAtIndex(array, range.location + -1 + (1 << lg)); // idx will be the current probe index into the range CFIndex idx = (comparator(item, value, context) < 0) ? range.length - (1 << lg) : -1; while (lg--) { item = CFArrayGetValueAtIndex(array, range.location + idx + (1 << lg)); if (comparator(item, value, context) < 0) { idx += (1 << lg); } } idx++; return idx + range.location; }
void CFArrayReplaceValues(CFMutableArrayRef array, CFRange range, const void **newValues, CFIndex newCount) { CF_OBJC_FUNCDISPATCHV(__kCFArrayTypeID, void, (NSMutableArray *)array, replaceObjectsInRange:NSMakeRange(range.location, range.length) withObjects:(id *)newValues count:(NSUInteger)newCount); __CFGenericValidateType(array, __kCFArrayTypeID); __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__); CFAssert2(0 <= newCount, __kCFLogAssertion, "%s(): newCount (%d) cannot be less than zero", __PRETTY_FUNCTION__, newCount); CHECK_FOR_MUTATION(array); return _CFArrayReplaceValues(array, range, newValues, newCount); }
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; result = CF_OBJC_CALLV((NSMutableArray *)array, isKindOfClass:[NSMutableArray class]); immutable = !result; } else if (__kCFArrayImmutable == __CFArrayGetType(array)) {
void CFArrayApplyFunction(CFArrayRef array, CFRange range, CFArrayApplierFunction applier, void *context) { CFIndex idx; FAULT_CALLBACK((void **)&(applier)); __CFGenericValidateType(array, __kCFArrayTypeID); __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CFAssert1(NULL != applier, __kCFLogAssertion, "%s(): pointer to applier function may not be NULL", __PRETTY_FUNCTION__); CHECK_FOR_MUTATION(array); for (idx = 0; idx < range.length; idx++) { const void *item = CFArrayGetValueAtIndex(array, range.location + idx); INVOKE_CALLBACK2(applier, item, context); } }
CFIndex CFArrayGetLastIndexOfValue(CFArrayRef array, CFRange range, const void *value) { CFIndex idx; __CFGenericValidateType(array, __kCFArrayTypeID); __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CHECK_FOR_MUTATION(array); const CFArrayCallBacks *cb = CF_IS_OBJC(CFArrayGetTypeID(), array) ? &kCFTypeArrayCallBacks : __CFArrayGetCallBacks(array); for (idx = range.length; idx--;) { const void *item = CFArrayGetValueAtIndex(array, range.location + idx); if (value == item || (cb->equal && INVOKE_CALLBACK2(cb->equal, value, item))) return idx + range.location; } return kCFNotFound; }
Boolean CFArrayContainsValue(CFArrayRef array, CFRange range, const void *value) { CFIndex idx; __CFGenericValidateType(array, __kCFArrayTypeID); __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CHECK_FOR_MUTATION(array); const CFArrayCallBacks *cb = CF_IS_OBJC(CFArrayGetTypeID(), array) ? &kCFTypeArrayCallBacks : __CFArrayGetCallBacks(array); for (idx = 0; idx < range.length; idx++) { const void *item = CFArrayGetValueAtIndex(array, range.location + idx); if (value == item || (cb->equal && INVOKE_CALLBACK2(cb->equal, value, item))) { return true; } } return false; }
void CFArrayGetValues(CFArrayRef array, CFRange range, const void **values) { CF_OBJC_FUNCDISPATCHV(__kCFArrayTypeID, void, (NSArray *)array, getObjects:(id *)values range:NSMakeRange(range.location, range.length)); __CFGenericValidateType(array, __kCFArrayTypeID); __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__); CFAssert1(NULL != values, __kCFLogAssertion, "%s(): pointer to values may not be NULL", __PRETTY_FUNCTION__); CHECK_FOR_MUTATION(array); if (0 < range.length) { switch (__CFArrayGetType(array)) { case __kCFArrayImmutable: case __kCFArrayDeque: objc_memmove_collectable(values, __CFArrayGetBucketsPtr(array) + range.location, range.length * sizeof(struct __CFArrayBucket)); break; } } }
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); }