|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.0 (the 'License'). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License." ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: /* ! 25: List.m ! 26: Copyright 1988, 1989 NeXT, Inc. ! 27: Written by: Bryan Yamamoto ! 28: Responsibility: Bertrand Serlet ! 29: */ ! 30: ! 31: #ifdef SHLIB ! 32: #import "shlib.h" ! 33: #endif SHLIB ! 34: ! 35: #import <stdlib.h> ! 36: #import <stdio.h> ! 37: #import <string.h> ! 38: #import "List.h" ! 39: ! 40: #define DATASIZE(count) ((count) * sizeof(id)) ! 41: ! 42: @implementation List ! 43: ! 44: + initialize ! 45: { ! 46: [self setVersion: 1]; ! 47: return self; ! 48: } ! 49: ! 50: - initCount:(unsigned)numSlots ! 51: { ! 52: maxElements = numSlots; ! 53: if (maxElements) ! 54: dataPtr = (id *)NXZoneMalloc([self zone], DATASIZE(maxElements)); ! 55: return self; ! 56: } ! 57: ! 58: + newCount:(unsigned)numSlots ! 59: { ! 60: return [[self allocFromZone: NXDefaultMallocZone()] initCount:numSlots]; ! 61: } ! 62: ! 63: + new ! 64: { ! 65: return [self newCount:0]; ! 66: } ! 67: ! 68: - init ! 69: { ! 70: return [self initCount:0]; ! 71: } ! 72: ! 73: - free ! 74: { ! 75: free(dataPtr); ! 76: return [super free]; ! 77: } ! 78: ! 79: - freeObjects ! 80: { ! 81: id element; ! 82: while ((element = [self removeLastObject])) ! 83: [element free]; ! 84: return self; ! 85: } ! 86: ! 87: - copyFromZone:(NXZone *)zone ! 88: { ! 89: List *new = [[[self class] allocFromZone:zone] initCount: numElements]; ! 90: new->numElements = numElements; ! 91: bcopy (dataPtr, new->dataPtr, DATASIZE(numElements)); ! 92: return new; ! 93: } ! 94: ! 95: - (BOOL) isEqual: anObject ! 96: { ! 97: List *other; ! 98: if (! [anObject isKindOf: [self class]]) return NO; ! 99: other = (List *) anObject; ! 100: return (numElements == other->numElements) ! 101: && (bcmp (dataPtr, other->dataPtr, DATASIZE(numElements)) == 0); ! 102: } ! 103: ! 104: - (unsigned)capacity ! 105: { ! 106: return maxElements; ! 107: } ! 108: ! 109: - (unsigned)count ! 110: { ! 111: return numElements; ! 112: } ! 113: ! 114: - objectAt:(unsigned)index ! 115: { ! 116: if (index >= numElements) ! 117: return nil; ! 118: return dataPtr[index]; ! 119: } ! 120: ! 121: - (unsigned)indexOf:anObject ! 122: { ! 123: register id *this = dataPtr; ! 124: register id *last = this + numElements; ! 125: while (this < last) { ! 126: if (*this == anObject) ! 127: return this - dataPtr; ! 128: this++; ! 129: } ! 130: return NX_NOT_IN_LIST; ! 131: } ! 132: ! 133: - lastObject ! 134: { ! 135: if (! numElements) ! 136: return nil; ! 137: return dataPtr[numElements - 1]; ! 138: } ! 139: ! 140: - setAvailableCapacity:(unsigned)numSlots ! 141: { ! 142: if (numSlots < numElements) return nil; ! 143: dataPtr = (id *) NXZoneRealloc ([self zone], dataPtr, DATASIZE(numSlots)); ! 144: maxElements = numSlots; ! 145: return self; ! 146: } ! 147: ! 148: - insertObject:anObject at:(unsigned)index ! 149: { ! 150: register id *this, *last, *prev; ! 151: if (! anObject) return nil; ! 152: if (index > numElements) ! 153: return nil; ! 154: if ((numElements + 1) > maxElements) { ! 155: /* we double the capacity, also a good size for malloc */ ! 156: maxElements += maxElements + 1; ! 157: dataPtr = (id *) NXZoneRealloc ( ! 158: [self zone], dataPtr, DATASIZE(maxElements)); ! 159: } ! 160: this = dataPtr + numElements; ! 161: prev = this - 1; ! 162: last = dataPtr + index; ! 163: while (this > last) ! 164: *this-- = *prev--; ! 165: *last = anObject; ! 166: numElements++; ! 167: return self; ! 168: } ! 169: ! 170: - addObject:anObject ! 171: { ! 172: return [self insertObject:anObject at:numElements]; ! 173: ! 174: } ! 175: ! 176: ! 177: - addObjectIfAbsent:anObject ! 178: { ! 179: register id *this, *last; ! 180: if (! anObject) return nil; ! 181: this = dataPtr; ! 182: last = dataPtr + numElements; ! 183: while (this < last) { ! 184: if (*this == anObject) ! 185: return self; ! 186: this++; ! 187: } ! 188: return [self insertObject:anObject at:numElements]; ! 189: ! 190: } ! 191: ! 192: ! 193: - removeObjectAt:(unsigned)index ! 194: { ! 195: register id *this, *last, *next; ! 196: id retval; ! 197: if (index >= numElements) ! 198: return nil; ! 199: this = dataPtr + index; ! 200: last = dataPtr + numElements; ! 201: next = this + 1; ! 202: retval = *this; ! 203: while (next < last) ! 204: *this++ = *next++; ! 205: numElements--; ! 206: return retval; ! 207: } ! 208: ! 209: - removeObject:anObject ! 210: { ! 211: register id *this, *last; ! 212: this = dataPtr; ! 213: last = dataPtr + numElements; ! 214: while (this < last) { ! 215: if (*this == anObject) ! 216: return [self removeObjectAt:this - dataPtr]; ! 217: this++; ! 218: } ! 219: return nil; ! 220: } ! 221: ! 222: - removeLastObject ! 223: { ! 224: if (! numElements) ! 225: return nil; ! 226: return [self removeObjectAt: numElements - 1]; ! 227: } ! 228: ! 229: - empty ! 230: { ! 231: numElements = 0; ! 232: return self; ! 233: } ! 234: ! 235: - replaceObject:anObject with:newObject ! 236: { ! 237: register id *this, *last; ! 238: if (! newObject) ! 239: return nil; ! 240: this = dataPtr; ! 241: last = dataPtr + numElements; ! 242: while (this < last) { ! 243: if (*this == anObject) { ! 244: *this = newObject; ! 245: return anObject; ! 246: } ! 247: this++; ! 248: } ! 249: return nil; ! 250: } ! 251: ! 252: - replaceObjectAt:(unsigned)index with:newObject ! 253: { ! 254: register id *this; ! 255: id retval; ! 256: if (! newObject) ! 257: return nil; ! 258: if (index >= numElements) ! 259: return nil; ! 260: this = dataPtr + index; ! 261: retval = *this; ! 262: *this = newObject; ! 263: return retval; ! 264: } ! 265: ! 266: #ifndef KERNEL ! 267: - write:(NXTypedStream *) stream ! 268: { ! 269: [super write: stream]; ! 270: NXWriteTypes (stream, "i", &numElements); ! 271: if (numElements) ! 272: NXWriteArray (stream, "@", numElements, dataPtr); ! 273: return self; ! 274: } ! 275: ! 276: - read:(NXTypedStream *) stream ! 277: { ! 278: NXZone *zone = [self zone]; ! 279: [super read: stream]; ! 280: if (NXTypedStreamClassVersion (stream, "List") == 0) { ! 281: int _growAmount = 0; ! 282: NXReadTypes (stream, "ii", &_growAmount, &numElements); ! 283: dataPtr = (id *) NXZoneMalloc (zone, numElements*sizeof(id)); ! 284: maxElements = numElements; ! 285: NXReadArray (stream, "@", numElements, dataPtr); ! 286: } else { ! 287: NXReadTypes (stream, "i", &numElements); ! 288: maxElements = numElements; ! 289: if (numElements) { ! 290: dataPtr = (id *) NXZoneMalloc (zone, numElements*sizeof(id)); ! 291: NXReadArray (stream, "@", numElements, dataPtr); ! 292: } ! 293: } ! 294: return self; ! 295: } ! 296: #else /* KERNEL */ ! 297: - write:(NXTypedStream *) stream ! 298: { ! 299: return nil; ! 300: } ! 301: - read:(NXTypedStream *) stream ! 302: { ! 303: return nil; ! 304: } ! 305: #endif /* KERNEL */ ! 306: ! 307: - makeObjectsPerform:(SEL)aSelector ! 308: { ! 309: unsigned count = numElements; ! 310: while (count--) ! 311: [dataPtr[count] perform: aSelector]; ! 312: return self; ! 313: } ! 314: ! 315: - makeObjectsPerform:(SEL)aSelector with:anObject ! 316: { ! 317: unsigned count = numElements; ! 318: while (count--) ! 319: [dataPtr[count] perform: aSelector with: anObject]; ! 320: return self; ! 321: } ! 322: ! 323: -appendList: (List *)otherList ! 324: { ! 325: unsigned i, count; ! 326: ! 327: for (i = 0, count = [otherList count]; i < count; i++) ! 328: [self addObject: [otherList objectAt: i]]; ! 329: return self; ! 330: } ! 331: ! 332: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.