import core.thread; import std.socket; import std.stream; import std.socketstream; import std.stdio; /** An experimental TCP/IP socket server, written in the C++/Java subset of D. Author: Ian Kaplan */ /** The stream server has a simple protocol with the client. It expects the client to tell it the name of the file containing the time series. The server will then open the file and stream it to the client. The command is: "open:" For example: "open:GS.Jul_01_2008", where GS.Jul_01_2008 is the name of the file. If the file is opened successfully, the server will respond with "OK\n". If there is a problem opening the file the server will respond with "ERROR:". The stream will be closed if there is an error. Following the OK will be a stream of values and time stamps. */ class StreamServer : Thread { private string dataPath; private Socket socket; private Stream ioStream; private uint lastMsec = 0; private bool processStream = true; this( string path, Socket soc ) { super( &run ); dataPath = path; socket = soc; ioStream = new SocketStream( soc ); } // constructor void stopProcessing() { processStream = false; } /** Strip the file name out of the "open:" string. There must be a better way, but I could not figure it out. This is a pretty crude algorith. It just looks for the ':' and then copies the characters after that. */ static string getFileName( char[] line ) { string fileName; bool start = false; foreach (ch; line) { if (start) { fileName ~= ch; } if (ch == ':') { start = true; } } return fileName; } // getFileName /** Convert a string of decimal digit characters into an unsigned integer. This code does no format checking. There is certainly a better way to do this in D, but I was in a rush to get this code done. */ private uint toInt( char[] numChars ) { uint val = 0; foreach (ch; numChars) { val = (val * 10) + (ch - '0'); } return val; } // toInt /** The time series values that are streamed by the StreamServer have the format ,