2 * Copyright (c) 2012 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@
25 Copyright (c) 1998-2012, Apple Inc. All rights reserved.
26 Responsibility: Christopher Kane
27 Machine generated from Notes/HashingCode.template
34 #include <CoreFoundation/CFBag.h>
35 #include "CFInternal.h"
36 #include "CFBasicHash.h"
37 #include <CoreFoundation/CFString.h>
40 #define CFDictionary 0
47 const CFBagKeyCallBacks kCFTypeBagKeyCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
48 const CFBagKeyCallBacks kCFCopyStringBagKeyCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
49 const CFBagValueCallBacks kCFTypeBagValueCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
};
50 __private_extern__
const CFBagValueCallBacks kCFTypeBagValueCompactableCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
};
51 static const CFBagKeyCallBacks __kCFNullBagKeyCallBacks
= {0, NULL
, NULL
, NULL
, NULL
, NULL
};
52 static const CFBagValueCallBacks __kCFNullBagValueCallBacks
= {0, NULL
, NULL
, NULL
, NULL
};
54 #define CFHashRef CFDictionaryRef
55 #define CFMutableHashRef CFMutableDictionaryRef
56 #define CFHashKeyCallBacks CFBagKeyCallBacks
57 #define CFHashValueCallBacks CFBagValueCallBacks
61 const CFBagCallBacks kCFTypeBagCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
62 const CFBagCallBacks kCFCopyStringBagCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
63 static const CFBagCallBacks __kCFNullBagCallBacks
= {0, NULL
, NULL
, NULL
, NULL
, NULL
};
65 #define CFBagKeyCallBacks CFBagCallBacks
66 #define CFBagValueCallBacks CFBagCallBacks
67 #define kCFTypeBagKeyCallBacks kCFTypeBagCallBacks
68 #define kCFTypeBagValueCallBacks kCFTypeBagCallBacks
69 #define __kCFNullBagKeyCallBacks __kCFNullBagCallBacks
70 #define __kCFNullBagValueCallBacks __kCFNullBagCallBacks
72 #define CFHashRef CFSetRef
73 #define CFMutableHashRef CFMutableSetRef
74 #define CFHashKeyCallBacks CFBagCallBacks
75 #define CFHashValueCallBacks CFBagCallBacks
79 const CFBagCallBacks kCFTypeBagCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
80 const CFBagCallBacks kCFCopyStringBagCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
81 static const CFBagCallBacks __kCFNullBagCallBacks
= {0, NULL
, NULL
, NULL
, NULL
, NULL
};
83 #define CFBagKeyCallBacks CFBagCallBacks
84 #define CFBagValueCallBacks CFBagCallBacks
85 #define kCFTypeBagKeyCallBacks kCFTypeBagCallBacks
86 #define kCFTypeBagValueCallBacks kCFTypeBagCallBacks
87 #define __kCFNullBagKeyCallBacks __kCFNullBagCallBacks
88 #define __kCFNullBagValueCallBacks __kCFNullBagCallBacks
90 #define CFHashRef CFBagRef
91 #define CFMutableHashRef CFMutableBagRef
92 #define CFHashKeyCallBacks CFBagCallBacks
93 #define CFHashValueCallBacks CFBagCallBacks
97 typedef uintptr_t any_t
;
98 typedef const void * const_any_pointer_t
;
99 typedef void * any_pointer_t
;
101 static Boolean
__CFBagEqual(CFTypeRef cf1
, CFTypeRef cf2
) {
102 return __CFBasicHashEqual((CFBasicHashRef
)cf1
, (CFBasicHashRef
)cf2
);
105 static CFHashCode
__CFBagHash(CFTypeRef cf
) {
106 return __CFBasicHashHash((CFBasicHashRef
)cf
);
109 static CFStringRef
__CFBagCopyDescription(CFTypeRef cf
) {
110 return __CFBasicHashCopyDescription((CFBasicHashRef
)cf
);
113 static void __CFBagDeallocate(CFTypeRef cf
) {
114 __CFBasicHashDeallocate((CFBasicHashRef
)cf
);
117 static CFTypeID __kCFBagTypeID
= _kCFRuntimeNotATypeID
;
119 static const CFRuntimeClass __CFBagClass
= {
120 _kCFRuntimeScannedObject
,
128 __CFBagCopyDescription
131 CFTypeID
CFBagGetTypeID(void) {
132 if (_kCFRuntimeNotATypeID
== __kCFBagTypeID
) __kCFBagTypeID
= _CFRuntimeRegisterClass(&__CFBagClass
);
133 return __kCFBagTypeID
;
136 #define GCRETAIN(A, B) kCFTypeSetCallBacks.retain(A, B)
137 #define GCRELEASE(A, B) kCFTypeSetCallBacks.release(A, B)
139 static uintptr_t __CFBagStandardRetainValue(CFConstBasicHashRef ht
, uintptr_t stack_value
) {
140 if (CFBasicHashGetSpecialBits(ht
) & 0x0100) return stack_value
;
141 return (CFBasicHashHasStrongValues(ht
)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault
, (CFTypeRef
)stack_value
) : (uintptr_t)CFRetain((CFTypeRef
)stack_value
);
144 static uintptr_t __CFBagStandardRetainKey(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
145 if (CFBasicHashGetSpecialBits(ht
) & 0x0001) return stack_key
;
146 return (CFBasicHashHasStrongKeys(ht
)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault
, (CFTypeRef
)stack_key
) : (uintptr_t)CFRetain((CFTypeRef
)stack_key
);
149 static void __CFBagStandardReleaseValue(CFConstBasicHashRef ht
, uintptr_t stack_value
) {
150 if (CFBasicHashGetSpecialBits(ht
) & 0x0200) return;
151 if (CFBasicHashHasStrongValues(ht
)) GCRELEASE(kCFAllocatorSystemDefault
, (CFTypeRef
)stack_value
); else CFRelease((CFTypeRef
)stack_value
);
154 static void __CFBagStandardReleaseKey(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
155 if (CFBasicHashGetSpecialBits(ht
) & 0x0002) return;
156 if (CFBasicHashHasStrongKeys(ht
)) GCRELEASE(kCFAllocatorSystemDefault
, (CFTypeRef
)stack_key
); else CFRelease((CFTypeRef
)stack_key
);
159 static Boolean
__CFBagStandardEquateValues(CFConstBasicHashRef ht
, uintptr_t coll_value1
, uintptr_t stack_value2
) {
160 if (CFBasicHashGetSpecialBits(ht
) & 0x0400) return coll_value1
== stack_value2
;
161 return CFEqual((CFTypeRef
)coll_value1
, (CFTypeRef
)stack_value2
);
164 static Boolean
__CFBagStandardEquateKeys(CFConstBasicHashRef ht
, uintptr_t coll_key1
, uintptr_t stack_key2
) {
165 if (CFBasicHashGetSpecialBits(ht
) & 0x0004) return coll_key1
== stack_key2
;
166 return CFEqual((CFTypeRef
)coll_key1
, (CFTypeRef
)stack_key2
);
169 static uintptr_t __CFBagStandardHashKey(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
170 if (CFBasicHashGetSpecialBits(ht
) & 0x0008) return stack_key
;
171 return (uintptr_t)CFHash((CFTypeRef
)stack_key
);
174 static uintptr_t __CFBagStandardGetIndirectKey(CFConstBasicHashRef ht
, uintptr_t coll_value
) {
178 static CFStringRef
__CFBagStandardCopyValueDescription(CFConstBasicHashRef ht
, uintptr_t stack_value
) {
179 if (CFBasicHashGetSpecialBits(ht
) & 0x0800) return CFStringCreateWithFormat(kCFAllocatorSystemDefault
, NULL
, CFSTR("<%p>"), (void *)stack_value
);
180 return CFCopyDescription((CFTypeRef
)stack_value
);
183 static CFStringRef
__CFBagStandardCopyKeyDescription(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
184 if (CFBasicHashGetSpecialBits(ht
) & 0x0010) return CFStringCreateWithFormat(kCFAllocatorSystemDefault
, NULL
, CFSTR("<%p>"), (void *)stack_key
);
185 return CFCopyDescription((CFTypeRef
)stack_key
);
188 static CFBasicHashCallbacks
*__CFBagStandardCopyCallbacks(CFConstBasicHashRef ht
, CFAllocatorRef allocator
, CFBasicHashCallbacks
*cb
);
189 static void __CFBagStandardFreeCallbacks(CFConstBasicHashRef ht
, CFAllocatorRef allocator
, CFBasicHashCallbacks
*cb
);
191 static const CFBasicHashCallbacks CFBagStandardCallbacks
= {
192 __CFBagStandardCopyCallbacks
,
193 __CFBagStandardFreeCallbacks
,
194 __CFBagStandardRetainValue
,
195 __CFBagStandardRetainKey
,
196 __CFBagStandardReleaseValue
,
197 __CFBagStandardReleaseKey
,
198 __CFBagStandardEquateValues
,
199 __CFBagStandardEquateKeys
,
200 __CFBagStandardHashKey
,
201 __CFBagStandardGetIndirectKey
,
202 __CFBagStandardCopyValueDescription
,
203 __CFBagStandardCopyKeyDescription
206 static CFBasicHashCallbacks
*__CFBagStandardCopyCallbacks(CFConstBasicHashRef ht
, CFAllocatorRef allocator
, CFBasicHashCallbacks
*cb
) {
207 return (CFBasicHashCallbacks
*)&CFBagStandardCallbacks
;
210 static void __CFBagStandardFreeCallbacks(CFConstBasicHashRef ht
, CFAllocatorRef allocator
, CFBasicHashCallbacks
*cb
) {
214 static CFBasicHashCallbacks
*__CFBagCopyCallbacks(CFConstBasicHashRef ht
, CFAllocatorRef allocator
, CFBasicHashCallbacks
*cb
) {
215 CFBasicHashCallbacks
*newcb
= NULL
;
216 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) {
217 newcb
= (CFBasicHashCallbacks
*)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks
) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED
, false, false);
219 newcb
= (CFBasicHashCallbacks
*)CFAllocatorAllocate(allocator
, sizeof(CFBasicHashCallbacks
) + 10 * sizeof(void *), 0);
221 if (!newcb
) return NULL
;
222 memmove(newcb
, (void *)cb
, sizeof(CFBasicHashCallbacks
) + 10 * sizeof(void *));
226 static void __CFBagFreeCallbacks(CFConstBasicHashRef ht
, CFAllocatorRef allocator
, CFBasicHashCallbacks
*cb
) {
227 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) {
229 CFAllocatorDeallocate(allocator
, cb
);
233 static uintptr_t __CFBagRetainValue(CFConstBasicHashRef ht
, uintptr_t stack_value
) {
234 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
235 const_any_pointer_t (*value_retain
)(CFAllocatorRef
, const_any_pointer_t
) = (const_any_pointer_t (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[0];
236 if (NULL
== value_retain
) return stack_value
;
237 return (uintptr_t)INVOKE_CALLBACK2(value_retain
, CFGetAllocator(ht
), (const_any_pointer_t
)stack_value
);
240 static uintptr_t __CFBagRetainKey(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
241 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
242 const_any_pointer_t (*key_retain
)(CFAllocatorRef
, const_any_pointer_t
) = (const_any_pointer_t (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[1];
243 if (NULL
== key_retain
) return stack_key
;
244 return (uintptr_t)INVOKE_CALLBACK2(key_retain
, CFGetAllocator(ht
), (const_any_pointer_t
)stack_key
);
247 static void __CFBagReleaseValue(CFConstBasicHashRef ht
, uintptr_t stack_value
) {
248 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
249 void (*value_release
)(CFAllocatorRef
, const_any_pointer_t
) = (void (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[2];
250 if (NULL
!= value_release
) INVOKE_CALLBACK2(value_release
, CFGetAllocator(ht
), (const_any_pointer_t
) stack_value
);
253 static void __CFBagReleaseKey(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
254 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
255 void (*key_release
)(CFAllocatorRef
, const_any_pointer_t
) = (void (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[3];
256 if (NULL
!= key_release
) INVOKE_CALLBACK2(key_release
, CFGetAllocator(ht
), (const_any_pointer_t
) stack_key
);
259 static Boolean
__CFBagEquateValues(CFConstBasicHashRef ht
, uintptr_t coll_value1
, uintptr_t stack_value2
) {
260 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
261 Boolean (*value_equal
)(const_any_pointer_t
, const_any_pointer_t
) = (Boolean (*)(const_any_pointer_t
, const_any_pointer_t
))cb
->context
[4];
262 if (NULL
== value_equal
) return (coll_value1
== stack_value2
);
263 return INVOKE_CALLBACK2(value_equal
, (const_any_pointer_t
) coll_value1
, (const_any_pointer_t
) stack_value2
) ? 1 : 0;
266 static Boolean
__CFBagEquateKeys(CFConstBasicHashRef ht
, uintptr_t coll_key1
, uintptr_t stack_key2
) {
267 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
268 Boolean (*key_equal
)(const_any_pointer_t
, const_any_pointer_t
) = (Boolean (*)(const_any_pointer_t
, const_any_pointer_t
))cb
->context
[5];
269 if (NULL
== key_equal
) return (coll_key1
== stack_key2
);
270 return INVOKE_CALLBACK2(key_equal
, (const_any_pointer_t
) coll_key1
, (const_any_pointer_t
) stack_key2
) ? 1 : 0;
273 static uintptr_t __CFBagHashKey(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
274 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
275 CFHashCode (*hash
)(const_any_pointer_t
) = (CFHashCode (*)(const_any_pointer_t
))cb
->context
[6];
276 if (NULL
== hash
) return stack_key
;
277 return (uintptr_t)INVOKE_CALLBACK1(hash
, (const_any_pointer_t
) stack_key
);
280 static uintptr_t __CFBagGetIndirectKey(CFConstBasicHashRef ht
, uintptr_t coll_value
) {
284 static CFStringRef
__CFBagCopyValueDescription(CFConstBasicHashRef ht
, uintptr_t stack_value
) {
285 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
286 CFStringRef (*value_describe
)(const_any_pointer_t
) = (CFStringRef (*)(const_any_pointer_t
))cb
->context
[8];
287 if (NULL
== value_describe
) return CFStringCreateWithFormat(kCFAllocatorSystemDefault
, NULL
, CFSTR("<%p>"), (const_any_pointer_t
) stack_value
);
288 return (CFStringRef
)INVOKE_CALLBACK1(value_describe
, (const_any_pointer_t
) stack_value
);
291 static CFStringRef
__CFBagCopyKeyDescription(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
292 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
293 CFStringRef (*key_describe
)(const_any_pointer_t
) = (CFStringRef (*)(const_any_pointer_t
))cb
->context
[9];
294 if (NULL
== key_describe
) return CFStringCreateWithFormat(kCFAllocatorSystemDefault
, NULL
, CFSTR("<%p>"), (const_any_pointer_t
) stack_key
);
295 return (CFStringRef
)INVOKE_CALLBACK1(key_describe
, (const_any_pointer_t
) stack_key
);
298 static CFBasicHashRef
__CFBagCreateGeneric(CFAllocatorRef allocator
, const CFHashKeyCallBacks
*keyCallBacks
, const CFHashValueCallBacks
*valueCallBacks
, Boolean useValueCB
) {
299 CFOptionFlags flags
= kCFBasicHashLinearHashing
; // kCFBasicHashExponentialHashing
300 flags
|= (CFDictionary
? kCFBasicHashHasKeys
: 0) | (CFBag
? kCFBasicHashHasCounts
: 0);
302 CFBasicHashCallbacks
*cb
= NULL
;
303 Boolean std_cb
= false;
304 uint16_t specialBits
= 0;
305 const_any_pointer_t (*key_retain
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
306 void (*key_release
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
307 const_any_pointer_t (*value_retain
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
308 void (*value_release
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
310 if ((NULL
== keyCallBacks
|| 0 == keyCallBacks
->version
) && (!useValueCB
|| NULL
== valueCallBacks
|| 0 == valueCallBacks
->version
)) {
311 Boolean keyRetainNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->retain
;
312 Boolean keyReleaseNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->release
;
313 Boolean keyEquateNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->equal
;
314 Boolean keyHashNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->hash
;
315 Boolean keyDescribeNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->copyDescription
;
317 Boolean valueRetainNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->retain
)) || (!useValueCB
&& keyRetainNull
);
318 Boolean valueReleaseNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->release
)) || (!useValueCB
&& keyReleaseNull
);
319 Boolean valueEquateNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->equal
)) || (!useValueCB
&& keyEquateNull
);
320 Boolean valueDescribeNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->copyDescription
)) || (!useValueCB
&& keyDescribeNull
);
322 Boolean keyRetainStd
= keyRetainNull
|| __CFTypeCollectionRetain
== keyCallBacks
->retain
;
323 Boolean keyReleaseStd
= keyReleaseNull
|| __CFTypeCollectionRelease
== keyCallBacks
->release
;
324 Boolean keyEquateStd
= keyEquateNull
|| CFEqual
== keyCallBacks
->equal
;
325 Boolean keyHashStd
= keyHashNull
|| CFHash
== keyCallBacks
->hash
;
326 Boolean keyDescribeStd
= keyDescribeNull
|| CFCopyDescription
== keyCallBacks
->copyDescription
;
328 Boolean valueRetainStd
= (useValueCB
&& (valueRetainNull
|| __CFTypeCollectionRetain
== valueCallBacks
->retain
)) || (!useValueCB
&& keyRetainStd
);
329 Boolean valueReleaseStd
= (useValueCB
&& (valueReleaseNull
|| __CFTypeCollectionRelease
== valueCallBacks
->release
)) || (!useValueCB
&& keyReleaseStd
);
330 Boolean valueEquateStd
= (useValueCB
&& (valueEquateNull
|| CFEqual
== valueCallBacks
->equal
)) || (!useValueCB
&& keyEquateStd
);
331 Boolean valueDescribeStd
= (useValueCB
&& (valueDescribeNull
|| CFCopyDescription
== valueCallBacks
->copyDescription
)) || (!useValueCB
&& keyDescribeStd
);
333 if (keyRetainStd
&& keyReleaseStd
&& keyEquateStd
&& keyHashStd
&& keyDescribeStd
&& valueRetainStd
&& valueReleaseStd
&& valueEquateStd
&& valueDescribeStd
) {
334 cb
= (CFBasicHashCallbacks
*)&CFBagStandardCallbacks
;
335 if (!(keyRetainNull
|| keyReleaseNull
|| keyEquateNull
|| keyHashNull
|| keyDescribeNull
|| valueRetainNull
|| valueReleaseNull
|| valueEquateNull
|| valueDescribeNull
)) {
338 // just set these to tickle the GC Strong logic below in a way that mimics past practice
339 key_retain
= keyCallBacks
? keyCallBacks
->retain
: NULL
;
340 key_release
= keyCallBacks
? keyCallBacks
->release
: NULL
;
342 value_retain
= valueCallBacks
? valueCallBacks
->retain
: NULL
;
343 value_release
= valueCallBacks
? valueCallBacks
->release
: NULL
;
345 value_retain
= key_retain
;
346 value_release
= key_release
;
349 if (keyRetainNull
) specialBits
|= 0x0001;
350 if (keyReleaseNull
) specialBits
|= 0x0002;
351 if (keyEquateNull
) specialBits
|= 0x0004;
352 if (keyHashNull
) specialBits
|= 0x0008;
353 if (keyDescribeNull
) specialBits
|= 0x0010;
354 if (valueRetainNull
) specialBits
|= 0x0100;
355 if (valueReleaseNull
) specialBits
|= 0x0200;
356 if (valueEquateNull
) specialBits
|= 0x0400;
357 if (valueDescribeNull
) specialBits
|= 0x0800;
362 Boolean (*key_equal
)(const_any_pointer_t
, const_any_pointer_t
) = NULL
;
363 Boolean (*value_equal
)(const_any_pointer_t
, const_any_pointer_t
) = NULL
;
364 CFStringRef (*key_describe
)(const_any_pointer_t
) = NULL
;
365 CFStringRef (*value_describe
)(const_any_pointer_t
) = NULL
;
366 CFHashCode (*hash_key
)(const_any_pointer_t
) = NULL
;
367 key_retain
= keyCallBacks
? keyCallBacks
->retain
: NULL
;
368 key_release
= keyCallBacks
? keyCallBacks
->release
: NULL
;
369 key_equal
= keyCallBacks
? keyCallBacks
->equal
: NULL
;
370 key_describe
= keyCallBacks
? keyCallBacks
->copyDescription
: NULL
;
372 value_retain
= valueCallBacks
? valueCallBacks
->retain
: NULL
;
373 value_release
= valueCallBacks
? valueCallBacks
->release
: NULL
;
374 value_equal
= valueCallBacks
? valueCallBacks
->equal
: NULL
;
375 value_describe
= valueCallBacks
? valueCallBacks
->copyDescription
: NULL
;
377 value_retain
= key_retain
;
378 value_release
= key_release
;
379 value_equal
= key_equal
;
380 value_describe
= key_describe
;
382 hash_key
= keyCallBacks
? keyCallBacks
->hash
: NULL
;
384 CFBasicHashCallbacks
*newcb
= NULL
;
385 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) {
386 newcb
= (CFBasicHashCallbacks
*)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks
) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED
, false, false);
388 newcb
= (CFBasicHashCallbacks
*)CFAllocatorAllocate(allocator
, sizeof(CFBasicHashCallbacks
) + 10 * sizeof(void *), 0);
390 if (!newcb
) return NULL
;
391 newcb
->copyCallbacks
= __CFBagCopyCallbacks
;
392 newcb
->freeCallbacks
= __CFBagFreeCallbacks
;
393 newcb
->retainValue
= __CFBagRetainValue
;
394 newcb
->retainKey
= __CFBagRetainKey
;
395 newcb
->releaseValue
= __CFBagReleaseValue
;
396 newcb
->releaseKey
= __CFBagReleaseKey
;
397 newcb
->equateValues
= __CFBagEquateValues
;
398 newcb
->equateKeys
= __CFBagEquateKeys
;
399 newcb
->hashKey
= __CFBagHashKey
;
400 newcb
->getIndirectKey
= __CFBagGetIndirectKey
;
401 newcb
->copyValueDescription
= __CFBagCopyValueDescription
;
402 newcb
->copyKeyDescription
= __CFBagCopyKeyDescription
;
403 newcb
->context
[0] = (uintptr_t)value_retain
;
404 newcb
->context
[1] = (uintptr_t)key_retain
;
405 newcb
->context
[2] = (uintptr_t)value_release
;
406 newcb
->context
[3] = (uintptr_t)key_release
;
407 newcb
->context
[4] = (uintptr_t)value_equal
;
408 newcb
->context
[5] = (uintptr_t)key_equal
;
409 newcb
->context
[6] = (uintptr_t)hash_key
;
410 newcb
->context
[8] = (uintptr_t)value_describe
;
411 newcb
->context
[9] = (uintptr_t)key_describe
;
415 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) {
416 if (std_cb
|| value_retain
!= NULL
|| value_release
!= NULL
) {
417 flags
|= kCFBasicHashStrongValues
;
419 if (std_cb
|| key_retain
!= NULL
|| key_release
!= NULL
) {
420 flags
|= kCFBasicHashStrongKeys
;
423 if (valueCallBacks
== &kCFTypeDictionaryValueCompactableCallBacks
) {
424 // Foundation allocated collections will have compactable values
425 flags
|= kCFBasicHashCompactableValues
;
430 CFBasicHashRef ht
= CFBasicHashCreate(allocator
, flags
, cb
);
431 if (ht
) CFBasicHashSetSpecialBits(ht
, specialBits
);
432 if (!ht
&& !CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) CFAllocatorDeallocate(allocator
, cb
);
437 __private_extern__ CFHashRef
__CFBagCreateTransfer(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, const_any_pointer_t
*vlist
, CFIndex numValues
) {
440 __private_extern__ CFHashRef
__CFBagCreateTransfer(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, CFIndex numValues
) {
441 const_any_pointer_t
*vlist
= klist
;
443 CFTypeID typeID
= CFBagGetTypeID();
444 CFAssert2(0 <= numValues
, __kCFLogAssertion
, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, numValues
);
445 CFOptionFlags flags
= kCFBasicHashLinearHashing
; // kCFBasicHashExponentialHashing
446 flags
|= (CFDictionary
? kCFBasicHashHasKeys
: 0) | (CFBag
? kCFBasicHashHasCounts
: 0);
447 CFBasicHashCallbacks
*cb
= (CFBasicHashCallbacks
*)&CFBagStandardCallbacks
;
448 CFBasicHashRef ht
= CFBasicHashCreate(allocator
, flags
, cb
);
449 CFBasicHashSetSpecialBits(ht
, 0x0303);
450 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
451 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
452 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
454 CFBasicHashSetSpecialBits(ht
, 0x0000);
455 CFBasicHashMakeImmutable(ht
);
456 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
457 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
458 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFBag (immutable)");
459 return (CFHashRef
)ht
;
463 CFHashRef
CFBagCreate(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, const_any_pointer_t
*vlist
, CFIndex numValues
, const CFBagKeyCallBacks
*keyCallBacks
, const CFBagValueCallBacks
*valueCallBacks
) {
466 CFHashRef
CFBagCreate(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, CFIndex numValues
, const CFBagKeyCallBacks
*keyCallBacks
) {
467 const_any_pointer_t
*vlist
= klist
;
468 const CFBagValueCallBacks
*valueCallBacks
= 0;
470 CFTypeID typeID
= CFBagGetTypeID();
471 CFAssert2(0 <= numValues
, __kCFLogAssertion
, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, numValues
);
472 CFBasicHashRef ht
= __CFBagCreateGeneric(allocator
, keyCallBacks
, valueCallBacks
, CFDictionary
);
473 if (!ht
) return NULL
;
474 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
475 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
476 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
478 CFBasicHashMakeImmutable(ht
);
479 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
480 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
481 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFBag (immutable)");
482 return (CFHashRef
)ht
;
486 CFMutableHashRef
CFBagCreateMutable(CFAllocatorRef allocator
, CFIndex capacity
, const CFBagKeyCallBacks
*keyCallBacks
, const CFBagValueCallBacks
*valueCallBacks
) {
489 CFMutableHashRef
CFBagCreateMutable(CFAllocatorRef allocator
, CFIndex capacity
, const CFBagKeyCallBacks
*keyCallBacks
) {
490 const CFBagValueCallBacks
*valueCallBacks
= 0;
492 CFTypeID typeID
= CFBagGetTypeID();
493 CFAssert2(0 <= capacity
, __kCFLogAssertion
, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, capacity
);
494 CFBasicHashRef ht
= __CFBagCreateGeneric(allocator
, keyCallBacks
, valueCallBacks
, CFDictionary
);
495 if (!ht
) return NULL
;
496 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
497 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
498 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFBag (mutable)");
499 return (CFMutableHashRef
)ht
;
502 CFHashRef
CFBagCreateCopy(CFAllocatorRef allocator
, CFHashRef other
) {
503 CFTypeID typeID
= CFBagGetTypeID();
504 CFAssert1(other
, __kCFLogAssertion
, "%s(): other CFBag cannot be NULL", __PRETTY_FUNCTION__
);
505 __CFGenericValidateType(other
, typeID
);
506 CFBasicHashRef ht
= NULL
;
507 if (CF_IS_OBJC(typeID
, other
)) {
508 CFIndex numValues
= CFBagGetCount(other
);
509 const_any_pointer_t vbuffer
[256], kbuffer
[256];
510 const_any_pointer_t
*vlist
= (numValues
<= 256) ? vbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
512 const_any_pointer_t
*klist
= vlist
;
513 CFBagGetValues(other
, vlist
);
516 const_any_pointer_t
*klist
= (numValues
<= 256) ? kbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
517 CFDictionaryGetKeysAndValues(other
, klist
, vlist
);
519 ht
= __CFBagCreateGeneric(allocator
, & kCFTypeBagKeyCallBacks
, CFDictionary
? & kCFTypeBagValueCallBacks
: NULL
, CFDictionary
);
520 if (ht
&& 0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
521 for (CFIndex idx
= 0; ht
&& idx
< numValues
; idx
++) {
522 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
524 if (klist
!= kbuffer
&& klist
!= vlist
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, klist
);
525 if (vlist
!= vbuffer
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, vlist
);
527 ht
= CFBasicHashCreateCopy(allocator
, (CFBasicHashRef
)other
);
529 if (!ht
) return NULL
;
530 CFBasicHashMakeImmutable(ht
);
531 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
532 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
533 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFBag (immutable)");
534 return (CFHashRef
)ht
;
537 CFMutableHashRef
CFBagCreateMutableCopy(CFAllocatorRef allocator
, CFIndex capacity
, CFHashRef other
) {
538 CFTypeID typeID
= CFBagGetTypeID();
539 CFAssert1(other
, __kCFLogAssertion
, "%s(): other CFBag cannot be NULL", __PRETTY_FUNCTION__
);
540 __CFGenericValidateType(other
, typeID
);
541 CFAssert2(0 <= capacity
, __kCFLogAssertion
, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, capacity
);
542 CFBasicHashRef ht
= NULL
;
543 if (CF_IS_OBJC(typeID
, other
)) {
544 CFIndex numValues
= CFBagGetCount(other
);
545 const_any_pointer_t vbuffer
[256], kbuffer
[256];
546 const_any_pointer_t
*vlist
= (numValues
<= 256) ? vbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
548 const_any_pointer_t
*klist
= vlist
;
549 CFBagGetValues(other
, vlist
);
552 const_any_pointer_t
*klist
= (numValues
<= 256) ? kbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
553 CFDictionaryGetKeysAndValues(other
, klist
, vlist
);
555 ht
= __CFBagCreateGeneric(allocator
, & kCFTypeBagKeyCallBacks
, CFDictionary
? & kCFTypeBagValueCallBacks
: NULL
, CFDictionary
);
556 if (ht
&& 0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
557 for (CFIndex idx
= 0; ht
&& idx
< numValues
; idx
++) {
558 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
560 if (klist
!= kbuffer
&& klist
!= vlist
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, klist
);
561 if (vlist
!= vbuffer
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, vlist
);
563 ht
= CFBasicHashCreateCopy(allocator
, (CFBasicHashRef
)other
);
565 if (!ht
) return NULL
;
566 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
567 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
568 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFBag (mutable)");
569 return (CFMutableHashRef
)ht
;
572 CFIndex
CFBagGetCount(CFHashRef hc
) {
573 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, CFIndex
, (NSDictionary
*)hc
, count
);
574 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, CFIndex
, (NSSet
*)hc
, count
);
575 __CFGenericValidateType(hc
, __kCFBagTypeID
);
576 return CFBasicHashGetCount((CFBasicHashRef
)hc
);
580 CFIndex
CFBagGetCountOfKey(CFHashRef hc
, const_any_pointer_t key
) {
583 CFIndex
CFBagGetCountOfValue(CFHashRef hc
, const_any_pointer_t key
) {
585 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, CFIndex
, (NSDictionary
*)hc
, countForKey
:(id
)key
);
586 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, CFIndex
, (NSSet
*)hc
, countForObject
:(id
)key
);
587 __CFGenericValidateType(hc
, __kCFBagTypeID
);
588 return CFBasicHashGetCountOfKey((CFBasicHashRef
)hc
, (uintptr_t)key
);
592 Boolean
CFBagContainsKey(CFHashRef hc
, const_any_pointer_t key
) {
595 Boolean
CFBagContainsValue(CFHashRef hc
, const_any_pointer_t key
) {
597 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, char, (NSDictionary
*)hc
, containsKey
:(id
)key
);
598 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, char, (NSSet
*)hc
, containsObject
:(id
)key
);
599 __CFGenericValidateType(hc
, __kCFBagTypeID
);
600 return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef
)hc
, (uintptr_t)key
));
603 const_any_pointer_t
CFBagGetValue(CFHashRef hc
, const_any_pointer_t key
) {
604 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, const_any_pointer_t
, (NSDictionary
*)hc
, objectForKey
:(id
)key
);
605 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, const_any_pointer_t
, (NSSet
*)hc
, member
:(id
)key
);
606 __CFGenericValidateType(hc
, __kCFBagTypeID
);
607 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
608 return (0 < bkt
.count
? (const_any_pointer_t
)bkt
.weak_value
: 0);
611 Boolean
CFBagGetValueIfPresent(CFHashRef hc
, const_any_pointer_t key
, const_any_pointer_t
*value
) {
612 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, Boolean
, (NSDictionary
*)hc
, __getValue
:(id
*)value forKey
:(id
)key
);
613 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, Boolean
, (NSSet
*)hc
, __getValue
:(id
*)value forObj
:(id
)key
);
614 __CFGenericValidateType(hc
, __kCFBagTypeID
);
615 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
618 if (kCFUseCollectableAllocator
&& (CFBasicHashGetFlags((CFBasicHashRef
)hc
) & kCFBasicHashStrongValues
)) {
619 __CFAssignWithWriteBarrier((void **)value
, (void *)bkt
.weak_value
);
621 *value
= (const_any_pointer_t
)bkt
.weak_value
;
630 CFIndex
CFDictionaryGetCountOfValue(CFHashRef hc
, const_any_pointer_t value
) {
631 CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, CFIndex
, (NSDictionary
*)hc
, countForObject
:(id
)value
);
632 __CFGenericValidateType(hc
, __kCFBagTypeID
);
633 return CFBasicHashGetCountOfValue((CFBasicHashRef
)hc
, (uintptr_t)value
);
636 Boolean
CFDictionaryContainsValue(CFHashRef hc
, const_any_pointer_t value
) {
637 CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, char, (NSDictionary
*)hc
, containsObject
:(id
)value
);
638 __CFGenericValidateType(hc
, __kCFBagTypeID
);
639 return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef
)hc
, (uintptr_t)value
));
642 CF_EXPORT Boolean
CFDictionaryGetKeyIfPresent(CFHashRef hc
, const_any_pointer_t key
, const_any_pointer_t
*actualkey
) {
643 __CFGenericValidateType(hc
, __kCFBagTypeID
);
644 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
647 if (kCFUseCollectableAllocator
&& (CFBasicHashGetFlags((CFBasicHashRef
)hc
) & kCFBasicHashStrongKeys
)) {
648 __CFAssignWithWriteBarrier((void **)actualkey
, (void *)bkt
.weak_key
);
650 *actualkey
= (const_any_pointer_t
)bkt
.weak_key
;
660 void CFBagGetKeysAndValues(CFHashRef hc
, const_any_pointer_t
*keybuf
, const_any_pointer_t
*valuebuf
) {
663 void CFBagGetValues(CFHashRef hc
, const_any_pointer_t
*keybuf
) {
664 const_any_pointer_t
*valuebuf
= 0;
666 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSDictionary
*)hc
, getObjects
:(id
*)valuebuf andKeys
:(id
*)keybuf
);
667 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSSet
*)hc
, getObjects
:(id
*)keybuf
);
668 __CFGenericValidateType(hc
, __kCFBagTypeID
);
669 if (kCFUseCollectableAllocator
) {
670 CFOptionFlags flags
= CFBasicHashGetFlags((CFBasicHashRef
)hc
);
671 __block const_any_pointer_t
*keys
= keybuf
;
672 __block const_any_pointer_t
*values
= valuebuf
;
673 CFBasicHashApply((CFBasicHashRef
)hc
, ^(CFBasicHashBucket bkt
) {
674 for (CFIndex cnt
= bkt
.count
; cnt
--;) {
675 if (keybuf
&& (flags
& kCFBasicHashStrongKeys
)) { __CFAssignWithWriteBarrier((void **)keys
, (void *)bkt
.weak_key
); keys
++; }
676 if (keybuf
&& !(flags
& kCFBasicHashStrongKeys
)) { *keys
++ = (const_any_pointer_t
)bkt
.weak_key
; }
677 if (valuebuf
&& (flags
& kCFBasicHashStrongValues
)) { __CFAssignWithWriteBarrier((void **)values
, (void *)bkt
.weak_value
); values
++; }
678 if (valuebuf
&& !(flags
& kCFBasicHashStrongValues
)) { *values
++ = (const_any_pointer_t
)bkt
.weak_value
; }
680 return (Boolean
)true;
683 CFBasicHashGetElements((CFBasicHashRef
)hc
, CFBagGetCount(hc
), (uintptr_t *)valuebuf
, (uintptr_t *)keybuf
);
687 void CFBagApplyFunction(CFHashRef hc
, CFBagApplierFunction applier
, any_pointer_t context
) {
688 FAULT_CALLBACK((void **)&(applier
));
689 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSDictionary
*)hc
, __apply
:(void (*)(const void *, const void *, void *))applier context
:(void *)context
);
690 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSSet
*)hc
, __applyValues
:(void (*)(const void *, void *))applier context
:(void *)context
);
691 __CFGenericValidateType(hc
, __kCFBagTypeID
);
692 CFBasicHashApply((CFBasicHashRef
)hc
, ^(CFBasicHashBucket bkt
) {
694 INVOKE_CALLBACK3(applier
, (const_any_pointer_t
)bkt
.weak_key
, (const_any_pointer_t
)bkt
.weak_value
, context
);
697 INVOKE_CALLBACK2(applier
, (const_any_pointer_t
)bkt
.weak_value
, context
);
700 for (CFIndex cnt
= bkt
.count
; cnt
--;) {
701 INVOKE_CALLBACK2(applier
, (const_any_pointer_t
)bkt
.weak_value
, context
);
704 return (Boolean
)true;
708 // This function is for Foundation's benefit; no one else should use it.
709 CF_EXPORT
unsigned long _CFBagFastEnumeration(CFHashRef hc
, struct __objcFastEnumerationStateEquivalent
*state
, void *stackbuffer
, unsigned long count
) {
710 if (CF_IS_OBJC(__kCFBagTypeID
, hc
)) return 0;
711 __CFGenericValidateType(hc
, __kCFBagTypeID
);
712 return __CFBasicHashFastEnumeration((CFBasicHashRef
)hc
, (struct __objcFastEnumerationStateEquivalent2
*)state
, stackbuffer
, count
);
715 // This function is for Foundation's benefit; no one else should use it.
716 CF_EXPORT Boolean
_CFBagIsMutable(CFHashRef hc
) {
717 if (CF_IS_OBJC(__kCFBagTypeID
, hc
)) return false;
718 __CFGenericValidateType(hc
, __kCFBagTypeID
);
719 return CFBasicHashIsMutable((CFBasicHashRef
)hc
);
722 // This function is for Foundation's benefit; no one else should use it.
723 CF_EXPORT
void _CFBagSetCapacity(CFMutableHashRef hc
, CFIndex cap
) {
724 if (CF_IS_OBJC(__kCFBagTypeID
, hc
)) return;
725 __CFGenericValidateType(hc
, __kCFBagTypeID
);
726 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
727 CFAssert3(CFBagGetCount(hc
) <= cap
, __kCFLogAssertion
, "%s(): desired capacity (%ld) is less than count (%ld)", __PRETTY_FUNCTION__
, cap
, CFBagGetCount(hc
));
728 CFBasicHashSetCapacity((CFBasicHashRef
)hc
, cap
);
731 CF_INLINE CFIndex
__CFBagGetKVOBit(CFHashRef hc
) {
732 return __CFBitfieldGetValue(((CFRuntimeBase
*)hc
)->_cfinfo
[CF_INFO_BITS
], 0, 0);
735 CF_INLINE
void __CFBagSetKVOBit(CFHashRef hc
, CFIndex bit
) {
736 __CFBitfieldSetValue(((CFRuntimeBase
*)hc
)->_cfinfo
[CF_INFO_BITS
], 0, 0, ((uintptr_t)bit
& 0x1));
739 // This function is for Foundation's benefit; no one else should use it.
740 CF_EXPORT CFIndex
_CFBagGetKVOBit(CFHashRef hc
) {
741 return __CFBagGetKVOBit(hc
);
744 // This function is for Foundation's benefit; no one else should use it.
745 CF_EXPORT
void _CFBagSetKVOBit(CFHashRef hc
, CFIndex bit
) {
746 __CFBagSetKVOBit(hc
, bit
);
750 #if !defined(CF_OBJC_KVO_WILLCHANGE)
751 #define CF_OBJC_KVO_WILLCHANGE(obj, key)
752 #define CF_OBJC_KVO_DIDCHANGE(obj, key)
753 #define CF_OBJC_KVO_WILLCHANGEALL(obj)
754 #define CF_OBJC_KVO_DIDCHANGEALL(obj)
758 void CFBagAddValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
761 void CFBagAddValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
762 const_any_pointer_t value
= key
;
764 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSMutableDictionary
*)hc
, __addObject
:(id
)value forKey
:(id
)key
);
765 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSMutableSet
*)hc
, addObject
:(id
)key
);
766 __CFGenericValidateType(hc
, __kCFBagTypeID
);
767 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
768 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
769 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
771 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
772 CFBasicHashAddValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
773 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
777 void CFBagReplaceValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
780 void CFBagReplaceValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
781 const_any_pointer_t value
= key
;
783 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSMutableDictionary
*)hc
, replaceObject
:(id
)value forKey
:(id
)key
);
784 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSMutableSet
*)hc
, replaceObject
:(id
)key
);
785 __CFGenericValidateType(hc
, __kCFBagTypeID
);
786 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
787 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
788 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
790 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
791 CFBasicHashReplaceValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
792 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
796 void CFBagSetValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
799 void CFBagSetValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
800 const_any_pointer_t value
= key
;
802 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSMutableDictionary
*)hc
, setObject
:(id
)value forKey
:(id
)key
);
803 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSMutableSet
*)hc
, setObject
:(id
)key
);
804 __CFGenericValidateType(hc
, __kCFBagTypeID
);
805 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
806 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
807 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
809 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
810 //#warning this for a dictionary used to not replace the key
811 CFBasicHashSetValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
812 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
815 void CFBagRemoveValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
816 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSMutableDictionary
*)hc
, removeObjectForKey
:(id
)key
);
817 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSMutableSet
*)hc
, removeObject
:(id
)key
);
818 __CFGenericValidateType(hc
, __kCFBagTypeID
);
819 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
820 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
821 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
823 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
824 CFBasicHashRemoveValue((CFBasicHashRef
)hc
, (uintptr_t)key
);
825 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
828 void CFBagRemoveAllValues(CFMutableHashRef hc
) {
829 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSMutableDictionary
*)hc
, removeAllObjects
);
830 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID
, void, (NSMutableSet
*)hc
, removeAllObjects
);
831 __CFGenericValidateType(hc
, __kCFBagTypeID
);
832 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
833 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
834 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
836 CF_OBJC_KVO_WILLCHANGEALL(hc
);
837 CFBasicHashRemoveAllValues((CFBasicHashRef
)hc
);
838 CF_OBJC_KVO_DIDCHANGEALL(hc
);
841 #undef CF_OBJC_KVO_WILLCHANGE
842 #undef CF_OBJC_KVO_DIDCHANGE
843 #undef CF_OBJC_KVO_WILLCHANGEALL
844 #undef CF_OBJC_KVO_DIDCHANGEALL