Index: src/OFDictionary.h ================================================================== --- src/OFDictionary.h +++ src/OFDictionary.h @@ -11,10 +11,11 @@ #include #import "OFObject.h" #import "OFList.h" +#import "OFArray.h" /** * The OFDictionary class provides a class for using hash tables. */ @interface OFDictionary: OFObject @@ -46,10 +47,20 @@ * \return A new autoreleased OFDictionary */ + dictionaryWithKey: (OFObject *)key andObject: (OFObject*)obj; +/** + * Creates a new OFDictionary with the specified keys and objects. + * + * \param keys An array of keys + * \param objs An array of objects + * \return A new autoreleased OFDictionary + */ ++ dictionaryWithKeys: (OFArray*)keys + andObjects: (OFArray*)objs; + /** * Creates a new OFDictionary with the specified keys objects. * * \param first The first key * \return A new autoreleased OFDictionary @@ -80,10 +91,21 @@ * \return A new initialized OFDictionary */ - initWithKey: (OFObject *)key andObject: (OFObject*)obj; +/** + * Initializes an already allocated OFDictionary with the specified keys and + * objects. + * + * \param keys An array of keys + * \param objs An array of objects + * \return A new initialized OFDictionary + */ +- initWithKeys: (OFArray*)keys + andObjects: (OFArray*)objs; + /** * Initializes an already allocated OFDictionary with the specified keys and * objects. * * \param first The first key Index: src/OFDictionary.m ================================================================== --- src/OFDictionary.m +++ src/OFDictionary.m @@ -38,10 +38,17 @@ andObject: (OFObject*)obj { return [[[self alloc] initWithKey: key andObject: obj] autorelease]; } + ++ dictionaryWithKeys: (OFArray*)keys + andObjects: (OFArray*)objs +{ + return [[[self alloc] initWithKeys: keys + andObjects: objs] autorelease]; +} + dictionaryWithKeysAndObjects: (OFObject *)first, ... { id ret; va_list args; @@ -143,10 +150,68 @@ [key release]; } return self; } + +- initWithKeys: (OFArray*)keys + andObjects: (OFArray*)objs +{ + Class c; + OFObject **keys_data; + OFObject **objs_data; + size_t count, i; + + self = [self init]; + count = [keys count]; + + if (keys == nil || objs == nil || count != [objs count]) { + c = isa; + [self dealloc]; + @throw [OFInvalidArgumentException newWithClass: isa + andSelector: _cmd]; + } + + keys_data = [keys data]; + objs_data = [objs data]; + + for (i = 0; i < count; i++) { + uint32_t hash; + OFObject *key; + + if (keys_data[i] == nil || objs_data[i] == nil) { + c = isa; + [self dealloc]; + @throw [OFInvalidArgumentException newWithClass: isa + andSelector: _cmd]; + } + + hash = [keys_data[i] hash] & (size - 1); + + @try { + key = [keys_data[i] copy]; + } @catch (OFException *e) { + [self dealloc]; + @throw e; + } + + @try { + if (data[hash] == nil) + data[hash] = [[OFList alloc] init]; + + [data[hash] append: key]; + [data[hash] append: objs_data[i]]; + } @catch (OFException *e) { + [self dealloc]; + @throw e; + } @finally { + [key release]; + } + } + + return self; +} - initWithKeysAndObjects: (OFObject *)first, ... { id ret; va_list args; @@ -160,16 +225,17 @@ } - initWithKey: (OFObject *)first andArgList: (va_list)args { - id key, obj; + OFObject *key; + OFObject *obj; Class c; uint32_t hash; self = [self init]; - obj = va_arg(args, id); + obj = va_arg(args, OFObject*); if (first == nil || obj == nil) { c = isa; [self dealloc]; @throw [OFInvalidArgumentException newWithClass: isa @@ -196,12 +262,12 @@ @throw e; } @finally { [key release]; } - while ((key = va_arg(args, id)) != nil) { - if ((obj = va_arg(args, id)) == nil) { + while ((key = va_arg(args, OFObject *)) != nil) { + if ((obj = va_arg(args, OFObject*)) == nil) { c = isa; [self dealloc]; @throw [OFInvalidArgumentException newWithClass: isa andSelector: _cmd]; } Index: tests/OFDictionary/OFDictionary.m ================================================================== --- tests/OFDictionary/OFDictionary.m +++ tests/OFDictionary/OFDictionary.m @@ -17,11 +17,11 @@ #import "OFAutoreleasePool.h" #import "OFDictionary.h" #import "OFString.h" #import "OFExceptions.h" -#define TESTS 10 +#define TESTS 12 int main() { int i = 0; @@ -114,10 +114,26 @@ andObject: @"bar"]; if (![[dict get: @"foo"] isEqual: @"bar"]) { printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS); return 1; } + + i++; + [dict release]; + dict = [OFDictionary + dictionaryWithKeys: [OFArray arrayWithObjects: @"k1", @"k2", nil] + andObjects: [OFArray arrayWithObjects: @"o1", @"o2", nil]]; + if (![[dict get: @"k1"] isEqual: @"o1"]) { + printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS); + return 1; + } + + i++; + if (![[dict get: @"k2"] isEqual: @"o2"]) { + printf("\033[K\033[1;31mTest %d/%d failed!\033[m\n", i, TESTS); + return 1; + } printf("\033[1;32mTests successful: %d/%d\033[0m\n", i, TESTS); return 0; }