// // HOMIteratedArgument.m // HigherOrderMessaging // // Created by Ofri Wolfus on 29/08/06. // Copyright 2006 Ofri Wolfus. All rights reserved. // #include #include #import "HOMIteratedArgument.h" #import "HOMUtilities.h" extern Method _hom_findMethodForSelector(SEL sel); @interface HOMIteratedArrayArgument : HOMIteratedArgument { NSArray *contents; IMP objectAtIndex; } - (id)initWithArray:(NSArray *)array; @end @interface HOMIteratedObjectsArray : HOMIteratedArgument { id *objects; } - (id)initWithObjects:(id *)objects count:(unsigned)count; @end @implementation HOMIteratedArgument + (id)iteratedArgumentWithArray:(NSArray *)array { return [[[HOMIteratedArrayArgument alloc] initWithArray:array] autorelease]; } + (id)iteratedArgumentWithObjects:(id *)objects count:(unsigned)count { return [[[HOMIteratedObjectsArray alloc] initWithObjects:objects count:count] autorelease]; } - (id)init { if ((self = [super init])) { nextIndex = 0U; } return self; } - (id)nextObject { DP_SUBCLASS_MUST_IMPLEMENT; return nil; } - (BOOL)isFinished { return nextIndex >= count; } - (unsigned)count { return count; } - (void)reset { nextIndex = 0U; } @end @implementation HOMIteratedArrayArgument - (id)initWithArray:(NSArray *)array { if ((self = [super init])) { contents = [array retain]; count = [contents count]; objectAtIndex = [contents methodForSelector:@selector(objectAtIndex:)]; } return self; } - (void)dealloc { [contents release]; contents = nil; [super dealloc]; } - (id)nextObject { if (count > nextIndex) { ++nextIndex; return objectAtIndex(contents, @selector(objectAtIndex:), nextIndex - 1U); } else { return objectAtIndex(contents, @selector(objectAtIndex:), count - 1U); } } - (id)forward:(SEL)sel :(marg_list)args { Method m = (count > 0U ? _hom_findMethodForSelector(sel) : NULL); unsigned i; unsigned size = m ? method_getSizeOfArguments(m) : 0U; DPAssert(m != NULL, @"Can't find a method for the selector: %s", NSStringFromSelector(sel)); for (i = 0U; i < count; i++) objc_msgSendv(objectAtIndex(contents, @selector(objectAtIndex:), i), sel, size, args); return self; } @end @implementation HOMIteratedObjectsArray - (id)initWithObjects:(id *)objs count:(unsigned)c { if ((self = [super init])) { NSAssert(objs != NULL, @"Passed objects array must not be NULL"); objects = objs; count = c; } return self; } - (void)dealloc { free(objects); objects = NULL; [super dealloc]; } - (id)nextObject { if (count > nextIndex) { ++nextIndex; return objects[nextIndex - 1U]; } else { return objects[count - 1U]; } } - (id)forward:(SEL)sel :(marg_list)args { Method m = (count > 0U ? _hom_findMethodForSelector(sel) : NULL); unsigned i; unsigned size = m ? method_getSizeOfArguments(m) : 0U; DPAssert(m != NULL, @"Can't find a method for the selector: %s", NSStringFromSelector(sel)); for (i = 0U; i < count; i++) objc_msgSendv(objects[i], sel, size, args); return self; } @end