12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- //
- // Licensed under the terms in License.txt
- //
- // Copyright 2010 Allen Ding. All rights reserved.
- //
- #import "NSInvocation+KiwiAdditions.h"
- #import "KWFormatter.h"
- #import "KWObjCUtilities.h"
- #import "NSMethodSignature+KiwiAdditions.h"
- @implementation NSInvocation(KiwiAdditions)
- #pragma mark - Creating NSInvocation Objects
- + (NSInvocation *)invocationWithTarget:(id)anObject selector:(SEL)aSelector {
- return [self invocationWithTarget:anObject selector:aSelector messageArguments:nil];
- }
- + (NSInvocation *)invocationWithTarget:(id)anObject selector:(SEL)aSelector messageArguments:(const void *)firstBytes, ... {
- if (anObject == nil) {
- [NSException raise:NSInvalidArgumentException format:@"%@ - target must not be nil",
- NSStringFromSelector(_cmd)];
- }
- NSMethodSignature *signature = [anObject methodSignatureForSelector:aSelector];
- if (signature == nil) {
- [NSException raise:NSInvalidArgumentException format:@"%@ - target returned nil for -methodSignatureForSelector",
- NSStringFromSelector(_cmd)];
- }
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
- [invocation setTarget:anObject];
- [invocation setSelector:aSelector];
- NSUInteger numberOfMessageArguments = [signature numberOfMessageArguments];
- if (numberOfMessageArguments == 0)
- return invocation;
- va_list argumentList;
- va_start(argumentList, firstBytes);
- const void *bytes = firstBytes;
- for (NSUInteger i = 0; i < numberOfMessageArguments && bytes != nil; ++i) {
- [invocation setMessageArgument:bytes atIndex:i];
- bytes = va_arg(argumentList, const void *);
- }
- va_end(argumentList);
- return invocation;
- }
- #pragma mark - Accessing Message Arguments
- - (NSData *)messageArgumentDataAtIndex:(NSUInteger)anIndex {
- NSUInteger length = KWObjCTypeLength([[self methodSignature] messageArgumentTypeAtIndex:anIndex]);
- void *buffer = malloc(length);
- [self getMessageArgument:buffer atIndex:anIndex];
- // NSData takes over ownership of buffer
- NSData* data = [NSData dataWithBytesNoCopy:buffer length:length];
- return data;
- }
- - (void)getMessageArgument:(void *)buffer atIndex:(NSUInteger)anIndex {
- [self getArgument:buffer atIndex:anIndex + 2];
- }
- - (void)setMessageArgument:(const void *)bytes atIndex:(NSUInteger)anIndex {
- [self setArgument:(void *)bytes atIndex:anIndex + 2];
- }
- - (void)setMessageArguments:(const void *)firstBytes, ... {
- NSUInteger numberOfMessageArguments = [[self methodSignature] numberOfMessageArguments];
- if (numberOfMessageArguments == 0)
- return;
- va_list argumentList;
- va_start(argumentList, firstBytes);
- const void *bytes = firstBytes;
- for (NSUInteger i = 0; i < numberOfMessageArguments && bytes != nil; ++i) {
- [self setMessageArgument:bytes atIndex:i];
- bytes = va_arg(argumentList, const void *);
- }
- va_end(argumentList);
- }
- @end
|