aboutsummaryrefslogtreecommitdiff
path: root/src/objective-c/GRPCClient/GRPCTransport.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/objective-c/GRPCClient/GRPCTransport.mm')
-rw-r--r--src/objective-c/GRPCClient/GRPCTransport.mm149
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