Skip to content

Commit

Permalink
Improve handling of literal values as arguments in map operations
Browse files Browse the repository at this point in the history
  • Loading branch information
moredip committed Jun 24, 2011
1 parent 93f8b93 commit ebb5507
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
8 changes: 8 additions & 0 deletions example/EmployeeAdmin/features/frank_tests.feature
@@ -0,0 +1,8 @@
Feature: Various scenarios that exercise different parts of Frank

Background:
Given I launch the app

Scenario: Counting number of rows in a table section
Then I should see 3 rows in section 0

Expand Up @@ -14,6 +14,14 @@
end
end

Then /^I should see (\d+) rows in section (\d+)$/ do |expected_num_rows, section|
section = section.to_i
expected_num_rows = expected_num_rows.to_i
num_rows_array = frankly_map( "tableView first", "numberOfRowsInSection:", section )
raise "no table found" if num_rows_array.empty?
num_rows_array.first.should eq(expected_num_rows)
end

When /^I touch the "([^\"]*)" nav bar button$/ do |mark|
touch( "navigationButton marked:'#{mark}'" )
end
Expand Down
22 changes: 21 additions & 1 deletion src/Operation.m
Expand Up @@ -34,6 +34,17 @@ - (BOOL) appliesToObject:(id)target {
return [target respondsToSelector:_selector];
}

- (void)castNumber:(NSNumber *)number toType:(const char*)objCType intoBuffer:(void *)buffer{
// specific cases should be added here as needed
if( !strcmp(objCType, @encode(int)) ){
*((int *)buffer) = [number intValue];
}else if( !strcmp(objCType, @encode(uint)) ){
*((uint *)buffer) = [number unsignedIntValue];
}else {
NSLog(@"Didn't know how to convert NSNumber to type %s", objCType);
}
}

- (id) applyToObject:(id)target {
NSMethodSignature *signature = [target methodSignatureForSelector:_selector];
NSUInteger requiredNumberOfArguments = signature.numberOfArguments - 2; // Indices 0 and 1 indicate the hidden arguments self and _cmd, respectively
Expand All @@ -44,9 +55,18 @@ - (id) applyToObject:(id)target {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:_selector];

char invocationBuffer[300]; //let's hope we don't get asked to invoke a method with more than 28 arguments.

NSInteger index = 2; // Indices 0 and 1 indicate the hidden arguments self and _cmd, respectively
for( id arg in _arguments ) {
[invocation setArgument:&arg atIndex:index++];
if( [arg isKindOfClass:[NSNumber class]] ){
void *buffer = &(invocationBuffer[index*10]);
[self castNumber:arg toType:[signature getArgumentTypeAtIndex:index] intoBuffer:buffer];
[invocation setArgument:buffer atIndex:index];
}else {
[invocation setArgument:&arg atIndex:index];
}
index++;
}

[invocation invokeWithTarget:target];
Expand Down

0 comments on commit ebb5507

Please sign in to comment.