|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 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. ! 11: * ! 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 ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: ! 23: #include <libkern/c++/OSOrderedSet.h> ! 24: #include <libkern/c++/OSLib.h> ! 25: ! 26: #define super OSCollection ! 27: ! 28: OSDefineMetaClassAndStructors(OSOrderedSet, OSCollection) ! 29: ! 30: #ifdef DEBUG ! 31: extern "C" { ! 32: extern int debug_container_malloc_size; ! 33: }; ! 34: #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0) ! 35: #else ! 36: #define ACCUMSIZE(s) ! 37: #endif ! 38: ! 39: struct _Element { ! 40: OSObject * obj; ! 41: // unsigned int pri; ! 42: }; ! 43: ! 44: ! 45: bool OSOrderedSet::initWithCapacity(unsigned int inCapacity, ! 46: OSOrderFunction ordering, void * orderingRef) ! 47: { ! 48: int size; ! 49: ! 50: if (!super::init()) ! 51: return false; ! 52: ! 53: size = sizeof(_Element) * inCapacity; ! 54: array = (_Element *) kalloc(size); ! 55: if (!array) ! 56: return false; ! 57: ! 58: count = 0; ! 59: capacity = inCapacity; ! 60: capacityIncrement = capacity; ! 61: this->ordering = ordering; ! 62: this->orderingRef = orderingRef; ! 63: ! 64: bzero(array, size); ! 65: ACCUMSIZE(size); ! 66: ! 67: return this; ! 68: } ! 69: ! 70: OSOrderedSet * OSOrderedSet::withCapacity(unsigned int capacity, ! 71: OSOrderFunction ordering, void * orderingRef) ! 72: { ! 73: OSOrderedSet *me = new OSOrderedSet; ! 74: ! 75: if (me && !me->initWithCapacity(capacity, ordering, orderingRef)) { ! 76: me->free(); ! 77: me = 0; ! 78: } ! 79: ! 80: return me; ! 81: } ! 82: ! 83: void OSOrderedSet::free() ! 84: { ! 85: flushCollection(); ! 86: ! 87: if (array) { ! 88: kfree((vm_offset_t)array, sizeof(_Element) * capacity); ! 89: ACCUMSIZE( -(sizeof(_Element) * capacity) ); ! 90: } ! 91: ! 92: super::free(); ! 93: } ! 94: ! 95: unsigned int OSOrderedSet::getCount() const { return count; } ! 96: unsigned int OSOrderedSet::getCapacity() const { return capacity; } ! 97: unsigned int OSOrderedSet::getCapacityIncrement() const ! 98: { return capacityIncrement; } ! 99: unsigned int OSOrderedSet::setCapacityIncrement(unsigned int increment) ! 100: { ! 101: return capacityIncrement = increment; ! 102: } ! 103: ! 104: unsigned int OSOrderedSet::ensureCapacity(unsigned int newCapacity) ! 105: { ! 106: _Element *newArray; ! 107: int oldSize, newSize; ! 108: ! 109: if (!capacityIncrement || newCapacity <= capacity) ! 110: return capacity; ! 111: ! 112: // round up ! 113: newCapacity = (((newCapacity - 1) / capacityIncrement) + 1) ! 114: * capacityIncrement; ! 115: newSize = sizeof(_Element) * newCapacity; ! 116: ! 117: newArray = (_Element *) kalloc(newSize); ! 118: if (newArray) { ! 119: oldSize = sizeof(_Element) * capacity; ! 120: ! 121: ACCUMSIZE(newSize - oldSize); ! 122: ! 123: bcopy(array, newArray, oldSize); ! 124: bzero(&newArray[capacity], newSize - oldSize); ! 125: kfree((vm_offset_t)array, oldSize); ! 126: array = newArray; ! 127: capacity = newCapacity; ! 128: } ! 129: ! 130: return capacity; ! 131: } ! 132: ! 133: void OSOrderedSet::flushCollection() ! 134: { ! 135: unsigned int i; ! 136: ! 137: haveUpdated(); ! 138: ! 139: for (i = 0; i < count; i++) ! 140: array[i].obj->release(); ! 141: ! 142: count = 0; ! 143: } ! 144: ! 145: /* internal */ ! 146: bool OSOrderedSet::setObject(unsigned int index, OSObject *anObject) ! 147: { ! 148: unsigned int i; ! 149: unsigned int newCount = count + 1; ! 150: ! 151: if ((index > count) || !anObject) ! 152: return false; ! 153: ! 154: if (containsObject(anObject)) ! 155: return false; ! 156: ! 157: // do we need more space? ! 158: if (newCount > capacity && newCount > ensureCapacity(newCount)) ! 159: return false; ! 160: ! 161: haveUpdated(); ! 162: if (index != count) { ! 163: for (i = count; i > index; i--) ! 164: array[i] = array[i-1]; ! 165: } ! 166: array[index].obj = anObject; ! 167: // array[index].pri = pri; ! 168: anObject->retain(); ! 169: count++; ! 170: ! 171: return true; ! 172: } ! 173: ! 174: ! 175: bool OSOrderedSet::setFirstObject(OSObject *anObject) ! 176: { ! 177: return( setObject(0, anObject)); ! 178: } ! 179: ! 180: bool OSOrderedSet::setLastObject(OSObject *anObject) ! 181: { ! 182: return( setObject( count, anObject)); ! 183: } ! 184: ! 185: ! 186: #define ORDER(obj1,obj2) \ ! 187: (ordering ? ((*ordering)( obj1, obj2, orderingRef)) : 0) ! 188: ! 189: bool OSOrderedSet::setObject(OSObject *anObject ) ! 190: { ! 191: unsigned int i; ! 192: ! 193: // queue it behind those with same priority ! 194: for( i = 0; ! 195: (i < count) && (ORDER(array[i].obj, anObject) >= 0); ! 196: i++ ) {} ! 197: ! 198: return( setObject(i, anObject)); ! 199: } ! 200: ! 201: void OSOrderedSet::removeObject(OSObject *anObject) ! 202: { ! 203: bool deleted = false; ! 204: unsigned int i; ! 205: ! 206: for (i = 0; i < count; i++) { ! 207: ! 208: if( deleted) ! 209: array[i-1] = array[i]; ! 210: else if( (array[i].obj == anObject)) { ! 211: array[i].obj->release(); ! 212: deleted = true; ! 213: } ! 214: } ! 215: ! 216: if( deleted) { ! 217: count--; ! 218: haveUpdated(); ! 219: } ! 220: } ! 221: ! 222: bool OSOrderedSet::containsObject(const OSObject *anObject) const ! 223: { ! 224: return anObject && member(anObject); ! 225: } ! 226: ! 227: bool OSOrderedSet::member(const OSObject *anObject) const ! 228: { ! 229: unsigned int i; ! 230: ! 231: for( i = 0; ! 232: (i < count) && (array[i].obj != anObject); ! 233: i++ ) {} ! 234: ! 235: return( i < count); ! 236: } ! 237: ! 238: /* internal */ ! 239: OSObject *OSOrderedSet::getObject( unsigned int index ) const ! 240: { ! 241: if (index >= count) ! 242: return 0; ! 243: ! 244: // if( pri) ! 245: // *pri = array[index].pri; ! 246: ! 247: return( array[index].obj ); ! 248: } ! 249: ! 250: OSObject *OSOrderedSet::getFirstObject() const ! 251: { ! 252: if( count) ! 253: return( array[0].obj ); ! 254: else ! 255: return( 0 ); ! 256: } ! 257: ! 258: OSObject *OSOrderedSet::getLastObject() const ! 259: { ! 260: if( count) ! 261: return( array[count-1].obj ); ! 262: else ! 263: return( 0 ); ! 264: } ! 265: ! 266: SInt32 OSOrderedSet::orderObject( OSObject * anObject ) ! 267: { ! 268: return( ORDER( anObject, 0 )); ! 269: } ! 270: ! 271: void *OSOrderedSet::getOrderingRef() ! 272: { ! 273: return orderingRef; ! 274: } ! 275: ! 276: bool OSOrderedSet::isEqualTo(OSOrderedSet *anOrderedSet) const ! 277: { ! 278: unsigned int i; ! 279: ! 280: if ( this == anOrderedSet ) ! 281: return true; ! 282: ! 283: if ( count != anOrderedSet->getCount() ) ! 284: return false; ! 285: ! 286: for ( i = 0; i < count; i++ ) { ! 287: if ( !array[i].obj->isEqualTo(anOrderedSet->getObject(i)) ) ! 288: return false; ! 289: } ! 290: ! 291: return true; ! 292: } ! 293: ! 294: bool OSOrderedSet::isEqualTo(const OSObject *anObject) const ! 295: { ! 296: OSOrderedSet *oSet; ! 297: ! 298: oSet = OSDynamicCast(OSOrderedSet, (OSObject *)anObject); ! 299: if ( oSet ) ! 300: return isEqualTo(oSet); ! 301: else ! 302: return false; ! 303: } ! 304: ! 305: unsigned int OSOrderedSet::iteratorSize() const ! 306: { ! 307: return( sizeof(unsigned int)); ! 308: } ! 309: ! 310: bool OSOrderedSet::initIterator(void *inIterator) const ! 311: { ! 312: unsigned int *iteratorP = (unsigned int *) inIterator; ! 313: ! 314: *iteratorP = 0; ! 315: return true; ! 316: } ! 317: ! 318: bool OSOrderedSet::getNextObjectForIterator(void *inIterator, OSObject **ret) const ! 319: { ! 320: unsigned int *iteratorP = (unsigned int *) inIterator; ! 321: unsigned int index = (*iteratorP)++; ! 322: ! 323: if (index < count) ! 324: *ret = array[index].obj; ! 325: else ! 326: *ret = 0; ! 327: ! 328: return (*ret != 0); ! 329: } ! 330:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.