Index: src/OFArray.h ================================================================== --- src/OFArray.h +++ src/OFArray.h @@ -252,17 +252,19 @@ #endif @end @interface OFArrayEnumerator: OFEnumerator { - OFDataArray *array; + OFArray *array; + OFDataArray *dataArray; size_t count; unsigned long mutations; unsigned long *mutationsPtr; size_t pos; } -- initWithDataArray: (OFDataArray*)data - mutationsPointer: (unsigned long*)mutations_ptr; +- initWithArray: (OFArray*)data + dataArray: (OFDataArray*)dataArray + mutationsPointer: (unsigned long*)mutationsPtr; @end #import "OFMutableArray.h" Index: src/OFArray.m ================================================================== --- src/OFArray.m +++ src/OFArray.m @@ -459,13 +459,13 @@ return (int)count; } - (OFEnumerator*)objectEnumerator { - return [[[OFArrayEnumerator alloc] - initWithDataArray: array - mutationsPointer: NULL] autorelease]; + return [[[OFArrayEnumerator alloc] initWithArray: self + dataArray: array + mutationsPointer: NULL] autorelease]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block { @@ -556,37 +556,49 @@ [super dealloc]; } @end @implementation OFArrayEnumerator -- initWithDataArray: (OFDataArray*)array_ - mutationsPointer: (unsigned long*)mutationsPtr_; +- initWithArray: (OFArray*)array_ + dataArray: (OFDataArray*)dataArray_ + mutationsPointer: (unsigned long*)mutationsPtr_; { self = [super init]; - array = array_; - count = [array_ count]; + array = [array_ retain]; + dataArray = [dataArray_ retain]; + count = [dataArray count]; mutations = (mutationsPtr_ != NULL ? *mutationsPtr_ : 0); mutationsPtr = mutationsPtr_; return self; } + +- (void)dealloc +{ + [array release]; + [dataArray release]; + + [super dealloc]; +} - (id)nextObject { if (mutationsPtr != NULL && *mutationsPtr != mutations) - @throw [OFEnumerationMutationException newWithClass: isa]; + @throw [OFEnumerationMutationException newWithClass: isa + object: array]; if (pos < count) - return *(id*)[array itemAtIndex: pos++]; + return *(id*)[dataArray itemAtIndex: pos++]; return nil; } - (void)reset { if (mutationsPtr != NULL && *mutationsPtr != mutations) - @throw [OFEnumerationMutationException newWithClass: isa]; + @throw [OFEnumerationMutationException newWithClass: isa + object: array]; pos = 0; } @end Index: src/OFDictionary.h ================================================================== --- src/OFDictionary.h +++ src/OFDictionary.h @@ -193,20 +193,22 @@ #endif @end @interface OFDictionaryEnumerator: OFEnumerator { + OFDictionary *dictionary; struct of_dictionary_bucket **data; uint32_t size; unsigned long mutations; unsigned long *mutationsPtr; uint32_t pos; } -- initWithData: (struct of_dictionary_bucket**)data - size: (uint32_t)size - mutationsPointer: (unsigned long*)mutations_ptr; +- initWithDictionary: (OFDictionary*)dictionary + data: (struct of_dictionary_bucket**)data + size: (uint32_t)size + mutationsPointer: (unsigned long*)mutationsPtr; @end @interface OFDictionaryObjectEnumerator: OFDictionaryEnumerator @end Index: src/OFDictionary.m ================================================================== --- src/OFDictionary.m +++ src/OFDictionary.m @@ -585,21 +585,23 @@ } - (OFEnumerator*)objectEnumerator { return [[[OFDictionaryObjectEnumerator alloc] - initWithData: data - size: size - mutationsPointer: NULL] autorelease]; + initWithDictionary: self + data: data + size: size + mutationsPointer: NULL] autorelease]; } - (OFEnumerator*)keyEnumerator { return [[[OFDictionaryKeyEnumerator alloc] - initWithData: data - size: size - mutationsPointer: NULL] autorelease]; + initWithDictionary: self + data: data + size: size + mutationsPointer: NULL] autorelease]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateKeysAndObjectsUsingBlock: (of_dictionary_enumeration_block_t)block @@ -735,38 +737,51 @@ return ret; } @end @implementation OFDictionaryEnumerator -- initWithData: (struct of_dictionary_bucket**)data_ - size: (uint32_t)size_ - mutationsPointer: (unsigned long*)mutationsPtr_ +- initWithDictionary: (OFDictionary*)dictionary_ + data: (struct of_dictionary_bucket**)data_ + size: (uint32_t)size_ + mutationsPointer: (unsigned long*)mutationsPtr_ { self = [super init]; + dictionary = [dictionary_ retain]; data = data_; size = size_; mutations = (mutationsPtr_ != NULL ? *mutationsPtr_ : 0); mutationsPtr = mutationsPtr_; return self; } + +- (void)dealloc +{ + [dictionary release]; + + [super dealloc]; +} - (void)reset { if (mutationsPtr != NULL && *mutationsPtr != mutations) - @throw [OFEnumerationMutationException newWithClass: isa]; + @throw [OFEnumerationMutationException + newWithClass: isa + object: dictionary]; pos = 0; } @end @implementation OFDictionaryObjectEnumerator - (id)nextObject { if (mutationsPtr != NULL && *mutationsPtr != mutations) - @throw [OFEnumerationMutationException newWithClass: isa]; + @throw [OFEnumerationMutationException + newWithClass: isa + object: dictionary]; for (; pos < size && (data[pos] == NULL || data[pos] == DELETED); pos++); if (pos < size) @@ -778,11 +793,13 @@ @implementation OFDictionaryKeyEnumerator - (id)nextObject { if (mutationsPtr != NULL && *mutationsPtr != mutations) - @throw [OFEnumerationMutationException newWithClass: isa]; + @throw [OFEnumerationMutationException + newWithClass: isa + object: dictionary]; for (; pos < size && (data[pos] == NULL || data[pos] == DELETED); pos++); if (pos < size) Index: src/OFList.h ================================================================== --- src/OFList.h +++ src/OFList.h @@ -117,14 +117,14 @@ - (void)removeListObject: (of_list_object_t*)listobj; @end @interface OFListEnumerator: OFEnumerator { - of_list_object_t *first; + OFList *list; of_list_object_t *current; unsigned long mutations; unsigned long *mutationsPtr; } -- initWithFirstListObject: (of_list_object_t*)first - mutationsPointer: (unsigned long*)mutations_ptr; +- initWithList: (OFList*)list + mutationsPointer: (unsigned long*)mutationsPtr; @end Index: src/OFList.m ================================================================== --- src/OFList.m +++ src/OFList.m @@ -347,35 +347,43 @@ } - (OFEnumerator*)objectEnumerator { return [[[OFListEnumerator alloc] - initWithFirstListObject: firstListObject - mutationsPointer: &mutations] autorelease]; + initWithList: self + mutationsPointer: &mutations] autorelease]; } @end @implementation OFListEnumerator -- initWithFirstListObject: (of_list_object_t*)first_ - mutationsPointer: (unsigned long*)mutationsPtr_; +- initWithList: (OFList*)list_ + mutationsPointer: (unsigned long*)mutationsPtr_; { self = [super init]; - first = first_; - current = first_; + list = [list_ retain]; + current = [list firstListObject]; mutations = *mutationsPtr_; mutationsPtr = mutationsPtr_; return self; } + +- (void)dealloc +{ + [list release]; + + [super dealloc]; +} - (id)nextObject { id ret; if (*mutationsPtr != mutations) - @throw [OFEnumerationMutationException newWithClass: isa]; + @throw [OFEnumerationMutationException newWithClass: isa + object: list]; if (current == NULL) return nil; ret = current->object; @@ -387,8 +395,8 @@ - (void)reset { if (*mutationsPtr != mutations) @throw [OFEnumerationMutationException newWithClass: isa]; - current = first; + current = [list firstListObject]; } @end Index: src/OFMutableArray.m ================================================================== --- src/OFMutableArray.m +++ src/OFMutableArray.m @@ -224,12 +224,13 @@ } - (OFEnumerator*)objectEnumerator { return [[[OFArrayEnumerator alloc] - initWithDataArray: array - mutationsPointer: &mutations] autorelease]; + initWithArray: self + dataArray: array + mutationsPointer: &mutations] autorelease]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block { @@ -240,11 +241,12 @@ unsigned long mutations2 = mutations; for (i = 0; i < count && !stop; i++) { if (mutations != mutations2) @throw [OFEnumerationMutationException - newWithClass: isa]; + newWithClass: isa + object: self]; block(objs[i], i, &stop); [pool releaseObjects]; } @@ -260,11 +262,12 @@ unsigned long mutations2 = mutations; for (i = 0; i < count && !stop; i++) { if (mutations != mutations2) @throw [OFEnumerationMutationException - newWithClass: isa]; + newWithClass: isa + object: self]; id new = block(objs[i], i, &stop); if (new == nil) @throw [OFInvalidArgumentException newWithClass: isa Index: src/OFMutableDictionary.m ================================================================== --- src/OFMutableDictionary.m +++ src/OFMutableDictionary.m @@ -260,21 +260,23 @@ } - (OFEnumerator*)objectEnumerator { return [[[OFDictionaryObjectEnumerator alloc] - initWithData: data - size: size - mutationsPointer: &mutations] autorelease]; + initWithDictionary: self + data: data + size: size + mutationsPointer: &mutations] autorelease]; } - (OFEnumerator*)keyEnumerator { return [[[OFDictionaryKeyEnumerator alloc] - initWithData: data - size: size - mutationsPointer: &mutations] autorelease]; + initWithDictionary: self + data: data + size: size + mutationsPointer: &mutations] autorelease]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateKeysAndObjectsUsingBlock: (of_dictionary_enumeration_block_t)block @@ -285,11 +287,12 @@ unsigned long mutations2 = mutations; for (i = 0; i < size && !stop; i++) { if (mutations != mutations2) @throw [OFEnumerationMutationException - newWithClass: isa]; + newWithClass: isa + object: self]; if (data[i] != NULL && data[i] != DELETED) { block(data[i]->key, data[i]->object, &stop); [pool releaseObjects]; } @@ -306,11 +309,12 @@ unsigned long mutations2 = mutations; for (i = 0; i < size && !stop; i++) { if (mutations != mutations2) @throw [OFEnumerationMutationException - newWithClass: isa]; + newWithClass: isa + object: self]; if (data[i] != NULL && data[i] != DELETED) { id new = block(data[i]->key, data[i]->object, &stop); if (new == nil) Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -97,11 +97,12 @@ #endif static void enumeration_mutation_handler(id obj) { - @throw [OFEnumerationMutationException newWithClass: [obj class]]; + @throw [OFEnumerationMutationException newWithClass: [obj class] + object: obj]; } #ifndef HAVE_OBJC_ENUMERATIONMUTATION void objc_enumerationMutation(id obj) Index: src/exceptions/OFEnumerationMutationException.h ================================================================== --- src/exceptions/OFEnumerationMutationException.h +++ src/exceptions/OFEnumerationMutationException.h @@ -19,6 +19,32 @@ /** * \brief An exception indicating that a mutation was detected during * enumeration. */ @interface OFEnumerationMutationException: OFException +{ + id object; +} + +/** + * \param class_ The class of the object which caused the exception + * \param object The object which was mutated during enumeration + * \return A new enumeration mutation exception + */ ++ newWithClass: (Class)class_ + object: (id)object; + +/** + * Initializes an already allocated enumeration mutation exception. + * + * \param class_ The class of the object which caused the exception + * \param object The object which was mutated during enumeration + * \return An initialized enumeration mutation exception + */ +- initWithClass: (Class)class_ + object: (id)object; + +/** + * \return The object which was mutated during enumeration + */ +- (id)object; @end Index: src/exceptions/OFEnumerationMutationException.m ================================================================== --- src/exceptions/OFEnumerationMutationException.m +++ src/exceptions/OFEnumerationMutationException.m @@ -16,12 +16,51 @@ #include "config.h" #import "OFEnumerationMutationException.h" #import "OFString.h" + +#import "OFNotImplementedException.h" @implementation OFEnumerationMutationException ++ newWithClass: (Class)class_ + object: (id)object +{ + return [[self alloc] initWithClass: class_ + object: object]; +} + +- initWithClass: (Class)class_ +{ + Class c = isa; + [self release]; + @throw [OFNotImplementedException newWithClass: c + selector: _cmd]; +} + +- initWithClass: (Class)class_ + object: (id)object_ +{ + self = [super initWithClass: class_]; + + @try { + object = [object_ retain]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [object release]; + + [super dealloc]; +} + - (OFString*)description { if (description != nil) return description; @@ -28,6 +67,11 @@ description = [[OFString alloc] initWithFormat: @"Object of class %@ was mutated during enumeration!", inClass]; return description; } + +- (id)object +{ + return object; +} @end