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