OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 patch class RawServerSocket { | 5 patch class RawServerSocket { |
6 /* patch */ static Future<RawServerSocket> bind(address, | 6 /* patch */ static Future<RawServerSocket> bind(address, |
7 int port, | 7 int port, |
8 {int backlog: 0, | 8 {int backlog: 0, |
9 bool v6Only: false}) { | 9 bool v6Only: false}) { |
10 return _RawServerSocket.bind(address, port, backlog, v6Only); | 10 return _RawServerSocket.bind(address, port, backlog, v6Only); |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 static const int PIPE_SOCKET = 17; | 240 static const int PIPE_SOCKET = 17; |
241 static const int TYPE_NORMAL_SOCKET = 0; | 241 static const int TYPE_NORMAL_SOCKET = 0; |
242 static const int TYPE_LISTENING_SOCKET = 1 << LISTENING_SOCKET; | 242 static const int TYPE_LISTENING_SOCKET = 1 << LISTENING_SOCKET; |
243 static const int TYPE_PIPE = 1 << PIPE_SOCKET; | 243 static const int TYPE_PIPE = 1 << PIPE_SOCKET; |
244 | 244 |
245 // Native port messages. | 245 // Native port messages. |
246 static const HOST_NAME_LOOKUP = 0; | 246 static const HOST_NAME_LOOKUP = 0; |
247 static const LIST_INTERFACES = 1; | 247 static const LIST_INTERFACES = 1; |
248 static const REVERSE_LOOKUP = 2; | 248 static const REVERSE_LOOKUP = 2; |
249 | 249 |
| 250 // Protocol flags. |
| 251 static const int PROTOCOL_IPV4 = 1 << 0; |
| 252 static const int PROTOCOL_IPV6 = 1 << 1; |
| 253 |
250 // Socket close state | 254 // Socket close state |
251 bool isClosed = false; | 255 bool isClosed = false; |
252 bool isClosing = false; | 256 bool isClosing = false; |
253 bool isClosedRead = false; | 257 bool isClosedRead = false; |
254 bool isClosedWrite = false; | 258 bool isClosedWrite = false; |
255 Completer closeCompleter = new Completer(); | 259 Completer closeCompleter = new Completer(); |
256 | 260 |
257 // Handlers and receive port for socket events from the event handler. | 261 // Handlers and receive port for socket events from the event handler. |
258 int eventMask = 0; | 262 int eventMask = 0; |
259 List eventHandlers; | 263 List eventHandlers; |
260 RawReceivePort eventPort; | 264 RawReceivePort eventPort; |
261 | 265 |
262 // Indicates if native interrupts can be activated. | 266 // Indicates if native interrupts can be activated. |
263 bool canActivateEvents = true; | 267 bool canActivateEvents = true; |
264 | 268 |
265 // The type flags for this socket. | 269 // The type flags for this socket. |
266 final int typeFlags; | 270 final int typeFlags; |
267 | 271 |
268 // Holds the port of the socket, null if not known. | 272 // Holds the port of the socket, 0 if not known. |
269 int localPort; | 273 int localPort = 0; |
270 | 274 |
271 // Holds the address used to connect or bind the socket. | 275 // Holds the address used to connect or bind the socket. |
272 InternetAddress address; | 276 InternetAddress address; |
273 | 277 |
274 static Future<List<InternetAddress>> lookup( | 278 static Future<List<InternetAddress>> lookup( |
275 String host, {InternetAddressType type: InternetAddressType.ANY}) { | 279 String host, {InternetAddressType type: InternetAddressType.ANY}) { |
276 return _IOService.dispatch(_SOCKET_LOOKUP, [host, type._value]) | 280 return _IOService.dispatch(_SOCKET_LOOKUP, [host, type._value]) |
277 .then((response) { | 281 .then((response) { |
278 if (isErrorResponse(response)) { | 282 if (isErrorResponse(response)) { |
279 throw createError(response, "Failed host lookup: '$host'"); | 283 throw createError(response, "Failed host lookup: '$host'"); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 throw new SocketException("Failed to create server socket", | 395 throw new SocketException("Failed to create server socket", |
392 osError: result, | 396 osError: result, |
393 address: address, | 397 address: address, |
394 port: port); | 398 port: port); |
395 } | 399 } |
396 if (port != 0) socket.localPort = port; | 400 if (port != 0) socket.localPort = port; |
397 return socket; | 401 return socket; |
398 }); | 402 }); |
399 } | 403 } |
400 | 404 |
| 405 static Future<_NativeSocket> bindDatagram( |
| 406 host, int port, bool reuseAddress) { |
| 407 return new Future.value(host) |
| 408 .then((host) { |
| 409 if (host is _InternetAddress) return host; |
| 410 return lookup(host) |
| 411 .then((list) { |
| 412 if (list.length == 0) { |
| 413 throw createError(response, "Failed host lookup: '$host'"); |
| 414 } |
| 415 return list[0]; |
| 416 }); |
| 417 }) |
| 418 .then((address) { |
| 419 var socket = new _NativeSocket.datagram(address); |
| 420 var result = socket.nativeCreateBindDatagram( |
| 421 address._sockaddr_storage, port, reuseAddress); |
| 422 if (result is OSError) { |
| 423 throw new SocketException("Failed to create datagram socket", |
| 424 osError: result, |
| 425 address: address, |
| 426 port: port); |
| 427 } |
| 428 if (port != 0) socket.localPort = port; |
| 429 return socket; |
| 430 }); |
| 431 } |
| 432 |
| 433 _NativeSocket.datagram(this.address) |
| 434 : typeFlags = TYPE_NORMAL_SOCKET { |
| 435 eventHandlers = new List(EVENT_COUNT + 1); |
| 436 } |
| 437 |
401 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { | 438 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { |
402 eventHandlers = new List(EVENT_COUNT + 1); | 439 eventHandlers = new List(EVENT_COUNT + 1); |
403 } | 440 } |
404 | 441 |
405 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { | 442 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { |
406 eventHandlers = new List(EVENT_COUNT + 1); | 443 eventHandlers = new List(EVENT_COUNT + 1); |
407 } | 444 } |
408 | 445 |
409 _NativeSocket.pipe() : typeFlags = TYPE_PIPE { | 446 _NativeSocket.pipe() : typeFlags = TYPE_PIPE { |
410 eventHandlers = new List(EVENT_COUNT + 1); | 447 eventHandlers = new List(EVENT_COUNT + 1); |
(...skipping 22 matching lines...) Expand all Loading... |
433 } | 470 } |
434 if (isClosing || isClosed) return null; | 471 if (isClosing || isClosed) return null; |
435 var result = nativeRead(len == null ? -1 : len); | 472 var result = nativeRead(len == null ? -1 : len); |
436 if (result is OSError) { | 473 if (result is OSError) { |
437 reportError(result, "Read failed"); | 474 reportError(result, "Read failed"); |
438 return null; | 475 return null; |
439 } | 476 } |
440 return result; | 477 return result; |
441 } | 478 } |
442 | 479 |
| 480 Datagram receive() { |
| 481 if (isClosing || isClosed) return null; |
| 482 var result = nativeRecvFrom(); |
| 483 if (result is OSError) { |
| 484 reportError(result, "Receive failed"); |
| 485 return null; |
| 486 } |
| 487 return result; |
| 488 } |
| 489 |
443 int write(List<int> buffer, int offset, int bytes) { | 490 int write(List<int> buffer, int offset, int bytes) { |
444 if (buffer is! List) throw new ArgumentError(); | 491 if (buffer is! List) throw new ArgumentError(); |
445 if (offset == null) offset = 0; | 492 if (offset == null) offset = 0; |
446 if (bytes == null) { | 493 if (bytes == null) { |
447 if (offset > buffer.length) { | 494 if (offset > buffer.length) { |
448 throw new RangeError.value(offset); | 495 throw new RangeError.value(offset); |
449 } | 496 } |
450 bytes = buffer.length - offset; | 497 bytes = buffer.length - offset; |
451 } | 498 } |
452 if (offset < 0) throw new RangeError.value(offset); | 499 if (offset < 0) throw new RangeError.value(offset); |
(...skipping 10 matching lines...) Expand all Loading... |
463 _ensureFastAndSerializableByteData(buffer, offset, offset + bytes); | 510 _ensureFastAndSerializableByteData(buffer, offset, offset + bytes); |
464 var result = | 511 var result = |
465 nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes); | 512 nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes); |
466 if (result is OSError) { | 513 if (result is OSError) { |
467 scheduleMicrotask(() => reportError(result, "Write failed")); | 514 scheduleMicrotask(() => reportError(result, "Write failed")); |
468 result = 0; | 515 result = 0; |
469 } | 516 } |
470 return result; | 517 return result; |
471 } | 518 } |
472 | 519 |
| 520 int send(List<int> buffer, int offset, int bytes, |
| 521 InternetAddress address, int port) { |
| 522 if (isClosing || isClosed) return 0; |
| 523 _BufferAndStart bufferAndStart = |
| 524 _ensureFastAndSerializableByteData( |
| 525 buffer, offset, bytes); |
| 526 var result = nativeSendTo( |
| 527 bufferAndStart.buffer, bufferAndStart.start, bytes, |
| 528 address._sockaddr_storage, port); |
| 529 if (result is OSError) { |
| 530 scheduleMicrotask(() => reportError(result, "Send failed")); |
| 531 result = 0; |
| 532 } |
| 533 return result; |
| 534 } |
| 535 |
473 _NativeSocket accept() { | 536 _NativeSocket accept() { |
474 // Don't issue accept if we're closing. | 537 // Don't issue accept if we're closing. |
475 if (isClosing || isClosed) return null; | 538 if (isClosing || isClosed) return null; |
476 var socket = new _NativeSocket.normal(); | 539 var socket = new _NativeSocket.normal(); |
477 if (nativeAccept(socket) != true) return null; | 540 if (nativeAccept(socket) != true) return null; |
478 socket.localPort = localPort; | 541 socket.localPort = localPort; |
479 socket.address = address; | 542 socket.address = address; |
480 return socket; | 543 return socket; |
481 } | 544 } |
482 | 545 |
483 int get port { | 546 int get port { |
484 if (localPort != null) return localPort; | 547 if (localPort != 0) return localPort; |
485 return localPort = nativeGetPort(); | 548 return localPort = nativeGetPort(); |
486 } | 549 } |
487 | 550 |
488 int get remotePort { | 551 int get remotePort { |
489 return nativeGetRemotePeer()[1]; | 552 return nativeGetRemotePeer()[1]; |
490 } | 553 } |
491 | 554 |
492 InternetAddress get remoteAddress { | 555 InternetAddress get remoteAddress { |
493 var result = nativeGetRemotePeer()[0]; | 556 var result = nativeGetRemotePeer()[0]; |
494 var type = new InternetAddressType._from(result[0]); | 557 var type = new InternetAddressType._from(result[0]); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 void reportError(error, String message) { | 753 void reportError(error, String message) { |
691 var e = createError(error, message, address, localPort); | 754 var e = createError(error, message, address, localPort); |
692 // Invoke the error handler if any. | 755 // Invoke the error handler if any. |
693 if (eventHandlers[ERROR_EVENT] != null) { | 756 if (eventHandlers[ERROR_EVENT] != null) { |
694 eventHandlers[ERROR_EVENT](e); | 757 eventHandlers[ERROR_EVENT](e); |
695 } | 758 } |
696 // For all errors we close the socket | 759 // For all errors we close the socket |
697 close(); | 760 close(); |
698 } | 761 } |
699 | 762 |
700 bool setOption(SocketOption option, bool enabled) { | 763 getOption(SocketOption option) { |
701 if (option is! SocketOption) throw new ArgumentError(options); | 764 if (option is! SocketOption) throw new ArgumentError(options); |
702 if (enabled is! bool) throw new ArgumentError(enabled); | 765 var result = nativeGetOption(option._value, address.type._value); |
703 return nativeSetOption(option._value, enabled); | 766 if (result is OSError) throw result; |
| 767 return result; |
| 768 } |
| 769 |
| 770 bool setOption(SocketOption option, value) { |
| 771 if (option is! SocketOption) throw new ArgumentError(options); |
| 772 var result = nativeSetOption(option._value, address.type._value, value); |
| 773 if (result is OSError) throw result; |
| 774 } |
| 775 |
| 776 InternetAddress multicastAddress( |
| 777 InternetAddress addr, NetworkInterface interface) { |
| 778 // On Mac OS using the interface index for joining IPv4 multicast groups |
| 779 // is not supported. Here the IP address of the interface is needed. |
| 780 if (Platform.isMacOS && addr.type == InternetAddressType.IP_V4) { |
| 781 if (interface != null) { |
| 782 for (int i = 0; i < interface.addresses.length; i++) { |
| 783 if (addr.type == InternetAddressType.IP_V4) { |
| 784 return interface.addresses[i]; |
| 785 } |
| 786 } |
| 787 // No IPv4 address found on the interface. |
| 788 throw new SocketException( |
| 789 "The network interface does not have an address " |
| 790 "of the same family as the multicast address"); |
| 791 } else { |
| 792 // Default to the ANY address if on iterface is specified. |
| 793 return InternetAddress.ANY_IP_V4; |
| 794 } |
| 795 } else { |
| 796 return null; |
| 797 } |
| 798 } |
| 799 |
| 800 void joinMulticast(InternetAddress addr, NetworkInterface interface) { |
| 801 var interfaceAddr = multicastAddress(addr, interface); |
| 802 var interfaceIndex = interface == null ? 0 : interface.index; |
| 803 var result = nativeJoinMulticast( |
| 804 addr._sockaddr_storage, |
| 805 interfaceAddr == null ? null : interfaceAddr._sockaddr_storage, |
| 806 interfaceIndex); |
| 807 if (result is OSError) throw result; |
| 808 } |
| 809 |
| 810 void leaveMulticast(InternetAddress addr, NetworkInterface interface) { |
| 811 var interfaceAddr = multicastAddress(addr, interface); |
| 812 var interfaceIndex = interface == null ? 0 : interface.index; |
| 813 var result = nativeLeaveMulticast( |
| 814 addr._sockaddr_storage, |
| 815 interfaceAddr == null ? null : interfaceAddr._sockaddr_storage, |
| 816 interfaceIndex); |
| 817 if (result is OSError) throw result; |
704 } | 818 } |
705 | 819 |
706 void nativeSetSocketId(int id) native "Socket_SetSocketId"; | 820 void nativeSetSocketId(int id) native "Socket_SetSocketId"; |
707 nativeAvailable() native "Socket_Available"; | 821 nativeAvailable() native "Socket_Available"; |
708 nativeRead(int len) native "Socket_Read"; | 822 nativeRead(int len) native "Socket_Read"; |
| 823 nativeRecvFrom() native "Socket_RecvFrom"; |
709 nativeWrite(List<int> buffer, int offset, int bytes) | 824 nativeWrite(List<int> buffer, int offset, int bytes) |
710 native "Socket_WriteList"; | 825 native "Socket_WriteList"; |
| 826 nativeSendTo(List<int> buffer, int offset, int bytes, |
| 827 List<int> address, int port) |
| 828 native "Socket_SendTo"; |
711 nativeCreateConnect(List<int> addr, | 829 nativeCreateConnect(List<int> addr, |
712 int port) native "Socket_CreateConnect"; | 830 int port) native "Socket_CreateConnect"; |
713 nativeCreateBindListen(List<int> addr, int port, int backlog, bool v6Only) | 831 nativeCreateBindListen(List<int> addr, int port, int backlog, bool v6Only) |
714 native "ServerSocket_CreateBindListen"; | 832 native "ServerSocket_CreateBindListen"; |
| 833 nativeCreateBindDatagram(List<int> addr, int port, bool reuseAddress) |
| 834 native "Socket_CreateBindDatagram"; |
715 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; | 835 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; |
716 int nativeGetPort() native "Socket_GetPort"; | 836 int nativeGetPort() native "Socket_GetPort"; |
717 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; | 837 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; |
718 OSError nativeGetError() native "Socket_GetError"; | 838 OSError nativeGetError() native "Socket_GetError"; |
719 bool nativeSetOption(int option, bool enabled) native "Socket_SetOption"; | 839 nativeGetOption(int option, int protocol) native "Socket_GetOption"; |
| 840 bool nativeSetOption(int option, int protocol, value) |
| 841 native "Socket_SetOption"; |
| 842 bool nativeJoinMulticast( |
| 843 List<int> addr, List<int> interfaceAddr, int interfaceIndex) |
| 844 native "Socket_JoinMulticast"; |
| 845 bool nativeLeaveMulticast( |
| 846 List<int> addr, List<int> interfaceAddr, int interfaceIndex) |
| 847 native "Socket_LeaveMulticast"; |
720 } | 848 } |
721 | 849 |
722 | 850 |
723 class _RawServerSocket extends Stream<RawSocket> | 851 class _RawServerSocket extends Stream<RawSocket> |
724 implements RawServerSocket { | 852 implements RawServerSocket { |
725 final _NativeSocket _socket; | 853 final _NativeSocket _socket; |
726 StreamController<RawSocket> _controller; | 854 StreamController<RawSocket> _controller; |
727 | 855 |
728 static Future<_RawServerSocket> bind(address, | 856 static Future<_RawServerSocket> bind(address, |
729 int port, | 857 int port, |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1274 if (_detachReady != null) { | 1402 if (_detachReady != null) { |
1275 _detachReady.complete(null); | 1403 _detachReady.complete(null); |
1276 } else { | 1404 } else { |
1277 if (_raw != null) { | 1405 if (_raw != null) { |
1278 _raw.shutdown(SocketDirection.SEND); | 1406 _raw.shutdown(SocketDirection.SEND); |
1279 _disableWriteEvent(); | 1407 _disableWriteEvent(); |
1280 } | 1408 } |
1281 } | 1409 } |
1282 } | 1410 } |
1283 } | 1411 } |
| 1412 |
| 1413 |
| 1414 patch class RawDatagramSocket { |
| 1415 /* patch */ static Future<RawDatagramSocket> bind( |
| 1416 host, int port, {bool reuseAddress: true}) { |
| 1417 return _RawDatagramSocket.bind(host, port, reuseAddress); |
| 1418 } |
| 1419 } |
| 1420 |
| 1421 class _RawDatagramSocket extends Stream implements RawDatagramSocket { |
| 1422 _NativeSocket _socket; |
| 1423 StreamController<RawSocketEvent> _controller; |
| 1424 bool _readEventsEnabled = true; |
| 1425 bool _writeEventsEnabled = true; |
| 1426 |
| 1427 _RawDatagramSocket(this._socket) { |
| 1428 var zone = Zone.current; |
| 1429 _controller = new StreamController(sync: true, |
| 1430 onListen: _onSubscriptionStateChange, |
| 1431 onCancel: _onSubscriptionStateChange, |
| 1432 onPause: _onPauseStateChange, |
| 1433 onResume: _onPauseStateChange); |
| 1434 _socket.closeFuture.then((_) => _controller.close()); |
| 1435 _socket.setHandlers( |
| 1436 read: () => _controller.add(RawSocketEvent.READ), |
| 1437 write: () { |
| 1438 // The write event handler is automatically disabled by the |
| 1439 // event handler when it fires. |
| 1440 _writeEventsEnabled = false; |
| 1441 _controller.add(RawSocketEvent.WRITE); |
| 1442 }, |
| 1443 closed: () => _controller.add(RawSocketEvent.READ_CLOSED), |
| 1444 destroyed: () => _controller.add(RawSocketEvent.CLOSED), |
| 1445 error: zone.bindUnaryCallback((e) { |
| 1446 _controller.addError(e); |
| 1447 close(); |
| 1448 }) |
| 1449 ); |
| 1450 } |
| 1451 |
| 1452 static Future<RawDatagramSocket> bind( |
| 1453 host, int port, bool reuseAddress) { |
| 1454 if (port < 0 || port > 0xffff) |
| 1455 throw new ArgumentError("Invalid port $port"); |
| 1456 return _NativeSocket.bindDatagram(host, port, reuseAddress) |
| 1457 .then((socket) => new _RawDatagramSocket(socket)); |
| 1458 } |
| 1459 |
| 1460 StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent event), |
| 1461 {Function onError, |
| 1462 void onDone(), |
| 1463 bool cancelOnError}) { |
| 1464 return _controller.stream.listen( |
| 1465 onData, |
| 1466 onError: onError, |
| 1467 onDone: onDone, |
| 1468 cancelOnError: cancelOnError); |
| 1469 } |
| 1470 |
| 1471 Future close() => _socket.close().then((_) => this); |
| 1472 |
| 1473 int send(List<data> buffer, InternetAddress address, int port) => |
| 1474 _socket.send(buffer, 0, buffer.length, address, port); |
| 1475 |
| 1476 Datagram receive() { |
| 1477 return _socket.receive(); |
| 1478 } |
| 1479 |
| 1480 void joinMulticast(InternetAddress group, [NetworkInterface interface]) { |
| 1481 _socket.joinMulticast(group, interface); |
| 1482 } |
| 1483 |
| 1484 void leaveMulticast(InternetAddress group, [NetworkInterface interface]) { |
| 1485 _socket.leaveMulticast(group, interface); |
| 1486 } |
| 1487 |
| 1488 bool get readEventsEnabled => _readEventsEnabled; |
| 1489 void set readEventsEnabled(bool value) { |
| 1490 if (value != _readEventsEnabled) { |
| 1491 _readEventsEnabled = value; |
| 1492 if (!_controller.isPaused) _resume(); |
| 1493 } |
| 1494 } |
| 1495 |
| 1496 bool get writeEventsEnabled => _writeEventsEnabled; |
| 1497 void set writeEventsEnabled(bool value) { |
| 1498 if (value != _writeEventsEnabled) { |
| 1499 _writeEventsEnabled = value; |
| 1500 if (!_controller.isPaused) _resume(); |
| 1501 } |
| 1502 } |
| 1503 |
| 1504 bool get multicastLoopback => |
| 1505 _socket.getOption(SocketOption._IP_MULTICAST_LOOP); |
| 1506 void set multicastLoopback(bool value) => |
| 1507 _socket.setOption(SocketOption._IP_MULTICAST_LOOP, value); |
| 1508 |
| 1509 int get multicastHops => |
| 1510 _socket.getOption(SocketOption._IP_MULTICAST_HOPS); |
| 1511 void set multicastHops(int value) => |
| 1512 _socket.setOption(SocketOption._IP_MULTICAST_HOPS, value); |
| 1513 |
| 1514 NetworkInterface get multicastInterface => |
| 1515 throw "Not implemented"; |
| 1516 void set multicastInterface(NetworkInterface value) => |
| 1517 throw "Not implemented"; |
| 1518 |
| 1519 bool get broadcastEnabled => |
| 1520 _socket.getOption(SocketOption._IP_BROADCAST); |
| 1521 void set broadcastEnabled(bool value) => |
| 1522 _socket.setOption(SocketOption._IP_BROADCAST, value); |
| 1523 |
| 1524 int get port => _socket.port; |
| 1525 |
| 1526 InternetAddress get address => _socket.address; |
| 1527 |
| 1528 _pause() { |
| 1529 _socket.setListening(read: false, write: false); |
| 1530 } |
| 1531 |
| 1532 void _resume() { |
| 1533 _socket.setListening(read: _readEventsEnabled, write: _writeEventsEnabled); |
| 1534 } |
| 1535 |
| 1536 void _onPauseStateChange() { |
| 1537 if (_controller.isPaused) { |
| 1538 _pause(); |
| 1539 } else { |
| 1540 _resume(); |
| 1541 } |
| 1542 } |
| 1543 |
| 1544 void _onSubscriptionStateChange() { |
| 1545 if (_controller.hasListener) { |
| 1546 _resume(); |
| 1547 } else { |
| 1548 close(); |
| 1549 } |
| 1550 } |
| 1551 } |
| 1552 |
| 1553 Datagram _makeDatagram(List<int> data, |
| 1554 bool ipV6, |
| 1555 String address, |
| 1556 List<int> sockaddr_storage, |
| 1557 int port) { |
| 1558 var addressType = |
| 1559 ipV6 ? InternetAddressType.IP_V6 : InternetAddressType.IP_V4; |
| 1560 return new Datagram( |
| 1561 data, |
| 1562 new _InternetAddress(addressType, address, null, sockaddr_storage), |
| 1563 port); |
| 1564 } |
OLD | NEW |