Index: src/OFArray.h ================================================================== --- src/OFArray.h +++ src/OFArray.h @@ -13,30 +13,31 @@ #import "OFObject.h" @interface OFArray: OFObject { - void *data; + char *data; size_t itemsize; - size_t size; + size_t items; } ++ newWithItemSize: (size_t)is; - initWithItemSize: (size_t)is; -- (size_t)size; +- (size_t)items; - (void*)item: (size_t)item; - (void*)last; - add: (void*)item; - addNItems: (size_t)nitems fromCArray: (void*)carray; -- removeLastNItems: (size_t)nitems; +- removeNItems: (size_t)nitems; @end @interface OFBigArray: OFArray { - size_t realsize; + size_t size; } - initWithSize: (size_t)is; - addNItems: (size_t)nitems fromCArray: (void*)carray; -- removeLastNItems: (size_t)nitems; +- removeNItems: (size_t)nitems; @end Index: src/OFArray.m ================================================================== --- src/OFArray.m +++ src/OFArray.m @@ -7,74 +7,106 @@ * This file is part of libobjfw. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE included in * the packaging of this file. */ +#import +#import + #import "OFArray.h" #import "OFExceptions.h" #import "OFMacros.h" @implementation OFArray ++ newWithItemSize: (size_t)is +{ + return [[OFArray alloc] initWithItemSize: is]; +} + - initWithItemSize: (size_t)is { if ((self = [super init])) { data = NULL; itemsize = is; - size = 0; + items = 0; } return self; } -- (size_t)size +- (size_t)items { - return size; + return items; } - (size_t)itemsize { return itemsize; } - (void*)item: (size_t)item { - /* FIXME */ - OF_NOT_IMPLEMENTED(NULL) + if (item >= items) + /* FIXME: Maybe OFOutOfRangeException would be better? */ + [[OFOverflowException newWithObject: self] raise]; + + return data + item * itemsize; } - (void*)last { - /* FIXME */ - OF_NOT_IMPLEMENTED(NULL) + return data + (items - 1) * itemsize; } - add: (void*)item { - return [self addNItems: 1 - fromCArray: item]; + data = [self resizeMem: data + toNItems: items + 1 + ofSize: itemsize]; + + memcpy(data + items++ * itemsize, item, itemsize); + + return self; } - addNItems: (size_t)nitems fromCArray: (void*)carray { - /* FIXME */ - OF_NOT_IMPLEMENTED(self) + if (nitems > SIZE_MAX - items) + [[OFOverflowException newWithObject: self] raise]; + + data = [self resizeMem: data + toNItems: items + nitems + ofSize: itemsize]; + + memcpy(data + items * itemsize, carray, nitems * itemsize); + items += nitems; + + return self; } -- removeLastNItems: (size_t)nitems +- removeNItems: (size_t)nitems { - /* FIXME */ - OF_NOT_IMPLEMENTED(self) + if (nitems > items) + [[OFOverflowException newWithObject: self] raise]; + + data = [self resizeMem: data + toNItems: items - nitems + ofSize: itemsize]; + + items -= nitems; + + return self; } @end @implementation OFBigArray - initWithSize: (size_t)is { if ((self = [super init])) - realsize = 0; + size = 0; return self; } - addNItems: (size_t)nitems @@ -82,11 +114,11 @@ { /* FIXME */ OF_NOT_IMPLEMENTED(self) } -- removeLastNItems: (size_t)nitems +- removeNItems: (size_t)nitems { /* FIXME */ OF_NOT_IMPLEMENTED(self) } @end Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -1,3 +1,3 @@ -SUBDIRS = OFObject OFHashes OFString OFList OFWideString OFXMLFactory +SUBDIRS = OFObject OFArray OFHashes OFString OFList OFWideString OFXMLFactory include ../buildsys.mk ADDED tests/OFArray/Makefile Index: tests/OFArray/Makefile ================================================================== --- tests/OFArray/Makefile +++ tests/OFArray/Makefile @@ -0,0 +1,19 @@ +PROG_NOINST = ofarray +SRCS = OFArray.m + +include ../../buildsys.mk + +CPPFLAGS += -I../../src +LIBS += -lobjc -L../../src -lobjfw + +.PHONY: run + +all: run +run: ${PROG_NOINST} + rm -f libobjfw.so.1 libobjfw.dylib + ln -s ../../src/libobjfw.so libobjfw.so.1 + ln -s ../../src/libobjfw.dylib libobjfw.dylib + LD_LIBRARY_PATH=. \ + DYLD_LIBRARY_PATH=. \ + ./${PROG_NOINST} + rm -f libobjfw.so.1 libobjfw.dylib ADDED tests/OFArray/OFArray.m Index: tests/OFArray/OFArray.m ================================================================== --- tests/OFArray/OFArray.m +++ tests/OFArray/OFArray.m @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2008 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of libobjfw. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE included in + * the packaging of this file. + */ + +#import +#import +#import + +#import "OFArray.h" +#import "OFExceptions.h" + +#define CATCH_EXCEPTION(code, exception) \ + caught = NO; \ + @try { \ + code; \ + } @catch (exception *e) { \ + caught = YES; \ + puts("CAUGHT! Error string was:"); \ + fputs([e cString], stdout); \ + puts("Resuming..."); \ + } \ + if (!caught) { \ + puts("NOT CAUGHT!"); \ + return 1; \ + } + +int +main() +{ + BOOL caught; + OFArray *a; + void *p, *q; + size_t i; + + puts("Trying to add too much to an array..."); + a = [OFArray newWithItemSize: 4096]; + CATCH_EXCEPTION([a addNItems: SIZE_MAX + fromCArray: NULL], + OFOverflowException) + + puts("Trying to add something after that error..."); + p = [a getMemWithSize: 4096]; + memset(p, 255, 4096); + [a add: p]; + if (!memcmp([a last], p, 4096)) + puts("[a last] matches with p!"); + else { + puts("[a last] does not match p!"); + abort(); + } + [a freeMem: p]; + + puts("Adding more data..."); + q = [a getMemWithSize: 4096]; + memset(q, 42, 4096); + [a add: q]; + if (!memcmp([a last], q, 4096)) + puts("[a last] matches with q!"); + else { + puts("[a last] does not match q!"); + abort(); + } + [a freeMem: q]; + + puts("Adding multiple items at once..."); + p = [a getMemWithSize: 8192]; + memset(p, 64, 8192); + [a addNItems: 2 + fromCArray: p]; + if (!memcmp([a last], [a item: [a items] - 2], 4096) && + !memcmp([a item: [a items] - 2], p, 4096)) + puts("[a last], [a item: [a items] - 2] and p match!"); + else { + puts("[a last], [a item: [a items] - 2] and p did not match!"); + abort(); + } + [a freeMem: p]; + + i = [a items]; + puts("Removing 2 items..."); + [a removeNItems: 2]; + if ([a items] + 2 != i) { + puts("[a items] + 2 != i!"); + abort(); + } + + puts("Trying to remove more data than we added..."); + CATCH_EXCEPTION([a removeNItems: [a items] + 1], OFOverflowException); + + puts("Trying to access an index that does not exist..."); + CATCH_EXCEPTION([a item: [a items]], OFOverflowException); + + [a free]; + return 0; +}