diff options
Diffstat (limited to 'src/objective-c/GRPCClient/GRPCTransport.mm')
-rw-r--r-- | src/objective-c/GRPCClient/GRPCTransport.mm | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/objective-c/GRPCClient/GRPCTransport.mm b/src/objective-c/GRPCClient/GRPCTransport.mm new file mode 100644 index 0000000000..c55beca0c4 --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCTransport.mm @@ -0,0 +1,149 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * 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 "GRPCTransport.h" + +static const GRPCTransportID gGRPCCoreSecureID = "io.grpc.transport.core.secure"; +static const GRPCTransportID gGRPCCoreInsecureID = "io.grpc.transport.core.insecure"; + +const struct GRPCDefaultTransportImplList GRPCDefaultTransportImplList = { + .core_secure = gGRPCCoreSecureID, .core_insecure = gGRPCCoreInsecureID}; + +static const GRPCTransportID gDefaultTransportID = gGRPCCoreSecureID; + +static GRPCTransportRegistry *gTransportRegistry = nil; +static dispatch_once_t initTransportRegistry; + +BOOL TransportIDIsEqual(GRPCTransportID lhs, GRPCTransportID rhs) { + // Directly comparing pointers works because we require users to use the id provided by each + // implementation, not coming up with their own string. + return lhs == rhs; +} + +NSUInteger TransportIDHash(GRPCTransportID transportID) { + if (transportID == NULL) { + transportID = gDefaultTransportID; + } + return [NSString stringWithCString:transportID encoding:NSUTF8StringEncoding].hash; +} + +@implementation GRPCTransportRegistry { + NSMutableDictionary<NSString *, id<GRPCTransportFactory>> *_registry; + id<GRPCTransportFactory> _defaultFactory; +} + ++ (instancetype)sharedInstance { + dispatch_once(&initTransportRegistry, ^{ + gTransportRegistry = [[GRPCTransportRegistry alloc] init]; + NSAssert(gTransportRegistry != nil, @"Unable to initialize transport registry."); + if (gTransportRegistry == nil) { + NSLog(@"Unable to initialize transport registry."); + [NSException raise:NSGenericException format:@"Unable to initialize transport registry."]; + } + }); + return gTransportRegistry; +} + +- (instancetype)init { + if ((self = [super init])) { + _registry = [NSMutableDictionary dictionary]; + } + return self; +} + +- (void)registerTransportWithID:(GRPCTransportID)transportID + factory:(id<GRPCTransportFactory>)factory { + NSString *nsTransportID = [NSString stringWithCString:transportID encoding:NSUTF8StringEncoding]; + NSAssert(_registry[nsTransportID] == nil, @"The transport %@ has already been registered.", + nsTransportID); + if (_registry[nsTransportID] != nil) { + NSLog(@"The transport %@ has already been registered.", nsTransportID); + return; + } + _registry[nsTransportID] = factory; + + // if the default transport is registered, mark it. + if (0 == strcmp(transportID, gDefaultTransportID)) { + _defaultFactory = factory; + } +} + +- (id<GRPCTransportFactory>)getTransportFactoryWithID:(GRPCTransportID)transportID { + if (transportID == NULL) { + if (_defaultFactory == nil) { + // fall back to default transport if no transport is provided + [NSException raise:NSInvalidArgumentException + format:@"Did not specify transport and unable to find a default transport."]; + return nil; + } + return _defaultFactory; + } + NSString *nsTransportID = [NSString stringWithCString:transportID encoding:NSUTF8StringEncoding]; + id<GRPCTransportFactory> transportFactory = _registry[nsTransportID]; + if (transportFactory == nil) { + if (_defaultFactory != nil) { + // fall back to default transport if no transport is found + NSLog(@"Unable to find transport with id %s; falling back to default transport.", + transportID); + return _defaultFactory; + } else { + [NSException raise:NSInvalidArgumentException + format:@"Unable to find transport with id %s", transportID]; + return nil; + } + } + return transportFactory; +} + +@end + +@implementation GRPCTransport + +- (dispatch_queue_t)dispatchQueue { + [NSException raise:NSGenericException + format:@"Implementations should override the dispatch queue"]; + return nil; +} + +- (void)startWithRequestOptions:(nonnull GRPCRequestOptions *)requestOptions + callOptions:(nonnull GRPCCallOptions *)callOptions { + [NSException raise:NSGenericException + format:@"Implementations should override the methods of GRPCTransport"]; +} + +- (void)writeData:(nonnull id)data { + [NSException raise:NSGenericException + format:@"Implementations should override the methods of GRPCTransport"]; +} + +- (void)cancel { + [NSException raise:NSGenericException + format:@"Implementations should override the methods of GRPCTransport"]; +} + +- (void)finish { + [NSException raise:NSGenericException + format:@"Implementations should override the methods of GRPCTransport"]; +} + +- (void)receiveNextMessages:(NSUInteger)numberOfMessages { + [NSException raise:NSGenericException + format:@"Implementations should override the methods of GRPCTransport"]; +} + +@end |