Index: TODO ================================================================== --- TODO +++ TODO @@ -1,8 +1,9 @@ Tests for OFFile. OFArray +OFDirectory OFDictionary OFSortedArray OFSocket OFThread OFAutoreleasePool Index: src/OFArray.m ================================================================== --- src/OFArray.m +++ src/OFArray.m @@ -9,15 +9,18 @@ * the packaging of this file. */ #import #import +#import #import "OFArray.h" #import "OFExceptions.h" #import "OFMacros.h" + +static size_t pagesize = 0; @implementation OFArray + newWithItemSize: (size_t)is { return [[OFArray alloc] initWithItemSize: is]; @@ -62,10 +65,13 @@ return data + (items - 1) * itemsize; } - add: (void*)item { + if (SIZE_MAX - items < 1) + [[OFOutOfRangeException newWithObject: self] raise]; + data = [self resizeMem: data toNItems: items + 1 ofSize: itemsize]; memcpy(data + items++ * itemsize, item, itemsize); @@ -110,24 +116,54 @@ return [[OFBigArray alloc] initWithItemSize: is]; } - initWithItemSize: (size_t)is { - if ((self = [super init])) + if (pagesize == 0) + pagesize = getpagesize(); + + if ((self = [super initWithItemSize: is])) size = 0; return self; } - addNItems: (size_t)nitems fromCArray: (void*)carray { - /* FIXME */ - OF_NOT_IMPLEMENTED(self) + size_t nsize; + + if (nitems > SIZE_MAX - items || items + nitems > SIZE_MAX / itemsize) + [[OFOutOfRangeException newWithObject: self] raise]; + + nsize = (((items + nitems) * itemsize) / pagesize) + 1; + + 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 { - /* FIXME */ - OF_NOT_IMPLEMENTED(self) + size_t nsize; + + if (nitems > items) + [[OFOutOfRangeException newWithObject: self] raise]; + + nsize = (((items - nitems) * itemsize) / pagesize) + 1; + + if (size != nsize) + data = [self resizeMem: data + toSize: nsize]; + + items -= nitems; + size = nsize; + + return self; } @end Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -82,11 +82,11 @@ size_t memsize; if (nitems == 0 || size == 0) return NULL; - if (size > SIZE_MAX / nitems) + if (nitems > SIZE_MAX / size) [[OFOutOfRangeException newWithObject: self] raise]; memsize = nitems * size; return [self getMemWithSize: memsize]; } @@ -133,11 +133,11 @@ if (nitems == 0 || size == 0) { [self freeMem: ptr]; return NULL; } - if (size > SIZE_MAX / nitems) + if (nitems > SIZE_MAX / size) [[OFOutOfRangeException newWithObject: self] raise]; memsize = nitems * size; return [self resizeMem: ptr toSize: memsize]; Index: tests/OFArray/OFArray.m ================================================================== --- tests/OFArray/OFArray.m +++ tests/OFArray/OFArray.m @@ -31,91 +31,99 @@ return 1; \ } const char *str = "Hallo!"; +#define TEST(type) \ + puts("Trying to add too much to an array..."); \ + a = [type newWithItemSize: 4096]; \ + CATCH_EXCEPTION([a addNItems: SIZE_MAX \ + fromCArray: NULL], \ + OFOutOfRangeException) \ + \ + 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], \ + OFOutOfRangeException); \ + \ + puts("Trying to access an index that does not exist..."); \ + CATCH_EXCEPTION([a item: [a items]], OFOutOfRangeException); \ + \ + [a free]; \ + \ + puts("Creating new array and using it to build a string..."); \ + a = [type newWithItemSize: 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 free]; + int main() { BOOL caught; - OFArray *a; + id 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], - OFOutOfRangeException) - - 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], OFOutOfRangeException); - - puts("Trying to access an index that does not exist..."); - CATCH_EXCEPTION([a item: [a items]], OFOutOfRangeException); - - [a free]; - - puts("Creating new array and using it to build a string..."); - a = [OFArray newWithItemSize: 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 free]; + puts("== TESTING OFArray =="); + TEST(OFArray) + + puts("== TESTING OFBigArray =="); + TEST(OFBigArray) return 0; } Index: tests/OFObject/OFObject.m ================================================================== --- tests/OFObject/OFObject.m +++ tests/OFObject/OFObject.m @@ -76,18 +76,18 @@ CATCH_EXCEPTION([obj freeMem: q], OFMemNotPartOfObjException) CATCH_EXCEPTION([obj freeMem: r], OFMemNotPartOfObjException) puts("Got all 3!"); puts("Trying to allocate more memory than possible..."); - CATCH_EXCEPTION(p = [obj getMemWithSize: 4294967295U], OFNoMemException) + CATCH_EXCEPTION(p = [obj getMemWithSize: SIZE_MAX], OFNoMemException) puts("Allocating 1 byte..."); p = [obj getMemWithSize: 1]; puts("Trying to resize that 1 byte to more than possible..."); CATCH_EXCEPTION(p = [obj resizeMem: p - toSize: 4294967295U], + toSize: SIZE_MAX], OFNoMemException) puts("Trying to resize NULL to 1024 bytes..."); p = [obj resizeMem: NULL toSize: 1024];