|
|
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.