2 * Copyright (c) 2014 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-2013, 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>
40 #define CFDictionary 0
44 #define CFDictionary 1
47 const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
48 const CFDictionaryKeyCallBacks kCFCopyStringDictionaryKeyCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
49 const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks
= {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
;
136 static CFBasicHashRef
__CFDictionaryCreateGeneric(CFAllocatorRef allocator
, const CFHashKeyCallBacks
*keyCallBacks
, const CFHashValueCallBacks
*valueCallBacks
, Boolean useValueCB
) {
137 CFOptionFlags flags
= kCFBasicHashLinearHashing
; // kCFBasicHashExponentialHashing
138 flags
|= (CFDictionary
? kCFBasicHashHasKeys
: 0) | (CFBag
? kCFBasicHashHasCounts
: 0);
140 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) { // all this crap is just for figuring out two flags for GC in the way done historically; it probably simplifies down to three lines, but we let the compiler worry about that
141 Boolean set_cb
= false;
142 Boolean std_cb
= false;
143 const_any_pointer_t (*key_retain
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
144 void (*key_release
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
145 const_any_pointer_t (*value_retain
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
146 void (*value_release
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
148 if ((NULL
== keyCallBacks
|| 0 == keyCallBacks
->version
) && (!useValueCB
|| NULL
== valueCallBacks
|| 0 == valueCallBacks
->version
)) {
149 Boolean keyRetainNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->retain
;
150 Boolean keyReleaseNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->release
;
151 Boolean keyEquateNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->equal
;
152 Boolean keyHashNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->hash
;
153 Boolean keyDescribeNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->copyDescription
;
155 Boolean valueRetainNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->retain
)) || (!useValueCB
&& keyRetainNull
);
156 Boolean valueReleaseNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->release
)) || (!useValueCB
&& keyReleaseNull
);
157 Boolean valueEquateNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->equal
)) || (!useValueCB
&& keyEquateNull
);
158 Boolean valueDescribeNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->copyDescription
)) || (!useValueCB
&& keyDescribeNull
);
160 Boolean keyRetainStd
= keyRetainNull
|| __CFTypeCollectionRetain
== keyCallBacks
->retain
;
161 Boolean keyReleaseStd
= keyReleaseNull
|| __CFTypeCollectionRelease
== keyCallBacks
->release
;
162 Boolean keyEquateStd
= keyEquateNull
|| CFEqual
== keyCallBacks
->equal
;
163 Boolean keyHashStd
= keyHashNull
|| CFHash
== keyCallBacks
->hash
;
164 Boolean keyDescribeStd
= keyDescribeNull
|| CFCopyDescription
== keyCallBacks
->copyDescription
;
166 Boolean valueRetainStd
= (useValueCB
&& (valueRetainNull
|| __CFTypeCollectionRetain
== valueCallBacks
->retain
)) || (!useValueCB
&& keyRetainStd
);
167 Boolean valueReleaseStd
= (useValueCB
&& (valueReleaseNull
|| __CFTypeCollectionRelease
== valueCallBacks
->release
)) || (!useValueCB
&& keyReleaseStd
);
168 Boolean valueEquateStd
= (useValueCB
&& (valueEquateNull
|| CFEqual
== valueCallBacks
->equal
)) || (!useValueCB
&& keyEquateStd
);
169 Boolean valueDescribeStd
= (useValueCB
&& (valueDescribeNull
|| CFCopyDescription
== valueCallBacks
->copyDescription
)) || (!useValueCB
&& keyDescribeStd
);
171 if (keyRetainStd
&& keyReleaseStd
&& keyEquateStd
&& keyHashStd
&& keyDescribeStd
&& valueRetainStd
&& valueReleaseStd
&& valueEquateStd
&& valueDescribeStd
) {
173 if (!(keyRetainNull
|| keyReleaseNull
|| keyEquateNull
|| keyHashNull
|| keyDescribeNull
|| valueRetainNull
|| valueReleaseNull
|| valueEquateNull
|| valueDescribeNull
)) {
176 // just set these to tickle the GC Strong logic below in a way that mimics past practice
177 key_retain
= keyCallBacks
? keyCallBacks
->retain
: NULL
;
178 key_release
= keyCallBacks
? keyCallBacks
->release
: NULL
;
180 value_retain
= valueCallBacks
? valueCallBacks
->retain
: NULL
;
181 value_release
= valueCallBacks
? valueCallBacks
->release
: NULL
;
183 value_retain
= key_retain
;
184 value_release
= key_release
;
191 key_retain
= keyCallBacks
? keyCallBacks
->retain
: NULL
;
192 key_release
= keyCallBacks
? keyCallBacks
->release
: NULL
;
194 value_retain
= valueCallBacks
? valueCallBacks
->retain
: NULL
;
195 value_release
= valueCallBacks
? valueCallBacks
->release
: NULL
;
197 value_retain
= key_retain
;
198 value_release
= key_release
;
202 if (std_cb
|| value_retain
!= NULL
|| value_release
!= NULL
) {
203 flags
|= kCFBasicHashStrongValues
;
205 if (std_cb
|| key_retain
!= NULL
|| key_release
!= NULL
) {
206 flags
|= kCFBasicHashStrongKeys
;
211 CFBasicHashCallbacks callbacks
;
212 callbacks
.retainKey
= keyCallBacks
? (uintptr_t (*)(CFAllocatorRef
, uintptr_t))keyCallBacks
->retain
: NULL
;
213 callbacks
.releaseKey
= keyCallBacks
? (void (*)(CFAllocatorRef
, uintptr_t))keyCallBacks
->release
: NULL
;
214 callbacks
.equateKeys
= keyCallBacks
? (Boolean (*)(uintptr_t, uintptr_t))keyCallBacks
->equal
: NULL
;
215 callbacks
.hashKey
= keyCallBacks
? (CFHashCode (*)(uintptr_t))keyCallBacks
->hash
: NULL
;
216 callbacks
.getIndirectKey
= NULL
;
217 callbacks
.copyKeyDescription
= keyCallBacks
? (CFStringRef (*)(uintptr_t))keyCallBacks
->copyDescription
: NULL
;
218 callbacks
.retainValue
= useValueCB
? (valueCallBacks
? (uintptr_t (*)(CFAllocatorRef
, uintptr_t))valueCallBacks
->retain
: NULL
) : (callbacks
.retainKey
);
219 callbacks
.releaseValue
= useValueCB
? (valueCallBacks
? (void (*)(CFAllocatorRef
, uintptr_t))valueCallBacks
->release
: NULL
) : (callbacks
.releaseKey
);
220 callbacks
.equateValues
= useValueCB
? (valueCallBacks
? (Boolean (*)(uintptr_t, uintptr_t))valueCallBacks
->equal
: NULL
) : (callbacks
.equateKeys
);
221 callbacks
.copyValueDescription
= useValueCB
? (valueCallBacks
? (CFStringRef (*)(uintptr_t))valueCallBacks
->copyDescription
: NULL
) : (callbacks
.copyKeyDescription
);
223 CFBasicHashRef ht
= CFBasicHashCreate(allocator
, flags
, &callbacks
);
228 CF_PRIVATE CFHashRef
__CFDictionaryCreateTransfer(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, const_any_pointer_t
*vlist
, CFIndex numValues
) {
231 CF_PRIVATE CFHashRef
__CFDictionaryCreateTransfer(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, CFIndex numValues
) {
232 const_any_pointer_t
*vlist
= klist
;
234 CFTypeID typeID
= CFDictionaryGetTypeID();
235 CFAssert2(0 <= numValues
, __kCFLogAssertion
, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, numValues
);
236 CFOptionFlags flags
= kCFBasicHashLinearHashing
; // kCFBasicHashExponentialHashing
237 flags
|= (CFDictionary
? kCFBasicHashHasKeys
: 0) | (CFBag
? kCFBasicHashHasCounts
: 0);
239 CFBasicHashCallbacks callbacks
;
240 callbacks
.retainKey
= (uintptr_t (*)(CFAllocatorRef
, uintptr_t))kCFTypeDictionaryKeyCallBacks
.retain
;
241 callbacks
.releaseKey
= (void (*)(CFAllocatorRef
, uintptr_t))kCFTypeDictionaryKeyCallBacks
.release
;
242 callbacks
.equateKeys
= (Boolean (*)(uintptr_t, uintptr_t))kCFTypeDictionaryKeyCallBacks
.equal
;
243 callbacks
.hashKey
= (CFHashCode (*)(uintptr_t))kCFTypeDictionaryKeyCallBacks
.hash
;
244 callbacks
.getIndirectKey
= NULL
;
245 callbacks
.copyKeyDescription
= (CFStringRef (*)(uintptr_t))kCFTypeDictionaryKeyCallBacks
.copyDescription
;
246 callbacks
.retainValue
= CFDictionary
? (uintptr_t (*)(CFAllocatorRef
, uintptr_t))kCFTypeDictionaryValueCallBacks
.retain
: callbacks
.retainKey
;
247 callbacks
.releaseValue
= CFDictionary
? (void (*)(CFAllocatorRef
, uintptr_t))kCFTypeDictionaryValueCallBacks
.release
: callbacks
.releaseKey
;
248 callbacks
.equateValues
= CFDictionary
? (Boolean (*)(uintptr_t, uintptr_t))kCFTypeDictionaryValueCallBacks
.equal
: callbacks
.equateKeys
;
249 callbacks
.copyValueDescription
= CFDictionary
? (CFStringRef (*)(uintptr_t))kCFTypeDictionaryValueCallBacks
.copyDescription
: callbacks
.copyKeyDescription
;
251 CFBasicHashRef ht
= CFBasicHashCreate(allocator
, flags
, &callbacks
);
252 CFBasicHashSuppressRC(ht
);
253 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
254 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
255 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
257 CFBasicHashUnsuppressRC(ht
);
258 CFBasicHashMakeImmutable(ht
);
259 _CFRuntimeSetInstanceTypeIDAndIsa(ht
, typeID
);
260 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (immutable)");
261 return (CFHashRef
)ht
;
265 CFHashRef
CFDictionaryCreate(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, const_any_pointer_t
*vlist
, CFIndex numValues
, const CFDictionaryKeyCallBacks
*keyCallBacks
, const CFDictionaryValueCallBacks
*valueCallBacks
) {
268 CFHashRef
CFDictionaryCreate(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, CFIndex numValues
, const CFDictionaryKeyCallBacks
*keyCallBacks
) {
269 const_any_pointer_t
*vlist
= klist
;
270 const CFDictionaryValueCallBacks
*valueCallBacks
= 0;
272 CFTypeID typeID
= CFDictionaryGetTypeID();
273 CFAssert2(0 <= numValues
, __kCFLogAssertion
, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, numValues
);
274 CFBasicHashRef ht
= __CFDictionaryCreateGeneric(allocator
, keyCallBacks
, valueCallBacks
, CFDictionary
);
275 if (!ht
) return NULL
;
276 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
277 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
278 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
280 CFBasicHashMakeImmutable(ht
);
281 _CFRuntimeSetInstanceTypeIDAndIsa(ht
, typeID
);
282 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (immutable)");
283 return (CFHashRef
)ht
;
287 CFMutableHashRef
CFDictionaryCreateMutable(CFAllocatorRef allocator
, CFIndex capacity
, const CFDictionaryKeyCallBacks
*keyCallBacks
, const CFDictionaryValueCallBacks
*valueCallBacks
) {
290 CFMutableHashRef
CFDictionaryCreateMutable(CFAllocatorRef allocator
, CFIndex capacity
, const CFDictionaryKeyCallBacks
*keyCallBacks
) {
291 const CFDictionaryValueCallBacks
*valueCallBacks
= 0;
293 CFTypeID typeID
= CFDictionaryGetTypeID();
294 CFAssert2(0 <= capacity
, __kCFLogAssertion
, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, capacity
);
295 CFBasicHashRef ht
= __CFDictionaryCreateGeneric(allocator
, keyCallBacks
, valueCallBacks
, CFDictionary
);
296 if (!ht
) return NULL
;
297 _CFRuntimeSetInstanceTypeIDAndIsa(ht
, typeID
);
298 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (mutable)");
299 return (CFMutableHashRef
)ht
;
302 CFHashRef
CFDictionaryCreateCopy(CFAllocatorRef allocator
, CFHashRef other
) {
303 CFTypeID typeID
= CFDictionaryGetTypeID();
304 CFAssert1(other
, __kCFLogAssertion
, "%s(): other CFDictionary cannot be NULL", __PRETTY_FUNCTION__
);
305 __CFGenericValidateType(other
, typeID
);
306 CFBasicHashRef ht
= NULL
;
307 if (CF_IS_OBJC(typeID
, other
)) {
308 CFIndex numValues
= CFDictionaryGetCount(other
);
309 const_any_pointer_t vbuffer
[256], kbuffer
[256];
310 const_any_pointer_t
*vlist
= (numValues
<= 256) ? vbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
312 const_any_pointer_t
*klist
= vlist
;
313 CFDictionaryGetValues(other
, vlist
);
316 const_any_pointer_t
*klist
= (numValues
<= 256) ? kbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
317 CFDictionaryGetKeysAndValues(other
, klist
, vlist
);
319 ht
= __CFDictionaryCreateGeneric(allocator
, & kCFTypeDictionaryKeyCallBacks
, CFDictionary
? & kCFTypeDictionaryValueCallBacks
: NULL
, CFDictionary
);
320 if (ht
&& 0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
321 for (CFIndex idx
= 0; ht
&& idx
< numValues
; idx
++) {
322 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
324 if (klist
!= kbuffer
&& klist
!= vlist
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, klist
);
325 if (vlist
!= vbuffer
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, vlist
);
327 ht
= CFBasicHashCreateCopy(allocator
, (CFBasicHashRef
)other
);
329 if (!ht
) return NULL
;
330 CFBasicHashMakeImmutable(ht
);
331 _CFRuntimeSetInstanceTypeIDAndIsa(ht
, typeID
);
332 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (immutable)");
333 return (CFHashRef
)ht
;
336 CFMutableHashRef
CFDictionaryCreateMutableCopy(CFAllocatorRef allocator
, CFIndex capacity
, CFHashRef other
) {
337 CFTypeID typeID
= CFDictionaryGetTypeID();
338 CFAssert1(other
, __kCFLogAssertion
, "%s(): other CFDictionary cannot be NULL", __PRETTY_FUNCTION__
);
339 __CFGenericValidateType(other
, typeID
);
340 CFAssert2(0 <= capacity
, __kCFLogAssertion
, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, capacity
);
341 CFBasicHashRef ht
= NULL
;
342 if (CF_IS_OBJC(typeID
, other
)) {
343 CFIndex numValues
= CFDictionaryGetCount(other
);
344 const_any_pointer_t vbuffer
[256], kbuffer
[256];
345 const_any_pointer_t
*vlist
= (numValues
<= 256) ? vbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
347 const_any_pointer_t
*klist
= vlist
;
348 CFDictionaryGetValues(other
, vlist
);
351 const_any_pointer_t
*klist
= (numValues
<= 256) ? kbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
352 CFDictionaryGetKeysAndValues(other
, klist
, vlist
);
354 ht
= __CFDictionaryCreateGeneric(allocator
, & kCFTypeDictionaryKeyCallBacks
, CFDictionary
? & kCFTypeDictionaryValueCallBacks
: NULL
, CFDictionary
);
355 if (ht
&& 0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
356 for (CFIndex idx
= 0; ht
&& idx
< numValues
; idx
++) {
357 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
359 if (klist
!= kbuffer
&& klist
!= vlist
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, klist
);
360 if (vlist
!= vbuffer
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, vlist
);
362 ht
= CFBasicHashCreateCopy(allocator
, (CFBasicHashRef
)other
);
364 if (!ht
) return NULL
;
365 _CFRuntimeSetInstanceTypeIDAndIsa(ht
, typeID
);
366 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (mutable)");
367 return (CFMutableHashRef
)ht
;
370 CFIndex
CFDictionaryGetCount(CFHashRef hc
) {
371 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, CFIndex
, (NSDictionary
*)hc
, count
);
372 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, CFIndex
, (NSSet
*)hc
, count
);
373 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
374 return CFBasicHashGetCount((CFBasicHashRef
)hc
);
378 CFIndex
CFDictionaryGetCountOfKey(CFHashRef hc
, const_any_pointer_t key
) {
381 CFIndex
CFDictionaryGetCountOfValue(CFHashRef hc
, const_any_pointer_t key
) {
383 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, CFIndex
, (NSDictionary
*)hc
, countForKey
:(id
)key
);
384 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, CFIndex
, (NSSet
*)hc
, countForObject
:(id
)key
);
385 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
386 return CFBasicHashGetCountOfKey((CFBasicHashRef
)hc
, (uintptr_t)key
);
390 Boolean
CFDictionaryContainsKey(CFHashRef hc
, const_any_pointer_t key
) {
393 Boolean
CFDictionaryContainsValue(CFHashRef hc
, const_any_pointer_t key
) {
395 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, char, (NSDictionary
*)hc
, containsKey
:(id
)key
);
396 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, char, (NSSet
*)hc
, containsObject
:(id
)key
);
397 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
398 return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef
)hc
, (uintptr_t)key
));
401 const_any_pointer_t
CFDictionaryGetValue(CFHashRef hc
, const_any_pointer_t key
) {
402 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, const_any_pointer_t
, (NSDictionary
*)hc
, objectForKey
:(id
)key
);
403 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, const_any_pointer_t
, (NSSet
*)hc
, member
:(id
)key
);
404 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
405 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
406 return (0 < bkt
.count
? (const_any_pointer_t
)bkt
.weak_value
: 0);
409 Boolean
CFDictionaryGetValueIfPresent(CFHashRef hc
, const_any_pointer_t key
, const_any_pointer_t
*value
) {
410 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, Boolean
, (NSDictionary
*)hc
, __getValue
:(id
*)value forKey
:(id
)key
);
411 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, Boolean
, (NSSet
*)hc
, __getValue
:(id
*)value forObj
:(id
)key
);
412 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
413 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
416 if (kCFUseCollectableAllocator
&& (CFBasicHashGetFlags((CFBasicHashRef
)hc
) & kCFBasicHashStrongValues
)) {
417 __CFAssignWithWriteBarrier((void **)value
, (void *)bkt
.weak_value
);
419 *value
= (const_any_pointer_t
)bkt
.weak_value
;
428 CFIndex
CFDictionaryGetCountOfValue(CFHashRef hc
, const_any_pointer_t value
) {
429 CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, CFIndex
, (NSDictionary
*)hc
, countForObject
:(id
)value
);
430 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
431 return CFBasicHashGetCountOfValue((CFBasicHashRef
)hc
, (uintptr_t)value
);
434 Boolean
CFDictionaryContainsValue(CFHashRef hc
, const_any_pointer_t value
) {
435 CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, char, (NSDictionary
*)hc
, containsObject
:(id
)value
);
436 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
437 return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef
)hc
, (uintptr_t)value
));
440 CF_EXPORT Boolean
CFDictionaryGetKeyIfPresent(CFHashRef hc
, const_any_pointer_t key
, const_any_pointer_t
*actualkey
) {
441 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
442 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
445 if (kCFUseCollectableAllocator
&& (CFBasicHashGetFlags((CFBasicHashRef
)hc
) & kCFBasicHashStrongKeys
)) {
446 __CFAssignWithWriteBarrier((void **)actualkey
, (void *)bkt
.weak_key
);
448 *actualkey
= (const_any_pointer_t
)bkt
.weak_key
;
458 void CFDictionaryGetKeysAndValues(CFHashRef hc
, const_any_pointer_t
*keybuf
, const_any_pointer_t
*valuebuf
) {
461 void CFDictionaryGetValues(CFHashRef hc
, const_any_pointer_t
*keybuf
) {
462 const_any_pointer_t
*valuebuf
= 0;
464 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSDictionary
*)hc
, getObjects
:(id
*)valuebuf andKeys
:(id
*)keybuf
);
465 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSSet
*)hc
, getObjects
:(id
*)keybuf
);
466 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
467 if (kCFUseCollectableAllocator
) {
468 CFOptionFlags flags
= CFBasicHashGetFlags((CFBasicHashRef
)hc
);
469 __block const_any_pointer_t
*keys
= keybuf
;
470 __block const_any_pointer_t
*values
= valuebuf
;
471 CFBasicHashApply((CFBasicHashRef
)hc
, ^(CFBasicHashBucket bkt
) {
472 for (CFIndex cnt
= bkt
.count
; cnt
--;) {
473 if (keybuf
&& (flags
& kCFBasicHashStrongKeys
)) { __CFAssignWithWriteBarrier((void **)keys
, (void *)bkt
.weak_key
); keys
++; }
474 if (keybuf
&& !(flags
& kCFBasicHashStrongKeys
)) { *keys
++ = (const_any_pointer_t
)bkt
.weak_key
; }
475 if (valuebuf
&& (flags
& kCFBasicHashStrongValues
)) { __CFAssignWithWriteBarrier((void **)values
, (void *)bkt
.weak_value
); values
++; }
476 if (valuebuf
&& !(flags
& kCFBasicHashStrongValues
)) { *values
++ = (const_any_pointer_t
)bkt
.weak_value
; }
478 return (Boolean
)true;
481 CFBasicHashGetElements((CFBasicHashRef
)hc
, CFDictionaryGetCount(hc
), (uintptr_t *)valuebuf
, (uintptr_t *)keybuf
);
485 void CFDictionaryApplyFunction(CFHashRef hc
, CFDictionaryApplierFunction applier
, any_pointer_t context
) {
486 FAULT_CALLBACK((void **)&(applier
));
487 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSDictionary
*)hc
, __apply
:(void (*)(const void *, const void *, void *))applier context
:(void *)context
);
488 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSSet
*)hc
, __applyValues
:(void (*)(const void *, void *))applier context
:(void *)context
);
489 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
490 CFBasicHashApply((CFBasicHashRef
)hc
, ^(CFBasicHashBucket bkt
) {
492 INVOKE_CALLBACK3(applier
, (const_any_pointer_t
)bkt
.weak_key
, (const_any_pointer_t
)bkt
.weak_value
, context
);
495 INVOKE_CALLBACK2(applier
, (const_any_pointer_t
)bkt
.weak_value
, context
);
498 for (CFIndex cnt
= bkt
.count
; cnt
--;) {
499 INVOKE_CALLBACK2(applier
, (const_any_pointer_t
)bkt
.weak_value
, context
);
502 return (Boolean
)true;
506 // This function is for Foundation's benefit; no one else should use it.
507 CF_EXPORT
unsigned long _CFDictionaryFastEnumeration(CFHashRef hc
, struct __objcFastEnumerationStateEquivalent
*state
, void *stackbuffer
, unsigned long count
) {
508 if (CF_IS_OBJC(__kCFDictionaryTypeID
, hc
)) return 0;
509 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
510 return __CFBasicHashFastEnumeration((CFBasicHashRef
)hc
, (struct __objcFastEnumerationStateEquivalent2
*)state
, stackbuffer
, count
);
513 // This function is for Foundation's benefit; no one else should use it.
514 CF_EXPORT Boolean
_CFDictionaryIsMutable(CFHashRef hc
) {
515 if (CF_IS_OBJC(__kCFDictionaryTypeID
, hc
)) return false;
516 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
517 return CFBasicHashIsMutable((CFBasicHashRef
)hc
);
520 // This function is for Foundation's benefit; no one else should use it.
521 CF_EXPORT
void _CFDictionarySetCapacity(CFMutableHashRef hc
, CFIndex cap
) {
522 if (CF_IS_OBJC(__kCFDictionaryTypeID
, hc
)) return;
523 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
524 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
525 CFAssert3(CFDictionaryGetCount(hc
) <= cap
, __kCFLogAssertion
, "%s(): desired capacity (%ld) is less than count (%ld)", __PRETTY_FUNCTION__
, cap
, CFDictionaryGetCount(hc
));
526 CFBasicHashSetCapacity((CFBasicHashRef
)hc
, cap
);
529 CF_INLINE CFIndex
__CFDictionaryGetKVOBit(CFHashRef hc
) {
530 return __CFBitfieldGetValue(((CFRuntimeBase
*)hc
)->_cfinfo
[CF_INFO_BITS
], 0, 0);
533 CF_INLINE
void __CFDictionarySetKVOBit(CFHashRef hc
, CFIndex bit
) {
534 __CFBitfieldSetValue(((CFRuntimeBase
*)hc
)->_cfinfo
[CF_INFO_BITS
], 0, 0, ((uintptr_t)bit
& 0x1));
537 // This function is for Foundation's benefit; no one else should use it.
538 CF_EXPORT CFIndex
_CFDictionaryGetKVOBit(CFHashRef hc
) {
539 return __CFDictionaryGetKVOBit(hc
);
542 // This function is for Foundation's benefit; no one else should use it.
543 CF_EXPORT
void _CFDictionarySetKVOBit(CFHashRef hc
, CFIndex bit
) {
544 __CFDictionarySetKVOBit(hc
, bit
);
548 #if !defined(CF_OBJC_KVO_WILLCHANGE)
549 #define CF_OBJC_KVO_WILLCHANGE(obj, key)
550 #define CF_OBJC_KVO_DIDCHANGE(obj, key)
551 #define CF_OBJC_KVO_WILLCHANGEALL(obj)
552 #define CF_OBJC_KVO_DIDCHANGEALL(obj)
556 void CFDictionaryAddValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
559 void CFDictionaryAddValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
560 const_any_pointer_t value
= key
;
562 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSMutableDictionary
*)hc
, __addObject
:(id
)value forKey
:(id
)key
);
563 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSMutableSet
*)hc
, addObject
:(id
)key
);
564 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
565 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
566 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
567 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
569 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
570 CFBasicHashAddValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
571 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
575 void CFDictionaryReplaceValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
578 void CFDictionaryReplaceValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
579 const_any_pointer_t value
= key
;
581 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSMutableDictionary
*)hc
, replaceObject
:(id
)value forKey
:(id
)key
);
582 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSMutableSet
*)hc
, replaceObject
:(id
)key
);
583 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
584 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
585 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
586 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
588 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
589 CFBasicHashReplaceValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
590 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
594 void CFDictionarySetValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
597 void CFDictionarySetValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
598 const_any_pointer_t value
= key
;
600 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSMutableDictionary
*)hc
, __setObject
:(id
)value forKey
:(id
)key
);
601 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSMutableSet
*)hc
, setObject
:(id
)key
);
602 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
603 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
604 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
605 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
607 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
608 //#warning this for a dictionary used to not replace the key
609 CFBasicHashSetValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
610 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
613 void CFDictionaryRemoveValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
614 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSMutableDictionary
*)hc
, removeObjectForKey
:(id
)key
);
615 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSMutableSet
*)hc
, removeObject
:(id
)key
);
616 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
617 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
618 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
619 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
621 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
622 CFBasicHashRemoveValue((CFBasicHashRef
)hc
, (uintptr_t)key
);
623 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
626 void CFDictionaryRemoveAllValues(CFMutableHashRef hc
) {
627 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSMutableDictionary
*)hc
, removeAllObjects
);
628 if (CFSet
) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID
, void, (NSMutableSet
*)hc
, removeAllObjects
);
629 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
630 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
631 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
632 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
634 CF_OBJC_KVO_WILLCHANGEALL(hc
);
635 CFBasicHashRemoveAllValues((CFBasicHashRef
)hc
);
636 CF_OBJC_KVO_DIDCHANGEALL(hc
);
639 #undef CF_OBJC_KVO_WILLCHANGE
640 #undef CF_OBJC_KVO_DIDCHANGE
641 #undef CF_OBJC_KVO_WILLCHANGEALL
642 #undef CF_OBJC_KVO_DIDCHANGEALL