]>
git.saurik.com Git - apple/xnu.git/blob - libkern/c++/OSArray.cpp
fcdca78d14a360f31ab04062ef75c47cb03fe7bc
   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 /* IOArray.m created by rsulack on Fri 12-Sep-1997 */ 
  29 /* IOArray.cpp converted to C++ by gvdl on Fri 1998-10-30 */ 
  32 #include <libkern/c++/OSArray.h> 
  33 #include <libkern/c++/OSDictionary.h> 
  34 #include <libkern/c++/OSSerialize.h> 
  35 #include <libkern/c++/OSLib.h> 
  36 #include <libkern/OSDebug.h> 
  38 #define super OSCollection 
  40 OSDefineMetaClassAndStructors(OSArray
, OSCollection
) 
  41 OSMetaClassDefineReservedUnused(OSArray
, 0); 
  42 OSMetaClassDefineReservedUnused(OSArray
, 1); 
  43 OSMetaClassDefineReservedUnused(OSArray
, 2); 
  44 OSMetaClassDefineReservedUnused(OSArray
, 3); 
  45 OSMetaClassDefineReservedUnused(OSArray
, 4); 
  46 OSMetaClassDefineReservedUnused(OSArray
, 5); 
  47 OSMetaClassDefineReservedUnused(OSArray
, 6); 
  48 OSMetaClassDefineReservedUnused(OSArray
, 7); 
  51 #define EXT_CAST(obj) \ 
  52     reinterpret_cast<OSObject *>(const_cast<OSMetaClassBase *>(obj)) 
  54 bool OSArray::initWithCapacity(unsigned int inCapacity
) 
  61     // integer overflow check 
  62     if (inCapacity 
> (UINT_MAX 
/ sizeof(const OSMetaClassBase
*))) 
  65     size 
= sizeof(const OSMetaClassBase 
*) * inCapacity
; 
  66     array 
= (const OSMetaClassBase 
**) kalloc_container(size
); 
  71     capacity 
= inCapacity
; 
  72     capacityIncrement 
= (inCapacity
)? inCapacity 
: 16; 
  75     OSCONTAINER_ACCUMSIZE(size
); 
  80 bool OSArray::initWithObjects(const OSObject 
*objects
[], 
  81                               unsigned int theCount
, 
  82                               unsigned int theCapacity
) 
  84     unsigned int initCapacity
; 
  87         initCapacity 
= theCount
; 
  88     else if (theCount 
> theCapacity
) 
  91         initCapacity 
= theCapacity
; 
  93     if (!objects 
|| !initWithCapacity(initCapacity
)) 
  96     for ( unsigned int i 
= 0; i 
< theCount
; i
++ ) { 
  97         const OSMetaClassBase 
*newObject 
= *objects
++; 
 102         array
[count
++] = newObject
; 
 103         newObject
->taggedRetain(OSTypeID(OSCollection
)); 
 109 bool OSArray::initWithArray(const OSArray 
*anArray
, 
 110                             unsigned int theCapacity
) 
 115     return initWithObjects((const OSObject 
**) anArray
->array
, 
 116                            anArray
->count
, theCapacity
); 
 119 OSArray 
*OSArray::withCapacity(unsigned int capacity
) 
 121     OSArray 
*me 
= new OSArray
; 
 123     if (me 
&& !me
->initWithCapacity(capacity
)) { 
 131 OSArray 
*OSArray::withObjects(const OSObject 
*objects
[], 
 133                               unsigned int capacity
) 
 135     OSArray 
*me 
= new OSArray
; 
 137     if (me 
&& !me
->initWithObjects(objects
, count
, capacity
)) { 
 145 OSArray 
*OSArray::withArray(const OSArray 
*array
, 
 146                             unsigned int capacity
) 
 148     OSArray 
*me 
= new OSArray
; 
 150     if (me 
&& !me
->initWithArray(array
, capacity
)) { 
 160     // Clear immutability - assumes the container is doing the right thing 
 161     (void) super::setOptions(0, kImmutable
); 
 166         kfree(array
, sizeof(const OSMetaClassBase 
*) * capacity
); 
 167         OSCONTAINER_ACCUMSIZE( -(sizeof(const OSMetaClassBase 
*) * capacity
) ); 
 174 unsigned int OSArray::getCount() const { return count
; } 
 175 unsigned int OSArray::getCapacity() const { return capacity
; } 
 176 unsigned int OSArray::getCapacityIncrement() const { return capacityIncrement
; } 
 177 unsigned int OSArray::setCapacityIncrement(unsigned int increment
) 
 179     capacityIncrement 
= (increment
)? increment 
: 16; 
 181     return capacityIncrement
; 
 184 unsigned int OSArray::ensureCapacity(unsigned int newCapacity
) 
 186     const OSMetaClassBase 
**newArray
; 
 187     unsigned int finalCapacity
; 
 188     unsigned int oldSize
, newSize
; 
 190     if (newCapacity 
<= capacity
) 
 194     finalCapacity 
= (((newCapacity 
- 1) / capacityIncrement
) + 1) 
 197     // integer overflow check 
 198     if ((finalCapacity 
< newCapacity
) || (finalCapacity 
> (UINT_MAX 
/ sizeof(const OSMetaClassBase
*)))) 
 201     newSize 
= sizeof(const OSMetaClassBase 
*) * finalCapacity
; 
 203     newArray 
= (const OSMetaClassBase 
**) kalloc_container(newSize
); 
 205         oldSize 
= sizeof(const OSMetaClassBase 
*) * capacity
; 
 207         OSCONTAINER_ACCUMSIZE(((size_t)newSize
) - ((size_t)oldSize
)); 
 209         bcopy(array
, newArray
, oldSize
); 
 210         bzero(&newArray
[capacity
], newSize 
- oldSize
); 
 211         kfree(array
, oldSize
); 
 213         capacity 
= finalCapacity
; 
 219 void OSArray::flushCollection() 
 224     for (i 
= 0; i 
< count
; i
++) { 
 225         array
[i
]->taggedRelease(OSTypeID(OSCollection
)); 
 230 bool OSArray::setObject(const OSMetaClassBase 
*anObject
) 
 232     return setObject(count
, anObject
); 
 235 bool OSArray::setObject(unsigned int index
, const OSMetaClassBase 
*anObject
) 
 238     unsigned int newCount 
= count 
+ 1; 
 240     if ((index 
> count
) || !anObject
) 
 243     // do we need more space? 
 244     if (newCount 
> capacity 
&& newCount 
> ensureCapacity(newCount
)) 
 248     if (index 
!= count
) { 
 249         for (i 
= count
; i 
> index
; i
--) 
 250             array
[i
] = array
[i
-1]; 
 252     array
[index
] = anObject
; 
 253     anObject
->taggedRetain(OSTypeID(OSCollection
)); 
 259 bool OSArray::merge(const OSArray 
* otherArray
) 
 261     unsigned int otherCount 
= otherArray
->getCount(); 
 262     unsigned int newCount 
= count 
+ otherCount
; 
 267     // do we need more space? 
 268     if (newCount 
> capacity 
&& newCount 
> ensureCapacity(newCount
)) 
 272     for (unsigned int i 
= 0; i 
< otherCount
; i
++) { 
 273         const OSMetaClassBase 
*newObject 
= otherArray
->getObject(i
); 
 275         array
[count
++] = newObject
; 
 276         newObject
->taggedRetain(OSTypeID(OSCollection
)); 
 283 replaceObject(unsigned int index
, const OSMetaClassBase 
*anObject
) 
 285     const OSMetaClassBase 
*oldObject
; 
 287     if ((index 
>= count
) || !anObject
) 
 291     oldObject 
= array
[index
]; 
 292     array
[index
] = anObject
; 
 293     anObject
->taggedRetain(OSTypeID(OSCollection
)); 
 295     oldObject
->taggedRelease(OSTypeID(OSCollection
)); 
 298 void OSArray::removeObject(unsigned int index
) 
 301     const OSMetaClassBase 
*oldObject
; 
 307     oldObject 
= array
[index
]; 
 310     for (i 
= index
; i 
< count
; i
++) 
 311         array
[i
] = array
[i
+1]; 
 313     oldObject
->taggedRelease(OSTypeID(OSCollection
)); 
 316 bool OSArray::isEqualTo(const OSArray 
*anArray
) const 
 320     if ( this == anArray 
) 
 323     if ( count 
!= anArray
->getCount() ) 
 326     for ( i 
= 0; i 
< count
; i
++ ) { 
 327         if ( !array
[i
]->isEqualTo(anArray
->getObject(i
)) ) 
 334 bool OSArray::isEqualTo(const OSMetaClassBase 
*anObject
) const 
 338     otherArray 
= OSDynamicCast(OSArray
, anObject
); 
 340         return isEqualTo(otherArray
); 
 345 OSObject 
*OSArray::getObject(unsigned int index
) const 
 350         return (OSObject 
*) (const_cast<OSMetaClassBase 
*>(array
[index
])); 
 353 OSObject 
*OSArray::getLastObject() const 
 358         return ( OSObject 
*) (const_cast<OSMetaClassBase 
*>(array
[count 
- 1])); 
 361 unsigned int OSArray::getNextIndexOfObject(const OSMetaClassBase 
* anObject
, 
 362                                             unsigned int index
) const 
 364     while ((index 
< count
) && (array
[index
] != anObject
)) 
 367         index 
= (unsigned int)-1; 
 371 unsigned int OSArray::iteratorSize() const 
 373     return sizeof(unsigned int); 
 376 bool OSArray::initIterator(void *inIterator
) const 
 378     unsigned int *iteratorP 
= (unsigned int *) inIterator
; 
 384 bool OSArray::getNextObjectForIterator(void *inIterator
, OSObject 
**ret
) const 
 386     unsigned int *iteratorP 
= (unsigned int *) inIterator
; 
 387     unsigned int index 
= (*iteratorP
)++; 
 390         *ret 
= (OSObject 
*)(const_cast<OSMetaClassBase 
*> (array
[index
])); 
 399 bool OSArray::serialize(OSSerialize 
*s
) const 
 401     if (s
->previouslySerialized(this)) return true; 
 403     if (!s
->addXMLStartTag(this, "array")) return false; 
 405     for (unsigned i 
= 0; i 
< count
; i
++) { 
 406         if (array
[i
] == NULL 
|| !array
[i
]->serialize(s
)) return false; 
 409     return s
->addXMLEndTag("array"); 
 412 unsigned OSArray::setOptions(unsigned options
, unsigned mask
, void *) 
 414     unsigned old 
= super::setOptions(options
, mask
); 
 415     if ((old 
^ options
) & mask
) { 
 417         // Value changed need to recurse over all of the child collections 
 418         for ( unsigned i 
= 0; i 
< count
; i
++ ) { 
 419             OSCollection 
*coll 
= OSDynamicCast(OSCollection
, array
[i
]); 
 421                 coll
->setOptions(options
, mask
); 
 428 OSCollection 
* OSArray::copyCollection(OSDictionary 
*cycleDict
) 
 430     bool allocDict 
= !cycleDict
; 
 431     OSCollection 
*ret 
= 0; 
 432     OSArray 
*newArray 
= 0; 
 435         cycleDict 
= OSDictionary::withCapacity(16); 
 442         ret 
= super::copyCollection(cycleDict
); 
 446         newArray 
= OSArray::withArray(this); 
 450         // Insert object into cycle Dictionary 
 451         cycleDict
->setObject((const OSSymbol 
*) this, newArray
); 
 453         for (unsigned int i 
= 0; i 
< count
; i
++) { 
 455                 OSDynamicCast(OSCollection
, EXT_CAST(newArray
->array
[i
])); 
 458                 OSCollection 
*newColl 
= coll
->copyCollection(cycleDict
); 
 462                 newArray
->replaceObject(i
, newColl
); 
 477         cycleDict
->release();