]>
Commit | Line | Data |
---|---|---|
bd5b749c | 1 | /* |
e29e285d | 2 | * Copyright (c) 2015 Apple Inc. All rights reserved. |
bd5b749c A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
d7384798 | 5 | * |
bd5b749c A |
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 | |
11 | * file. | |
d7384798 | 12 | * |
bd5b749c A |
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. | |
d7384798 | 20 | * |
bd5b749c A |
21 | * @APPLE_LICENSE_HEADER_END@ |
22 | */ | |
f64f9b69 | 23 | |
bd5b749c | 24 | /* CFBag.c |
d7384798 | 25 | Copyright (c) 1998-2014, Apple Inc. All rights reserved. |
bd5b749c | 26 | Responsibility: Christopher Kane |
cf7d2af9 | 27 | Machine generated from Notes/HashingCode.template |
bd5b749c A |
28 | */ |
29 | ||
30 | ||
31 | ||
32 | ||
cf7d2af9 | 33 | |
bd5b749c A |
34 | #include <CoreFoundation/CFBag.h> |
35 | #include "CFInternal.h" | |
cf7d2af9 A |
36 | #include "CFBasicHash.h" |
37 | #include <CoreFoundation/CFString.h> | |
bd5b749c | 38 | |
856091c5 | 39 | |
bd5b749c A |
40 | #define CFDictionary 0 |
41 | #define CFSet 0 | |
42 | #define CFBag 0 | |
43 | #undef CFBag | |
44 | #define CFBag 1 | |
45 | ||
46 | #if CFDictionary | |
47 | const CFBagKeyCallBacks kCFTypeBagKeyCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; | |
48 | const CFBagKeyCallBacks kCFCopyStringBagKeyCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; | |
49 | const CFBagValueCallBacks kCFTypeBagValueCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual}; | |
bd5b749c A |
50 | |
51 | #define CFHashRef CFDictionaryRef | |
52 | #define CFMutableHashRef CFMutableDictionaryRef | |
cf7d2af9 A |
53 | #define CFHashKeyCallBacks CFBagKeyCallBacks |
54 | #define CFHashValueCallBacks CFBagValueCallBacks | |
bd5b749c A |
55 | #endif |
56 | ||
57 | #if CFSet | |
58 | const CFBagCallBacks kCFTypeBagCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; | |
59 | const CFBagCallBacks kCFCopyStringBagCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; | |
bd5b749c A |
60 | |
61 | #define CFBagKeyCallBacks CFBagCallBacks | |
62 | #define CFBagValueCallBacks CFBagCallBacks | |
63 | #define kCFTypeBagKeyCallBacks kCFTypeBagCallBacks | |
64 | #define kCFTypeBagValueCallBacks kCFTypeBagCallBacks | |
bd5b749c A |
65 | |
66 | #define CFHashRef CFSetRef | |
67 | #define CFMutableHashRef CFMutableSetRef | |
cf7d2af9 A |
68 | #define CFHashKeyCallBacks CFBagCallBacks |
69 | #define CFHashValueCallBacks CFBagCallBacks | |
bd5b749c A |
70 | #endif |
71 | ||
72 | #if CFBag | |
73 | const CFBagCallBacks kCFTypeBagCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; | |
74 | const CFBagCallBacks kCFCopyStringBagCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash}; | |
bd5b749c A |
75 | |
76 | #define CFBagKeyCallBacks CFBagCallBacks | |
77 | #define CFBagValueCallBacks CFBagCallBacks | |
78 | #define kCFTypeBagKeyCallBacks kCFTypeBagCallBacks | |
79 | #define kCFTypeBagValueCallBacks kCFTypeBagCallBacks | |
bd5b749c A |
80 | |
81 | #define CFHashRef CFBagRef | |
82 | #define CFMutableHashRef CFMutableBagRef | |
cf7d2af9 A |
83 | #define CFHashKeyCallBacks CFBagCallBacks |
84 | #define CFHashValueCallBacks CFBagCallBacks | |
bd5b749c A |
85 | #endif |
86 | ||
bd5b749c A |
87 | |
88 | typedef uintptr_t any_t; | |
89 | typedef const void * const_any_pointer_t; | |
90 | typedef void * any_pointer_t; | |
91 | ||
bd5b749c | 92 | static Boolean __CFBagEqual(CFTypeRef cf1, CFTypeRef cf2) { |
cf7d2af9 | 93 | return __CFBasicHashEqual((CFBasicHashRef)cf1, (CFBasicHashRef)cf2); |
bd5b749c A |
94 | } |
95 | ||
96 | static CFHashCode __CFBagHash(CFTypeRef cf) { | |
cf7d2af9 | 97 | return __CFBasicHashHash((CFBasicHashRef)cf); |
bd5b749c A |
98 | } |
99 | ||
100 | static CFStringRef __CFBagCopyDescription(CFTypeRef cf) { | |
cf7d2af9 | 101 | return __CFBasicHashCopyDescription((CFBasicHashRef)cf); |
bd5b749c A |
102 | } |
103 | ||
104 | static void __CFBagDeallocate(CFTypeRef cf) { | |
cf7d2af9 | 105 | __CFBasicHashDeallocate((CFBasicHashRef)cf); |
bd5b749c A |
106 | } |
107 | ||
108 | static CFTypeID __kCFBagTypeID = _kCFRuntimeNotATypeID; | |
109 | ||
110 | static const CFRuntimeClass __CFBagClass = { | |
111 | _kCFRuntimeScannedObject, | |
112 | "CFBag", | |
113 | NULL, // init | |
114 | NULL, // copy | |
115 | __CFBagDeallocate, | |
116 | __CFBagEqual, | |
117 | __CFBagHash, | |
118 | NULL, // | |
119 | __CFBagCopyDescription | |
120 | }; | |
121 | ||
bd5b749c | 122 | CFTypeID CFBagGetTypeID(void) { |
d7384798 A |
123 | static dispatch_once_t initOnce; |
124 | dispatch_once(&initOnce, ^{ __kCFBagTypeID = _CFRuntimeRegisterClass(&__CFBagClass); }); | |
cf7d2af9 | 125 | return __kCFBagTypeID; |
bd5b749c A |
126 | } |
127 | ||
8ca704e1 A |
128 | |
129 | static CFBasicHashRef __CFBagCreateGeneric(CFAllocatorRef allocator, const CFHashKeyCallBacks *keyCallBacks, const CFHashValueCallBacks *valueCallBacks, Boolean useValueCB) { | |
cf7d2af9 A |
130 | CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing |
131 | flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0); | |
132 | ||
a48904a4 A |
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; | |
140 | ||
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; | |
147 | ||
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); | |
152 | ||
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; | |
158 | ||
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); | |
163 | ||
164 | if (keyRetainStd && keyReleaseStd && keyEquateStd && keyHashStd && keyDescribeStd && valueRetainStd && valueReleaseStd && valueEquateStd && valueDescribeStd) { | |
165 | set_cb = true; | |
166 | if (!(keyRetainNull || keyReleaseNull || keyEquateNull || keyHashNull || keyDescribeNull || valueRetainNull || valueReleaseNull || valueEquateNull || valueDescribeNull)) { | |
167 | std_cb = true; | |
168 | } else { | |
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; | |
172 | if (useValueCB) { | |
173 | value_retain = valueCallBacks ? valueCallBacks->retain : NULL; | |
174 | value_release = valueCallBacks ? valueCallBacks->release : NULL; | |
175 | } else { | |
176 | value_retain = key_retain; | |
177 | value_release = key_release; | |
178 | } | |
179 | } | |
180 | } | |
181 | } | |
182 | ||
183 | if (!set_cb) { | |
184 | key_retain = keyCallBacks ? keyCallBacks->retain : NULL; | |
185 | key_release = keyCallBacks ? keyCallBacks->release : NULL; | |
186 | if (useValueCB) { | |
187 | value_retain = valueCallBacks ? valueCallBacks->retain : NULL; | |
188 | value_release = valueCallBacks ? valueCallBacks->release : NULL; | |
8ca704e1 | 189 | } else { |
a48904a4 A |
190 | value_retain = key_retain; |
191 | value_release = key_release; | |
8ca704e1 | 192 | } |
cf7d2af9 | 193 | } |
cf7d2af9 | 194 | |
cf7d2af9 A |
195 | if (std_cb || value_retain != NULL || value_release != NULL) { |
196 | flags |= kCFBasicHashStrongValues; | |
bd5b749c | 197 | } |
cf7d2af9 A |
198 | if (std_cb || key_retain != NULL || key_release != NULL) { |
199 | flags |= kCFBasicHashStrongKeys; | |
bd5b749c | 200 | } |
bd5b749c | 201 | } |
cf7d2af9 | 202 | |
a48904a4 A |
203 | |
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); | |
215 | ||
216 | CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks); | |
8ca704e1 A |
217 | return ht; |
218 | } | |
219 | ||
220 | #if CFDictionary | |
a48904a4 | 221 | CF_PRIVATE CFHashRef __CFBagCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues) { |
8ca704e1 A |
222 | #endif |
223 | #if CFSet || CFBag | |
a48904a4 | 224 | CF_PRIVATE CFHashRef __CFBagCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues) { |
8ca704e1 A |
225 | const_any_pointer_t *vlist = klist; |
226 | #endif | |
227 | CFTypeID typeID = CFBagGetTypeID(); | |
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); | |
a48904a4 A |
231 | |
232 | CFBasicHashCallbacks callbacks; | |
233 | callbacks.retainKey = (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeBagKeyCallBacks.retain; | |
234 | callbacks.releaseKey = (void (*)(CFAllocatorRef, uintptr_t))kCFTypeBagKeyCallBacks.release; | |
235 | callbacks.equateKeys = (Boolean (*)(uintptr_t, uintptr_t))kCFTypeBagKeyCallBacks.equal; | |
236 | callbacks.hashKey = (CFHashCode (*)(uintptr_t))kCFTypeBagKeyCallBacks.hash; | |
237 | callbacks.getIndirectKey = NULL; | |
238 | callbacks.copyKeyDescription = (CFStringRef (*)(uintptr_t))kCFTypeBagKeyCallBacks.copyDescription; | |
239 | callbacks.retainValue = CFDictionary ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeBagValueCallBacks.retain : callbacks.retainKey; | |
240 | callbacks.releaseValue = CFDictionary ? (void (*)(CFAllocatorRef, uintptr_t))kCFTypeBagValueCallBacks.release : callbacks.releaseKey; | |
241 | callbacks.equateValues = CFDictionary ? (Boolean (*)(uintptr_t, uintptr_t))kCFTypeBagValueCallBacks.equal : callbacks.equateKeys; | |
242 | callbacks.copyValueDescription = CFDictionary ? (CFStringRef (*)(uintptr_t))kCFTypeBagValueCallBacks.copyDescription : callbacks.copyKeyDescription; | |
243 | ||
244 | CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks); | |
245 | CFBasicHashSuppressRC(ht); | |
8ca704e1 A |
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]); | |
249 | } | |
a48904a4 | 250 | CFBasicHashUnsuppressRC(ht); |
8ca704e1 | 251 | CFBasicHashMakeImmutable(ht); |
a48904a4 | 252 | _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); |
8ca704e1 A |
253 | if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (immutable)"); |
254 | return (CFHashRef)ht; | |
bd5b749c A |
255 | } |
256 | ||
257 | #if CFDictionary | |
cf7d2af9 | 258 | CFHashRef CFBagCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues, const CFBagKeyCallBacks *keyCallBacks, const CFBagValueCallBacks *valueCallBacks) { |
bd5b749c A |
259 | #endif |
260 | #if CFSet || CFBag | |
cf7d2af9 A |
261 | CFHashRef CFBagCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues, const CFBagKeyCallBacks *keyCallBacks) { |
262 | const_any_pointer_t *vlist = klist; | |
263 | const CFBagValueCallBacks *valueCallBacks = 0; | |
bd5b749c | 264 | #endif |
cf7d2af9 | 265 | CFTypeID typeID = CFBagGetTypeID(); |
bd5b749c | 266 | CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues); |
cf7d2af9 | 267 | CFBasicHashRef ht = __CFBagCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary); |
856091c5 | 268 | if (!ht) return NULL; |
cf7d2af9 | 269 | if (0 < numValues) CFBasicHashSetCapacity(ht, numValues); |
bd5b749c | 270 | for (CFIndex idx = 0; idx < numValues; idx++) { |
cf7d2af9 | 271 | CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]); |
bd5b749c | 272 | } |
cf7d2af9 | 273 | CFBasicHashMakeImmutable(ht); |
a48904a4 | 274 | _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); |
cf7d2af9 A |
275 | if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (immutable)"); |
276 | return (CFHashRef)ht; | |
bd5b749c A |
277 | } |
278 | ||
279 | #if CFDictionary | |
280 | CFMutableHashRef CFBagCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFBagKeyCallBacks *keyCallBacks, const CFBagValueCallBacks *valueCallBacks) { | |
281 | #endif | |
282 | #if CFSet || CFBag | |
283 | CFMutableHashRef CFBagCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFBagKeyCallBacks *keyCallBacks) { | |
cf7d2af9 | 284 | const CFBagValueCallBacks *valueCallBacks = 0; |
bd5b749c | 285 | #endif |
cf7d2af9 | 286 | CFTypeID typeID = CFBagGetTypeID(); |
bd5b749c | 287 | CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__, capacity); |
cf7d2af9 | 288 | CFBasicHashRef ht = __CFBagCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary); |
856091c5 | 289 | if (!ht) return NULL; |
a48904a4 | 290 | _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); |
cf7d2af9 A |
291 | if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (mutable)"); |
292 | return (CFMutableHashRef)ht; | |
bd5b749c A |
293 | } |
294 | ||
cf7d2af9 A |
295 | CFHashRef CFBagCreateCopy(CFAllocatorRef allocator, CFHashRef other) { |
296 | CFTypeID typeID = CFBagGetTypeID(); | |
297 | CFAssert1(other, __kCFLogAssertion, "%s(): other CFBag cannot be NULL", __PRETTY_FUNCTION__); | |
298 | __CFGenericValidateType(other, typeID); | |
299 | CFBasicHashRef ht = NULL; | |
300 | if (CF_IS_OBJC(typeID, other)) { | |
301 | CFIndex numValues = CFBagGetCount(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); | |
bd5b749c | 304 | #if CFSet || CFBag |
cf7d2af9 A |
305 | const_any_pointer_t *klist = vlist; |
306 | CFBagGetValues(other, vlist); | |
bd5b749c A |
307 | #endif |
308 | #if CFDictionary | |
cf7d2af9 A |
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); | |
bd5b749c | 311 | #endif |
cf7d2af9 | 312 | ht = __CFBagCreateGeneric(allocator, & kCFTypeBagKeyCallBacks, CFDictionary ? & kCFTypeBagValueCallBacks : NULL, CFDictionary); |
856091c5 A |
313 | if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues); |
314 | for (CFIndex idx = 0; ht && idx < numValues; idx++) { | |
cf7d2af9 | 315 | CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]); |
bd5b749c | 316 | } |
cf7d2af9 A |
317 | if (klist != kbuffer && klist != vlist) CFAllocatorDeallocate(kCFAllocatorSystemDefault, klist); |
318 | if (vlist != vbuffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, vlist); | |
319 | } else { | |
320 | ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other); | |
bd5b749c | 321 | } |
856091c5 | 322 | if (!ht) return NULL; |
cf7d2af9 | 323 | CFBasicHashMakeImmutable(ht); |
a48904a4 | 324 | _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); |
cf7d2af9 A |
325 | if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (immutable)"); |
326 | return (CFHashRef)ht; | |
bd5b749c A |
327 | } |
328 | ||
329 | CFMutableHashRef CFBagCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFHashRef other) { | |
cf7d2af9 A |
330 | CFTypeID typeID = CFBagGetTypeID(); |
331 | CFAssert1(other, __kCFLogAssertion, "%s(): other CFBag 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 = CFBagGetCount(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); | |
bd5b749c | 339 | #if CFSet || CFBag |
cf7d2af9 A |
340 | const_any_pointer_t *klist = vlist; |
341 | CFBagGetValues(other, vlist); | |
bd5b749c A |
342 | #endif |
343 | #if CFDictionary | |
cf7d2af9 A |
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); | |
bd5b749c | 346 | #endif |
cf7d2af9 | 347 | ht = __CFBagCreateGeneric(allocator, & kCFTypeBagKeyCallBacks, CFDictionary ? & kCFTypeBagValueCallBacks : NULL, CFDictionary); |
856091c5 A |
348 | if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues); |
349 | for (CFIndex idx = 0; ht && idx < numValues; idx++) { | |
cf7d2af9 A |
350 | CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]); |
351 | } | |
352 | if (klist != kbuffer && klist != vlist) CFAllocatorDeallocate(kCFAllocatorSystemDefault, klist); | |
353 | if (vlist != vbuffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, vlist); | |
bd5b749c | 354 | } else { |
cf7d2af9 | 355 | ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other); |
bd5b749c | 356 | } |
856091c5 | 357 | if (!ht) return NULL; |
a48904a4 | 358 | _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID); |
cf7d2af9 A |
359 | if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (mutable)"); |
360 | return (CFMutableHashRef)ht; | |
bd5b749c A |
361 | } |
362 | ||
363 | CFIndex CFBagGetCount(CFHashRef hc) { | |
d7384798 A |
364 | #if CFDictionary |
365 | if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (NSDictionary *)hc, count); | |
366 | #endif | |
367 | #if CFSet | |
368 | if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (NSSet *)hc, count); | |
369 | #endif | |
370 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 | 371 | return CFBasicHashGetCount((CFBasicHashRef)hc); |
bd5b749c A |
372 | } |
373 | ||
374 | #if CFDictionary | |
375 | CFIndex CFBagGetCountOfKey(CFHashRef hc, const_any_pointer_t key) { | |
376 | #endif | |
377 | #if CFSet || CFBag | |
378 | CFIndex CFBagGetCountOfValue(CFHashRef hc, const_any_pointer_t key) { | |
379 | #endif | |
d7384798 A |
380 | #if CFDictionary |
381 | if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (NSDictionary *)hc, countForKey:(id)key); | |
382 | #endif | |
383 | #if CFSet | |
384 | if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (NSSet *)hc, countForObject:(id)key); | |
385 | #endif | |
386 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 | 387 | return CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key); |
bd5b749c A |
388 | } |
389 | ||
390 | #if CFDictionary | |
391 | Boolean CFBagContainsKey(CFHashRef hc, const_any_pointer_t key) { | |
392 | #endif | |
393 | #if CFSet || CFBag | |
394 | Boolean CFBagContainsValue(CFHashRef hc, const_any_pointer_t key) { | |
395 | #endif | |
d7384798 A |
396 | #if CFDictionary |
397 | if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), char, (NSDictionary *)hc, containsKey:(id)key); | |
398 | #endif | |
399 | #if CFSet | |
400 | if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), char, (NSSet *)hc, containsObject:(id)key); | |
401 | #endif | |
402 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 | 403 | return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key)); |
bd5b749c A |
404 | } |
405 | ||
cf7d2af9 | 406 | const_any_pointer_t CFBagGetValue(CFHashRef hc, const_any_pointer_t key) { |
d7384798 A |
407 | #if CFDictionary |
408 | if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), const_any_pointer_t, (NSDictionary *)hc, objectForKey:(id)key); | |
409 | #endif | |
410 | #if CFSet | |
411 | if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), const_any_pointer_t, (NSSet *)hc, member:(id)key); | |
412 | #endif | |
413 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 A |
414 | CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key); |
415 | return (0 < bkt.count ? (const_any_pointer_t)bkt.weak_value : 0); | |
bd5b749c A |
416 | } |
417 | ||
cf7d2af9 | 418 | Boolean CFBagGetValueIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *value) { |
d7384798 A |
419 | #if CFDictionary |
420 | if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), Boolean, (NSDictionary *)hc, __getValue:(id *)value forKey:(id)key); | |
421 | #endif | |
422 | #if CFSet | |
423 | if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), Boolean, (NSSet *)hc, __getValue:(id *)value forObj:(id)key); | |
424 | #endif | |
425 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 A |
426 | CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key); |
427 | if (0 < bkt.count) { | |
428 | if (value) { | |
429 | if (kCFUseCollectableAllocator && (CFBasicHashGetFlags((CFBasicHashRef)hc) & kCFBasicHashStrongValues)) { | |
430 | __CFAssignWithWriteBarrier((void **)value, (void *)bkt.weak_value); | |
431 | } else { | |
432 | *value = (const_any_pointer_t)bkt.weak_value; | |
bd5b749c A |
433 | } |
434 | } | |
cf7d2af9 | 435 | return true; |
bd5b749c A |
436 | } |
437 | return false; | |
438 | } | |
bd5b749c | 439 | |
cf7d2af9 A |
440 | #if CFDictionary |
441 | CFIndex CFDictionaryGetCountOfValue(CFHashRef hc, const_any_pointer_t value) { | |
d7384798 A |
442 | CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), CFIndex, (NSDictionary *)hc, countForObject:(id)value); |
443 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 | 444 | return CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value); |
bd5b749c A |
445 | } |
446 | ||
cf7d2af9 | 447 | Boolean CFDictionaryContainsValue(CFHashRef hc, const_any_pointer_t value) { |
d7384798 A |
448 | CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), char, (NSDictionary *)hc, containsObject:(id)value); |
449 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 | 450 | return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value)); |
bd5b749c A |
451 | } |
452 | ||
cf7d2af9 | 453 | CF_EXPORT Boolean CFDictionaryGetKeyIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *actualkey) { |
d7384798 | 454 | __CFGenericValidateType(hc, CFBagGetTypeID()); |
cf7d2af9 A |
455 | CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key); |
456 | if (0 < bkt.count) { | |
457 | if (actualkey) { | |
458 | if (kCFUseCollectableAllocator && (CFBasicHashGetFlags((CFBasicHashRef)hc) & kCFBasicHashStrongKeys)) { | |
459 | __CFAssignWithWriteBarrier((void **)actualkey, (void *)bkt.weak_key); | |
460 | } else { | |
461 | *actualkey = (const_any_pointer_t)bkt.weak_key; | |
462 | } | |
463 | } | |
464 | return true; | |
465 | } | |
466 | return false; | |
bd5b749c A |
467 | } |
468 | #endif | |
469 | ||
470 | #if CFDictionary | |
471 | void CFBagGetKeysAndValues(CFHashRef hc, const_any_pointer_t *keybuf, const_any_pointer_t *valuebuf) { | |
472 | #endif | |
473 | #if CFSet || CFBag | |
474 | void CFBagGetValues(CFHashRef hc, const_any_pointer_t *keybuf) { | |
475 | const_any_pointer_t *valuebuf = 0; | |
476 | #endif | |
d7384798 A |
477 | #if CFDictionary |
478 | if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSDictionary *)hc, getObjects:(id *)valuebuf andKeys:(id *)keybuf); | |
479 | #endif | |
480 | #if CFSet | |
481 | if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSSet *)hc, getObjects:(id *)keybuf); | |
482 | #endif | |
483 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 A |
484 | if (kCFUseCollectableAllocator) { |
485 | CFOptionFlags flags = CFBasicHashGetFlags((CFBasicHashRef)hc); | |
8ca704e1 A |
486 | __block const_any_pointer_t *keys = keybuf; |
487 | __block const_any_pointer_t *values = valuebuf; | |
cf7d2af9 A |
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; } | |
494 | } | |
495 | return (Boolean)true; | |
496 | }); | |
497 | } else { | |
8ca704e1 | 498 | CFBasicHashGetElements((CFBasicHashRef)hc, CFBagGetCount(hc), (uintptr_t *)valuebuf, (uintptr_t *)keybuf); |
bd5b749c | 499 | } |
bd5b749c | 500 | } |
bd5b749c A |
501 | |
502 | void CFBagApplyFunction(CFHashRef hc, CFBagApplierFunction applier, any_pointer_t context) { | |
503 | FAULT_CALLBACK((void **)&(applier)); | |
d7384798 A |
504 | #if CFDictionary |
505 | if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSDictionary *)hc, __apply:(void (*)(const void *, const void *, void *))applier context:(void *)context); | |
506 | #endif | |
507 | #if CFSet | |
508 | if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSSet *)hc, __applyValues:(void (*)(const void *, void *))applier context:(void *)context); | |
509 | #endif | |
510 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 | 511 | CFBasicHashApply((CFBasicHashRef)hc, ^(CFBasicHashBucket bkt) { |
bd5b749c | 512 | #if CFDictionary |
cf7d2af9 | 513 | INVOKE_CALLBACK3(applier, (const_any_pointer_t)bkt.weak_key, (const_any_pointer_t)bkt.weak_value, context); |
bd5b749c | 514 | #endif |
cf7d2af9 A |
515 | #if CFSet |
516 | INVOKE_CALLBACK2(applier, (const_any_pointer_t)bkt.weak_value, context); | |
bd5b749c | 517 | #endif |
cf7d2af9 A |
518 | #if CFBag |
519 | for (CFIndex cnt = bkt.count; cnt--;) { | |
520 | INVOKE_CALLBACK2(applier, (const_any_pointer_t)bkt.weak_value, context); | |
bd5b749c | 521 | } |
cf7d2af9 A |
522 | #endif |
523 | return (Boolean)true; | |
524 | }); | |
bd5b749c A |
525 | } |
526 | ||
cf7d2af9 A |
527 | // This function is for Foundation's benefit; no one else should use it. |
528 | CF_EXPORT unsigned long _CFBagFastEnumeration(CFHashRef hc, struct __objcFastEnumerationStateEquivalent *state, void *stackbuffer, unsigned long count) { | |
d7384798 A |
529 | if (CF_IS_OBJC(CFBagGetTypeID(), hc)) return 0; |
530 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 | 531 | return __CFBasicHashFastEnumeration((CFBasicHashRef)hc, (struct __objcFastEnumerationStateEquivalent2 *)state, stackbuffer, count); |
bd5b749c A |
532 | } |
533 | ||
534 | // This function is for Foundation's benefit; no one else should use it. | |
cf7d2af9 | 535 | CF_EXPORT Boolean _CFBagIsMutable(CFHashRef hc) { |
d7384798 A |
536 | if (CF_IS_OBJC(CFBagGetTypeID(), hc)) return false; |
537 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 | 538 | return CFBasicHashIsMutable((CFBasicHashRef)hc); |
bd5b749c A |
539 | } |
540 | ||
cf7d2af9 A |
541 | // This function is for Foundation's benefit; no one else should use it. |
542 | CF_EXPORT void _CFBagSetCapacity(CFMutableHashRef hc, CFIndex cap) { | |
d7384798 A |
543 | if (CF_IS_OBJC(CFBagGetTypeID(), hc)) return; |
544 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 A |
545 | CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc); |
546 | CFAssert3(CFBagGetCount(hc) <= cap, __kCFLogAssertion, "%s(): desired capacity (%ld) is less than count (%ld)", __PRETTY_FUNCTION__, cap, CFBagGetCount(hc)); | |
547 | CFBasicHashSetCapacity((CFBasicHashRef)hc, cap); | |
548 | } | |
549 | ||
550 | CF_INLINE CFIndex __CFBagGetKVOBit(CFHashRef hc) { | |
551 | return __CFBitfieldGetValue(((CFRuntimeBase *)hc)->_cfinfo[CF_INFO_BITS], 0, 0); | |
552 | } | |
553 | ||
554 | CF_INLINE void __CFBagSetKVOBit(CFHashRef hc, CFIndex bit) { | |
555 | __CFBitfieldSetValue(((CFRuntimeBase *)hc)->_cfinfo[CF_INFO_BITS], 0, 0, ((uintptr_t)bit & 0x1)); | |
556 | } | |
557 | ||
558 | // This function is for Foundation's benefit; no one else should use it. | |
559 | CF_EXPORT CFIndex _CFBagGetKVOBit(CFHashRef hc) { | |
560 | return __CFBagGetKVOBit(hc); | |
561 | } | |
562 | ||
563 | // This function is for Foundation's benefit; no one else should use it. | |
564 | CF_EXPORT void _CFBagSetKVOBit(CFHashRef hc, CFIndex bit) { | |
565 | __CFBagSetKVOBit(hc, bit); | |
566 | } | |
567 | ||
568 | ||
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) | |
574 | #endif | |
bd5b749c A |
575 | |
576 | #if CFDictionary | |
577 | void CFBagAddValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) { | |
578 | #endif | |
579 | #if CFSet || CFBag | |
580 | void CFBagAddValue(CFMutableHashRef hc, const_any_pointer_t key) { | |
cf7d2af9 | 581 | const_any_pointer_t value = key; |
bd5b749c | 582 | #endif |
d7384798 A |
583 | #if CFDictionary |
584 | if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableDictionary *)hc, __addObject:(id)value forKey:(id)key); | |
585 | #endif | |
586 | #if CFSet | |
587 | if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableSet *)hc, addObject:(id)key); | |
588 | #endif | |
589 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 A |
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); | |
bd5b749c | 593 | } |
cf7d2af9 A |
594 | CF_OBJC_KVO_WILLCHANGE(hc, key); |
595 | CFBasicHashAddValue((CFBasicHashRef)hc, (uintptr_t)key, (uintptr_t)value); | |
596 | CF_OBJC_KVO_DIDCHANGE(hc, key); | |
bd5b749c A |
597 | } |
598 | ||
599 | #if CFDictionary | |
600 | void CFBagReplaceValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) { | |
601 | #endif | |
602 | #if CFSet || CFBag | |
603 | void CFBagReplaceValue(CFMutableHashRef hc, const_any_pointer_t key) { | |
cf7d2af9 | 604 | const_any_pointer_t value = key; |
bd5b749c | 605 | #endif |
d7384798 A |
606 | #if CFDictionary |
607 | if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableDictionary *)hc, replaceObject:(id)value forKey:(id)key); | |
608 | #endif | |
609 | #if CFSet | |
610 | if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableSet *)hc, replaceObject:(id)key); | |
611 | #endif | |
612 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 A |
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); | |
bd5b749c | 616 | } |
cf7d2af9 A |
617 | CF_OBJC_KVO_WILLCHANGE(hc, key); |
618 | CFBasicHashReplaceValue((CFBasicHashRef)hc, (uintptr_t)key, (uintptr_t)value); | |
619 | CF_OBJC_KVO_DIDCHANGE(hc, key); | |
bd5b749c A |
620 | } |
621 | ||
622 | #if CFDictionary | |
623 | void CFBagSetValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_pointer_t value) { | |
624 | #endif | |
625 | #if CFSet || CFBag | |
626 | void CFBagSetValue(CFMutableHashRef hc, const_any_pointer_t key) { | |
cf7d2af9 | 627 | const_any_pointer_t value = key; |
bd5b749c | 628 | #endif |
d7384798 A |
629 | #if CFDictionary |
630 | if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableDictionary *)hc, __setObject:(id)value forKey:(id)key); | |
631 | #endif | |
632 | #if CFSet | |
633 | if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableSet *)hc, setObject:(id)key); | |
634 | #endif | |
635 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 A |
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); | |
bd5b749c | 639 | } |
cf7d2af9 A |
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); | |
bd5b749c A |
644 | } |
645 | ||
646 | void CFBagRemoveValue(CFMutableHashRef hc, const_any_pointer_t key) { | |
d7384798 A |
647 | #if CFDictionary |
648 | if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableDictionary *)hc, removeObjectForKey:(id)key); | |
649 | #endif | |
650 | #if CFSet | |
651 | if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableSet *)hc, removeObject:(id)key); | |
652 | #endif | |
653 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 A |
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); | |
bd5b749c | 657 | } |
cf7d2af9 A |
658 | CF_OBJC_KVO_WILLCHANGE(hc, key); |
659 | CFBasicHashRemoveValue((CFBasicHashRef)hc, (uintptr_t)key); | |
660 | CF_OBJC_KVO_DIDCHANGE(hc, key); | |
bd5b749c A |
661 | } |
662 | ||
663 | void CFBagRemoveAllValues(CFMutableHashRef hc) { | |
d7384798 A |
664 | #if CFDictionary |
665 | if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableDictionary *)hc, removeAllObjects); | |
666 | #endif | |
667 | #if CFSet | |
668 | if (CFSet) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSMutableSet *)hc, removeAllObjects); | |
669 | #endif | |
670 | __CFGenericValidateType(hc, CFBagGetTypeID()); | |
cf7d2af9 A |
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); | |
bd5b749c | 674 | } |
cf7d2af9 A |
675 | CF_OBJC_KVO_WILLCHANGEALL(hc); |
676 | CFBasicHashRemoveAllValues((CFBasicHashRef)hc); | |
677 | CF_OBJC_KVO_DIDCHANGEALL(hc); | |
bd5b749c A |
678 | } |
679 | ||
680 | #undef CF_OBJC_KVO_WILLCHANGE | |
681 | #undef CF_OBJC_KVO_DIDCHANGE | |
cf7d2af9 A |
682 | #undef CF_OBJC_KVO_WILLCHANGEALL |
683 | #undef CF_OBJC_KVO_DIDCHANGEALL | |
bd5b749c | 684 |