summaryrefslogtreecommitdiff
path: root/Ivy/IvyTCPStreamV4.cs
diff options
context:
space:
mode:
authorfcolin2007-02-01 12:04:16 +0000
committerfcolin2007-02-01 12:04:16 +0000
commit92757a8d629812303ff3665343bd098917cca611 (patch)
treecd995c9863aa6fc4c32ec5ce247e4c3119eb44a3 /Ivy/IvyTCPStreamV4.cs
parent98ab5d0164040427f7c554febae125686284e2a7 (diff)
downloadivy-csharp-92757a8d629812303ff3665343bd098917cca611.zip
ivy-csharp-92757a8d629812303ff3665343bd098917cca611.tar.gz
ivy-csharp-92757a8d629812303ff3665343bd098917cca611.tar.bz2
ivy-csharp-92757a8d629812303ff3665343bd098917cca611.tar.xz
modification structure svn
Diffstat (limited to 'Ivy/IvyTCPStreamV4.cs')
-rw-r--r--Ivy/IvyTCPStreamV4.cs273
1 files changed, 273 insertions, 0 deletions
diff --git a/Ivy/IvyTCPStreamV4.cs b/Ivy/IvyTCPStreamV4.cs
new file mode 100644
index 0000000..9a96d62
--- /dev/null
+++ b/Ivy/IvyTCPStreamV4.cs
@@ -0,0 +1,273 @@
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+
+namespace IvyBus
+{
+ /// <summary>
+ /// Description résumée de IvyStream.
+ /// </summary>
+ internal class IvyTCPStreamV4 : NetworkStream , IvyProtocol
+ {
+ BinaryReader input;
+ BinaryWriter output;
+ IvyProtocol 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 */
+ ApplicationId = 11, /* on start send my ID and priority */
+ AddBinding = 12, /* other methods for binding message based on hash table */
+
+ };
+
+ internal IvyTCPStreamV4(Socket socket, IvyProtocol _receiver) : base( socket )
+ {
+
+ input = new BinaryReader(this, Encoding.ASCII);
+ output = new BinaryWriter(this, Encoding.ASCII);
+ receiver = _receiver;
+ }
+
+
+ /*
+ * message Syntax:
+ * this is a binary formated message use of network representation
+ *
+ * message Format:
+ MessageType, id , length, string
+ */
+ private void Serialize(short arg)
+ {
+ output.Write((ushort)IPAddress.HostToNetworkOrder(arg));
+ }
+ private void Serialize(string arg)
+ {
+ short length = arg != null ? (short)arg.Length : (short)0;
+ Serialize(length);
+ if (length != 0)
+ output.Write(arg.ToCharArray());
+ }
+ private void Serialize(string[] arg)
+ {
+
+ /* serialize count */
+ Serialize((short)arg.Length);
+
+ for (int i = 0; i < arg.Length; i++)
+ {
+ Serialize(arg[i]);
+ }
+ }
+ private void sendMsg(MessageType type, int id, params string[] arg)
+ {
+
+ Serialize( (short)type );
+ Serialize( (short)id );
+ Serialize(arg);
+ 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)
+ {
+ sendMsg(MessageType.ApplicationId, priority, appId);
+ }
+
+ 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:
+ sendMsg(MessageType.AddBinding, id, expression); /* perhaps we should perform some checking here */
+ break;
+ }
+ }
+
+ void IvyProtocol.TokenDelBinding(ushort id)
+ {
+ sendMsg(MessageType.DelBinding, id, null );
+ }
+
+ 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)
+ {
+ sendMsg(MessageType.Msg, key, args );
+ }
+
+ void IvyProtocol.TokenError(ushort key, string arg)
+ {
+ sendMsg(MessageType.Msg, key, arg);
+ }
+
+ private short DeserializeShort()
+ {
+ return IPAddress.NetworkToHostOrder((short)input.ReadUInt16());
+ }
+ private string DeserializeString()
+ {
+ string arg;
+ int val_len;
+ char[] data;
+ val_len = (ushort)DeserializeShort();
+ if (val_len != 0)
+ {
+ data = input.ReadChars(val_len);
+ arg = new String(data);
+ }
+ else
+ arg = "";
+ return arg;
+ }
+
+
+ private string[] DeserializeArgument()
+ {
+ int nb_children;
+ string[] arg;
+
+ /* Deserialize childrens */
+ nb_children = (ushort)DeserializeShort();
+ /* deserialize Value */
+ arg = new string[nb_children];
+
+ for (int i = 0; i < nb_children; i++)
+ {
+ arg[i] = DeserializeString();
+ }
+ return arg;
+ }
+ bool IvyProtocol.receiveMsg()
+ {
+ MessageType msgType = MessageType.Die;
+ ushort msgId = 0;
+ string[] msgData = null;
+
+ try
+ {
+ msgType = (MessageType)(ushort)DeserializeShort();
+ msgId = (ushort)DeserializeShort();
+ msgData = DeserializeArgument();
+
+ switch (msgType)
+ {
+ case MessageType.Die:
+ receiver.TokenDie(msgId, msgData[0]);
+ break;
+
+ case MessageType.Bye:
+ receiver.TokenBye(msgId, msgData[0]);
+ break;
+
+ case MessageType.AddRegexp:
+ receiver.TokenAddBinding(BindingType.Regexp, msgId, msgData[0]);
+ break;
+
+ case MessageType.AddBinding:
+ receiver.TokenAddBinding(BindingType.Simple, msgId, msgData[0]);
+ break;
+
+ case MessageType.DelBinding:
+ receiver.TokenDelBinding(msgId);
+ break;
+
+ case MessageType.EndRegexp:
+ receiver.TokenEndRegexp();
+ break;
+
+ case MessageType.Msg:
+ receiver.TokenMsg( msgId, msgData );
+ break;
+
+ case MessageType.Pong:
+ receiver.TokenPong(msgData[0]);
+ break;
+
+ case MessageType.Ping:
+ receiver.TokenPing(msgData[0]);
+ break;
+
+ case MessageType.Error:
+ receiver.TokenError(msgId, msgData[0]);
+ break;
+
+ case MessageType.StartRegexp:
+ receiver.TokenStartRegexp(msgId, msgData[0]);
+ break;
+
+ case MessageType.DirectMsg:
+ receiver.TokenDirectMsg(msgId, msgData[0]);
+ break;
+ case MessageType.ApplicationId:
+ receiver.TokenApplicationId(msgId, msgData[0]);
+ 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;
+ }
+
+ }
+}