| // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 
 | // for details. All rights reserved. Use of this source code is governed by a | 
 | // BSD-style license that can be found in the LICENSE file. | 
 |  | 
 | // Echo server test program to test socket streams. | 
 | // | 
 | // VMOptions= | 
 | // VMOptions=--short_socket_read | 
 | // VMOptions=--short_socket_write | 
 | // VMOptions=--short_socket_read --short_socket_write | 
 |  | 
 | library ServerTest; | 
 |  | 
 | import "package:expect/async_helper.dart"; | 
 | import "package:expect/expect.dart"; | 
 | import "dart:async"; | 
 | import "dart:io"; | 
 | import "dart:isolate"; | 
 | part "testing_server.dart"; | 
 |  | 
 | class EchoServerGame { | 
 |   static const MSGSIZE = 10; | 
 |   static const MESSAGES = 100; | 
 |   static const FIRSTCHAR = 65; | 
 |  | 
 |   EchoServerGame.start() { | 
 |     for (int i = 0; i < MSGSIZE; i++) { | 
 |       _buffer[i] = FIRSTCHAR + i; | 
 |     } | 
 |     initialize(); | 
 |   } | 
 |  | 
 |   void sendData() { | 
 |     int offset = 0; | 
 |     List<int> data; | 
 |  | 
 |     void onData(List<int> data) { | 
 |       int bytesRead = data.length; | 
 |       for (int i = 0; i < data.length; i++) { | 
 |         Expect.equals(FIRSTCHAR + i + offset, data[i]); | 
 |       } | 
 |       offset += bytesRead; | 
 |     } | 
 |  | 
 |     void onClosed() { | 
 |       Expect.equals(MSGSIZE, offset); | 
 |       _messages++; | 
 |       if (_messages < MESSAGES) { | 
 |         sendData(); | 
 |       } else { | 
 |         shutdown(); | 
 |       } | 
 |     } | 
 |  | 
 |     void errorHandler(e, trace) { | 
 |       String msg = "Socket error $e"; | 
 |       if (trace != null) msg += "\nStackTrace: $trace"; | 
 |       Expect.fail(msg); | 
 |     } | 
 |  | 
 |     void connectHandler() { | 
 |       _socket.listen(onData, onError: errorHandler, onDone: onClosed); | 
 |       _socket.add(_buffer); | 
 |       _socket.close(); | 
 |       data = new List<int>.filled(MSGSIZE, 0); | 
 |     } | 
 |  | 
 |     Socket.connect(TestingServer.HOST, _port).then((s) { | 
 |       _socket = s; | 
 |       connectHandler(); | 
 |     }); | 
 |   } | 
 |  | 
 |   void initialize() { | 
 |     var receivePort = new ReceivePort(); | 
 |     var remote = Isolate.spawn(startEchoServer, receivePort.sendPort); | 
 |     receivePort.first.then((msg) { | 
 |       this._port = msg[0]; | 
 |       this._closeSendPort = msg[1]; | 
 |       sendData(); | 
 |     }); | 
 |   } | 
 |  | 
 |   void shutdown() { | 
 |     _closeSendPort.send(null); | 
 |     asyncEnd(); | 
 |   } | 
 |  | 
 |   late int _port; | 
 |   late SendPort _closeSendPort; | 
 |   late Socket _socket; | 
 |   final _buffer = new List<int>.filled(MSGSIZE, 0); | 
 |   int _messages = 0; | 
 | } | 
 |  | 
 | void startEchoServer(Object replyPortObj) { | 
 |   SendPort replyPort = replyPortObj as SendPort; | 
 |   var server = new EchoServer(); | 
 |   server.init().then((port) { | 
 |     replyPort.send([port, server.closeSendPort]); | 
 |   }); | 
 | } | 
 |  | 
 | class EchoServer extends TestingServer { | 
 |   static const int MSGSIZE = EchoServerGame.MSGSIZE; | 
 |  | 
 |   void onConnection(Socket connection) { | 
 |     List<int> buffer = new List<int>.filled(MSGSIZE, 0); | 
 |     int offset = 0; | 
 |  | 
 |     void dataReceived(List<int> data) { | 
 |       int bytesRead; | 
 |       bytesRead = data.length; | 
 |       if (bytesRead > 0) { | 
 |         buffer.setRange(offset, offset + data.length, data); | 
 |         offset += bytesRead; | 
 |         for (int i = 0; i < offset; i++) { | 
 |           Expect.equals(EchoServerGame.FIRSTCHAR + i, buffer[i]); | 
 |         } | 
 |         if (offset == MSGSIZE) { | 
 |           connection.add(buffer); | 
 |           connection.close(); | 
 |         } | 
 |       } | 
 |     } | 
 |  | 
 |     void errorHandler(e, trace) { | 
 |       String msg = "Socket error $e"; | 
 |       if (trace != null) msg += "\nStackTrace: $trace"; | 
 |       Expect.fail(msg); | 
 |     } | 
 |  | 
 |     connection.listen(dataReceived, onError: errorHandler); | 
 |   } | 
 | } | 
 |  | 
 | main() { | 
 |   asyncStart(); | 
 |   EchoServerGame echoServerGame = new EchoServerGame.start(); | 
 | } |