2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved. 
   8  * This file contains Original Code and/or Modifications of Original Code 
   9  * as defined in and that are subject to the Apple Public Source License 
  10  * Version 2.0 (the 'License'). You may not use this file except in 
  11  * compliance with the License. Please obtain a copy of the License at 
  12  * http://www.opensource.apple.com/apsl/ and read it before using this 
  15  * The Original Code and all software distributed under the License are 
  16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  20  * Please see the License for the specific language governing rights and 
  21  * limitations under the License. 
  23  * @APPLE_LICENSE_HEADER_END@ 
  26 #include <libkern/c++/OSOrderedSet.h> 
  27 #include <libkern/c++/OSLib.h> 
  29 #define super OSCollection 
  31 OSDefineMetaClassAndStructors(OSOrderedSet
, OSCollection
) 
  32 OSMetaClassDefineReservedUnused(OSOrderedSet
, 0); 
  33 OSMetaClassDefineReservedUnused(OSOrderedSet
, 1); 
  34 OSMetaClassDefineReservedUnused(OSOrderedSet
, 2); 
  35 OSMetaClassDefineReservedUnused(OSOrderedSet
, 3); 
  36 OSMetaClassDefineReservedUnused(OSOrderedSet
, 4); 
  37 OSMetaClassDefineReservedUnused(OSOrderedSet
, 5); 
  38 OSMetaClassDefineReservedUnused(OSOrderedSet
, 6); 
  39 OSMetaClassDefineReservedUnused(OSOrderedSet
, 7); 
  43     extern int debug_container_malloc_size
; 
  45 #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0) 
  51     const OSMetaClassBase 
*             obj
; 
  57 initWithCapacity(unsigned int inCapacity
, 
  58                  OSOrderFunction inOrdering
, void *inOrderingRef
) 
  65     size 
= sizeof(_Element
) * inCapacity
; 
  66     array 
= (_Element 
*) kalloc(size
); 
  71     capacity 
= inCapacity
; 
  72     capacityIncrement 
= (inCapacity
)? inCapacity 
: 16; 
  73     ordering 
= inOrdering
; 
  74     orderingRef 
= inOrderingRef
; 
  82 OSOrderedSet 
* OSOrderedSet:: 
  83 withCapacity(unsigned int capacity
, 
  84              OSOrderFunction ordering
, void * orderingRef
) 
  86     OSOrderedSet 
*me 
= new OSOrderedSet
; 
  88     if (me 
&& !me
->initWithCapacity(capacity
, ordering
, orderingRef
)) { 
  96 void OSOrderedSet::free() 
 101         kfree((vm_offset_t
)array
, sizeof(_Element
) * capacity
); 
 102         ACCUMSIZE( -(sizeof(_Element
) * capacity
) ); 
 108 unsigned int OSOrderedSet::getCount() const { return count
; } 
 109 unsigned int OSOrderedSet::getCapacity() const { return capacity
; } 
 110 unsigned int OSOrderedSet::getCapacityIncrement() const 
 111         { return capacityIncrement
; } 
 112 unsigned int OSOrderedSet::setCapacityIncrement(unsigned int increment
) 
 114     capacityIncrement 
= (increment
)? increment 
: 16; 
 115     return capacityIncrement
; 
 118 unsigned int OSOrderedSet::ensureCapacity(unsigned int newCapacity
) 
 121     int oldSize
, newSize
; 
 123     if (newCapacity 
<= capacity
) 
 127     newCapacity 
= (((newCapacity 
- 1) / capacityIncrement
) + 1) 
 129     newSize 
= sizeof(_Element
) * newCapacity
; 
 131     newArray 
= (_Element 
*) kalloc(newSize
); 
 133         oldSize 
= sizeof(_Element
) * capacity
; 
 135         ACCUMSIZE(newSize 
- oldSize
); 
 137         bcopy(array
, newArray
, oldSize
); 
 138         bzero(&newArray
[capacity
], newSize 
- oldSize
); 
 139         kfree((vm_offset_t
)array
, oldSize
); 
 141         capacity 
= newCapacity
; 
 147 void OSOrderedSet::flushCollection() 
 153     for (i 
= 0; i 
< count
; i
++) 
 154         array
[i
].obj
->taggedRelease(OSTypeID(OSCollection
)); 
 160 bool OSOrderedSet::setObject(unsigned int index
, const OSMetaClassBase 
*anObject
) 
 163     unsigned int newCount 
= count 
+ 1; 
 165     if ((index 
> count
) || !anObject
) 
 168     if (containsObject(anObject
)) 
 171     // do we need more space? 
 172     if (newCount 
> capacity 
&& newCount 
> ensureCapacity(newCount
)) 
 176     if (index 
!= count
) { 
 177         for (i 
= count
; i 
> index
; i
--) 
 178             array
[i
] = array
[i
-1]; 
 180     array
[index
].obj 
= anObject
; 
 181 //    array[index].pri = pri; 
 182     anObject
->taggedRetain(OSTypeID(OSCollection
)); 
 189 bool OSOrderedSet::setFirstObject(const OSMetaClassBase 
*anObject
) 
 191     return( setObject(0, anObject
)); 
 194 bool OSOrderedSet::setLastObject(const OSMetaClassBase 
*anObject
) 
 196     return( setObject( count
, anObject
)); 
 200 #define ORDER(obj1,obj2) \ 
 201     (ordering ? ((*ordering)( (OSObject *) obj1, (OSObject *) obj2, orderingRef)) : 0) 
 203 bool OSOrderedSet::setObject(const OSMetaClassBase 
*anObject 
) 
 207     // queue it behind those with same priority 
 209         (i 
< count
) && (ORDER(array
[i
].obj
, anObject
) >= 0); 
 212     return( setObject(i
, anObject
)); 
 215 void OSOrderedSet::removeObject(const OSMetaClassBase 
*anObject
) 
 217     bool                deleted 
= false; 
 220     for (i 
= 0; i 
< count
; i
++) { 
 223             array
[i
-1] = array
[i
]; 
 224         else if( (array
[i
].obj 
== anObject
)) { 
 225             array
[i
].obj
->taggedRelease(OSTypeID(OSCollection
)); 
 236 bool OSOrderedSet::containsObject(const OSMetaClassBase 
*anObject
) const 
 238     return anObject 
&& member(anObject
); 
 241 bool OSOrderedSet::member(const OSMetaClassBase 
*anObject
) const 
 246         (i 
< count
) && (array
[i
].obj 
!= anObject
); 
 253 OSObject 
*OSOrderedSet::getObject( unsigned int index 
) const 
 259 //      *pri = array[index].pri; 
 261     return( (OSObject 
*) array
[index
].obj 
); 
 264 OSObject 
*OSOrderedSet::getFirstObject() const 
 267         return( (OSObject 
*) array
[0].obj 
); 
 272 OSObject 
*OSOrderedSet::getLastObject() const 
 275         return( (OSObject 
*) array
[count
-1].obj 
); 
 280 SInt32 
OSOrderedSet::orderObject( const OSMetaClassBase 
* anObject 
) 
 282     return( ORDER( anObject
, 0 )); 
 285 void *OSOrderedSet::getOrderingRef() 
 290 bool OSOrderedSet::isEqualTo(const OSOrderedSet 
*anOrderedSet
) const 
 294     if ( this == anOrderedSet 
) 
 297     if ( count 
!= anOrderedSet
->getCount() ) 
 300     for ( i 
= 0; i 
< count
; i
++ ) { 
 301         if ( !array
[i
].obj
->isEqualTo(anOrderedSet
->getObject(i
)) ) 
 308 bool OSOrderedSet::isEqualTo(const OSMetaClassBase 
*anObject
) const 
 312     oSet 
= OSDynamicCast(OSOrderedSet
, anObject
); 
 314         return isEqualTo(oSet
); 
 319 unsigned int OSOrderedSet::iteratorSize() const 
 321     return( sizeof(unsigned int)); 
 324 bool OSOrderedSet::initIterator(void *inIterator
) const 
 326     unsigned int *iteratorP 
= (unsigned int *) inIterator
; 
 333 getNextObjectForIterator(void *inIterator
, OSObject 
**ret
) const 
 335     unsigned int *iteratorP 
= (unsigned int *) inIterator
; 
 336     unsigned int index 
= (*iteratorP
)++; 
 339         *ret 
= (OSObject 
*) array
[index
].obj
;