@@ -233,19 +233,38 @@ } - initWithObjects: (OFArray*)objects forKeys: (OFArray*)keys { + id ret; + + @try { + if ([objects count] != [keys count]) + @throw [OFInvalidArgumentException + exceptionWithClass: isa]; + + ret = [self initWithObjects: [objects objects] + forKeys: [keys objects] + count: [objects count]]; + } @catch (id e) { + [self release]; + @throw e; + } + + return ret; +} + +- initWithObjects: (id*)objects + forKeys: (id*)keys + count: (size_t)count_ +{ self = [super init]; @try { - id *objectsCArray, *keysCArray; uint32_t i, j, newSize; - keysCArray = [keys objects]; - objectsCArray = [objects objects]; - count = [keys count]; + count = count_; if (count > UINT32_MAX) @throw [OFOutOfRangeException exceptionWithClass: isa]; for (newSize = 1; newSize < count; newSize <<= 1); @@ -264,31 +283,30 @@ size = newSize; for (i = 0; i < count; i++) { uint32_t hash, last; - hash = [keysCArray[i] hash]; + hash = [keys[i] hash]; last = size; for (j = hash & (size - 1); j < last && data[j] != NULL; j++) - if ([data[j]->key isEqual: keysCArray[i]]) + if ([data[j]->key isEqual: keys[i]]) break; /* In case the last bucket is already used */ if (j >= last) { last = hash & (size - 1); for (j = 0; j < last && data[j] != NULL; j++) - if ([data[j]->key - isEqual: keysCArray[i]]) + if ([data[j]->key isEqual: keys[i]]) break; } /* Key not in dictionary */ if (j >= last || data[j] == NULL || - ![data[j]->key isEqual: keysCArray[i]]) { + ![data[j]->key isEqual: keys[i]]) { struct of_dictionary_hashtable_bucket *bucket; id key; last = size; @@ -307,14 +325,14 @@ @throw [OFOutOfRangeException exceptionWithClass: isa]; bucket = [self allocMemoryWithSize: sizeof(*bucket)]; - key = [keysCArray[i] copy]; + key = [keys[i] copy]; bucket->key = key; - bucket->object = [objectsCArray[i] retain]; + bucket->object = [objects[i] retain]; bucket->hash = hash; data[j] = bucket; continue; @@ -324,13 +342,13 @@ * The key is already in the dictionary. However, we * just replace it so that the programmer gets the same * behavior as if he'd call setObject:forKey: for each * key/object pair. */ - [objectsCArray[i] retain]; + [objects[i] retain]; [data[j]->object release]; - data[j]->object = objectsCArray[i]; + data[j]->object = objects[i]; } } @catch (id e) { [self release]; @throw e; }