Annotation of XNU/libkern/c++/OSArray.cpp, revision 1.1.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.