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-2011, Apple Inc. All rights reserved.
26 Responsibility: Christopher Kane
27 Machine generated from Notes/HashingCode.template
34 #include <CoreFoundation/CFDictionary.h>
35 #include "CFInternal.h"
36 #include "CFBasicHash.h"
37 #include <CoreFoundation/CFString.h>
39 #define CFDictionary 0
43 #define CFDictionary 1
46 const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
47 const CFDictionaryKeyCallBacks kCFCopyStringDictionaryKeyCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
48 const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
};
49 __private_extern__
const CFDictionaryValueCallBacks kCFTypeDictionaryValueCompactableCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
};
50 static const CFDictionaryKeyCallBacks __kCFNullDictionaryKeyCallBacks
= {0, NULL
, NULL
, NULL
, NULL
, NULL
};
51 static const CFDictionaryValueCallBacks __kCFNullDictionaryValueCallBacks
= {0, NULL
, NULL
, NULL
, NULL
};
53 #define CFHashRef CFDictionaryRef
54 #define CFMutableHashRef CFMutableDictionaryRef
55 #define CFHashKeyCallBacks CFDictionaryKeyCallBacks
56 #define CFHashValueCallBacks CFDictionaryValueCallBacks
60 const CFDictionaryCallBacks kCFTypeDictionaryCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
61 const CFDictionaryCallBacks kCFCopyStringDictionaryCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
62 static const CFDictionaryCallBacks __kCFNullDictionaryCallBacks
= {0, NULL
, NULL
, NULL
, NULL
, NULL
};
64 #define CFDictionaryKeyCallBacks CFDictionaryCallBacks
65 #define CFDictionaryValueCallBacks CFDictionaryCallBacks
66 #define kCFTypeDictionaryKeyCallBacks kCFTypeDictionaryCallBacks
67 #define kCFTypeDictionaryValueCallBacks kCFTypeDictionaryCallBacks
68 #define __kCFNullDictionaryKeyCallBacks __kCFNullDictionaryCallBacks
69 #define __kCFNullDictionaryValueCallBacks __kCFNullDictionaryCallBacks
71 #define CFHashRef CFSetRef
72 #define CFMutableHashRef CFMutableSetRef
73 #define CFHashKeyCallBacks CFDictionaryCallBacks
74 #define CFHashValueCallBacks CFDictionaryCallBacks
78 const CFDictionaryCallBacks kCFTypeDictionaryCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
79 const CFDictionaryCallBacks kCFCopyStringDictionaryCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
80 static const CFDictionaryCallBacks __kCFNullDictionaryCallBacks
= {0, NULL
, NULL
, NULL
, NULL
, NULL
};
82 #define CFDictionaryKeyCallBacks CFDictionaryCallBacks
83 #define CFDictionaryValueCallBacks CFDictionaryCallBacks
84 #define kCFTypeDictionaryKeyCallBacks kCFTypeDictionaryCallBacks
85 #define kCFTypeDictionaryValueCallBacks kCFTypeDictionaryCallBacks
86 #define __kCFNullDictionaryKeyCallBacks __kCFNullDictionaryCallBacks
87 #define __kCFNullDictionaryValueCallBacks __kCFNullDictionaryCallBacks
89 #define CFHashRef CFBagRef
90 #define CFMutableHashRef CFMutableBagRef
91 #define CFHashKeyCallBacks CFDictionaryCallBacks
92 #define CFHashValueCallBacks CFDictionaryCallBacks
96 typedef uintptr_t any_t
;
97 typedef const void * const_any_pointer_t
;
98 typedef void * any_pointer_t
;
100 static Boolean
__CFDictionaryEqual(CFTypeRef cf1
, CFTypeRef cf2
) {
101 return __CFBasicHashEqual((CFBasicHashRef
)cf1
, (CFBasicHashRef
)cf2
);
104 static CFHashCode
__CFDictionaryHash(CFTypeRef cf
) {
105 return __CFBasicHashHash((CFBasicHashRef
)cf
);
108 static CFStringRef
__CFDictionaryCopyDescription(CFTypeRef cf
) {
109 return __CFBasicHashCopyDescription((CFBasicHashRef
)cf
);
112 static void __CFDictionaryDeallocate(CFTypeRef cf
) {
113 __CFBasicHashDeallocate((CFBasicHashRef
)cf
);
116 static CFTypeID __kCFDictionaryTypeID
= _kCFRuntimeNotATypeID
;
118 static const CFRuntimeClass __CFDictionaryClass
= {
119 _kCFRuntimeScannedObject
,
123 __CFDictionaryDeallocate
,
127 __CFDictionaryCopyDescription
130 CFTypeID
CFDictionaryGetTypeID(void) {
131 if (_kCFRuntimeNotATypeID
== __kCFDictionaryTypeID
) __kCFDictionaryTypeID
= _CFRuntimeRegisterClass(&__CFDictionaryClass
);
132 return __kCFDictionaryTypeID
;
135 #define GCRETAIN(A, B) kCFTypeSetCallBacks.retain(A, B)
136 #define GCRELEASE(A, B) kCFTypeSetCallBacks.release(A, B)
138 static uintptr_t __CFDictionaryStandardRetainValue(CFConstBasicHashRef ht
, uintptr_t stack_value
) {
139 if (CFBasicHashGetSpecialBits(ht
) & 0x0100) return stack_value
;
140 return (CFBasicHashHasStrongValues(ht
)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault
, (CFTypeRef
)stack_value
) : (uintptr_t)CFRetain((CFTypeRef
)stack_value
);
143 static uintptr_t __CFDictionaryStandardRetainKey(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
144 if (CFBasicHashGetSpecialBits(ht
) & 0x0001) return stack_key
;
145 return (CFBasicHashHasStrongKeys(ht
)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault
, (CFTypeRef
)stack_key
) : (uintptr_t)CFRetain((CFTypeRef
)stack_key
);
148 static void __CFDictionaryStandardReleaseValue(CFConstBasicHashRef ht
, uintptr_t stack_value
) {
149 if (CFBasicHashGetSpecialBits(ht
) & 0x0200) return;
150 if (CFBasicHashHasStrongValues(ht
)) GCRELEASE(kCFAllocatorSystemDefault
, (CFTypeRef
)stack_value
); else CFRelease((CFTypeRef
)stack_value
);
153 static void __CFDictionaryStandardReleaseKey(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
154 if (CFBasicHashGetSpecialBits(ht
) & 0x0002) return;
155 if (CFBasicHashHasStrongKeys(ht
)) GCRELEASE(kCFAllocatorSystemDefault
, (CFTypeRef
)stack_key
); else CFRelease((CFTypeRef
)stack_key
);
158 static Boolean
__CFDictionaryStandardEquateValues(CFConstBasicHashRef ht
, uintptr_t coll_value1
, uintptr_t stack_value2
) {
159 if (CFBasicHashGetSpecialBits(ht
) & 0x0400) return coll_value1
== stack_value2
;
160 return CFEqual((CFTypeRef
)coll_value1
, (CFTypeRef
)stack_value2
);
163 static Boolean
__CFDictionaryStandardEquateKeys(CFConstBasicHashRef ht
, uintptr_t coll_key1
, uintptr_t stack_key2
) {
164 if (CFBasicHashGetSpecialBits(ht
) & 0x0004) return coll_key1
== stack_key2
;
165 return CFEqual((CFTypeRef
)coll_key1
, (CFTypeRef
)stack_key2
);
168 static uintptr_t __CFDictionaryStandardHashKey(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
169 if (CFBasicHashGetSpecialBits(ht
) & 0x0008) return stack_key
;
170 return (uintptr_t)CFHash((CFTypeRef
)stack_key
);
173 static uintptr_t __CFDictionaryStandardGetIndirectKey(CFConstBasicHashRef ht
, uintptr_t coll_value
) {
177 static CFStringRef
__CFDictionaryStandardCopyValueDescription(CFConstBasicHashRef ht
, uintptr_t stack_value
) {
178 if (CFBasicHashGetSpecialBits(ht
) & 0x0800) return CFStringCreateWithFormat(kCFAllocatorSystemDefault
, NULL
, CFSTR("<%p>"), (void *)stack_value
);
179 return CFCopyDescription((CFTypeRef
)stack_value
);
182 static CFStringRef
__CFDictionaryStandardCopyKeyDescription(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
183 if (CFBasicHashGetSpecialBits(ht
) & 0x0010) return CFStringCreateWithFormat(kCFAllocatorSystemDefault
, NULL
, CFSTR("<%p>"), (void *)stack_key
);
184 return CFCopyDescription((CFTypeRef
)stack_key
);
187 static CFBasicHashCallbacks
*__CFDictionaryStandardCopyCallbacks(CFConstBasicHashRef ht
, CFAllocatorRef allocator
, CFBasicHashCallbacks
*cb
);
188 static void __CFDictionaryStandardFreeCallbacks(CFConstBasicHashRef ht
, CFAllocatorRef allocator
, CFBasicHashCallbacks
*cb
);
190 static const CFBasicHashCallbacks CFDictionaryStandardCallbacks
= {
191 __CFDictionaryStandardCopyCallbacks
,
192 __CFDictionaryStandardFreeCallbacks
,
193 __CFDictionaryStandardRetainValue
,
194 __CFDictionaryStandardRetainKey
,
195 __CFDictionaryStandardReleaseValue
,
196 __CFDictionaryStandardReleaseKey
,
197 __CFDictionaryStandardEquateValues
,
198 __CFDictionaryStandardEquateKeys
,
199 __CFDictionaryStandardHashKey
,
200 __CFDictionaryStandardGetIndirectKey
,
201 __CFDictionaryStandardCopyValueDescription
,
202 __CFDictionaryStandardCopyKeyDescription
205 static CFBasicHashCallbacks
*__CFDictionaryStandardCopyCallbacks(CFConstBasicHashRef ht
, CFAllocatorRef allocator
, CFBasicHashCallbacks
*cb
) {
206 return (CFBasicHashCallbacks
*)&CFDictionaryStandardCallbacks
;
209 static void __CFDictionaryStandardFreeCallbacks(CFConstBasicHashRef ht
, CFAllocatorRef allocator
, CFBasicHashCallbacks
*cb
) {
213 static CFBasicHashCallbacks
*__CFDictionaryCopyCallbacks(CFConstBasicHashRef ht
, CFAllocatorRef allocator
, CFBasicHashCallbacks
*cb
) {
214 CFBasicHashCallbacks
*newcb
= NULL
;
215 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) {
216 newcb
= (CFBasicHashCallbacks
*)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks
) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED
, false, false);
218 newcb
= (CFBasicHashCallbacks
*)CFAllocatorAllocate(allocator
, sizeof(CFBasicHashCallbacks
) + 10 * sizeof(void *), 0);
221 memmove(newcb
, (void *)cb
, sizeof(CFBasicHashCallbacks
) + 10 * sizeof(void *));
225 static void __CFDictionaryFreeCallbacks(CFConstBasicHashRef ht
, CFAllocatorRef allocator
, CFBasicHashCallbacks
*cb
) {
226 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) {
228 CFAllocatorDeallocate(allocator
, cb
);
232 static uintptr_t __CFDictionaryRetainValue(CFConstBasicHashRef ht
, uintptr_t stack_value
) {
233 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
234 const_any_pointer_t (*value_retain
)(CFAllocatorRef
, const_any_pointer_t
) = (const_any_pointer_t (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[0];
235 if (NULL
== value_retain
) return stack_value
;
236 return (uintptr_t)INVOKE_CALLBACK2(value_retain
, CFGetAllocator(ht
), (const_any_pointer_t
)stack_value
);
239 static uintptr_t __CFDictionaryRetainKey(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
240 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
241 const_any_pointer_t (*key_retain
)(CFAllocatorRef
, const_any_pointer_t
) = (const_any_pointer_t (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[1];
242 if (NULL
== key_retain
) return stack_key
;
243 return (uintptr_t)INVOKE_CALLBACK2(key_retain
, CFGetAllocator(ht
), (const_any_pointer_t
)stack_key
);
246 static void __CFDictionaryReleaseValue(CFConstBasicHashRef ht
, uintptr_t stack_value
) {
247 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
248 void (*value_release
)(CFAllocatorRef
, const_any_pointer_t
) = (void (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[2];
249 if (NULL
!= value_release
) INVOKE_CALLBACK2(value_release
, CFGetAllocator(ht
), (const_any_pointer_t
) stack_value
);
252 static void __CFDictionaryReleaseKey(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
253 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
254 void (*key_release
)(CFAllocatorRef
, const_any_pointer_t
) = (void (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[3];
255 if (NULL
!= key_release
) INVOKE_CALLBACK2(key_release
, CFGetAllocator(ht
), (const_any_pointer_t
) stack_key
);
258 static Boolean
__CFDictionaryEquateValues(CFConstBasicHashRef ht
, uintptr_t coll_value1
, uintptr_t stack_value2
) {
259 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
260 Boolean (*value_equal
)(const_any_pointer_t
, const_any_pointer_t
) = (Boolean (*)(const_any_pointer_t
, const_any_pointer_t
))cb
->context
[4];
261 if (NULL
== value_equal
) return (coll_value1
== stack_value2
);
262 return INVOKE_CALLBACK2(value_equal
, (const_any_pointer_t
) coll_value1
, (const_any_pointer_t
) stack_value2
) ? 1 : 0;
265 static Boolean
__CFDictionaryEquateKeys(CFConstBasicHashRef ht
, uintptr_t coll_key1
, uintptr_t stack_key2
) {
266 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
267 Boolean (*key_equal
)(const_any_pointer_t
, const_any_pointer_t
) = (Boolean (*)(const_any_pointer_t
, const_any_pointer_t
))cb
->context
[5];
268 if (NULL
== key_equal
) return (coll_key1
== stack_key2
);
269 return INVOKE_CALLBACK2(key_equal
, (const_any_pointer_t
) coll_key1
, (const_any_pointer_t
) stack_key2
) ? 1 : 0;
272 static uintptr_t __CFDictionaryHashKey(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
273 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
274 CFHashCode (*hash
)(const_any_pointer_t
) = (CFHashCode (*)(const_any_pointer_t
))cb
->context
[6];
275 if (NULL
== hash
) return stack_key
;
276 return (uintptr_t)INVOKE_CALLBACK1(hash
, (const_any_pointer_t
) stack_key
);
279 static uintptr_t __CFDictionaryGetIndirectKey(CFConstBasicHashRef ht
, uintptr_t coll_value
) {
283 static CFStringRef
__CFDictionaryCopyValueDescription(CFConstBasicHashRef ht
, uintptr_t stack_value
) {
284 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
285 CFStringRef (*value_describe
)(const_any_pointer_t
) = (CFStringRef (*)(const_any_pointer_t
))cb
->context
[8];
286 if (NULL
== value_describe
) return CFStringCreateWithFormat(kCFAllocatorSystemDefault
, NULL
, CFSTR("<%p>"), (const_any_pointer_t
) stack_value
);
287 return (CFStringRef
)INVOKE_CALLBACK1(value_describe
, (const_any_pointer_t
) stack_value
);
290 static CFStringRef
__CFDictionaryCopyKeyDescription(CFConstBasicHashRef ht
, uintptr_t stack_key
) {
291 const CFBasicHashCallbacks
*cb
= CFBasicHashGetCallbacks(ht
);
292 CFStringRef (*key_describe
)(const_any_pointer_t
) = (CFStringRef (*)(const_any_pointer_t
))cb
->context
[9];
293 if (NULL
== key_describe
) return CFStringCreateWithFormat(kCFAllocatorSystemDefault
, NULL
, CFSTR("<%p>"), (const_any_pointer_t
) stack_key
);
294 return (CFStringRef
)INVOKE_CALLBACK1(key_describe
, (const_any_pointer_t
) stack_key
);
297 static CFBasicHashRef
__CFDictionaryCreateGeneric(CFAllocatorRef allocator
, const CFHashKeyCallBacks
*keyCallBacks
, const CFHashValueCallBacks
*valueCallBacks
, Boolean useValueCB
) {
298 CFOptionFlags flags
= kCFBasicHashLinearHashing
; // kCFBasicHashExponentialHashing
299 flags
|= (CFDictionary
? kCFBasicHashHasKeys
: 0) | (CFBag
? kCFBasicHashHasCounts
: 0);
301 CFBasicHashCallbacks
*cb
= NULL
;
302 Boolean std_cb
= false;
303 uint16_t specialBits
= 0;
304 const_any_pointer_t (*key_retain
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
305 void (*key_release
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
306 const_any_pointer_t (*value_retain
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
307 void (*value_release
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
309 if ((NULL
== keyCallBacks
|| 0 == keyCallBacks
->version
) && (!useValueCB
|| NULL
== valueCallBacks
|| 0 == valueCallBacks
->version
)) {
310 Boolean keyRetainNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->retain
;
311 Boolean keyReleaseNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->release
;
312 Boolean keyEquateNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->equal
;
313 Boolean keyHashNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->hash
;
314 Boolean keyDescribeNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->copyDescription
;
316 Boolean valueRetainNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->retain
)) || (!useValueCB
&& keyRetainNull
);
317 Boolean valueReleaseNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->release
)) || (!useValueCB
&& keyReleaseNull
);
318 Boolean valueEquateNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->equal
)) || (!useValueCB
&& keyEquateNull
);
319 Boolean valueDescribeNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->copyDescription
)) || (!useValueCB
&& keyDescribeNull
);
321 Boolean keyRetainStd
= keyRetainNull
|| __CFTypeCollectionRetain
== keyCallBacks
->retain
;
322 Boolean keyReleaseStd
= keyReleaseNull
|| __CFTypeCollectionRelease
== keyCallBacks
->release
;
323 Boolean keyEquateStd
= keyEquateNull
|| CFEqual
== keyCallBacks
->equal
;
324 Boolean keyHashStd
= keyHashNull
|| CFHash
== keyCallBacks
->hash
;
325 Boolean keyDescribeStd
= keyDescribeNull
|| CFCopyDescription
== keyCallBacks
->copyDescription
;
327 Boolean valueRetainStd
= (useValueCB
&& (valueRetainNull
|| __CFTypeCollectionRetain
== valueCallBacks
->retain
)) || (!useValueCB
&& keyRetainStd
);
328 Boolean valueReleaseStd
= (useValueCB
&& (valueReleaseNull
|| __CFTypeCollectionRelease
== valueCallBacks
->release
)) || (!useValueCB
&& keyReleaseStd
);
329 Boolean valueEquateStd
= (useValueCB
&& (valueEquateNull
|| CFEqual
== valueCallBacks
->equal
)) || (!useValueCB
&& keyEquateStd
);
330 Boolean valueDescribeStd
= (useValueCB
&& (valueDescribeNull
|| CFCopyDescription
== valueCallBacks
->copyDescription
)) || (!useValueCB
&& keyDescribeStd
);
332 if (keyRetainStd
&& keyReleaseStd
&& keyEquateStd
&& keyHashStd
&& keyDescribeStd
&& valueRetainStd
&& valueReleaseStd
&& valueEquateStd
&& valueDescribeStd
) {
333 cb
= (CFBasicHashCallbacks
*)&CFDictionaryStandardCallbacks
;
334 if (!(keyRetainNull
|| keyReleaseNull
|| keyEquateNull
|| keyHashNull
|| keyDescribeNull
|| valueRetainNull
|| valueReleaseNull
|| valueEquateNull
|| valueDescribeNull
)) {
337 // just set these to tickle the GC Strong logic below in a way that mimics past practice
338 key_retain
= keyCallBacks
? keyCallBacks
->retain
: NULL
;
339 key_release
= keyCallBacks
? keyCallBacks
->release
: NULL
;
341 value_retain
= valueCallBacks
? valueCallBacks
->retain
: NULL
;
342 value_release
= valueCallBacks
? valueCallBacks
->release
: NULL
;
344 value_retain
= key_retain
;
345 value_release
= key_release
;
348 if (keyRetainNull
) specialBits
|= 0x0001;
349 if (keyReleaseNull
) specialBits
|= 0x0002;
350 if (keyEquateNull
) specialBits
|= 0x0004;
351 if (keyHashNull
) specialBits
|= 0x0008;
352 if (keyDescribeNull
) specialBits
|= 0x0010;
353 if (valueRetainNull
) specialBits
|= 0x0100;
354 if (valueReleaseNull
) specialBits
|= 0x0200;
355 if (valueEquateNull
) specialBits
|= 0x0400;
356 if (valueDescribeNull
) specialBits
|= 0x0800;
361 Boolean (*key_equal
)(const_any_pointer_t
, const_any_pointer_t
) = NULL
;
362 Boolean (*value_equal
)(const_any_pointer_t
, const_any_pointer_t
) = NULL
;
363 CFStringRef (*key_describe
)(const_any_pointer_t
) = NULL
;
364 CFStringRef (*value_describe
)(const_any_pointer_t
) = NULL
;
365 CFHashCode (*hash_key
)(const_any_pointer_t
) = NULL
;
366 key_retain
= keyCallBacks
? keyCallBacks
->retain
: NULL
;
367 key_release
= keyCallBacks
? keyCallBacks
->release
: NULL
;
368 key_equal
= keyCallBacks
? keyCallBacks
->equal
: NULL
;
369 key_describe
= keyCallBacks
? keyCallBacks
->copyDescription
: NULL
;
371 value_retain
= valueCallBacks
? valueCallBacks
->retain
: NULL
;
372 value_release
= valueCallBacks
? valueCallBacks
->release
: NULL
;
373 value_equal
= valueCallBacks
? valueCallBacks
->equal
: NULL
;
374 value_describe
= valueCallBacks
? valueCallBacks
->copyDescription
: NULL
;
376 value_retain
= key_retain
;
377 value_release
= key_release
;
378 value_equal
= key_equal
;
379 value_describe
= key_describe
;
381 hash_key
= keyCallBacks
? keyCallBacks
->hash
: NULL
;
383 CFBasicHashCallbacks
*newcb
= NULL
;
384 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) {
385 newcb
= (CFBasicHashCallbacks
*)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks
) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED
, false, false);
387 newcb
= (CFBasicHashCallbacks
*)CFAllocatorAllocate(allocator
, sizeof(CFBasicHashCallbacks
) + 10 * sizeof(void *), 0);
390 newcb
->copyCallbacks
= __CFDictionaryCopyCallbacks
;
391 newcb
->freeCallbacks
= __CFDictionaryFreeCallbacks
;
392 newcb
->retainValue
= __CFDictionaryRetainValue
;
393 newcb
->retainKey
= __CFDictionaryRetainKey
;
394 newcb
->releaseValue
= __CFDictionaryReleaseValue
;
395 newcb
->releaseKey
= __CFDictionaryReleaseKey
;
396 newcb
->equateValues
= __CFDictionaryEquateValues
;
397 newcb
->equateKeys
= __CFDictionaryEquateKeys
;
398 newcb
->hashKey
= __CFDictionaryHashKey
;
399 newcb
->getIndirectKey
= __CFDictionaryGetIndirectKey
;
400 newcb
->copyValueDescription
= __CFDictionaryCopyValueDescription
;
401 newcb
->copyKeyDescription
= __CFDictionaryCopyKeyDescription
;
402 newcb
->context
[0] = (uintptr_t)value_retain
;
403 newcb
->context
[1] = (uintptr_t)key_retain
;
404 newcb
->context
[2] = (uintptr_t)value_release
;
405 newcb
->context
[3] = (uintptr_t)key_release
;
406 newcb
->context
[4] = (uintptr_t)value_equal
;
407 newcb
->context
[5] = (uintptr_t)key_equal
;
408 newcb
->context
[6] = (uintptr_t)hash_key
;
409 newcb
->context
[8] = (uintptr_t)value_describe
;
410 newcb
->context
[9] = (uintptr_t)key_describe
;
414 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) {
415 if (std_cb
|| value_retain
!= NULL
|| value_release
!= NULL
) {
416 flags
|= kCFBasicHashStrongValues
;
418 if (std_cb
|| key_retain
!= NULL
|| key_release
!= NULL
) {
419 flags
|= kCFBasicHashStrongKeys
;
422 if (valueCallBacks
== &kCFTypeDictionaryValueCompactableCallBacks
) {
423 // Foundation allocated collections will have compactable values
424 flags
|= kCFBasicHashCompactableValues
;
429 CFBasicHashRef ht
= CFBasicHashCreate(allocator
, flags
, cb
);
430 CFBasicHashSetSpecialBits(ht
, specialBits
);
435 __private_extern__ CFHashRef
__CFDictionaryCreateTransfer(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, const_any_pointer_t
*vlist
, CFIndex numValues
) {
438 __private_extern__ CFHashRef
__CFDictionaryCreateTransfer(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, CFIndex numValues
) {
439 const_any_pointer_t
*vlist
= klist
;
441 CFTypeID typeID
= CFDictionaryGetTypeID();
442 CFAssert2(0 <= numValues
, __kCFLogAssertion
, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, numValues
);
443 CFOptionFlags flags
= kCFBasicHashLinearHashing
; // kCFBasicHashExponentialHashing
444 flags
|= (CFDictionary
? kCFBasicHashHasKeys
: 0) | (CFBag
? kCFBasicHashHasCounts
: 0);
445 CFBasicHashCallbacks
*cb
= (CFBasicHashCallbacks
*)&CFDictionaryStandardCallbacks
;
446 CFBasicHashRef ht
= CFBasicHashCreate(allocator
, flags
, cb
);
447 CFBasicHashSetSpecialBits(ht
, 0x0303);
448 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
449 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
450 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
452 CFBasicHashSetSpecialBits(ht
, 0x0000);
453 CFBasicHashMakeImmutable(ht
);
454 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
455 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
456 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (immutable)");
457 return (CFHashRef
)ht
;
461 CFHashRef
CFDictionaryCreate(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, const_any_pointer_t
*vlist
, CFIndex numValues
, const CFDictionaryKeyCallBacks
*keyCallBacks
, const CFDictionaryValueCallBacks
*valueCallBacks
) {
464 CFHashRef
CFDictionaryCreate(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, CFIndex numValues
, const CFDictionaryKeyCallBacks
*keyCallBacks
) {
465 const_any_pointer_t
*vlist
= klist
;
466 const CFDictionaryValueCallBacks
*valueCallBacks
= 0;
468 CFTypeID typeID
= CFDictionaryGetTypeID();
469 CFAssert2(0 <= numValues
, __kCFLogAssertion
, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, numValues
);
470 CFBasicHashRef ht
= __CFDictionaryCreateGeneric(allocator
, keyCallBacks
, valueCallBacks
, CFDictionary
);
471 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
472 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
473 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
475 CFBasicHashMakeImmutable(ht
);
476 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
477 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
478 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (immutable)");
479 return (CFHashRef
)ht
;
483 CFMutableHashRef
CFDictionaryCreateMutable(CFAllocatorRef allocator
, CFIndex capacity
, const CFDictionaryKeyCallBacks
*keyCallBacks
, const CFDictionaryValueCallBacks
*valueCallBacks
) {
486 CFMutableHashRef
CFDictionaryCreateMutable(CFAllocatorRef allocator
, CFIndex capacity
, const CFDictionaryKeyCallBacks
*keyCallBacks
) {
487 const CFDictionaryValueCallBacks
*valueCallBacks
= 0;
489 CFTypeID typeID
= CFDictionaryGetTypeID();
490 CFAssert2(0 <= capacity
, __kCFLogAssertion
, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, capacity
);
491 CFBasicHashRef ht
= __CFDictionaryCreateGeneric(allocator
, keyCallBacks
, valueCallBacks
, CFDictionary
);
492 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
493 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
494 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (mutable)");
495 return (CFMutableHashRef
)ht
;
498 CFHashRef
CFDictionaryCreateCopy(CFAllocatorRef allocator
, CFHashRef other
) {
499 CFTypeID typeID
= CFDictionaryGetTypeID();
500 CFAssert1(other
, __kCFLogAssertion
, "%s(): other CFDictionary cannot be NULL", __PRETTY_FUNCTION__
);
501 __CFGenericValidateType(other
, typeID
);
502 CFBasicHashRef ht
= NULL
;
503 if (CF_IS_OBJC(typeID
, other
)) {
504 CFIndex numValues
= CFDictionaryGetCount(other
);
505 const_any_pointer_t vbuffer
[256], kbuffer
[256];
506 const_any_pointer_t
*vlist
= (numValues
<= 256) ? vbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
508 const_any_pointer_t
*klist
= vlist
;
509 CFDictionaryGetValues(other
, vlist
);
512 const_any_pointer_t
*klist
= (numValues
<= 256) ? kbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
513 CFDictionaryGetKeysAndValues(other
, klist
, vlist
);
515 ht
= __CFDictionaryCreateGeneric(allocator
, & kCFTypeDictionaryKeyCallBacks
, CFDictionary
? & kCFTypeDictionaryValueCallBacks
: NULL
, CFDictionary
);
516 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
517 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
518 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
520 if (klist
!= kbuffer
&& klist
!= vlist
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, klist
);
521 if (vlist
!= vbuffer
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, vlist
);
523 ht
= CFBasicHashCreateCopy(allocator
, (CFBasicHashRef
)other
);
525 CFBasicHashMakeImmutable(ht
);
526 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
527 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
528 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (immutable)");
529 return (CFHashRef
)ht
;
532 CFMutableHashRef
CFDictionaryCreateMutableCopy(CFAllocatorRef allocator
, CFIndex capacity
, CFHashRef other
) {
533 CFTypeID typeID
= CFDictionaryGetTypeID();
534 CFAssert1(other
, __kCFLogAssertion
, "%s(): other CFDictionary cannot be NULL", __PRETTY_FUNCTION__
);
535 __CFGenericValidateType(other
, typeID
);
536 CFAssert2(0 <= capacity
, __kCFLogAssertion
, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, capacity
);
537 CFBasicHashRef ht
= NULL
;
538 if (CF_IS_OBJC(typeID
, other
)) {
539 CFIndex numValues
= CFDictionaryGetCount(other
);
540 const_any_pointer_t vbuffer
[256], kbuffer
[256];
541 const_any_pointer_t
*vlist
= (numValues
<= 256) ? vbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
543 const_any_pointer_t
*klist
= vlist
;
544 CFDictionaryGetValues(other
, vlist
);
547 const_any_pointer_t
*klist
= (numValues
<= 256) ? kbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
548 CFDictionaryGetKeysAndValues(other
, klist
, vlist
);
550 ht
= __CFDictionaryCreateGeneric(allocator
, & kCFTypeDictionaryKeyCallBacks
, CFDictionary
? & kCFTypeDictionaryValueCallBacks
: NULL
, CFDictionary
);
551 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
552 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
553 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
555 if (klist
!= kbuffer
&& klist
!= vlist
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, klist
);
556 if (vlist
!= vbuffer
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, vlist
);
558 ht
= CFBasicHashCreateCopy(allocator
, (CFBasicHashRef
)other
);
560 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
561 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
562 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (mutable)");
563 return (CFMutableHashRef
)ht
;
566 CFIndex
CFDictionaryGetCount(CFHashRef hc
) {
567 if (CFDictionary
) CF_OBJC_FUNCDISPATCH0(__kCFDictionaryTypeID
, CFIndex
, hc
, "count");
568 if (CFSet
) CF_OBJC_FUNCDISPATCH0(__kCFDictionaryTypeID
, CFIndex
, hc
, "count");
569 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
570 return CFBasicHashGetCount((CFBasicHashRef
)hc
);
574 CFIndex
CFDictionaryGetCountOfKey(CFHashRef hc
, const_any_pointer_t key
) {
577 CFIndex
CFDictionaryGetCountOfValue(CFHashRef hc
, const_any_pointer_t key
) {
579 if (CFDictionary
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, CFIndex
, hc
, "countForKey:", key
);
580 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, CFIndex
, hc
, "countForObject:", key
);
581 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
582 return CFBasicHashGetCountOfKey((CFBasicHashRef
)hc
, (uintptr_t)key
);
586 Boolean
CFDictionaryContainsKey(CFHashRef hc
, const_any_pointer_t key
) {
589 Boolean
CFDictionaryContainsValue(CFHashRef hc
, const_any_pointer_t key
) {
591 if (CFDictionary
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, char, hc
, "containsKey:", key
);
592 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, char, hc
, "containsObject:", key
);
593 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
594 return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef
)hc
, (uintptr_t)key
));
597 const_any_pointer_t
CFDictionaryGetValue(CFHashRef hc
, const_any_pointer_t key
) {
598 if (CFDictionary
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, const_any_pointer_t
, hc
, "objectForKey:", key
);
599 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, const_any_pointer_t
, hc
, "member:", key
);
600 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
601 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
602 return (0 < bkt
.count
? (const_any_pointer_t
)bkt
.weak_value
: 0);
605 Boolean
CFDictionaryGetValueIfPresent(CFHashRef hc
, const_any_pointer_t key
, const_any_pointer_t
*value
) {
606 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, Boolean
, hc
, "__getValue:forKey:", (any_t
*)value
, key
);
607 if (CFSet
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, Boolean
, hc
, "__getValue:forObj:", (any_t
*)value
, key
);
608 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
609 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
612 if (kCFUseCollectableAllocator
&& (CFBasicHashGetFlags((CFBasicHashRef
)hc
) & kCFBasicHashStrongValues
)) {
613 __CFAssignWithWriteBarrier((void **)value
, (void *)bkt
.weak_value
);
615 *value
= (const_any_pointer_t
)bkt
.weak_value
;
624 CFIndex
CFDictionaryGetCountOfValue(CFHashRef hc
, const_any_pointer_t value
) {
625 CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, CFIndex
, hc
, "countForObject:", value
);
626 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
627 return CFBasicHashGetCountOfValue((CFBasicHashRef
)hc
, (uintptr_t)value
);
630 Boolean
CFDictionaryContainsValue(CFHashRef hc
, const_any_pointer_t value
) {
631 CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, char, hc
, "containsObject:", value
);
632 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
633 return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef
)hc
, (uintptr_t)value
));
636 CF_EXPORT Boolean
CFDictionaryGetKeyIfPresent(CFHashRef hc
, const_any_pointer_t key
, const_any_pointer_t
*actualkey
) {
637 CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, Boolean
, hc
, "getActualKey:forKey:", actualkey
, key
);
638 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
639 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
642 if (kCFUseCollectableAllocator
&& (CFBasicHashGetFlags((CFBasicHashRef
)hc
) & kCFBasicHashStrongKeys
)) {
643 __CFAssignWithWriteBarrier((void **)actualkey
, (void *)bkt
.weak_key
);
645 *actualkey
= (const_any_pointer_t
)bkt
.weak_key
;
655 void CFDictionaryGetKeysAndValues(CFHashRef hc
, const_any_pointer_t
*keybuf
, const_any_pointer_t
*valuebuf
) {
658 void CFDictionaryGetValues(CFHashRef hc
, const_any_pointer_t
*keybuf
) {
659 const_any_pointer_t
*valuebuf
= 0;
661 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, void, hc
, "getObjects:andKeys:", (any_t
*)valuebuf
, (any_t
*)keybuf
);
662 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, void, hc
, "getObjects:", (any_t
*)keybuf
);
663 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
664 if (kCFUseCollectableAllocator
) {
665 CFOptionFlags flags
= CFBasicHashGetFlags((CFBasicHashRef
)hc
);
666 __block const_any_pointer_t
*keys
= keybuf
;
667 __block const_any_pointer_t
*values
= valuebuf
;
668 CFBasicHashApply((CFBasicHashRef
)hc
, ^(CFBasicHashBucket bkt
) {
669 for (CFIndex cnt
= bkt
.count
; cnt
--;) {
670 if (keybuf
&& (flags
& kCFBasicHashStrongKeys
)) { __CFAssignWithWriteBarrier((void **)keys
, (void *)bkt
.weak_key
); keys
++; }
671 if (keybuf
&& !(flags
& kCFBasicHashStrongKeys
)) { *keys
++ = (const_any_pointer_t
)bkt
.weak_key
; }
672 if (valuebuf
&& (flags
& kCFBasicHashStrongValues
)) { __CFAssignWithWriteBarrier((void **)values
, (void *)bkt
.weak_value
); values
++; }
673 if (valuebuf
&& !(flags
& kCFBasicHashStrongValues
)) { *values
++ = (const_any_pointer_t
)bkt
.weak_value
; }
675 return (Boolean
)true;
678 CFBasicHashGetElements((CFBasicHashRef
)hc
, CFDictionaryGetCount(hc
), (uintptr_t *)valuebuf
, (uintptr_t *)keybuf
);
682 void CFDictionaryApplyFunction(CFHashRef hc
, CFDictionaryApplierFunction applier
, any_pointer_t context
) {
683 FAULT_CALLBACK((void **)&(applier
));
684 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, void, hc
, "__apply:context:", applier
, context
);
685 if (CFSet
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, void, hc
, "__applyValues:context:", applier
, context
);
686 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
687 CFBasicHashApply((CFBasicHashRef
)hc
, ^(CFBasicHashBucket bkt
) {
689 INVOKE_CALLBACK3(applier
, (const_any_pointer_t
)bkt
.weak_key
, (const_any_pointer_t
)bkt
.weak_value
, context
);
692 INVOKE_CALLBACK2(applier
, (const_any_pointer_t
)bkt
.weak_value
, context
);
695 for (CFIndex cnt
= bkt
.count
; cnt
--;) {
696 INVOKE_CALLBACK2(applier
, (const_any_pointer_t
)bkt
.weak_value
, context
);
699 return (Boolean
)true;
703 // This function is for Foundation's benefit; no one else should use it.
704 CF_EXPORT
unsigned long _CFDictionaryFastEnumeration(CFHashRef hc
, struct __objcFastEnumerationStateEquivalent
*state
, void *stackbuffer
, unsigned long count
) {
705 if (CF_IS_OBJC(__kCFDictionaryTypeID
, hc
)) return 0;
706 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
707 return __CFBasicHashFastEnumeration((CFBasicHashRef
)hc
, (struct __objcFastEnumerationStateEquivalent2
*)state
, stackbuffer
, count
);
710 // This function is for Foundation's benefit; no one else should use it.
711 CF_EXPORT Boolean
_CFDictionaryIsMutable(CFHashRef hc
) {
712 if (CF_IS_OBJC(__kCFDictionaryTypeID
, hc
)) return false;
713 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
714 return CFBasicHashIsMutable((CFBasicHashRef
)hc
);
717 // This function is for Foundation's benefit; no one else should use it.
718 CF_EXPORT
void _CFDictionarySetCapacity(CFMutableHashRef hc
, CFIndex cap
) {
719 if (CF_IS_OBJC(__kCFDictionaryTypeID
, hc
)) return;
720 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
721 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
722 CFAssert3(CFDictionaryGetCount(hc
) <= cap
, __kCFLogAssertion
, "%s(): desired capacity (%ld) is less than count (%ld)", __PRETTY_FUNCTION__
, cap
, CFDictionaryGetCount(hc
));
723 CFBasicHashSetCapacity((CFBasicHashRef
)hc
, cap
);
726 CF_INLINE CFIndex
__CFDictionaryGetKVOBit(CFHashRef hc
) {
727 return __CFBitfieldGetValue(((CFRuntimeBase
*)hc
)->_cfinfo
[CF_INFO_BITS
], 0, 0);
730 CF_INLINE
void __CFDictionarySetKVOBit(CFHashRef hc
, CFIndex bit
) {
731 __CFBitfieldSetValue(((CFRuntimeBase
*)hc
)->_cfinfo
[CF_INFO_BITS
], 0, 0, ((uintptr_t)bit
& 0x1));
734 // This function is for Foundation's benefit; no one else should use it.
735 CF_EXPORT CFIndex
_CFDictionaryGetKVOBit(CFHashRef hc
) {
736 return __CFDictionaryGetKVOBit(hc
);
739 // This function is for Foundation's benefit; no one else should use it.
740 CF_EXPORT
void _CFDictionarySetKVOBit(CFHashRef hc
, CFIndex bit
) {
741 __CFDictionarySetKVOBit(hc
, bit
);
745 #if !defined(CF_OBJC_KVO_WILLCHANGE)
746 #define CF_OBJC_KVO_WILLCHANGE(obj, key)
747 #define CF_OBJC_KVO_DIDCHANGE(obj, key)
748 #define CF_OBJC_KVO_WILLCHANGEALL(obj)
749 #define CF_OBJC_KVO_DIDCHANGEALL(obj)
753 void CFDictionaryAddValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
756 void CFDictionaryAddValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
757 const_any_pointer_t value
= key
;
759 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, void, hc
, "addObject:forKey:", value
, key
);
760 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, void, hc
, "addObject:", key
);
761 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
762 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
763 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
764 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
766 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
767 CFBasicHashAddValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
768 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
772 void CFDictionaryReplaceValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
775 void CFDictionaryReplaceValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
776 const_any_pointer_t value
= key
;
778 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, void, hc
, "replaceObject:forKey:", value
, key
);
779 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, void, hc
, "replaceObject:", key
);
780 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
781 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
782 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
783 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
785 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
786 CFBasicHashReplaceValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
787 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
791 void CFDictionarySetValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
794 void CFDictionarySetValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
795 const_any_pointer_t value
= key
;
797 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, void, hc
, "setObject:forKey:", value
, key
);
798 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, void, hc
, "setObject:", key
);
799 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
800 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
801 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
802 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
804 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
805 //#warning this for a dictionary used to not replace the key
806 CFBasicHashSetValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
807 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
810 void CFDictionaryRemoveValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
811 if (CFDictionary
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, void, hc
, "removeObjectForKey:", key
);
812 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, void, hc
, "removeObject:", key
);
813 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
814 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
815 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
816 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
818 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
819 CFBasicHashRemoveValue((CFBasicHashRef
)hc
, (uintptr_t)key
);
820 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
823 void CFDictionaryRemoveAllValues(CFMutableHashRef hc
) {
824 if (CFDictionary
) CF_OBJC_FUNCDISPATCH0(__kCFDictionaryTypeID
, void, hc
, "removeAllObjects");
825 if (CFSet
) CF_OBJC_FUNCDISPATCH0(__kCFDictionaryTypeID
, void, hc
, "removeAllObjects");
826 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
827 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
828 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
829 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
831 CF_OBJC_KVO_WILLCHANGEALL(hc
);
832 CFBasicHashRemoveAllValues((CFBasicHashRef
)hc
);
833 CF_OBJC_KVO_DIDCHANGEALL(hc
);
836 #undef CF_OBJC_KVO_WILLCHANGE
837 #undef CF_OBJC_KVO_DIDCHANGE
838 #undef CF_OBJC_KVO_WILLCHANGEALL
839 #undef CF_OBJC_KVO_DIDCHANGEALL