|
|
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: /* IOArray.m created by rsulack on Fri 12-Sep-1997 */ ! 23: /* IOArray.cpp converted to C++ by gvdl on Fri 1998-10-30 */ ! 24: ! 25: ! 26: #include <libkern/c++/OSArray.h> ! 27: #include <libkern/c++/OSSerialize.h> ! 28: #include <libkern/c++/OSLib.h> ! 29: ! 30: #define super OSCollection ! 31: ! 32: OSDefineMetaClassAndStructors(OSArray, OSCollection) ! 33: ! 34: ! 35: #ifdef DEBUG ! 36: extern "C" { ! 37: extern int debug_container_malloc_size; ! 38: }; ! 39: #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0) ! 40: #else ! 41: #define ACCUMSIZE(s) ! 42: #endif ! 43: ! 44: bool OSArray::initWithCapacity(unsigned int inCapacity) ! 45: { ! 46: int size; ! 47: ! 48: if (!super::init()) ! 49: return false; ! 50: ! 51: size = sizeof(OSObject *) * inCapacity; ! 52: array = (OSObject **) kalloc(size); ! 53: if (!array) ! 54: return false; ! 55: ! 56: count = 0; ! 57: capacity = inCapacity; ! 58: capacityIncrement = capacity; ! 59: ! 60: bzero(array, size); ! 61: ACCUMSIZE(size); ! 62: ! 63: return this; ! 64: } ! 65: ! 66: bool OSArray::initWithObjects(OSObject *objects[], ! 67: unsigned int theCount, ! 68: unsigned int theCapacity = 0) ! 69: { ! 70: unsigned int capacity = theCount; ! 71: ! 72: if ( theCapacity ) { ! 73: if ( theCount > theCapacity ) ! 74: return false; ! 75: ! 76: capacity = theCapacity; ! 77: } ! 78: ! 79: if (!objects || !initWithCapacity(capacity)) ! 80: return false; ! 81: ! 82: for ( unsigned int i = 0; i < theCount; i++ ) { ! 83: OSObject *newObject = *objects++; ! 84: ! 85: if (!newObject) ! 86: return false; ! 87: ! 88: array[count++] = newObject; ! 89: newObject->retain(); ! 90: } ! 91: ! 92: return true; ! 93: } ! 94: ! 95: bool OSArray::initWithArray(const OSArray *anArray, ! 96: unsigned int theCapacity = 0) ! 97: { ! 98: if ( !anArray ) ! 99: return false; ! 100: ! 101: return initWithObjects(anArray->array, anArray->count, ! 102: theCapacity); ! 103: } ! 104: ! 105: OSArray *OSArray::withCapacity(unsigned int capacity) ! 106: { ! 107: OSArray *me = new OSArray; ! 108: ! 109: if (me && !me->initWithCapacity(capacity)) { ! 110: me->free(); ! 111: return 0; ! 112: } ! 113: ! 114: return me; ! 115: } ! 116: ! 117: OSArray *OSArray::withObjects(OSObject *objects[], ! 118: unsigned int count, ! 119: unsigned int capacity = 0) ! 120: { ! 121: OSArray *me = new OSArray; ! 122: ! 123: if (me && !me->initWithObjects(objects, count, capacity)) { ! 124: me->free(); ! 125: return 0; ! 126: } ! 127: ! 128: return me; ! 129: } ! 130: ! 131: OSArray *OSArray::withArray(const OSArray *array, ! 132: unsigned int capacity = 0) ! 133: { ! 134: OSArray *me = new OSArray; ! 135: ! 136: if (me && !me->initWithArray(array, capacity)) { ! 137: me->free(); ! 138: return 0; ! 139: } ! 140: ! 141: return me; ! 142: } ! 143: ! 144: void OSArray::free() ! 145: { ! 146: flushCollection(); ! 147: ! 148: if (array) { ! 149: kfree((vm_offset_t)array, sizeof(OSObject *) * capacity); ! 150: ACCUMSIZE( -(sizeof(OSObject *) * capacity) ); ! 151: } ! 152: ! 153: super::free(); ! 154: } ! 155: ! 156: ! 157: unsigned int OSArray::getCount() const { return count; } ! 158: unsigned int OSArray::getCapacity() const { return capacity; } ! 159: unsigned int OSArray::getCapacityIncrement() const { return capacityIncrement; } ! 160: unsigned int OSArray::setCapacityIncrement(unsigned int increment) ! 161: { ! 162: return capacityIncrement = increment; ! 163: } ! 164: ! 165: unsigned int OSArray::ensureCapacity(unsigned int newCapacity) ! 166: { ! 167: OSObject **newArray; ! 168: int oldSize, newSize; ! 169: ! 170: if (!capacityIncrement || newCapacity <= capacity) ! 171: return capacity; ! 172: ! 173: // round up ! 174: newCapacity = (((newCapacity - 1) / capacityIncrement) + 1) ! 175: * capacityIncrement; ! 176: newSize = sizeof(OSObject *) * newCapacity; ! 177: ! 178: newArray = (OSObject **) kalloc(newSize); ! 179: if (newArray) { ! 180: oldSize = sizeof(OSObject *) * capacity; ! 181: ! 182: ACCUMSIZE(newSize - oldSize); ! 183: ! 184: bcopy(array, newArray, oldSize); ! 185: bzero(&newArray[capacity], newSize - oldSize); ! 186: kfree((vm_offset_t)array, oldSize); ! 187: array = newArray; ! 188: capacity = newCapacity; ! 189: } ! 190: ! 191: return capacity; ! 192: } ! 193: ! 194: void OSArray::flushCollection() ! 195: { ! 196: unsigned int i; ! 197: ! 198: haveUpdated(); ! 199: for (i = 0; i < count; i++) ! 200: array[i]->release(); ! 201: count = 0; ! 202: } ! 203: ! 204: bool OSArray::setObject(OSObject *anObject) ! 205: { ! 206: return setObject(count, anObject); ! 207: } ! 208: ! 209: bool OSArray::setObject(unsigned int index, OSObject *anObject) ! 210: { ! 211: unsigned int i; ! 212: unsigned int newCount = count + 1; ! 213: ! 214: if ((index > count) || !anObject) ! 215: return false; ! 216: ! 217: // do we need more space? ! 218: if (newCount > capacity && newCount > ensureCapacity(newCount)) ! 219: return false; ! 220: ! 221: haveUpdated(); ! 222: if (index != count) { ! 223: for (i = count; i > index; i--) ! 224: array[i] = array[i-1]; ! 225: } ! 226: array[index] = anObject; ! 227: anObject->retain(); ! 228: count++; ! 229: ! 230: return true; ! 231: } ! 232: ! 233: bool OSArray::merge(const OSArray * otherArray) ! 234: { ! 235: unsigned int otherCount = otherArray->getCount(); ! 236: unsigned int newCount = count + otherCount; ! 237: ! 238: if (!otherCount) ! 239: return true; ! 240: ! 241: // do we need more space? ! 242: if (newCount > capacity && newCount > ensureCapacity(newCount)) ! 243: return false; ! 244: ! 245: haveUpdated(); ! 246: for (unsigned int i = 0; i < otherCount; i++) { ! 247: OSObject *newObject = otherArray->getObject(i); ! 248: ! 249: array[count++] = newObject; ! 250: newObject->retain(); ! 251: } ! 252: ! 253: return true; ! 254: } ! 255: ! 256: void OSArray::replaceObject(unsigned int index, OSObject *anObject) ! 257: ! 258: { ! 259: OSObject *oldObject; ! 260: ! 261: if ((index >= count) || !anObject) ! 262: return; ! 263: ! 264: haveUpdated(); ! 265: oldObject = array[index]; ! 266: array[index] = anObject; ! 267: anObject->retain(); ! 268: ! 269: oldObject->release(); ! 270: } ! 271: ! 272: void OSArray::removeObject(unsigned int index) ! 273: { ! 274: unsigned int i; ! 275: OSObject *oldObject; ! 276: ! 277: if (index >= count) ! 278: return; ! 279: ! 280: haveUpdated(); ! 281: oldObject = array[index]; ! 282: ! 283: count--; ! 284: for (i = index; i < count; i++) ! 285: array[i] = array[i+1]; ! 286: ! 287: oldObject->release(); ! 288: } ! 289: ! 290: bool OSArray::isEqualTo(OSArray *anArray) const ! 291: { ! 292: unsigned int i; ! 293: ! 294: if ( this == anArray ) ! 295: return true; ! 296: ! 297: if ( count != anArray->getCount() ) ! 298: return false; ! 299: ! 300: for ( i = 0; i < count; i++ ) { ! 301: if ( !array[i]->isEqualTo(anArray->getObject(i)) ) ! 302: return false; ! 303: } ! 304: ! 305: return true; ! 306: } ! 307: ! 308: bool OSArray::isEqualTo(const OSObject *anObject) const ! 309: { ! 310: OSArray *otherArray; ! 311: ! 312: otherArray = OSDynamicCast(OSArray, (OSObject *)anObject); ! 313: if ( otherArray ) ! 314: return isEqualTo(otherArray); ! 315: else ! 316: return false; ! 317: } ! 318: ! 319: OSObject *OSArray::getObject(unsigned int index) const ! 320: { ! 321: if (index >= count) ! 322: return 0; ! 323: else ! 324: return array[index]; ! 325: } ! 326: ! 327: OSObject *OSArray::lastObject() const ! 328: { ! 329: if (count == 0) ! 330: return 0; ! 331: else ! 332: return array[count - 1]; ! 333: } ! 334: ! 335: unsigned int OSArray::getNextIndexOfObject(OSObject * anObject, ! 336: unsigned int index) const ! 337: { ! 338: while ((index < count) && (array[index] != anObject)) ! 339: {} ! 340: if (index >= count) ! 341: index = (unsigned int)-1; ! 342: return index; ! 343: } ! 344: ! 345: unsigned int OSArray::iteratorSize() const ! 346: { ! 347: return sizeof(unsigned int); ! 348: } ! 349: ! 350: bool OSArray::initIterator(void *inIterator) const ! 351: { ! 352: unsigned int *iteratorP = (unsigned int *) inIterator; ! 353: ! 354: *iteratorP = 0; ! 355: return true; ! 356: } ! 357: ! 358: bool OSArray::getNextObjectForIterator(void *inIterator, OSObject **ret) const ! 359: { ! 360: unsigned int *iteratorP = (unsigned int *) inIterator; ! 361: unsigned int index = (*iteratorP)++; ! 362: ! 363: if (index < count) { ! 364: *ret = array[index]; ! 365: return true; ! 366: } ! 367: else { ! 368: *ret = 0; ! 369: return false; ! 370: } ! 371: } ! 372: ! 373: bool OSArray::serialize(OSSerialize *s) const ! 374: { ! 375: if (s->previouslySerialized(this)) return true; ! 376: ! 377: if (!s->addXMLStartTag(this, "array")) return false; ! 378: ! 379: for (unsigned i = 0; i < count; i++) { ! 380: if (!array[i]->serialize(s)) return false; ! 381: } ! 382: ! 383: return s->addXMLEndTag("array"); ! 384: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.