2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * The contents of this file constitute Original Code as defined in and 
   7  * are subject to the Apple Public Source License Version 1.1 (the 
   8  * "License").  You may not use this file except in compliance with the 
   9  * License.  Please obtain a copy of the License at 
  10  * http://www.apple.com/publicsource and read it before using this file. 
  12  * This Original Code and all software distributed under the License are 
  13  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  14  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  15  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  16  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the 
  17  * License for the specific language governing rights and limitations 
  20  * @APPLE_LICENSE_HEADER_END@ 
  23 #include <libkern/c++/OSOrderedSet.h> 
  24 #include <libkern/c++/OSLib.h> 
  26 #define super OSCollection 
  28 OSDefineMetaClassAndStructors(OSOrderedSet
, OSCollection
) 
  29 OSMetaClassDefineReservedUnused(OSOrderedSet
, 0); 
  30 OSMetaClassDefineReservedUnused(OSOrderedSet
, 1); 
  31 OSMetaClassDefineReservedUnused(OSOrderedSet
, 2); 
  32 OSMetaClassDefineReservedUnused(OSOrderedSet
, 3); 
  33 OSMetaClassDefineReservedUnused(OSOrderedSet
, 4); 
  34 OSMetaClassDefineReservedUnused(OSOrderedSet
, 5); 
  35 OSMetaClassDefineReservedUnused(OSOrderedSet
, 6); 
  36 OSMetaClassDefineReservedUnused(OSOrderedSet
, 7); 
  40     extern int debug_container_malloc_size
; 
  42 #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0) 
  48     const OSMetaClassBase 
*             obj
; 
  54 initWithCapacity(unsigned int inCapacity
, 
  55                  OSOrderFunction inOrdering
, void *inOrderingRef
) 
  62     size 
= sizeof(_Element
) * inCapacity
; 
  63     array 
= (_Element 
*) kalloc(size
); 
  68     capacity 
= inCapacity
; 
  69     capacityIncrement 
= (inCapacity
)? inCapacity 
: 16; 
  70     ordering 
= inOrdering
; 
  71     orderingRef 
= inOrderingRef
; 
  79 OSOrderedSet 
* OSOrderedSet:: 
  80 withCapacity(unsigned int capacity
, 
  81              OSOrderFunction ordering
, void * orderingRef
) 
  83     OSOrderedSet 
*me 
= new OSOrderedSet
; 
  85     if (me 
&& !me
->initWithCapacity(capacity
, ordering
, orderingRef
)) { 
  93 void OSOrderedSet::free() 
  98         kfree((vm_offset_t
)array
, sizeof(_Element
) * capacity
); 
  99         ACCUMSIZE( -(sizeof(_Element
) * capacity
) ); 
 105 unsigned int OSOrderedSet::getCount() const { return count
; } 
 106 unsigned int OSOrderedSet::getCapacity() const { return capacity
; } 
 107 unsigned int OSOrderedSet::getCapacityIncrement() const 
 108         { return capacityIncrement
; } 
 109 unsigned int OSOrderedSet::setCapacityIncrement(unsigned int increment
) 
 111     capacityIncrement 
= (increment
)? increment 
: 16; 
 112     return capacityIncrement
; 
 115 unsigned int OSOrderedSet::ensureCapacity(unsigned int newCapacity
) 
 118     int oldSize
, newSize
; 
 120     if (newCapacity 
<= capacity
) 
 124     newCapacity 
= (((newCapacity 
- 1) / capacityIncrement
) + 1) 
 126     newSize 
= sizeof(_Element
) * newCapacity
; 
 128     newArray 
= (_Element 
*) kalloc(newSize
); 
 130         oldSize 
= sizeof(_Element
) * capacity
; 
 132         ACCUMSIZE(newSize 
- oldSize
); 
 134         bcopy(array
, newArray
, oldSize
); 
 135         bzero(&newArray
[capacity
], newSize 
- oldSize
); 
 136         kfree((vm_offset_t
)array
, oldSize
); 
 138         capacity 
= newCapacity
; 
 144 void OSOrderedSet::flushCollection() 
 150     for (i 
= 0; i 
< count
; i
++) 
 151         array
[i
].obj
->taggedRelease(OSTypeID(OSCollection
)); 
 157 bool OSOrderedSet::setObject(unsigned int index
, const OSMetaClassBase 
*anObject
) 
 160     unsigned int newCount 
= count 
+ 1; 
 162     if ((index 
> count
) || !anObject
) 
 165     if (containsObject(anObject
)) 
 168     // do we need more space? 
 169     if (newCount 
> capacity 
&& newCount 
> ensureCapacity(newCount
)) 
 173     if (index 
!= count
) { 
 174         for (i 
= count
; i 
> index
; i
--) 
 175             array
[i
] = array
[i
-1]; 
 177     array
[index
].obj 
= anObject
; 
 178 //    array[index].pri = pri; 
 179     anObject
->taggedRetain(OSTypeID(OSCollection
)); 
 186 bool OSOrderedSet::setFirstObject(const OSMetaClassBase 
*anObject
) 
 188     return( setObject(0, anObject
)); 
 191 bool OSOrderedSet::setLastObject(const OSMetaClassBase 
*anObject
) 
 193     return( setObject( count
, anObject
)); 
 197 #define ORDER(obj1,obj2) \ 
 198     (ordering ? ((*ordering)( (OSObject *) obj1, (OSObject *) obj2, orderingRef)) : 0) 
 200 bool OSOrderedSet::setObject(const OSMetaClassBase 
*anObject 
) 
 204     // queue it behind those with same priority 
 206         (i 
< count
) && (ORDER(array
[i
].obj
, anObject
) >= 0); 
 209     return( setObject(i
, anObject
)); 
 212 void OSOrderedSet::removeObject(const OSMetaClassBase 
*anObject
) 
 214     bool                deleted 
= false; 
 217     for (i 
= 0; i 
< count
; i
++) { 
 220             array
[i
-1] = array
[i
]; 
 221         else if( (array
[i
].obj 
== anObject
)) { 
 222             array
[i
].obj
->taggedRelease(OSTypeID(OSCollection
)); 
 233 bool OSOrderedSet::containsObject(const OSMetaClassBase 
*anObject
) const 
 235     return anObject 
&& member(anObject
); 
 238 bool OSOrderedSet::member(const OSMetaClassBase 
*anObject
) const 
 243         (i 
< count
) && (array
[i
].obj 
!= anObject
); 
 250 OSObject 
*OSOrderedSet::getObject( unsigned int index 
) const 
 256 //      *pri = array[index].pri; 
 258     return( (OSObject 
*) array
[index
].obj 
); 
 261 OSObject 
*OSOrderedSet::getFirstObject() const 
 264         return( (OSObject 
*) array
[0].obj 
); 
 269 OSObject 
*OSOrderedSet::getLastObject() const 
 272         return( (OSObject 
*) array
[count
-1].obj 
); 
 277 SInt32 
OSOrderedSet::orderObject( const OSMetaClassBase 
* anObject 
) 
 279     return( ORDER( anObject
, 0 )); 
 282 void *OSOrderedSet::getOrderingRef() 
 287 bool OSOrderedSet::isEqualTo(const OSOrderedSet 
*anOrderedSet
) const 
 291     if ( this == anOrderedSet 
) 
 294     if ( count 
!= anOrderedSet
->getCount() ) 
 297     for ( i 
= 0; i 
< count
; i
++ ) { 
 298         if ( !array
[i
].obj
->isEqualTo(anOrderedSet
->getObject(i
)) ) 
 305 bool OSOrderedSet::isEqualTo(const OSMetaClassBase 
*anObject
) const 
 309     oSet 
= OSDynamicCast(OSOrderedSet
, anObject
); 
 311         return isEqualTo(oSet
); 
 316 unsigned int OSOrderedSet::iteratorSize() const 
 318     return( sizeof(unsigned int)); 
 321 bool OSOrderedSet::initIterator(void *inIterator
) const 
 323     unsigned int *iteratorP 
= (unsigned int *) inIterator
; 
 330 getNextObjectForIterator(void *inIterator
, OSObject 
**ret
) const 
 332     unsigned int *iteratorP 
= (unsigned int *) inIterator
; 
 333     unsigned int index 
= (*iteratorP
)++; 
 336         *ret 
= (OSObject 
*) array
[index
].obj
;