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