Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: runtime/bin/sync_socket_patch.dart

Issue 2803543006: Added synchronous socket implementation to dart:io. (Closed)
Patch Set: Changed signature for GetSocketIdNativeField Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/bin/sync_socket_macos.cc ('k') | runtime/bin/sync_socket_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 @patch
6 class RawSynchronousSocket {
7 @patch
8 static RawSynchronousSocket connectSync(host, int port) {
9 return _RawSynchronousSocket.connectSync(host, port);
10 }
11 }
12
13 class _RawSynchronousSocket implements RawSynchronousSocket {
14 final _NativeSynchronousSocket _socket;
15
16 _RawSynchronousSocket(this._socket);
17
18 static RawSynchronousSocket connectSync(host, int port) {
19 _throwOnBadPort(port);
20 return new _RawSynchronousSocket(
21 _NativeSynchronousSocket.connectSync(host, port));
22 }
23
24 InternetAddress get address => _socket.address;
25 int get port => _socket.port;
26 InternetAddress get remoteAddress => _socket.remoteAddress;
27 int get remotePort => _socket.remotePort;
28
29 int available() => _socket.available;
30
31 void closeSync() => _socket.closeSync();
32
33 int readIntoSync(List<int> buffer, [int start = 0, int end]) =>
34 _socket.readIntoSync(buffer, start, end);
35
36 List<int> readSync(int bytes) => _socket.readSync(bytes);
37
38 void shutdown(SocketDirection direction) => _socket.shutdown(direction);
39
40 void writeFromSync(List<int> buffer, [int start = 0, int end]) =>
41 _socket.writeFromSync(buffer, start, end);
42 }
43
44 // The NativeFieldWrapperClass1 can not be used with a mixin, due to missing
45 // implicit constructor.
46 class _NativeSynchronousSocketNativeWrapper extends NativeFieldWrapperClass1 {}
47
48 // The _NativeSynchronousSocket class encapsulates a synchronous OS socket.
49 class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper {
50 // Socket close state.
51 bool isClosed = false;
52 bool isClosedRead = false;
53 bool isClosedWrite = false;
54
55 // Holds the address used to connect the socket.
56 InternetAddress localAddress;
57
58 // Holds the port of the socket, 0 if not known.
59 int localPort = 0;
60
61 _ReadWriteResourceInfo resourceInfo;
62
63 static _NativeSynchronousSocket connectSync(host, int port) {
64 if (host == null) {
65 throw ArgumentError("Parameter host cannot be null");
66 }
67 List<_InternetAddress> addresses = null;
68 var error = null;
69 if (host is _InternetAddress) {
70 addresses = [host];
71 } else {
72 try {
73 addresses = lookup(host);
74 } catch (e) {
75 error = e;
76 }
77 if (error != null || addresses == null || addresses.isEmpty) {
78 throw createError(error, "Failed host lookup: '$host'");
79 }
80 }
81 assert(addresses is List);
82 var it = addresses.iterator;
83 _NativeSynchronousSocket connectNext() {
84 if (!it.moveNext()) {
85 // Could not connect. Throw the first connection error we encountered.
86 assert(error != null);
87 throw error;
88 }
89 var address = it.current;
90 var socket = new _NativeSynchronousSocket();
91 socket.localAddress = address;
92 var result = socket.nativeCreateConnectSync(address._in_addr, port);
93 if (result is OSError) {
94 // Keep first error, if present.
95 if (error == null) {
96 error = createError(result, "Connection failed", address, port);
97 }
98 return connectNext();
99 } else {
100 // Query the local port, for error messages.
101 try {
102 socket.port;
103 } catch (e) {
104 if (error == null) {
105 error = createError(e, "Connection failed", address, port);
106 }
107 return connectNext();
108 }
109 setupResourceInfo(socket);
110 }
111 return socket;
112 }
113
114 return connectNext();
115 }
116
117 InternetAddress get address => localAddress;
118 int get available => nativeAvailable();
119
120 int get port {
121 if (localPort != 0) {
122 return localPort;
123 }
124 if (isClosed) {
125 throw const SocketException.closed();
126 }
127 var result = nativeGetPort();
128 if (result is OSError) {
129 throw result;
130 }
131 return localPort = result;
132 }
133
134 InternetAddress get remoteAddress {
135 if (isClosed) {
136 throw const SocketException.closed();
137 }
138 var result = nativeGetRemotePeer();
139 if (result is OSError) {
140 throw result;
141 }
142 var addr = result[0];
143 return new _InternetAddress(addr[1], null, addr[2]);
144 }
145
146 int get remotePort {
147 if (isClosed) {
148 throw const SocketException.closed();
149 }
150 var result = nativeGetRemotePeer();
151 if (result is OSError) {
152 throw result;
153 }
154 return result[1];
155 }
156
157 void closeSync() {
158 if (!isClosed) {
159 nativeCloseSync();
160 _SocketResourceInfo.SocketClosed(resourceInfo);
161 isClosed = true;
162 }
163 }
164
165 // Create the appropriate error/exception from different returned
166 // error objects.
167 static createError(error, String message,
168 [InternetAddress address, int port]) {
169 if (error is OSError) {
170 return new SocketException(message,
171 osError: error, address: address, port: port);
172 } else {
173 return new SocketException(message, address: address, port: port);
174 }
175 }
176
177 static List<_InternetAddress> lookup(String host,
178 {InternetAddressType type: InternetAddressType.ANY}) {
179 var response = nativeLookupRequest(host, type._value);
180 if (response is OSError) {
181 throw response;
182 }
183 List<_InternetAddress> addresses =
184 new List<_InternetAddress>(response.length);
185 for (int i = 0; i < response.length; ++i) {
186 var result = response[i];
187 addresses[i] = new _InternetAddress(result[1], host, result[2]);
188 }
189 return addresses;
190 }
191
192 int readIntoSync(List<int> buffer, int start, int end) {
193 _checkAvailable();
194 if (isClosedRead) {
195 throw new SocketException("Socket is closed for reading");
196 }
197
198 if ((buffer is! List) ||
199 ((start != null) && (start is! int)) ||
200 ((end != null) && (end is! int))) {
201 throw new ArgumentError("Invalid arguments to readIntoSync");
202 }
203 if (start == null) {
204 throw new ArgumentError("start cannot be null");
205 }
206 end = RangeError.checkValidRange(start, end, buffer.length);
207 if (end == start) {
208 return 0;
209 }
210 var result = nativeReadInto(buffer, start, (end - start));
211 if (result is OSError) {
212 throw new SocketException("readIntoSync failed", osError: result);
213 }
214 resourceInfo.addRead(result);
215 return result;
216 }
217
218 List<int> readSync(int len) {
219 _checkAvailable();
220 if (isClosedRead) {
221 throw new SocketException("Socket is closed for reading");
222 }
223
224 if ((len != null) && (len < 0)) {
225 throw new ArgumentError("Illegal length $len");
226 }
227 if (len == 0) {
228 return null;
229 }
230 var result = nativeRead(len);
231 if (result is OSError) {
232 throw result;
233 }
234 assert(resourceInfo != null);
235 if (result != null) {
236 if (resourceInfo != null) {
237 resourceInfo.totalRead += result.length;
238 }
239 }
240 if (resourceInfo != null) {
241 resourceInfo.didRead();
242 }
243 return result;
244 }
245
246 static void setupResourceInfo(_NativeSynchronousSocket socket) {
247 socket.resourceInfo = new _SocketResourceInfo(socket);
248 }
249
250 void shutdown(SocketDirection direction) {
251 if (isClosed) {
252 return;
253 }
254 switch (direction) {
255 case SocketDirection.RECEIVE:
256 shutdownRead();
257 break;
258 case SocketDirection.SEND:
259 shutdownWrite();
260 break;
261 case SocketDirection.BOTH:
262 closeSync();
263 break;
264 default:
265 throw new ArgumentError(direction);
266 }
267 }
268
269 void shutdownRead() {
270 if (isClosed || isClosedRead) {
271 return;
272 }
273 if (isClosedWrite) {
274 closeSync();
275 } else {
276 nativeShutdownRead();
277 }
278 isClosedRead = true;
279 }
280
281 void shutdownWrite() {
282 if (isClosed || isClosedWrite) {
283 return;
284 }
285 if (isClosedRead) {
286 closeSync();
287 } else {
288 nativeShutdownWrite();
289 }
290 isClosedWrite = true;
291 }
292
293 void writeFromSync(List<int> buffer, int start, int end) {
294 _checkAvailable();
295 if (isClosedWrite) {
296 throw new SocketException("Socket is closed for writing");
297 }
298 if ((buffer is! List) ||
299 ((start != null) && (start is! int)) ||
300 ((end != null) && (end is! int))) {
301 throw new ArgumentError("Invalid arguments to writeFromSync");
302 }
303 if (start == null) {
304 throw new ArgumentError("start cannot be equal to null");
305 }
306
307 end = RangeError.checkValidRange(start, end, buffer.length);
308 if (end == start) {
309 return;
310 }
311
312 _BufferAndStart bufferAndStart =
313 _ensureFastAndSerializableByteData(buffer, start, end);
314 var result = nativeWrite(bufferAndStart.buffer, bufferAndStart.start,
315 end - (start - bufferAndStart.start));
316 if (result is OSError) {
317 throw new SocketException("writeFromSync failed", osError: result);
318 }
319 assert(resourceInfo != null);
320 if (resourceInfo != null) {
321 resourceInfo.addWrite(result);
322 }
323 }
324
325 void _checkAvailable() {
326 if (isClosed) {
327 throw const SocketException.closed();
328 }
329 }
330
331 // Native method declarations.
332 static nativeLookupRequest(host, int type)
333 native "SynchronousSocket_LookupRequest";
334 nativeCreateConnectSync(host, int port)
335 native "SynchronousSocket_CreateConnectSync";
336 nativeAvailable() native "SynchronousSocket_Available";
337 nativeCloseSync() native "SynchronousSocket_CloseSync";
338 int nativeGetPort() native "SynchronousSocket_GetPort";
339 List nativeGetRemotePeer() native "SynchronousSocket_GetRemotePeer";
340 nativeRead(int len) native "SynchronousSocket_Read";
341 nativeReadInto(List<int> buffer, int offset, int bytes)
342 native "SynchronousSocket_ReadList";
343 nativeShutdownRead() native "SynchronousSocket_ShutdownRead";
344 nativeShutdownWrite() native "SynchronousSocket_ShutdownWrite";
345 nativeWrite(List<int> buffer, int offset, int bytes)
346 native "SynchronousSocket_WriteList";
347 }
OLDNEW
« no previous file with comments | « runtime/bin/sync_socket_macos.cc ('k') | runtime/bin/sync_socket_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698