]> git.saurik.com Git - apple/objc4.git/blob - runtime/OldClasses.subproj/List.m
objc4-532.tar.gz
[apple/objc4.git] / runtime / OldClasses.subproj / List.m
1 /*
2 * Copyright (c) 1999-2001, 2005-2006 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
24 List.m
25 Copyright 1988-1996 NeXT Software, Inc.
26 Written by: Bryan Yamamoto
27 Responsibility: Bertrand Serlet
28 */
29
30 #ifndef __OBJC2__
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35
36 #include <objc/List.h>
37
38 #define DATASIZE(count) ((count) * sizeof(id))
39
40 @implementation List
41
42 + (id)initialize
43 {
44 [self setVersion: 1];
45 return self;
46 }
47
48 - (id)initCount:(unsigned)numSlots
49 {
50 maxElements = numSlots;
51 if (maxElements)
52 dataPtr = (id *)malloc(DATASIZE(maxElements));
53 return self;
54 }
55
56 + (id)newCount:(unsigned)numSlots
57 {
58 return [[self alloc] initCount:numSlots];
59 }
60
61 + (id)new
62 {
63 return [self newCount:0];
64 }
65
66 - (id)init
67 {
68 return [self initCount:0];
69 }
70
71 - (id)free
72 {
73 free(dataPtr);
74 return [super free];
75 }
76
77 - (id)freeObjects
78 {
79 id element;
80 while ((element = [self removeLastObject]))
81 [element free];
82 return self;
83 }
84
85 - (id)copyFromZone:(void *)z
86 {
87 List *new = [[[self class] alloc] initCount: numElements];
88 new->numElements = numElements;
89 bcopy ((const char*)dataPtr, (char*)new->dataPtr, DATASIZE(numElements));
90 return new;
91 }
92
93 - (BOOL) isEqual: anObject
94 {
95 List *other;
96 if (! [anObject isKindOf: [self class]]) return NO;
97 other = (List *) anObject;
98 return (numElements == other->numElements)
99 && (bcmp ((const char*)dataPtr, (const char*)other->dataPtr, DATASIZE(numElements)) == 0);
100 }
101
102 - (unsigned)capacity
103 {
104 return maxElements;
105 }
106
107 - (unsigned)count
108 {
109 return numElements;
110 }
111
112 - (id)objectAt:(unsigned)index
113 {
114 if (index >= numElements)
115 return nil;
116 return dataPtr[index];
117 }
118
119 - (unsigned)indexOf:anObject
120 {
121 register id *this = dataPtr;
122 register id *last = this + numElements;
123 while (this < last) {
124 if (*this == anObject)
125 return this - dataPtr;
126 this++;
127 }
128 return NX_NOT_IN_LIST;
129 }
130
131 - (id)lastObject
132 {
133 if (! numElements)
134 return nil;
135 return dataPtr[numElements - 1];
136 }
137
138 - (id)setAvailableCapacity:(unsigned)numSlots
139 {
140 volatile id *tempDataPtr;
141 if (numSlots < numElements) return nil;
142 tempDataPtr = (id *) realloc (dataPtr, DATASIZE(numSlots));
143 dataPtr = (id *)tempDataPtr;
144 maxElements = numSlots;
145 return self;
146 }
147
148 - (id)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 volatile id *tempDataPtr;
156 /* we double the capacity, also a good size for malloc */
157 maxElements += maxElements + 1;
158 tempDataPtr = (id *) realloc (dataPtr, DATASIZE(maxElements));
159 dataPtr = (id*)tempDataPtr;
160 }
161 this = dataPtr + numElements;
162 prev = this - 1;
163 last = dataPtr + index;
164 while (this > last)
165 *this-- = *prev--;
166 *last = anObject;
167 numElements++;
168 return self;
169 }
170
171 - (id)addObject:anObject
172 {
173 return [self insertObject:anObject at:numElements];
174
175 }
176
177
178 - (id)addObjectIfAbsent:anObject
179 {
180 register id *this, *last;
181 if (! anObject) return nil;
182 this = dataPtr;
183 last = dataPtr + numElements;
184 while (this < last) {
185 if (*this == anObject)
186 return self;
187 this++;
188 }
189 return [self insertObject:anObject at:numElements];
190
191 }
192
193
194 - (id)removeObjectAt:(unsigned)index
195 {
196 register id *this, *last, *next;
197 id retval;
198 if (index >= numElements)
199 return nil;
200 this = dataPtr + index;
201 last = dataPtr + numElements;
202 next = this + 1;
203 retval = *this;
204 while (next < last)
205 *this++ = *next++;
206 numElements--;
207 return retval;
208 }
209
210 - (id)removeObject:anObject
211 {
212 register id *this, *last;
213 this = dataPtr;
214 last = dataPtr + numElements;
215 while (this < last) {
216 if (*this == anObject)
217 return [self removeObjectAt:this - dataPtr];
218 this++;
219 }
220 return nil;
221 }
222
223 - (id)removeLastObject
224 {
225 if (! numElements)
226 return nil;
227 return [self removeObjectAt: numElements - 1];
228 }
229
230 - (id)empty
231 {
232 numElements = 0;
233 return self;
234 }
235
236 - (id)replaceObject:anObject with:newObject
237 {
238 register id *this, *last;
239 if (! newObject)
240 return nil;
241 this = dataPtr;
242 last = dataPtr + numElements;
243 while (this < last) {
244 if (*this == anObject) {
245 *this = newObject;
246 return anObject;
247 }
248 this++;
249 }
250 return nil;
251 }
252
253 - (id)replaceObjectAt:(unsigned)index with:newObject
254 {
255 register id *this;
256 id retval;
257 if (! newObject)
258 return nil;
259 if (index >= numElements)
260 return nil;
261 this = dataPtr + index;
262 retval = *this;
263 *this = newObject;
264 return retval;
265 }
266
267 - (id)makeObjectsPerform:(SEL)aSelector
268 {
269 unsigned count = numElements;
270 while (count--)
271 [dataPtr[count] perform: aSelector];
272 return self;
273 }
274
275 - (id)makeObjectsPerform:(SEL)aSelector with:anObject
276 {
277 unsigned count = numElements;
278 while (count--)
279 [dataPtr[count] perform: aSelector with: anObject];
280 return self;
281 }
282
283 -(id)appendList: (List *)otherList
284 {
285 unsigned i, count;
286
287 for (i = 0, count = [otherList count]; i < count; i++)
288 [self addObject: [otherList objectAt: i]];
289 return self;
290 }
291
292 @end
293
294 #endif