summaryrefslogtreecommitdiff
path: root/CSharp/Ivy/IvyPPC/IvyTCPStreamV4.cs
blob: 780b3d620647dabb0abcb9525bf78a69586ff7d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections;
using System.IO;

namespace IvyBus
{
	/// <summary>
	/// Description résumée de IvyStream.
	/// </summary>
	public class IvyStream :  NetworkStream
	{
		StringBuilder msg_buffer;  /* the message buffer */
		public IvyStream(Socket socket) : base( socket, true ) 
		{
		}
		/* the protocol magic numbers */
		internal enum MessageType : int 
		{
			Bye = 0,			/* end of the peer */
			AddRegexp = 1,		/* the peer adds a regexp */
			Msg = 2,			/* the peer sends a message */
			Error = 3,			/* error message */
			DelRegexp = 4,		/* the peer removes one of his regex */
			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 */
			AddBinding = 11,	/* other methods for binding message based on hash table */
			DelBinding = 12,	/* other methods for binding message based on hash table */
			ApplicationId = 13,	/* on start send my ID and priority */
		};
		/*
		 * message Separator:
		 */
		private const char MESSAGE_TERMINATOR	= '\0';		/* the previous protocol used \n */
		private const char MESSAGE_SEPARATOR	= '\x01';	/* end of arguments */
		/*
		 * message Format:
		MessageType + MESSAGE_SEPARATOR + id + MESSAGE_SEPARATOR + string + MESSAGE_SEPARATOR + string ....
		MessageType + MESSAGE_SEPARATOR + id + MESSAGE_SEPARATOR + string 
		 */
		internal void  sendMsg(MessageType type, int id, string arg)
		{
			try
			{
				StringBuilder builder = new StringBuilder(1024);
				builder.Append( (int)type );
				builder.Append( MESSAGE_SEPARATOR );
				builder.Append( id );
				builder.Append( MESSAGE_SEPARATOR );
				builder.Append( arg );
				builder.Append( MESSAGE_TERMINATOR );
				byte[] buffer = Encoding.ASCII.GetBytes( builder.ToString() );
				Write(buffer,0,buffer.Length);
				Flush();
			}
			catch (IOException ie)
			{
				Console.Error.WriteLine("received an exception: " + ie.Message);
				Console.Error.WriteLine(ie.StackTrace);
			}
		}
		internal void  sendMsg(MessageType type, Int32 id, string[] args)
		{
			StringBuilder builder = new StringBuilder(1024);
			builder.Append( (int)type );
			builder.Append( MESSAGE_SEPARATOR );
			builder.Append( id );
			for (int sub = 0; sub < args.Length; sub++)
			{
				builder.Append( MESSAGE_SEPARATOR );
				builder.Append( args[sub] );
			}
			builder.Append( MESSAGE_TERMINATOR );
			try
			{
				byte[] buffer = Encoding.ASCII.GetBytes( builder.ToString() );
				Write(buffer,0,buffer.Length);
				Flush();
			}
			catch (IOException ie)
			{
				Console.Error.WriteLine("received an exception: " + ie.Message);
				Console.Error.WriteLine(ie.StackTrace);
			}
		}
		internal bool  receiveMsg(out MessageType type, out int id, out string[] args)
		{
			int data;
			
			type = MessageType.Die;
			id = 0;
			args = null;
			msg_buffer = new StringBuilder(1024);
			while ( true ) 
			{
				data = ReadByte();
				if ( data == -1 ) return false;
				if ( data == MESSAGE_TERMINATOR ) break;
				msg_buffer.Append( (char)data );
			}
			ParseMsg( out type, out id , out args );
			return true;
		}
		private void  ParseMsg( out MessageType msgType, out int msgId, out string[] args)
		{
			string appID;
			string[] msgFields = msg_buffer.ToString().Split( MESSAGE_SEPARATOR );
			
			try
			{
				msgType = (IvyStream.MessageType)Int32.Parse(msgFields[0]);
			}
			catch (FormatException nfe)
			{
				throw new IvyException("protocol error on msgType");
			}
			
			try
			{
				msgId = Int32.Parse(msgFields[1]);
			}
			catch (FormatException nfe)
			{
				throw new IvyException("protocol error on identifier");
			}
			
			args = new String[msgFields.Length-2];
			for ( int i = 0; i < args.Length; i++)
			{
				args[i] = msgFields[2+i];
				// for developpemnt purposes
				// out.println(" *"+tab[i]+"* "+(tab[i]).length());
			}		
			
		}
		
		
	}
}