@@ -1,7 +1,7 @@ /* - * Copyright (c) 2008-2022 Jonathan Schleifer + * Copyright (c) 2008-2024 Jonathan Schleifer * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in @@ -15,22 +15,21 @@ #include "config.h" #include -#import "OFAdjacentArray.h" -#import "OFAdjacentSubarray.h" +#import "OFConcreteArray.h" +#import "OFConcreteMutableArray.h" +#import "OFConcreteSubarray.h" #import "OFData.h" -#import "OFMutableAdjacentArray.h" #import "OFString.h" -#import "OFXMLElement.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" -@implementation OFAdjacentArray +@implementation OFConcreteArray - (instancetype)init { self = [super init]; @try { @@ -124,11 +123,11 @@ return self; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { - self = [self init]; + self = [super init]; @try { bool ok = true; for (size_t i = 0; i < count; i++) { @@ -139,52 +138,21 @@ } if (!ok) @throw [OFInvalidArgumentException exception]; + _array = [[OFMutableData alloc] initWithItemSize: sizeof(id) + capacity: count]; [_array addItems: objects count: count]; } @catch (id e) { for (size_t i = 0; i < count; i++) [objects[i] release]; [self release]; @throw e; } - return self; -} - -- (instancetype)initWithSerialization: (OFXMLElement *)element -{ - self = [self init]; - - @try { - void *pool = objc_autoreleasePoolPush(); - - if ((![element.name isEqual: @"OFArray"] && - ![element.name isEqual: @"OFMutableArray"]) || - ![element.namespace isEqual: OFSerializationNS]) - @throw [OFInvalidArgumentException exception]; - - for (OFXMLElement *child in - [element elementsForNamespace: OFSerializationNS]) { - void *pool2 = objc_autoreleasePoolPush(); - id object; - - object = child.objectByDeserializing; - [_array addItem: &object]; - [object retain]; - - objc_autoreleasePoolPop(pool2); - } - - objc_autoreleasePoolPop(pool); - } @catch (id e) { - [self release]; - @throw e; - } - return self; } - (size_t)count { @@ -265,11 +233,12 @@ if ([self isKindOfClass: [OFMutableArray class]]) return [OFArray arrayWithObjects: (id *)_array.items + range.location count: range.length]; - return [OFAdjacentSubarray arrayWithArray: self range: range]; + return [[[OFConcreteSubarray alloc] initWithArray: self + range: range] autorelease]; } - (bool)isEqual: (id)object { OFArray *otherArray; @@ -277,12 +246,12 @@ size_t count; if (object == self) return true; - if (![object isKindOfClass: [OFAdjacentArray class]] && - ![object isKindOfClass: [OFMutableAdjacentArray class]]) + if (![object isKindOfClass: [OFConcreteArray class]] && + ![object isKindOfClass: [OFConcreteMutableArray class]]) return [super isEqual: object]; otherArray = object; count = _array.count; @@ -318,10 +287,11 @@ - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count_ { + static unsigned long dummyMutations; size_t count = _array.count; if (count > INT_MAX) /* * Use the implementation from OFArray, which is slower, but can @@ -334,11 +304,11 @@ if (state->state >= count) return 0; state->state = (unsigned long)count; state->itemsPtr = (id *)_array.items; - state->mutationsPtr = (unsigned long *)self; + state->mutationsPtr = &dummyMutations; return (int)count; } #ifdef OF_HAVE_BLOCKS