2 * Copyright (c) 2009 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 Copyright 1998-2008, 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 static const CFDictionaryKeyCallBacks __kCFNullDictionaryKeyCallBacks
= {0, NULL
, NULL
, NULL
, NULL
, NULL
};
50 static const CFDictionaryValueCallBacks __kCFNullDictionaryValueCallBacks
= {0, NULL
, NULL
, NULL
, NULL
};
52 #define CFHashRef CFDictionaryRef
53 #define CFMutableHashRef CFMutableDictionaryRef
54 #define CFHashKeyCallBacks CFDictionaryKeyCallBacks
55 #define CFHashValueCallBacks CFDictionaryValueCallBacks
59 const CFDictionaryCallBacks kCFTypeDictionaryCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
60 const CFDictionaryCallBacks kCFCopyStringDictionaryCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
61 static const CFDictionaryCallBacks __kCFNullDictionaryCallBacks
= {0, NULL
, NULL
, NULL
, NULL
, NULL
};
63 #define CFDictionaryKeyCallBacks CFDictionaryCallBacks
64 #define CFDictionaryValueCallBacks CFDictionaryCallBacks
65 #define kCFTypeDictionaryKeyCallBacks kCFTypeDictionaryCallBacks
66 #define kCFTypeDictionaryValueCallBacks kCFTypeDictionaryCallBacks
67 #define __kCFNullDictionaryKeyCallBacks __kCFNullDictionaryCallBacks
68 #define __kCFNullDictionaryValueCallBacks __kCFNullDictionaryCallBacks
70 #define CFHashRef CFSetRef
71 #define CFMutableHashRef CFMutableSetRef
72 #define CFHashKeyCallBacks CFDictionaryCallBacks
73 #define CFHashValueCallBacks CFDictionaryCallBacks
77 const CFDictionaryCallBacks kCFTypeDictionaryCallBacks
= {0, __CFTypeCollectionRetain
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
78 const CFDictionaryCallBacks kCFCopyStringDictionaryCallBacks
= {0, __CFStringCollectionCopy
, __CFTypeCollectionRelease
, CFCopyDescription
, CFEqual
, CFHash
};
79 static const CFDictionaryCallBacks __kCFNullDictionaryCallBacks
= {0, NULL
, NULL
, NULL
, NULL
, NULL
};
81 #define CFDictionaryKeyCallBacks CFDictionaryCallBacks
82 #define CFDictionaryValueCallBacks CFDictionaryCallBacks
83 #define kCFTypeDictionaryKeyCallBacks kCFTypeDictionaryCallBacks
84 #define kCFTypeDictionaryValueCallBacks kCFTypeDictionaryCallBacks
85 #define __kCFNullDictionaryKeyCallBacks __kCFNullDictionaryCallBacks
86 #define __kCFNullDictionaryValueCallBacks __kCFNullDictionaryCallBacks
88 #define CFHashRef CFBagRef
89 #define CFMutableHashRef CFMutableBagRef
90 #define CFHashKeyCallBacks CFDictionaryCallBacks
91 #define CFHashValueCallBacks CFDictionaryCallBacks
95 typedef uintptr_t any_t
;
96 typedef const void * const_any_pointer_t
;
97 typedef void * any_pointer_t
;
99 static Boolean
__CFDictionaryEqual(CFTypeRef cf1
, CFTypeRef cf2
) {
100 return __CFBasicHashEqual((CFBasicHashRef
)cf1
, (CFBasicHashRef
)cf2
);
103 static CFHashCode
__CFDictionaryHash(CFTypeRef cf
) {
104 return __CFBasicHashHash((CFBasicHashRef
)cf
);
107 static CFStringRef
__CFDictionaryCopyDescription(CFTypeRef cf
) {
108 return __CFBasicHashCopyDescription((CFBasicHashRef
)cf
);
111 static void __CFDictionaryDeallocate(CFTypeRef cf
) {
112 __CFBasicHashDeallocate((CFBasicHashRef
)cf
);
115 static CFTypeID __kCFDictionaryTypeID
= _kCFRuntimeNotATypeID
;
117 static const CFRuntimeClass __CFDictionaryClass
= {
118 _kCFRuntimeScannedObject
,
122 __CFDictionaryDeallocate
,
126 __CFDictionaryCopyDescription
129 CFTypeID
CFDictionaryGetTypeID(void) {
130 if (_kCFRuntimeNotATypeID
== __kCFDictionaryTypeID
) __kCFDictionaryTypeID
= _CFRuntimeRegisterClass(&__CFDictionaryClass
);
131 return __kCFDictionaryTypeID
;
134 static uintptr_t __CFDictionaryCallback(CFBasicHashRef ht
, uint8_t op
, uintptr_t a1
, uintptr_t a2
, CFBasicHashCallbacks
*cb
) {
136 case kCFBasicHashCallbackOpCopyCallbacks
: {
137 CFBasicHashCallbacks
*newcb
= NULL
;
138 if (CF_IS_COLLECTABLE_ALLOCATOR((CFAllocatorRef
)a1
)) {
139 newcb
= (CFBasicHashCallbacks
*)auto_zone_allocate_object(auto_zone(), 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED
, true, false);
141 newcb
= (CFBasicHashCallbacks
*)CFAllocatorAllocate((CFAllocatorRef
)a1
, 10 * sizeof(void *), 0);
144 memmove(newcb
, (void *)cb
, 10 * sizeof(void *));
145 return (uintptr_t)newcb
;
147 case kCFBasicHashCallbackOpFreeCallbacks
: {
148 if (CF_IS_COLLECTABLE_ALLOCATOR((CFAllocatorRef
)a1
)) {
149 auto_zone_release(auto_zone(), cb
);
151 CFAllocatorDeallocate((CFAllocatorRef
)a1
, cb
);
155 case kCFBasicHashCallbackOpRetainValue
: {
156 const_any_pointer_t (*value_retain
)(CFAllocatorRef
, const_any_pointer_t
) = (const_any_pointer_t (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[0];
157 if (NULL
== value_retain
) return a1
;
158 return (uintptr_t)INVOKE_CALLBACK2(value_retain
, CFGetAllocator(ht
), (const_any_pointer_t
)a1
);
160 case kCFBasicHashCallbackOpRetainKey
: {
161 const_any_pointer_t (*key_retain
)(CFAllocatorRef
, const_any_pointer_t
) = (const_any_pointer_t (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[1];
162 if (NULL
== key_retain
) return a1
;
163 return (uintptr_t)INVOKE_CALLBACK2(key_retain
, CFGetAllocator(ht
), (const_any_pointer_t
)a1
);
165 case kCFBasicHashCallbackOpReleaseValue
: {
166 void (*value_release
)(CFAllocatorRef
, const_any_pointer_t
) = (void (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[2];
167 if (NULL
!= value_release
) INVOKE_CALLBACK2(value_release
, CFGetAllocator(ht
), (const_any_pointer_t
)a1
);
170 case kCFBasicHashCallbackOpReleaseKey
: {
171 void (*key_release
)(CFAllocatorRef
, const_any_pointer_t
) = (void (*)(CFAllocatorRef
, const_any_pointer_t
))cb
->context
[3];
172 if (NULL
!= key_release
) INVOKE_CALLBACK2(key_release
, CFGetAllocator(ht
), (const_any_pointer_t
)a1
);
175 case kCFBasicHashCallbackOpValueEqual
: {
176 Boolean (*value_equal
)(const_any_pointer_t
, const_any_pointer_t
) = (Boolean (*)(const_any_pointer_t
, const_any_pointer_t
))cb
->context
[4];
177 if (NULL
== value_equal
) return (a1
== a2
);
178 return INVOKE_CALLBACK2(value_equal
, (const_any_pointer_t
)a1
, (const_any_pointer_t
)a2
) ? 1 : 0;
180 case kCFBasicHashCallbackOpKeyEqual
: {
181 Boolean (*key_equal
)(const_any_pointer_t
, const_any_pointer_t
) = (Boolean (*)(const_any_pointer_t
, const_any_pointer_t
))cb
->context
[5];
182 if (NULL
== key_equal
) return (a1
== a2
);
183 return INVOKE_CALLBACK2(key_equal
, (const_any_pointer_t
)a1
, (const_any_pointer_t
)a2
) ? 1 : 0;
185 case kCFBasicHashCallbackOpHashKey
: {
186 CFHashCode (*hash
)(const_any_pointer_t
) = (CFHashCode (*)(const_any_pointer_t
))cb
->context
[6];
187 if (NULL
== hash
) return a1
;
188 return (uintptr_t)INVOKE_CALLBACK1(hash
, (const_any_pointer_t
)a1
);
190 case kCFBasicHashCallbackOpDescribeValue
: {
191 CFStringRef (*value_describe
)(const_any_pointer_t
) = (CFStringRef (*)(const_any_pointer_t
))cb
->context
[7];
192 if (NULL
== value_describe
) return (uintptr_t)CFStringCreateWithFormat(kCFAllocatorSystemDefault
, NULL
, CFSTR("<%p>"), (const_any_pointer_t
)a1
);
193 return (uintptr_t)INVOKE_CALLBACK1(value_describe
, (const_any_pointer_t
)a1
);
195 case kCFBasicHashCallbackOpDescribeKey
: {
196 CFStringRef (*key_describe
)(const_any_pointer_t
) = (CFStringRef (*)(const_any_pointer_t
))cb
->context
[8];
197 if (NULL
== key_describe
) return (uintptr_t)CFStringCreateWithFormat(kCFAllocatorSystemDefault
, NULL
, CFSTR("<%p>"), (const_any_pointer_t
)a1
);
198 return (uintptr_t)INVOKE_CALLBACK1(key_describe
, (const_any_pointer_t
)a1
);
204 static CFBasicHashRef
__CFDictionaryCreateGeneric(CFAllocatorRef allocator
, const CFHashKeyCallBacks
*keyCallBacks
, const CFHashValueCallBacks
*valueCallBacks
, Boolean useValueCB
) {
206 CFBasicHashCallbacks
*cb
= NULL
;
207 CFOptionFlags flags
= kCFBasicHashLinearHashing
; // kCFBasicHashExponentialHashing
208 flags
|= (CFDictionary
? kCFBasicHashHasKeys
: 0) | (CFBag
? kCFBasicHashHasCounts
: 0);
210 const_any_pointer_t (*key_retain
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
211 void (*key_release
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
212 const_any_pointer_t (*value_retain
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
213 void (*value_release
)(CFAllocatorRef
, const_any_pointer_t
) = NULL
;
214 Boolean std_cb
= false;
215 if ((NULL
== keyCallBacks
|| (keyCallBacks
&& 0 == memcmp(&__kCFNullDictionaryKeyCallBacks
, keyCallBacks
, sizeof(__kCFNullDictionaryKeyCallBacks
))))
216 && (!useValueCB
|| (NULL
== valueCallBacks
|| (valueCallBacks
&& 0 == memcmp(&__kCFNullDictionaryValueCallBacks
, valueCallBacks
, sizeof(__kCFNullDictionaryValueCallBacks
)))))) {
217 cb
= (CFBasicHashCallbacks
*)& CFBasicHashNullCallbacks
;
218 } else if ((&kCFTypeDictionaryKeyCallBacks
== keyCallBacks
|| (keyCallBacks
&& 0 == memcmp(&kCFTypeDictionaryKeyCallBacks
, keyCallBacks
, sizeof(kCFTypeDictionaryKeyCallBacks
))))
219 && (!useValueCB
|| (&kCFTypeDictionaryValueCallBacks
== valueCallBacks
|| (valueCallBacks
&& 0 == memcmp(&kCFTypeDictionaryValueCallBacks
, valueCallBacks
, sizeof(kCFTypeDictionaryValueCallBacks
)))))) {
221 cb
= (CFBasicHashCallbacks
*)& CFBasicHashStandardCallbacks
;
223 Boolean (*key_equal
)(const_any_pointer_t
, const_any_pointer_t
) = NULL
;
224 Boolean (*value_equal
)(const_any_pointer_t
, const_any_pointer_t
) = NULL
;
225 CFStringRef (*key_describe
)(const_any_pointer_t
) = NULL
;
226 CFStringRef (*value_describe
)(const_any_pointer_t
) = NULL
;
227 CFHashCode (*hash_key
)(const_any_pointer_t
) = NULL
;
228 key_retain
= keyCallBacks
? keyCallBacks
->retain
: NULL
;
229 key_release
= keyCallBacks
? keyCallBacks
->release
: NULL
;
230 key_equal
= keyCallBacks
? keyCallBacks
->equal
: NULL
;
231 key_describe
= keyCallBacks
? keyCallBacks
->copyDescription
: NULL
;
233 value_retain
= valueCallBacks
? valueCallBacks
->retain
: NULL
;
234 value_release
= valueCallBacks
? valueCallBacks
->release
: NULL
;
235 value_equal
= valueCallBacks
? valueCallBacks
->equal
: NULL
;
236 value_describe
= valueCallBacks
? valueCallBacks
->copyDescription
: NULL
;
238 value_retain
= key_retain
;
239 value_release
= key_release
;
240 value_equal
= key_equal
;
241 value_describe
= key_describe
;
243 hash_key
= keyCallBacks
? keyCallBacks
->hash
: NULL
;
244 FAULT_CALLBACK((void **)&key_retain
);
245 FAULT_CALLBACK((void **)&key_release
);
246 FAULT_CALLBACK((void **)&value_retain
);
247 FAULT_CALLBACK((void **)&value_release
);
248 FAULT_CALLBACK((void **)&key_equal
);
249 FAULT_CALLBACK((void **)&value_equal
);
250 FAULT_CALLBACK((void **)&key_describe
);
251 FAULT_CALLBACK((void **)&value_describe
);
252 FAULT_CALLBACK((void **)&hash_key
);
254 CFBasicHashCallbacks
*newcb
= NULL
;
255 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) {
256 newcb
= (CFBasicHashCallbacks
*)auto_zone_allocate_object(auto_zone(), 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED
, true, false);
258 newcb
= (CFBasicHashCallbacks
*)CFAllocatorAllocate(allocator
, 10 * sizeof(void *), 0);
261 newcb
->func
= (CFBasicHashCallbackType
)__CFDictionaryCallback
;
262 newcb
->context
[0] = (uintptr_t)value_retain
;
263 newcb
->context
[1] = (uintptr_t)key_retain
;
264 newcb
->context
[2] = (uintptr_t)value_release
;
265 newcb
->context
[3] = (uintptr_t)key_release
;
266 newcb
->context
[4] = (uintptr_t)value_equal
;
267 newcb
->context
[5] = (uintptr_t)key_equal
;
268 newcb
->context
[6] = (uintptr_t)hash_key
;
269 newcb
->context
[7] = (uintptr_t)value_describe
;
270 newcb
->context
[8] = (uintptr_t)key_describe
;
274 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator
)) {
275 if (std_cb
|| value_retain
!= NULL
|| value_release
!= NULL
) {
276 flags
|= kCFBasicHashStrongValues
;
278 if (std_cb
|| key_retain
!= NULL
|| key_release
!= NULL
) {
279 flags
|= kCFBasicHashStrongKeys
;
283 return CFBasicHashCreate(allocator
, flags
, cb
);
287 CFHashRef
CFDictionaryCreate(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, const_any_pointer_t
*vlist
, CFIndex numValues
, const CFDictionaryKeyCallBacks
*keyCallBacks
, const CFDictionaryValueCallBacks
*valueCallBacks
) {
290 CFHashRef
CFDictionaryCreate(CFAllocatorRef allocator
, const_any_pointer_t
*klist
, CFIndex numValues
, const CFDictionaryKeyCallBacks
*keyCallBacks
) {
291 const_any_pointer_t
*vlist
= klist
;
292 const CFDictionaryValueCallBacks
*valueCallBacks
= 0;
294 CFTypeID typeID
= CFDictionaryGetTypeID();
295 CFAssert2(0 <= numValues
, __kCFLogAssertion
, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, numValues
);
296 CFBasicHashRef ht
= __CFDictionaryCreateGeneric(allocator
, keyCallBacks
, valueCallBacks
, CFDictionary
);
297 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
298 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
299 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
301 CFBasicHashMakeImmutable(ht
);
302 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
303 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
304 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (immutable)");
305 return (CFHashRef
)ht
;
309 CFMutableHashRef
CFDictionaryCreateMutable(CFAllocatorRef allocator
, CFIndex capacity
, const CFDictionaryKeyCallBacks
*keyCallBacks
, const CFDictionaryValueCallBacks
*valueCallBacks
) {
312 CFMutableHashRef
CFDictionaryCreateMutable(CFAllocatorRef allocator
, CFIndex capacity
, const CFDictionaryKeyCallBacks
*keyCallBacks
) {
313 const CFDictionaryValueCallBacks
*valueCallBacks
= 0;
315 CFTypeID typeID
= CFDictionaryGetTypeID();
316 CFAssert2(0 <= capacity
, __kCFLogAssertion
, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, capacity
);
317 CFBasicHashRef ht
= __CFDictionaryCreateGeneric(allocator
, keyCallBacks
, valueCallBacks
, CFDictionary
);
318 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
319 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
320 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (mutable)");
321 return (CFMutableHashRef
)ht
;
324 CFHashRef
CFDictionaryCreateCopy(CFAllocatorRef allocator
, CFHashRef other
) {
325 CFTypeID typeID
= CFDictionaryGetTypeID();
326 CFAssert1(other
, __kCFLogAssertion
, "%s(): other CFDictionary cannot be NULL", __PRETTY_FUNCTION__
);
327 __CFGenericValidateType(other
, typeID
);
328 CFBasicHashRef ht
= NULL
;
329 if (CF_IS_OBJC(typeID
, other
)) {
330 CFIndex numValues
= CFDictionaryGetCount(other
);
331 const_any_pointer_t vbuffer
[256], kbuffer
[256];
332 const_any_pointer_t
*vlist
= (numValues
<= 256) ? vbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
334 const_any_pointer_t
*klist
= vlist
;
335 CFDictionaryGetValues(other
, vlist
);
338 const_any_pointer_t
*klist
= (numValues
<= 256) ? kbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
339 CFDictionaryGetKeysAndValues(other
, klist
, vlist
);
341 ht
= __CFDictionaryCreateGeneric(allocator
, & kCFTypeDictionaryKeyCallBacks
, CFDictionary
? & kCFTypeDictionaryValueCallBacks
: NULL
, CFDictionary
);
342 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
343 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
344 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
346 if (klist
!= kbuffer
&& klist
!= vlist
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, klist
);
347 if (vlist
!= vbuffer
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, vlist
);
349 ht
= CFBasicHashCreateCopy(allocator
, (CFBasicHashRef
)other
);
351 CFBasicHashMakeImmutable(ht
);
352 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
353 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
354 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (immutable)");
355 return (CFHashRef
)ht
;
358 CFMutableHashRef
CFDictionaryCreateMutableCopy(CFAllocatorRef allocator
, CFIndex capacity
, CFHashRef other
) {
359 CFTypeID typeID
= CFDictionaryGetTypeID();
360 CFAssert1(other
, __kCFLogAssertion
, "%s(): other CFDictionary cannot be NULL", __PRETTY_FUNCTION__
);
361 __CFGenericValidateType(other
, typeID
);
362 CFAssert2(0 <= capacity
, __kCFLogAssertion
, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__
, capacity
);
363 CFBasicHashRef ht
= NULL
;
364 if (CF_IS_OBJC(typeID
, other
)) {
365 CFIndex numValues
= CFDictionaryGetCount(other
);
366 const_any_pointer_t vbuffer
[256], kbuffer
[256];
367 const_any_pointer_t
*vlist
= (numValues
<= 256) ? vbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
369 const_any_pointer_t
*klist
= vlist
;
370 CFDictionaryGetValues(other
, vlist
);
373 const_any_pointer_t
*klist
= (numValues
<= 256) ? kbuffer
: (const_any_pointer_t
*)CFAllocatorAllocate(kCFAllocatorSystemDefault
, numValues
* sizeof(const_any_pointer_t
), 0);
374 CFDictionaryGetKeysAndValues(other
, klist
, vlist
);
376 ht
= __CFDictionaryCreateGeneric(allocator
, & kCFTypeDictionaryKeyCallBacks
, CFDictionary
? & kCFTypeDictionaryValueCallBacks
: NULL
, CFDictionary
);
377 if (0 < numValues
) CFBasicHashSetCapacity(ht
, numValues
);
378 for (CFIndex idx
= 0; idx
< numValues
; idx
++) {
379 CFBasicHashAddValue(ht
, (uintptr_t)klist
[idx
], (uintptr_t)vlist
[idx
]);
381 if (klist
!= kbuffer
&& klist
!= vlist
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, klist
);
382 if (vlist
!= vbuffer
) CFAllocatorDeallocate(kCFAllocatorSystemDefault
, vlist
);
384 ht
= CFBasicHashCreateCopy(allocator
, (CFBasicHashRef
)other
);
386 *(uintptr_t *)ht
= __CFISAForTypeID(typeID
);
387 _CFRuntimeSetInstanceTypeID(ht
, typeID
);
388 if (__CFOASafe
) __CFSetLastAllocationEventName(ht
, "CFDictionary (mutable)");
389 return (CFMutableHashRef
)ht
;
392 CFIndex
CFDictionaryGetCount(CFHashRef hc
) {
393 if (CFDictionary
) CF_OBJC_FUNCDISPATCH0(__kCFDictionaryTypeID
, CFIndex
, hc
, "count");
394 if (CFSet
) CF_OBJC_FUNCDISPATCH0(__kCFDictionaryTypeID
, CFIndex
, hc
, "count");
395 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
396 return CFBasicHashGetCount((CFBasicHashRef
)hc
);
400 CFIndex
CFDictionaryGetCountOfKey(CFHashRef hc
, const_any_pointer_t key
) {
403 CFIndex
CFDictionaryGetCountOfValue(CFHashRef hc
, const_any_pointer_t key
) {
405 if (CFDictionary
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, CFIndex
, hc
, "countForKey:", key
);
406 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, CFIndex
, hc
, "countForObject:", key
);
407 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
408 return CFBasicHashGetCountOfKey((CFBasicHashRef
)hc
, (uintptr_t)key
);
412 Boolean
CFDictionaryContainsKey(CFHashRef hc
, const_any_pointer_t key
) {
415 Boolean
CFDictionaryContainsValue(CFHashRef hc
, const_any_pointer_t key
) {
417 if (CFDictionary
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, char, hc
, "containsKey:", key
);
418 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, char, hc
, "containsObject:", key
);
419 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
420 return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef
)hc
, (uintptr_t)key
));
423 const_any_pointer_t
CFDictionaryGetValue(CFHashRef hc
, const_any_pointer_t key
) {
424 if (CFDictionary
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, const_any_pointer_t
, hc
, "objectForKey:", key
);
425 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, const_any_pointer_t
, hc
, "member:", key
);
426 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
427 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
428 return (0 < bkt
.count
? (const_any_pointer_t
)bkt
.weak_value
: 0);
431 Boolean
CFDictionaryGetValueIfPresent(CFHashRef hc
, const_any_pointer_t key
, const_any_pointer_t
*value
) {
432 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, Boolean
, hc
, "_getValue:forKey:", (any_t
*)value
, key
);
433 if (CFSet
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, Boolean
, hc
, "_getValue:forObj:", (any_t
*)value
, key
);
434 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
435 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
438 if (kCFUseCollectableAllocator
&& (CFBasicHashGetFlags((CFBasicHashRef
)hc
) & kCFBasicHashStrongValues
)) {
439 __CFAssignWithWriteBarrier((void **)value
, (void *)bkt
.weak_value
);
441 *value
= (const_any_pointer_t
)bkt
.weak_value
;
450 CFIndex
CFDictionaryGetCountOfValue(CFHashRef hc
, const_any_pointer_t value
) {
451 CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, CFIndex
, hc
, "countForObject:", value
);
452 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
453 return CFBasicHashGetCountOfValue((CFBasicHashRef
)hc
, (uintptr_t)value
);
456 Boolean
CFDictionaryContainsValue(CFHashRef hc
, const_any_pointer_t value
) {
457 CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, char, hc
, "containsObject:", value
);
458 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
459 return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef
)hc
, (uintptr_t)value
));
462 CF_EXPORT Boolean
CFDictionaryGetKeyIfPresent(CFHashRef hc
, const_any_pointer_t key
, const_any_pointer_t
*actualkey
) {
463 CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, Boolean
, hc
, "getActualKey:forKey:", actualkey
, key
);
464 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
465 CFBasicHashBucket bkt
= CFBasicHashFindBucket((CFBasicHashRef
)hc
, (uintptr_t)key
);
468 if (kCFUseCollectableAllocator
&& (CFBasicHashGetFlags((CFBasicHashRef
)hc
) & kCFBasicHashStrongKeys
)) {
469 __CFAssignWithWriteBarrier((void **)actualkey
, (void *)bkt
.weak_key
);
471 *actualkey
= (const_any_pointer_t
)bkt
.weak_key
;
481 void CFDictionaryGetKeysAndValues(CFHashRef hc
, const_any_pointer_t
*keybuf
, const_any_pointer_t
*valuebuf
) {
484 void CFDictionaryGetValues(CFHashRef hc
, const_any_pointer_t
*keybuf
) {
485 const_any_pointer_t
*valuebuf
= 0;
487 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, void, hc
, "getObjects:andKeys:", (any_t
*)valuebuf
, (any_t
*)keybuf
);
488 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, void, hc
, "getObjects:", (any_t
*)keybuf
);
489 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
490 if (kCFUseCollectableAllocator
) {
491 CFOptionFlags flags
= CFBasicHashGetFlags((CFBasicHashRef
)hc
);
492 __block const_any_pointer_t
*keys
= keybuf
, *values
= valuebuf
;
493 CFBasicHashApply((CFBasicHashRef
)hc
, ^(CFBasicHashBucket bkt
) {
494 for (CFIndex cnt
= bkt
.count
; cnt
--;) {
495 if (keybuf
&& (flags
& kCFBasicHashStrongKeys
)) { __CFAssignWithWriteBarrier((void **)keys
, (void *)bkt
.weak_key
); keys
++; }
496 if (keybuf
&& !(flags
& kCFBasicHashStrongKeys
)) { *keys
++ = (const_any_pointer_t
)bkt
.weak_key
; }
497 if (valuebuf
&& (flags
& kCFBasicHashStrongValues
)) { __CFAssignWithWriteBarrier((void **)values
, (void *)bkt
.weak_value
); values
++; }
498 if (valuebuf
&& !(flags
& kCFBasicHashStrongValues
)) { *values
++ = (const_any_pointer_t
)bkt
.weak_value
; }
500 return (Boolean
)true;
503 CFBasicHashGetElements((CFBasicHashRef
)hc
, CFDictionaryGetCount(hc
), (uintptr_t *)valuebuf
, NULL
, (uintptr_t *)keybuf
, NULL
);
507 void CFDictionaryApplyFunction(CFHashRef hc
, CFDictionaryApplierFunction applier
, any_pointer_t context
) {
508 FAULT_CALLBACK((void **)&(applier
));
509 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, void, hc
, "_apply:context:", applier
, context
);
510 if (CFSet
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, void, hc
, "_applyValues:context:", applier
, context
);
511 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
512 CFBasicHashApply((CFBasicHashRef
)hc
, ^(CFBasicHashBucket bkt
) {
514 INVOKE_CALLBACK3(applier
, (const_any_pointer_t
)bkt
.weak_key
, (const_any_pointer_t
)bkt
.weak_value
, context
);
517 INVOKE_CALLBACK2(applier
, (const_any_pointer_t
)bkt
.weak_value
, context
);
520 for (CFIndex cnt
= bkt
.count
; cnt
--;) {
521 INVOKE_CALLBACK2(applier
, (const_any_pointer_t
)bkt
.weak_value
, context
);
524 return (Boolean
)true;
528 // This function is for Foundation's benefit; no one else should use it.
529 CF_EXPORT
unsigned long _CFDictionaryFastEnumeration(CFHashRef hc
, struct __objcFastEnumerationStateEquivalent
*state
, void *stackbuffer
, unsigned long count
) {
530 if (CF_IS_OBJC(__kCFDictionaryTypeID
, hc
)) return 0;
531 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
532 return __CFBasicHashFastEnumeration((CFBasicHashRef
)hc
, (struct __objcFastEnumerationStateEquivalent2
*)state
, stackbuffer
, count
);
535 // This function is for Foundation's benefit; no one else should use it.
536 CF_EXPORT Boolean
_CFDictionaryIsMutable(CFHashRef hc
) {
537 if (CF_IS_OBJC(__kCFDictionaryTypeID
, hc
)) return false;
538 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
539 return CFBasicHashIsMutable((CFBasicHashRef
)hc
);
542 // This function is for Foundation's benefit; no one else should use it.
543 CF_EXPORT
void _CFDictionarySetCapacity(CFMutableHashRef hc
, CFIndex cap
) {
544 if (CF_IS_OBJC(__kCFDictionaryTypeID
, hc
)) return;
545 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
546 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
547 CFAssert3(CFDictionaryGetCount(hc
) <= cap
, __kCFLogAssertion
, "%s(): desired capacity (%ld) is less than count (%ld)", __PRETTY_FUNCTION__
, cap
, CFDictionaryGetCount(hc
));
548 CFBasicHashSetCapacity((CFBasicHashRef
)hc
, cap
);
551 CF_INLINE CFIndex
__CFDictionaryGetKVOBit(CFHashRef hc
) {
552 return __CFBitfieldGetValue(((CFRuntimeBase
*)hc
)->_cfinfo
[CF_INFO_BITS
], 0, 0);
555 CF_INLINE
void __CFDictionarySetKVOBit(CFHashRef hc
, CFIndex bit
) {
556 __CFBitfieldSetValue(((CFRuntimeBase
*)hc
)->_cfinfo
[CF_INFO_BITS
], 0, 0, ((uintptr_t)bit
& 0x1));
559 // This function is for Foundation's benefit; no one else should use it.
560 CF_EXPORT CFIndex
_CFDictionaryGetKVOBit(CFHashRef hc
) {
561 return __CFDictionaryGetKVOBit(hc
);
564 // This function is for Foundation's benefit; no one else should use it.
565 CF_EXPORT
void _CFDictionarySetKVOBit(CFHashRef hc
, CFIndex bit
) {
566 __CFDictionarySetKVOBit(hc
, bit
);
570 #if !defined(CF_OBJC_KVO_WILLCHANGE)
571 #define CF_OBJC_KVO_WILLCHANGE(obj, key)
572 #define CF_OBJC_KVO_DIDCHANGE(obj, key)
573 #define CF_OBJC_KVO_WILLCHANGEALL(obj)
574 #define CF_OBJC_KVO_DIDCHANGEALL(obj)
578 void CFDictionaryAddValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
581 void CFDictionaryAddValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
582 const_any_pointer_t value
= key
;
584 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, void, hc
, "addObject:forKey:", value
, key
);
585 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, void, hc
, "addObject:", key
);
586 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
587 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
588 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
589 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
591 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
592 CFBasicHashAddValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
593 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
597 void CFDictionaryReplaceValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
600 void CFDictionaryReplaceValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
601 const_any_pointer_t value
= key
;
603 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, void, hc
, "replaceObject:forKey:", value
, key
);
604 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, void, hc
, "replaceObject:", key
);
605 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
606 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
607 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
608 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
610 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
611 CFBasicHashReplaceValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
612 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
616 void CFDictionarySetValue(CFMutableHashRef hc
, const_any_pointer_t key
, const_any_pointer_t value
) {
619 void CFDictionarySetValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
620 const_any_pointer_t value
= key
;
622 if (CFDictionary
) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID
, void, hc
, "setObject:forKey:", value
, key
);
623 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, void, hc
, "_setObject:", key
);
624 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
625 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
626 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
627 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
629 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
630 //#warning this for a dictionary used to not replace the key
631 CFBasicHashSetValue((CFBasicHashRef
)hc
, (uintptr_t)key
, (uintptr_t)value
);
632 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
635 void CFDictionaryRemoveValue(CFMutableHashRef hc
, const_any_pointer_t key
) {
636 if (CFDictionary
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, void, hc
, "removeObjectForKey:", key
);
637 if (CFSet
) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID
, void, hc
, "removeObject:", key
);
638 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
639 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
640 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
642 CF_OBJC_KVO_WILLCHANGE(hc
, key
);
643 CFBasicHashRemoveValue((CFBasicHashRef
)hc
, (uintptr_t)key
);
644 CF_OBJC_KVO_DIDCHANGE(hc
, key
);
647 void CFDictionaryRemoveAllValues(CFMutableHashRef hc
) {
648 if (CFDictionary
) CF_OBJC_FUNCDISPATCH0(__kCFDictionaryTypeID
, void, hc
, "removeAllObjects");
649 if (CFSet
) CF_OBJC_FUNCDISPATCH0(__kCFDictionaryTypeID
, void, hc
, "removeAllObjects");
650 __CFGenericValidateType(hc
, __kCFDictionaryTypeID
);
651 CFAssert2(CFBasicHashIsMutable((CFBasicHashRef
)hc
), __kCFLogAssertion
, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__
, hc
);
652 if (!CFBasicHashIsMutable((CFBasicHashRef
)hc
)) {
653 CFLog(3, CFSTR("%s(): immutable collection %p given to mutating function"), __PRETTY_FUNCTION__
, hc
);
655 CF_OBJC_KVO_WILLCHANGEALL(hc
);
656 CFBasicHashRemoveAllValues((CFBasicHashRef
)hc
);
657 CF_OBJC_KVO_DIDCHANGEALL(hc
);
660 #undef CF_OBJC_KVO_WILLCHANGE
661 #undef CF_OBJC_KVO_DIDCHANGE
662 #undef CF_OBJC_KVO_WILLCHANGEALL
663 #undef CF_OBJC_KVO_DIDCHANGEALL