Annotation of XNU/libkern/c++/OSArray.cpp, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.