OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #import "RTCDataChannel.h" | |
12 | |
13 #import "webrtc/api/objc/RTCDataChannel+Private.h" | |
14 #import "webrtc/base/objc/NSString+StdString.h" | |
15 | |
16 #include "webrtc/base/scoped_ptr.h" | |
17 | |
18 namespace webrtc { | |
19 | |
20 class DataChannelDelegateAdapter : public DataChannelObserver { | |
21 public: | |
22 DataChannelDelegateAdapter(RTCDataChannel *channel) { channel_ = channel; } | |
23 | |
24 void OnStateChange() override { | |
25 [channel_.delegate dataChannelDidChangeState:channel_]; | |
26 } | |
27 | |
28 void OnMessage(const DataBuffer& buffer) override { | |
29 RTCDataBuffer *data_buffer = | |
30 [[RTCDataBuffer alloc] initWithNativeBuffer:buffer]; | |
31 [channel_.delegate dataChannel:channel_ | |
32 didReceiveMessageWithBuffer:data_buffer]; | |
33 } | |
34 | |
35 void OnBufferedAmountChange(uint64_t previousAmount) override { | |
36 id<RTCDataChannelDelegate> delegate = channel_.delegate; | |
37 SEL sel = @selector(dataChannel:didChangeBufferedAmount:); | |
38 if ([delegate respondsToSelector:sel]) { | |
39 [delegate dataChannel:channel_ didChangeBufferedAmount:previousAmount]; | |
40 } | |
41 } | |
42 | |
43 private: | |
44 __weak RTCDataChannel *channel_; | |
45 }; | |
46 } | |
47 | |
48 | |
49 @implementation RTCDataBuffer { | |
50 rtc::scoped_ptr<webrtc::DataBuffer> _dataBuffer; | |
51 } | |
52 | |
53 - (instancetype)initWithData:(NSData *)data isBinary:(BOOL)isBinary { | |
54 NSParameterAssert(data); | |
55 if (self = [super init]) { | |
56 rtc::CopyOnWriteBuffer buffer( | |
57 reinterpret_cast<const uint8_t*>(data.bytes), data.length); | |
58 _dataBuffer.reset(new webrtc::DataBuffer(buffer, isBinary)); | |
59 } | |
60 return self; | |
61 } | |
62 | |
63 - (NSData *)data { | |
64 return [NSData dataWithBytes:_dataBuffer->data.data() | |
65 length:_dataBuffer->data.size()]; | |
66 } | |
67 | |
68 - (BOOL)isBinary { | |
69 return _dataBuffer->binary; | |
70 } | |
71 | |
72 #pragma mark - Private | |
73 | |
74 - (instancetype)initWithNativeBuffer:(const webrtc::DataBuffer&)nativeBuffer { | |
75 if (self = [super init]) { | |
76 _dataBuffer.reset(new webrtc::DataBuffer(nativeBuffer)); | |
77 } | |
78 return self; | |
79 } | |
80 | |
81 - (const webrtc::DataBuffer *)nativeDataBuffer { | |
82 return _dataBuffer.get(); | |
83 } | |
84 | |
85 @end | |
86 | |
87 | |
88 @implementation RTCDataChannel { | |
89 rtc::scoped_refptr<webrtc::DataChannelInterface> _nativeDataChannel; | |
90 rtc::scoped_ptr<webrtc::DataChannelDelegateAdapter> _observer; | |
91 BOOL _isObserverRegistered; | |
92 } | |
93 | |
94 @synthesize delegate = _delegate; | |
95 | |
96 - (void)dealloc { | |
97 // Handles unregistering the observer properly. We need to do this because | |
98 // there may still be other references to the underlying data channel. | |
99 self.delegate = nil; | |
100 } | |
101 | |
102 - (NSString *)label { | |
103 return [NSString stringForStdString:_nativeDataChannel->label()]; | |
104 } | |
105 | |
106 - (BOOL)isReliable { | |
107 return _nativeDataChannel->reliable(); | |
108 } | |
109 | |
110 - (BOOL)isOrdered { | |
111 return _nativeDataChannel->ordered(); | |
112 } | |
113 | |
114 - (NSUInteger)maxRetransmitTime { | |
115 return self.maxPacketLifeTime; | |
116 } | |
117 | |
118 - (uint16_t)maxPacketLifeTime { | |
119 return _nativeDataChannel->maxRetransmitTime(); | |
120 } | |
121 | |
122 - (uint16_t)maxRetransmits { | |
123 return _nativeDataChannel->maxRetransmits(); | |
124 } | |
125 | |
126 - (NSString *)protocol { | |
127 return [NSString stringForStdString:_nativeDataChannel->protocol()]; | |
128 } | |
129 | |
130 - (BOOL)isNegotiated { | |
131 return _nativeDataChannel->negotiated(); | |
132 } | |
133 | |
134 - (NSInteger)streamId { | |
135 return self.channelId; | |
136 } | |
137 | |
138 - (int)channelId { | |
139 return _nativeDataChannel->id(); | |
140 } | |
141 | |
142 - (RTCDataChannelState)readyState { | |
143 return [[self class] dataChannelStateForNativeState: | |
144 _nativeDataChannel->state()]; | |
145 } | |
146 | |
147 - (uint64_t)bufferedAmount { | |
148 return _nativeDataChannel->buffered_amount(); | |
149 } | |
150 | |
151 - (void)setDelegate:(id<RTCDataChannelDelegate>)delegate { | |
152 if (_delegate == delegate) { | |
153 return; | |
154 } | |
155 if (_isObserverRegistered) { | |
156 _nativeDataChannel->UnregisterObserver(); | |
157 _isObserverRegistered = NO; | |
158 } | |
159 _delegate = delegate; | |
160 if (_delegate) { | |
161 _nativeDataChannel->RegisterObserver(_observer.get()); | |
162 _isObserverRegistered = YES; | |
163 } | |
164 } | |
165 | |
166 - (void)close { | |
167 _nativeDataChannel->Close(); | |
168 } | |
169 | |
170 - (BOOL)sendData:(RTCDataBuffer *)data { | |
171 return _nativeDataChannel->Send(*data.nativeDataBuffer); | |
172 } | |
173 | |
174 - (NSString *)description { | |
175 return [NSString stringWithFormat:@"RTCDataChannel:\n%ld\n%@\n%@", | |
176 (long)self.channelId, | |
177 self.label, | |
178 [[self class] | |
179 stringForState:self.readyState]]; | |
180 } | |
181 | |
182 #pragma mark - Private | |
183 | |
184 - (instancetype)initWithNativeDataChannel: | |
185 (rtc::scoped_refptr<webrtc::DataChannelInterface>)nativeDataChannel { | |
186 NSParameterAssert(nativeDataChannel); | |
187 if (self = [super init]) { | |
188 _nativeDataChannel = nativeDataChannel; | |
189 _observer.reset(new webrtc::DataChannelDelegateAdapter(self)); | |
190 } | |
191 return self; | |
192 } | |
193 | |
194 + (webrtc::DataChannelInterface::DataState) | |
195 nativeDataChannelStateForState:(RTCDataChannelState)state { | |
196 switch (state) { | |
197 case RTCDataChannelStateConnecting: | |
198 return webrtc::DataChannelInterface::DataState::kConnecting; | |
199 case RTCDataChannelStateOpen: | |
200 return webrtc::DataChannelInterface::DataState::kOpen; | |
201 case RTCDataChannelStateClosing: | |
202 return webrtc::DataChannelInterface::DataState::kClosing; | |
203 case RTCDataChannelStateClosed: | |
204 return webrtc::DataChannelInterface::DataState::kClosed; | |
205 } | |
206 } | |
207 | |
208 + (RTCDataChannelState)dataChannelStateForNativeState: | |
209 (webrtc::DataChannelInterface::DataState)nativeState { | |
210 switch (nativeState) { | |
211 case webrtc::DataChannelInterface::DataState::kConnecting: | |
212 return RTCDataChannelStateConnecting; | |
213 case webrtc::DataChannelInterface::DataState::kOpen: | |
214 return RTCDataChannelStateOpen; | |
215 case webrtc::DataChannelInterface::DataState::kClosing: | |
216 return RTCDataChannelStateClosing; | |
217 case webrtc::DataChannelInterface::DataState::kClosed: | |
218 return RTCDataChannelStateClosed; | |
219 } | |
220 } | |
221 | |
222 + (NSString *)stringForState:(RTCDataChannelState)state { | |
223 switch (state) { | |
224 case RTCDataChannelStateConnecting: | |
225 return @"Connecting"; | |
226 case RTCDataChannelStateOpen: | |
227 return @"Open"; | |
228 case RTCDataChannelStateClosing: | |
229 return @"Closing"; | |
230 case RTCDataChannelStateClosed: | |
231 return @"Closed"; | |
232 } | |
233 } | |
234 | |
235 @end | |
OLD | NEW |