using System; using System.Runtime.Serialization; using Newtonsoft.Json; using Newtonsoft.Json.Converters; namespace Ooui { public class Message { [JsonProperty("m")] public MessageType MessageType = MessageType.Nop; [JsonProperty("id")] public string TargetId = ""; [JsonProperty("k")] public string Key = ""; [JsonProperty("v", NullValueHandling = NullValueHandling.Ignore)] public object Value = null; [JsonProperty("rid", NullValueHandling = NullValueHandling.Ignore)] public string ResultId = null; public static Message Call (string targetId, string method, params object[] args) => new Message { MessageType = MessageType.Call, TargetId = targetId, Key = method, Value = args, }; public static Message Set (string targetId, string property, object value) => new Message { MessageType = MessageType.Set, TargetId = targetId, Key = property, Value = value, }; public static Message Event (string targetId, string eventType, object value = null) => new Message { MessageType = MessageType.Event, TargetId = targetId, Key = eventType, Value = value, }; public class PropertyReference { [JsonProperty ("id")] public string TargetId = ""; [JsonProperty ("k")] public string Key = ""; } 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); w.Write ('\"'); if (Value != null) { w.Write (",\"v\":"); JsonConvert.WriteJsonValue (w, Value); } if (ResultId != null) { w.Write (",\"rid\":"); JsonConvert.WriteJsonString (w, ResultId); } w.Write ('}'); } public string ToJson () { using (var sw = new System.IO.StringWriter ()) { WriteJson (sw); return sw.ToString (); } } public static Message FromJson (string json) { var m = new Message (); var i = 0; var e = json.Length; while (i < e) { while (i < e && (json[i]==',' || json[i]=='{' || char.IsWhiteSpace (json[i]))) i++; if (i >= e) throw new Exception ("JSON Unexpected end"); var n = e - i; if (json[i] == '}') break; if (n > 4 && json[i] == '\"' && json[i+2] == '\"' && json[i+3] == ':') { switch (json[i + 1]) { case 'm': if (json[i + 4] == '\"' && json[i + 5] == 'e') { m.MessageType = MessageType.Event; } i += 5; while (i < e && json[i] != '\"') i++; i++; break; case 'k': { i += 5; var se = i; while (se < e && json[se] != '\"') se++; m.Key = json.Substring (i, se - i); i = se + 1; } break; case 'v': m.Value = JsonConvert.ReadJsonValue (json, i + 4); break; } } else if (n > 5 && json[i] == '\"' && json[i + 3] == '\"' && json[i + 4] == ':' && json[i+5] == '\"') { switch (json[i + 1]) { case 'i': { i += 6; var se = i; while (se < e && json[se] != '\"') se++; m.TargetId = json.Substring (i, se - i); i = se + 1; } break; } } else { throw new Exception ("JSON Expected property"); } } return m; } public override string ToString () { return ToJson (); } } [JsonConverter (typeof (StringEnumConverter))] public enum MessageType { [EnumMember(Value = "nop")] Nop, [EnumMember(Value = "create")] Create, [EnumMember(Value = "set")] Set, [EnumMember (Value = "setAttr")] SetAttribute, [EnumMember(Value = "remAttr")] RemoveAttribute, [EnumMember(Value = "call")] Call, [EnumMember(Value = "listen")] Listen, [EnumMember(Value = "event")] Event, } }