2 * Copyright (c) 2015 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-2014, 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
};
51 #define CFHashRef CFDictionaryRef
52 #define CFMutableHashRef CFMutableDictionaryRef
53 #define CFHashKeyCallBacks CFDictionaryKeyCallBacks
54 #define CFHashValueCallBacks CFDictionaryValueCallBacks
58 const CFDictionaryCallBacks kCFTypeDictionaryCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
59 const CFDictionaryCallBacks kCFCopyStringDictionaryCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
61 #define CFDictionaryKeyCallBacks CFDictionaryCallBacks
62 #define CFDictionaryValueCallBacks CFDictionaryCallBacks
63 #define kCFTypeDictionaryKeyCallBacks kCFTypeDictionaryCallBacks
64 #define kCFTypeDictionaryValueCallBacks kCFTypeDictionaryCallBacks
66 #define CFHashRef CFSetRef
67 #define CFMutableHashRef CFMutableSetRef
68 #define CFHashKeyCallBacks CFDictionaryCallBacks
69 #define CFHashValueCallBacks CFDictionaryCallBacks
73 const CFDictionaryCallBacks kCFTypeDictionaryCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
74 const CFDictionaryCallBacks kCFCopyStringDictionaryCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
76 #define CFDictionaryKeyCallBacks CFDictionaryCallBacks
77 #define CFDictionaryValueCallBacks CFDictionaryCallBacks
78 #define kCFTypeDictionaryKeyCallBacks kCFTypeDictionaryCallBacks
79 #define kCFTypeDictionaryValueCallBacks kCFTypeDictionaryCallBacks
81 #define CFHashRef CFBagRef
82 #define CFMutableHashRef CFMutableBagRef
83 #define CFHashKeyCallBacks CFDictionaryCallBacks
84 #define CFHashValueCallBacks CFDictionaryCallBacks
88 typedef uintptr_t any_t
;
89 typedef const void * const_any_pointer_t
;
90 typedef void * any_pointer_t
;
92 static Boolean
__CFDictionaryEqual(CFTypeRef cf1
, CFTypeRef cf2
) {
93 return __CFBasicHashEqual((CFBasicHashRef
)cf1
, (CFBasicHashRef
)cf2
);
96 static CFHashCode
__CFDictionaryHash(CFTypeRef cf
) {
97 return __CFBasicHashHash((CFBasicHashRef
)cf
);
100 static CFStringRef
__CFDictionaryCopyDescription(CFTypeRef cf
) {
101 return __CFBasicHashCopyDescription((CFBasicHashRef
)cf
);
104 static void __CFDictionaryDeallocate(CFTypeRef cf
) {
105 __CFBasicHashDeallocate((CFBasicHashRef
)cf
);
108 static CFTypeID __kCFDictionaryTypeID
= _kCFRuntimeNotATypeID
;
110 static const CFRuntimeClass __CFDictionaryClass
= {
111 _kCFRuntimeScannedObject
,
115 __CFDictionaryDeallocate
,
119 __CFDictionaryCopyDescription
122 CFTypeID
CFDictionaryGetTypeID(void) {
123 static dispatch_once_t initOnce
;
124 dispatch_once(&initOnce
, ^{ __kCFDictionaryTypeID
= _CFRuntimeRegisterClass(&__CFDictionaryClass
); });
125 return __kCFDictionaryTypeID
;
129 static CFBasicHashRef
__CFDictionaryCreateGeneric(CFAllocatorRef allocator
, const CFHashKeyCallBacks
*keyCallBacks
, const CFHashValueCallBacks
*valueCallBacks
, Boolean useValueCB
) {
130 CFOptionFlags flags
= kCFBasicHashLinearHashing
; // kCFBasicHashExponentialHashing
131 flags
|= (CFDictionary
? kCFBasicHashHasKeys
: 0) | (CFBag
? kCFBasicHashHasCounts
: 0);
133 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
134 Boolean set_cb
= false;
135 Boolean std_cb
= false;
136 const_any_pointer_t (*key_retain
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
137 void (*key_release
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
138 const_any_pointer_t (*value_retain
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
139 void (*value_release
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
141 if ((NULL
== keyCallBacks
|| 0 == keyCallBacks
->version
) && (!useValueCB
|| NULL
== valueCallBacks
|| 0 == valueCallBacks
->version
)) {
142 Boolean keyRetainNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->retain
;
143 Boolean keyReleaseNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->release
;
144 Boolean keyEquateNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->equal
;
145 Boolean keyHashNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->hash
;
146 Boolean keyDescribeNull
= NULL
== keyCallBacks
|| NULL
== keyCallBacks
->copyDescription
;
148 Boolean valueRetainNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->retain
)) || (!useValueCB
&& keyRetainNull
);
149 Boolean valueReleaseNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->release
)) || (!useValueCB
&& keyReleaseNull
);
150 Boolean valueEquateNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->equal
)) || (!useValueCB
&& keyEquateNull
);
151 Boolean valueDescribeNull
= (useValueCB
&& (NULL
== valueCallBacks
|| NULL
== valueCallBacks
->copyDescription
)) || (!useValueCB
&& keyDescribeNull
);
153 Boolean keyRetainStd
= keyRetainNull
|| __CFTypeCollectionRetain
== keyCallBacks
->retain
;
154 Boolean keyReleaseStd
= keyReleaseNull
|| __CFTypeCollectionRelease
== keyCallBacks
->release
;
155 Boolean keyEquateStd
= keyEquateNull
|| CFEqual
== keyCallBacks
->equal
;
156 Boolean keyHashStd
= keyHashNull
|| CFHash
== keyCallBacks
->hash
;
157 Boolean keyDescribeStd
= keyDescribeNull
|| CFCopyDescription
== keyCallBacks
->copyDescription
;
159 Boolean valueRetainStd
= (useValueCB
&& (valueRetainNull
|| __CFTypeCollectionRetain
== valueCallBacks
->retain
)) || (!useValueCB
&& keyRetainStd
);
160 Boolean valueReleaseStd
= (useValueCB
&& (valueReleaseNull
|| __CFTypeCollectionRelease
== valueCallBacks
->release
)) || (!useValueCB
&& keyReleaseStd
);
161 Boolean valueEquateStd
= (useValueCB
&& (valueEquateNull
|| CFEqual
== valueCallBacks
->equal
)) || (!useValueCB
&& keyEquateStd
);
162 Boolean valueDescribeStd
= (useValueCB
&& (valueDescribeNull
|| CFCopyDescription
== valueCallBacks
->copyDescription
)) || (!useValueCB
&& keyDescribeStd
);
164 if (keyRetainStd
&& keyReleaseStd
&& keyEquateStd
&& keyHashStd
&& keyDescribeStd
&& valueRetainStd
&& valueReleaseStd
&& valueEquateStd
&& valueDescribeStd
) {
166 if (!(keyRetainNull
|| keyReleaseNull
|| keyEquateNull
|| keyHashNull
|| keyDescribeNull
|| valueRetainNull
|| valueReleaseNull
|| valueEquateNull
|| valueDescribeNull
)) {
169 // just set these to tickle the GC Strong logic below in a way that mimics past practice
170 key_retain
= keyCallBacks
? keyCallBacks
->retain
: NULL
;
171 key_release
= keyCallBacks
? keyCallBacks
->release
: NULL
;
173 value_retain
= valueCallBacks
? valueCallBacks
->retain
: NULL
;
174 value_release
= valueCallBacks
? valueCallBacks
->release
: NULL
;
176 value_retain
= key_retain
;
177 value_release
= key_release
;
184 key_retain
= keyCallBacks
? keyCallBacks
->retain
: NULL
;
185 key_release
= keyCallBacks
? keyCallBacks
->release
: NULL
;
187 value_retain
= valueCallBacks
? valueCallBacks
->retain
: NULL
;
188 value_release
= valueCallBacks
? valueCallBacks
->release
: NULL
;
190 value_retain
= key_retain
;
191 value_release
= key_release
;
195 if (std_cb
|| value_retain
!= NULL
|| value_release
!= NULL
) {
196 flags
|= kCFBasicHashStrongValues
;
198 if (std_cb
|| key_retain
!= NULL
|| key_release
!= NULL
) {
199 flags
|= kCFBasicHashStrongKeys
;
204 CFBasicHashCallbacks callbacks
;
205 callbacks
.retainKey
= keyCallBacks
? (uintptr_t (*)(CFAllocatorRef
, uintptr_t))keyCallBacks
->retain
: NULL
;
206 callbacks
.releaseKey
= keyCallBacks
? (void (*)(CFAllocatorRef
, uintptr_t))keyCallBacks
->release
: NULL
;
207 callbacks
.equateKeys
= keyCallBacks
? (Boolean (*)(uintptr_t, uintptr_t))keyCallBacks
->equal
: NULL
;
208 callbacks
.hashKey
= keyCallBacks
? (CFHashCode (*)(uintptr_t))keyCallBacks
->hash
: NULL
;
209 callbacks
.getIndirectKey
= NULL
;
210 callbacks
.copyKeyDescription
= keyCallBacks
? (CFStringRef (*)(uintptr_t))keyCallBacks
->copyDescription
: NULL
;
211 callbacks
.retainValue
= useValueCB
? (valueCallBacks
? (uintptr_t (*)(CFAllocatorRef
, uintptr_t))valueCallBacks
->retain
: NULL
) : (callbacks
.retainKey
);
212 callbacks
.releaseValue
= useValueCB
? (valueCallBacks
? (void (*)(CFAllocatorRef
, uintptr_t))valueCallBacks
->release
: NULL
) : (callbacks
.releaseKey
);
213 callbacks
.equateValues
= useValueCB
? (valueCallBacks
? (Boolean (*)(uintptr_t, uintptr_t))valueCallBacks
->equal
: NULL
) : (callbacks
.equateKeys
);
214 callbacks
.copyValueDescription
= useValueCB
? (valueCallBacks
? (CFStringRef (*)(uintptr_t))valueCallBacks
->copyDescription
: NULL
) : (callbacks
.copyKeyDescription
);
216 CFBasicHashRef ht
= CFBasicHashCreate(allocator
, flags
, &callbacks
);
221 CF_PRIVATE CFHashRef
__CFDictionaryCreateTransfer(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, const_any_pointer_t
*vlist
, CFIndex numValues
) {
224 CF_PRIVATE CFHashRef
__CFDictionaryCreateTransfer(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, CFIndex numValues
) {
225 const_any_pointer_t
*vlist
= klist
;
227 CFTypeID typeID
= CFDictionaryGetTypeID();
228 CFAssert2(0 <= numValues
, __kCFLogAssertion
, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, numValues
);
229 CFOptionFlags flags
= kCFBasicHashLinearHashing
; // kCFBasicHashExponentialHashing
230 flags
|= (CFDictionary
? kCFBasicHashHasKeys
: 0) | (CFBag
? kCFBasicHashHasCounts
: 0);
232 CFBasicHashCallbacks callbacks
;
233 callbacks
.retainKey
= (uintptr_t (*)(CFAllocatorRef
, uintptr_t))kCFTypeDictionaryKeyCallBacks
.retain
;
234 callbacks
.releaseKey
= (void (*)(CFAllocatorRef
, uintptr_t))kCFTypeDictionaryKeyCallBacks
.release
;
235 callbacks
.equateKeys
= (Boolean (*)(uintptr_t, uintptr_t))kCFTypeDictionaryKeyCallBacks
.equal
;
236 callbacks
.hashKey
= (CFHashCode (*)(uintptr_t))kCFTypeDictionaryKeyCallBacks
.hash
;
237 callbacks
.getIndirectKey
= NULL
;
238 callbacks
.copyKeyDescription
= (CFStringRef (*)(uintptr_t))kCFTypeDictionaryKeyCallBacks
.copyDescription
;
239 callbacks
.retainValue
= CFDictionary
? (uintptr_t (*)(CFAllocatorRef
, uintptr_t))kCFTypeDictionaryValueCallBacks
.retain
: callbacks
.retainKey
;
240 callbacks
.releaseValue
= CFDictionary
? (void (*)(CFAllocatorRef
, uintptr_t))kCFTypeDictionaryValueCallBacks
.release
: callbacks
.releaseKey
;
241 callbacks
.equateValues
= CFDictionary
? (Boolean (*)(uintptr_t, uintptr_t))kCFTypeDictionaryValueCallBacks
.equal
: callbacks
.equateKeys
;
242 callbacks
.copyValueDescription
= CFDictionary
? (CFStringRef (*)(uintptr_t))kCFTypeDictionaryValueCallBacks
.copyDescription
: callbacks
.copyKeyDescription
;
244 CFBasicHashRef ht
= CFBasicHashCreate(allocator
, flags
, &callbacks
);
245 CFBasicHashSuppressRC(ht
);
246 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
247 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
248 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
250 CFBasicHashUnsuppressRC(ht
);
251 CFBasicHashMakeImmutable(ht
);
252 _CFRuntimeSetInstanceTypeIDAndIsa(ht
, typeID
);
253 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (immutable)");
254 return (CFHashRef
)ht
;
258 CFHashRef
CFDictionaryCreate(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, const_any_pointer_t
*vlist
, CFIndex numValues
, const CFDictionaryKeyCallBacks
*keyCallBacks
, const CFDictionaryValueCallBacks
*valueCallBacks
) {
261 CFHashRef
CFDictionaryCreate(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, CFIndex numValues
, const CFDictionaryKeyCallBacks
*keyCallBacks
) {
262 const_any_pointer_t
*vlist
= klist
;
263 const CFDictionaryValueCallBacks
*valueCallBacks
= 0;
265 CFTypeID typeID
= CFDictionaryGetTypeID();
266 CFAssert2(0 <= numValues
, __kCFLogAssertion
, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, numValues
);
267 CFBasicHashRef ht
= __CFDictionaryCreateGeneric(allocator
, keyCallBacks
, valueCallBacks
, CFDictionary
);
268 if (!ht
) return NULL
;
269 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
270 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
271 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
273 CFBasicHashMakeImmutable(ht
);
274 _CFRuntimeSetInstanceTypeIDAndIsa(ht
, typeID
);
275 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (immutable)");
276 return (CFHashRef
)ht
;
280 CFMutableHashRef
CFDictionaryCreateMutable(CFAllocatorRef allocator
, CFIndex capacity
, const CFDictionaryKeyCallBacks
*keyCallBacks
, const CFDictionaryValueCallBacks
*valueCallBacks
) {
283 CFMutableHashRef
CFDictionaryCreateMutable(CFAllocatorRef allocator
, CFIndex capacity
, const CFDictionaryKeyCallBacks
*keyCallBacks
) {
284 const CFDictionaryValueCallBacks
*valueCallBacks
= 0;
286 CFTypeID typeID
= CFDictionaryGetTypeID();
287 CFAssert2(0 <= capacity
, __kCFLogAssertion
, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, capacity
);
288 CFBasicHashRef ht
= __CFDictionaryCreateGeneric(allocator
, keyCallBacks
, valueCallBacks
, CFDictionary
);
289 if (!ht
) return NULL
;
290 _CFRuntimeSetInstanceTypeIDAndIsa(ht
, typeID
);
291 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (mutable)");
292 return (CFMutableHashRef
)ht
;
295 CFHashRef
CFDictionaryCreateCopy(CFAllocatorRef allocator
, CFHashRef other
) {
296 CFTypeID typeID
= CFDictionaryGetTypeID();
297 CFAssert1(other
, __kCFLogAssertion
, "%s(): other CFDictionary cannot be NULL", __PRETTY_FUNCTION__
);
298 __CFGenericValidateType(other
, typeID
);
299 CFBasicHashRef ht
= NULL
;
300 if (CF_IS_OBJC(typeID
, other
)) {
301 CFIndex numValues
= CFDictionaryGetCount(other
);
302 const_any_pointer_t vbuffer
[256], kbuffer
[256];
303 const_any_pointer_t
*vlist
= (numValues
<= 256) ? vbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
305 const_any_pointer_t
*klist
= vlist
;
306 CFDictionaryGetValues(other
, vlist
);
309 const_any_pointer_t
*klist
= (numValues
<= 256) ? kbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
310 CFDictionaryGetKeysAndValues(other
, klist
, vlist
);
312 ht
= __CFDictionaryCreateGeneric(allocator
, & kCFTypeDictionaryKeyCallBacks
, CFDictionary
? & kCFTypeDictionaryValueCallBacks
: NULL
, CFDictionary
);
313 if (ht
&& 0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
314 for (CFIndex idx
= 0; ht
&& idx
< numValues
; idx
++) {
315 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
317 if (klist
!= kbuffer
&& klist
!= vlist
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, klist
);
318 if (vlist
!= vbuffer
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, vlist
);
320 ht
= CFBasicHashCreateCopy(allocator
, (CFBasicHashRef
)other
);
322 if (!ht
) return NULL
;
323 CFBasicHashMakeImmutable(ht
);
324 _CFRuntimeSetInstanceTypeIDAndIsa(ht
, typeID
);
325 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (immutable)");
326 return (CFHashRef
)ht
;
329 CFMutableHashRef
CFDictionaryCreateMutableCopy(CFAllocatorRef allocator
, CFIndex capacity
, CFHashRef other
) {
330 CFTypeID typeID
= CFDictionaryGetTypeID();
331 CFAssert1(other
, __kCFLogAssertion
, "%s(): other CFDictionary cannot be NULL", __PRETTY_FUNCTION__
);
332 __CFGenericValidateType(other
, typeID
);
333 CFAssert2(0 <= capacity
, __kCFLogAssertion
, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, capacity
);
334 CFBasicHashRef ht
= NULL
;
335 if (CF_IS_OBJC(typeID
, other
)) {
336 CFIndex numValues
= CFDictionaryGetCount(other
);
337 const_any_pointer_t vbuffer
[256], kbuffer
[256];
338 const_any_pointer_t
*vlist
= (numValues
<= 256) ? vbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
340 const_any_pointer_t
*klist
= vlist
;
341 CFDictionaryGetValues(other
, vlist
);
344 const_any_pointer_t
*klist
= (numValues
<= 256) ? kbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
345 CFDictionaryGetKeysAndValues(other
, klist
, vlist
);
347 ht
= __CFDictionaryCreateGeneric(allocator
, & kCFTypeDictionaryKeyCallBacks
, CFDictionary
? & kCFTypeDictionaryValueCallBacks
: NULL
, CFDictionary
);
348 if (ht
&& 0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
349 for (CFIndex idx
= 0; ht
&& idx
< numValues
; idx
++) {
350 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
352 if (klist
!= kbuffer
&& klist
!= vlist
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, klist
);
353 if (vlist
!= vbuffer
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, vlist
);
355 ht
= CFBasicHashCreateCopy(allocator
, (CFBasicHashRef
)other
);
357 if (!ht
) return NULL
;
358 _CFRuntimeSetInstanceTypeIDAndIsa(ht
, typeID
);
359 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (mutable)");
360 return (CFMutableHashRef
)ht
;
363 CFIndex
CFDictionaryGetCount(CFHashRef hc
) {
365 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex
, (NSDictionary
*)hc
, count
);
368 if (CFSet
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex
, (NSSet
*)hc
, count
);
370 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
371 return CFBasicHashGetCount((CFBasicHashRef
)hc
);
375 CFIndex
CFDictionaryGetCountOfKey(CFHashRef hc
, const_any_pointer_t key
) {
378 CFIndex
CFDictionaryGetCountOfValue(CFHashRef hc
, const_any_pointer_t key
) {
381 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex
, (NSDictionary
*)hc
, countForKey
:(id
)key
);
384 if (CFSet
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex
, (NSSet
*)hc
, countForObject
:(id
)key
);
386 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
387 return CFBasicHashGetCountOfKey((CFBasicHashRef
)hc
, (uintptr_t)key
);
391 Boolean
CFDictionaryContainsKey(CFHashRef hc
, const_any_pointer_t key
) {
394 Boolean
CFDictionaryContainsValue(CFHashRef hc
, const_any_pointer_t key
) {
397 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), char, (NSDictionary
*)hc
, containsKey
:(id
)key
);
400 if (CFSet
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), char, (NSSet
*)hc
, containsObject
:(id
)key
);
402 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
403 return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef
)hc
, (uintptr_t)key
));
406 const_any_pointer_t
CFDictionaryGetValue(CFHashRef hc
, const_any_pointer_t key
) {
408 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), const_any_pointer_t
, (NSDictionary
*)hc
, objectForKey
:(id
)key
);
411 if (CFSet
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), const_any_pointer_t
, (NSSet
*)hc
, member
:(id
)key
);
413 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
414 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
415 return (0 < bkt
.count
? (const_any_pointer_t
)bkt
.weak_value
: 0);
418 Boolean
CFDictionaryGetValueIfPresent(CFHashRef hc
, const_any_pointer_t key
, const_any_pointer_t
*value
) {
420 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), Boolean
, (NSDictionary
*)hc
, __getValue
:(id
*)value forKey
:(id
)key
);
423 if (CFSet
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), Boolean
, (NSSet
*)hc
, __getValue
:(id
*)value forObj
:(id
)key
);
425 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
426 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
429 if (kCFUseCollectableAllocator
&& (CFBasicHashGetFlags((CFBasicHashRef
)hc
) & kCFBasicHashStrongValues
)) {
430 __CFAssignWithWriteBarrier((void **)value
, (void *)bkt
.weak_value
);
432 *value
= (const_any_pointer_t
)bkt
.weak_value
;
441 CFIndex
CFDictionaryGetCountOfValue(CFHashRef hc
, const_any_pointer_t value
) {
442 CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), CFIndex
, (NSDictionary
*)hc
, countForObject
:(id
)value
);
443 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
444 return CFBasicHashGetCountOfValue((CFBasicHashRef
)hc
, (uintptr_t)value
);
447 Boolean
CFDictionaryContainsValue(CFHashRef hc
, const_any_pointer_t value
) {
448 CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), char, (NSDictionary
*)hc
, containsObject
:(id
)value
);
449 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
450 return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef
)hc
, (uintptr_t)value
));
453 CF_EXPORT Boolean
CFDictionaryGetKeyIfPresent(CFHashRef hc
, const_any_pointer_t key
, const_any_pointer_t
*actualkey
) {
454 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
455 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
458 if (kCFUseCollectableAllocator
&& (CFBasicHashGetFlags((CFBasicHashRef
)hc
) & kCFBasicHashStrongKeys
)) {
459 __CFAssignWithWriteBarrier((void **)actualkey
, (void *)bkt
.weak_key
);
461 *actualkey
= (const_any_pointer_t
)bkt
.weak_key
;
471 void CFDictionaryGetKeysAndValues(CFHashRef hc
, const_any_pointer_t
*keybuf
, const_any_pointer_t
*valuebuf
) {
474 void CFDictionaryGetValues(CFHashRef hc
, const_any_pointer_t
*keybuf
) {
475 const_any_pointer_t
*valuebuf
= 0;
478 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSDictionary
*)hc
, getObjects
:(id
*)valuebuf andKeys
:(id
*)keybuf
);
481 if (CFSet
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSSet
*)hc
, getObjects
:(id
*)keybuf
);
483 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
484 if (kCFUseCollectableAllocator
) {
485 CFOptionFlags flags
= CFBasicHashGetFlags((CFBasicHashRef
)hc
);
486 __block const_any_pointer_t
*keys
= keybuf
;
487 __block const_any_pointer_t
*values
= valuebuf
;
488 CFBasicHashApply((CFBasicHashRef
)hc
, ^(CFBasicHashBucket bkt
) {
489 for (CFIndex cnt
= bkt
.count
; cnt
--;) {
490 if (keybuf
&& (flags
& kCFBasicHashStrongKeys
)) { __CFAssignWithWriteBarrier((void **)keys
, (void *)bkt
.weak_key
); keys
++; }
491 if (keybuf
&& !(flags
& kCFBasicHashStrongKeys
)) { *keys
++ = (const_any_pointer_t
)bkt
.weak_key
; }
492 if (valuebuf
&& (flags
& kCFBasicHashStrongValues
)) { __CFAssignWithWriteBarrier((void **)values
, (void *)bkt
.weak_value
); values
++; }
493 if (valuebuf
&& !(flags
& kCFBasicHashStrongValues
)) { *values
++ = (const_any_pointer_t
)bkt
.weak_value
; }
495 return (Boolean
)true;
498 CFBasicHashGetElements((CFBasicHashRef
)hc
, CFDictionaryGetCount(hc
), (uintptr_t *)valuebuf
, (uintptr_t *)keybuf
);
502 void CFDictionaryApplyFunction(CFHashRef hc
, CFDictionaryApplierFunction applier
, any_pointer_t context
) {
503 FAULT_CALLBACK((void **)&(applier
));
505 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSDictionary
*)hc
, __apply
:(void (*)(const void *, const void *, void *))applier context
:(void *)context
);
508 if (CFSet
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSSet
*)hc
, __applyValues
:(void (*)(const void *, void *))applier context
:(void *)context
);
510 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
511 CFBasicHashApply((CFBasicHashRef
)hc
, ^(CFBasicHashBucket bkt
) {
513 INVOKE_CALLBACK3(applier
, (const_any_pointer_t
)bkt
.weak_key
, (const_any_pointer_t
)bkt
.weak_value
, context
);
516 INVOKE_CALLBACK2(applier
, (const_any_pointer_t
)bkt
.weak_value
, context
);
519 for (CFIndex cnt
= bkt
.count
; cnt
--;) {
520 INVOKE_CALLBACK2(applier
, (const_any_pointer_t
)bkt
.weak_value
, context
);
523 return (Boolean
)true;
527 // This function is for Foundation's benefit; no one else should use it.
528 CF_EXPORT
unsigned long _CFDictionaryFastEnumeration(CFHashRef hc
, struct __objcFastEnumerationStateEquivalent
*state
, void *stackbuffer
, unsigned long count
) {
529 if (CF_IS_OBJC(CFDictionaryGetTypeID(), hc
)) return 0;
530 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
531 return __CFBasicHashFastEnumeration((CFBasicHashRef
)hc
, (struct __objcFastEnumerationStateEquivalent2
*)state
, stackbuffer
, count
);
534 // This function is for Foundation's benefit; no one else should use it.
535 CF_EXPORT Boolean
_CFDictionaryIsMutable(CFHashRef hc
) {
536 if (CF_IS_OBJC(CFDictionaryGetTypeID(), hc
)) return false;
537 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
538 return CFBasicHashIsMutable((CFBasicHashRef
)hc
);
541 // This function is for Foundation's benefit; no one else should use it.
542 CF_EXPORT
void _CFDictionarySetCapacity(CFMutableHashRef hc
, CFIndex cap
) {
543 if (CF_IS_OBJC(CFDictionaryGetTypeID(), hc
)) return;
544 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
545 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
546 CFAssert3(CFDictionaryGetCount(hc
) <= cap
, __kCFLogAssertion
, "%s(): desired capacity (%ld) is less than count (%ld)", __PRETTY_FUNCTION__
, cap
, CFDictionaryGetCount(hc
));
547 CFBasicHashSetCapacity((CFBasicHashRef
)hc
, cap
);
550 CF_INLINE CFIndex
__CFDictionaryGetKVOBit(CFHashRef hc
) {
551 return __CFBitfieldGetValue(((CFRuntimeBase
*)hc
)->_cfinfo
[CF_INFO_BITS
], 0, 0);
554 CF_INLINE
void __CFDictionarySetKVOBit(CFHashRef hc
, CFIndex bit
) {
555 __CFBitfieldSetValue(((CFRuntimeBase
*)hc
)->_cfinfo
[CF_INFO_BITS
], 0, 0, ((uintptr_t)bit
& 0x1));
558 // This function is for Foundation's benefit; no one else should use it.
559 CF_EXPORT CFIndex
_CFDictionaryGetKVOBit(CFHashRef hc
) {
560 return __CFDictionaryGetKVOBit(hc
);
563 // This function is for Foundation's benefit; no one else should use it.
564 CF_EXPORT
void _CFDictionarySetKVOBit(CFHashRef hc
, CFIndex bit
) {
565 __CFDictionarySetKVOBit(hc
, bit
);
569 #if !defined(CF_OBJC_KVO_WILLCHANGE)
570 #define CF_OBJC_KVO_WILLCHANGE(obj, key)
571 #define CF_OBJC_KVO_DIDCHANGE(obj, key)
572 #define CF_OBJC_KVO_WILLCHANGEALL(obj)
573 #define CF_OBJC_KVO_DIDCHANGEALL(obj)
577 void CFDictionaryAddValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
580 void CFDictionaryAddValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
581 const_any_pointer_t value
= key
;
584 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableDictionary
*)hc
, __addObject
:(id
)value forKey
:(id
)key
);
587 if (CFSet
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableSet
*)hc
, addObject
:(id
)key
);
589 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
590 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
591 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
592 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
594 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
595 CFBasicHashAddValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
596 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
600 void CFDictionaryReplaceValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
603 void CFDictionaryReplaceValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
604 const_any_pointer_t value
= key
;
607 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableDictionary
*)hc
, replaceObject
:(id
)value forKey
:(id
)key
);
610 if (CFSet
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableSet
*)hc
, replaceObject
:(id
)key
);
612 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
613 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
614 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
615 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
617 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
618 CFBasicHashReplaceValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
619 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
623 void CFDictionarySetValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
626 void CFDictionarySetValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
627 const_any_pointer_t value
= key
;
630 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableDictionary
*)hc
, __setObject
:(id
)value forKey
:(id
)key
);
633 if (CFSet
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableSet
*)hc
, setObject
:(id
)key
);
635 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
636 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
637 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
638 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
640 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
641 //#warning this for a dictionary used to not replace the key
642 CFBasicHashSetValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
643 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
646 void CFDictionaryRemoveValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
648 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableDictionary
*)hc
, removeObjectForKey
:(id
)key
);
651 if (CFSet
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableSet
*)hc
, removeObject
:(id
)key
);
653 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
654 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
655 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
656 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
658 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
659 CFBasicHashRemoveValue((CFBasicHashRef
)hc
, (uintptr_t)key
);
660 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
663 void CFDictionaryRemoveAllValues(CFMutableHashRef hc
) {
665 if (CFDictionary
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableDictionary
*)hc
, removeAllObjects
);
668 if (CFSet
) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSMutableSet
*)hc
, removeAllObjects
);
670 __CFGenericValidateType(hc
, CFDictionaryGetTypeID());
671 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
672 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
673 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
675 CF_OBJC_KVO_WILLCHANGEALL(hc
);
676 CFBasicHashRemoveAllValues((CFBasicHashRef
)hc
);
677 CF_OBJC_KVO_DIDCHANGEALL(hc
);
680 #undef CF_OBJC_KVO_WILLCHANGE
681 #undef CF_OBJC_KVO_DIDCHANGE
682 #undef CF_OBJC_KVO_WILLCHANGEALL
683 #undef CF_OBJC_KVO_DIDCHANGEALL