diff options
Diffstat (limited to 'IrcTokens/Protocol.cs')
-rw-r--r-- | IrcTokens/Protocol.cs | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/IrcTokens/Protocol.cs b/IrcTokens/Protocol.cs new file mode 100644 index 0000000..b2af6fa --- /dev/null +++ b/IrcTokens/Protocol.cs @@ -0,0 +1,74 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace IrcTokens +{ + public class Protocol + { + private static readonly string[] TagUnescaped = new [] + { + "\\", " ", ";", "\r", "\n" + }; + + private static readonly string[] TagEscaped = new [] + { + "\\\\", "\\s", "\\:", "\\r", "\\n" + }; + + /// <summary> + /// Unescape ircv3 tag + /// </summary> + /// <param name="val">escaped string</param> + /// <returns>unescaped string</returns> + public static string UnescapeTag(string val) + { + var unescaped = new StringBuilder(); + + var graphemeIterator = StringInfo.GetTextElementEnumerator(val); + graphemeIterator.Reset(); + + while (graphemeIterator.MoveNext()) + { + var current = graphemeIterator.GetTextElement(); + + if (current == @"\") + { + try + { + graphemeIterator.MoveNext(); + var next = graphemeIterator.GetTextElement(); + var pair = current + next; + unescaped.Append(TagEscaped.Contains(pair) + ? TagUnescaped[Array.IndexOf(TagEscaped, pair)] + : next); + } + catch (InvalidOperationException) + { + // ignored + } + } + else + unescaped.Append(current); + } + + return unescaped.ToString(); + } + + /// <summary> + /// Escape strings for use in ircv3 tags + /// </summary> + /// <param name="val">string to escape</param> + /// <returns>escaped string</returns> + public static string EscapeTag(string val) + { + for (var i = 0; i < TagUnescaped.Length; ++i) + { + val = val.Replace(TagUnescaped[i], TagEscaped[i]); + } + + return val; + } + } +} |