Index: src/OFDictionary.h ================================================================== --- src/OFDictionary.h +++ src/OFDictionary.h @@ -37,11 +37,21 @@ * \return A new autoreleased OFDictionary */ + dictionaryWithHashSize: (int)hashsize; /** - * Creates a new OFDictionary with the specified objects. + * Creates a new OFDictionary with the specified key and object. + * + * \param key The key + * \param obj The object + * \return A new autoreleased OFDictionary + */ ++ dictionaryWithKey: (OFObject *)key + andObject: (OFObject*)obj; + +/** + * Creates a new OFDictionary with the specified keys objects. * * \param first The first key * \return A new autoreleased OFDictionary */ + dictionaryWithKeysAndObjects: (OFObject *)first, ...; @@ -60,19 +70,32 @@ * \return An initialized OFDictionary */ - initWithHashSize: (int)hashsize; /** - * Initialized an already allocated OFDictionary with the specified objects. + * Initializes an already allocated OFDictionary with the specified key and + * object. + * + * \param key The key + * \param obj The object + * \return A new initialized OFDictionary + */ +- initWithKey: (OFObject *)key + andObject: (OFObject*)obj; + +/** + * Initializes an already allocated OFDictionary with the specified keys and + * objects. * * \param first The first key * \return A new initialized OFDictionary */ - initWithKeysAndObjects: (OFObject *)first, ...; /** - * Initialized an already allocated OFDictionary with the specified objects. + * Initializes an already allocated OFDictionary with the specified key and + * va_list. * * \param first The first key * \return A new initialized OFDictionary */ - initWithKey: (OFObject *)first Index: src/OFDictionary.m ================================================================== --- src/OFDictionary.m +++ src/OFDictionary.m @@ -31,10 +31,17 @@ + dictionaryWithHashSize: (int)hashsize { return [[[self alloc] initWithHashSize: hashsize] autorelease]; } + ++ dictionaryWithKey: (OFObject *)key + andObject: (OFObject*)obj +{ + return [[[self alloc] initWithKey: key + andObject: obj] autorelease]; +} + dictionaryWithKeysAndObjects: (OFObject *)first, ... { id ret; va_list args; @@ -97,10 +104,49 @@ } memset(data, 0, size * sizeof(OFList*)); return self; } + +- initWithKey: (OFObject *)key + andObject: (OFObject*)obj +{ + Class c; + uint32_t hash; + + self = [self init]; + + if (key == nil || obj == nil) { + c = isa; + [self dealloc]; + @throw [OFInvalidArgumentException newWithClass: isa + andSelector: _cmd]; + } + + hash = [key hash] & (size - 1); + + @try { + key = [key copy]; + } @catch (OFException *e) { + [self dealloc]; + @throw e; + } + + @try { + data[hash] = [[OFList alloc] init]; + + [data[hash] append: key]; + [data[hash] append: obj]; + } @catch (OFException *e) { + [self dealloc]; + @throw e; + } @finally { + [key release]; + } + + return self; +} - initWithKeysAndObjects: (OFObject *)first, ... { id ret; va_list args; @@ -121,19 +167,25 @@ uint32_t hash; self = [self init]; obj = va_arg(args, id); - if (obj == nil) { + if (first == nil || obj == nil) { c = isa; [self dealloc]; @throw [OFInvalidArgumentException newWithClass: isa andSelector: _cmd]; } hash = [first hash] & (size - 1); - key = [first copy]; + + @try { + key = [first copy]; + } @catch (OFException *e) { + [self dealloc]; + @throw e; + } @try { if (data[hash] == nil) data[hash] = [[OFList alloc] init]; Index: tests/OFDictionary/OFDictionary.m ================================================================== --- tests/OFDictionary/OFDictionary.m +++ tests/OFDictionary/OFDictionary.m @@ -17,15 +17,18 @@ #import "OFAutoreleasePool.h" #import "OFDictionary.h" #import "OFString.h" #import "OFExceptions.h" +#define TESTS 10 + int main() { + int i = 0; + OFDictionary *dict = [OFMutableDictionary dictionaryWithHashSize: 16]; - OFDictionary *dict2; OFIterator *iter = [dict iterator]; OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFString *key1 = [OFString stringWithCString: "key1"]; OFString *key2 = [OFString stringWithCString: "key2"]; @@ -36,66 +39,85 @@ to: value1]; [dict set: key2 to: value2]; [pool release]; + i++; if (strcmp([[dict get: @"key1"] cString], "value1")) { - puts("\033[K\033[1;31mTest 1/9 failed!\033[m"); + printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS); return 1; } + i++; if (strcmp([[dict get: key2] cString], "value2")) { - puts("\033[K\033[1;31mTest 2/9 failed!\033[m"); + printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS); return 1; } + i++; if (![[iter nextObject] isEqual: @"key2"] || ![[iter nextObject] isEqual: @"value2"] || ![[iter nextObject] isEqual: @"key1"] || ![[iter nextObject] isEqual: @"value1"]) { - puts("\033[K\033[1;31mTest 3/9 failed!\033[m"); + printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS); return 1; } + i++; [dict changeHashSize: 8]; iter = [dict iterator]; if (![[iter nextObject] isEqual: @"key1"] || ![[iter nextObject] isEqual: @"value1"] || ![[iter nextObject] isEqual: @"key2"] || ![[iter nextObject] isEqual: @"value2"]) { - puts("\033[K\033[1;31mTest 4/9 failed!\033[m"); + printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS); + return 1; + } + + i++; + if ([dict averageItemsPerBucket] != 1.0) { + printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS); return 1; } - if ([dict averageItemsPerBucket] != 1.0) { - puts("\033[K\033[1;31mTest 5/9 failed!\033[m"); + i++; + if ([iter nextObject] != nil) { + printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS); return 1; } - if ([iter nextObject] != nil) { - puts("\033[K\033[1;31mTest 6/9 failed!\033[m"); + i++; + if ([dict get: @"key3"] != nil) { + printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS); return 1; } - if ([dict get: @"key3"] != nil) { - puts("\033[K\033[1;31mTest 7/9 failed!\033[m"); - return 1; - } - - dict2 = [OFDictionary dictionaryWithKeysAndObjects: @"foo", @"bar", + i++; + [dict release]; + dict = [OFDictionary dictionaryWithKeysAndObjects: @"foo", @"bar", @"baz", @"qux", nil]; - if (![[dict2 get: @"foo"] isEqual: @"bar"]) { - puts("\033[K\033[1;31mTest 8/9 failed!\033[m"); + if (![[dict get: @"foo"] isEqual: @"bar"]) { + printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS); + return 1; + } + + i++; + if (![[dict get: @"baz"] isEqual: @"qux"]) { + printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS); return 1; } - if (![[dict2 get: @"baz"] isEqual: @"qux"]) { - puts("\033[K\033[1;31mTest 9/9 failed!\033[m"); + i++; + [dict release]; + dict = [OFDictionary dictionaryWithKey: @"foo" + andObject: @"bar"]; + if (![[dict get: @"foo"] isEqual: @"bar"]) { + printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS); return 1; } - puts("\033[1;32mTests successful: 9/9\033[0m"); + printf("\033[1;32mTests successful: %d/%d\033[0m\n", i, TESTS); return 0; }