Index: TODO ================================================================== --- TODO +++ TODO @@ -1,11 +1,11 @@ Test if autorelease pool releases everything correctly when thread is ended Proper UTF-8 support! +Tests for OFArray. Tests for OFFile. Tests for OFNumber. -readLine: for OFFile. Tests for readLine:. Serialization OFQueue Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -5,10 +5,11 @@ LIB_MINOR = 0 SRCS = OFArray.m \ OFAutoreleasePool.m \ OFConstString.m \ + OFDataArray.m \ OFDictionary.m \ OFExceptions.m \ OFFile.m \ OFHashes.m \ OFIterator.m \ Index: src/OFArray.h ================================================================== --- src/OFArray.h +++ src/OFArray.h @@ -8,116 +8,59 @@ * Q Public License 1.0, which can be found in the file LICENSE included in * the packaging of this file. */ #import "OFObject.h" - -/** - * The OFArray class provides a class for storing dynamically sized arrays. - * If you plan to store large hunks of data, you should consider using - * OFBigArray, which allocates the memory in pages and not in bytes. - */ -@interface OFArray: OFObject -{ - char *data; - size_t itemsize; - size_t items; -} - -/** - * Creates a new OFArray whose items all have the same size. - * - * \param is The size of each element in the OFArray - * \return A new autoreleased OFArray - */ -+ arrayWithItemSize: (size_t)is; - -/* - * Creates a new OFArray optimized for big arrays whose items all have the same - * size, which means memory is allocated in pages rather than in bytes. - * - * \param is The size of each element in the OFArray - * \return A new autoreleased OFArray - */ -+ bigArrayWithItemSize: (size_t)is; - -/** - * Initializes an already allocated OFArray whose items all have the same size. - * - * \param is The size of each element in the OFArray - * \return An initialized OFArray - */ -- initWithItemSize: (size_t)is; - -/** - * \return The number of items in the OFArray - */ -- (size_t)items; - -/** - * \return The size of each item in the OFArray in bytes - */ -- (size_t)itemsize; - -/** - * \return All elements of the OFArray - */ -- (void*)data; +#import "OFDataArray.h" + +/** + * The OFArray class provides a class for storing objects in an array. + */ +@interface OFArray: OFObject +{ + OFDataArray *array; +} + +/** + * \return A new autoreleased OFArray + */ ++ array; + +/** + * \return The number of objects in the OFArray + */ +- (size_t)objects; /** * Clones the OFArray, creating a new one. * * \return A new autoreleased copy of the OFArray */ - (id)copy; /** - * Compares the OFArray to another object. - * - * \param obj An object to compare with - * \return An integer which is the result of the comparison, see for example - * strcmp - */ -- (int)compare: (id)obj; - -/** - * Returns a specific item of the OFArray. - * - * \param item The number of the item to return - * \return The specified item of the OFArray - */ -- (void*)item: (size_t)item; - -/** - * \return The last item of the OFArray - */ -- (void*)last; - -/** - * Adds an item to the OFArray. - * - * \param item A pointer to an arbitrary item - */ -- add: (void*)item; - -/** - * Adds items from a C array to the OFArray. - * - * \param nitems The number of items to add - * \param carray A C array containing the items to add - */ -- addNItems: (size_t)nitems - fromCArray: (void*)carray; - -/** - * Removes a specified amount of the last items from the OFArray. - * - * \param nitems The number of items to remove - */ -- removeNItems: (size_t)nitems; -@end - -@interface OFBigArray: OFArray -{ - size_t size; -} + * Returns a specific object of the OFDataArray. + * + * \param index The number of the object to return + * \return The specified object of the OFArray + */ +- (OFObject*)object: (size_t)index; + +/** + * \return The last object of the OFDataArray + */ +- (OFObject*)last; + +/** + * Adds an object to the OFDataArray. + * + * \param obj An object to add + */ +- add: (OFObject*)obj; + +/** + * Removes the specified amount of object from the end of the OFDataArray. + * + * \param nobjects The number of objects to remove + */ +- removeNObjects: (size_t)nobjects; @end Index: src/OFArray.m ================================================================== --- src/OFArray.m +++ src/OFArray.m @@ -9,263 +9,111 @@ * the packaging of this file. */ #import "config.h" -#include -#include -#include -#include - -#import "OFArray.h" -#import "OFExceptions.h" -#import "OFMacros.h" - -static size_t lastpagebyte = 0; -extern int getpagesize(void); - -@implementation OFArray -+ arrayWithItemSize: (size_t)is -{ - return [[[OFArray alloc] initWithItemSize: is] autorelease]; -} - -+ bigArrayWithItemSize: (size_t)is -{ - return [[[OFBigArray alloc] initWithItemSize: is] autorelease]; -} - -- initWithItemSize: (size_t)is -{ - Class c; - - self = [super init]; - - if (is == 0) { - c = isa; - [super free]; - @throw [OFInvalidArgumentException newWithClass: c]; - } - - data = NULL; - itemsize = is; - items = 0; - - return self; -} - -- (size_t)items -{ - return items; -} - -- (size_t)itemsize -{ - return itemsize; -} - -- (void*)data -{ - return data; -} - -- (void*)item: (size_t)item -{ - if (item >= items) - @throw [OFOutOfRangeException newWithClass: isa]; - - return data + item * itemsize; -} - -- (void*)last -{ - return data + (items - 1) * itemsize; -} - -- add: (void*)item -{ - if (SIZE_MAX - items < 1) - @throw [OFOutOfRangeException newWithClass: isa]; - - data = [self resizeMem: data - toNItems: items + 1 - withSize: itemsize]; - - memcpy(data + items++ * itemsize, item, itemsize); - - return self; -} - -- addNItems: (size_t)nitems - fromCArray: (void*)carray -{ - if (nitems > SIZE_MAX - items) - @throw [OFOutOfRangeException newWithClass: isa]; - - data = [self resizeMem: data - toNItems: items + nitems - withSize: itemsize]; - - memcpy(data + items * itemsize, carray, nitems * itemsize); - items += nitems; - - return self; -} - -- removeNItems: (size_t)nitems -{ - if (nitems > items) - @throw [OFOutOfRangeException newWithClass: isa]; - - data = [self resizeMem: data - toNItems: items - nitems - withSize: itemsize]; - - items -= nitems; - - return self; -} - -- (id)copy -{ - OFArray *new = [OFArray arrayWithItemSize: itemsize]; - - [new addNItems: items - fromCArray: data]; - - return new; -} - -- (BOOL)isEqual: (id)obj -{ - if (![obj isKindOf: [OFArray class]]) - return NO; - if ([obj items] != items || [obj itemsize] != itemsize) - return NO; - if (memcmp([obj data], data, items * itemsize)) - return NO; - - return YES; -} - -- (int)compare: (id)obj -{ - int ret; - - if (![obj isKindOf: [OFArray class]]) - @throw [OFInvalidArgumentException newWithClass: isa - andSelector: _cmd]; - if ([obj itemsize] != itemsize) - @throw [OFInvalidArgumentException newWithClass: isa - andSelector: _cmd]; - - if ([obj items] == items) - return memcmp(data, [obj data], items * itemsize); - - if (items > [obj items]) { - if ((ret = memcmp(data, [obj data], [obj items] * itemsize))) - return ret; - - return *(char*)[self item: [obj items]]; - } else { - if ((ret = memcmp(data, [obj data], items * itemsize))) - return ret; - - return *(char*)[obj item: [self items]] * -1; - } -} - -- (uint32_t)hash -{ - uint32_t hash; - size_t i; - - OF_HASH_INIT(hash); - for (i = 0; i < items * itemsize; i++) - OF_HASH_ADD(hash, ((char*)data)[i]); - OF_HASH_FINALIZE(hash); - - return hash; -} -@end - -@implementation OFBigArray -- initWithItemSize: (size_t)is -{ - self = [super initWithItemSize: is]; - - if (lastpagebyte == 0) - lastpagebyte = getpagesize() - 1; - size = 0; - - return self; -} - -- add: (void*)item -{ - size_t nsize; - - if (SIZE_MAX - items < 1 || items + 1 > SIZE_MAX / itemsize) - @throw [OFOutOfRangeException newWithClass: isa]; - - nsize = ((items + 1) * itemsize + lastpagebyte) & ~lastpagebyte; - - if (size != nsize) - data = [self resizeMem: data - toSize: nsize]; - - memcpy(data + items++ * itemsize, item, itemsize); - size = nsize; - - return self; -} - -- addNItems: (size_t)nitems - fromCArray: (void*)carray -{ - size_t nsize; - - if (nitems > SIZE_MAX - items || items + nitems > SIZE_MAX / itemsize) - @throw [OFOutOfRangeException newWithClass: isa]; - - nsize = ((items + nitems) * itemsize + lastpagebyte) & ~lastpagebyte; - - if (size != nsize) - data = [self resizeMem: data - toSize: nsize]; - - memcpy(data + items * itemsize, carray, nitems * itemsize); - items += nitems; - size = nsize; - - return self; -} - -- removeNItems: (size_t)nitems -{ - size_t nsize; - - if (nitems > items) - @throw [OFOutOfRangeException newWithClass: isa]; - - nsize = ((items - nitems) * itemsize + lastpagebyte) & ~lastpagebyte; - - if (size != nsize) - data = [self resizeMem: data - toSize: nsize]; - - items -= nitems; - size = nsize; - - return self; -} - -- (id)copy -{ - OFArray *new = [OFArray bigArrayWithItemSize: itemsize]; - - [new addNItems: items - fromCArray: data]; - - return new; +#import "OFArray.h" +#import "OFExceptions.h" + +@implementation OFArray ++ array +{ + return [[[OFArray alloc] init] autorelease]; +} + +- init +{ + self = [super init]; + + @try { + array = [[OFDataArray alloc] + initWithItemSize: sizeof(OFObject*)]; + } @catch (OFException *e) { + /* + * We can't use [super free] on OS X here. Compiler bug? + * [self free] will do here as we check for nil in free. + */ + [self free]; + @throw e; + } + + return self; +} + +- (size_t)objects +{ + return [array items]; +} + +- (id)copy +{ + OFArray *new = [OFArray array]; + OFObject **objs; + size_t len, i; + + objs = [array data]; + len = [array items]; + + [new->array addNItems: len + fromCArray: objs]; + + for (i = 0; i < len; i++) + [objs[i] retain]; + + return new; +} + +- (OFObject*)object: (size_t)index +{ + return *((OFObject**)[array item: index]); +} + +- (OFObject*)last +{ + return *((OFObject**)[array last]); +} + +- add: (OFObject*)obj +{ + [array add: &obj]; + [obj retain]; + + return self; +} + +- removeNObjects: (size_t)nobjects +{ + OFObject **objs; + size_t len, i; + + objs = [array data]; + len = [array items]; + + if (nobjects > len) + @throw [OFOutOfRangeException newWithClass: isa]; + + for (i = len - nobjects; i < len; i++) + [objs[i] release]; + + [array removeNItems: nobjects]; + + return self; +} + +- free +{ + OFObject **objs; + size_t len, i; + + if (array != nil) { + objs = [array data]; + len = [array items]; + + for (i = 0; i < len; i++) + [objs[i] release]; + + [array release]; + } + + return [super free]; } @end Index: src/OFAutoreleasePool.m ================================================================== --- src/OFAutoreleasePool.m +++ src/OFAutoreleasePool.m @@ -95,13 +95,14 @@ } - addToPool: (OFObject*)obj { if (objects == nil) - objects = [[OFArray alloc] initWithItemSize: sizeof(char*)]; + objects = [[OFArray alloc] init]; - [objects add: &obj]; + [objects add: obj]; + [obj release]; return self; } - release @@ -111,23 +112,14 @@ return [super release]; } - releaseObjects { - size_t i, size; - IMP get_item; - if (objects == nil) return self; - size = [objects items]; - get_item = [objects methodFor: @selector(item:)]; - - for (i = 0; i < size; i++) - [*((OFObject**)get_item(objects, @selector(item:), i)) release]; - [objects release]; objects = nil; return self; } @end Index: src/OFConstString.m ================================================================== --- src/OFConstString.m +++ src/OFConstString.m @@ -7,11 +7,11 @@ * 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 "config.h" #import "OFConstString.h" #ifndef __objc_INCLUDE_GNU void *_OFConstStringClassReference; ADDED src/OFDataArray.h Index: src/OFDataArray.h ================================================================== --- src/OFDataArray.h +++ src/OFDataArray.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2008 - 2009 + * 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 "OFObject.h" + +/** + * The OFDataArray class provides a class for storing arbitrary data in an + * array. + * + * If you plan to store large hunks of data, you should consider using + * OFBigDataArray, which allocates the memory in pages rather than in bytes. + */ +@interface OFDataArray: OFObject +{ + char *data; + size_t itemsize; + size_t items; +} + +/** + * Creates a new OFDataArray whose items all have the same size. + * + * \param is The size of each element in the OFDataArray + * \return A new autoreleased OFDataArray + */ ++ dataArrayWithItemSize: (size_t)is; + +/* + * Creates a new OFDataArray optimized for big arrays whose items all have the + * same size, which means memory is allocated in pages rather than in bytes. + * + * \param is The size of each element in the OFBigDataArray + * \return A new autoreleased OFBigDataArray + */ ++ bigDataArrayWithItemSize: (size_t)is; + +/** + * Initializes an already allocated OFDataArray whose items all have the same + * size. + * + * \param is The size of each element in the OFDataArray + * \return An initialized OFDataArray + */ +- initWithItemSize: (size_t)is; + +/** + * \return The number of items in the OFDataArray + */ +- (size_t)items; + +/** + * \return The size of each item in the OFDataArray in bytes + */ +- (size_t)itemsize; + +/** + * \return All elements of the OFDataArray + */ +- (void*)data; + +/** + * Clones the OFDataArray, creating a new one. + * + * \return A new autoreleased copy of the OFDataArray + */ +- (id)copy; + +/** + * Compares the OFDataArray to another object. + * + * \param obj An object to compare with + * \return An integer which is the result of the comparison, see for example + * strcmp + */ +- (int)compare: (id)obj; + +/** + * Returns a specific item of the OFDataArray. + * + * \param index The number of the item to return + * \return The specified item of the OFDataArray + */ +- (void*)item: (size_t)index; + +/** + * \return The last item of the OFDataArray + */ +- (void*)last; + +/** + * Adds an item to the OFDataArray. + * + * \param item A pointer to an arbitrary item + */ +- add: (void*)item; + +/** + * Adds items from a C array to the OFDataArray. + * + * \param nitems The number of items to add + * \param carray A C array containing the items to add + */ +- addNItems: (size_t)nitems + fromCArray: (void*)carray; + +/** + * Removes the specified amount of items from the end of the OFDataArray. + * + * \param nitems The number of items to remove + */ +- removeNItems: (size_t)nitems; +@end + +@interface OFBigDataArray: OFDataArray +{ + size_t size; +} +@end ADDED src/OFDataArray.m Index: src/OFDataArray.m ================================================================== --- src/OFDataArray.m +++ src/OFDataArray.m @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2008 - 2009 + * 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 "config.h" + +#include +#include +#include +#include + +#import "OFDataArray.h" +#import "OFExceptions.h" +#import "OFMacros.h" + +static size_t lastpagebyte = 0; +extern int getpagesize(void); + +@implementation OFDataArray ++ dataArrayWithItemSize: (size_t)is +{ + return [[[OFDataArray alloc] initWithItemSize: is] autorelease]; +} + ++ bigDataArrayWithItemSize: (size_t)is +{ + return [[[OFBigDataArray alloc] initWithItemSize: is] autorelease]; +} + +- initWithItemSize: (size_t)is +{ + Class c; + + self = [super init]; + + if (is == 0) { + c = isa; + [super free]; + @throw [OFInvalidArgumentException newWithClass: c]; + } + + data = NULL; + itemsize = is; + items = 0; + + return self; +} + +- (size_t)items +{ + return items; +} + +- (size_t)itemsize +{ + return itemsize; +} + +- (void*)data +{ + return data; +} + +- (void*)item: (size_t)index +{ + if (index >= items) + @throw [OFOutOfRangeException newWithClass: isa]; + + return data + index * itemsize; +} + +- (void*)last +{ + return data + (items - 1) * itemsize; +} + +- add: (void*)item +{ + if (SIZE_MAX - items < 1) + @throw [OFOutOfRangeException newWithClass: isa]; + + data = [self resizeMem: data + toNItems: items + 1 + withSize: itemsize]; + + memcpy(data + items++ * itemsize, item, itemsize); + + return self; +} + +- addNItems: (size_t)nitems + fromCArray: (void*)carray +{ + if (nitems > SIZE_MAX - items) + @throw [OFOutOfRangeException newWithClass: isa]; + + data = [self resizeMem: data + toNItems: items + nitems + withSize: itemsize]; + + memcpy(data + items * itemsize, carray, nitems * itemsize); + items += nitems; + + return self; +} + +- removeNItems: (size_t)nitems +{ + if (nitems > items) + @throw [OFOutOfRangeException newWithClass: isa]; + + data = [self resizeMem: data + toNItems: items - nitems + withSize: itemsize]; + + items -= nitems; + + return self; +} + +- (id)copy +{ + OFDataArray *new = [OFDataArray dataArrayWithItemSize: itemsize]; + [new addNItems: items + fromCArray: data]; + + return new; +} + +- (BOOL)isEqual: (id)obj +{ + if (![obj isKindOf: [OFDataArray class]]) + return NO; + if ([obj items] != items || [obj itemsize] != itemsize) + return NO; + if (memcmp([obj data], data, items * itemsize)) + return NO; + + return YES; +} + +- (int)compare: (id)obj +{ + int ret; + + if (![obj isKindOf: [OFDataArray class]]) + @throw [OFInvalidArgumentException newWithClass: isa + andSelector: _cmd]; + if ([obj itemsize] != itemsize) + @throw [OFInvalidArgumentException newWithClass: isa + andSelector: _cmd]; + + if ([obj items] == items) + return memcmp(data, [obj data], items * itemsize); + + if (items > [obj items]) { + if ((ret = memcmp(data, [obj data], [obj items] * itemsize))) + return ret; + + return *(char*)[self item: [obj items]]; + } else { + if ((ret = memcmp(data, [obj data], items * itemsize))) + return ret; + + return *(char*)[obj item: [self items]] * -1; + } +} + +- (uint32_t)hash +{ + uint32_t hash; + size_t i; + + OF_HASH_INIT(hash); + for (i = 0; i < items * itemsize; i++) + OF_HASH_ADD(hash, ((char*)data)[i]); + OF_HASH_FINALIZE(hash); + + return hash; +} +@end + +@implementation OFBigDataArray +- initWithItemSize: (size_t)is +{ + self = [super initWithItemSize: is]; + + if (lastpagebyte == 0) + lastpagebyte = getpagesize() - 1; + size = 0; + + return self; +} + +- add: (void*)item +{ + size_t nsize; + + if (SIZE_MAX - items < 1 || items + 1 > SIZE_MAX / itemsize) + @throw [OFOutOfRangeException newWithClass: isa]; + + nsize = ((items + 1) * itemsize + lastpagebyte) & ~lastpagebyte; + + if (size != nsize) + data = [self resizeMem: data + toSize: nsize]; + + memcpy(data + items++ * itemsize, item, itemsize); + size = nsize; + + return self; +} + +- addNItems: (size_t)nitems + fromCArray: (void*)carray +{ + size_t nsize; + + if (nitems > SIZE_MAX - items || items + nitems > SIZE_MAX / itemsize) + @throw [OFOutOfRangeException newWithClass: isa]; + + nsize = ((items + nitems) * itemsize + lastpagebyte) & ~lastpagebyte; + + if (size != nsize) + data = [self resizeMem: data + toSize: nsize]; + + memcpy(data + items * itemsize, carray, nitems * itemsize); + items += nitems; + size = nsize; + + return self; +} + +- removeNItems: (size_t)nitems +{ + size_t nsize; + + if (nitems > items) + @throw [OFOutOfRangeException newWithClass: isa]; + + nsize = ((items - nitems) * itemsize + lastpagebyte) & ~lastpagebyte; + + if (size != nsize) + data = [self resizeMem: data + toSize: nsize]; + + items -= nitems; + size = nsize; + + return self; +} + +- (id)copy +{ + OFDataArray *new = [OFDataArray bigDataArrayWithItemSize: itemsize]; + + [new addNItems: items + fromCArray: data]; + + return new; +} +@end Index: src/OFIterator.m ================================================================== --- src/OFIterator.m +++ src/OFIterator.m @@ -7,11 +7,11 @@ * 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 "config.h" #import "OFIterator.h" #import "OFDictionary.h" #import "OFExceptions.h" Index: src/OFStream.m ================================================================== --- src/OFStream.m +++ src/OFStream.m @@ -7,11 +7,11 @@ * 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 "config.h" #include #include #import "OFStream.h" Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -1,10 +1,10 @@ include ../extra.mk SUBDIRS = OFObject \ OFAutoreleasePool \ - OFArray \ + OFDataArray \ OFDictionary \ OFHashes \ ${OFPLUGIN} \ OFString \ OFTCPSocket \ DELETED tests/OFArray/Makefile Index: tests/OFArray/Makefile ================================================================== --- tests/OFArray/Makefile +++ tests/OFArray/Makefile @@ -1,23 +0,0 @@ -PROG_NOINST = ofarray${PROG_SUFFIX} -SRCS = OFArray.m - -include ../../buildsys.mk -include ../../extra.mk - -CPPFLAGS += -I../../src -I../.. -LIBS := -L../../src -lobjfw ${LIBS} - -.PHONY: run - -all: run -run: ${PROG_NOINST} - rm -f libobjfw.so.1 libobjfw.so.1.0 libobjfw.dll libobjfw.dylib - ln -s ../../src/libobjfw.so libobjfw.so.1 - ln -s ../../src/libobjfw.so libobjfw.so.1.0 - ln -s ../../src/libobjfw.dll libobjfw.dll - ln -s ../../src/libobjfw.dylib libobjfw.dylib - LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ - DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \ - ${TEST_LAUNCHER} ./${PROG_NOINST}; EXIT=$$?; \ - rm -f libobjfw.so.1 libobjfw.so.1.0 libobjfw.dll libobjfw.dylib; \ - exit $$EXIT DELETED tests/OFArray/OFArray.m Index: tests/OFArray/OFArray.m ================================================================== --- tests/OFArray/OFArray.m +++ tests/OFArray/OFArray.m @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2008 - 2009 - * 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 "config.h" - -#include -#include -#include -#include - -#import "OFArray.h" -#import "OFExceptions.h" -#import "OFAutoreleasePool.h" - -#define CATCH_EXCEPTION(code, exception) \ - @try { \ - code; \ - \ - puts("NOT CAUGHT!"); \ - return 1; \ - } @catch (exception *e) { \ - puts("CAUGHT! Error string was:"); \ - puts([e cString]); \ - puts("Resuming..."); \ - } - -const char *str = "Hallo!"; - -#define TEST(type) \ - puts("Trying to add too much to an array..."); \ - a = [[type alloc] initWithItemSize: 4096]; \ - CATCH_EXCEPTION([a addNItems: SIZE_MAX \ - fromCArray: NULL], \ - OFOutOfRangeException) \ - \ - puts("Trying to add something after that error..."); \ - p = [a allocWithSize: 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 allocWithSize: 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 allocWithSize: 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], \ - OFOutOfRangeException); \ - \ - puts("Trying to access an index that does not exist..."); \ - CATCH_EXCEPTION([a item: [a items]], OFOutOfRangeException); \ - \ - [a release]; \ - \ - puts("Creating new array and using it to build a string..."); \ - a = [[type alloc] initWithItemSize: 1]; \ - \ - for (i = 0; i < strlen(str); i++) \ - [a add: (void*)&str[i]]; \ - [a add: ""]; \ - \ - if (!strcmp([a data], str)) \ - puts("Built string matches!"); \ - else { \ - puts("Built string does not match!"); \ - abort(); \ - } \ - \ - [a release]; - -int -main() -{ - id a; - void *p, *q; - size_t i; - OFArray *x, *y; - OFAutoreleasePool *pool; - - puts("== TESTING OFArray =="); - TEST(OFArray) - - puts("== TESTING OFBigArray =="); - TEST(OFBigArray) - - pool = [[OFAutoreleasePool alloc] init]; - x = [OFArray arrayWithItemSize: 1]; - y = [OFArray bigArrayWithItemSize: 1]; - - if (![x isEqual: y]) { - puts("FAIL 1!"); - return 1; - } - - if ([x hash] != [y hash]) { - puts("FAIL 2!"); - return 1; - } - - [x add: "x"]; - if ([x isEqual: y]) { - puts("FAIL 3!"); - return 1; - } - [pool releaseObjects]; - - x = [OFArray arrayWithItemSize: 2]; - y = [OFArray bigArrayWithItemSize: 4]; - - if ([x isEqual: y]) { - puts("FAIL 4!"); - return 1; - } - [pool releaseObjects]; - - x = [OFArray arrayWithItemSize: 1]; - [x addNItems: 3 - fromCArray: "abc"]; - y = [x copy]; - if ([x compare: y]) { - puts("FAIL 5!"); - return 1; - } - - [y add: "de"]; - if ([x compare: y] != -100) { - puts("FAIL 6!"); - return 1; - } - - if ([y hash] != 0xCD8B6206) { - puts("FAIL 7!"); - return 1; - } - [pool release]; - - return 0; -} Index: tests/OFAutoreleasePool/OFAutoreleasePool.m ================================================================== --- tests/OFAutoreleasePool/OFAutoreleasePool.m +++ tests/OFAutoreleasePool/OFAutoreleasePool.m @@ -100,7 +100,7 @@ [pool1 retain]; [pool1 release]; [pool1 release]; [o3 free]; - return (inits == 16 && retains == 2 && releases == 7 ? 0 : 1); + return (inits == 20 && retains == 6 && releases == 13 ? 0 : 1); } ADDED tests/OFDataArray/Makefile Index: tests/OFDataArray/Makefile ================================================================== --- tests/OFDataArray/Makefile +++ tests/OFDataArray/Makefile @@ -0,0 +1,23 @@ +PROG_NOINST = ofdataarray${PROG_SUFFIX} +SRCS = OFDataArray.m + +include ../../buildsys.mk +include ../../extra.mk + +CPPFLAGS += -I../../src -I../.. +LIBS := -L../../src -lobjfw ${LIBS} + +.PHONY: run + +all: run +run: ${PROG_NOINST} + rm -f libobjfw.so.1 libobjfw.so.1.0 libobjfw.dll libobjfw.dylib + ln -s ../../src/libobjfw.so libobjfw.so.1 + ln -s ../../src/libobjfw.so libobjfw.so.1.0 + ln -s ../../src/libobjfw.dll libobjfw.dll + ln -s ../../src/libobjfw.dylib libobjfw.dylib + LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ + DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \ + ${TEST_LAUNCHER} ./${PROG_NOINST}; EXIT=$$?; \ + rm -f libobjfw.so.1 libobjfw.so.1.0 libobjfw.dll libobjfw.dylib; \ + exit $$EXIT ADDED tests/OFDataArray/OFDataArray.m Index: tests/OFDataArray/OFDataArray.m ================================================================== --- tests/OFDataArray/OFDataArray.m +++ tests/OFDataArray/OFDataArray.m @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2008 - 2009 + * 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 "config.h" + +#include +#include +#include +#include + +#import "OFDataArray.h" +#import "OFExceptions.h" +#import "OFAutoreleasePool.h" + +#define CATCH_EXCEPTION(code, exception) \ + @try { \ + code; \ + \ + puts("NOT CAUGHT!"); \ + return 1; \ + } @catch (exception *e) { \ + puts("CAUGHT! Error string was:"); \ + puts([e cString]); \ + puts("Resuming..."); \ + } + +const char *str = "Hallo!"; + +#define TEST(type) \ + puts("Trying to add too much to an array..."); \ + a = [[type alloc] initWithItemSize: 4096]; \ + CATCH_EXCEPTION([a addNItems: SIZE_MAX \ + fromCArray: NULL], \ + OFOutOfRangeException) \ + \ + puts("Trying to add something after that error..."); \ + p = [a allocWithSize: 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 allocWithSize: 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 allocWithSize: 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], \ + OFOutOfRangeException); \ + \ + puts("Trying to access an index that does not exist..."); \ + CATCH_EXCEPTION([a item: [a items]], OFOutOfRangeException); \ + \ + [a release]; \ + \ + puts("Creating new array and using it to build a string..."); \ + a = [[type alloc] initWithItemSize: 1]; \ + \ + for (i = 0; i < strlen(str); i++) \ + [a add: (void*)&str[i]]; \ + [a add: ""]; \ + \ + if (!strcmp([a data], str)) \ + puts("Built string matches!"); \ + else { \ + puts("Built string does not match!"); \ + abort(); \ + } \ + \ + [a release]; + +int +main() +{ + id a; + void *p, *q; + size_t i; + OFDataArray *x, *y; + OFAutoreleasePool *pool; + + puts("== TESTING OFDataArray =="); + TEST(OFDataArray) + + puts("== TESTING OFBigArray =="); + TEST(OFBigDataArray) + + pool = [[OFAutoreleasePool alloc] init]; + x = [OFDataArray dataArrayWithItemSize: 1]; + y = [OFDataArray bigDataArrayWithItemSize: 1]; + + if (![x isEqual: y]) { + puts("FAIL 1!"); + return 1; + } + + if ([x hash] != [y hash]) { + puts("FAIL 2!"); + return 1; + } + + [x add: "x"]; + if ([x isEqual: y]) { + puts("FAIL 3!"); + return 1; + } + [pool releaseObjects]; + + x = [OFDataArray dataArrayWithItemSize: 2]; + y = [OFDataArray bigDataArrayWithItemSize: 4]; + + if ([x isEqual: y]) { + puts("FAIL 4!"); + return 1; + } + [pool releaseObjects]; + + x = [OFDataArray dataArrayWithItemSize: 1]; + [x addNItems: 3 + fromCArray: "abc"]; + y = [x copy]; + if ([x compare: y]) { + puts("FAIL 5!"); + return 1; + } + + [y add: "de"]; + if ([x compare: y] != -100) { + puts("FAIL 6!"); + return 1; + } + + if ([y hash] != 0xCD8B6206) { + puts("FAIL 7!"); + return 1; + } + [pool release]; + + return 0; +}