GINInvocation.m 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * Copyright 2018 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "FirebaseDynamicLinks/Sources/GINInvocation/GINInvocation.h"
  17. #import "FirebaseDynamicLinks/Sources/GINInvocation/GINArgument.h"
  18. @implementation GINInvocation
  19. // A method that performs a selector on a target object, and return the result.
  20. + (id)objectByPerformingSelector:(SEL)selector
  21. onTarget:(id)target
  22. numberOfArguments:(NSInteger)numberOfArguments, ... {
  23. if (![target respondsToSelector:selector]) {
  24. #if DEBUG
  25. [NSException raise:@"InvalidSelectorException" format:@"Invalid selector send to target"];
  26. #endif
  27. return nil;
  28. }
  29. NSMethodSignature *methodSignature = [target methodSignatureForSelector:selector];
  30. NSInvocation *inv = [NSInvocation invocationWithMethodSignature:methodSignature];
  31. [inv setSelector:selector];
  32. [inv setTarget:target];
  33. int index = 2;
  34. va_list argumentList;
  35. va_start(argumentList, numberOfArguments);
  36. for (NSInteger i = 0; i < numberOfArguments; i++) {
  37. [GINArgument setNextArgumentInList:argumentList atIndex:index inInvocation:inv];
  38. }
  39. va_end(argumentList);
  40. [inv invoke];
  41. // This method only returns object.
  42. if ([methodSignature methodReturnLength]) {
  43. CFTypeRef result;
  44. [inv getReturnValue:&result];
  45. if (result) {
  46. CFRetain(result);
  47. }
  48. return (__bridge_transfer id)result;
  49. }
  50. return nil;
  51. }
  52. // A method that performs a selector on a target object, and return the result.
  53. + (double)doubleByPerformingSelector:(SEL)selector
  54. onTarget:(id)target
  55. numberOfArguments:(NSInteger)numberOfArguments, ... {
  56. if (![target respondsToSelector:selector]) {
  57. #if DEBUG
  58. [NSException raise:@"InvalidSelectorException" format:@"Invalid selector send to target"];
  59. #endif
  60. return 0;
  61. }
  62. NSMethodSignature *methodSignature = [target methodSignatureForSelector:selector];
  63. NSInvocation *inv = [NSInvocation invocationWithMethodSignature:methodSignature];
  64. [inv setSelector:selector];
  65. [inv setTarget:target];
  66. int index = 2;
  67. va_list argumentList;
  68. va_start(argumentList, numberOfArguments);
  69. for (NSInteger i = 0; i < numberOfArguments; i++) {
  70. [GINArgument setNextArgumentInList:argumentList atIndex:index inInvocation:inv];
  71. }
  72. va_end(argumentList);
  73. [inv invoke];
  74. // This method only returns double.
  75. if ([methodSignature methodReturnLength]) {
  76. double doubleValue;
  77. [inv getReturnValue:&doubleValue];
  78. return doubleValue;
  79. }
  80. return 0;
  81. }
  82. @end