Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 311 lines (249 sloc) 6.345 kB
fb77b22 @Midar Make OFArray an abstract class.
authored
1 /*
f5cc2b9 @Midar Update copyright.
authored
2 * Copyright (c) 2008, 2009, 2010, 2011, 2012
fb77b22 @Midar Make OFArray an abstract class.
authored
3 * Jonathan Schleifer <js@webkeks.org>
4 *
5 * All rights reserved.
6 *
7 * This file is part of ObjFW. It may be distributed under the terms of the
8 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
9 * the packaging of this file.
10 *
11 * Alternatively, it may be distributed under the terms of the GNU General
12 * Public License, either version 2 or 3, which can be found in the file
13 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
14 * file.
15 */
16
17 #include "config.h"
18
19 #include <string.h>
20
dcbb398 @Midar Introduce a naming scheme for classes implementing abstract classes.
authored
21 #import "OFMutableArray_adjacent.h"
22 #import "OFArray_adjacent.h"
fb77b22 @Midar Make OFArray an abstract class.
authored
23 #import "OFDataArray.h"
24 #import "OFAutoreleasePool.h"
25
26 #import "OFEnumerationMutationException.h"
27 #import "OFInvalidArgumentException.h"
28 #import "OFOutOfRangeException.h"
29
dcbb398 @Midar Introduce a naming scheme for classes implementing abstract classes.
authored
30 @implementation OFMutableArray_adjacent
fb77b22 @Midar Make OFArray an abstract class.
authored
31 + (void)initialize
32 {
dcbb398 @Midar Introduce a naming scheme for classes implementing abstract classes.
authored
33 if (self == [OFMutableArray_adjacent class])
34 [self inheritMethodsFromClass: [OFArray_adjacent class]];
fb77b22 @Midar Make OFArray an abstract class.
authored
35 }
36
37 - (void)addObject: (id)object
38 {
39 [array addItem: &object];
40 [object retain];
41
42 mutations++;
43 }
44
45 - (void)addObject: (id)object
46 atIndex: (size_t)index
47 {
48 [array addItem: &object
49 atIndex: index];
50 [object retain];
51
52 mutations++;
53 }
54
55 - (void)replaceObject: (id)oldObject
56 withObject: (id)newObject
57 {
58 id *cArray = [array cArray];
59 size_t i, count = [array count];
60
61 for (i = 0; i < count; i++) {
62 if ([cArray[i] isEqual: oldObject]) {
63 [newObject retain];
64 [cArray[i] release];
65 cArray[i] = newObject;
66
67 return;
68 }
69 }
70 }
71
72 - (void)replaceObjectAtIndex: (size_t)index
73 withObject: (id)object
74 {
75 id *cArray = [array cArray];
76 id oldObject;
77
78 if (index >= [array count])
9b5e368 @Midar Exceptions are now autoreleased.
authored
79 @throw [OFOutOfRangeException exceptionWithClass: isa];
fb77b22 @Midar Make OFArray an abstract class.
authored
80
81 oldObject = cArray[index];
82 cArray[index] = [object retain];
83 [oldObject release];
84 }
85
86 - (void)replaceObjectIdenticalTo: (id)oldObject
87 withObject: (id)newObject
88 {
89 id *cArray = [array cArray];
90 size_t i, count = [array count];
91
92 for (i = 0; i < count; i++) {
93 if (cArray[i] == oldObject) {
94 [newObject retain];
95 [cArray[i] release];
96 cArray[i] = newObject;
97
98 return;
99 }
100 }
101 }
102
103 - (void)removeObject: (id)object
104 {
105 id *cArray = [array cArray];
106 size_t i, count = [array count];
107
108 for (i = 0; i < count; i++) {
109 if ([cArray[i] isEqual: object]) {
110 object = cArray[i];
111
112 [array removeItemAtIndex: i];
113 mutations++;
114
115 [object release];
116
117 return;
118 }
119 }
120 }
121
122 - (void)removeObjectIdenticalTo: (id)object
123 {
124 id *cArray = [array cArray];
125 size_t i, count = [array count];
126
127 for (i = 0; i < count; i++) {
128 if (cArray[i] == object) {
129 [array removeItemAtIndex: i];
130 mutations++;
131
132 [object release];
133
134 return;
135 }
136 }
137 }
138
139 - (void)removeObjectAtIndex: (size_t)index
140 {
141 id object = [self objectAtIndex: index];
142 [array removeItemAtIndex: index];
143 [object release];
144
145 mutations++;
146 }
147
148 - (void)removeNObjects: (size_t)nObjects
149 {
150 id *cArray = [array cArray], *copy;
151 size_t i, count = [array count];
152
153 if (nObjects > count)
9b5e368 @Midar Exceptions are now autoreleased.
authored
154 @throw [OFOutOfRangeException exceptionWithClass: isa];
fb77b22 @Midar Make OFArray an abstract class.
authored
155
156 copy = [self allocMemoryForNItems: nObjects
21ea66a @Midar Rename -[allocMemoryForNItems:withSize:] and friends.
authored
157 ofSize: sizeof(id)];
fb77b22 @Midar Make OFArray an abstract class.
authored
158 memcpy(copy, cArray + (count - nObjects), nObjects * sizeof(id));
159
160 @try {
161 [array removeNItems: nObjects];
162 mutations++;
163
164 for (i = 0; i < nObjects; i++)
165 [copy[i] release];
166 } @finally {
167 [self freeMemory: copy];
168 }
169 }
170
171 - (void)removeObjectsInRange: (of_range_t)range
172 {
173 id *cArray = [array cArray], *copy;
174 size_t i, count = [array count];
175
176 if (range.length > count - range.start)
9b5e368 @Midar Exceptions are now autoreleased.
authored
177 @throw [OFOutOfRangeException exceptionWithClass: isa];
fb77b22 @Midar Make OFArray an abstract class.
authored
178
179 copy = [self allocMemoryForNItems: range.length
21ea66a @Midar Rename -[allocMemoryForNItems:withSize:] and friends.
authored
180 ofSize: sizeof(id)];
fb77b22 @Midar Make OFArray an abstract class.
authored
181 memcpy(copy, cArray + range.start, range.length * sizeof(id));
182
183 @try {
184 [array removeNItems: range.length
185 atIndex: range.start];
186 mutations++;
187
188 for (i = 0; i < range.length; i++)
189 [copy[i] release];
190 } @finally {
191 [self freeMemory: copy];
192 }
193 }
194
195 - (void)removeLastObject
196 {
197 id object = [self objectAtIndex: [array count] - 1];
198 [array removeLastItem];
199 [object release];
200
201 mutations++;
202 }
203
9499bb1 @Midar More methods for OFArray and OFMutableArray.
authored
204 - (void)swapObjectAtIndex: (size_t)index1
205 withObjectAtIndex: (size_t)index2
206 {
207 id *cArray = [array cArray];
208 size_t count = [array count];
209 id tmp;
210
211 if (index1 >= count || index2 >= count)
212 @throw [OFOutOfRangeException exceptionWithClass: isa];
213
214 tmp = cArray[index1];
215 cArray[index1] = cArray[index2];
216 cArray[index2] = tmp;
217 }
218
219 - (void)reverse
220 {
221 id *cArray = [array cArray];
222 size_t i, j, count = [array count];
223
224 if (count == 0 || count == 1)
225 return;
226
227 for (i = 0, j = count - 1; i < j; i++, j--) {
228 id tmp = cArray[i];
229 cArray[i] = cArray[j];
230 cArray[j] = tmp;
231 }
232 }
233
fb77b22 @Midar Make OFArray an abstract class.
authored
234 - (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
235 objects: (id*)objects
d802047 @Midar Add a note about usage of super to OFMutableCArray.
authored
236 count: (int)count
fb77b22 @Midar Make OFArray an abstract class.
authored
237 {
d802047 @Midar Add a note about usage of super to OFMutableCArray.
authored
238 /*
239 * Super means the implementation from OFArray here, as OFMutableArray
dcbb398 @Midar Introduce a naming scheme for classes implementing abstract classes.
authored
240 * does not reimplement it. As OFArray_adjacent does not reimplement it
241 * either, this is fine.
d802047 @Midar Add a note about usage of super to OFMutableCArray.
authored
242 */
fb77b22 @Midar Make OFArray an abstract class.
authored
243 int ret = [super countByEnumeratingWithState: state
244 objects: objects
d802047 @Midar Add a note about usage of super to OFMutableCArray.
authored
245 count: count];
fb77b22 @Midar Make OFArray an abstract class.
authored
246
247 state->mutationsPtr = &mutations;
248
249 return ret;
250 }
251
252 - (OFEnumerator*)objectEnumerator
253 {
254 return [[[OFArrayEnumerator alloc]
255 initWithArray: self
256 mutationsPtr: &mutations] autorelease];
257 }
258
259 #ifdef OF_HAVE_BLOCKS
260 - (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
261 {
262 id *cArray = [array cArray];
263 size_t i, count = [array count];
264 BOOL stop = NO;
265 unsigned long mutations2 = mutations;
266
267 for (i = 0; i < count && !stop; i++) {
268 if (mutations != mutations2)
269 @throw [OFEnumerationMutationException
9b5e368 @Midar Exceptions are now autoreleased.
authored
270 exceptionWithClass: isa
271 object: self];
fb77b22 @Midar Make OFArray an abstract class.
authored
272
273 block(cArray[i], i, &stop);
274 }
275 }
276
277 - (void)replaceObjectsUsingBlock: (of_array_replace_block_t)block
278 {
279 id *cArray = [array cArray];
280 size_t i, count = [array count];
281 BOOL stop = NO;
282 unsigned long mutations2 = mutations;
283
284 for (i = 0; i < count && !stop; i++) {
285 id newObject;
286
287 if (mutations != mutations2)
288 @throw [OFEnumerationMutationException
9b5e368 @Midar Exceptions are now autoreleased.
authored
289 exceptionWithClass: isa
290 object: self];
fb77b22 @Midar Make OFArray an abstract class.
authored
291
292 newObject = block(cArray[i], i, &stop);
293
294 if (newObject == nil)
9b5e368 @Midar Exceptions are now autoreleased.
authored
295 @throw [OFInvalidArgumentException
296 exceptionWithClass: isa
297 selector: _cmd];
fb77b22 @Midar Make OFArray an abstract class.
authored
298
299 [newObject retain];
300 [cArray[i] release];
301 cArray[i] = newObject;
302 }
303 }
304 #endif
305
f1c37a4 @Midar Add -[makeImmutable] to all mutable classes and use it.
authored
306 - (void)makeImmutable
fb77b22 @Midar Make OFArray an abstract class.
authored
307 {
dcbb398 @Midar Introduce a naming scheme for classes implementing abstract classes.
authored
308 isa = [OFArray_adjacent class];
fb77b22 @Midar Make OFArray an abstract class.
authored
309 }
310 @end
Something went wrong with that request. Please try again.