Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -71,10 +71,12 @@ macros.h \ objfw-defs.h \ ${THREADING_H} SRCS += OFArray_adjacent.m \ + OFArray_adjacentSubarray.m \ + OFArray_subarray.m \ OFCountedSet_hashtable.m \ OFDictionary_hashtable.m \ OFMutableArray_adjacent.m \ OFMutableDictionary_hashtable.m \ OFMutableSet_hashtable.m \ Index: src/OFArray.m ================================================================== --- src/OFArray.m +++ src/OFArray.m @@ -17,10 +17,11 @@ #include "config.h" #include #import "OFArray.h" +#import "OFArray_subarray.h" #import "OFArray_adjacent.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFAutoreleasePool.h" @@ -336,11 +337,17 @@ } - (OFArray*)objectsInRange: (of_range_t)range { OFArray *ret; - id *buffer = [self allocMemoryForNItems: range.length + id *buffer; + + if (![self isKindOfClass: [OFMutableArray class]]) + return [OFArray_subarray arrayWithArray: self + range: range]; + + buffer = [self allocMemoryForNItems: range.length withSize: sizeof(*buffer)]; @try { [self getObjects: buffer inRange: range]; Index: src/OFArray_adjacent.m ================================================================== --- src/OFArray_adjacent.m +++ src/OFArray_adjacent.m @@ -18,10 +18,11 @@ #include #import "OFArray_adjacent.h" #import "OFMutableArray_adjacent.h" +#import "OFArray_adjacentSubarray.h" #import "OFDataArray.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFAutoreleasePool.h" @@ -269,11 +270,17 @@ } - (OFArray*)objectsInRange: (of_range_t)range { - size_t count = [array count]; + size_t count; + + if (![self isKindOfClass: [OFMutableArray class]]) + return [OFArray_adjacentSubarray arrayWithArray: self + range: range]; + + count = [array count]; if (range.start + range.length > count) @throw [OFOutOfRangeException newWithClass: isa]; return [OFArray arrayWithCArray: (id*)[array cArray] + range.start @@ -285,11 +292,12 @@ OFArray *otherArray; id *cArray, *otherCArray; size_t i, count; if ([object class] != [OFArray_adjacent class] && - [object class] != [OFMutableArray_adjacent class]) + [object class] != [OFMutableArray_adjacent class] && + [object class] != [OFArray_adjacentSubarray class]) return [super isEqual: object]; otherArray = object; count = [array count]; ADDED src/OFArray_adjacentSubarray.h Index: src/OFArray_adjacentSubarray.h ================================================================== --- src/OFArray_adjacentSubarray.h +++ src/OFArray_adjacentSubarray.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 + * 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 + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFArray_subarray.h" + +@interface OFArray_adjacentSubarray: OFArray_subarray +@end ADDED src/OFArray_adjacentSubarray.m Index: src/OFArray_adjacentSubarray.m ================================================================== --- src/OFArray_adjacentSubarray.m +++ src/OFArray_adjacentSubarray.m @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 + * 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 + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFArray_adjacentSubarray.h" +#import "OFArray_adjacent.h" +#import "OFMutableArray_adjacent.h" + +@implementation OFArray_adjacentSubarray +- (id*)cArray +{ + return [array cArray] + range.start; +} + +- (BOOL)isEqual: (id)object +{ + OFArray *otherArray; + id *cArray, *otherCArray; + size_t i; + + if ([object class] != [OFArray_adjacent class] && + [object class] != [OFMutableArray_adjacent class] && + [object class] != [OFArray_adjacentSubarray class]) + return [super isEqual: object]; + + otherArray = object; + + if (range.length != [otherArray count]) + return NO; + + cArray = [self cArray]; + otherCArray = [otherArray cArray]; + + for (i = 0; i < range.length; i++) + if (![cArray[i] isEqual: otherCArray[i]]) + return NO; + + return YES; +} + +#ifdef OF_HAVE_BLOCKS +- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block +{ + id *cArray = [self cArray]; + size_t i; + BOOL stop = NO; + + for (i = 0; i < range.length && !stop; i++) + block(cArray[i], i, &stop); +} +#endif +@end ADDED src/OFArray_subarray.h Index: src/OFArray_subarray.h ================================================================== --- src/OFArray_subarray.h +++ src/OFArray_subarray.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 + * 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 + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFArray.h" + +@interface OFArray_subarray: OFArray +{ + OFArray *array; + of_range_t range; +} + ++ arrayWithArray: (OFArray*)array + range: (of_range_t)range; +- initWithArray: (OFArray*)array + range: (of_range_t)range; +@end ADDED src/OFArray_subarray.m Index: src/OFArray_subarray.m ================================================================== --- src/OFArray_subarray.m +++ src/OFArray_subarray.m @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 + * 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 + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFArray_subarray.h" + +#import "OFOutOfRangeException.h" + +@implementation OFArray_subarray ++ arrayWithArray: (OFArray*)array + range: (of_range_t)range +{ + return [[[self alloc] initWithArray: array + range: range] autorelease]; +} + +- initWithArray: (OFArray*)array_ + range: (of_range_t)range_ +{ + self = [super init]; + + @try { + /* Should usually be retain, as it's useless with a copy */ + array = [array_ copy]; + range = range_; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [array release]; + + [super dealloc]; +} + +- (size_t)count +{ + return range.length; +} + +- (id)objectAtIndex: (size_t)index +{ + if (index >= range.length) + @throw [OFOutOfRangeException newWithClass: isa]; + + return [array objectAtIndex: index + range.start]; +} + +- (void)getObjects: (id*)buffer + inRange: (of_range_t)range_ +{ + if (range_.start + range_.length > range.length) + @throw [OFOutOfRangeException newWithClass: isa]; + + range_.start += range.start; + + return [array getObjects: buffer + inRange: range_]; +} + +- (size_t)indexOfObject: (id)object +{ + size_t index = [array indexOfObject: object] + range.start; + + if (index > range.length) + index = OF_INVALID_INDEX; + + return index; +} + +- (size_t)indexOfObjectIdenticalTo: (id)object +{ + size_t index = [array indexOfObjectIdenticalTo: object] + range.start; + + if (index > range.length) + index = OF_INVALID_INDEX; + + return index; +} + +- (OFArray*)objectsInRange: (of_range_t)range_ +{ + if (range_.start + range_.length > range.length) + @throw [OFOutOfRangeException newWithClass: isa]; + + range_.start += range.start; + + return [array objectsInRange: range_]; +} +@end