Overview
Comment: | Make OFListItem opaque |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
8573ef86c66de270eca67694b7497096 |
User & Date: | js on 2021-04-25 16:48:25 |
Other Links: | manifest | tags |
Context
2021-04-25
| ||
19:41 | OFStrdup -> OFStrDup and slightly change behavior check-in: fd51df7022 user: js tags: trunk | |
16:48 | Make OFListItem opaque check-in: 8573ef86c6 user: js tags: trunk | |
16:20 | OFSecureData: Move chunkSize into #ifdef check-in: b648c7090f user: js tags: trunk | |
Changes
Modified src/OFList.h from [0c075514d1] to [0e994cc065].
︙ | ︙ | |||
16 17 18 19 20 21 22 | #import "OFObject.h" #import "OFCollection.h" #import "OFEnumerator.h" #import "OFSerialization.h" OF_ASSUME_NONNULL_BEGIN | < | < | | | > > > > > > > > > > | > > > > > | > | | > > > > > > > | < > > > > > | | | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | #import "OFObject.h" #import "OFCollection.h" #import "OFEnumerator.h" #import "OFSerialization.h" OF_ASSUME_NONNULL_BEGIN /** * @typedef OFListItem OFList.h ObjFW/OFList.h * * @brief A list item. * * See @ref OFListItemNext, @ref OFListItemPrevious and @ref OFListItemObject. */ typedef struct OFListItem *OFListItem; #ifdef __cplusplus extern "C" { #endif /*! * @brief Returns the next list item of the list item. * * @param listItem The list item for which the next list item should be returned * @return The next list item of the list item */ OFListItem OFListItemNext(OFListItem _Nonnull listItem); /*! * @brief Returns the previous list item of the list item. * * @param listItem The list item for which the previous list item should be * returned * @return The previous list item of the list item */ OFListItem OFListItemPrevious(OFListItem _Nonnull listItem); /*! * @brief Returns the object of the list item. * * @warning The returned object is not retained and autoreleased - this is the * caller's responsibility! * * @param listItem The list item for which the object should be returned * @return The object of the list item */ id OFListItemObject(OFListItem _Nonnull listItem); #ifdef __cplusplus } #endif /** * @class OFList OFList.h ObjFW/OFList.h * * @brief A class which provides easy to use double-linked lists. */ @interface OFList OF_GENERIC(ObjectType): OFObject <OFCopying, OFCollection, OFSerialization> #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif { OFListItem _Nullable _firstListItem; OFListItem _Nullable _lastListItem; size_t _count; unsigned long _mutations; OF_RESERVE_IVARS(OFList, 4) } /** * @brief The first list object of the list. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFListItem firstListItem; /** * @brief The first object of the list or `nil`. * * @warning The returned object is *not* retained and autoreleased for * performance reasons! */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) ObjectType firstObject; /** * @brief The last list object of the list. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFListItem lastListItem; /** * @brief The last object of the list or `nil`. * * @warning The returned object is *not* retained and autoreleased for * performance reasons! */ |
︙ | ︙ | |||
93 94 95 96 97 98 99 | * @brief Appends an object to the list. * * @param object The object to append * @return An OFListItem, needed to identify the object inside the list. * For example, if you want to remove an object from the list, you need * its OFListItem. */ | | | | | | | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | * @brief Appends an object to the list. * * @param object The object to append * @return An OFListItem, needed to identify the object inside the list. * For example, if you want to remove an object from the list, you need * its OFListItem. */ - (OFListItem)appendObject: (ObjectType)object; /** * @brief Prepends an object to the list. * * @param object The object to prepend * @return An OFListItem, needed to identify the object inside the list. * For example, if you want to remove an object from the list, you need * its OFListItem. */ - (OFListItem)prependObject: (ObjectType)object; /** * @brief Inserts an object before another list object. * * @param object The object to insert * @param listItem The OFListItem of the object before which it should be * inserted * @return An OFListItem, needed to identify the object inside the list. * For example, if you want to remove an object from the list, you need * its OFListItem. */ - (OFListItem)insertObject: (ObjectType)object beforeListItem: (OFListItem)listItem; /** * @brief Inserts an object after another list object. * * @param object The object to insert * @param listItem The OFListItem of the object after which it should be * inserted * @return An OFListItem, needed to identify the object inside the list. * For example, if you want to remove an object from the list, you need * its OFListItem. */ - (OFListItem)insertObject: (ObjectType)object afterListItem: (OFListItem)listItem; /** * @brief Removes the object with the specified list object from the list. * * @param listItem The list object returned by append / prepend */ - (void)removeListItem: (OFListItem)listItem; /** * @brief Checks whether the list contains an object equal to the specified * object. * * @param object The object which is checked for being in the list * @return A boolean whether the list contains the specified object |
︙ | ︙ |
Modified src/OFList.m from [270e405c2f] to [71b5abf54f].
︙ | ︙ | |||
21 22 23 24 25 26 27 28 29 30 31 32 | #import "OFList.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFArray.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" OF_DIRECT_MEMBERS @interface OFListEnumerator: OFEnumerator { OFList *_list; | > > > > > | > > > > > > > > > > > > > > > > > > | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | #import "OFList.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFArray.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" struct OFListItem { OFListItem previous, next; id object; }; OF_DIRECT_MEMBERS @interface OFListEnumerator: OFEnumerator { OFList *_list; OFListItem _Nullable _current; unsigned long _mutations; unsigned long *_Nullable _mutationsPtr; } - (instancetype)initWithList: (OFList *)list mutationsPointer: (unsigned long *)mutationsPtr; @end OFListItem OFListItemNext(OFListItem listItem) { return listItem->next; } OFListItem OFListItemPrevious(OFListItem listItem) { return listItem->previous; } id OFListItemObject(OFListItem listItem) { return listItem->object; } @implementation OFList @synthesize firstListItem = _firstListItem, lastListItem = _lastListItem; + (instancetype)list { return [[[self alloc] init] autorelease]; |
︙ | ︙ | |||
74 75 76 77 78 79 80 | } return self; } - (void)dealloc { | | | | | < | | < | | < | | | | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | } return self; } - (void)dealloc { OFListItem next; for (OFListItem iter = _firstListItem; iter != NULL; iter = next) { [iter->object release]; next = iter->next; OFFreeMemory(iter); } [super dealloc]; } - (OFListItem)appendObject: (id)object { OFListItem listItem = OFAllocMemory(1, sizeof(*listItem)); listItem->object = [object retain]; listItem->next = NULL; listItem->previous = _lastListItem; if (_lastListItem != NULL) _lastListItem->next = listItem; _lastListItem = listItem; if (_firstListItem == NULL) _firstListItem = listItem; _count++; _mutations++; return listItem; } - (OFListItem)prependObject: (id)object { OFListItem listItem = OFAllocMemory(1, sizeof(*listItem)); listItem->object = [object retain]; listItem->next = _firstListItem; listItem->previous = NULL; if (_firstListItem != NULL) _firstListItem->previous = listItem; _firstListItem = listItem; if (_lastListItem == NULL) _lastListItem = listItem; _count++; _mutations++; return listItem; } - (OFListItem)insertObject: (id)object beforeListItem: (OFListItem)listItem { OFListItem newListItem = OFAllocMemory(1, sizeof(*newListItem)); newListItem->object = [object retain]; newListItem->next = listItem; newListItem->previous = listItem->previous; if (listItem->previous != NULL) listItem->previous->next = newListItem; listItem->previous = newListItem; if (listItem == _firstListItem) _firstListItem = newListItem; _count++; _mutations++; return newListItem; } - (OFListItem)insertObject: (id)object afterListItem: (OFListItem)listItem { OFListItem newListItem = OFAllocMemory(1, sizeof(*newListItem)); newListItem->object = [object retain]; newListItem->next = listItem->next; newListItem->previous = listItem; if (listItem->next != NULL) listItem->next->previous = newListItem; listItem->next = newListItem; if (listItem == _lastListItem) _lastListItem = newListItem; _count++; _mutations++; return newListItem; } - (void)removeListItem: (OFListItem)listItem { if (listItem->previous != NULL) listItem->previous->next = listItem->next; if (listItem->next != NULL) listItem->next->previous = listItem->previous; if (_firstListItem == listItem) |
︙ | ︙ | |||
212 213 214 215 216 217 218 | { return _count; } - (bool)isEqual: (id)object { OFList *list; | | | 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | { return _count; } - (bool)isEqual: (id)object { OFList *list; OFListItem iter, iter2; if (object == self) return true; if (![object isKindOfClass: [OFList class]]) return false; |
︙ | ︙ | |||
242 243 244 245 246 247 248 | } - (bool)containsObject: (id)object { if (_count == 0) return false; | | | | | < < < | | | | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | } - (bool)containsObject: (id)object { if (_count == 0) return false; for (OFListItem iter = _firstListItem; iter != NULL; iter = iter->next) if ([iter->object isEqual: object]) return true; return false; } - (bool)containsObjectIdenticalTo: (id)object { if (_count == 0) return false; for (OFListItem iter = _firstListItem; iter != NULL; iter = iter->next) if (iter->object == object) return true; return false; } - (void)removeAllObjects { OFListItem next; _mutations++; for (OFListItem iter = _firstListItem; iter != NULL; iter = next) { [iter->object release]; next = iter->next; OFFreeMemory(iter); } _firstListItem = _lastListItem = NULL; } - (id)copy { OFList *copy = [[[self class] alloc] init]; OFListItem listItem = NULL, previous = NULL; @try { for (OFListItem iter = _firstListItem; iter != NULL; iter = iter->next) { listItem = OFAllocMemory(1, sizeof(*listItem)); listItem->object = [iter->object retain]; listItem->next = NULL; listItem->previous = previous; if (copy->_firstListItem == NULL) copy->_firstListItem = listItem; if (previous != NULL) |
︙ | ︙ | |||
317 318 319 320 321 322 323 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); | | | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); for (OFListItem iter = _firstListItem; iter != NULL; iter = iter->next) OFHashAddHash(&hash, [iter->object hash]); OFHashFinalize(&hash); return hash; } - (OFString *)description { OFMutableString *ret; if (_count == 0) return @"[]"; ret = [OFMutableString stringWithString: @"[\n"]; for (OFListItem iter = _firstListItem; iter != NULL; iter = iter->next) { void *pool = objc_autoreleasePoolPush(); [ret appendString: [iter->object description]]; if (iter->next != NULL) [ret appendString: @",\n"]; |
︙ | ︙ | |||
359 360 361 362 363 364 365 | - (OFXMLElement *)XMLElementBySerializing { OFXMLElement *element = [OFXMLElement elementWithName: self.className namespace: OFSerializationNS]; | | | | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 | - (OFXMLElement *)XMLElementBySerializing { OFXMLElement *element = [OFXMLElement elementWithName: self.className namespace: OFSerializationNS]; for (OFListItem iter = _firstListItem; iter != NULL; iter = iter->next) { void *pool = objc_autoreleasePoolPush(); [element addChild: [iter->object XMLElementBySerializing]]; objc_autoreleasePoolPop(pool); } return element; } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count { OFListItem listItem; memcpy(&listItem, state->extra, sizeof(listItem)); state->itemsPtr = objects; state->mutationsPtr = &_mutations; if (state->state == 0) { |
︙ | ︙ |
Modified src/OFRunLoop.m from [ffb2965c25] to [ab97878b5e].
︙ | ︙ | |||
272 273 274 275 276 277 278 | OFList OF_GENERIC(OF_KINDOF(OFRunLoopReadQueueItem *)) *queue = [[_readQueues objectForKey: object] retain]; assert(queue != nil); @try { if (![queue.firstObject handleObject: object]) { | | > | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | OFList OF_GENERIC(OF_KINDOF(OFRunLoopReadQueueItem *)) *queue = [[_readQueues objectForKey: object] retain]; assert(queue != nil); @try { if (![queue.firstObject handleObject: object]) { OFListItem listItem = queue.firstListItem; /* * The handler might have called -[cancelAsyncRequests] * so that our queue is now empty, in which case we * should do nothing. */ if (listItem != NULL) { /* * Make sure we keep the target until after we * are done removing the object. The reason for * this is that the target might call * -[cancelAsyncRequests] in its dealloc. */ [[OFListItemObject(listItem) retain] autorelease]; [queue removeListItem: listItem]; if (queue.count == 0) { [_kernelEventObserver removeObjectForReading: object]; [_readQueues |
︙ | ︙ | |||
315 316 317 318 319 320 321 | */ OFList *queue = [[_writeQueues objectForKey: object] retain]; assert(queue != nil); @try { if (![queue.firstObject handleObject: object]) { | | > | | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | */ OFList *queue = [[_writeQueues objectForKey: object] retain]; assert(queue != nil); @try { if (![queue.firstObject handleObject: object]) { OFListItem listItem = queue.firstListItem; /* * The handler might have called -[cancelAsyncRequests] * so that our queue is now empty, in which case we * should do nothing. */ if (listItem != NULL) { /* * Make sure we keep the target until after we * are done removing the object. The reason for * this is that the target might call * -[cancelAsyncRequests] in its dealloc. */ [[OFListItemObject(listItem) retain] autorelease]; [queue removeListItem: listItem]; if (queue.count == 0) { [_kernelEventObserver removeObjectForWriting: object]; [_writeQueues |
︙ | ︙ | |||
1416 1417 1418 1419 1420 1421 1422 | if (state == nil) return; #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif | | | | | 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 | if (state == nil) return; #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif for (OFListItem iter = state->_timersQueue.firstListItem; iter != NULL; iter = OFListItemNext(iter)) { if ([OFListItemObject(iter) isEqual: timer]) { [state->_timersQueue removeListItem: iter]; break; } } #ifdef OF_HAVE_THREADS } @finally { [state->_timersQueueMutex unlock]; |
︙ | ︙ | |||
1573 1574 1575 1576 1577 1578 1579 | for (;;) { OFTimer *timer; #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif | | | > | | | 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 | for (;;) { OFTimer *timer; #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif OFListItem listItem = state->_timersQueue.firstListItem; if (listItem != NULL && [OFListItemObject(listItem) fireDate] .timeIntervalSinceNow <= 0) { timer = [[OFListItemObject(listItem) retain] autorelease]; [state->_timersQueue removeListItem: listItem]; [timer of_setInRunLoop: nil mode: nil]; } else |
︙ | ︙ |
Modified src/OFSortedList.h from [10d4fe8869] to [a53236cd47].
︙ | ︙ | |||
29 30 31 32 33 34 35 | #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif { OF_RESERVE_IVARS(OFSortedList, 4) } | | | | | < | | < | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif { OF_RESERVE_IVARS(OFSortedList, 4) } - (OFListItem)appendObject: (ObjectType)object OF_UNAVAILABLE; - (OFListItem)prependObject: (ObjectType)object OF_UNAVAILABLE; - (OFListItem)insertObject: (ObjectType)object beforeListItem: (OFListItem)listItem OF_UNAVAILABLE; - (OFListItem)insertObject: (ObjectType)object afterListItem: (OFListItem)listItem OF_UNAVAILABLE; /** * @brief Inserts the object to the list while keeping the list sorted. * * @param object The object to insert * @return The list object for the object just added */ - (OFListItem)insertObject: (ObjectType <OFComparing>)object; #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # undef ObjectType #endif @end OF_ASSUME_NONNULL_END |
Modified src/OFSortedList.m from [228aa13ba0] to [647acba740].
︙ | ︙ | |||
14 15 16 17 18 19 20 | */ #include "config.h" #import "OFSortedList.h" @implementation OFSortedList | | > > > > > | | < < < < < < < | | | > > | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | */ #include "config.h" #import "OFSortedList.h" @implementation OFSortedList - (OFListItem)appendObject: (id)object { OF_UNRECOGNIZED_SELECTOR } - (OFListItem)prependObject: (id)object { OF_UNRECOGNIZED_SELECTOR } - (OFListItem)insertObject: (id)object beforeListItem: (OFListItem)listItem { OF_UNRECOGNIZED_SELECTOR } - (OFListItem)insertObject: (id)object afterListItem: (OFListItem)listItem { OF_UNRECOGNIZED_SELECTOR } - (OFListItem)insertObject: (id <OFComparing>)object { OFListItem iter; for (iter = _lastListItem; iter != NULL; iter = OFListItemPrevious(iter)) { if ([object compare: OFListItemObject(iter)] != OFOrderedAscending) return [super insertObject: object afterListItem: iter]; } return [super prependObject: object]; } @end |
Modified src/OFThreadPool.m from [62afef694d] to [bf37211055].
︙ | ︙ | |||
158 159 160 161 162 163 164 | pool = objc_autoreleasePoolPush(); for (;;) { OFThreadPoolJob *job; [_queueCondition lock]; @try { | | | | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | pool = objc_autoreleasePoolPush(); for (;;) { OFThreadPoolJob *job; [_queueCondition lock]; @try { OFListItem listItem; if (_terminate) { objc_autoreleasePoolPop(pool); return nil; } listItem = _queue.firstListItem; while (listItem == NULL) { [_queueCondition wait]; if (_terminate) { objc_autoreleasePoolPop(pool); return nil; } listItem = _queue.firstListItem; } job = [[OFListItemObject(listItem) retain] autorelease]; [_queue removeListItem: listItem]; } @finally { [_queueCondition unlock]; } if (_terminate) { objc_autoreleasePoolPop(pool); |
︙ | ︙ |
Modified tests/OFListTests.m from [045f6f7c6a] to [ede47645fa].
︙ | ︙ | |||
26 27 28 29 30 31 32 | @implementation TestsAppDelegate (OFListTests) - (void)listTests { void *pool = objc_autoreleasePoolPush(); OFList *list; OFEnumerator *enumerator; | | | > | | | > | | | | > | | | | > | | | | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | @implementation TestsAppDelegate (OFListTests) - (void)listTests { void *pool = objc_autoreleasePoolPush(); OFList *list; OFEnumerator *enumerator; OFListItem iter; OFString *obj; size_t i; bool ok; TEST(@"+[list]", (list = [OFList list])) TEST(@"-[appendObject:]", [list appendObject: strings[0]] && [list appendObject: strings[1]] && [list appendObject: strings[2]]) TEST(@"-[firstListItem]", [OFListItemObject(list.firstListItem) isEqual: strings[0]]) TEST(@"OFListItemNext()", [OFListItemObject(OFListItemNext(list.firstListItem)) isEqual: strings[1]]) TEST(@"-[lastListItem]", [OFListItemObject(list.lastListItem) isEqual: strings[2]]) TEST(@"OFListItemPrevious()", [OFListItemObject(OFListItemPrevious(list.lastListItem)) isEqual: strings[1]]) TEST(@"-[removeListItem:]", R([list removeListItem: list.lastListItem]) && [list.lastObject isEqual: strings[1]] && R([list removeListItem: list.firstListItem]) && [list.firstObject isEqual: list.lastObject]) TEST(@"-[insertObject:beforeListItem:]", [list insertObject: strings[0] beforeListItem: list.lastListItem] && [OFListItemObject(OFListItemPrevious(list.lastListItem)) isEqual: strings[0]]) TEST(@"-[insertObject:afterListItem:]", [list insertObject: strings[2] afterListItem: OFListItemNext(list.firstListItem)] && [list.lastObject isEqual: strings[2]]) TEST(@"-[count]", list.count == 3) TEST(@"-[containsObject:]", [list containsObject: strings[1]] && ![list containsObject: @"nonexistent"]) TEST(@"-[containsObjectIdenticalTo:]", [list containsObjectIdenticalTo: strings[1]] && ![list containsObjectIdenticalTo: [OFString stringWithString: strings[1]]]) TEST(@"-[copy]", (list = [[list copy] autorelease]) && [list.firstObject isEqual: strings[0]] && [OFListItemObject(OFListItemNext(list.firstListItem)) isEqual: strings[1]] && [list.lastObject isEqual: strings[2]]) TEST(@"-[isEqual:]", [list isEqual: [[list copy] autorelease]]) TEST(@"-[description]", [list.description isEqual: @"[\n\tFoo,\n\tBar,\n\tBaz\n]"]) TEST(@"-[objectEnumerator]", (enumerator = [list objectEnumerator])) iter = list.firstListItem; i = 0; ok = true; while ((obj = [enumerator nextObject]) != nil) { if (![obj isEqual: OFListItemObject(iter)]) ok = false; iter = OFListItemNext(iter); i++; } if (list.count != i) ok = false; TEST(@"OFEnumerator's -[nextObject]", ok); [list removeListItem: list.firstListItem]; EXPECT_EXCEPTION(@"Detection of mutation during enumeration", OFEnumerationMutationException, [enumerator nextObject]) [list prependObject: strings[0]]; iter = list.firstListItem; i = 0; ok = true; for (OFString *object in list) { if (![object isEqual: OFListItemObject(iter)]) ok = false; iter = OFListItemNext(iter); i++; } if (list.count != i) ok = false; TEST(@"Fast Enumeration", ok) |
︙ | ︙ |