]> git.saurik.com Git - apple/xnu.git/blame - libkern/c++/OSSet.cpp
xnu-792.6.56.tar.gz
[apple/xnu.git] / libkern / c++ / OSSet.cpp
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
ff6e181a
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
1c79356b 12 *
ff6e181a
A
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
ff6e181a
A
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
1c79356b
A
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/* IOSet.m created by rsulack on Thu 11-Jun-1998 */
24
91447636 25#include <libkern/c++/OSDictionary.h>
1c79356b
A
26#include <libkern/c++/OSArray.h>
27#include <libkern/c++/OSSerialize.h>
91447636 28#include <libkern/c++/OSSet.h>
1c79356b
A
29
30#define super OSCollection
31
32OSDefineMetaClassAndStructors(OSSet, OSCollection)
33OSMetaClassDefineReservedUnused(OSSet, 0);
34OSMetaClassDefineReservedUnused(OSSet, 1);
35OSMetaClassDefineReservedUnused(OSSet, 2);
36OSMetaClassDefineReservedUnused(OSSet, 3);
37OSMetaClassDefineReservedUnused(OSSet, 4);
38OSMetaClassDefineReservedUnused(OSSet, 5);
39OSMetaClassDefineReservedUnused(OSSet, 6);
40OSMetaClassDefineReservedUnused(OSSet, 7);
41
91447636
A
42#define EXT_CAST(obj) \
43 reinterpret_cast<OSObject *>(const_cast<OSMetaClassBase *>(obj))
44
1c79356b
A
45bool OSSet::initWithCapacity(unsigned int inCapacity)
46{
47 if ( !super::init() )
48 return false;
49
50 members = OSArray::withCapacity(inCapacity);
51 if (!members)
52 return false;
53
54 return true;
55}
56
57bool OSSet::initWithObjects(const OSObject *inObjects[],
58 unsigned int inCount,
55e303ae 59 unsigned int inCapacity)
1c79356b
A
60{
61 unsigned int capacity = inCount;
62
63 if ( inCapacity ) {
64 if ( inCount > inCapacity )
65 return false;
66
67 capacity = inCapacity;
68 }
69
70 if (!inObjects || !initWithCapacity(capacity))
71 return false;
72
73 for ( unsigned int i = 0; i < inCount; i++ ) {
74 if (members->getCount() < inCapacity)
75 setObject(inObjects[i]);
76 else
77 return false;
78 }
79
80 return true;
81}
82
83bool OSSet::initWithArray(const OSArray *inArray,
55e303ae 84 unsigned int inCapacity)
1c79356b
A
85{
86 if ( !inArray )
87 return false;
88
89 return initWithObjects((const OSObject **) inArray->array,
90 inArray->count, inCapacity);
91}
92
93bool OSSet::initWithSet(const OSSet *inSet,
55e303ae 94 unsigned int inCapacity)
1c79356b
A
95{
96 return initWithArray(inSet->members, inCapacity);
97}
98
99OSSet *OSSet::withCapacity(unsigned int capacity)
100{
101 OSSet *me = new OSSet;
102
103 if (me && !me->initWithCapacity(capacity)) {
55e303ae 104 me->release();
1c79356b
A
105 return 0;
106 }
107
108 return me;
109}
110
111OSSet *OSSet::withObjects(const OSObject *objects[],
112 unsigned int count,
55e303ae 113 unsigned int capacity)
1c79356b
A
114{
115 OSSet *me = new OSSet;
116
117 if (me && !me->initWithObjects(objects, count, capacity)) {
55e303ae 118 me->release();
1c79356b
A
119 return 0;
120 }
121
122 return me;
123}
124
125OSSet *OSSet::withArray(const OSArray *array,
55e303ae 126 unsigned int capacity)
1c79356b
A
127{
128 OSSet *me = new OSSet;
129
130 if (me && !me->initWithArray(array, capacity)) {
55e303ae 131 me->release();
1c79356b
A
132 return 0;
133 }
134
135 return me;
136}
137
138OSSet *OSSet::withSet(const OSSet *set,
55e303ae 139 unsigned int capacity)
1c79356b
A
140{
141 OSSet *me = new OSSet;
142
143 if (me && !me->initWithSet(set, capacity)) {
55e303ae 144 me->release();
1c79356b
A
145 return 0;
146 }
147
148 return me;
149}
150
151void OSSet::free()
152{
91447636 153 (void) members->super::setOptions(0, kImmutable);
1c79356b
A
154 if (members)
155 members->release();
156
157 super::free();
158}
159
160unsigned int OSSet::getCount() const
161{
162 return members->count;
163}
164
165unsigned int OSSet::getCapacity() const
166{
167 return members->capacity;
168}
169
170unsigned int OSSet::getCapacityIncrement() const
171{
172 return members->capacityIncrement;
173}
174
175unsigned int OSSet::setCapacityIncrement(unsigned int increment)
176{
177 return members->setCapacityIncrement(increment);
178}
179
180unsigned int OSSet::ensureCapacity(unsigned int newCapacity)
181{
182 return members->ensureCapacity(newCapacity);
183}
184
185void OSSet::flushCollection()
186{
187 haveUpdated();
188 members->flushCollection();
189}
190
191bool OSSet::setObject(const OSMetaClassBase *anObject)
192{
193 if (containsObject(anObject))
194 return false;
195 else {
196 haveUpdated();
197 return members->setObject(anObject);
198 }
199}
200
201bool OSSet::merge(const OSArray *array)
202{
203 const OSMetaClassBase *anObject;
204 bool retVal = false;
205
206 for (int i = 0; (anObject = array->getObject(i)); i++)
207 if (setObject(anObject))
208 retVal = true;
209
210 return retVal;
211}
212
213bool OSSet::merge(const OSSet *set)
214{
91447636 215 return merge(set->members);
1c79356b
A
216}
217
218void OSSet::removeObject(const OSMetaClassBase *anObject)
219{
220 const OSMetaClassBase *probeObject;
221
222 for (int i = 0; (probeObject = members->getObject(i)); i++)
223 if (probeObject == anObject) {
224 haveUpdated();
225 members->removeObject(i);
226 return;
227 }
228}
229
230
231bool OSSet::containsObject(const OSMetaClassBase *anObject) const
232{
233 return anObject && member(anObject);
234}
235
236bool OSSet::member(const OSMetaClassBase *anObject) const
237{
238 OSMetaClassBase *probeObject;
239
240 for (int i = 0; (probeObject = members->getObject(i)); i++)
241 if (probeObject == anObject)
242 return true;
243
244 return false;
245}
246
247OSObject *OSSet::getAnyObject() const
248{
249 return members->getObject(0);
250}
251
252bool OSSet::isEqualTo(const OSSet *aSet) const
253{
254 unsigned int count;
255 unsigned int i;
256 const OSMetaClassBase *obj1;
257 const OSMetaClassBase *obj2;
258
259 if ( this == aSet )
260 return true;
261
262 count = members->count;
263 if ( count != aSet->getCount() )
264 return false;
265
266 for ( i = 0; i < count; i++ ) {
267 obj1 = aSet->members->getObject(i);
268 obj2 = members->getObject(i);
269 if ( !obj1 || !obj2 )
270 return false;
271
272 if ( !obj1->isEqualTo(obj2) )
273 return false;
274 }
275
276 return true;
277}
278
279bool OSSet::isEqualTo(const OSMetaClassBase *anObject) const
280{
281 OSSet *otherSet;
282
283 otherSet = OSDynamicCast(OSSet, anObject);
284 if ( otherSet )
285 return isEqualTo(otherSet);
286 else
287 return false;
288}
289
290unsigned int OSSet::iteratorSize() const
291{
292 return sizeof(unsigned int);
293}
294
295bool OSSet::initIterator(void *inIterator) const
296{
297 unsigned int *iteratorP = (unsigned int *) inIterator;
298
299 *iteratorP = 0;
300 return true;
301}
302
303bool OSSet::getNextObjectForIterator(void *inIterator, OSObject **ret) const
304{
305 unsigned int *iteratorP = (unsigned int *) inIterator;
306 unsigned int index = (*iteratorP)++;
307
308 if (index < members->count)
309 *ret = members->getObject(index);
310 else
311 *ret = 0;
312
313 return (*ret != 0);
314}
315
316bool OSSet::serialize(OSSerialize *s) const
317{
318 const OSMetaClassBase *o;
319
320 if (s->previouslySerialized(this)) return true;
321
322 if (!s->addXMLStartTag(this, "set")) return false;
323
324 for (int i = 0; (o = members->getObject(i)); i++) {
325 if (!o->serialize(s)) return false;
326 }
327
328 return s->addXMLEndTag("set");
329}
91447636
A
330
331unsigned OSSet::setOptions(unsigned options, unsigned mask, void *)
332{
333 unsigned old = super::setOptions(options, mask);
334 if ((old ^ options) & mask)
335 members->setOptions(options, mask);
336
337 return old;
338}
339
340OSCollection * OSSet::copyCollection(OSDictionary *cycleDict)
341{
342 bool allocDict = !cycleDict;
343 OSCollection *ret = 0;
344 OSSet *newSet = 0;
345
346 if (allocDict) {
347 cycleDict = OSDictionary::withCapacity(16);
348 if (!cycleDict)
349 return 0;
350 }
351
352 do {
353 // Check for a cycle
354 ret = super::copyCollection(cycleDict);
355 if (ret)
356 continue; // Found it
357
358 newSet = OSSet::withCapacity(members->capacity);
359 if (!newSet)
360 continue; // Couldn't create new set abort
361
362 // Insert object into cycle Dictionary
363 cycleDict->setObject((const OSSymbol *) this, newSet);
364
365 OSArray *newMembers = newSet->members;
366 newMembers->capacityIncrement = members->capacityIncrement;
367
368 // Now copy over the contents into the new duplicate
369 for (unsigned int i = 0; i < members->count; i++) {
370 OSObject *obj = EXT_CAST(members->array[i]);
371 OSCollection *coll = OSDynamicCast(OSCollection, obj);
372 if (coll) {
373 OSCollection *newColl = coll->copyCollection(cycleDict);
374 if (newColl) {
375 obj = newColl; // Rely on cycleDict ref for a bit
376 newColl->release();
377 }
378 else
379 goto abortCopy;
380 };
381 newMembers->setObject(obj);
382 };
383
384 ret = newSet;
385 newSet = 0;
386
387 } while(false);
388
389abortCopy:
390 if (newSet)
391 newSet->release();
392
393 if (allocDict)
394 cycleDict->release();
395
396 return ret;
397}