@@ -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]; }