]>
git.saurik.com Git - apple/xnu.git/blob - libkern/c++/OSSet.cpp
775253bafe7b67b7e43bcb15a39df0bc929e7b9a
   2  * Copyright (c) 2000 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)) 
  50 bool OSSet::initWithCapacity(unsigned int inCapacity
) 
  55     members 
= OSArray::withCapacity(inCapacity
); 
  62 bool OSSet::initWithObjects(const OSObject 
*inObjects
[], 
  64                               unsigned int inCapacity
) 
  66     unsigned int capacity 
= inCount
; 
  69         if ( inCount 
> inCapacity 
) 
  72         capacity 
= inCapacity
; 
  75     if (!inObjects 
|| !initWithCapacity(capacity
)) 
  78     for ( unsigned int i 
= 0; i 
< inCount
; i
++ ) { 
  79 // xx-review: no test here for failure of setObject() 
  80         if (members
->getCount() < inCapacity
) 
  81             setObject(inObjects
[i
]); 
  89 bool OSSet::initWithArray(const OSArray 
*inArray
, 
  90                           unsigned int inCapacity
) 
  95     return initWithObjects((const OSObject 
**) inArray
->array
, 
  96                            inArray
->count
, inCapacity
); 
  99 bool OSSet::initWithSet(const OSSet 
*inSet
, 
 100                         unsigned int inCapacity
) 
 102     return initWithArray(inSet
->members
, inCapacity
); 
 105 OSSet 
*OSSet::withCapacity(unsigned int capacity
) 
 107     OSSet 
*me 
= new OSSet
; 
 109     if (me 
&& !me
->initWithCapacity(capacity
)) { 
 117 OSSet 
*OSSet::withObjects(const OSObject 
*objects
[], 
 119                           unsigned int capacity
) 
 121     OSSet 
*me 
= new OSSet
; 
 123     if (me 
&& !me
->initWithObjects(objects
, count
, capacity
)) { 
 131 OSSet 
*OSSet::withArray(const OSArray 
*array
, 
 132                         unsigned int capacity
) 
 134     OSSet 
*me 
= new OSSet
; 
 136     if (me 
&& !me
->initWithArray(array
, capacity
)) { 
 144 OSSet 
*OSSet::withSet(const OSSet 
*set
, 
 145                       unsigned int capacity
) 
 147     OSSet 
*me 
= new OSSet
; 
 149     if (me 
&& !me
->initWithSet(set
, capacity
)) { 
 159     (void) members
->super::setOptions(0, kImmutable
); 
 166 unsigned int OSSet::getCount() const 
 168     return members
->count
; 
 171 unsigned int OSSet::getCapacity() const 
 173     return members
->capacity
; 
 176 unsigned int OSSet::getCapacityIncrement() const 
 178     return members
->capacityIncrement
; 
 181 unsigned int OSSet::setCapacityIncrement(unsigned int increment
) 
 183     return members
->setCapacityIncrement(increment
); 
 186 unsigned int OSSet::ensureCapacity(unsigned int newCapacity
) 
 188     return members
->ensureCapacity(newCapacity
); 
 191 void OSSet::flushCollection() 
 194     members
->flushCollection(); 
 197 bool OSSet::setObject(const OSMetaClassBase 
*anObject
) 
 199     if (containsObject(anObject
)) { 
 203         return members
->setObject(anObject
); 
 207 bool OSSet::merge(const OSArray 
* array
) 
 209     const OSMetaClassBase 
* anObject 
= 0; 
 212     for (int i 
= 0; (anObject 
= array
->getObject(i
)); i
++) { 
 214        /* setObject() returns false if the object is already in the set, 
 215         * so we have to check beforehand here with containsObject(). 
 217         if (containsObject(anObject
)) { 
 220         if (!setObject(anObject
)) { 
 228 bool OSSet::merge(const OSSet 
* set
) 
 230     return merge(set
->members
); 
 233 void OSSet::removeObject(const OSMetaClassBase 
*anObject
) 
 235     const OSMetaClassBase 
*probeObject
; 
 237     for (int i 
= 0; (probeObject 
= members
->getObject(i
)); i
++) 
 238         if (probeObject 
== anObject
) { 
 240             members
->removeObject(i
); 
 246 bool OSSet::containsObject(const OSMetaClassBase 
*anObject
) const 
 248     return anObject 
&& member(anObject
); 
 251 bool OSSet::member(const OSMetaClassBase 
*anObject
) const 
 253     OSMetaClassBase 
*probeObject
; 
 255     for (int i 
= 0; (probeObject 
= members
->getObject(i
)); i
++) 
 256         if (probeObject 
== anObject
) 
 262 OSObject 
*OSSet::getAnyObject() const 
 264     return members
->getObject(0); 
 267 bool OSSet::isEqualTo(const OSSet 
*aSet
) const 
 271     const OSMetaClassBase 
*obj1
; 
 272     const OSMetaClassBase 
*obj2
; 
 277     count 
= members
->count
; 
 278     if ( count 
!= aSet
->getCount() ) 
 281     for ( i 
= 0; i 
< count
; i
++ ) { 
 282         obj1 
= aSet
->members
->getObject(i
); 
 283         if (containsObject(obj1
)) 
 285         obj2 
= members
->getObject(i
); 
 286         if ( !obj1 
|| !obj2 
) 
 289         if ( !obj1
->isEqualTo(obj2
) ) 
 296 bool OSSet::isEqualTo(const OSMetaClassBase 
*anObject
) const 
 300     otherSet 
= OSDynamicCast(OSSet
, anObject
); 
 302         return isEqualTo(otherSet
); 
 307 unsigned int OSSet::iteratorSize() const 
 309     return sizeof(unsigned int); 
 312 bool OSSet::initIterator(void *inIterator
) const 
 314     unsigned int *iteratorP 
= (unsigned int *) inIterator
; 
 320 bool OSSet::getNextObjectForIterator(void *inIterator
, OSObject 
**ret
) const 
 322     unsigned int *iteratorP 
= (unsigned int *) inIterator
; 
 323     unsigned int index 
= (*iteratorP
)++; 
 325     if (index 
< members
->count
) 
 326         *ret 
= members
->getObject(index
); 
 333 bool OSSet::serialize(OSSerialize 
*s
) const 
 335     const OSMetaClassBase 
*o
; 
 337     if (s
->previouslySerialized(this)) return true;    
 339     if (!s
->addXMLStartTag(this, "set")) return false; 
 341     for (int i 
= 0; (o 
= members
->getObject(i
)); i
++) { 
 342         if (!o
->serialize(s
)) return false; 
 345     return s
->addXMLEndTag("set"); 
 348 unsigned OSSet::setOptions(unsigned options
, unsigned mask
, void *) 
 350     unsigned old 
= super::setOptions(options
, mask
); 
 351     if ((old 
^ options
) & mask
) 
 352         members
->setOptions(options
, mask
); 
 357 OSCollection 
* OSSet::copyCollection(OSDictionary 
*cycleDict
) 
 359     bool allocDict 
= !cycleDict
; 
 360     OSCollection 
*ret 
= 0; 
 364         cycleDict 
= OSDictionary::withCapacity(16); 
 371         ret 
= super::copyCollection(cycleDict
); 
 373             continue;   // Found it 
 375         newSet 
= OSSet::withCapacity(members
->capacity
); 
 377             continue;   // Couldn't create new set abort 
 379         // Insert object into cycle Dictionary 
 380         cycleDict
->setObject((const OSSymbol 
*) this, newSet
); 
 382         OSArray 
*newMembers 
= newSet
->members
; 
 383         newMembers
->capacityIncrement 
= members
->capacityIncrement
; 
 385         // Now copy over the contents into the new duplicate 
 386         for (unsigned int i 
= 0; i 
< members
->count
; i
++) { 
 387             OSObject 
*obj 
= EXT_CAST(members
->array
[i
]); 
 388             OSCollection 
*coll 
= OSDynamicCast(OSCollection
, obj
); 
 390                 OSCollection 
*newColl 
= coll
->copyCollection(cycleDict
); 
 392                     obj 
= newColl
;      // Rely on cycleDict ref for a bit 
 398             newMembers
->setObject(obj
); 
 411         cycleDict
->release();