Revision
16306
Author
verifier
Date
2010-01-14 08:08:33 -0600 (Thu, 14 Jan 2010)

Log Message

Rewrote the parser + trying to validate contained events.

Modified Paths

Added Paths

Diff

Modified: freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/ParserTest.cs (16305 => 16306)


--- freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/ParserTest.cs	2010-01-14 07:03:24 UTC (rev 16305)
+++ freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/ParserTest.cs	2010-01-14 14:08:33 UTC (rev 16306)
@@ -4,7 +4,54 @@
 
 namespace FreeSwitch.EventSocket.Test
 {
-    class ParserTest
+    public class ParserTest
     {
+    	private const string Auth = "Content-Type: auth/request\n\n";
+
+    	private const string Messages =
+    		"Content-Type: event\nContent-Length:10\n\n1234567890\n\nContent-Type:event\nContent-Length:0\n\n";
+		private const string Messages2 =
+			"Content-Type:event\nContent-Length:0\n\nContent-Type: event\nContent-Length:10\n\n1234567890\n\n";
+
+		private const string Partial1 =
+			"Content-Type: event\nContent-Length:10\n\n12345";
+		private const string Partial2 =
+			"67890\n\nContent-Type:event\nContent-Length:0\n\n";
+
+		public void ParseAuth()
+		{
+			Parser parser = new Parser();
+			parser.Append(Auth);
+			PlainEventMsg msg = parser.ParseOne();
+
+		}
+
+		public void ParseMessages()
+		{
+			Parser parser = new Parser();
+			parser.Append(Messages);
+			var msg = parser.ParseOne();
+
+			msg = parser.ParseOne();
+		}
+
+		public void ParseMessages2()
+		{
+			Parser parser = new Parser();
+			parser.Append(Messages2);
+			var msg = parser.ParseOne();
+
+			msg = parser.ParseOne();
+		}
+
+		public void ParsePartials()
+		{
+			Parser parser = new Parser();
+			parser.Append(Partial1);
+			var msg = parser.ParseOne();
+			parser.Append(Partial2);
+			msg = parser.ParseOne();
+			msg = parser.ParseOne();
+		}
     }
 }

Modified: freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Program.cs (16305 => 16306)


--- freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Program.cs	2010-01-14 07:03:24 UTC (rev 16305)
+++ freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Program.cs	2010-01-14 14:08:33 UTC (rev 16306)
@@ -9,6 +9,12 @@
     {
         static void Main(string[] args)
         {
+			ParserTest pt = new ParserTest();
+			pt.ParseMessages();
+			pt.ParseAuth();
+			pt.ParsePartials();
+			pt.ParseMessages2();
+
             /*EventManager mgr = new EventManager();
             mgr.Subscribe(Events.GetChannelEvents());
             mgr.Start("localhost");
@@ -20,12 +26,12 @@
         }
 
         private int _counter;
-        private EventParser _parser;
+        private Parser _parser;
         Random _rand = new Random((int)DateTime.Now.Ticks);
 
         public void Test()
         {
-            _parser = new EventParser();
+            _parser = new Parser();
             string text = File.ReadAllText("C:\\mymsgs.txt");
             Thread[] threads = new Thread[5];
             for (int i = 0; i < 5; ++i)

Modified: freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventSocket.cs (16305 => 16306)


--- freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventSocket.cs	2010-01-14 07:03:24 UTC (rev 16305)
+++ freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventSocket.cs	2010-01-14 14:08:33 UTC (rev 16306)
@@ -25,7 +25,7 @@
 		private readonly Queue<CmdBase> _commands = new Queue<CmdBase>();
 		private readonly object _lockobj = new object();
 		private readonly ManualResetEvent _parseEvent = new ManualResetEvent(false);
-		private readonly EventParser _parser = new EventParser();
+		private readonly Parser _parser = new Parser();
 		private readonly Thread _parseThread;
 		private readonly byte[] _readBuffer = new byte[8192];
 		private bool _authed;

Modified: freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventBase.cs (16305 => 16306)


--- freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventBase.cs	2010-01-14 07:03:24 UTC (rev 16305)
+++ freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventBase.cs	2010-01-14 14:08:33 UTC (rev 16306)
@@ -134,7 +134,14 @@
                     m_coreId = value;
                     break;
                 case "event-date-local":
-                    m_dateLocal = DateTime.Parse(value);
+					try
+					{
+						m_dateLocal = DateTime.Parse(value);
+					}
+					catch(Exception err)
+					{
+						Console.WriteLine(err.ToString());
+					}
                     break;
                 case "event-date-gmt":
                     m_dateGMT = DateTime.Parse(value);

Modified: freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/FreeSwitch.EventSocket.csproj (16305 => 16306)


--- freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/FreeSwitch.EventSocket.csproj	2010-01-14 07:03:24 UTC (rev 16305)
+++ freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/FreeSwitch.EventSocket.csproj	2010-01-14 14:08:33 UTC (rev 16306)
@@ -96,8 +96,8 @@
     <Compile Include="Ivr\IvrQueue.cs" />
     <Compile Include="Ivr\PrivateWaitDtmf.cs" />
     <Compile Include="LogWriterHandler.cs" />
+    <Compile Include="Parser.cs" />
     <Compile Include="PlainEventMsg.cs" />
-    <Compile Include="EventParser.cs" />
     <Compile Include="Events.cs" />
     <Compile Include="Events\EventApiCommand.cs" />
     <Compile Include="Events\EventBase.cs" />

Added: freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Parser.cs (0 => 16306)


--- freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Parser.cs	                        (rev 0)
+++ freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Parser.cs	2010-01-14 14:08:33 UTC (rev 16306)
@@ -0,0 +1,161 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+	public class Parser
+	{
+		private readonly StringBuilder _text = new StringBuilder();
+		private readonly Queue<string> _piecesToAppend = new Queue<string>();
+
+		public string Text
+		{
+			get { return _text.ToString(); }
+		}
+
+		public void Append(string text)
+		{
+			lock (_piecesToAppend)
+				_piecesToAppend.Enqueue(text);
+		}
+
+		internal static void ParseHeaders(PlainEventMsg msg, string header)
+		{
+			StringParser parser = new StringParser(header);
+			string name = parser.Read(':', true);
+			while (name != string.Empty)
+			{
+				switch (name)
+				{
+					case "Content-Length":
+						msg.ContentLength = int.Parse(parser.ReadLine(true));
+						break;
+					case "Content-Type":
+						msg.ContentType = parser.ReadLine(true);
+						break;
+					case "Reply-Text":
+						msg.Body = parser.ReadLine(true);
+						break;
+				}
+
+				// empty line == end of header
+				if (parser.EOL)
+					break;
+
+				name = parser.Read(':', true);
+			}
+		}
+
+		public PlainEventMsg ParseOne()
+		{
+			AppendPieces();
+
+			int index = 0;
+			PlainEventMsg msg = FindHeaders(ref index);
+			if (msg == null)
+				return null;
+
+			// no body
+			if (msg.ContentLength <= 0)
+			{
+				_text.Remove(0, index);
+				return msg;
+			}
+
+			// too few bytes.
+			if (_text.Length-index < msg.ContentLength)
+				return null;
+
+			// ignore empty line between header and body.
+			IgnoreEmptyLines(ref index);
+
+			int start = index;
+			FindEmptyLine(ref index);
+
+			int size = index - start + 2; // include \n\n
+
+			// Validate size.
+			//
+			// Someone suggested that the sizes are correct and that 
+			// the events was wrapped. Well. I've checked if the
+			// specified position is a \n\n, and it's not.
+			//
+			// Don't force me to check source code of another implementation
+			//
+			if (size != msg.ContentLength)
+			{
+				// Check if the buffer contains header + body only,
+				// then use the reported size, despite that our check failed.
+				if (_text.Length == msg.ContentLength + start)
+					size = msg.ContentLength;
+				// buffer contains more than one message.
+				else if (_text.Length > msg.ContentLength+start)
+				{
+					// Check if the reported size ends with a \n,
+					// in that case we have a container event.
+					if (_text[msg.ContentLength + start - 1] == '\n')
+						size = msg.ContentLength;
+				}
+			}
+
+			char[] body = new char[size];
+			_text.CopyTo(start, body, 0, size);
+			msg.Body = new string(body);
+			_text.Remove(0, index);
+			return msg;
+		}
+
+		private PlainEventMsg FindHeaders(ref int index)
+		{
+			IgnoreEmptyLines(ref index);
+
+			int start = index;
+			FindEmptyLine(ref index);
+			if (start == index)
+				return null; //got no header.
+
+			char[] headerBuffer = new char[index - start];
+			_text.CopyTo(start, headerBuffer, 0, index - start);
+			
+			PlainEventMsg eventMsg = new PlainEventMsg();
+			ParseHeaders(eventMsg, new string(headerBuffer));
+			return eventMsg;
+		}
+
+
+		private void IgnoreEmptyLines(ref int index)
+		{
+			while (index < _text.Length && _text[index] == '\n')
+				++index;
+		}
+
+		private void FindEmptyLine(ref int index)
+		{
+			int pos = index;
+			while (index < _text.Length-1)
+			{
+				if (_text[index] == '\n' && _text[index + 1] == '\n')
+					return;
+				++index;
+			}
+
+			index = pos;
+		}
+
+		private void AppendPieces()
+		{
+			lock (_piecesToAppend)
+			{
+				while (_piecesToAppend.Count > 0)
+					_text.Append(_piecesToAppend.Dequeue());
+			}
+		}
+
+		public void Clear()
+		{
+			_piecesToAppend.Clear();
+			_text.Length = 0;
+		}
+	}
+}

Modified: freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringParser.cs (16305 => 16306)


--- freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringParser.cs	2010-01-14 07:03:24 UTC (rev 16305)
+++ freeswitch/trunk/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringParser.cs	2010-01-14 14:08:33 UTC (rev 16306)
@@ -188,19 +188,19 @@
             {
                 ++_pos; // skip delimiter
                 int endpos = TrimEnd(); // skip 
-                return _text.Substring(startpos, endpos - startpos);
+                return _text.Substring(startpos, endpos - startpos-1);
             }
         }
 
         private int TrimEnd()
         {
-            if (EOF)
-                return _pos;
+			if (EOF || !IsWS(_text[_pos]))
+				return _pos;
 
             int pos = _pos;
             while (IsWS(_text[pos]))
                 --pos;
-            return pos;
+            return pos+1;
         }
 
         private int FindWS(bool stopAtEOL)