提交 5eb42b18 authored 作者: Jonas Gauffin's avatar Jonas Gauffin

Rewrote the parser + trying to validate contained events.

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk/contrib@16306 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 ef337e2a
......@@ -4,7 +4,54 @@ using System.Text;
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();
}
}
}
......@@ -9,6 +9,12 @@ namespace FreeSwitch.EventSocket.Test
{
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 @@ namespace FreeSwitch.EventSocket.Test
}
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)
......
......@@ -25,7 +25,7 @@ namespace FreeSwitch.EventSocket
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;
......
......@@ -134,7 +134,14 @@ namespace FreeSwitch.EventSocket
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);
......
......@@ -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" />
......
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;
}
}
}
......@@ -188,19 +188,19 @@ namespace FreeSwitch.EventSocket
{
++_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)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论