Index: src/OFDictionary.h ================================================================== --- src/OFDictionary.h +++ src/OFDictionary.h @@ -171,10 +171,24 @@ * \return A boolean whether the dictionary contains an object with the * specified address. */ - (BOOL)containsObjectIdenticalTo: (id)object; +/** + * \brief Returns an array of all keys. + * + * \return An array of all keys + */ +- (OFArray*)allKeys; + +/** + * \brief Returns an array of all objects. + * + * \return An array of all objects + */ +- (OFArray*)allObjects; + /** * \brief Returns an OFEnumerator to enumerate through the dictionary's keys. * * \return An OFEnumerator to enumerate through the dictionary's keys */ Index: src/OFDictionary.m ================================================================== --- src/OFDictionary.m +++ src/OFDictionary.m @@ -15,10 +15,12 @@ */ #include "config.h" #include + +#include #import "OFDictionary.h" #import "OFEnumerator.h" #import "OFArray.h" #import "OFString.h" @@ -638,10 +640,74 @@ data[i]->object == object) return YES; return NO; } + +- (OFArray*)allKeys +{ + OFArray *ret; + id *cArray = [self allocMemoryForNItems: count + withSize: sizeof(id)]; + size_t i, j; + + for (i = j = 0; i < size; i++) + if (data[i] != NULL && data[i] != DELETED) + cArray[j++] = data[i]->key; + + assert(j == count); + + @try { + ret = [OFArray arrayWithCArray: cArray + length: count]; + } @finally { + [self freeMemory: cArray]; + } + + return ret; +} + +- (OFArray*)allObjects +{ + OFArray *ret; + id *cArray = [self allocMemoryForNItems: count + withSize: sizeof(id)]; + size_t i, j; + + for (i = j = 0; i < size; i++) + if (data[i] != NULL && data[i] != DELETED) + cArray[j++] = data[i]->object; + + assert(j == count); + + @try { + ret = [OFArray arrayWithCArray: cArray + length: count]; + } @finally { + [self freeMemory: cArray]; + } + + return ret; +} + +- (OFEnumerator*)objectEnumerator +{ + return [[[OFDictionaryObjectEnumerator alloc] + initWithDictionary: self + data: data + size: size + mutationsPointer: NULL] autorelease]; +} + +- (OFEnumerator*)keyEnumerator +{ + return [[[OFDictionaryKeyEnumerator alloc] + initWithDictionary: self + data: data + size: size + mutationsPointer: NULL] autorelease]; +} - (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state objects: (id*)objects count: (int)count_ { @@ -662,28 +728,10 @@ state->mutationsPtr = (unsigned long*)self; return i; } -- (OFEnumerator*)objectEnumerator -{ - return [[[OFDictionaryObjectEnumerator alloc] - initWithDictionary: self - data: data - size: size - mutationsPointer: NULL] autorelease]; -} - -- (OFEnumerator*)keyEnumerator -{ - return [[[OFDictionaryKeyEnumerator alloc] - initWithDictionary: self - data: data - size: size - mutationsPointer: NULL] autorelease]; -} - #ifdef OF_HAVE_BLOCKS - (void)enumerateKeysAndObjectsUsingBlock: (of_dictionary_enumeration_block_t)block { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; Index: tests/OFDictionaryTests.m ================================================================== --- tests/OFDictionaryTests.m +++ tests/OFDictionaryTests.m @@ -64,10 +64,18 @@ TEST(@"-[description]", [[dict description] isEqual: @"{\n\tkey1 = value1;\n\tkey2 = value2;\n}"]) + TEST(@"-[allKeys]", + [[dict allKeys] isEqual: ([OFArray arrayWithObjects: keys[0], + keys[1], nil])]) + + TEST(@"-[allObjects]", + [[dict allObjects] isEqual: ([OFArray arrayWithObjects: values[0], + values[1], nil])]) + TEST(@"-[keyEnumerator]", (key_enum = [dict keyEnumerator])) TEST(@"-[objectEnumerator]", (obj_enum = [dict objectEnumerator])) TEST(@"OFEnumerator's -[nextObject]", [[key_enum nextObject] isEqual: keys[0]] &&