]>
git.saurik.com Git - apple/xnu.git/blob - libkern/c++/OSSet.cpp
3c7701dcf4abe9970fb98bd687d306676a7dfb4d
2 * Copyright (c) 2000, 2014 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 /* IOSet.m created by rsulack on Thu 11-Jun-1998 */
30 #include <libkern/c++/OSDictionary.h>
31 #include <libkern/c++/OSArray.h>
32 #include <libkern/c++/OSSerialize.h>
33 #include <libkern/c++/OSSet.h>
35 #define super OSCollection
37 OSDefineMetaClassAndStructors(OSSet
, OSCollection
)
38 OSMetaClassDefineReservedUnused(OSSet
, 0);
39 OSMetaClassDefineReservedUnused(OSSet
, 1);
40 OSMetaClassDefineReservedUnused(OSSet
, 2);
41 OSMetaClassDefineReservedUnused(OSSet
, 3);
42 OSMetaClassDefineReservedUnused(OSSet
, 4);
43 OSMetaClassDefineReservedUnused(OSSet
, 5);
44 OSMetaClassDefineReservedUnused(OSSet
, 6);
45 OSMetaClassDefineReservedUnused(OSSet
, 7);
47 #define EXT_CAST(obj) \
48 reinterpret_cast<OSObject *>(const_cast<OSMetaClassBase *>(obj))
51 OSSet::initWithCapacity(unsigned int inCapacity
)
57 members
= OSArray::withCapacity(inCapacity
);
66 OSSet::initWithObjects(const OSObject
*inObjects
[],
68 unsigned int inCapacity
)
70 unsigned int capacity
= inCount
;
73 if (inCount
> inCapacity
) {
77 capacity
= inCapacity
;
80 if (!inObjects
|| !initWithCapacity(capacity
)) {
84 for (unsigned int i
= 0; i
< inCount
; i
++) {
85 // xx-review: no test here for failure of setObject()
86 if (members
->getCount() < capacity
) {
87 setObject(inObjects
[i
]);
97 OSSet::initWithArray(const OSArray
*inArray
,
98 unsigned int inCapacity
)
104 return initWithObjects((const OSObject
**) inArray
->array
,
105 inArray
->count
, inCapacity
);
109 OSSet::initWithSet(const OSSet
*inSet
,
110 unsigned int inCapacity
)
112 return initWithArray(inSet
->members
, inCapacity
);
116 OSSet::withCapacity(unsigned int capacity
)
118 OSSet
*me
= new OSSet
;
120 if (me
&& !me
->initWithCapacity(capacity
)) {
129 OSSet::withObjects(const OSObject
*objects
[],
131 unsigned int capacity
)
133 OSSet
*me
= new OSSet
;
135 if (me
&& !me
->initWithObjects(objects
, count
, capacity
)) {
144 OSSet::withArray(const OSArray
*array
,
145 unsigned int capacity
)
147 OSSet
*me
= new OSSet
;
149 if (me
&& !me
->initWithArray(array
, capacity
)) {
158 OSSet::withSet(const OSSet
*set
,
159 unsigned int capacity
)
161 OSSet
*me
= new OSSet
;
163 if (me
&& !me
->initWithSet(set
, capacity
)) {
175 (void) members
->super::setOptions(0, kImmutable
);
183 OSSet::getCount() const
185 return members
->count
;
189 OSSet::getCapacity() const
191 return members
->capacity
;
195 OSSet::getCapacityIncrement() const
197 return members
->capacityIncrement
;
201 OSSet::setCapacityIncrement(unsigned int increment
)
203 return members
->setCapacityIncrement(increment
);
207 OSSet::ensureCapacity(unsigned int newCapacity
)
209 return members
->ensureCapacity(newCapacity
);
213 OSSet::flushCollection()
216 members
->flushCollection();
220 OSSet::setObject(const OSMetaClassBase
*anObject
)
222 if (containsObject(anObject
)) {
226 return members
->setObject(anObject
);
231 OSSet::merge(const OSArray
* array
)
233 const OSMetaClassBase
* anObject
= 0;
236 for (int i
= 0; (anObject
= array
->getObject(i
)); i
++) {
237 /* setObject() returns false if the object is already in the set,
238 * so we have to check beforehand here with containsObject().
240 if (containsObject(anObject
)) {
243 if (!setObject(anObject
)) {
252 OSSet::merge(const OSSet
* set
)
254 return merge(set
->members
);
258 OSSet::removeObject(const OSMetaClassBase
*anObject
)
260 const OSMetaClassBase
*probeObject
;
262 for (int i
= 0; (probeObject
= members
->getObject(i
)); i
++) {
263 if (probeObject
== anObject
) {
265 members
->removeObject(i
);
273 OSSet::containsObject(const OSMetaClassBase
*anObject
) const
275 return anObject
&& member(anObject
);
279 OSSet::member(const OSMetaClassBase
*anObject
) const
281 OSMetaClassBase
*probeObject
;
283 for (int i
= 0; (probeObject
= members
->getObject(i
)); i
++) {
284 if (probeObject
== anObject
) {
293 OSSet::getAnyObject() const
295 return members
->getObject(0);
299 OSSet::isEqualTo(const OSSet
*aSet
) const
303 const OSMetaClassBase
*obj1
;
304 const OSMetaClassBase
*obj2
;
310 count
= members
->count
;
311 if (count
!= aSet
->getCount()) {
315 for (i
= 0; i
< count
; i
++) {
316 obj1
= aSet
->members
->getObject(i
);
317 if (containsObject(obj1
)) {
320 obj2
= members
->getObject(i
);
321 if (!obj1
|| !obj2
) {
325 if (!obj1
->isEqualTo(obj2
)) {
334 OSSet::isEqualTo(const OSMetaClassBase
*anObject
) const
338 otherSet
= OSDynamicCast(OSSet
, anObject
);
340 return isEqualTo(otherSet
);
347 OSSet::iteratorSize() const
349 return sizeof(unsigned int);
353 OSSet::initIterator(void *inIterator
) const
355 unsigned int *iteratorP
= (unsigned int *) inIterator
;
362 OSSet::getNextObjectForIterator(void *inIterator
, OSObject
**ret
) const
364 unsigned int *iteratorP
= (unsigned int *) inIterator
;
365 unsigned int index
= (*iteratorP
)++;
367 if (index
< members
->count
) {
368 *ret
= members
->getObject(index
);
377 OSSet::serialize(OSSerialize
*s
) const
379 const OSMetaClassBase
*o
;
381 if (s
->previouslySerialized(this)) {
385 if (!s
->addXMLStartTag(this, "set")) {
389 for (int i
= 0; (o
= members
->getObject(i
)); i
++) {
390 if (!o
->serialize(s
)) {
395 return s
->addXMLEndTag("set");
399 OSSet::setOptions(unsigned options
, unsigned mask
, void *)
401 unsigned old
= super::setOptions(options
, mask
);
402 if ((old
^ options
) & mask
) {
403 members
->setOptions(options
, mask
);
410 OSSet::copyCollection(OSDictionary
*cycleDict
)
412 bool allocDict
= !cycleDict
;
413 OSCollection
*ret
= 0;
417 cycleDict
= OSDictionary::withCapacity(16);
425 ret
= super::copyCollection(cycleDict
);
427 continue; // Found it
429 newSet
= OSSet::withCapacity(members
->capacity
);
431 continue; // Couldn't create new set abort
433 // Insert object into cycle Dictionary
434 cycleDict
->setObject((const OSSymbol
*) this, newSet
);
436 OSArray
*newMembers
= newSet
->members
;
437 newMembers
->capacityIncrement
= members
->capacityIncrement
;
439 // Now copy over the contents into the new duplicate
440 for (unsigned int i
= 0; i
< members
->count
; i
++) {
441 OSObject
*obj
= EXT_CAST(members
->array
[i
]);
442 OSCollection
*coll
= OSDynamicCast(OSCollection
, obj
);
444 OSCollection
*newColl
= coll
->copyCollection(cycleDict
);
446 obj
= newColl
; // Rely on cycleDict ref for a bit
453 newMembers
->setObject(obj
);
467 cycleDict
->release();