Files
PepperDashCore/Pepperdash Core/Pepperdash Core/Comm/CommunicationGather.cs
2020-10-16 12:03:30 -05:00

182 lines
5.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Core
{
/// <summary>
/// Defines the string event handler for line events on the gather
/// </summary>
/// <param name="text">A string</param>
public delegate void LineReceivedHandler(string text);
/// <summary>
/// Attaches to IBasicCommunication as a text gather
/// </summary>
public class CommunicationGather
{
/// <summary>
/// Event that fires when a line is received from the IBasicCommunication source.
/// The event merely contains the text, not an EventArgs type class.
/// </summary>
public event EventHandler<GenericCommMethodReceiveTextArgs> LineReceived;
/// <summary>
/// The communication port that this gathers on
/// </summary>
public ICommunicationReceiver Port { get; private set; }
/// <summary>
/// Default false. If true, the delimiter will be included in the line output
/// events
/// </summary>
public bool IncludeDelimiter { get; set; }
/// <summary>
/// For receive buffer
/// </summary>
StringBuilder ReceiveBuffer = new StringBuilder();
/// <summary>
/// Delimiter character
/// </summary>
char Delimiter;
/// <summary>
/// Delimiter string
/// </summary>
string StringDelimiter;
/// <summary>
/// Fires up a gather, given a IBasicCommunicaion port and char for delimiter
/// </summary>
/// <param name="port"><seealso cref="PepperDash.Core.ICommunicationReceiver"/>ICommunicationReceiver port</param>
/// <param name="delimiter">Delimiter character</param>
public CommunicationGather(ICommunicationReceiver port, char delimiter)
{
Port = port;
Delimiter = delimiter;
port.TextReceived += new EventHandler<GenericCommMethodReceiveTextArgs>(Port_TextReceived);
}
/// <summary>
/// Fires up a gather, given a IBasicCommunicaion port and string for delimiter
/// </summary>
/// <param name="port"><seealso cref="PepperDash.Core.ICommunicationReceiver"/>ICommunicationReceiver port</param>
/// <param name="delimiter">Delimiter string</param>
public CommunicationGather(ICommunicationReceiver port, string delimiter)
{
Port = port;
StringDelimiter = delimiter;
port.TextReceived += Port_TextReceivedStringDelimiter;
}
/// <summary>
/// Disconnects this gather from the Port's TextReceived event. This will not fire LineReceived
/// after the this call.
/// </summary>
public void Stop()
{
Port.TextReceived -= Port_TextReceived;
Port.TextReceived -= Port_TextReceivedStringDelimiter;
}
/// <summary>
/// Handler for raw data coming from port
/// </summary>
void Port_TextReceived(object sender, GenericCommMethodReceiveTextArgs args)
{
var handler = LineReceived;
if (handler != null)
{
if (Debug.Level >= 2)
{
var output = Regex.Replace(args.Text,
@"\p{Cc}",
a => string.Format("[{0:X2}]", (byte)a.Value[0]));
Debug.Console(2, Port, "RX: '{0}", output);
}
ReceiveBuffer.Append(args.Text);
var str = ReceiveBuffer.ToString();
var lines = str.Split(Delimiter);
if (lines.Length > 0)
{
for (int i = 0; i < lines.Length - 1; i++)
{
string strToSend = null;
if (IncludeDelimiter)
strToSend = lines[i] + Delimiter;
else
strToSend = lines[i];
handler(this, new GenericCommMethodReceiveTextArgs(strToSend));
}
ReceiveBuffer = new StringBuilder(lines[lines.Length - 1]);
}
}
}
/// <summary>
/// Handler for delimited data coming from port
/// </summary>
/// <param name="sender">An object</param>
/// <param name="args">A GenericCommMethodReceiveTextArgs</param>
void Port_TextReceivedStringDelimiter(object sender, GenericCommMethodReceiveTextArgs args)
{
var handler = LineReceived;
if (handler != null)
{
// Receive buffer should either be empty or not contain the delimiter
// If the line does not have a delimiter, append the
if (Debug.Level >= 2)
{
var output = Regex.Replace(args.Text,
@"\p{Cc}",
a => string.Format("[{0:X2}]", (byte)a.Value[0]));
Debug.Console(2, Port, "RX: '{0}'", output);
}
ReceiveBuffer.Append(args.Text);
var str = ReceiveBuffer.ToString();
// Case: Receiving DEVICE get version\x0d\0x0a+OK "value":"1234"\x0d\x0a
// RX: DEV
// Split: (1) "DEV"
// RX: I
// Split: (1) "DEVI"
// RX: CE get version
// Split: (1) "DEVICE get version"
// RX: \x0d\x0a+OK "value":"1234"\x0d\x0a
// Split: (2) DEVICE get version, +OK "value":"1234"
var lines = Regex.Split(str, StringDelimiter);
if (lines.Length > 1)
{
for (int i = 0; i < lines.Length - 1; i++)
{
string strToSend = null;
if (IncludeDelimiter)
strToSend = lines[i] + StringDelimiter;
else
strToSend = lines[i];
handler(this, new GenericCommMethodReceiveTextArgs(strToSend));
}
ReceiveBuffer = new StringBuilder(lines[lines.Length - 1]);
}
}
}
/// <summary>
/// Deconstructor. Disconnects from port TextReceived events.
/// </summary>
~CommunicationGather()
{
Stop();
}
}
}