From 31a4ba441a313dca7821cae97378ac77b90068cc Mon Sep 17 00:00:00 2001 From: fcolin Date: Thu, 1 Feb 2007 11:59:19 +0000 Subject: suppression niveaux --- Ivy/IvyPPC/IvyTCPStreamV3.cs | 254 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 Ivy/IvyPPC/IvyTCPStreamV3.cs (limited to 'Ivy/IvyPPC/IvyTCPStreamV3.cs') diff --git a/Ivy/IvyPPC/IvyTCPStreamV3.cs b/Ivy/IvyPPC/IvyTCPStreamV3.cs new file mode 100644 index 0000000..4eef12c --- /dev/null +++ b/Ivy/IvyPPC/IvyTCPStreamV3.cs @@ -0,0 +1,254 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Collections; +using System.Collections.Specialized; +using System.IO; + +namespace IvyBus +{ + /// + /// Description résumée de IvyStream. + /// + internal class IvyTCPStreamV3 : NetworkStream, IvyProtocol + { + StreamReader input; + StreamWriter output; + IvyProtocol receiver; + + /// the protocol separator + internal const char ARG_START = '\x02'; + internal const char ARG_END = '\x03'; + internal const char MSG_END = '\n'; + + internal IvyTCPStreamV3(Socket socket, IvyProtocol _receiver) : base ( socket ) + { + output = new StreamWriter(this, Encoding.ASCII); + output.NewLine = MSG_END.ToString(); + input = new StreamReader(this, Encoding.ASCII); + receiver = _receiver; + } + /* the protocol magic numbers */ + internal enum MessageType : ushort + { + Bye = 0, /* end of the peer */ + AddRegexp = 1, /* the peer adds a regexp */ + Msg = 2, /* the peer sends a message */ + Error = 3, /* error message */ + DelBinding = 4, /* the peer removes one of his regex */ // OLD DelRegexp rename to DelBinding + EndRegexp = 5, /* no more regexp in the handshake */ + StartRegexp = 6, /* avoid race condition in concurrent connexions */ + DirectMsg = 7, /* the peer sends a direct message */ + Die = 8, /* the peer wants us to quit */ + Ping = 9, /* checks the presence of the other */ + Pong = 10, /* checks the presence of the other */ + }; + + /* + * message Syntax: + * this is text formated message 'type id STX ARG0 {[ETX] ARG1 [ETX] ARGn}\n' + * + * message Format: + MessageType, id , length, string + */ + + private void sendMsg(MessageType msgType, ushort msgId, string msgData) + { + // IOException Should be traited upstairs + output.Write((ushort)msgType); + output.Write(' '); + output.Write(msgId); + output.Write(ARG_START); + output.Write(msgData); + output.Write(MSG_END); + output.Flush(); + + } + void IvyProtocol.TokenStartRegexp(ushort port, string appName) + { + sendMsg(MessageType.StartRegexp, port, appName); + } + void IvyProtocol.TokenEndRegexp() + { + sendMsg(MessageType.EndRegexp, 0, ""); + } + void IvyProtocol.TokenApplicationId(ushort priority, string appId) + { + // NOt implemented in this protocol version + } + + void IvyProtocol.TokenAddBinding(BindingType type, ushort id, string expression) + { + switch (type) + { + case BindingType.Regexp: + sendMsg(MessageType.AddRegexp, id, expression); /* perhaps we should perform some checking here */ + break; + case BindingType.Simple: + // NO Simple Binding in this protocol + break; + } + } + + void IvyProtocol.TokenDelBinding(ushort id) + { + sendMsg(MessageType.DelBinding, id, ""); + } + + void IvyProtocol.TokenDirectMsg(ushort id, string message) + { + sendMsg(MessageType.DirectMsg, id, message); + } + void IvyProtocol.TokenPong(string s) + { + sendMsg(MessageType.Pong, 0, s); + } + void IvyProtocol.TokenPing(string s) + { + sendMsg(MessageType.Ping, 0, s); + } + + void IvyProtocol.TokenBye(ushort id, string message) + { + sendMsg(MessageType.Bye, id, message); + } + + void IvyProtocol.TokenDie(ushort id, string message) + { + sendMsg(MessageType.Die, id, message); + } + + void IvyProtocol.TokenMsg(ushort key, string[] args) + { + string delimiter = "" + ARG_END; + string data = string.Join(delimiter, args); + // a bad protocol implementation in C add a delimiter to the end of each arg + // we must add a delimiter to the end + data += delimiter; + sendMsg(MessageType.Msg, key, data); + } + + void IvyProtocol.TokenError(ushort key, string arg) + { + sendMsg(MessageType.Msg, key, arg); + } + + private ushort DeserializeShort() + { + int read; + ushort ret = 0; + char digit; + // this will eat next non digit char ie space + do + { + read = input.Read(); + if (read < 0) + throw new EndOfStreamException(); + digit = (char)read; + if (Char.IsDigit(digit)) + ret = (ushort)(ret * 10 + (digit - 0x30)); + } while (Char.IsDigit(digit)); + return ret; + } + private string DeserializeString(char sep) + { + int read; + char car; + StringBuilder str = new StringBuilder(); + // this will eat next non separator char + do + { + read = input.Read(); + if (read < 0) + throw new EndOfStreamException(); + car = (char)read; + if (car != sep ) str.Append(car); + } while (car != sep); + return str.ToString(); + } + + bool IvyProtocol.receiveMsg() + { + MessageType msgType = MessageType.Die; + ushort msgId = 0; + string msgData = null; + + try + { + msgType = (MessageType)DeserializeShort(); + msgId = DeserializeShort(); + msgData = DeserializeString(MSG_END); + + switch (msgType) + { + case MessageType.Die: + receiver.TokenDie(msgId, msgData); + break; + + case MessageType.Bye: + receiver.TokenBye(msgId, msgData); + break; + + case MessageType.AddRegexp: + receiver.TokenAddBinding(BindingType.Regexp, msgId, msgData); + break; + + case MessageType.DelBinding: + receiver.TokenDelBinding(msgId); + break; + + case MessageType.EndRegexp: + receiver.TokenEndRegexp(); + break; + + case MessageType.Msg: + // a bad protocol implementation in C add a delimiter to the end of each arg + // we must remove a delimiter to the end + if ( msgData.Length > 0 ) + msgData = msgData.Remove(msgData.Length - 1,1); + receiver.TokenMsg(msgId, msgData.Split( ARG_END )); + break; + + case MessageType.Pong: + receiver.TokenPong(msgData); + break; + + case MessageType.Ping: + receiver.TokenPing(msgData); + break; + + case MessageType.Error: + receiver.TokenError(msgId, msgData); + break; + + case MessageType.StartRegexp: + receiver.TokenStartRegexp(msgId, msgData); + break; + + case MessageType.DirectMsg: + receiver.TokenDirectMsg(msgId, msgData); + break; + default: + throw new IvyException("protocol error, unknown message type " + msgType); + + } + + + + } + catch (EndOfStreamException) + { + return false; + } + catch (FormatException) + { + throw new IvyException("protocol error on msgType"); + } + + + return true; + } + + } +} -- cgit v1.1