/*
- * Copyright (c) 2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2011 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
*/
/* CFSet.c
- Copyright 1998-2008, Apple, Inc. All rights reserved.
+ Copyright (c) 1998-2011, Apple Inc. All rights reserved.
Responsibility: Christopher Kane
Machine generated from Notes/HashingCode.template
*/
const CFSetKeyCallBacks kCFTypeSetKeyCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
const CFSetKeyCallBacks kCFCopyStringSetKeyCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
const CFSetValueCallBacks kCFTypeSetValueCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual};
+__private_extern__ const CFSetValueCallBacks kCFTypeSetValueCompactableCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual};
static const CFSetKeyCallBacks __kCFNullSetKeyCallBacks = {0, NULL, NULL, NULL, NULL, NULL};
static const CFSetValueCallBacks __kCFNullSetValueCallBacks = {0, NULL, NULL, NULL, NULL};
return __kCFSetTypeID;
}
-static uintptr_t __CFSetCallback(CFBasicHashRef ht, uint8_t op, uintptr_t a1, uintptr_t a2, CFBasicHashCallbacks *cb) {
- switch (op) {
- case kCFBasicHashCallbackOpCopyCallbacks: {
- CFBasicHashCallbacks *newcb = NULL;
- if (CF_IS_COLLECTABLE_ALLOCATOR((CFAllocatorRef)a1)) {
- newcb = (CFBasicHashCallbacks *)auto_zone_allocate_object(auto_zone(), 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED, true, false);
- } else {
- newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate((CFAllocatorRef)a1, 10 * sizeof(void *), 0);
- }
- if (!newcb) HALT;
- memmove(newcb, (void *)cb, 10 * sizeof(void *));
- return (uintptr_t)newcb;
- }
- case kCFBasicHashCallbackOpFreeCallbacks: {
- if (CF_IS_COLLECTABLE_ALLOCATOR((CFAllocatorRef)a1)) {
- auto_zone_release(auto_zone(), cb);
- } else {
- CFAllocatorDeallocate((CFAllocatorRef)a1, cb);
- }
- return 0;
- }
- case kCFBasicHashCallbackOpRetainValue: {
- const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = (const_any_pointer_t (*)(CFAllocatorRef, const_any_pointer_t))cb->context[0];
- if (NULL == value_retain) return a1;
- return (uintptr_t)INVOKE_CALLBACK2(value_retain, CFGetAllocator(ht), (const_any_pointer_t)a1);
- }
- case kCFBasicHashCallbackOpRetainKey: {
- const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = (const_any_pointer_t (*)(CFAllocatorRef, const_any_pointer_t))cb->context[1];
- if (NULL == key_retain) return a1;
- return (uintptr_t)INVOKE_CALLBACK2(key_retain, CFGetAllocator(ht), (const_any_pointer_t)a1);
- }
- case kCFBasicHashCallbackOpReleaseValue: {
- void (*value_release)(CFAllocatorRef, const_any_pointer_t) = (void (*)(CFAllocatorRef, const_any_pointer_t))cb->context[2];
- if (NULL != value_release) INVOKE_CALLBACK2(value_release, CFGetAllocator(ht), (const_any_pointer_t)a1);
- return 0;
- }
- case kCFBasicHashCallbackOpReleaseKey: {
- void (*key_release)(CFAllocatorRef, const_any_pointer_t) = (void (*)(CFAllocatorRef, const_any_pointer_t))cb->context[3];
- if (NULL != key_release) INVOKE_CALLBACK2(key_release, CFGetAllocator(ht), (const_any_pointer_t)a1);
- return 0;
- }
- case kCFBasicHashCallbackOpValueEqual: {
- Boolean (*value_equal)(const_any_pointer_t, const_any_pointer_t) = (Boolean (*)(const_any_pointer_t, const_any_pointer_t))cb->context[4];
- if (NULL == value_equal) return (a1 == a2);
- return INVOKE_CALLBACK2(value_equal, (const_any_pointer_t)a1, (const_any_pointer_t)a2) ? 1 : 0;
- }
- case kCFBasicHashCallbackOpKeyEqual: {
- Boolean (*key_equal)(const_any_pointer_t, const_any_pointer_t) = (Boolean (*)(const_any_pointer_t, const_any_pointer_t))cb->context[5];
- if (NULL == key_equal) return (a1 == a2);
- return INVOKE_CALLBACK2(key_equal, (const_any_pointer_t)a1, (const_any_pointer_t)a2) ? 1 : 0;
- }
- case kCFBasicHashCallbackOpHashKey: {
- CFHashCode (*hash)(const_any_pointer_t) = (CFHashCode (*)(const_any_pointer_t))cb->context[6];
- if (NULL == hash) return a1;
- return (uintptr_t)INVOKE_CALLBACK1(hash, (const_any_pointer_t)a1);
- }
- case kCFBasicHashCallbackOpDescribeValue: {
- CFStringRef (*value_describe)(const_any_pointer_t) = (CFStringRef (*)(const_any_pointer_t))cb->context[7];
- if (NULL == value_describe) return (uintptr_t)CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (const_any_pointer_t)a1);
- return (uintptr_t)INVOKE_CALLBACK1(value_describe, (const_any_pointer_t)a1);
- }
- case kCFBasicHashCallbackOpDescribeKey: {
- CFStringRef (*key_describe)(const_any_pointer_t) = (CFStringRef (*)(const_any_pointer_t))cb->context[8];
- if (NULL == key_describe) return (uintptr_t)CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (const_any_pointer_t)a1);
- return (uintptr_t)INVOKE_CALLBACK1(key_describe, (const_any_pointer_t)a1);
+#define GCRETAIN(A, B) kCFTypeSetCallBacks.retain(A, B)
+#define GCRELEASE(A, B) kCFTypeSetCallBacks.release(A, B)
+
+static uintptr_t __CFSetStandardRetainValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
+ if (CFBasicHashGetSpecialBits(ht) & 0x0100) return stack_value;
+ return (CFBasicHashHasStrongValues(ht)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault, (CFTypeRef)stack_value) : (uintptr_t)CFRetain((CFTypeRef)stack_value);
+}
+
+static uintptr_t __CFSetStandardRetainKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
+ if (CFBasicHashGetSpecialBits(ht) & 0x0001) return stack_key;
+ return (CFBasicHashHasStrongKeys(ht)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault, (CFTypeRef)stack_key) : (uintptr_t)CFRetain((CFTypeRef)stack_key);
+}
+
+static void __CFSetStandardReleaseValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
+ if (CFBasicHashGetSpecialBits(ht) & 0x0200) return;
+ if (CFBasicHashHasStrongValues(ht)) GCRELEASE(kCFAllocatorSystemDefault, (CFTypeRef)stack_value); else CFRelease((CFTypeRef)stack_value);
+}
+
+static void __CFSetStandardReleaseKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
+ if (CFBasicHashGetSpecialBits(ht) & 0x0002) return;
+ if (CFBasicHashHasStrongKeys(ht)) GCRELEASE(kCFAllocatorSystemDefault, (CFTypeRef)stack_key); else CFRelease((CFTypeRef)stack_key);
+}
+
+static Boolean __CFSetStandardEquateValues(CFConstBasicHashRef ht, uintptr_t coll_value1, uintptr_t stack_value2) {
+ if (CFBasicHashGetSpecialBits(ht) & 0x0400) return coll_value1 == stack_value2;
+ return CFEqual((CFTypeRef)coll_value1, (CFTypeRef)stack_value2);
+}
+
+static Boolean __CFSetStandardEquateKeys(CFConstBasicHashRef ht, uintptr_t coll_key1, uintptr_t stack_key2) {
+ if (CFBasicHashGetSpecialBits(ht) & 0x0004) return coll_key1 == stack_key2;
+ return CFEqual((CFTypeRef)coll_key1, (CFTypeRef)stack_key2);
+}
+
+static uintptr_t __CFSetStandardHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
+ if (CFBasicHashGetSpecialBits(ht) & 0x0008) return stack_key;
+ return (uintptr_t)CFHash((CFTypeRef)stack_key);
+}
+
+static uintptr_t __CFSetStandardGetIndirectKey(CFConstBasicHashRef ht, uintptr_t coll_value) {
+ return 0;
+}
+
+static CFStringRef __CFSetStandardCopyValueDescription(CFConstBasicHashRef ht, uintptr_t stack_value) {
+ if (CFBasicHashGetSpecialBits(ht) & 0x0800) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_value);
+ return CFCopyDescription((CFTypeRef)stack_value);
+}
+
+static CFStringRef __CFSetStandardCopyKeyDescription(CFConstBasicHashRef ht, uintptr_t stack_key) {
+ if (CFBasicHashGetSpecialBits(ht) & 0x0010) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_key);
+ return CFCopyDescription((CFTypeRef)stack_key);
+}
+
+static CFBasicHashCallbacks *__CFSetStandardCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb);
+static void __CFSetStandardFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb);
+
+static const CFBasicHashCallbacks CFSetStandardCallbacks = {
+ __CFSetStandardCopyCallbacks,
+ __CFSetStandardFreeCallbacks,
+ __CFSetStandardRetainValue,
+ __CFSetStandardRetainKey,
+ __CFSetStandardReleaseValue,
+ __CFSetStandardReleaseKey,
+ __CFSetStandardEquateValues,
+ __CFSetStandardEquateKeys,
+ __CFSetStandardHashKey,
+ __CFSetStandardGetIndirectKey,
+ __CFSetStandardCopyValueDescription,
+ __CFSetStandardCopyKeyDescription
+};
+
+static CFBasicHashCallbacks *__CFSetStandardCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
+ return (CFBasicHashCallbacks *)&CFSetStandardCallbacks;
+}
+
+static void __CFSetStandardFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
+}
+
+
+static CFBasicHashCallbacks *__CFSetCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
+ CFBasicHashCallbacks *newcb = NULL;
+ if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+ newcb = (CFBasicHashCallbacks *)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED, false, false);
+ } else {
+ newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
}
+ if (!newcb) HALT;
+ memmove(newcb, (void *)cb, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *));
+ return newcb;
+}
+
+static void __CFSetFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
+ if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+ } else {
+ CFAllocatorDeallocate(allocator, cb);
}
+}
+
+static uintptr_t __CFSetRetainValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
+ const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
+ const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = (const_any_pointer_t (*)(CFAllocatorRef, const_any_pointer_t))cb->context[0];
+ if (NULL == value_retain) return stack_value;
+ return (uintptr_t)INVOKE_CALLBACK2(value_retain, CFGetAllocator(ht), (const_any_pointer_t)stack_value);
+}
+
+static uintptr_t __CFSetRetainKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
+ const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
+ const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = (const_any_pointer_t (*)(CFAllocatorRef, const_any_pointer_t))cb->context[1];
+ if (NULL == key_retain) return stack_key;
+ return (uintptr_t)INVOKE_CALLBACK2(key_retain, CFGetAllocator(ht), (const_any_pointer_t)stack_key);
+}
+
+static void __CFSetReleaseValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
+ const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
+ void (*value_release)(CFAllocatorRef, const_any_pointer_t) = (void (*)(CFAllocatorRef, const_any_pointer_t))cb->context[2];
+ if (NULL != value_release) INVOKE_CALLBACK2(value_release, CFGetAllocator(ht), (const_any_pointer_t) stack_value);
+}
+
+static void __CFSetReleaseKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
+ const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
+ void (*key_release)(CFAllocatorRef, const_any_pointer_t) = (void (*)(CFAllocatorRef, const_any_pointer_t))cb->context[3];
+ if (NULL != key_release) INVOKE_CALLBACK2(key_release, CFGetAllocator(ht), (const_any_pointer_t) stack_key);
+}
+
+static Boolean __CFSetEquateValues(CFConstBasicHashRef ht, uintptr_t coll_value1, uintptr_t stack_value2) {
+ const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
+ Boolean (*value_equal)(const_any_pointer_t, const_any_pointer_t) = (Boolean (*)(const_any_pointer_t, const_any_pointer_t))cb->context[4];
+ if (NULL == value_equal) return (coll_value1 == stack_value2);
+ return INVOKE_CALLBACK2(value_equal, (const_any_pointer_t) coll_value1, (const_any_pointer_t) stack_value2) ? 1 : 0;
+}
+
+static Boolean __CFSetEquateKeys(CFConstBasicHashRef ht, uintptr_t coll_key1, uintptr_t stack_key2) {
+ const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
+ Boolean (*key_equal)(const_any_pointer_t, const_any_pointer_t) = (Boolean (*)(const_any_pointer_t, const_any_pointer_t))cb->context[5];
+ if (NULL == key_equal) return (coll_key1 == stack_key2);
+ return INVOKE_CALLBACK2(key_equal, (const_any_pointer_t) coll_key1, (const_any_pointer_t) stack_key2) ? 1 : 0;
+}
+
+static uintptr_t __CFSetHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
+ const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
+ CFHashCode (*hash)(const_any_pointer_t) = (CFHashCode (*)(const_any_pointer_t))cb->context[6];
+ if (NULL == hash) return stack_key;
+ return (uintptr_t)INVOKE_CALLBACK1(hash, (const_any_pointer_t) stack_key);
+}
+
+static uintptr_t __CFSetGetIndirectKey(CFConstBasicHashRef ht, uintptr_t coll_value) {
return 0;
}
-static CFBasicHashRef __CFSetCreateGeneric(CFAllocatorRef allocator, const CFHashKeyCallBacks *keyCallBacks, const CFHashValueCallBacks *valueCallBacks, Boolean useValueCB) {
+static CFStringRef __CFSetCopyValueDescription(CFConstBasicHashRef ht, uintptr_t stack_value) {
+ const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
+ CFStringRef (*value_describe)(const_any_pointer_t) = (CFStringRef (*)(const_any_pointer_t))cb->context[8];
+ if (NULL == value_describe) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (const_any_pointer_t) stack_value);
+ return (CFStringRef)INVOKE_CALLBACK1(value_describe, (const_any_pointer_t) stack_value);
+}
- CFBasicHashCallbacks *cb = NULL;
+static CFStringRef __CFSetCopyKeyDescription(CFConstBasicHashRef ht, uintptr_t stack_key) {
+ const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
+ CFStringRef (*key_describe)(const_any_pointer_t) = (CFStringRef (*)(const_any_pointer_t))cb->context[9];
+ if (NULL == key_describe) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (const_any_pointer_t) stack_key);
+ return (CFStringRef)INVOKE_CALLBACK1(key_describe, (const_any_pointer_t) stack_key);
+}
+
+static CFBasicHashRef __CFSetCreateGeneric(CFAllocatorRef allocator, const CFHashKeyCallBacks *keyCallBacks, const CFHashValueCallBacks *valueCallBacks, Boolean useValueCB) {
CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing
flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0);
+ CFBasicHashCallbacks *cb = NULL;
+ Boolean std_cb = false;
+ uint16_t specialBits = 0;
const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
void (*key_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
void (*value_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
- Boolean std_cb = false;
- if ((NULL == keyCallBacks || (keyCallBacks && 0 == memcmp(&__kCFNullSetKeyCallBacks, keyCallBacks, sizeof(__kCFNullSetKeyCallBacks))))
- && (!useValueCB || (NULL == valueCallBacks || (valueCallBacks && 0 == memcmp(&__kCFNullSetValueCallBacks, valueCallBacks, sizeof(__kCFNullSetValueCallBacks)))))) {
- cb = (CFBasicHashCallbacks *)& CFBasicHashNullCallbacks;
- } else if ((&kCFTypeSetKeyCallBacks == keyCallBacks || (keyCallBacks && 0 == memcmp(&kCFTypeSetKeyCallBacks, keyCallBacks, sizeof(kCFTypeSetKeyCallBacks))))
- && (!useValueCB || (&kCFTypeSetValueCallBacks == valueCallBacks || (valueCallBacks && 0 == memcmp(&kCFTypeSetValueCallBacks, valueCallBacks, sizeof(kCFTypeSetValueCallBacks)))))) {
- std_cb = true;
- cb = (CFBasicHashCallbacks *)& CFBasicHashStandardCallbacks;
- } else {
+
+ if ((NULL == keyCallBacks || 0 == keyCallBacks->version) && (!useValueCB || NULL == valueCallBacks || 0 == valueCallBacks->version)) {
+ Boolean keyRetainNull = NULL == keyCallBacks || NULL == keyCallBacks->retain;
+ Boolean keyReleaseNull = NULL == keyCallBacks || NULL == keyCallBacks->release;
+ Boolean keyEquateNull = NULL == keyCallBacks || NULL == keyCallBacks->equal;
+ Boolean keyHashNull = NULL == keyCallBacks || NULL == keyCallBacks->hash;
+ Boolean keyDescribeNull = NULL == keyCallBacks || NULL == keyCallBacks->copyDescription;
+
+ Boolean valueRetainNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->retain)) || (!useValueCB && keyRetainNull);
+ Boolean valueReleaseNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->release)) || (!useValueCB && keyReleaseNull);
+ Boolean valueEquateNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->equal)) || (!useValueCB && keyEquateNull);
+ Boolean valueDescribeNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeNull);
+
+ Boolean keyRetainStd = keyRetainNull || __CFTypeCollectionRetain == keyCallBacks->retain;
+ Boolean keyReleaseStd = keyReleaseNull || __CFTypeCollectionRelease == keyCallBacks->release;
+ Boolean keyEquateStd = keyEquateNull || CFEqual == keyCallBacks->equal;
+ Boolean keyHashStd = keyHashNull || CFHash == keyCallBacks->hash;
+ Boolean keyDescribeStd = keyDescribeNull || CFCopyDescription == keyCallBacks->copyDescription;
+
+ Boolean valueRetainStd = (useValueCB && (valueRetainNull || __CFTypeCollectionRetain == valueCallBacks->retain)) || (!useValueCB && keyRetainStd);
+ Boolean valueReleaseStd = (useValueCB && (valueReleaseNull || __CFTypeCollectionRelease == valueCallBacks->release)) || (!useValueCB && keyReleaseStd);
+ Boolean valueEquateStd = (useValueCB && (valueEquateNull || CFEqual == valueCallBacks->equal)) || (!useValueCB && keyEquateStd);
+ Boolean valueDescribeStd = (useValueCB && (valueDescribeNull || CFCopyDescription == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeStd);
+
+ if (keyRetainStd && keyReleaseStd && keyEquateStd && keyHashStd && keyDescribeStd && valueRetainStd && valueReleaseStd && valueEquateStd && valueDescribeStd) {
+ cb = (CFBasicHashCallbacks *)&CFSetStandardCallbacks;
+ if (!(keyRetainNull || keyReleaseNull || keyEquateNull || keyHashNull || keyDescribeNull || valueRetainNull || valueReleaseNull || valueEquateNull || valueDescribeNull)) {
+ std_cb = true;
+ } else {
+ // just set these to tickle the GC Strong logic below in a way that mimics past practice
+ key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
+ key_release = keyCallBacks ? keyCallBacks->release : NULL;
+ if (useValueCB) {
+ value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
+ value_release = valueCallBacks ? valueCallBacks->release : NULL;
+ } else {
+ value_retain = key_retain;
+ value_release = key_release;
+ }
+ }
+ if (keyRetainNull) specialBits |= 0x0001;
+ if (keyReleaseNull) specialBits |= 0x0002;
+ if (keyEquateNull) specialBits |= 0x0004;
+ if (keyHashNull) specialBits |= 0x0008;
+ if (keyDescribeNull) specialBits |= 0x0010;
+ if (valueRetainNull) specialBits |= 0x0100;
+ if (valueReleaseNull) specialBits |= 0x0200;
+ if (valueEquateNull) specialBits |= 0x0400;
+ if (valueDescribeNull) specialBits |= 0x0800;
+ }
+ }
+
+ if (!cb) {
Boolean (*key_equal)(const_any_pointer_t, const_any_pointer_t) = NULL;
Boolean (*value_equal)(const_any_pointer_t, const_any_pointer_t) = NULL;
CFStringRef (*key_describe)(const_any_pointer_t) = NULL;
value_describe = key_describe;
}
hash_key = keyCallBacks ? keyCallBacks->hash : NULL;
- FAULT_CALLBACK((void **)&key_retain);
- FAULT_CALLBACK((void **)&key_release);
- FAULT_CALLBACK((void **)&value_retain);
- FAULT_CALLBACK((void **)&value_release);
- FAULT_CALLBACK((void **)&key_equal);
- FAULT_CALLBACK((void **)&value_equal);
- FAULT_CALLBACK((void **)&key_describe);
- FAULT_CALLBACK((void **)&value_describe);
- FAULT_CALLBACK((void **)&hash_key);
CFBasicHashCallbacks *newcb = NULL;
if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
- newcb = (CFBasicHashCallbacks *)auto_zone_allocate_object(auto_zone(), 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED, true, false);
+ newcb = (CFBasicHashCallbacks *)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED, false, false);
} else {
- newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, 10 * sizeof(void *), 0);
+ newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
}
if (!newcb) HALT;
- newcb->func = (CFBasicHashCallbackType)__CFSetCallback;
+ newcb->copyCallbacks = __CFSetCopyCallbacks;
+ newcb->freeCallbacks = __CFSetFreeCallbacks;
+ newcb->retainValue = __CFSetRetainValue;
+ newcb->retainKey = __CFSetRetainKey;
+ newcb->releaseValue = __CFSetReleaseValue;
+ newcb->releaseKey = __CFSetReleaseKey;
+ newcb->equateValues = __CFSetEquateValues;
+ newcb->equateKeys = __CFSetEquateKeys;
+ newcb->hashKey = __CFSetHashKey;
+ newcb->getIndirectKey = __CFSetGetIndirectKey;
+ newcb->copyValueDescription = __CFSetCopyValueDescription;
+ newcb->copyKeyDescription = __CFSetCopyKeyDescription;
newcb->context[0] = (uintptr_t)value_retain;
newcb->context[1] = (uintptr_t)key_retain;
newcb->context[2] = (uintptr_t)value_release;
newcb->context[4] = (uintptr_t)value_equal;
newcb->context[5] = (uintptr_t)key_equal;
newcb->context[6] = (uintptr_t)hash_key;
- newcb->context[7] = (uintptr_t)value_describe;
- newcb->context[8] = (uintptr_t)key_describe;
+ newcb->context[8] = (uintptr_t)value_describe;
+ newcb->context[9] = (uintptr_t)key_describe;
cb = newcb;
}
if (std_cb || key_retain != NULL || key_release != NULL) {
flags |= kCFBasicHashStrongKeys;
}
+#if CFDictionary
+ if (valueCallBacks == &kCFTypeDictionaryValueCompactableCallBacks) {
+ // Foundation allocated collections will have compactable values
+ flags |= kCFBasicHashCompactableValues;
+ }
+#endif
}
- return CFBasicHashCreate(allocator, flags, cb);
+ CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, cb);
+ CFBasicHashSetSpecialBits(ht, specialBits);
+ return ht;
+}
+
+#if CFDictionary
+__private_extern__ CFHashRef __CFSetCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues) {
+#endif
+#if CFSet || CFBag
+__private_extern__ CFHashRef __CFSetCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues) {
+ const_any_pointer_t *vlist = klist;
+#endif
+ CFTypeID typeID = CFSetGetTypeID();
+ CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
+ CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing
+ flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0);
+ CFBasicHashCallbacks *cb = (CFBasicHashCallbacks *)&CFSetStandardCallbacks;
+ CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, cb);
+ CFBasicHashSetSpecialBits(ht, 0x0303);
+ if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
+ for (CFIndex idx = 0; idx < numValues; idx++) {
+ CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
+ }
+ CFBasicHashSetSpecialBits(ht, 0x0000);
+ CFBasicHashMakeImmutable(ht);
+ *(uintptr_t *)ht = __CFISAForTypeID(typeID);
+ _CFRuntimeSetInstanceTypeID(ht, typeID);
+ if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (immutable)");
+ return (CFHashRef)ht;
}
#if CFDictionary
}
Boolean CFSetGetValueIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *value) {
- if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, Boolean, hc, "_getValue:forKey:", (any_t *)value, key);
- if (CFSet) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, Boolean, hc, "_getValue:forObj:", (any_t *)value, key);
+ if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, Boolean, hc, "__getValue:forKey:", (any_t *)value, key);
+ if (CFSet) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, Boolean, hc, "__getValue:forObj:", (any_t *)value, key);
__CFGenericValidateType(hc, __kCFSetTypeID);
CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key);
if (0 < bkt.count) {
__CFGenericValidateType(hc, __kCFSetTypeID);
if (kCFUseCollectableAllocator) {
CFOptionFlags flags = CFBasicHashGetFlags((CFBasicHashRef)hc);
- __block const_any_pointer_t *keys = keybuf, *values = valuebuf;
+ __block const_any_pointer_t *keys = keybuf;
+ __block const_any_pointer_t *values = valuebuf;
CFBasicHashApply((CFBasicHashRef)hc, ^(CFBasicHashBucket bkt) {
for (CFIndex cnt = bkt.count; cnt--;) {
if (keybuf && (flags & kCFBasicHashStrongKeys)) { __CFAssignWithWriteBarrier((void **)keys, (void *)bkt.weak_key); keys++; }
return (Boolean)true;
});
} else {
- CFBasicHashGetElements((CFBasicHashRef)hc, CFSetGetCount(hc), (uintptr_t *)valuebuf, NULL, (uintptr_t *)keybuf, NULL);
+ CFBasicHashGetElements((CFBasicHashRef)hc, CFSetGetCount(hc), (uintptr_t *)valuebuf, (uintptr_t *)keybuf);
}
}
void CFSetApplyFunction(CFHashRef hc, CFSetApplierFunction applier, any_pointer_t context) {
FAULT_CALLBACK((void **)&(applier));
- if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, void, hc, "_apply:context:", applier, context);
- if (CFSet) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, void, hc, "_applyValues:context:", applier, context);
+ if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, void, hc, "__apply:context:", applier, context);
+ if (CFSet) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, void, hc, "__applyValues:context:", applier, context);
__CFGenericValidateType(hc, __kCFSetTypeID);
CFBasicHashApply((CFBasicHashRef)hc, ^(CFBasicHashBucket bkt) {
#if CFDictionary
const_any_pointer_t value = key;
#endif
if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, void, hc, "setObject:forKey:", value, key);
- if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, void, hc, "_setObject:", key);
+ if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, void, hc, "setObject:", key);
__CFGenericValidateType(hc, __kCFSetTypeID);
CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {