• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 *
3 * Copyright 2019 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19#import "GRPCTransport.h"
20
21static const GRPCTransportID gGRPCCoreSecureID = "io.grpc.transport.core.secure";
22static const GRPCTransportID gGRPCCoreInsecureID = "io.grpc.transport.core.insecure";
23
24const struct GRPCDefaultTransportImplList GRPCDefaultTransportImplList = {
25    .core_secure = gGRPCCoreSecureID, .core_insecure = gGRPCCoreInsecureID};
26
27static const GRPCTransportID gDefaultTransportID = gGRPCCoreSecureID;
28
29static GRPCTransportRegistry *gTransportRegistry = nil;
30static dispatch_once_t initTransportRegistry;
31
32BOOL TransportIDIsEqual(GRPCTransportID lhs, GRPCTransportID rhs) {
33  // Directly comparing pointers works because we require users to use the id provided by each
34  // implementation, not coming up with their own string.
35  return lhs == rhs;
36}
37
38NSUInteger TransportIDHash(GRPCTransportID transportID) {
39  if (transportID == NULL) {
40    transportID = gDefaultTransportID;
41  }
42  return [NSString stringWithCString:transportID encoding:NSUTF8StringEncoding].hash;
43}
44
45@implementation GRPCTransportRegistry {
46  NSMutableDictionary<NSString *, id<GRPCTransportFactory>> *_registry;
47  id<GRPCTransportFactory> _defaultFactory;
48}
49
50+ (instancetype)sharedInstance {
51  dispatch_once(&initTransportRegistry, ^{
52    gTransportRegistry = [[GRPCTransportRegistry alloc] init];
53    NSAssert(gTransportRegistry != nil, @"Unable to initialize transport registry.");
54    if (gTransportRegistry == nil) {
55      NSLog(@"Unable to initialize transport registry.");
56      [NSException raise:NSGenericException format:@"Unable to initialize transport registry."];
57    }
58  });
59  return gTransportRegistry;
60}
61
62- (instancetype)init {
63  if ((self = [super init])) {
64    _registry = [NSMutableDictionary dictionary];
65  }
66  return self;
67}
68
69- (void)registerTransportWithID:(GRPCTransportID)transportID
70                        factory:(id<GRPCTransportFactory>)factory {
71  NSString *nsTransportID = [NSString stringWithCString:transportID encoding:NSUTF8StringEncoding];
72  NSAssert(_registry[nsTransportID] == nil, @"The transport %@ has already been registered.",
73           nsTransportID);
74  if (_registry[nsTransportID] != nil) {
75    NSLog(@"The transport %@ has already been registered.", nsTransportID);
76    return;
77  }
78  _registry[nsTransportID] = factory;
79
80  // if the default transport is registered, mark it.
81  if (0 == strcmp(transportID, gDefaultTransportID)) {
82    _defaultFactory = factory;
83  }
84}
85
86- (id<GRPCTransportFactory>)getTransportFactoryWithID:(GRPCTransportID)transportID {
87  if (transportID == NULL) {
88    if (_defaultFactory == nil) {
89      // fall back to default transport if no transport is provided
90      [NSException raise:NSInvalidArgumentException
91                  format:@"Did not specify transport and unable to find a default transport."];
92      return nil;
93    }
94    return _defaultFactory;
95  }
96  NSString *nsTransportID = [NSString stringWithCString:transportID encoding:NSUTF8StringEncoding];
97  id<GRPCTransportFactory> transportFactory = _registry[nsTransportID];
98  if (transportFactory == nil) {
99    if (_defaultFactory != nil) {
100      // fall back to default transport if no transport is found
101      NSLog(@"Unable to find transport with id %s; falling back to default transport.",
102            transportID);
103      return _defaultFactory;
104    } else {
105      [NSException raise:NSInvalidArgumentException
106                  format:@"Unable to find transport with id %s", transportID];
107      return nil;
108    }
109  }
110  return transportFactory;
111}
112
113@end
114
115@implementation GRPCTransport
116
117- (dispatch_queue_t)dispatchQueue {
118  [NSException raise:NSGenericException
119              format:@"Implementations should override the dispatch queue"];
120  return nil;
121}
122
123- (void)startWithRequestOptions:(nonnull GRPCRequestOptions *)requestOptions
124                    callOptions:(nonnull GRPCCallOptions *)callOptions {
125  [NSException raise:NSGenericException
126              format:@"Implementations should override the methods of GRPCTransport"];
127}
128
129- (void)writeData:(nonnull id)data {
130  [NSException raise:NSGenericException
131              format:@"Implementations should override the methods of GRPCTransport"];
132}
133
134- (void)cancel {
135  [NSException raise:NSGenericException
136              format:@"Implementations should override the methods of GRPCTransport"];
137}
138
139- (void)finish {
140  [NSException raise:NSGenericException
141              format:@"Implementations should override the methods of GRPCTransport"];
142}
143
144- (void)receiveNextMessages:(NSUInteger)numberOfMessages {
145  [NSException raise:NSGenericException
146              format:@"Implementations should override the methods of GRPCTransport"];
147}
148
149@end
150