Index: src/OFDictionary.h ================================================================== --- src/OFDictionary.h +++ src/OFDictionary.h @@ -81,10 +81,22 @@ * \return A new autoreleased OFDictionary */ + dictionaryWithObjects: (OFArray*)objects forKeys: (OFArray*)keys; +/** + * \brief Creates a new OFDictionary with the specified keys and objects. + * + * \param keys An array of keys + * \param objects An array of objects + * \param count The number of objects in the arrays + * \return A new autoreleased OFDictionary + */ ++ dictionaryWithObjects: (id*)objects + forKeys: (id*)keys + count: (size_t)count; + /** * \brief Creates a new OFDictionary with the specified keys objects. * * \param firstKey The first key * \return A new autoreleased OFDictionary @@ -127,10 +139,23 @@ * \return A new initialized OFDictionary */ - initWithObjects: (OFArray*)objects forKeys: (OFArray*)keys; +/** + * \brief Initializes an already allocated OFDictionary with the specified keys + * and objects. + * + * \param keys An array of keys + * \param objects An array of objects + * \param count The number of objects in the arrays + * \return A new initialized OFDictionary + */ +- initWithObjects: (id*)objects + forKeys: (id*)keys + count: (size_t)count; + /** * \brief Initializes an already allocated OFDictionary with the specified keys * and objects. * * \param firstKey The first key Index: src/OFDictionary.m ================================================================== --- src/OFDictionary.m +++ src/OFDictionary.m @@ -57,10 +57,19 @@ forKeys: (OFArray*)keys { return (id)[[OFDictionary_hashtable alloc] initWithObjects: objects forKeys: keys]; } + +- initWithObjects: (id*)objects + forKeys: (id*)keys + count: (size_t)count +{ + return (id)[[OFDictionary_hashtable alloc] initWithObjects: objects + forKeys: keys + count: count]; +} - initWithKeysAndObjects: (id )firstKey, ... { id ret; va_list arguments; @@ -144,10 +153,19 @@ forKeys: (OFArray*)keys { return [[[self alloc] initWithObjects: objects forKeys: keys] autorelease]; } + ++ dictionaryWithObjects: (id*)objects + forKeys: (id*)keys + count: (size_t)count +{ + return [[[self alloc] initWithObjects: objects + forKeys: keys + count: count] autorelease]; +} + dictionaryWithKeysAndObjects: (id)firstKey, ... { id ret; va_list arguments; @@ -187,10 +205,20 @@ } - initWithObjects: (OFArray*)objects forKeys: (OFArray*)keys { + Class c = isa; + [self release]; + @throw [OFNotImplementedException exceptionWithClass: c + selector: _cmd]; +} + +- initWithObjects: (id*)objects + forKeys: (id*)keys + count: (size_t)count +{ Class c = isa; [self release]; @throw [OFNotImplementedException exceptionWithClass: c selector: _cmd]; } Index: src/OFDictionary_hashtable.m ================================================================== --- src/OFDictionary_hashtable.m +++ src/OFDictionary_hashtable.m @@ -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; } Index: src/OFMutableDictionary.m ================================================================== --- src/OFMutableDictionary.m +++ src/OFMutableDictionary.m @@ -52,10 +52,20 @@ { return (id)[[OFMutableDictionary_hashtable alloc] initWithObjects: objects forKeys: keys]; } + +- initWithObjects: (id*)objects + forKeys: (id*)keys + count: (size_t)count +{ + return (id)[[OFMutableDictionary_hashtable alloc] + initWithObjects: objects + forKeys: keys + count: count]; +} - initWithKeysAndObjects: (id)firstKey, ... { id ret; va_list arguments;