| // |
| // Copyright 2018 Google Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| |
| #import "Service/Sources/EDOMethodSignatureMessage.h" |
| |
| #import "Service/Sources/EDOHostService.h" |
| #import "Service/Sources/EDOMessage.h" |
| #import "Service/Sources/EDOObject+Private.h" |
| #import "Service/Sources/EDORuntimeUtils.h" |
| #import "Service/Sources/EDOServicePort.h" |
| #import "Service/Sources/EDOServiceRequest.h" |
| |
| #import <objc/runtime.h> |
| |
| static NSString *const kEDOMethodSignatureCoderObjectKey = @"object"; |
| static NSString *const kEDOMethodSignatureCoderPortKey = @"port"; |
| static NSString *const kEDOMethodSignatureCoderSignatureKey = @"signature"; |
| static NSString *const kEDOMethodSignatureCoderSelectorKey = @"selector"; |
| |
| #pragma mark - EDOMethodSignatureResponse |
| |
| @implementation EDOMethodSignatureResponse |
| |
| + (BOOL)supportsSecureCoding { |
| return YES; |
| } |
| |
| - (instancetype)initWithSignature:(NSString *)signature forRequest:(EDOServiceRequest *)request { |
| self = [super initWithMessageID:request.messageID]; |
| if (self) { |
| _signature = signature; |
| } |
| return self; |
| } |
| |
| - (instancetype)initWithCoder:(NSCoder *)aDecoder { |
| self = [super initWithCoder:aDecoder]; |
| if (self) { |
| _signature = [aDecoder decodeObjectOfClass:[NSString class] |
| forKey:kEDOMethodSignatureCoderSignatureKey]; |
| } |
| return self; |
| } |
| |
| - (void)encodeWithCoder:(NSCoder *)aCoder { |
| [super encodeWithCoder:aCoder]; |
| [aCoder encodeObject:self.signature forKey:kEDOMethodSignatureCoderSignatureKey]; |
| } |
| |
| - (NSString *)description { |
| return [NSString |
| stringWithFormat:@"Method signature response (%@): (%@)", self.messageID, self.signature]; |
| } |
| |
| @end |
| |
| #pragma mark - EDOMethodSignatureRequest |
| |
| @interface EDOMethodSignatureRequest () |
| /** The pointer to the class. */ |
| @property(nonatomic, readonly) EDOPointerType object; |
| /** The service port for the underlying object. */ |
| @property(nonatomic, readonly, nullable) EDOServicePort *port; |
| /** The selector name. */ |
| @property(nonatomic, readonly) NSString *selectorName; |
| @end |
| |
| @implementation EDOMethodSignatureRequest |
| |
| + (BOOL)supportsSecureCoding { |
| return YES; |
| } |
| |
| + (instancetype)requestWithObject:(EDOPointerType)object |
| port:(EDOServicePort *)port |
| selector:(SEL)selector { |
| return [[self alloc] initWithObject:object port:port selName:NSStringFromSelector(selector)]; |
| } |
| |
| + (EDORequestHandler)requestHandler { |
| return ^EDOServiceResponse *(EDOServiceRequest *request, EDOHostService *service) { |
| if (![request matchesService:service.port]) { |
| return nil; |
| } |
| |
| EDOMethodSignatureRequest *methodRequest = (EDOMethodSignatureRequest *)request; |
| id object = (__bridge Class)(void *)methodRequest.object; |
| SEL sel = NSSelectorFromString(methodRequest.selectorName); |
| |
| NSMethodSignature *signature = EDOGetMethodSignature(object, sel); |
| NSMutableString *encoding = |
| signature ? [NSMutableString stringWithUTF8String:signature.methodReturnType] : nil; |
| for (NSUInteger i = 0; i < signature.numberOfArguments; ++i) { |
| [encoding appendFormat:@"%s", [signature getArgumentTypeAtIndex:i]]; |
| } |
| return [[EDOMethodSignatureResponse alloc] initWithSignature:encoding forRequest:request]; |
| }; |
| } |
| |
| - (instancetype)initWithObject:(EDOPointerType)object |
| port:(EDOServicePort *)port |
| selName:(NSString *)selName { |
| self = [super init]; |
| if (self) { |
| _object = object; |
| _port = port; |
| _selectorName = selName; |
| } |
| return self; |
| } |
| |
| - (instancetype)initWithCoder:(NSCoder *)aDecoder { |
| self = [super initWithCoder:aDecoder]; |
| if (self) { |
| _object = [aDecoder decodeInt64ForKey:kEDOMethodSignatureCoderObjectKey]; |
| _selectorName = [aDecoder decodeObjectOfClass:[NSString class] |
| forKey:kEDOMethodSignatureCoderSelectorKey]; |
| _port = [aDecoder decodeObjectOfClass:[EDOServicePort class] |
| forKey:kEDOMethodSignatureCoderPortKey]; |
| } |
| return self; |
| } |
| |
| - (void)encodeWithCoder:(NSCoder *)aCoder { |
| [super encodeWithCoder:aCoder]; |
| [aCoder encodeInt64:self.object forKey:kEDOMethodSignatureCoderObjectKey]; |
| [aCoder encodeObject:self.selectorName forKey:kEDOMethodSignatureCoderSelectorKey]; |
| [aCoder encodeObject:self.port forKey:kEDOMethodSignatureCoderPortKey]; |
| } |
| |
| - (BOOL)matchesService:(EDOServicePort *)originatorPort { |
| return [self.port match:originatorPort]; |
| } |
| |
| - (NSString *)description { |
| return [NSString |
| stringWithFormat:@"Method signature request (%@): (%@)", self.messageID, self.selectorName]; |
| } |
| |
| @end |