From 0ada0c749779c4b9dbeb18638749a551589cdeeb Mon Sep 17 00:00:00 2001 From: "Frank A. Krueger" Date: Fri, 2 Mar 2018 23:44:28 -0800 Subject: [PATCH] Use custom json serialization --- Ooui/Message.cs | 116 +++++++++++++++++++++++++++++++++++++++++++++ Tests/JsonTests.cs | 52 ++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 Tests/JsonTests.cs diff --git a/Ooui/Message.cs b/Ooui/Message.cs index 1e78fc9..485db30 100644 --- a/Ooui/Message.cs +++ b/Ooui/Message.cs @@ -35,6 +35,122 @@ namespace Ooui Key = eventType, Value = value, }; + + static void WriteJsonString (System.IO.TextWriter w, string s) + { + w.Write ('\"'); + for (var i = 0; i < s.Length; i++) { + var c = s[0]; + if (c == '\r') { + w.Write ("\\r"); + } + else if (c == '\n') { + w.Write ("\\n"); + } + else if (c == '\t') { + w.Write ("\\t"); + } + else if (c == '\b') { + w.Write ("\\b"); + } + else if (c == '\\') { + w.Write ("\\"); + } + else { + w.Write (c); + } + } + w.Write ('\"'); + } + + static void WriteJsonValue (System.IO.TextWriter w, object value) + { + if (value == null) { + w.Write ("null"); + return; + } + var s = value as string; + if (s != null) { + WriteJsonString (w, s); + return; + } + + var a = value as Array; + if (a != null) { + w.Write ('['); + var head = ""; + foreach (var o in a) { + w.Write (head); + WriteJsonValue (w, o); + head = ","; + } + w.Write (']'); + return; + } + + var e = value as EventTarget; + if (e != null) { + w.Write ('\"'); + w.Write (e.Id); + w.Write ('\"'); + return; + } + + if (value is Color) { + WriteJsonString (w, ((Color)value).ToString ()); + return; + } + + var icult = System.Globalization.CultureInfo.InvariantCulture; + + if (value is double) { + w.Write (((double)value).ToString (icult)); + } + + if (value is int) { + w.Write (((int)value).ToString (icult)); + } + + if (value is float) { + w.Write (((float)value).ToString (icult)); + } + + WriteJsonString (w, Convert.ToString (value, icult)); + } + + public void WriteJson (System.IO.TextWriter w) + { + w.Write ('{'); + switch (MessageType) { + case MessageType.Call: w.Write ("\"m\":\"call\",\"id\":\""); break; + case MessageType.Create: w.Write ("\"m\":\"create\",\"id\":\""); break; + case MessageType.Event: w.Write ("\"m\":\"event\",\"id\":\""); break; + case MessageType.Listen: w.Write ("\"m\":\"listen\",\"id\":\""); break; + case MessageType.Nop: w.Write ("\"m\":\"nop\",\"id\":\""); break; + case MessageType.RemoveAttribute: w.Write ("\"m\":\"remAttr\",\"id\":\""); break; + case MessageType.Set: w.Write ("\"m\":\"set\",\"id\":\""); break; + case MessageType.SetAttribute: w.Write ("\"m\":\"setAttr\",\"id\":\""); break; + } + w.Write (TargetId); + w.Write ("\",\"k\":\""); + w.Write (Key); + if (Value != null) { + w.Write ("\",\"v\":"); + WriteJsonValue (w, Value); + w.Write ('}'); + } + else { + w.Write ("\"}"); + } + } + + public string ToJson () + { + using (var sw = new System.IO.StringWriter ()) { + WriteJson (sw); + return sw.ToString (); + } + } } [JsonConverter (typeof (StringEnumConverter))] diff --git a/Tests/JsonTests.cs b/Tests/JsonTests.cs new file mode 100644 index 0000000..f27fa35 --- /dev/null +++ b/Tests/JsonTests.cs @@ -0,0 +1,52 @@ +using System; + +#if NUNIT +using NUnit.Framework; +using TestClassAttribute = NUnit.Framework.TestFixtureAttribute; +using TestMethodAttribute = NUnit.Framework.TestCaseAttribute; +#else +using Microsoft.VisualStudio.TestTools.UnitTesting; +#endif + +using Ooui; +using System.IO; +using System.Text.RegularExpressions; + +namespace Tests +{ + [TestClass] + public class JsonTests + { + static readonly Regex noid = new Regex ("⦙\\d+"); + static string NoId (string s) + { + return noid.Replace (s, "⦙"); + } + + [TestMethod] + public void ButtonIndividualMessages () + { + var b = new Button (); + b.Text = "Hello"; + b.Click += (sender, e) => { }; + Assert.AreEqual ("{\"m\":\"create\",\"id\":\"⦙\",\"k\":\"button\"}", NoId (b.StateMessages[0].ToJson ())); + Assert.AreEqual ("{\"m\":\"call\",\"id\":\"⦙\",\"k\":\"insertBefore\",\"v\":[\"⦙\",null]}", NoId (b.StateMessages[1].ToJson ())); + Assert.AreEqual ("{\"m\":\"listen\",\"id\":\"⦙\",\"k\":\"click\"}", NoId (b.StateMessages[2].ToJson ())); + } + + [TestMethod] + public void ButtonWriteMessages () + { + var b = new Button (); + b.Text = "Hello"; + b.Click += (sender, e) => { }; + var sw = new StringWriter (); + foreach (var m in b.StateMessages) { + m.WriteJson (sw); + } + Assert.AreEqual ("{\"m\":\"create\",\"id\":\"⦙\",\"k\":\"button\"}" + + "{\"m\":\"call\",\"id\":\"⦙\",\"k\":\"insertBefore\",\"v\":[\"⦙\",null]}" + + "{\"m\":\"listen\",\"id\":\"⦙\",\"k\":\"click\"}", NoId (sw.ToString ())); + } + } +}