2 * Copyright (c) 2009 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 Copyright 1998-2008, Apple, Inc. All rights reserved.
25 Responsibility: Christopher Kane
26 Machine generated from Notes/HashingCode.template
33 #include <CoreFoundation/CFBag.h>
34 #include "CFInternal.h"
35 #include "CFBasicHash.h"
36 #include <CoreFoundation/CFString.h>
38 #define CFDictionary 0
45 const CFBagKeyCallBacks kCFTypeBagKeyCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
46 const CFBagKeyCallBacks kCFCopyStringBagKeyCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
47 const CFBagValueCallBacks kCFTypeBagValueCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
};
48 static const CFBagKeyCallBacks __kCFNullBagKeyCallBacks
= {0, NULL
, NULL
, NULL
, NULL
, NULL
};
49 static const CFBagValueCallBacks __kCFNullBagValueCallBacks
= {0, NULL
, NULL
, NULL
, NULL
};
51 #define CFHashRef CFDictionaryRef
52 #define CFMutableHashRef CFMutableDictionaryRef
53 #define CFHashKeyCallBacks CFBagKeyCallBacks
54 #define CFHashValueCallBacks CFBagValueCallBacks
58 const CFBagCallBacks kCFTypeBagCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
59 const CFBagCallBacks kCFCopyStringBagCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
60 static const CFBagCallBacks __kCFNullBagCallBacks
= {0, NULL
, NULL
, NULL
, NULL
, NULL
};
62 #define CFBagKeyCallBacks CFBagCallBacks
63 #define CFBagValueCallBacks CFBagCallBacks
64 #define kCFTypeBagKeyCallBacks kCFTypeBagCallBacks
65 #define kCFTypeBagValueCallBacks kCFTypeBagCallBacks
66 #define __kCFNullBagKeyCallBacks __kCFNullBagCallBacks
67 #define __kCFNullBagValueCallBacks __kCFNullBagCallBacks
69 #define CFHashRef CFSetRef
70 #define CFMutableHashRef CFMutableSetRef
71 #define CFHashKeyCallBacks CFBagCallBacks
72 #define CFHashValueCallBacks CFBagCallBacks
76 const CFBagCallBacks kCFTypeBagCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
77 const CFBagCallBacks kCFCopyStringBagCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
78 static const CFBagCallBacks __kCFNullBagCallBacks
= {0, NULL
, NULL
, NULL
, NULL
, NULL
};
80 #define CFBagKeyCallBacks CFBagCallBacks
81 #define CFBagValueCallBacks CFBagCallBacks
82 #define kCFTypeBagKeyCallBacks kCFTypeBagCallBacks
83 #define kCFTypeBagValueCallBacks kCFTypeBagCallBacks
84 #define __kCFNullBagKeyCallBacks __kCFNullBagCallBacks
85 #define __kCFNullBagValueCallBacks __kCFNullBagCallBacks
87 #define CFHashRef CFBagRef
88 #define CFMutableHashRef CFMutableBagRef
89 #define CFHashKeyCallBacks CFBagCallBacks
90 #define CFHashValueCallBacks CFBagCallBacks
94 typedef uintptr_t any_t
;
95 typedef const void * const_any_pointer_t
;
96 typedef void * any_pointer_t
;
98 static Boolean
__CFBagEqual(CFTypeRef cf1
, CFTypeRef cf2
) {
99 return __CFBasicHashEqual((CFBasicHashRef
)cf1
, (CFBasicHashRef
)cf2
);
102 static CFHashCode
__CFBagHash(CFTypeRef cf
) {
103 return __CFBasicHashHash((CFBasicHashRef
)cf
);
106 static CFStringRef
__CFBagCopyDescription(CFTypeRef cf
) {
107 return __CFBasicHashCopyDescription((CFBasicHashRef
)cf
);
110 static void __CFBagDeallocate(CFTypeRef cf
) {
111 __CFBasicHashDeallocate((CFBasicHashRef
)cf
);
114 static CFTypeID __kCFBagTypeID
= _kCFRuntimeNotATypeID
;
116 static const CFRuntimeClass __CFBagClass
= {
117 _kCFRuntimeScannedObject
,
125 __CFBagCopyDescription
128 CFTypeID
CFBagGetTypeID(void) {
129 if (_kCFRuntimeNotATypeID
== __kCFBagTypeID
) __kCFBagTypeID
= _CFRuntimeRegisterClass(&__CFBagClass
);
130 return __kCFBagTypeID
;
133 static uintptr_t __CFBagCallback(CFBasicHashRef ht
, uint8_t op
, uintptr_t a1
, uintptr_t a2
, CFBasicHashCallbacks
*cb
) {
135 case kCFBasicHashCallbackOpCopyCallbacks
: {
136 CFBasicHashCallbacks
*newcb
= NULL
;
137 if (CF_IS_COLLECTABLE_ALLOCATOR((CFAllocatorRef
)a1
)) {
138 newcb
= (CFBasicHashCallbacks
*)auto_zone_allocate_object(auto_zone(), 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED
, true, false);
140 newcb
= (CFBasicHashCallbacks
*)CFAllocatorAllocate((CFAllocatorRef
)a1
, 10 * sizeof(void *), 0);
143 memmove(newcb
, (void *)cb
, 10 * sizeof(void *));
144 return (uintptr_t)newcb
;
146 case kCFBasicHashCallbackOpFreeCallbacks
: {
147 if (CF_IS_COLLECTABLE_ALLOCATOR((CFAllocatorRef
)a1
)) {
148 auto_zone_release(auto_zone(), cb
);
150 CFAllocatorDeallocate((CFAllocatorRef
)a1
, cb
);
154 case kCFBasicHashCallbackOpRetainValue
: {
155 const_any_pointer_t (*value_retain
)(CFAllocatorRef
, const_any_pointer_t
) = (const_any_pointer_t (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[0];
156 if (NULL
== value_retain
) return a1
;
157 return (uintptr_t)INVOKE_CALLBACK2(value_retain
, CFGetAllocator(ht
), (const_any_pointer_t
)a1
);
159 case kCFBasicHashCallbackOpRetainKey
: {
160 const_any_pointer_t (*key_retain
)(CFAllocatorRef
, const_any_pointer_t
) = (const_any_pointer_t (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[1];
161 if (NULL
== key_retain
) return a1
;
162 return (uintptr_t)INVOKE_CALLBACK2(key_retain
, CFGetAllocator(ht
), (const_any_pointer_t
)a1
);
164 case kCFBasicHashCallbackOpReleaseValue
: {
165 void (*value_release
)(CFAllocatorRef
, const_any_pointer_t
) = (void (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[2];
166 if (NULL
!= value_release
) INVOKE_CALLBACK2(value_release
, CFGetAllocator(ht
), (const_any_pointer_t
)a1
);
169 case kCFBasicHashCallbackOpReleaseKey
: {
170 void (*key_release
)(CFAllocatorRef
, const_any_pointer_t
) = (void (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[3];
171 if (NULL
!= key_release
) INVOKE_CALLBACK2(key_release
, CFGetAllocator(ht
), (const_any_pointer_t
)a1
);
174 case kCFBasicHashCallbackOpValueEqual
: {
175 Boolean (*value_equal
)(const_any_pointer_t
, const_any_pointer_t
) = (Boolean (*)(const_any_pointer_t
, const_any_pointer_t
))cb
->context
[4];
176 if (NULL
== value_equal
) return (a1
== a2
);
177 return INVOKE_CALLBACK2(value_equal
, (const_any_pointer_t
)a1
, (const_any_pointer_t
)a2
) ? 1 : 0;
179 case kCFBasicHashCallbackOpKeyEqual
: {
180 Boolean (*key_equal
)(const_any_pointer_t
, const_any_pointer_t
) = (Boolean (*)(const_any_pointer_t
, const_any_pointer_t
))cb
->context
[5];
181 if (NULL
== key_equal
) return (a1
== a2
);
182 return INVOKE_CALLBACK2(key_equal
, (const_any_pointer_t
)a1
, (const_any_pointer_t
)a2
) ? 1 : 0;
184 case kCFBasicHashCallbackOpHashKey
: {
185 CFHashCode (*hash
)(const_any_pointer_t
) = (CFHashCode (*)(const_any_pointer_t
))cb
->context
[6];
186 if (NULL
== hash
) return a1
;
187 return (uintptr_t)INVOKE_CALLBACK1(hash
, (const_any_pointer_t
)a1
);
189 case kCFBasicHashCallbackOpDescribeValue
: {
190 CFStringRef (*value_describe
)(const_any_pointer_t
) = (CFStringRef (*)(const_any_pointer_t
))cb
->context
[7];
191 if (NULL
== value_describe
) return (uintptr_t)CFStringCreateWithFormat(kCFAllocatorSystemDefault
, NULL
, CFSTR("<%p>"), (const_any_pointer_t
)a1
);
192 return (uintptr_t)INVOKE_CALLBACK1(value_describe
, (const_any_pointer_t
)a1
);
194 case kCFBasicHashCallbackOpDescribeKey
: {
195 CFStringRef (*key_describe
)(const_any_pointer_t
) = (CFStringRef (*)(const_any_pointer_t
))cb
->context
[8];
196 if (NULL
== key_describe
) return (uintptr_t)CFStringCreateWithFormat(kCFAllocatorSystemDefault
, NULL
, CFSTR("<%p>"), (const_any_pointer_t
)a1
);
197 return (uintptr_t)INVOKE_CALLBACK1(key_describe
, (const_any_pointer_t
)a1
);
203 static CFBasicHashRef
__CFBagCreateGeneric(CFAllocatorRef allocator
, const CFHashKeyCallBacks
*keyCallBacks
, const CFHashValueCallBacks
*valueCallBacks
, Boolean useValueCB
) {
205 CFBasicHashCallbacks
*cb
= NULL
;
206 CFOptionFlags flags
= kCFBasicHashLinearHashing
; // kCFBasicHashExponentialHashing
207 flags
|= (CFDictionary
? kCFBasicHashHasKeys
: 0) | (CFBag
? kCFBasicHashHasCounts
: 0);
209 const_any_pointer_t (*key_retain
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
210 void (*key_release
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
211 const_any_pointer_t (*value_retain
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
212 void (*value_release
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
213 Boolean std_cb
= false;
214 if ((NULL
== keyCallBacks
|| (keyCallBacks
&& 0 == memcmp(&__kCFNullBagKeyCallBacks
, keyCallBacks
, sizeof(__kCFNullBagKeyCallBacks
))))
215 && (!useValueCB
|| (NULL
== valueCallBacks
|| (valueCallBacks
&& 0 == memcmp(&__kCFNullBagValueCallBacks
, valueCallBacks
, sizeof(__kCFNullBagValueCallBacks
)))))) {
216 cb
= (CFBasicHashCallbacks
*)& CFBasicHashNullCallbacks
;
217 } else if ((&kCFTypeBagKeyCallBacks
== keyCallBacks
|| (keyCallBacks
&& 0 == memcmp(&kCFTypeBagKeyCallBacks
, keyCallBacks
, sizeof(kCFTypeBagKeyCallBacks
))))
218 && (!useValueCB
|| (&kCFTypeBagValueCallBacks
== valueCallBacks
|| (valueCallBacks
&& 0 == memcmp(&kCFTypeBagValueCallBacks
, valueCallBacks
, sizeof(kCFTypeBagValueCallBacks
)))))) {
220 cb
= (CFBasicHashCallbacks
*)& CFBasicHashStandardCallbacks
;
222 Boolean (*key_equal
)(const_any_pointer_t
, const_any_pointer_t
) = NULL
;
223 Boolean (*value_equal
)(const_any_pointer_t
, const_any_pointer_t
) = NULL
;
224 CFStringRef (*key_describe
)(const_any_pointer_t
) = NULL
;
225 CFStringRef (*value_describe
)(const_any_pointer_t
) = NULL
;
226 CFHashCode (*hash_key
)(const_any_pointer_t
) = NULL
;
227 key_retain
= keyCallBacks
? keyCallBacks
->retain
: NULL
;
228 key_release
= keyCallBacks
? keyCallBacks
->release
: NULL
;
229 key_equal
= keyCallBacks
? keyCallBacks
->equal
: NULL
;
230 key_describe
= keyCallBacks
? keyCallBacks
->copyDescription
: NULL
;
232 value_retain
= valueCallBacks
? valueCallBacks
->retain
: NULL
;
233 value_release
= valueCallBacks
? valueCallBacks
->release
: NULL
;
234 value_equal
= valueCallBacks
? valueCallBacks
->equal
: NULL
;
235 value_describe
= valueCallBacks
? valueCallBacks
->copyDescription
: NULL
;
237 value_retain
= key_retain
;
238 value_release
= key_release
;
239 value_equal
= key_equal
;
240 value_describe
= key_describe
;
242 hash_key
= keyCallBacks
? keyCallBacks
->hash
: NULL
;
243 FAULT_CALLBACK((void **)&key_retain
);
244 FAULT_CALLBACK((void **)&key_release
);
245 FAULT_CALLBACK((void **)&value_retain
);
246 FAULT_CALLBACK((void **)&value_release
);
247 FAULT_CALLBACK((void **)&key_equal
);
248 FAULT_CALLBACK((void **)&value_equal
);
249 FAULT_CALLBACK((void **)&key_describe
);
250 FAULT_CALLBACK((void **)&value_describe
);
251 FAULT_CALLBACK((void **)&hash_key
);
253 CFBasicHashCallbacks
*newcb
= NULL
;
254 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) {
255 newcb
= (CFBasicHashCallbacks
*)auto_zone_allocate_object(auto_zone(), 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED
, true, false);
257 newcb
= (CFBasicHashCallbacks
*)CFAllocatorAllocate(allocator
, 10 * sizeof(void *), 0);
260 newcb
->func
= (CFBasicHashCallbackType
)__CFBagCallback
;
261 newcb
->context
[0] = (uintptr_t)value_retain
;
262 newcb
->context
[1] = (uintptr_t)key_retain
;
263 newcb
->context
[2] = (uintptr_t)value_release
;
264 newcb
->context
[3] = (uintptr_t)key_release
;
265 newcb
->context
[4] = (uintptr_t)value_equal
;
266 newcb
->context
[5] = (uintptr_t)key_equal
;
267 newcb
->context
[6] = (uintptr_t)hash_key
;
268 newcb
->context
[7] = (uintptr_t)value_describe
;
269 newcb
->context
[8] = (uintptr_t)key_describe
;
273 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) {
274 if (std_cb
|| value_retain
!= NULL
|| value_release
!= NULL
) {
275 flags
|= kCFBasicHashStrongValues
;
277 if (std_cb
|| key_retain
!= NULL
|| key_release
!= NULL
) {
278 flags
|= kCFBasicHashStrongKeys
;
282 return CFBasicHashCreate(allocator
, flags
, cb
);
286 CFHashRef
CFBagCreate(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, const_any_pointer_t
*vlist
, CFIndex numValues
, const CFBagKeyCallBacks
*keyCallBacks
, const CFBagValueCallBacks
*valueCallBacks
) {
289 CFHashRef
CFBagCreate(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, CFIndex numValues
, const CFBagKeyCallBacks
*keyCallBacks
) {
290 const_any_pointer_t
*vlist
= klist
;
291 const CFBagValueCallBacks
*valueCallBacks
= 0;
293 CFTypeID typeID
= CFBagGetTypeID();
294 CFAssert2(0 <= numValues
, __kCFLogAssertion
, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, numValues
);
295 CFBasicHashRef ht
= __CFBagCreateGeneric(allocator
, keyCallBacks
, valueCallBacks
, CFDictionary
);
296 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
297 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
298 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
300 CFBasicHashMakeImmutable(ht
);
301 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
302 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
303 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFBag (immutable)");
304 return (CFHashRef
)ht
;
308 CFMutableHashRef
CFBagCreateMutable(CFAllocatorRef allocator
, CFIndex capacity
, const CFBagKeyCallBacks
*keyCallBacks
, const CFBagValueCallBacks
*valueCallBacks
) {
311 CFMutableHashRef
CFBagCreateMutable(CFAllocatorRef allocator
, CFIndex capacity
, const CFBagKeyCallBacks
*keyCallBacks
) {
312 const CFBagValueCallBacks
*valueCallBacks
= 0;
314 CFTypeID typeID
= CFBagGetTypeID();
315 CFAssert2(0 <= capacity
, __kCFLogAssertion
, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, capacity
);
316 CFBasicHashRef ht
= __CFBagCreateGeneric(allocator
, keyCallBacks
, valueCallBacks
, CFDictionary
);
317 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
318 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
319 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFBag (mutable)");
320 return (CFMutableHashRef
)ht
;
323 CFHashRef
CFBagCreateCopy(CFAllocatorRef allocator
, CFHashRef other
) {
324 CFTypeID typeID
= CFBagGetTypeID();
325 CFAssert1(other
, __kCFLogAssertion
, "%s(): other CFBag cannot be NULL", __PRETTY_FUNCTION__
);
326 __CFGenericValidateType(other
, typeID
);
327 CFBasicHashRef ht
= NULL
;
328 if (CF_IS_OBJC(typeID
, other
)) {
329 CFIndex numValues
= CFBagGetCount(other
);
330 const_any_pointer_t vbuffer
[256], kbuffer
[256];
331 const_any_pointer_t
*vlist
= (numValues
<= 256) ? vbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
333 const_any_pointer_t
*klist
= vlist
;
334 CFBagGetValues(other
, vlist
);
337 const_any_pointer_t
*klist
= (numValues
<= 256) ? kbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
338 CFDictionaryGetKeysAndValues(other
, klist
, vlist
);
340 ht
= __CFBagCreateGeneric(allocator
, & kCFTypeBagKeyCallBacks
, CFDictionary
? & kCFTypeBagValueCallBacks
: NULL
, CFDictionary
);
341 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
342 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
343 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
345 if (klist
!= kbuffer
&& klist
!= vlist
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, klist
);
346 if (vlist
!= vbuffer
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, vlist
);
348 ht
= CFBasicHashCreateCopy(allocator
, (CFBasicHashRef
)other
);
350 CFBasicHashMakeImmutable(ht
);
351 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
352 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
353 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFBag (immutable)");
354 return (CFHashRef
)ht
;
357 CFMutableHashRef
CFBagCreateMutableCopy(CFAllocatorRef allocator
, CFIndex capacity
, CFHashRef other
) {
358 CFTypeID typeID
= CFBagGetTypeID();
359 CFAssert1(other
, __kCFLogAssertion
, "%s(): other CFBag cannot be NULL", __PRETTY_FUNCTION__
);
360 __CFGenericValidateType(other
, typeID
);
361 CFAssert2(0 <= capacity
, __kCFLogAssertion
, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, capacity
);
362 CFBasicHashRef ht
= NULL
;
363 if (CF_IS_OBJC(typeID
, other
)) {
364 CFIndex numValues
= CFBagGetCount(other
);
365 const_any_pointer_t vbuffer
[256], kbuffer
[256];
366 const_any_pointer_t
*vlist
= (numValues
<= 256) ? vbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
368 const_any_pointer_t
*klist
= vlist
;
369 CFBagGetValues(other
, vlist
);
372 const_any_pointer_t
*klist
= (numValues
<= 256) ? kbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
373 CFDictionaryGetKeysAndValues(other
, klist
, vlist
);
375 ht
= __CFBagCreateGeneric(allocator
, & kCFTypeBagKeyCallBacks
, CFDictionary
? & kCFTypeBagValueCallBacks
: NULL
, CFDictionary
);
376 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
377 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
378 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
380 if (klist
!= kbuffer
&& klist
!= vlist
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, klist
);
381 if (vlist
!= vbuffer
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, vlist
);
383 ht
= CFBasicHashCreateCopy(allocator
, (CFBasicHashRef
)other
);
385 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
386 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
387 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFBag (mutable)");
388 return (CFMutableHashRef
)ht
;
391 CFIndex
CFBagGetCount(CFHashRef hc
) {
392 if (CFDictionary
) CF_OBJC_FUNCDISPATCH0(__kCFBagTypeID
, CFIndex
, hc
, "count");
393 if (CFSet
) CF_OBJC_FUNCDISPATCH0(__kCFBagTypeID
, CFIndex
, hc
, "count");
394 __CFGenericValidateType(hc
, __kCFBagTypeID
);
395 return CFBasicHashGetCount((CFBasicHashRef
)hc
);
399 CFIndex
CFBagGetCountOfKey(CFHashRef hc
, const_any_pointer_t key
) {
402 CFIndex
CFBagGetCountOfValue(CFHashRef hc
, const_any_pointer_t key
) {
404 if (CFDictionary
) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, CFIndex
, hc
, "countForKey:", key
);
405 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, CFIndex
, hc
, "countForObject:", key
);
406 __CFGenericValidateType(hc
, __kCFBagTypeID
);
407 return CFBasicHashGetCountOfKey((CFBasicHashRef
)hc
, (uintptr_t)key
);
411 Boolean
CFBagContainsKey(CFHashRef hc
, const_any_pointer_t key
) {
414 Boolean
CFBagContainsValue(CFHashRef hc
, const_any_pointer_t key
) {
416 if (CFDictionary
) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, char, hc
, "containsKey:", key
);
417 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, char, hc
, "containsObject:", key
);
418 __CFGenericValidateType(hc
, __kCFBagTypeID
);
419 return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef
)hc
, (uintptr_t)key
));
422 const_any_pointer_t
CFBagGetValue(CFHashRef hc
, const_any_pointer_t key
) {
423 if (CFDictionary
) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, const_any_pointer_t
, hc
, "objectForKey:", key
);
424 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, const_any_pointer_t
, hc
, "member:", key
);
425 __CFGenericValidateType(hc
, __kCFBagTypeID
);
426 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
427 return (0 < bkt
.count
? (const_any_pointer_t
)bkt
.weak_value
: 0);
430 Boolean
CFBagGetValueIfPresent(CFHashRef hc
, const_any_pointer_t key
, const_any_pointer_t
*value
) {
431 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID
, Boolean
, hc
, "_getValue:forKey:", (any_t
*)value
, key
);
432 if (CFSet
) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID
, Boolean
, hc
, "_getValue:forObj:", (any_t
*)value
, key
);
433 __CFGenericValidateType(hc
, __kCFBagTypeID
);
434 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
437 if (kCFUseCollectableAllocator
&& (CFBasicHashGetFlags((CFBasicHashRef
)hc
) & kCFBasicHashStrongValues
)) {
438 __CFAssignWithWriteBarrier((void **)value
, (void *)bkt
.weak_value
);
440 *value
= (const_any_pointer_t
)bkt
.weak_value
;
449 CFIndex
CFDictionaryGetCountOfValue(CFHashRef hc
, const_any_pointer_t value
) {
450 CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, CFIndex
, hc
, "countForObject:", value
);
451 __CFGenericValidateType(hc
, __kCFBagTypeID
);
452 return CFBasicHashGetCountOfValue((CFBasicHashRef
)hc
, (uintptr_t)value
);
455 Boolean
CFDictionaryContainsValue(CFHashRef hc
, const_any_pointer_t value
) {
456 CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, char, hc
, "containsObject:", value
);
457 __CFGenericValidateType(hc
, __kCFBagTypeID
);
458 return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef
)hc
, (uintptr_t)value
));
461 CF_EXPORT Boolean
CFDictionaryGetKeyIfPresent(CFHashRef hc
, const_any_pointer_t key
, const_any_pointer_t
*actualkey
) {
462 CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID
, Boolean
, hc
, "getActualKey:forKey:", actualkey
, key
);
463 __CFGenericValidateType(hc
, __kCFBagTypeID
);
464 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
467 if (kCFUseCollectableAllocator
&& (CFBasicHashGetFlags((CFBasicHashRef
)hc
) & kCFBasicHashStrongKeys
)) {
468 __CFAssignWithWriteBarrier((void **)actualkey
, (void *)bkt
.weak_key
);
470 *actualkey
= (const_any_pointer_t
)bkt
.weak_key
;
480 void CFBagGetKeysAndValues(CFHashRef hc
, const_any_pointer_t
*keybuf
, const_any_pointer_t
*valuebuf
) {
483 void CFBagGetValues(CFHashRef hc
, const_any_pointer_t
*keybuf
) {
484 const_any_pointer_t
*valuebuf
= 0;
486 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID
, void, hc
, "getObjects:andKeys:", (any_t
*)valuebuf
, (any_t
*)keybuf
);
487 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, void, hc
, "getObjects:", (any_t
*)keybuf
);
488 __CFGenericValidateType(hc
, __kCFBagTypeID
);
489 if (kCFUseCollectableAllocator
) {
490 CFOptionFlags flags
= CFBasicHashGetFlags((CFBasicHashRef
)hc
);
491 __block const_any_pointer_t
*keys
= keybuf
, *values
= valuebuf
;
492 CFBasicHashApply((CFBasicHashRef
)hc
, ^(CFBasicHashBucket bkt
) {
493 for (CFIndex cnt
= bkt
.count
; cnt
--;) {
494 if (keybuf
&& (flags
& kCFBasicHashStrongKeys
)) { __CFAssignWithWriteBarrier((void **)keys
, (void *)bkt
.weak_key
); keys
++; }
495 if (keybuf
&& !(flags
& kCFBasicHashStrongKeys
)) { *keys
++ = (const_any_pointer_t
)bkt
.weak_key
; }
496 if (valuebuf
&& (flags
& kCFBasicHashStrongValues
)) { __CFAssignWithWriteBarrier((void **)values
, (void *)bkt
.weak_value
); values
++; }
497 if (valuebuf
&& !(flags
& kCFBasicHashStrongValues
)) { *values
++ = (const_any_pointer_t
)bkt
.weak_value
; }
499 return (Boolean
)true;
502 CFBasicHashGetElements((CFBasicHashRef
)hc
, CFBagGetCount(hc
), (uintptr_t *)valuebuf
, NULL
, (uintptr_t *)keybuf
, NULL
);
506 void CFBagApplyFunction(CFHashRef hc
, CFBagApplierFunction applier
, any_pointer_t context
) {
507 FAULT_CALLBACK((void **)&(applier
));
508 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID
, void, hc
, "_apply:context:", applier
, context
);
509 if (CFSet
) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID
, void, hc
, "_applyValues:context:", applier
, context
);
510 __CFGenericValidateType(hc
, __kCFBagTypeID
);
511 CFBasicHashApply((CFBasicHashRef
)hc
, ^(CFBasicHashBucket bkt
) {
513 INVOKE_CALLBACK3(applier
, (const_any_pointer_t
)bkt
.weak_key
, (const_any_pointer_t
)bkt
.weak_value
, context
);
516 INVOKE_CALLBACK2(applier
, (const_any_pointer_t
)bkt
.weak_value
, context
);
519 for (CFIndex cnt
= bkt
.count
; cnt
--;) {
520 INVOKE_CALLBACK2(applier
, (const_any_pointer_t
)bkt
.weak_value
, context
);
523 return (Boolean
)true;
527 // This function is for Foundation's benefit; no one else should use it.
528 CF_EXPORT
unsigned long _CFBagFastEnumeration(CFHashRef hc
, struct __objcFastEnumerationStateEquivalent
*state
, void *stackbuffer
, unsigned long count
) {
529 if (CF_IS_OBJC(__kCFBagTypeID
, hc
)) return 0;
530 __CFGenericValidateType(hc
, __kCFBagTypeID
);
531 return __CFBasicHashFastEnumeration((CFBasicHashRef
)hc
, (struct __objcFastEnumerationStateEquivalent2
*)state
, stackbuffer
, count
);
534 // This function is for Foundation's benefit; no one else should use it.
535 CF_EXPORT Boolean
_CFBagIsMutable(CFHashRef hc
) {
536 if (CF_IS_OBJC(__kCFBagTypeID
, hc
)) return false;
537 __CFGenericValidateType(hc
, __kCFBagTypeID
);
538 return CFBasicHashIsMutable((CFBasicHashRef
)hc
);
541 // This function is for Foundation's benefit; no one else should use it.
542 CF_EXPORT
void _CFBagSetCapacity(CFMutableHashRef hc
, CFIndex cap
) {
543 if (CF_IS_OBJC(__kCFBagTypeID
, hc
)) return;
544 __CFGenericValidateType(hc
, __kCFBagTypeID
);
545 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
546 CFAssert3(CFBagGetCount(hc
) <= cap
, __kCFLogAssertion
, "%s(): desired capacity (%ld) is less than count (%ld)", __PRETTY_FUNCTION__
, cap
, CFBagGetCount(hc
));
547 CFBasicHashSetCapacity((CFBasicHashRef
)hc
, cap
);
550 CF_INLINE CFIndex
__CFBagGetKVOBit(CFHashRef hc
) {
551 return __CFBitfieldGetValue(((CFRuntimeBase
*)hc
)->_cfinfo
[CF_INFO_BITS
], 0, 0);
554 CF_INLINE
void __CFBagSetKVOBit(CFHashRef hc
, CFIndex bit
) {
555 __CFBitfieldSetValue(((CFRuntimeBase
*)hc
)->_cfinfo
[CF_INFO_BITS
], 0, 0, ((uintptr_t)bit
& 0x1));
558 // This function is for Foundation's benefit; no one else should use it.
559 CF_EXPORT CFIndex
_CFBagGetKVOBit(CFHashRef hc
) {
560 return __CFBagGetKVOBit(hc
);
563 // This function is for Foundation's benefit; no one else should use it.
564 CF_EXPORT
void _CFBagSetKVOBit(CFHashRef hc
, CFIndex bit
) {
565 __CFBagSetKVOBit(hc
, bit
);
569 #if !defined(CF_OBJC_KVO_WILLCHANGE)
570 #define CF_OBJC_KVO_WILLCHANGE(obj, key)
571 #define CF_OBJC_KVO_DIDCHANGE(obj, key)
572 #define CF_OBJC_KVO_WILLCHANGEALL(obj)
573 #define CF_OBJC_KVO_DIDCHANGEALL(obj)
577 void CFBagAddValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
580 void CFBagAddValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
581 const_any_pointer_t value
= key
;
583 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID
, void, hc
, "addObject:forKey:", value
, key
);
584 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, void, hc
, "addObject:", key
);
585 __CFGenericValidateType(hc
, __kCFBagTypeID
);
586 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
587 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
588 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
590 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
591 CFBasicHashAddValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
592 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
596 void CFBagReplaceValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
599 void CFBagReplaceValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
600 const_any_pointer_t value
= key
;
602 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID
, void, hc
, "replaceObject:forKey:", value
, key
);
603 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, void, hc
, "replaceObject:", key
);
604 __CFGenericValidateType(hc
, __kCFBagTypeID
);
605 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
606 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
607 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
609 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
610 CFBasicHashReplaceValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
611 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
615 void CFBagSetValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
618 void CFBagSetValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
619 const_any_pointer_t value
= key
;
621 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID
, void, hc
, "setObject:forKey:", value
, key
);
622 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, void, hc
, "_setObject:", key
);
623 __CFGenericValidateType(hc
, __kCFBagTypeID
);
624 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
625 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
626 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
628 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
629 //#warning this for a dictionary used to not replace the key
630 CFBasicHashSetValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
631 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
634 void CFBagRemoveValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
635 if (CFDictionary
) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, void, hc
, "removeObjectForKey:", key
);
636 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID
, void, hc
, "removeObject:", key
);
637 __CFGenericValidateType(hc
, __kCFBagTypeID
);
638 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
639 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
640 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
642 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
643 CFBasicHashRemoveValue((CFBasicHashRef
)hc
, (uintptr_t)key
);
644 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
647 void CFBagRemoveAllValues(CFMutableHashRef hc
) {
648 if (CFDictionary
) CF_OBJC_FUNCDISPATCH0(__kCFBagTypeID
, void, hc
, "removeAllObjects");
649 if (CFSet
) CF_OBJC_FUNCDISPATCH0(__kCFBagTypeID
, void, hc
, "removeAllObjects");
650 __CFGenericValidateType(hc
, __kCFBagTypeID
);
651 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
652 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
653 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
655 CF_OBJC_KVO_WILLCHANGEALL(hc
);
656 CFBasicHashRemoveAllValues((CFBasicHashRef
)hc
);
657 CF_OBJC_KVO_DIDCHANGEALL(hc
);
660 #undef CF_OBJC_KVO_WILLCHANGE
661 #undef CF_OBJC_KVO_DIDCHANGE
662 #undef CF_OBJC_KVO_WILLCHANGEALL
663 #undef CF_OBJC_KVO_DIDCHANGEALL