1*fdd8201dSApple OSS Distributions /*
2*fdd8201dSApple OSS Distributions * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3*fdd8201dSApple OSS Distributions *
4*fdd8201dSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*fdd8201dSApple OSS Distributions *
6*fdd8201dSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*fdd8201dSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*fdd8201dSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*fdd8201dSApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*fdd8201dSApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*fdd8201dSApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*fdd8201dSApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*fdd8201dSApple OSS Distributions * terms of an Apple operating system software license agreement.
14*fdd8201dSApple OSS Distributions *
15*fdd8201dSApple OSS Distributions * Please obtain a copy of the License at
16*fdd8201dSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*fdd8201dSApple OSS Distributions *
18*fdd8201dSApple OSS Distributions * The Original Code and all software distributed under the License are
19*fdd8201dSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*fdd8201dSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*fdd8201dSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*fdd8201dSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*fdd8201dSApple OSS Distributions * Please see the License for the specific language governing rights and
24*fdd8201dSApple OSS Distributions * limitations under the License.
25*fdd8201dSApple OSS Distributions *
26*fdd8201dSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*fdd8201dSApple OSS Distributions */
28*fdd8201dSApple OSS Distributions /* OSDictionary.m created by rsulack on Fri 12-Sep-1997 */
29*fdd8201dSApple OSS Distributions /* OSDictionary.cpp converted to C++ by gvdl on Fri 1998-10-30 */
30*fdd8201dSApple OSS Distributions /* OSDictionary.cpp rewritten by gvdl on Fri 1998-10-30 */
31*fdd8201dSApple OSS Distributions
32*fdd8201dSApple OSS Distributions #define IOKIT_ENABLE_SHARED_PTR
33*fdd8201dSApple OSS Distributions
34*fdd8201dSApple OSS Distributions #include <libkern/c++/OSArray.h>
35*fdd8201dSApple OSS Distributions #include <libkern/c++/OSCollectionIterator.h>
36*fdd8201dSApple OSS Distributions #include <libkern/c++/OSDictionary.h>
37*fdd8201dSApple OSS Distributions #include <libkern/c++/OSLib.h>
38*fdd8201dSApple OSS Distributions #include <libkern/c++/OSSerialize.h>
39*fdd8201dSApple OSS Distributions #include <libkern/c++/OSSharedPtr.h>
40*fdd8201dSApple OSS Distributions #include <libkern/c++/OSSymbol.h>
41*fdd8201dSApple OSS Distributions #include <os/cpp_util.h>
42*fdd8201dSApple OSS Distributions
43*fdd8201dSApple OSS Distributions #define super OSCollection
44*fdd8201dSApple OSS Distributions
45*fdd8201dSApple OSS Distributions OSDefineMetaClassAndStructorsWithZone(OSDictionary, OSCollection,
46*fdd8201dSApple OSS Distributions (zone_create_flags_t) (ZC_CACHING | ZC_ZFREE_CLEARMEM))
47*fdd8201dSApple OSS Distributions OSMetaClassDefineReservedUnused(OSDictionary, 0);
48*fdd8201dSApple OSS Distributions OSMetaClassDefineReservedUnused(OSDictionary, 1);
49*fdd8201dSApple OSS Distributions OSMetaClassDefineReservedUnused(OSDictionary, 2);
50*fdd8201dSApple OSS Distributions OSMetaClassDefineReservedUnused(OSDictionary, 3);
51*fdd8201dSApple OSS Distributions OSMetaClassDefineReservedUnused(OSDictionary, 4);
52*fdd8201dSApple OSS Distributions OSMetaClassDefineReservedUnused(OSDictionary, 5);
53*fdd8201dSApple OSS Distributions OSMetaClassDefineReservedUnused(OSDictionary, 6);
54*fdd8201dSApple OSS Distributions OSMetaClassDefineReservedUnused(OSDictionary, 7);
55*fdd8201dSApple OSS Distributions
56*fdd8201dSApple OSS Distributions #define EXT_CAST(obj) \
57*fdd8201dSApple OSS Distributions reinterpret_cast<OSObject *>(const_cast<OSMetaClassBase *>(obj))
58*fdd8201dSApple OSS Distributions
59*fdd8201dSApple OSS Distributions extern "C" {
60*fdd8201dSApple OSS Distributions void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
61*fdd8201dSApple OSS Distributions }
62*fdd8201dSApple OSS Distributions
63*fdd8201dSApple OSS Distributions int
compare(const void * _e1,const void * _e2)64*fdd8201dSApple OSS Distributions OSDictionary::dictEntry::compare(const void *_e1, const void *_e2)
65*fdd8201dSApple OSS Distributions {
66*fdd8201dSApple OSS Distributions const OSDictionary::dictEntry *e1 = (const OSDictionary::dictEntry *)_e1;
67*fdd8201dSApple OSS Distributions const OSDictionary::dictEntry *e2 = (const OSDictionary::dictEntry *)_e2;
68*fdd8201dSApple OSS Distributions
69*fdd8201dSApple OSS Distributions if ((uintptr_t)e1->key.get() == (uintptr_t)e2->key.get()) {
70*fdd8201dSApple OSS Distributions return 0;
71*fdd8201dSApple OSS Distributions }
72*fdd8201dSApple OSS Distributions
73*fdd8201dSApple OSS Distributions return (uintptr_t)e1->key.get() > (uintptr_t)e2->key.get() ? 1 : -1;
74*fdd8201dSApple OSS Distributions }
75*fdd8201dSApple OSS Distributions
76*fdd8201dSApple OSS Distributions void
sortBySymbol(void)77*fdd8201dSApple OSS Distributions OSDictionary::sortBySymbol(void)
78*fdd8201dSApple OSS Distributions {
79*fdd8201dSApple OSS Distributions qsort(dictionary, count, sizeof(OSDictionary::dictEntry),
80*fdd8201dSApple OSS Distributions &OSDictionary::dictEntry::compare);
81*fdd8201dSApple OSS Distributions }
82*fdd8201dSApple OSS Distributions
83*fdd8201dSApple OSS Distributions bool
initWithCapacity(unsigned int inCapacity)84*fdd8201dSApple OSS Distributions OSDictionary::initWithCapacity(unsigned int inCapacity)
85*fdd8201dSApple OSS Distributions {
86*fdd8201dSApple OSS Distributions if (!super::init()) {
87*fdd8201dSApple OSS Distributions return false;
88*fdd8201dSApple OSS Distributions }
89*fdd8201dSApple OSS Distributions
90*fdd8201dSApple OSS Distributions if (inCapacity > (UINT_MAX / sizeof(dictEntry))) {
91*fdd8201dSApple OSS Distributions return false;
92*fdd8201dSApple OSS Distributions }
93*fdd8201dSApple OSS Distributions
94*fdd8201dSApple OSS Distributions //fOptions |= kSort;
95*fdd8201dSApple OSS Distributions
96*fdd8201dSApple OSS Distributions dictionary = kallocp_type_container(dictEntry, &inCapacity, Z_WAITOK_ZERO);
97*fdd8201dSApple OSS Distributions if (!dictionary) {
98*fdd8201dSApple OSS Distributions return false;
99*fdd8201dSApple OSS Distributions }
100*fdd8201dSApple OSS Distributions
101*fdd8201dSApple OSS Distributions os::uninitialized_value_construct(dictionary, dictionary + inCapacity);
102*fdd8201dSApple OSS Distributions OSCONTAINER_ACCUMSIZE(inCapacity * sizeof(dictEntry));
103*fdd8201dSApple OSS Distributions
104*fdd8201dSApple OSS Distributions count = 0;
105*fdd8201dSApple OSS Distributions capacity = inCapacity;
106*fdd8201dSApple OSS Distributions capacityIncrement = (inCapacity)? inCapacity : 16;
107*fdd8201dSApple OSS Distributions
108*fdd8201dSApple OSS Distributions return true;
109*fdd8201dSApple OSS Distributions }
110*fdd8201dSApple OSS Distributions
111*fdd8201dSApple OSS Distributions bool
initWithObjects(const OSObject * objects[],const OSSymbol * keys[],unsigned int theCount,unsigned int theCapacity)112*fdd8201dSApple OSS Distributions OSDictionary::initWithObjects(const OSObject *objects[],
113*fdd8201dSApple OSS Distributions const OSSymbol *keys[],
114*fdd8201dSApple OSS Distributions unsigned int theCount,
115*fdd8201dSApple OSS Distributions unsigned int theCapacity)
116*fdd8201dSApple OSS Distributions {
117*fdd8201dSApple OSS Distributions unsigned int newCapacity = theCount;
118*fdd8201dSApple OSS Distributions
119*fdd8201dSApple OSS Distributions if (!objects || !keys) {
120*fdd8201dSApple OSS Distributions return false;
121*fdd8201dSApple OSS Distributions }
122*fdd8201dSApple OSS Distributions
123*fdd8201dSApple OSS Distributions if (theCapacity) {
124*fdd8201dSApple OSS Distributions if (theCount > theCapacity) {
125*fdd8201dSApple OSS Distributions return false;
126*fdd8201dSApple OSS Distributions }
127*fdd8201dSApple OSS Distributions
128*fdd8201dSApple OSS Distributions newCapacity = theCapacity;
129*fdd8201dSApple OSS Distributions }
130*fdd8201dSApple OSS Distributions
131*fdd8201dSApple OSS Distributions if (!initWithCapacity(newCapacity)) {
132*fdd8201dSApple OSS Distributions return false;
133*fdd8201dSApple OSS Distributions }
134*fdd8201dSApple OSS Distributions
135*fdd8201dSApple OSS Distributions for (unsigned int i = 0; i < theCount; i++) {
136*fdd8201dSApple OSS Distributions const OSMetaClassBase *newObject = *objects++;
137*fdd8201dSApple OSS Distributions
138*fdd8201dSApple OSS Distributions if (!newObject || !keys[i] || !setObject(keys[i], newObject)) {
139*fdd8201dSApple OSS Distributions return false;
140*fdd8201dSApple OSS Distributions }
141*fdd8201dSApple OSS Distributions }
142*fdd8201dSApple OSS Distributions
143*fdd8201dSApple OSS Distributions return true;
144*fdd8201dSApple OSS Distributions }
145*fdd8201dSApple OSS Distributions
146*fdd8201dSApple OSS Distributions bool
initWithObjects(const OSObject * objects[],const OSString * keys[],unsigned int theCount,unsigned int theCapacity)147*fdd8201dSApple OSS Distributions OSDictionary::initWithObjects(const OSObject *objects[],
148*fdd8201dSApple OSS Distributions const OSString *keys[],
149*fdd8201dSApple OSS Distributions unsigned int theCount,
150*fdd8201dSApple OSS Distributions unsigned int theCapacity)
151*fdd8201dSApple OSS Distributions {
152*fdd8201dSApple OSS Distributions unsigned int newCapacity = theCount;
153*fdd8201dSApple OSS Distributions
154*fdd8201dSApple OSS Distributions if (!objects || !keys) {
155*fdd8201dSApple OSS Distributions return false;
156*fdd8201dSApple OSS Distributions }
157*fdd8201dSApple OSS Distributions
158*fdd8201dSApple OSS Distributions if (theCapacity) {
159*fdd8201dSApple OSS Distributions if (theCount > theCapacity) {
160*fdd8201dSApple OSS Distributions return false;
161*fdd8201dSApple OSS Distributions }
162*fdd8201dSApple OSS Distributions
163*fdd8201dSApple OSS Distributions newCapacity = theCapacity;
164*fdd8201dSApple OSS Distributions }
165*fdd8201dSApple OSS Distributions
166*fdd8201dSApple OSS Distributions if (!initWithCapacity(newCapacity)) {
167*fdd8201dSApple OSS Distributions return false;
168*fdd8201dSApple OSS Distributions }
169*fdd8201dSApple OSS Distributions
170*fdd8201dSApple OSS Distributions for (unsigned int i = 0; i < theCount; i++) {
171*fdd8201dSApple OSS Distributions OSSharedPtr<const OSSymbol> key = OSSymbol::withString(*keys++);
172*fdd8201dSApple OSS Distributions const OSMetaClassBase *newObject = *objects++;
173*fdd8201dSApple OSS Distributions
174*fdd8201dSApple OSS Distributions if (!key) {
175*fdd8201dSApple OSS Distributions return false;
176*fdd8201dSApple OSS Distributions }
177*fdd8201dSApple OSS Distributions
178*fdd8201dSApple OSS Distributions if (!newObject || !setObject(key.get(), newObject)) {
179*fdd8201dSApple OSS Distributions return false;
180*fdd8201dSApple OSS Distributions }
181*fdd8201dSApple OSS Distributions }
182*fdd8201dSApple OSS Distributions
183*fdd8201dSApple OSS Distributions return true;
184*fdd8201dSApple OSS Distributions }
185*fdd8201dSApple OSS Distributions
186*fdd8201dSApple OSS Distributions bool
initWithDictionary(const OSDictionary * dict,unsigned int theCapacity)187*fdd8201dSApple OSS Distributions OSDictionary::initWithDictionary(const OSDictionary *dict,
188*fdd8201dSApple OSS Distributions unsigned int theCapacity)
189*fdd8201dSApple OSS Distributions {
190*fdd8201dSApple OSS Distributions unsigned int newCapacity;
191*fdd8201dSApple OSS Distributions
192*fdd8201dSApple OSS Distributions if (!dict) {
193*fdd8201dSApple OSS Distributions return false;
194*fdd8201dSApple OSS Distributions }
195*fdd8201dSApple OSS Distributions
196*fdd8201dSApple OSS Distributions newCapacity = dict->count;
197*fdd8201dSApple OSS Distributions
198*fdd8201dSApple OSS Distributions if (theCapacity) {
199*fdd8201dSApple OSS Distributions if (dict->count > theCapacity) {
200*fdd8201dSApple OSS Distributions return false;
201*fdd8201dSApple OSS Distributions }
202*fdd8201dSApple OSS Distributions
203*fdd8201dSApple OSS Distributions newCapacity = theCapacity;
204*fdd8201dSApple OSS Distributions }
205*fdd8201dSApple OSS Distributions
206*fdd8201dSApple OSS Distributions if (!initWithCapacity(newCapacity)) {
207*fdd8201dSApple OSS Distributions return false;
208*fdd8201dSApple OSS Distributions }
209*fdd8201dSApple OSS Distributions
210*fdd8201dSApple OSS Distributions count = dict->count;
211*fdd8201dSApple OSS Distributions for (unsigned int i = 0; i < count; i++) {
212*fdd8201dSApple OSS Distributions dictionary[i].key = dict->dictionary[i].key;
213*fdd8201dSApple OSS Distributions dictionary[i].value = dict->dictionary[i].value;
214*fdd8201dSApple OSS Distributions }
215*fdd8201dSApple OSS Distributions
216*fdd8201dSApple OSS Distributions if ((kSort & fOptions) && !(kSort & dict->fOptions)) {
217*fdd8201dSApple OSS Distributions sortBySymbol();
218*fdd8201dSApple OSS Distributions }
219*fdd8201dSApple OSS Distributions
220*fdd8201dSApple OSS Distributions return true;
221*fdd8201dSApple OSS Distributions }
222*fdd8201dSApple OSS Distributions
223*fdd8201dSApple OSS Distributions OSSharedPtr<OSDictionary>
withCapacity(unsigned int capacity)224*fdd8201dSApple OSS Distributions OSDictionary::withCapacity(unsigned int capacity)
225*fdd8201dSApple OSS Distributions {
226*fdd8201dSApple OSS Distributions OSSharedPtr<OSDictionary> me = OSMakeShared<OSDictionary>();
227*fdd8201dSApple OSS Distributions
228*fdd8201dSApple OSS Distributions if (me && !me->initWithCapacity(capacity)) {
229*fdd8201dSApple OSS Distributions return nullptr;
230*fdd8201dSApple OSS Distributions }
231*fdd8201dSApple OSS Distributions
232*fdd8201dSApple OSS Distributions return me;
233*fdd8201dSApple OSS Distributions }
234*fdd8201dSApple OSS Distributions
235*fdd8201dSApple OSS Distributions OSSharedPtr<OSDictionary>
withObjects(const OSObject * objects[],const OSSymbol * keys[],unsigned int count,unsigned int capacity)236*fdd8201dSApple OSS Distributions OSDictionary::withObjects(const OSObject *objects[],
237*fdd8201dSApple OSS Distributions const OSSymbol *keys[],
238*fdd8201dSApple OSS Distributions unsigned int count,
239*fdd8201dSApple OSS Distributions unsigned int capacity)
240*fdd8201dSApple OSS Distributions {
241*fdd8201dSApple OSS Distributions OSSharedPtr<OSDictionary> me = OSMakeShared<OSDictionary>();
242*fdd8201dSApple OSS Distributions
243*fdd8201dSApple OSS Distributions if (me && !me->initWithObjects(objects, keys, count, capacity)) {
244*fdd8201dSApple OSS Distributions return nullptr;
245*fdd8201dSApple OSS Distributions }
246*fdd8201dSApple OSS Distributions
247*fdd8201dSApple OSS Distributions return me;
248*fdd8201dSApple OSS Distributions }
249*fdd8201dSApple OSS Distributions
250*fdd8201dSApple OSS Distributions OSSharedPtr<OSDictionary>
withObjects(const OSObject * objects[],const OSString * keys[],unsigned int count,unsigned int capacity)251*fdd8201dSApple OSS Distributions OSDictionary::withObjects(const OSObject *objects[],
252*fdd8201dSApple OSS Distributions const OSString *keys[],
253*fdd8201dSApple OSS Distributions unsigned int count,
254*fdd8201dSApple OSS Distributions unsigned int capacity)
255*fdd8201dSApple OSS Distributions {
256*fdd8201dSApple OSS Distributions OSSharedPtr<OSDictionary> me = OSMakeShared<OSDictionary>();
257*fdd8201dSApple OSS Distributions
258*fdd8201dSApple OSS Distributions if (me && !me->initWithObjects(objects, keys, count, capacity)) {
259*fdd8201dSApple OSS Distributions return nullptr;
260*fdd8201dSApple OSS Distributions }
261*fdd8201dSApple OSS Distributions
262*fdd8201dSApple OSS Distributions return me;
263*fdd8201dSApple OSS Distributions }
264*fdd8201dSApple OSS Distributions
265*fdd8201dSApple OSS Distributions OSSharedPtr<OSDictionary>
withDictionary(const OSDictionary * dict,unsigned int capacity)266*fdd8201dSApple OSS Distributions OSDictionary::withDictionary(const OSDictionary *dict,
267*fdd8201dSApple OSS Distributions unsigned int capacity)
268*fdd8201dSApple OSS Distributions {
269*fdd8201dSApple OSS Distributions OSSharedPtr<OSDictionary> me = OSMakeShared<OSDictionary>();
270*fdd8201dSApple OSS Distributions
271*fdd8201dSApple OSS Distributions if (me && !me->initWithDictionary(dict, capacity)) {
272*fdd8201dSApple OSS Distributions return nullptr;
273*fdd8201dSApple OSS Distributions }
274*fdd8201dSApple OSS Distributions
275*fdd8201dSApple OSS Distributions return me;
276*fdd8201dSApple OSS Distributions }
277*fdd8201dSApple OSS Distributions
278*fdd8201dSApple OSS Distributions void
free()279*fdd8201dSApple OSS Distributions OSDictionary::free()
280*fdd8201dSApple OSS Distributions {
281*fdd8201dSApple OSS Distributions (void) super::setOptions(0, kImmutable);
282*fdd8201dSApple OSS Distributions flushCollection();
283*fdd8201dSApple OSS Distributions if (dictionary) {
284*fdd8201dSApple OSS Distributions kfree_type(dictEntry, capacity, dictionary);
285*fdd8201dSApple OSS Distributions OSCONTAINER_ACCUMSIZE( -(capacity * sizeof(dictEntry)));
286*fdd8201dSApple OSS Distributions }
287*fdd8201dSApple OSS Distributions
288*fdd8201dSApple OSS Distributions super::free();
289*fdd8201dSApple OSS Distributions }
290*fdd8201dSApple OSS Distributions
291*fdd8201dSApple OSS Distributions unsigned int
getCount() const292*fdd8201dSApple OSS Distributions OSDictionary::getCount() const
293*fdd8201dSApple OSS Distributions {
294*fdd8201dSApple OSS Distributions return count;
295*fdd8201dSApple OSS Distributions }
296*fdd8201dSApple OSS Distributions unsigned int
getCapacity() const297*fdd8201dSApple OSS Distributions OSDictionary::getCapacity() const
298*fdd8201dSApple OSS Distributions {
299*fdd8201dSApple OSS Distributions return capacity;
300*fdd8201dSApple OSS Distributions }
301*fdd8201dSApple OSS Distributions
302*fdd8201dSApple OSS Distributions unsigned int
getCapacityIncrement() const303*fdd8201dSApple OSS Distributions OSDictionary::getCapacityIncrement() const
304*fdd8201dSApple OSS Distributions {
305*fdd8201dSApple OSS Distributions return capacityIncrement;
306*fdd8201dSApple OSS Distributions }
307*fdd8201dSApple OSS Distributions
308*fdd8201dSApple OSS Distributions unsigned int
setCapacityIncrement(unsigned int increment)309*fdd8201dSApple OSS Distributions OSDictionary::setCapacityIncrement(unsigned int increment)
310*fdd8201dSApple OSS Distributions {
311*fdd8201dSApple OSS Distributions capacityIncrement = (increment)? increment : 16;
312*fdd8201dSApple OSS Distributions
313*fdd8201dSApple OSS Distributions return capacityIncrement;
314*fdd8201dSApple OSS Distributions }
315*fdd8201dSApple OSS Distributions
316*fdd8201dSApple OSS Distributions unsigned int
ensureCapacity(unsigned int newCapacity)317*fdd8201dSApple OSS Distributions OSDictionary::ensureCapacity(unsigned int newCapacity)
318*fdd8201dSApple OSS Distributions {
319*fdd8201dSApple OSS Distributions dictEntry *newDict;
320*fdd8201dSApple OSS Distributions unsigned int finalCapacity;
321*fdd8201dSApple OSS Distributions
322*fdd8201dSApple OSS Distributions if (newCapacity <= capacity) {
323*fdd8201dSApple OSS Distributions return capacity;
324*fdd8201dSApple OSS Distributions }
325*fdd8201dSApple OSS Distributions
326*fdd8201dSApple OSS Distributions // round up
327*fdd8201dSApple OSS Distributions finalCapacity = (((newCapacity - 1) / capacityIncrement) + 1)
328*fdd8201dSApple OSS Distributions * capacityIncrement;
329*fdd8201dSApple OSS Distributions
330*fdd8201dSApple OSS Distributions // integer overflow check
331*fdd8201dSApple OSS Distributions if (finalCapacity < newCapacity) {
332*fdd8201dSApple OSS Distributions return capacity;
333*fdd8201dSApple OSS Distributions }
334*fdd8201dSApple OSS Distributions
335*fdd8201dSApple OSS Distributions newDict = kallocp_type_container(dictEntry, &finalCapacity, Z_WAITOK);
336*fdd8201dSApple OSS Distributions if (newDict) {
337*fdd8201dSApple OSS Distributions os::uninitialized_move(dictionary, dictionary + capacity, newDict);
338*fdd8201dSApple OSS Distributions os::uninitialized_value_construct(newDict + capacity, newDict + finalCapacity);
339*fdd8201dSApple OSS Distributions os::destroy(dictionary, dictionary + capacity);
340*fdd8201dSApple OSS Distributions
341*fdd8201dSApple OSS Distributions OSCONTAINER_ACCUMSIZE(sizeof(dictEntry) * (finalCapacity - capacity));
342*fdd8201dSApple OSS Distributions
343*fdd8201dSApple OSS Distributions kfree_type(dictEntry, capacity, dictionary);
344*fdd8201dSApple OSS Distributions dictionary = newDict;
345*fdd8201dSApple OSS Distributions capacity = finalCapacity;
346*fdd8201dSApple OSS Distributions }
347*fdd8201dSApple OSS Distributions
348*fdd8201dSApple OSS Distributions return capacity;
349*fdd8201dSApple OSS Distributions }
350*fdd8201dSApple OSS Distributions
351*fdd8201dSApple OSS Distributions void
flushCollection()352*fdd8201dSApple OSS Distributions OSDictionary::flushCollection()
353*fdd8201dSApple OSS Distributions {
354*fdd8201dSApple OSS Distributions haveUpdated();
355*fdd8201dSApple OSS Distributions
356*fdd8201dSApple OSS Distributions for (unsigned int i = 0; i < count; i++) {
357*fdd8201dSApple OSS Distributions dictionary[i].key->taggedRelease(OSTypeID(OSCollection));
358*fdd8201dSApple OSS Distributions dictionary[i].value->taggedRelease(OSTypeID(OSCollection));
359*fdd8201dSApple OSS Distributions }
360*fdd8201dSApple OSS Distributions count = 0;
361*fdd8201dSApple OSS Distributions }
362*fdd8201dSApple OSS Distributions
363*fdd8201dSApple OSS Distributions bool
364*fdd8201dSApple OSS Distributions OSDictionary::
setObject(const OSSymbol * aKey,const OSMetaClassBase * anObject,bool onlyAdd)365*fdd8201dSApple OSS Distributions setObject(const OSSymbol *aKey, const OSMetaClassBase *anObject, bool onlyAdd)
366*fdd8201dSApple OSS Distributions {
367*fdd8201dSApple OSS Distributions unsigned int i;
368*fdd8201dSApple OSS Distributions bool exists;
369*fdd8201dSApple OSS Distributions
370*fdd8201dSApple OSS Distributions if (!anObject || !aKey) {
371*fdd8201dSApple OSS Distributions return false;
372*fdd8201dSApple OSS Distributions }
373*fdd8201dSApple OSS Distributions
374*fdd8201dSApple OSS Distributions // if the key exists, replace the object
375*fdd8201dSApple OSS Distributions
376*fdd8201dSApple OSS Distributions if (fOptions & kSort) {
377*fdd8201dSApple OSS Distributions i = OSSymbol::bsearch(aKey, &dictionary[0], count, sizeof(dictionary[0]));
378*fdd8201dSApple OSS Distributions exists = (i < count) && (aKey == dictionary[i].key);
379*fdd8201dSApple OSS Distributions } else {
380*fdd8201dSApple OSS Distributions for (exists = false, i = 0; i < count; i++) {
381*fdd8201dSApple OSS Distributions if ((exists = (aKey == dictionary[i].key))) {
382*fdd8201dSApple OSS Distributions break;
383*fdd8201dSApple OSS Distributions }
384*fdd8201dSApple OSS Distributions }
385*fdd8201dSApple OSS Distributions }
386*fdd8201dSApple OSS Distributions
387*fdd8201dSApple OSS Distributions if (exists) {
388*fdd8201dSApple OSS Distributions if (onlyAdd) {
389*fdd8201dSApple OSS Distributions return false;
390*fdd8201dSApple OSS Distributions }
391*fdd8201dSApple OSS Distributions
392*fdd8201dSApple OSS Distributions OSTaggedSharedPtr<const OSMetaClassBase, OSCollection> oldObject;
393*fdd8201dSApple OSS Distributions
394*fdd8201dSApple OSS Distributions haveUpdated();
395*fdd8201dSApple OSS Distributions
396*fdd8201dSApple OSS Distributions dictionary[i].value.reset(anObject, OSRetain);
397*fdd8201dSApple OSS Distributions return true;
398*fdd8201dSApple OSS Distributions }
399*fdd8201dSApple OSS Distributions
400*fdd8201dSApple OSS Distributions // add new key, possibly extending our capacity
401*fdd8201dSApple OSS Distributions if (count >= capacity && count >= ensureCapacity(count + 1)) {
402*fdd8201dSApple OSS Distributions return false;
403*fdd8201dSApple OSS Distributions }
404*fdd8201dSApple OSS Distributions
405*fdd8201dSApple OSS Distributions haveUpdated();
406*fdd8201dSApple OSS Distributions
407*fdd8201dSApple OSS Distributions new (&dictionary[count]) dictEntry();
408*fdd8201dSApple OSS Distributions os::move_backward(&dictionary[i], &dictionary[count], &dictionary[count + 1]);
409*fdd8201dSApple OSS Distributions
410*fdd8201dSApple OSS Distributions dictionary[i].key.reset(aKey, OSRetain);
411*fdd8201dSApple OSS Distributions dictionary[i].value.reset(anObject, OSRetain);
412*fdd8201dSApple OSS Distributions count++;
413*fdd8201dSApple OSS Distributions
414*fdd8201dSApple OSS Distributions return true;
415*fdd8201dSApple OSS Distributions }
416*fdd8201dSApple OSS Distributions
417*fdd8201dSApple OSS Distributions bool
418*fdd8201dSApple OSS Distributions OSDictionary::
setObject(const OSSymbol * aKey,const OSMetaClassBase * anObject)419*fdd8201dSApple OSS Distributions setObject(const OSSymbol *aKey, const OSMetaClassBase *anObject)
420*fdd8201dSApple OSS Distributions {
421*fdd8201dSApple OSS Distributions return setObject(aKey, anObject, false);
422*fdd8201dSApple OSS Distributions }
423*fdd8201dSApple OSS Distributions
424*fdd8201dSApple OSS Distributions bool
setObject(OSSharedPtr<const OSSymbol> const & aKey,OSSharedPtr<const OSMetaClassBase> const & anObject)425*fdd8201dSApple OSS Distributions OSDictionary::setObject(OSSharedPtr<const OSSymbol> const& aKey, OSSharedPtr<const OSMetaClassBase> const& anObject)
426*fdd8201dSApple OSS Distributions {
427*fdd8201dSApple OSS Distributions return setObject(aKey.get(), anObject.get());
428*fdd8201dSApple OSS Distributions }
429*fdd8201dSApple OSS Distributions
430*fdd8201dSApple OSS Distributions bool
setObject(const OSString * aKey,OSSharedPtr<const OSMetaClassBase> const & anObject)431*fdd8201dSApple OSS Distributions OSDictionary::setObject(const OSString* aKey, OSSharedPtr<const OSMetaClassBase> const& anObject)
432*fdd8201dSApple OSS Distributions {
433*fdd8201dSApple OSS Distributions return setObject(aKey, anObject.get());
434*fdd8201dSApple OSS Distributions }
435*fdd8201dSApple OSS Distributions
436*fdd8201dSApple OSS Distributions bool
setObject(const char * aKey,OSSharedPtr<const OSMetaClassBase> const & anObject)437*fdd8201dSApple OSS Distributions OSDictionary::setObject(const char* aKey, OSSharedPtr<const OSMetaClassBase> const& anObject)
438*fdd8201dSApple OSS Distributions {
439*fdd8201dSApple OSS Distributions return setObject(aKey, anObject.get());
440*fdd8201dSApple OSS Distributions }
441*fdd8201dSApple OSS Distributions
442*fdd8201dSApple OSS Distributions void
removeObject(const OSSymbol * aKey)443*fdd8201dSApple OSS Distributions OSDictionary::removeObject(const OSSymbol *aKey)
444*fdd8201dSApple OSS Distributions {
445*fdd8201dSApple OSS Distributions unsigned int i;
446*fdd8201dSApple OSS Distributions bool exists;
447*fdd8201dSApple OSS Distributions
448*fdd8201dSApple OSS Distributions if (!aKey) {
449*fdd8201dSApple OSS Distributions return;
450*fdd8201dSApple OSS Distributions }
451*fdd8201dSApple OSS Distributions
452*fdd8201dSApple OSS Distributions // if the key exists, remove the object
453*fdd8201dSApple OSS Distributions
454*fdd8201dSApple OSS Distributions if (fOptions & kSort) {
455*fdd8201dSApple OSS Distributions i = OSSymbol::bsearch(aKey, &dictionary[0], count, sizeof(dictionary[0]));
456*fdd8201dSApple OSS Distributions exists = (i < count) && (aKey == dictionary[i].key);
457*fdd8201dSApple OSS Distributions } else {
458*fdd8201dSApple OSS Distributions for (exists = false, i = 0; i < count; i++) {
459*fdd8201dSApple OSS Distributions if ((exists = (aKey == dictionary[i].key))) {
460*fdd8201dSApple OSS Distributions break;
461*fdd8201dSApple OSS Distributions }
462*fdd8201dSApple OSS Distributions }
463*fdd8201dSApple OSS Distributions }
464*fdd8201dSApple OSS Distributions
465*fdd8201dSApple OSS Distributions if (exists) {
466*fdd8201dSApple OSS Distributions dictEntry oldEntry = dictionary[i];
467*fdd8201dSApple OSS Distributions
468*fdd8201dSApple OSS Distributions haveUpdated();
469*fdd8201dSApple OSS Distributions
470*fdd8201dSApple OSS Distributions count--;
471*fdd8201dSApple OSS Distributions bcopy(&dictionary[i + 1], &dictionary[i], (count - i) * sizeof(dictionary[0]));
472*fdd8201dSApple OSS Distributions
473*fdd8201dSApple OSS Distributions oldEntry.key->taggedRelease(OSTypeID(OSCollection));
474*fdd8201dSApple OSS Distributions oldEntry.value->taggedRelease(OSTypeID(OSCollection));
475*fdd8201dSApple OSS Distributions return;
476*fdd8201dSApple OSS Distributions }
477*fdd8201dSApple OSS Distributions }
478*fdd8201dSApple OSS Distributions
479*fdd8201dSApple OSS Distributions
480*fdd8201dSApple OSS Distributions // Returns true on success, false on an error condition.
481*fdd8201dSApple OSS Distributions bool
merge(const OSDictionary * srcDict)482*fdd8201dSApple OSS Distributions OSDictionary::merge(const OSDictionary *srcDict)
483*fdd8201dSApple OSS Distributions {
484*fdd8201dSApple OSS Distributions const OSSymbol * sym;
485*fdd8201dSApple OSS Distributions OSSharedPtr<OSCollectionIterator> iter;
486*fdd8201dSApple OSS Distributions
487*fdd8201dSApple OSS Distributions if (!OSDynamicCast(OSDictionary, srcDict)) {
488*fdd8201dSApple OSS Distributions return false;
489*fdd8201dSApple OSS Distributions }
490*fdd8201dSApple OSS Distributions
491*fdd8201dSApple OSS Distributions iter = OSCollectionIterator::withCollection(const_cast<OSDictionary *>(srcDict));
492*fdd8201dSApple OSS Distributions if (!iter) {
493*fdd8201dSApple OSS Distributions return false;
494*fdd8201dSApple OSS Distributions }
495*fdd8201dSApple OSS Distributions
496*fdd8201dSApple OSS Distributions while ((sym = (const OSSymbol *)iter->getNextObject())) {
497*fdd8201dSApple OSS Distributions const OSMetaClassBase * obj;
498*fdd8201dSApple OSS Distributions
499*fdd8201dSApple OSS Distributions obj = srcDict->getObject(sym);
500*fdd8201dSApple OSS Distributions if (!setObject(sym, obj)) {
501*fdd8201dSApple OSS Distributions return false;
502*fdd8201dSApple OSS Distributions }
503*fdd8201dSApple OSS Distributions }
504*fdd8201dSApple OSS Distributions
505*fdd8201dSApple OSS Distributions return true;
506*fdd8201dSApple OSS Distributions }
507*fdd8201dSApple OSS Distributions
508*fdd8201dSApple OSS Distributions OSObject *
getObject(const OSSymbol * aKey) const509*fdd8201dSApple OSS Distributions OSDictionary::getObject(const OSSymbol *aKey) const
510*fdd8201dSApple OSS Distributions {
511*fdd8201dSApple OSS Distributions unsigned int i, l = 0, r = count;
512*fdd8201dSApple OSS Distributions
513*fdd8201dSApple OSS Distributions if (!aKey) {
514*fdd8201dSApple OSS Distributions return NULL;
515*fdd8201dSApple OSS Distributions }
516*fdd8201dSApple OSS Distributions
517*fdd8201dSApple OSS Distributions // if the key exists, return the object
518*fdd8201dSApple OSS Distributions //
519*fdd8201dSApple OSS Distributions // inline OSSymbol::bsearch in this performance critical codepath
520*fdd8201dSApple OSS Distributions // for performance, the compiler can't do that due to the genericity
521*fdd8201dSApple OSS Distributions // of OSSymbol::bsearch
522*fdd8201dSApple OSS Distributions //
523*fdd8201dSApple OSS Distributions // If we have less than 4 objects, scanning is faster.
524*fdd8201dSApple OSS Distributions if (count > 4 && (fOptions & kSort)) {
525*fdd8201dSApple OSS Distributions while (l < r) {
526*fdd8201dSApple OSS Distributions i = (l + r) / 2;
527*fdd8201dSApple OSS Distributions if (aKey == dictionary[i].key) {
528*fdd8201dSApple OSS Distributions return const_cast<OSObject *> ((const OSObject *)dictionary[i].value.get());
529*fdd8201dSApple OSS Distributions }
530*fdd8201dSApple OSS Distributions
531*fdd8201dSApple OSS Distributions if ((uintptr_t)aKey < (uintptr_t)dictionary[i].key.get()) {
532*fdd8201dSApple OSS Distributions r = i;
533*fdd8201dSApple OSS Distributions } else {
534*fdd8201dSApple OSS Distributions l = i + 1;
535*fdd8201dSApple OSS Distributions }
536*fdd8201dSApple OSS Distributions }
537*fdd8201dSApple OSS Distributions } else {
538*fdd8201dSApple OSS Distributions for (i = l; i < r; i++) {
539*fdd8201dSApple OSS Distributions if (aKey == dictionary[i].key) {
540*fdd8201dSApple OSS Distributions return const_cast<OSObject *> ((const OSObject *)dictionary[i].value.get());
541*fdd8201dSApple OSS Distributions }
542*fdd8201dSApple OSS Distributions }
543*fdd8201dSApple OSS Distributions }
544*fdd8201dSApple OSS Distributions
545*fdd8201dSApple OSS Distributions return NULL;
546*fdd8201dSApple OSS Distributions }
547*fdd8201dSApple OSS Distributions
548*fdd8201dSApple OSS Distributions // Wrapper macros
549*fdd8201dSApple OSS Distributions #define OBJECT_WRAP_1(cmd, k) \
550*fdd8201dSApple OSS Distributions { \
551*fdd8201dSApple OSS Distributions OSSharedPtr<const OSSymbol> tmpKey = k; \
552*fdd8201dSApple OSS Distributions OSObject *retObj = NULL; \
553*fdd8201dSApple OSS Distributions if (tmpKey) { \
554*fdd8201dSApple OSS Distributions retObj = cmd(tmpKey.get()); \
555*fdd8201dSApple OSS Distributions } \
556*fdd8201dSApple OSS Distributions return retObj; \
557*fdd8201dSApple OSS Distributions }
558*fdd8201dSApple OSS Distributions
559*fdd8201dSApple OSS Distributions #define OBJECT_WRAP_2(cmd, k, o) \
560*fdd8201dSApple OSS Distributions { \
561*fdd8201dSApple OSS Distributions OSSharedPtr<const OSSymbol> tmpKey = k; \
562*fdd8201dSApple OSS Distributions bool ret = cmd(tmpKey.get(), o); \
563*fdd8201dSApple OSS Distributions \
564*fdd8201dSApple OSS Distributions return ret; \
565*fdd8201dSApple OSS Distributions }
566*fdd8201dSApple OSS Distributions
567*fdd8201dSApple OSS Distributions #define OBJECT_WRAP_3(cmd, k) \
568*fdd8201dSApple OSS Distributions { \
569*fdd8201dSApple OSS Distributions OSSharedPtr<const OSSymbol> tmpKey = k; \
570*fdd8201dSApple OSS Distributions if (tmpKey) { \
571*fdd8201dSApple OSS Distributions cmd(tmpKey.get()); \
572*fdd8201dSApple OSS Distributions } \
573*fdd8201dSApple OSS Distributions }
574*fdd8201dSApple OSS Distributions
575*fdd8201dSApple OSS Distributions
576*fdd8201dSApple OSS Distributions bool
setObject(const OSString * aKey,const OSMetaClassBase * anObject)577*fdd8201dSApple OSS Distributions OSDictionary::setObject(const OSString *aKey, const OSMetaClassBase *anObject)
578*fdd8201dSApple OSS Distributions OBJECT_WRAP_2(setObject, OSSymbol::withString(aKey), anObject)
579*fdd8201dSApple OSS Distributions bool
580*fdd8201dSApple OSS Distributions OSDictionary::setObject(const char *aKey, const OSMetaClassBase *anObject)
581*fdd8201dSApple OSS Distributions OBJECT_WRAP_2(setObject, OSSymbol::withCString(aKey), anObject)
582*fdd8201dSApple OSS Distributions
583*fdd8201dSApple OSS Distributions OSObject *OSDictionary::getObject(const OSString * aKey) const
584*fdd8201dSApple OSS Distributions OBJECT_WRAP_1(getObject, OSSymbol::existingSymbolForString(aKey))
585*fdd8201dSApple OSS Distributions OSObject *OSDictionary::getObject(const char *aKey) const
586*fdd8201dSApple OSS Distributions OBJECT_WRAP_1(getObject, OSSymbol::existingSymbolForCString(aKey))
587*fdd8201dSApple OSS Distributions
588*fdd8201dSApple OSS Distributions void
589*fdd8201dSApple OSS Distributions OSDictionary::removeObject(const OSString *aKey)
590*fdd8201dSApple OSS Distributions OBJECT_WRAP_3(removeObject, OSSymbol::existingSymbolForString(aKey))
591*fdd8201dSApple OSS Distributions void
592*fdd8201dSApple OSS Distributions OSDictionary::removeObject(const char *aKey)
593*fdd8201dSApple OSS Distributions OBJECT_WRAP_3(removeObject, OSSymbol::existingSymbolForCString(aKey))
594*fdd8201dSApple OSS Distributions
595*fdd8201dSApple OSS Distributions bool
596*fdd8201dSApple OSS Distributions OSDictionary::isEqualTo(const OSDictionary *srcDict, const OSCollection *keys) const
597*fdd8201dSApple OSS Distributions {
598*fdd8201dSApple OSS Distributions OSSharedPtr<OSCollectionIterator> iter;
599*fdd8201dSApple OSS Distributions unsigned int keysCount;
600*fdd8201dSApple OSS Distributions const OSMetaClassBase * obj1;
601*fdd8201dSApple OSS Distributions const OSMetaClassBase * obj2;
602*fdd8201dSApple OSS Distributions OSString * aKey;
603*fdd8201dSApple OSS Distributions bool ret;
604*fdd8201dSApple OSS Distributions
605*fdd8201dSApple OSS Distributions if (this == srcDict) {
606*fdd8201dSApple OSS Distributions return true;
607*fdd8201dSApple OSS Distributions }
608*fdd8201dSApple OSS Distributions
609*fdd8201dSApple OSS Distributions keysCount = keys->getCount();
610*fdd8201dSApple OSS Distributions if ((count < keysCount) || (srcDict->getCount() < keysCount)) {
611*fdd8201dSApple OSS Distributions return false;
612*fdd8201dSApple OSS Distributions }
613*fdd8201dSApple OSS Distributions
614*fdd8201dSApple OSS Distributions iter = OSCollectionIterator::withCollection(keys);
615*fdd8201dSApple OSS Distributions if (!iter) {
616*fdd8201dSApple OSS Distributions return false;
617*fdd8201dSApple OSS Distributions }
618*fdd8201dSApple OSS Distributions
619*fdd8201dSApple OSS Distributions ret = true;
620*fdd8201dSApple OSS Distributions while ((aKey = OSDynamicCast(OSString, iter->getNextObject()))) {
621*fdd8201dSApple OSS Distributions obj1 = getObject(aKey);
622*fdd8201dSApple OSS Distributions obj2 = srcDict->getObject(aKey);
623*fdd8201dSApple OSS Distributions if (!obj1 || !obj2) {
624*fdd8201dSApple OSS Distributions ret = false;
625*fdd8201dSApple OSS Distributions break;
626*fdd8201dSApple OSS Distributions }
627*fdd8201dSApple OSS Distributions
628*fdd8201dSApple OSS Distributions if (!obj1->isEqualTo(obj2)) {
629*fdd8201dSApple OSS Distributions ret = false;
630*fdd8201dSApple OSS Distributions break;
631*fdd8201dSApple OSS Distributions }
632*fdd8201dSApple OSS Distributions }
633*fdd8201dSApple OSS Distributions
634*fdd8201dSApple OSS Distributions return ret;
635*fdd8201dSApple OSS Distributions }
636*fdd8201dSApple OSS Distributions
637*fdd8201dSApple OSS Distributions bool
isEqualTo(const OSDictionary * srcDict) const638*fdd8201dSApple OSS Distributions OSDictionary::isEqualTo(const OSDictionary *srcDict) const
639*fdd8201dSApple OSS Distributions {
640*fdd8201dSApple OSS Distributions unsigned int i;
641*fdd8201dSApple OSS Distributions const OSMetaClassBase * obj;
642*fdd8201dSApple OSS Distributions
643*fdd8201dSApple OSS Distributions if (this == srcDict) {
644*fdd8201dSApple OSS Distributions return true;
645*fdd8201dSApple OSS Distributions }
646*fdd8201dSApple OSS Distributions
647*fdd8201dSApple OSS Distributions if (count != srcDict->getCount()) {
648*fdd8201dSApple OSS Distributions return false;
649*fdd8201dSApple OSS Distributions }
650*fdd8201dSApple OSS Distributions
651*fdd8201dSApple OSS Distributions for (i = 0; i < count; i++) {
652*fdd8201dSApple OSS Distributions obj = srcDict->getObject(dictionary[i].key.get());
653*fdd8201dSApple OSS Distributions if (!obj) {
654*fdd8201dSApple OSS Distributions return false;
655*fdd8201dSApple OSS Distributions }
656*fdd8201dSApple OSS Distributions
657*fdd8201dSApple OSS Distributions if (!dictionary[i].value->isEqualTo(obj)) {
658*fdd8201dSApple OSS Distributions return false;
659*fdd8201dSApple OSS Distributions }
660*fdd8201dSApple OSS Distributions }
661*fdd8201dSApple OSS Distributions
662*fdd8201dSApple OSS Distributions return true;
663*fdd8201dSApple OSS Distributions }
664*fdd8201dSApple OSS Distributions
665*fdd8201dSApple OSS Distributions bool
isEqualTo(const OSMetaClassBase * anObject) const666*fdd8201dSApple OSS Distributions OSDictionary::isEqualTo(const OSMetaClassBase *anObject) const
667*fdd8201dSApple OSS Distributions {
668*fdd8201dSApple OSS Distributions OSDictionary *dict;
669*fdd8201dSApple OSS Distributions
670*fdd8201dSApple OSS Distributions dict = OSDynamicCast(OSDictionary, anObject);
671*fdd8201dSApple OSS Distributions if (dict) {
672*fdd8201dSApple OSS Distributions return isEqualTo(dict);
673*fdd8201dSApple OSS Distributions } else {
674*fdd8201dSApple OSS Distributions return false;
675*fdd8201dSApple OSS Distributions }
676*fdd8201dSApple OSS Distributions }
677*fdd8201dSApple OSS Distributions
678*fdd8201dSApple OSS Distributions unsigned int
iteratorSize() const679*fdd8201dSApple OSS Distributions OSDictionary::iteratorSize() const
680*fdd8201dSApple OSS Distributions {
681*fdd8201dSApple OSS Distributions return sizeof(unsigned int);
682*fdd8201dSApple OSS Distributions }
683*fdd8201dSApple OSS Distributions
684*fdd8201dSApple OSS Distributions bool
initIterator(void * inIterator) const685*fdd8201dSApple OSS Distributions OSDictionary::initIterator(void *inIterator) const
686*fdd8201dSApple OSS Distributions {
687*fdd8201dSApple OSS Distributions unsigned int *iteratorP = (unsigned int *) inIterator;
688*fdd8201dSApple OSS Distributions
689*fdd8201dSApple OSS Distributions *iteratorP = 0;
690*fdd8201dSApple OSS Distributions return true;
691*fdd8201dSApple OSS Distributions }
692*fdd8201dSApple OSS Distributions
693*fdd8201dSApple OSS Distributions bool
getNextObjectForIterator(void * inIterator,OSObject ** ret) const694*fdd8201dSApple OSS Distributions OSDictionary::getNextObjectForIterator(void *inIterator, OSObject **ret) const
695*fdd8201dSApple OSS Distributions {
696*fdd8201dSApple OSS Distributions unsigned int *iteratorP = (unsigned int *) inIterator;
697*fdd8201dSApple OSS Distributions unsigned int index = (*iteratorP)++;
698*fdd8201dSApple OSS Distributions
699*fdd8201dSApple OSS Distributions if (index < count) {
700*fdd8201dSApple OSS Distributions *ret = const_cast<OSSymbol*>(dictionary[index].key.get());
701*fdd8201dSApple OSS Distributions } else {
702*fdd8201dSApple OSS Distributions *ret = NULL;
703*fdd8201dSApple OSS Distributions }
704*fdd8201dSApple OSS Distributions
705*fdd8201dSApple OSS Distributions return *ret != NULL;
706*fdd8201dSApple OSS Distributions }
707*fdd8201dSApple OSS Distributions
708*fdd8201dSApple OSS Distributions bool
serialize(OSSerialize * s) const709*fdd8201dSApple OSS Distributions OSDictionary::serialize(OSSerialize *s) const
710*fdd8201dSApple OSS Distributions {
711*fdd8201dSApple OSS Distributions if (s->previouslySerialized(this)) {
712*fdd8201dSApple OSS Distributions return true;
713*fdd8201dSApple OSS Distributions }
714*fdd8201dSApple OSS Distributions
715*fdd8201dSApple OSS Distributions if (!s->addXMLStartTag(this, "dict")) {
716*fdd8201dSApple OSS Distributions return false;
717*fdd8201dSApple OSS Distributions }
718*fdd8201dSApple OSS Distributions
719*fdd8201dSApple OSS Distributions for (unsigned i = 0; i < count; i++) {
720*fdd8201dSApple OSS Distributions const OSSymbol *key = dictionary[i].key.get();
721*fdd8201dSApple OSS Distributions
722*fdd8201dSApple OSS Distributions // due the nature of the XML syntax, this must be a symbol
723*fdd8201dSApple OSS Distributions if (!key->metaCast("OSSymbol")) {
724*fdd8201dSApple OSS Distributions return false;
725*fdd8201dSApple OSS Distributions }
726*fdd8201dSApple OSS Distributions if (!s->addString("<key>")) {
727*fdd8201dSApple OSS Distributions return false;
728*fdd8201dSApple OSS Distributions }
729*fdd8201dSApple OSS Distributions const char *c = key->getCStringNoCopy();
730*fdd8201dSApple OSS Distributions while (*c) {
731*fdd8201dSApple OSS Distributions if (*c == '<') {
732*fdd8201dSApple OSS Distributions if (!s->addString("<")) {
733*fdd8201dSApple OSS Distributions return false;
734*fdd8201dSApple OSS Distributions }
735*fdd8201dSApple OSS Distributions } else if (*c == '>') {
736*fdd8201dSApple OSS Distributions if (!s->addString(">")) {
737*fdd8201dSApple OSS Distributions return false;
738*fdd8201dSApple OSS Distributions }
739*fdd8201dSApple OSS Distributions } else if (*c == '&') {
740*fdd8201dSApple OSS Distributions if (!s->addString("&")) {
741*fdd8201dSApple OSS Distributions return false;
742*fdd8201dSApple OSS Distributions }
743*fdd8201dSApple OSS Distributions } else {
744*fdd8201dSApple OSS Distributions if (!s->addChar(*c)) {
745*fdd8201dSApple OSS Distributions return false;
746*fdd8201dSApple OSS Distributions }
747*fdd8201dSApple OSS Distributions }
748*fdd8201dSApple OSS Distributions c++;
749*fdd8201dSApple OSS Distributions }
750*fdd8201dSApple OSS Distributions if (!s->addXMLEndTag("key")) {
751*fdd8201dSApple OSS Distributions return false;
752*fdd8201dSApple OSS Distributions }
753*fdd8201dSApple OSS Distributions
754*fdd8201dSApple OSS Distributions if (!dictionary[i].value->serialize(s)) {
755*fdd8201dSApple OSS Distributions return false;
756*fdd8201dSApple OSS Distributions }
757*fdd8201dSApple OSS Distributions }
758*fdd8201dSApple OSS Distributions
759*fdd8201dSApple OSS Distributions return s->addXMLEndTag("dict");
760*fdd8201dSApple OSS Distributions }
761*fdd8201dSApple OSS Distributions
762*fdd8201dSApple OSS Distributions unsigned
setOptions(unsigned options,unsigned mask,void *)763*fdd8201dSApple OSS Distributions OSDictionary::setOptions(unsigned options, unsigned mask, void *)
764*fdd8201dSApple OSS Distributions {
765*fdd8201dSApple OSS Distributions unsigned old = super::setOptions(options, mask);
766*fdd8201dSApple OSS Distributions if ((old ^ options) & mask) {
767*fdd8201dSApple OSS Distributions // Value changed need to recurse over all of the child collections
768*fdd8201dSApple OSS Distributions for (unsigned i = 0; i < count; i++) {
769*fdd8201dSApple OSS Distributions OSCollection *v = OSDynamicCast(OSCollection, dictionary[i].value.get());
770*fdd8201dSApple OSS Distributions if (v) {
771*fdd8201dSApple OSS Distributions v->setOptions(options, mask);
772*fdd8201dSApple OSS Distributions }
773*fdd8201dSApple OSS Distributions }
774*fdd8201dSApple OSS Distributions }
775*fdd8201dSApple OSS Distributions
776*fdd8201dSApple OSS Distributions if (!(old & kSort) && (fOptions & kSort)) {
777*fdd8201dSApple OSS Distributions sortBySymbol();
778*fdd8201dSApple OSS Distributions }
779*fdd8201dSApple OSS Distributions
780*fdd8201dSApple OSS Distributions return old;
781*fdd8201dSApple OSS Distributions }
782*fdd8201dSApple OSS Distributions
783*fdd8201dSApple OSS Distributions OSSharedPtr<OSCollection>
copyCollection(OSDictionary * cycleDict)784*fdd8201dSApple OSS Distributions OSDictionary::copyCollection(OSDictionary *cycleDict)
785*fdd8201dSApple OSS Distributions {
786*fdd8201dSApple OSS Distributions OSSharedPtr<OSDictionary> ourCycleDict;
787*fdd8201dSApple OSS Distributions OSSharedPtr<OSCollection> ret;
788*fdd8201dSApple OSS Distributions OSSharedPtr<OSDictionary> newDict;
789*fdd8201dSApple OSS Distributions
790*fdd8201dSApple OSS Distributions if (!cycleDict) {
791*fdd8201dSApple OSS Distributions ourCycleDict = OSDictionary::withCapacity(16);
792*fdd8201dSApple OSS Distributions if (!ourCycleDict) {
793*fdd8201dSApple OSS Distributions return nullptr;
794*fdd8201dSApple OSS Distributions }
795*fdd8201dSApple OSS Distributions cycleDict = ourCycleDict.get();
796*fdd8201dSApple OSS Distributions }
797*fdd8201dSApple OSS Distributions
798*fdd8201dSApple OSS Distributions do {
799*fdd8201dSApple OSS Distributions // Check for a cycle
800*fdd8201dSApple OSS Distributions ret = super::copyCollection(cycleDict);
801*fdd8201dSApple OSS Distributions if (ret) {
802*fdd8201dSApple OSS Distributions continue;
803*fdd8201dSApple OSS Distributions }
804*fdd8201dSApple OSS Distributions
805*fdd8201dSApple OSS Distributions newDict = OSDictionary::withDictionary(this);
806*fdd8201dSApple OSS Distributions if (!newDict) {
807*fdd8201dSApple OSS Distributions continue;
808*fdd8201dSApple OSS Distributions }
809*fdd8201dSApple OSS Distributions
810*fdd8201dSApple OSS Distributions // Insert object into cycle Dictionary
811*fdd8201dSApple OSS Distributions cycleDict->setObject((const OSSymbol *) this, newDict.get());
812*fdd8201dSApple OSS Distributions
813*fdd8201dSApple OSS Distributions for (unsigned int i = 0; i < count; i++) {
814*fdd8201dSApple OSS Distributions const OSMetaClassBase *obj = dictionary[i].value.get();
815*fdd8201dSApple OSS Distributions OSTaggedSharedPtr<OSCollection, OSCollection> coll(OSDynamicCast(OSCollection, EXT_CAST(obj)), OSNoRetain);
816*fdd8201dSApple OSS Distributions
817*fdd8201dSApple OSS Distributions if (coll) {
818*fdd8201dSApple OSS Distributions OSSharedPtr<OSCollection> newColl = coll->copyCollection(cycleDict);
819*fdd8201dSApple OSS Distributions if (!newColl) {
820*fdd8201dSApple OSS Distributions return ret;
821*fdd8201dSApple OSS Distributions }
822*fdd8201dSApple OSS Distributions newDict->dictionary[i].value.detach();
823*fdd8201dSApple OSS Distributions newDict->dictionary[i].value.reset(newColl.get(), OSRetain);
824*fdd8201dSApple OSS Distributions }
825*fdd8201dSApple OSS Distributions }
826*fdd8201dSApple OSS Distributions
827*fdd8201dSApple OSS Distributions ret = os::move(newDict);
828*fdd8201dSApple OSS Distributions } while (false);
829*fdd8201dSApple OSS Distributions
830*fdd8201dSApple OSS Distributions return ret;
831*fdd8201dSApple OSS Distributions }
832*fdd8201dSApple OSS Distributions
833*fdd8201dSApple OSS Distributions OSSharedPtr<OSArray>
copyKeys(void)834*fdd8201dSApple OSS Distributions OSDictionary::copyKeys(void)
835*fdd8201dSApple OSS Distributions {
836*fdd8201dSApple OSS Distributions OSSharedPtr<OSArray> array;
837*fdd8201dSApple OSS Distributions
838*fdd8201dSApple OSS Distributions array = OSArray::withCapacity(count);
839*fdd8201dSApple OSS Distributions if (!array) {
840*fdd8201dSApple OSS Distributions return nullptr;
841*fdd8201dSApple OSS Distributions }
842*fdd8201dSApple OSS Distributions
843*fdd8201dSApple OSS Distributions for (unsigned int i = 0; i < count; i++) {
844*fdd8201dSApple OSS Distributions if (!array->setObject(i, dictionary[i].key.get())) {
845*fdd8201dSApple OSS Distributions return nullptr;
846*fdd8201dSApple OSS Distributions }
847*fdd8201dSApple OSS Distributions }
848*fdd8201dSApple OSS Distributions return array;
849*fdd8201dSApple OSS Distributions }
850*fdd8201dSApple OSS Distributions
851*fdd8201dSApple OSS Distributions bool
iterateObjects(void * refcon,bool (* callback)(void * refcon,const OSSymbol * key,OSObject * object))852*fdd8201dSApple OSS Distributions OSDictionary::iterateObjects(void * refcon, bool (*callback)(void * refcon, const OSSymbol * key, OSObject * object))
853*fdd8201dSApple OSS Distributions {
854*fdd8201dSApple OSS Distributions unsigned int initialUpdateStamp;
855*fdd8201dSApple OSS Distributions bool done;
856*fdd8201dSApple OSS Distributions
857*fdd8201dSApple OSS Distributions initialUpdateStamp = updateStamp;
858*fdd8201dSApple OSS Distributions done = false;
859*fdd8201dSApple OSS Distributions for (unsigned int i = 0; i < count; i++) {
860*fdd8201dSApple OSS Distributions done = callback(refcon, dictionary[i].key.get(), EXT_CAST(dictionary[i].value.get()));
861*fdd8201dSApple OSS Distributions if (done) {
862*fdd8201dSApple OSS Distributions break;
863*fdd8201dSApple OSS Distributions }
864*fdd8201dSApple OSS Distributions if (initialUpdateStamp != updateStamp) {
865*fdd8201dSApple OSS Distributions break;
866*fdd8201dSApple OSS Distributions }
867*fdd8201dSApple OSS Distributions }
868*fdd8201dSApple OSS Distributions
869*fdd8201dSApple OSS Distributions return initialUpdateStamp == updateStamp;
870*fdd8201dSApple OSS Distributions }
871*fdd8201dSApple OSS Distributions
872*fdd8201dSApple OSS Distributions static bool
OSDictionaryIterateObjectsBlock(void * refcon,const OSSymbol * key,OSObject * object)873*fdd8201dSApple OSS Distributions OSDictionaryIterateObjectsBlock(void * refcon, const OSSymbol * key, OSObject * object)
874*fdd8201dSApple OSS Distributions {
875*fdd8201dSApple OSS Distributions bool (^block)(const OSSymbol * key, OSObject * object) = (typeof(block))refcon;
876*fdd8201dSApple OSS Distributions return block(key, object);
877*fdd8201dSApple OSS Distributions }
878*fdd8201dSApple OSS Distributions
879*fdd8201dSApple OSS Distributions bool
880*fdd8201dSApple OSS Distributions OSDictionary::iterateObjects(bool (^block)(const OSSymbol * key, OSObject * object))
881*fdd8201dSApple OSS Distributions {
882*fdd8201dSApple OSS Distributions return iterateObjects((void *)block, &OSDictionaryIterateObjectsBlock);
883*fdd8201dSApple OSS Distributions }
884