From 07bd38b8a54e7e217320407a60c5e138416b6400 Mon Sep 17 00:00:00 2001 From: BlubbFish Date: Thu, 2 Aug 2018 21:15:40 +0000 Subject: [PATCH] Update Librarys --- litjson/litjson/JsonData.cs | 2004 ++++++++++++++++----------------- litjson/litjson/JsonMapper.cs | 1755 ++++++++++++++--------------- mqtt/M2Mqtt.sln | 2 +- 3 files changed, 1837 insertions(+), 1924 deletions(-) diff --git a/litjson/litjson/JsonData.cs b/litjson/litjson/JsonData.cs index a753958..94fbeef 100644 --- a/litjson/litjson/JsonData.cs +++ b/litjson/litjson/JsonData.cs @@ -1,1012 +1,1012 @@ -#region Header -/** - * JsonData.cs - * Generic type to hold JSON data (objects, arrays, and so on). This is - * the default type returned by JsonMapper.ToObject(). - * - * The authors disclaim copyright to this source code. For more details, see - * the COPYING file included with this distribution. - **/ -#endregion - - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.IO; - - -namespace LitJson -{ - public class JsonData : IJsonWrapper, IEquatable - { - #region Fields - private IList inst_array; - private bool inst_boolean; - private double inst_double; - private int inst_int; - private long inst_long; - private IDictionary inst_object; - private string inst_string; - private string json; - private JsonType type; - - // Used to implement the IOrderedDictionary interface - private IList> object_list; - #endregion - - - #region Properties - public int Count { - get { return EnsureCollection ().Count; } - } - - public bool IsArray { - get { return type == JsonType.Array; } - } - - public bool IsBoolean { - get { return type == JsonType.Boolean; } - } - - public bool IsDouble { - get { return type == JsonType.Double; } - } - - public bool IsInt { - get { return type == JsonType.Int; } - } - - public bool IsLong { - get { return type == JsonType.Long; } - } - - public bool IsObject { - get { return type == JsonType.Object; } - } - - public bool IsString { - get { return type == JsonType.String; } - } - - public ICollection Keys { - get { EnsureDictionary (); return inst_object.Keys; } - } +#region Header +/** + * JsonData.cs + * Generic type to hold JSON data (objects, arrays, and so on). This is + * the default type returned by JsonMapper.ToObject(). + * + * The authors disclaim copyright to this source code. For more details, see + * the COPYING file included with this distribution. + **/ +#endregion + + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; + + +namespace LitJson +{ + public class JsonData : IJsonWrapper, IEquatable + { + #region Fields + private IList inst_array; + private bool inst_boolean; + private double inst_double; + private int inst_int; + private long inst_long; + private IDictionary inst_object; + private string inst_string; + private string json; + private JsonType type; + + // Used to implement the IOrderedDictionary interface + private IList> object_list; + #endregion + + + #region Properties + public int Count { + get { return EnsureCollection ().Count; } + } + + public bool IsArray { + get { return type == JsonType.Array; } + } + + public bool IsBoolean { + get { return type == JsonType.Boolean; } + } + + public bool IsDouble { + get { return type == JsonType.Double; } + } + + public bool IsInt { + get { return type == JsonType.Int; } + } + + public bool IsLong { + get { return type == JsonType.Long; } + } + + public bool IsObject { + get { return type == JsonType.Object; } + } + + public bool IsString { + get { return type == JsonType.String; } + } + + public ICollection Keys { + get { EnsureDictionary (); return inst_object.Keys; } + } /// /// Determines whether the dictionary contains an element that has the specified key. /// /// The key to locate in the dictionary. - /// true if the dictionary contains an element that has the specified key; otherwise, false. + /// true if the dictionary contains an element that has the specified key; otherwise, false. public Boolean ContainsKey(String key) { EnsureDictionary(); return this.inst_object.Keys.Contains(key); } - #endregion + #endregion - #region ICollection Properties - int ICollection.Count { - get { - return Count; - } - } - - bool ICollection.IsSynchronized { - get { - return EnsureCollection ().IsSynchronized; - } - } - - object ICollection.SyncRoot { - get { - return EnsureCollection ().SyncRoot; - } - } - #endregion - - - #region IDictionary Properties - bool IDictionary.IsFixedSize { - get { - return EnsureDictionary ().IsFixedSize; - } - } - - bool IDictionary.IsReadOnly { - get { - return EnsureDictionary ().IsReadOnly; - } - } - - ICollection IDictionary.Keys { - get { - EnsureDictionary (); - IList keys = new List (); - - foreach (KeyValuePair entry in - object_list) { - keys.Add (entry.Key); - } - - return (ICollection) keys; - } - } - - ICollection IDictionary.Values { - get { - EnsureDictionary (); - IList values = new List (); - - foreach (KeyValuePair entry in - object_list) { - values.Add (entry.Value); - } - - return (ICollection) values; - } - } - #endregion - - - - #region IJsonWrapper Properties - bool IJsonWrapper.IsArray { - get { return IsArray; } - } - - bool IJsonWrapper.IsBoolean { - get { return IsBoolean; } - } - - bool IJsonWrapper.IsDouble { - get { return IsDouble; } - } - - bool IJsonWrapper.IsInt { - get { return IsInt; } - } - - bool IJsonWrapper.IsLong { - get { return IsLong; } - } - - bool IJsonWrapper.IsObject { - get { return IsObject; } - } - - bool IJsonWrapper.IsString { - get { return IsString; } - } - #endregion - - - #region IList Properties - bool IList.IsFixedSize { - get { - return EnsureList ().IsFixedSize; - } - } - - bool IList.IsReadOnly { - get { - return EnsureList ().IsReadOnly; - } - } - #endregion - - - #region IDictionary Indexer - object IDictionary.this[object key] { - get { - return EnsureDictionary ()[key]; - } - - set { - if (! (key is String)) - throw new ArgumentException ( - "The key has to be a string"); - - JsonData data = ToJsonData (value); - - this[(string) key] = data; - } - } - #endregion - - - #region IOrderedDictionary Indexer - object IOrderedDictionary.this[int idx] { - get { - EnsureDictionary (); - return object_list[idx].Value; - } - - set { - EnsureDictionary (); - JsonData data = ToJsonData (value); - - KeyValuePair old_entry = object_list[idx]; - - inst_object[old_entry.Key] = data; - - KeyValuePair entry = - new KeyValuePair (old_entry.Key, data); - - object_list[idx] = entry; - } - } - #endregion - - - #region IList Indexer - object IList.this[int index] { - get { - return EnsureList ()[index]; - } - - set { - EnsureList (); - JsonData data = ToJsonData (value); - - this[index] = data; - } - } - #endregion - - - #region Public Indexers - public JsonData this[string prop_name] { - get { - EnsureDictionary (); - return inst_object[prop_name]; - } - - set { - EnsureDictionary (); - - KeyValuePair entry = - new KeyValuePair (prop_name, value); - - if (inst_object.ContainsKey (prop_name)) { - for (int i = 0; i < object_list.Count; i++) { - if (object_list[i].Key == prop_name) { - object_list[i] = entry; - break; - } - } - } else - object_list.Add (entry); - - inst_object[prop_name] = value; - - json = null; - } - } - - public JsonData this[int index] { - get { - EnsureCollection (); - - if (type == JsonType.Array) - return inst_array[index]; - - return object_list[index].Value; - } - - set { - EnsureCollection (); - - if (type == JsonType.Array) - inst_array[index] = value; - else { - KeyValuePair entry = object_list[index]; - KeyValuePair new_entry = - new KeyValuePair (entry.Key, value); - - object_list[index] = new_entry; - inst_object[entry.Key] = value; - } - - json = null; - } - } - #endregion - - - #region Constructors - public JsonData () - { - } - - public JsonData (bool boolean) - { - type = JsonType.Boolean; - inst_boolean = boolean; - } - - public JsonData (double number) - { - type = JsonType.Double; - inst_double = number; - } - - public JsonData (int number) - { - type = JsonType.Int; - inst_int = number; - } - - public JsonData (long number) - { - type = JsonType.Long; - inst_long = number; - } - - public JsonData (object obj) - { - if (obj is Boolean) { - type = JsonType.Boolean; - inst_boolean = (bool) obj; - return; - } - - if (obj is Double) { - type = JsonType.Double; - inst_double = (double) obj; - return; - } - - if (obj is Int32) { - type = JsonType.Int; - inst_int = (int) obj; - return; - } - - if (obj is Int64) { - type = JsonType.Long; - inst_long = (long) obj; - return; - } - - if (obj is String) { - type = JsonType.String; - inst_string = (string) obj; - return; - } - - throw new ArgumentException ( - "Unable to wrap the given object with JsonData"); - } - - public JsonData (string str) - { - type = JsonType.String; - inst_string = str; - } - #endregion - - - #region Implicit Conversions - public static implicit operator JsonData (Boolean data) - { - return new JsonData (data); - } - - public static implicit operator JsonData (Double data) - { - return new JsonData (data); - } - - public static implicit operator JsonData (Int32 data) - { - return new JsonData (data); - } - - public static implicit operator JsonData (Int64 data) - { - return new JsonData (data); - } - - public static implicit operator JsonData (String data) - { - return new JsonData (data); - } - #endregion - - - #region Explicit Conversions - public static explicit operator Boolean (JsonData data) - { - if (data.type != JsonType.Boolean) - throw new InvalidCastException ( - "Instance of JsonData doesn't hold a double"); - - return data.inst_boolean; - } - - public static explicit operator Double (JsonData data) - { - if (data.type != JsonType.Double) - throw new InvalidCastException ( - "Instance of JsonData doesn't hold a double"); - - return data.inst_double; - } - - public static explicit operator Int32 (JsonData data) - { - if (data.type != JsonType.Int) - throw new InvalidCastException ( - "Instance of JsonData doesn't hold an int"); - - return data.inst_int; - } - - public static explicit operator Int64 (JsonData data) - { - if (data.type != JsonType.Long && data.type != JsonType.Int) - throw new InvalidCastException ( - "Instance of JsonData doesn't hold an int"); - - return (data.type == JsonType.Long) ? data.inst_long : data.inst_int; - } - - public static explicit operator String (JsonData data) - { - if (data.type != JsonType.String) - throw new InvalidCastException ( - "Instance of JsonData doesn't hold a string"); - - return data.inst_string; - } - #endregion - - - #region ICollection Methods - void ICollection.CopyTo (Array array, int index) - { - EnsureCollection ().CopyTo (array, index); - } - #endregion - - - #region IDictionary Methods - void IDictionary.Add (object key, object value) - { - JsonData data = ToJsonData (value); - - EnsureDictionary ().Add (key, data); - - KeyValuePair entry = - new KeyValuePair ((string) key, data); - object_list.Add (entry); - - json = null; - } - - void IDictionary.Clear () - { - EnsureDictionary ().Clear (); - object_list.Clear (); - json = null; - } - - bool IDictionary.Contains (object key) - { - return EnsureDictionary ().Contains (key); - } - - IDictionaryEnumerator IDictionary.GetEnumerator () - { - return ((IOrderedDictionary) this).GetEnumerator (); - } - - void IDictionary.Remove (object key) - { - EnsureDictionary ().Remove (key); - - for (int i = 0; i < object_list.Count; i++) { - if (object_list[i].Key == (string) key) { - object_list.RemoveAt (i); - break; - } - } - - json = null; - } - #endregion - - - #region IEnumerable Methods - IEnumerator IEnumerable.GetEnumerator () - { - return EnsureCollection ().GetEnumerator (); - } - #endregion - - - #region IJsonWrapper Methods - bool IJsonWrapper.GetBoolean () - { - if (type != JsonType.Boolean) - throw new InvalidOperationException ( - "JsonData instance doesn't hold a boolean"); - - return inst_boolean; - } - - double IJsonWrapper.GetDouble () - { - if (type != JsonType.Double) - throw new InvalidOperationException ( - "JsonData instance doesn't hold a double"); - - return inst_double; - } - - int IJsonWrapper.GetInt () - { - if (type != JsonType.Int) - throw new InvalidOperationException ( - "JsonData instance doesn't hold an int"); - - return inst_int; - } - - long IJsonWrapper.GetLong () - { - if (type != JsonType.Long) - throw new InvalidOperationException ( - "JsonData instance doesn't hold a long"); - - return inst_long; - } - - string IJsonWrapper.GetString () - { - if (type != JsonType.String) - throw new InvalidOperationException ( - "JsonData instance doesn't hold a string"); - - return inst_string; - } - - void IJsonWrapper.SetBoolean (bool val) - { - type = JsonType.Boolean; - inst_boolean = val; - json = null; - } - - void IJsonWrapper.SetDouble (double val) - { - type = JsonType.Double; - inst_double = val; - json = null; - } - - void IJsonWrapper.SetInt (int val) - { - type = JsonType.Int; - inst_int = val; - json = null; - } - - void IJsonWrapper.SetLong (long val) - { - type = JsonType.Long; - inst_long = val; - json = null; - } - - void IJsonWrapper.SetString (string val) - { - type = JsonType.String; - inst_string = val; - json = null; - } - - string IJsonWrapper.ToJson () - { - return ToJson (); - } - - void IJsonWrapper.ToJson (JsonWriter writer) - { - ToJson (writer); - } - #endregion - - - #region IList Methods - int IList.Add (object value) - { - return Add (value); - } - - void IList.Clear () - { - EnsureList ().Clear (); - json = null; - } - - bool IList.Contains (object value) - { - return EnsureList ().Contains (value); - } - - int IList.IndexOf (object value) - { - return EnsureList ().IndexOf (value); - } - - void IList.Insert (int index, object value) - { - EnsureList ().Insert (index, value); - json = null; - } - - void IList.Remove (object value) - { - EnsureList ().Remove (value); - json = null; - } - - void IList.RemoveAt (int index) - { - EnsureList ().RemoveAt (index); - json = null; - } - #endregion - - - #region IOrderedDictionary Methods - IDictionaryEnumerator IOrderedDictionary.GetEnumerator () - { - EnsureDictionary (); - - return new OrderedDictionaryEnumerator ( - object_list.GetEnumerator ()); - } - - void IOrderedDictionary.Insert (int idx, object key, object value) - { - string property = (string) key; - JsonData data = ToJsonData (value); - - this[property] = data; - - KeyValuePair entry = - new KeyValuePair (property, data); - - object_list.Insert (idx, entry); - } - - void IOrderedDictionary.RemoveAt (int idx) - { - EnsureDictionary (); - - inst_object.Remove (object_list[idx].Key); - object_list.RemoveAt (idx); - } - #endregion - - - #region Private Methods - private ICollection EnsureCollection () - { - if (type == JsonType.Array) - return (ICollection) inst_array; - - if (type == JsonType.Object) - return (ICollection) inst_object; - - throw new InvalidOperationException ( - "The JsonData instance has to be initialized first"); - } - - private IDictionary EnsureDictionary () - { - if (type == JsonType.Object) - return (IDictionary) inst_object; - - if (type != JsonType.None) - throw new InvalidOperationException ( - "Instance of JsonData is not a dictionary"); - - type = JsonType.Object; - inst_object = new Dictionary (); - object_list = new List> (); - - return (IDictionary) inst_object; - } - - private IList EnsureList () - { - if (type == JsonType.Array) - return (IList) inst_array; - - if (type != JsonType.None) - throw new InvalidOperationException ( - "Instance of JsonData is not a list"); - - type = JsonType.Array; - inst_array = new List (); - - return (IList) inst_array; - } - - private JsonData ToJsonData (object obj) - { - if (obj == null) - return null; - - if (obj is JsonData) - return (JsonData) obj; - - return new JsonData (obj); - } - - private static void WriteJson (IJsonWrapper obj, JsonWriter writer) - { - if (obj == null) { - writer.Write (null); - return; - } - - if (obj.IsString) { - writer.Write (obj.GetString ()); - return; - } - - if (obj.IsBoolean) { - writer.Write (obj.GetBoolean ()); - return; - } - - if (obj.IsDouble) { - writer.Write (obj.GetDouble ()); - return; - } - - if (obj.IsInt) { - writer.Write (obj.GetInt ()); - return; - } - - if (obj.IsLong) { - writer.Write (obj.GetLong ()); - return; - } - - if (obj.IsArray) { - writer.WriteArrayStart (); - foreach (object elem in (IList) obj) - WriteJson ((JsonData) elem, writer); - writer.WriteArrayEnd (); - - return; - } - - if (obj.IsObject) { - writer.WriteObjectStart (); - - foreach (DictionaryEntry entry in ((IDictionary) obj)) { - writer.WritePropertyName ((string) entry.Key); - WriteJson ((JsonData) entry.Value, writer); - } - writer.WriteObjectEnd (); - - return; - } - } - #endregion - - - public int Add (object value) - { - JsonData data = ToJsonData (value); - - json = null; - - return EnsureList ().Add (data); - } - - public void Clear () - { - if (IsObject) { - ((IDictionary) this).Clear (); - return; - } - - if (IsArray) { - ((IList) this).Clear (); - return; - } - } - - public bool Equals (JsonData x) - { - if (x == null) - return false; - - if (x.type != this.type) - return false; - - switch (this.type) { - case JsonType.None: - return true; - - case JsonType.Object: - return this.inst_object.Equals (x.inst_object); - - case JsonType.Array: - return this.inst_array.Equals (x.inst_array); - - case JsonType.String: - return this.inst_string.Equals (x.inst_string); - - case JsonType.Int: - return this.inst_int.Equals (x.inst_int); - - case JsonType.Long: - return this.inst_long.Equals (x.inst_long); - - case JsonType.Double: - return this.inst_double.Equals (x.inst_double); - - case JsonType.Boolean: - return this.inst_boolean.Equals (x.inst_boolean); - } - - return false; - } - - public JsonType GetJsonType () - { - return type; - } - - public void SetJsonType (JsonType type) - { - if (this.type == type) - return; - - switch (type) { - case JsonType.None: - break; - - case JsonType.Object: - inst_object = new Dictionary (); - object_list = new List> (); - break; - - case JsonType.Array: - inst_array = new List (); - break; - - case JsonType.String: - inst_string = default (String); - break; - - case JsonType.Int: - inst_int = default (Int32); - break; - - case JsonType.Long: - inst_long = default (Int64); - break; - - case JsonType.Double: - inst_double = default (Double); - break; - - case JsonType.Boolean: - inst_boolean = default (Boolean); - break; - } - - this.type = type; - } - - public string ToJson () - { - if (json != null) - return json; - - StringWriter sw = new StringWriter (); - JsonWriter writer = new JsonWriter (sw); - writer.Validate = false; - - WriteJson (this, writer); - json = sw.ToString (); - - return json; - } - - public void ToJson (JsonWriter writer) - { - bool old_validate = writer.Validate; - - writer.Validate = false; - - WriteJson (this, writer); - - writer.Validate = old_validate; - } - - public override string ToString () - { - switch (type) { - case JsonType.Array: - return "JsonData array"; - - case JsonType.Boolean: - return inst_boolean.ToString (); - - case JsonType.Double: - return inst_double.ToString (); - - case JsonType.Int: - return inst_int.ToString (); - - case JsonType.Long: - return inst_long.ToString (); - - case JsonType.Object: - return "JsonData object"; - - case JsonType.String: - return inst_string; - } - - return "Uninitialized JsonData"; - } - } - - - internal class OrderedDictionaryEnumerator : IDictionaryEnumerator - { - IEnumerator> list_enumerator; - - - public object Current { - get { return Entry; } - } - - public DictionaryEntry Entry { - get { - KeyValuePair curr = list_enumerator.Current; - return new DictionaryEntry (curr.Key, curr.Value); - } - } - - public object Key { - get { return list_enumerator.Current.Key; } - } - - - public object Value { - get { return list_enumerator.Current.Value; } - } - - - public OrderedDictionaryEnumerator ( - IEnumerator> enumerator) - { - list_enumerator = enumerator; - } - - - public bool MoveNext () - { - return list_enumerator.MoveNext (); - } - - public void Reset () - { - list_enumerator.Reset (); - } - } -} + #region ICollection Properties + int ICollection.Count { + get { + return Count; + } + } + + bool ICollection.IsSynchronized { + get { + return EnsureCollection ().IsSynchronized; + } + } + + object ICollection.SyncRoot { + get { + return EnsureCollection ().SyncRoot; + } + } + #endregion + + + #region IDictionary Properties + bool IDictionary.IsFixedSize { + get { + return EnsureDictionary ().IsFixedSize; + } + } + + bool IDictionary.IsReadOnly { + get { + return EnsureDictionary ().IsReadOnly; + } + } + + ICollection IDictionary.Keys { + get { + EnsureDictionary (); + IList keys = new List (); + + foreach (KeyValuePair entry in + object_list) { + keys.Add (entry.Key); + } + + return (ICollection) keys; + } + } + + ICollection IDictionary.Values { + get { + EnsureDictionary (); + IList values = new List (); + + foreach (KeyValuePair entry in + object_list) { + values.Add (entry.Value); + } + + return (ICollection) values; + } + } + #endregion + + + + #region IJsonWrapper Properties + bool IJsonWrapper.IsArray { + get { return IsArray; } + } + + bool IJsonWrapper.IsBoolean { + get { return IsBoolean; } + } + + bool IJsonWrapper.IsDouble { + get { return IsDouble; } + } + + bool IJsonWrapper.IsInt { + get { return IsInt; } + } + + bool IJsonWrapper.IsLong { + get { return IsLong; } + } + + bool IJsonWrapper.IsObject { + get { return IsObject; } + } + + bool IJsonWrapper.IsString { + get { return IsString; } + } + #endregion + + + #region IList Properties + bool IList.IsFixedSize { + get { + return EnsureList ().IsFixedSize; + } + } + + bool IList.IsReadOnly { + get { + return EnsureList ().IsReadOnly; + } + } + #endregion + + + #region IDictionary Indexer + object IDictionary.this[object key] { + get { + return EnsureDictionary ()[key]; + } + + set { + if (! (key is String)) + throw new ArgumentException ( + "The key has to be a string"); + + JsonData data = ToJsonData (value); + + this[(string) key] = data; + } + } + #endregion + + + #region IOrderedDictionary Indexer + object IOrderedDictionary.this[int idx] { + get { + EnsureDictionary (); + return object_list[idx].Value; + } + + set { + EnsureDictionary (); + JsonData data = ToJsonData (value); + + KeyValuePair old_entry = object_list[idx]; + + inst_object[old_entry.Key] = data; + + KeyValuePair entry = + new KeyValuePair (old_entry.Key, data); + + object_list[idx] = entry; + } + } + #endregion + + + #region IList Indexer + object IList.this[int index] { + get { + return EnsureList ()[index]; + } + + set { + EnsureList (); + JsonData data = ToJsonData (value); + + this[index] = data; + } + } + #endregion + + + #region Public Indexers + public JsonData this[string prop_name] { + get { + EnsureDictionary (); + return inst_object[prop_name]; + } + + set { + EnsureDictionary (); + + KeyValuePair entry = + new KeyValuePair (prop_name, value); + + if (inst_object.ContainsKey (prop_name)) { + for (int i = 0; i < object_list.Count; i++) { + if (object_list[i].Key == prop_name) { + object_list[i] = entry; + break; + } + } + } else + object_list.Add (entry); + + inst_object[prop_name] = value; + + json = null; + } + } + + public JsonData this[int index] { + get { + EnsureCollection (); + + if (type == JsonType.Array) + return inst_array[index]; + + return object_list[index].Value; + } + + set { + EnsureCollection (); + + if (type == JsonType.Array) + inst_array[index] = value; + else { + KeyValuePair entry = object_list[index]; + KeyValuePair new_entry = + new KeyValuePair (entry.Key, value); + + object_list[index] = new_entry; + inst_object[entry.Key] = value; + } + + json = null; + } + } + #endregion + + + #region Constructors + public JsonData () + { + } + + public JsonData (bool boolean) + { + type = JsonType.Boolean; + inst_boolean = boolean; + } + + public JsonData (double number) + { + type = JsonType.Double; + inst_double = number; + } + + public JsonData (int number) + { + type = JsonType.Int; + inst_int = number; + } + + public JsonData (long number) + { + type = JsonType.Long; + inst_long = number; + } + + public JsonData (object obj) + { + if (obj is Boolean) { + type = JsonType.Boolean; + inst_boolean = (bool) obj; + return; + } + + if (obj is Double) { + type = JsonType.Double; + inst_double = (double) obj; + return; + } + + if (obj is Int32) { + type = JsonType.Int; + inst_int = (int) obj; + return; + } + + if (obj is Int64) { + type = JsonType.Long; + inst_long = (long) obj; + return; + } + + if (obj is String) { + type = JsonType.String; + inst_string = (string) obj; + return; + } + + throw new ArgumentException ( + "Unable to wrap the given object with JsonData"); + } + + public JsonData (string str) + { + type = JsonType.String; + inst_string = str; + } + #endregion + + + #region Implicit Conversions + public static implicit operator JsonData (Boolean data) + { + return new JsonData (data); + } + + public static implicit operator JsonData (Double data) + { + return new JsonData (data); + } + + public static implicit operator JsonData (Int32 data) + { + return new JsonData (data); + } + + public static implicit operator JsonData (Int64 data) + { + return new JsonData (data); + } + + public static implicit operator JsonData (String data) + { + return new JsonData (data); + } + #endregion + + + #region Explicit Conversions + public static explicit operator Boolean (JsonData data) + { + if (data.type != JsonType.Boolean) + throw new InvalidCastException ( + "Instance of JsonData doesn't hold a double"); + + return data.inst_boolean; + } + + public static explicit operator Double (JsonData data) + { + if (data.type != JsonType.Double) + throw new InvalidCastException ( + "Instance of JsonData doesn't hold a double"); + + return data.inst_double; + } + + public static explicit operator Int32 (JsonData data) + { + if (data.type != JsonType.Int) + throw new InvalidCastException ( + "Instance of JsonData doesn't hold an int"); + + return data.inst_int; + } + + public static explicit operator Int64 (JsonData data) + { + if (data.type != JsonType.Long && data.type != JsonType.Int) + throw new InvalidCastException ( + "Instance of JsonData doesn't hold an int"); + + return (data.type == JsonType.Long) ? data.inst_long : data.inst_int; + } + + public static explicit operator String (JsonData data) + { + if (data.type != JsonType.String) + throw new InvalidCastException ( + "Instance of JsonData doesn't hold a string"); + + return data.inst_string; + } + #endregion + + + #region ICollection Methods + void ICollection.CopyTo (Array array, int index) + { + EnsureCollection ().CopyTo (array, index); + } + #endregion + + + #region IDictionary Methods + void IDictionary.Add (object key, object value) + { + JsonData data = ToJsonData (value); + + EnsureDictionary ().Add (key, data); + + KeyValuePair entry = + new KeyValuePair ((string) key, data); + object_list.Add (entry); + + json = null; + } + + void IDictionary.Clear () + { + EnsureDictionary ().Clear (); + object_list.Clear (); + json = null; + } + + bool IDictionary.Contains (object key) + { + return EnsureDictionary ().Contains (key); + } + + IDictionaryEnumerator IDictionary.GetEnumerator () + { + return ((IOrderedDictionary) this).GetEnumerator (); + } + + void IDictionary.Remove (object key) + { + EnsureDictionary ().Remove (key); + + for (int i = 0; i < object_list.Count; i++) { + if (object_list[i].Key == (string) key) { + object_list.RemoveAt (i); + break; + } + } + + json = null; + } + #endregion + + + #region IEnumerable Methods + IEnumerator IEnumerable.GetEnumerator () + { + return EnsureCollection ().GetEnumerator (); + } + #endregion + + + #region IJsonWrapper Methods + bool IJsonWrapper.GetBoolean () + { + if (type != JsonType.Boolean) + throw new InvalidOperationException ( + "JsonData instance doesn't hold a boolean"); + + return inst_boolean; + } + + double IJsonWrapper.GetDouble () + { + if (type != JsonType.Double) + throw new InvalidOperationException ( + "JsonData instance doesn't hold a double"); + + return inst_double; + } + + int IJsonWrapper.GetInt () + { + if (type != JsonType.Int) + throw new InvalidOperationException ( + "JsonData instance doesn't hold an int"); + + return inst_int; + } + + long IJsonWrapper.GetLong () + { + if (type != JsonType.Long) + throw new InvalidOperationException ( + "JsonData instance doesn't hold a long"); + + return inst_long; + } + + string IJsonWrapper.GetString () + { + if (type != JsonType.String) + throw new InvalidOperationException ( + "JsonData instance doesn't hold a string"); + + return inst_string; + } + + void IJsonWrapper.SetBoolean (bool val) + { + type = JsonType.Boolean; + inst_boolean = val; + json = null; + } + + void IJsonWrapper.SetDouble (double val) + { + type = JsonType.Double; + inst_double = val; + json = null; + } + + void IJsonWrapper.SetInt (int val) + { + type = JsonType.Int; + inst_int = val; + json = null; + } + + void IJsonWrapper.SetLong (long val) + { + type = JsonType.Long; + inst_long = val; + json = null; + } + + void IJsonWrapper.SetString (string val) + { + type = JsonType.String; + inst_string = val; + json = null; + } + + string IJsonWrapper.ToJson () + { + return ToJson (); + } + + void IJsonWrapper.ToJson (JsonWriter writer) + { + ToJson (writer); + } + #endregion + + + #region IList Methods + int IList.Add (object value) + { + return Add (value); + } + + void IList.Clear () + { + EnsureList ().Clear (); + json = null; + } + + bool IList.Contains (object value) + { + return EnsureList ().Contains (value); + } + + int IList.IndexOf (object value) + { + return EnsureList ().IndexOf (value); + } + + void IList.Insert (int index, object value) + { + EnsureList ().Insert (index, value); + json = null; + } + + void IList.Remove (object value) + { + EnsureList ().Remove (value); + json = null; + } + + void IList.RemoveAt (int index) + { + EnsureList ().RemoveAt (index); + json = null; + } + #endregion + + + #region IOrderedDictionary Methods + IDictionaryEnumerator IOrderedDictionary.GetEnumerator () + { + EnsureDictionary (); + + return new OrderedDictionaryEnumerator ( + object_list.GetEnumerator ()); + } + + void IOrderedDictionary.Insert (int idx, object key, object value) + { + string property = (string) key; + JsonData data = ToJsonData (value); + + this[property] = data; + + KeyValuePair entry = + new KeyValuePair (property, data); + + object_list.Insert (idx, entry); + } + + void IOrderedDictionary.RemoveAt (int idx) + { + EnsureDictionary (); + + inst_object.Remove (object_list[idx].Key); + object_list.RemoveAt (idx); + } + #endregion + + + #region Private Methods + private ICollection EnsureCollection () + { + if (type == JsonType.Array) + return (ICollection) inst_array; + + if (type == JsonType.Object) + return (ICollection) inst_object; + + throw new InvalidOperationException ( + "The JsonData instance has to be initialized first"); + } + + private IDictionary EnsureDictionary () + { + if (type == JsonType.Object) + return (IDictionary) inst_object; + + if (type != JsonType.None) + throw new InvalidOperationException ( + "Instance of JsonData is not a dictionary"); + + type = JsonType.Object; + inst_object = new Dictionary (); + object_list = new List> (); + + return (IDictionary) inst_object; + } + + private IList EnsureList () + { + if (type == JsonType.Array) + return (IList) inst_array; + + if (type != JsonType.None) + throw new InvalidOperationException ( + "Instance of JsonData is not a list"); + + type = JsonType.Array; + inst_array = new List (); + + return (IList) inst_array; + } + + private JsonData ToJsonData (object obj) + { + if (obj == null) + return null; + + if (obj is JsonData) + return (JsonData) obj; + + return new JsonData (obj); + } + + private static void WriteJson (IJsonWrapper obj, JsonWriter writer) + { + if (obj == null) { + writer.Write (null); + return; + } + + if (obj.IsString) { + writer.Write (obj.GetString ()); + return; + } + + if (obj.IsBoolean) { + writer.Write (obj.GetBoolean ()); + return; + } + + if (obj.IsDouble) { + writer.Write (obj.GetDouble ()); + return; + } + + if (obj.IsInt) { + writer.Write (obj.GetInt ()); + return; + } + + if (obj.IsLong) { + writer.Write (obj.GetLong ()); + return; + } + + if (obj.IsArray) { + writer.WriteArrayStart (); + foreach (object elem in (IList) obj) + WriteJson ((JsonData) elem, writer); + writer.WriteArrayEnd (); + + return; + } + + if (obj.IsObject) { + writer.WriteObjectStart (); + + foreach (DictionaryEntry entry in ((IDictionary) obj)) { + writer.WritePropertyName ((string) entry.Key); + WriteJson ((JsonData) entry.Value, writer); + } + writer.WriteObjectEnd (); + + return; + } + } + #endregion + + + public int Add (object value) + { + JsonData data = ToJsonData (value); + + json = null; + + return EnsureList ().Add (data); + } + + public void Clear () + { + if (IsObject) { + ((IDictionary) this).Clear (); + return; + } + + if (IsArray) { + ((IList) this).Clear (); + return; + } + } + + public bool Equals (JsonData x) + { + if (x == null) + return false; + + if (x.type != this.type) + return false; + + switch (this.type) { + case JsonType.None: + return true; + + case JsonType.Object: + return this.inst_object.Equals (x.inst_object); + + case JsonType.Array: + return this.inst_array.Equals (x.inst_array); + + case JsonType.String: + return this.inst_string.Equals (x.inst_string); + + case JsonType.Int: + return this.inst_int.Equals (x.inst_int); + + case JsonType.Long: + return this.inst_long.Equals (x.inst_long); + + case JsonType.Double: + return this.inst_double.Equals (x.inst_double); + + case JsonType.Boolean: + return this.inst_boolean.Equals (x.inst_boolean); + } + + return false; + } + + public JsonType GetJsonType () + { + return type; + } + + public void SetJsonType (JsonType type) + { + if (this.type == type) + return; + + switch (type) { + case JsonType.None: + break; + + case JsonType.Object: + inst_object = new Dictionary (); + object_list = new List> (); + break; + + case JsonType.Array: + inst_array = new List (); + break; + + case JsonType.String: + inst_string = default (String); + break; + + case JsonType.Int: + inst_int = default (Int32); + break; + + case JsonType.Long: + inst_long = default (Int64); + break; + + case JsonType.Double: + inst_double = default (Double); + break; + + case JsonType.Boolean: + inst_boolean = default (Boolean); + break; + } + + this.type = type; + } + + public string ToJson () + { + if (json != null) + return json; + + StringWriter sw = new StringWriter (); + JsonWriter writer = new JsonWriter (sw); + writer.Validate = false; + + WriteJson (this, writer); + json = sw.ToString (); + + return json; + } + + public void ToJson (JsonWriter writer) + { + bool old_validate = writer.Validate; + + writer.Validate = false; + + WriteJson (this, writer); + + writer.Validate = old_validate; + } + + public override string ToString () + { + switch (type) { + case JsonType.Array: + return "JsonData array"; + + case JsonType.Boolean: + return inst_boolean.ToString (); + + case JsonType.Double: + return inst_double.ToString (); + + case JsonType.Int: + return inst_int.ToString (); + + case JsonType.Long: + return inst_long.ToString (); + + case JsonType.Object: + return "JsonData object"; + + case JsonType.String: + return inst_string; + } + + return "Uninitialized JsonData"; + } + } + + + internal class OrderedDictionaryEnumerator : IDictionaryEnumerator + { + IEnumerator> list_enumerator; + + + public object Current { + get { return Entry; } + } + + public DictionaryEntry Entry { + get { + KeyValuePair curr = list_enumerator.Current; + return new DictionaryEntry (curr.Key, curr.Value); + } + } + + public object Key { + get { return list_enumerator.Current.Key; } + } + + + public object Value { + get { return list_enumerator.Current.Value; } + } + + + public OrderedDictionaryEnumerator ( + IEnumerator> enumerator) + { + list_enumerator = enumerator; + } + + + public bool MoveNext () + { + return list_enumerator.MoveNext (); + } + + public void Reset () + { + list_enumerator.Reset (); + } + } +} diff --git a/litjson/litjson/JsonMapper.cs b/litjson/litjson/JsonMapper.cs index bf70994..511ea40 100644 --- a/litjson/litjson/JsonMapper.cs +++ b/litjson/litjson/JsonMapper.cs @@ -17,928 +17,841 @@ using System.IO; using System.Reflection; -namespace LitJson -{ - internal struct PropertyMetadata - { - public MemberInfo Info; - public bool IsField; - public Type Type; - } - - - internal struct ArrayMetadata - { - private Type element_type; - private bool is_array; - private bool is_list; - - - public Type ElementType { - get { - if (element_type == null) - return typeof (JsonData); - - return element_type; - } - - set { element_type = value; } +namespace LitJson { + internal struct PropertyMetadata { + public MemberInfo Info; + public Boolean IsField; + public Type Type; + } + + internal struct ArrayMetadata { + private Type element_type; + + public Type ElementType { + get { + if (this.element_type == null) { + return typeof(JsonData); + } + + return this.element_type; + } + + set { this.element_type = value; } + } + + public Boolean IsArray { get; set; } + + public Boolean IsList { get; set; } + } + + internal struct ObjectMetadata { + private Type element_type; + + public Type ElementType { + get { + if (this.element_type == null) { + return typeof(JsonData); + } + + return this.element_type; + } + + set { this.element_type = value; } + } + + public Boolean IsDictionary { get; set; } + + public IDictionary Properties { get; set; } + } + + + internal delegate void ExporterFunc(Object obj, JsonWriter writer); + public delegate void ExporterFunc(T obj, JsonWriter writer); + + internal delegate Object ImporterFunc(Object input); + public delegate TValue ImporterFunc(TJson input); + + public delegate IJsonWrapper WrapperFactory(); + + public class JsonMapper { + #region Fields + private static readonly Int32 max_nesting_depth; + + private static readonly IFormatProvider datetime_format; + + private static readonly IDictionary base_exporters_table; + private static readonly IDictionary custom_exporters_table; + + private static readonly IDictionary> base_importers_table; + private static readonly IDictionary> custom_importers_table; + + private static readonly IDictionary array_metadata; + private static readonly Object array_metadata_lock = new Object(); + + private static readonly IDictionary> conv_ops; + private static readonly Object conv_ops_lock = new Object(); + + private static readonly IDictionary object_metadata; + private static readonly Object object_metadata_lock = new Object(); + + private static readonly IDictionary> type_properties; + private static readonly Object type_properties_lock = new Object(); + + private static readonly JsonWriter static_writer; + private static readonly Object static_writer_lock = new Object(); + #endregion + + #region Constructors + static JsonMapper() { + max_nesting_depth = 100; + + array_metadata = new Dictionary(); + conv_ops = new Dictionary>(); + object_metadata = new Dictionary(); + type_properties = new Dictionary>(); + + static_writer = new JsonWriter(); + + datetime_format = DateTimeFormatInfo.InvariantInfo; + + base_exporters_table = new Dictionary(); + custom_exporters_table = new Dictionary(); + + base_importers_table = new Dictionary>(); + custom_importers_table = new Dictionary>(); + + RegisterBaseExporters(); + RegisterBaseImporters(); + } + #endregion + + #region Private Methods + private static void AddArrayMetadata(Type type) { + if (array_metadata.ContainsKey(type)) { + return; + } + + ArrayMetadata data = new ArrayMetadata { + IsArray = type.IsArray + }; + + if (type.GetInterface("System.Collections.IList") != null) { + data.IsList = true; + } + + foreach (PropertyInfo p_info in type.GetProperties()) { + if (p_info.Name != "Item") { + continue; + } + + ParameterInfo[] parameters = p_info.GetIndexParameters(); + + if (parameters.Length != 1) { + continue; + } + + if (parameters[0].ParameterType == typeof(Int32)) { + data.ElementType = p_info.PropertyType; + } + } + + lock (array_metadata_lock) { + try { + array_metadata.Add(type, data); + } catch (ArgumentException) { + return; + } + } + } + + private static void AddObjectMetadata(Type type) { + if (object_metadata.ContainsKey(type)) { + return; + } + + ObjectMetadata data = new ObjectMetadata(); + + if (type.GetInterface("System.Collections.IDictionary") != null) { + data.IsDictionary = true; + } + + data.Properties = new Dictionary(); + + foreach (PropertyInfo p_info in type.GetProperties()) { + if (p_info.Name == "Item") { + ParameterInfo[] parameters = p_info.GetIndexParameters(); + + if (parameters.Length != 1) { + continue; + } + + if (parameters[0].ParameterType == typeof(String)) { + data.ElementType = p_info.PropertyType; + } + + continue; + } + + PropertyMetadata p_data = new PropertyMetadata { + Info = p_info, + Type = p_info.PropertyType + }; + + data.Properties.Add(p_info.Name, p_data); + } + + foreach (FieldInfo f_info in type.GetFields()) { + PropertyMetadata p_data = new PropertyMetadata { + Info = f_info, + IsField = true, + Type = f_info.FieldType + }; + + data.Properties.Add(f_info.Name, p_data); + } + + lock (object_metadata_lock) { + try { + object_metadata.Add(type, data); + } catch (ArgumentException) { + return; + } + } + } + + private static void AddTypeProperties(Type type) { + if (type_properties.ContainsKey(type)) { + return; + } + + IList props = new List(); + + foreach (PropertyInfo p_info in type.GetProperties()) { + if (p_info.Name == "Item") { + continue; + } + + PropertyMetadata p_data = new PropertyMetadata { + Info = p_info, + IsField = false + }; + props.Add(p_data); + } + + foreach (FieldInfo f_info in type.GetFields()) { + PropertyMetadata p_data = new PropertyMetadata { + Info = f_info, + IsField = true + }; + + props.Add(p_data); + } + + lock (type_properties_lock) { + try { + type_properties.Add(type, props); + } catch (ArgumentException) { + return; + } + } + } + + private static MethodInfo GetConvOp(Type t1, Type t2) { + lock (conv_ops_lock) { + if (!conv_ops.ContainsKey(t1)) { + conv_ops.Add(t1, new Dictionary()); + } + } + + if (conv_ops[t1].ContainsKey(t2)) { + return conv_ops[t1][t2]; + } + + MethodInfo op = t1.GetMethod("op_Implicit", new Type[] { t2 }); + + lock (conv_ops_lock) { + try { + conv_ops[t1].Add(t2, op); + } catch (ArgumentException) { + return conv_ops[t1][t2]; + } + } + + return op; + } + + private static Object ReadValue(Type inst_type, JsonReader reader) { + reader.Read(); + + if (reader.Token == JsonToken.ArrayEnd) { + return null; + } + + Type underlying_type = Nullable.GetUnderlyingType(inst_type); + Type value_type = underlying_type ?? inst_type; + + if (reader.Token == JsonToken.Null) { +#if NETSTANDARD1_5 + if (inst_type.IsClass() || underlying_type != null) { + return null; } - - public bool IsArray { - get { return is_array; } - set { is_array = value; } - } - - public bool IsList { - get { return is_list; } - set { is_list = value; } - } - } - - - internal struct ObjectMetadata - { - private Type element_type; - private bool is_dictionary; - - private IDictionary properties; - - - public Type ElementType { - get { - if (element_type == null) - return typeof (JsonData); - - return element_type; - } - - set { element_type = value; } - } - - public bool IsDictionary { - get { return is_dictionary; } - set { is_dictionary = value; } - } - - public IDictionary Properties { - get { return properties; } - set { properties = value; } - } - } - - - internal delegate void ExporterFunc (object obj, JsonWriter writer); - public delegate void ExporterFunc (T obj, JsonWriter writer); - - internal delegate object ImporterFunc (object input); - public delegate TValue ImporterFunc (TJson input); - - public delegate IJsonWrapper WrapperFactory (); - - - public class JsonMapper - { - #region Fields - private static readonly int max_nesting_depth; - - private static readonly IFormatProvider datetime_format; - - private static readonly IDictionary base_exporters_table; - private static readonly IDictionary custom_exporters_table; - - private static readonly IDictionary> base_importers_table; - private static readonly IDictionary> custom_importers_table; - - private static readonly IDictionary array_metadata; - private static readonly object array_metadata_lock = new Object (); - - private static readonly IDictionary> conv_ops; - private static readonly object conv_ops_lock = new Object (); - - private static readonly IDictionary object_metadata; - private static readonly object object_metadata_lock = new Object (); - - private static readonly IDictionary> type_properties; - private static readonly object type_properties_lock = new Object (); - - private static readonly JsonWriter static_writer; - private static readonly object static_writer_lock = new Object (); - #endregion - - - #region Constructors - static JsonMapper () - { - max_nesting_depth = 100; - - array_metadata = new Dictionary (); - conv_ops = new Dictionary> (); - object_metadata = new Dictionary (); - type_properties = new Dictionary> (); - - static_writer = new JsonWriter (); - - datetime_format = DateTimeFormatInfo.InvariantInfo; - - base_exporters_table = new Dictionary (); - custom_exporters_table = new Dictionary (); - - base_importers_table = new Dictionary> (); - custom_importers_table = new Dictionary> (); - - RegisterBaseExporters (); - RegisterBaseImporters (); - } - #endregion - - - #region Private Methods - private static void AddArrayMetadata (Type type) - { - if (array_metadata.ContainsKey (type)) - return; - - ArrayMetadata data = new ArrayMetadata (); - - data.IsArray = type.IsArray; - - if (type.GetInterface ("System.Collections.IList") != null) - data.IsList = true; - - foreach (PropertyInfo p_info in type.GetProperties ()) { - if (p_info.Name != "Item") - continue; - - ParameterInfo[] parameters = p_info.GetIndexParameters (); - - if (parameters.Length != 1) - continue; - - if (parameters[0].ParameterType == typeof (int)) - data.ElementType = p_info.PropertyType; - } - - lock (array_metadata_lock) { - try { - array_metadata.Add (type, data); - } catch (ArgumentException) { - return; - } - } - } - - private static void AddObjectMetadata (Type type) - { - if (object_metadata.ContainsKey (type)) - return; - - ObjectMetadata data = new ObjectMetadata (); - - if (type.GetInterface ("System.Collections.IDictionary") != null) - data.IsDictionary = true; - - data.Properties = new Dictionary (); - - foreach (PropertyInfo p_info in type.GetProperties ()) { - if (p_info.Name == "Item") { - ParameterInfo[] parameters = p_info.GetIndexParameters (); - - if (parameters.Length != 1) - continue; - - if (parameters[0].ParameterType == typeof (string)) - data.ElementType = p_info.PropertyType; - - continue; - } - - PropertyMetadata p_data = new PropertyMetadata (); - p_data.Info = p_info; - p_data.Type = p_info.PropertyType; - - data.Properties.Add (p_info.Name, p_data); - } - - foreach (FieldInfo f_info in type.GetFields ()) { - PropertyMetadata p_data = new PropertyMetadata (); - p_data.Info = f_info; - p_data.IsField = true; - p_data.Type = f_info.FieldType; - - data.Properties.Add (f_info.Name, p_data); - } - - lock (object_metadata_lock) { - try { - object_metadata.Add (type, data); - } catch (ArgumentException) { - return; - } - } - } - - private static void AddTypeProperties (Type type) - { - if (type_properties.ContainsKey (type)) - return; - - IList props = new List (); - - foreach (PropertyInfo p_info in type.GetProperties ()) { - if (p_info.Name == "Item") - continue; - - PropertyMetadata p_data = new PropertyMetadata (); - p_data.Info = p_info; - p_data.IsField = false; - props.Add (p_data); - } - - foreach (FieldInfo f_info in type.GetFields ()) { - PropertyMetadata p_data = new PropertyMetadata (); - p_data.Info = f_info; - p_data.IsField = true; - - props.Add (p_data); - } - - lock (type_properties_lock) { - try { - type_properties.Add (type, props); - } catch (ArgumentException) { - return; - } - } - } - - private static MethodInfo GetConvOp (Type t1, Type t2) - { - lock (conv_ops_lock) { - if (! conv_ops.ContainsKey (t1)) - conv_ops.Add (t1, new Dictionary ()); - } - - if (conv_ops[t1].ContainsKey (t2)) - return conv_ops[t1][t2]; - - MethodInfo op = t1.GetMethod ( - "op_Implicit", new Type[] { t2 }); - - lock (conv_ops_lock) { - try { - conv_ops[t1].Add (t2, op); - } catch (ArgumentException) { - return conv_ops[t1][t2]; - } - } - - return op; - } - - private static object ReadValue (Type inst_type, JsonReader reader) - { - reader.Read (); - - if (reader.Token == JsonToken.ArrayEnd) - return null; - - Type underlying_type = Nullable.GetUnderlyingType(inst_type); - Type value_type = underlying_type ?? inst_type; - - if (reader.Token == JsonToken.Null) { - #if NETSTANDARD1_5 - if (inst_type.IsClass() || underlying_type != null) { - return null; - } - #else - if (inst_type.IsClass || underlying_type != null) { - return null; - } - #endif - - throw new JsonException (String.Format ( - "Can't assign null to an instance of type {0}", - inst_type)); - } - - if (reader.Token == JsonToken.Double || - reader.Token == JsonToken.Int || - reader.Token == JsonToken.Long || - reader.Token == JsonToken.String || - reader.Token == JsonToken.Boolean) { - - Type json_type = reader.Value.GetType (); - - if (value_type.IsAssignableFrom (json_type)) - return reader.Value; - - // If there's a custom importer that fits, use it - if (custom_importers_table.ContainsKey (json_type) && - custom_importers_table[json_type].ContainsKey ( - value_type)) { - - ImporterFunc importer = - custom_importers_table[json_type][value_type]; - - return importer (reader.Value); - } - - // Maybe there's a base importer that works - if (base_importers_table.ContainsKey (json_type) && - base_importers_table[json_type].ContainsKey ( - value_type)) { - - ImporterFunc importer = - base_importers_table[json_type][value_type]; - - return importer (reader.Value); - } - - // Maybe it's an enum - #if NETSTANDARD1_5 +#else + if (inst_type.IsClass || underlying_type != null) { + return null; + } +#endif + + throw new JsonException(String.Format("Can't assign null to an instance of type {0}", inst_type)); + } + + if (reader.Token == JsonToken.Double || + reader.Token == JsonToken.Int || + reader.Token == JsonToken.Long || + reader.Token == JsonToken.String || + reader.Token == JsonToken.Boolean) { + + Type json_type = reader.Value.GetType(); + + if (value_type.IsAssignableFrom(json_type)) { + return reader.Value; + } + + // If there's a custom importer that fits, use it + if (custom_importers_table.ContainsKey(json_type) && + custom_importers_table[json_type].ContainsKey( + value_type)) { + + ImporterFunc importer = + custom_importers_table[json_type][value_type]; + + return importer(reader.Value); + } + + // Maybe there's a base importer that works + if (base_importers_table.ContainsKey(json_type) && + base_importers_table[json_type].ContainsKey( + value_type)) { + + ImporterFunc importer = + base_importers_table[json_type][value_type]; + + return importer(reader.Value); + } + + // Maybe it's an enum +#if NETSTANDARD1_5 if (value_type.IsEnum()) return Enum.ToObject (value_type, reader.Value); - #else - if (value_type.IsEnum) - return Enum.ToObject (value_type, reader.Value); - #endif - // Try using an implicit conversion operator - MethodInfo conv_op = GetConvOp (value_type, json_type); - - if (conv_op != null) - return conv_op.Invoke (null, - new object[] { reader.Value }); - - // No luck - throw new JsonException (String.Format ( - "Can't assign value '{0}' (type {1}) to type {2}", - reader.Value, json_type, inst_type)); - } - - object instance = null; - - if (reader.Token == JsonToken.ArrayStart) { - - AddArrayMetadata (inst_type); - ArrayMetadata t_data = array_metadata[inst_type]; - - if (! t_data.IsArray && ! t_data.IsList) - throw new JsonException (String.Format ( - "Type {0} can't act as an array", - inst_type)); - - IList list; - Type elem_type; - - if (! t_data.IsArray) { - list = (IList) Activator.CreateInstance (inst_type); - elem_type = t_data.ElementType; - } else { - list = new ArrayList (); - elem_type = inst_type.GetElementType (); - } - - while (true) { - object item = ReadValue (elem_type, reader); - if (item == null && reader.Token == JsonToken.ArrayEnd) - break; - - list.Add (item); - } - - if (t_data.IsArray) { - int n = list.Count; - instance = Array.CreateInstance (elem_type, n); - - for (int i = 0; i < n; i++) - ((Array) instance).SetValue (list[i], i); - } else - instance = list; - - } else if (reader.Token == JsonToken.ObjectStart) { - AddObjectMetadata (value_type); - ObjectMetadata t_data = object_metadata[value_type]; - - instance = Activator.CreateInstance (value_type); - - while (true) { - reader.Read (); - - if (reader.Token == JsonToken.ObjectEnd) - break; - - string property = (string) reader.Value; - - if (t_data.Properties.ContainsKey (property)) { - PropertyMetadata prop_data = - t_data.Properties[property]; - - if (prop_data.IsField) { - ((FieldInfo) prop_data.Info).SetValue ( - instance, ReadValue (prop_data.Type, reader)); - } else { - PropertyInfo p_info = - (PropertyInfo) prop_data.Info; - - if (p_info.CanWrite) - p_info.SetValue ( - instance, - ReadValue (prop_data.Type, reader), - null); - else - ReadValue (prop_data.Type, reader); - } - - } else { - if (! t_data.IsDictionary) { - - if (! reader.SkipNonMembers) { - throw new JsonException (String.Format ( - "The type {0} doesn't have the " + - "property '{1}'", - inst_type, property)); - } else { - ReadSkip (reader); - continue; - } - } - - ((IDictionary) instance).Add ( - property, ReadValue ( - t_data.ElementType, reader)); - } - - } - - } - - return instance; - } - - private static IJsonWrapper ReadValue (WrapperFactory factory, - JsonReader reader) - { - reader.Read (); - - if (reader.Token == JsonToken.ArrayEnd || - reader.Token == JsonToken.Null) - return null; - - IJsonWrapper instance = factory (); - - if (reader.Token == JsonToken.String) { - instance.SetString ((string) reader.Value); - return instance; - } - - if (reader.Token == JsonToken.Double) { - instance.SetDouble ((double) reader.Value); - return instance; - } - - if (reader.Token == JsonToken.Int) { - instance.SetInt ((int) reader.Value); - return instance; - } - - if (reader.Token == JsonToken.Long) { - instance.SetLong ((long) reader.Value); - return instance; - } - - if (reader.Token == JsonToken.Boolean) { - instance.SetBoolean ((bool) reader.Value); - return instance; - } - - if (reader.Token == JsonToken.ArrayStart) { - instance.SetJsonType (JsonType.Array); - - while (true) { - IJsonWrapper item = ReadValue (factory, reader); - if (item == null && reader.Token == JsonToken.ArrayEnd) - break; - - ((IList) instance).Add (item); - } - } - else if (reader.Token == JsonToken.ObjectStart) { - instance.SetJsonType (JsonType.Object); - - while (true) { - reader.Read (); - - if (reader.Token == JsonToken.ObjectEnd) - break; - - string property = (string) reader.Value; - - ((IDictionary) instance)[property] = ReadValue ( - factory, reader); - } - - } - - return instance; - } - - private static void ReadSkip (JsonReader reader) - { - ToWrapper ( - delegate { return new JsonMockWrapper (); }, reader); - } - - private static void RegisterBaseExporters () - { - base_exporters_table[typeof (byte)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToInt32 ((byte) obj)); - }; - - base_exporters_table[typeof (char)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToString ((char) obj)); - }; - - base_exporters_table[typeof (DateTime)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToString ((DateTime) obj, - datetime_format)); - }; - - base_exporters_table[typeof (decimal)] = - delegate (object obj, JsonWriter writer) { - writer.Write ((decimal) obj); - }; - - base_exporters_table[typeof (sbyte)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToInt32 ((sbyte) obj)); - }; - - base_exporters_table[typeof (short)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToInt32 ((short) obj)); - }; - - base_exporters_table[typeof (ushort)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToInt32 ((ushort) obj)); - }; - - base_exporters_table[typeof (uint)] = - delegate (object obj, JsonWriter writer) { - writer.Write (Convert.ToUInt64 ((uint) obj)); - }; - - base_exporters_table[typeof (ulong)] = - delegate (object obj, JsonWriter writer) { - writer.Write ((ulong) obj); - }; - } - - private static void RegisterBaseImporters () - { - ImporterFunc importer; - - importer = delegate (object input) { - return Convert.ToByte ((int) input); - }; - RegisterImporter (base_importers_table, typeof (int), - typeof (byte), importer); - - importer = delegate (object input) { - return Convert.ToUInt64 ((int) input); - }; - RegisterImporter (base_importers_table, typeof (int), - typeof (ulong), importer); - - importer = delegate (object input) { - return Convert.ToSByte ((int) input); - }; - RegisterImporter (base_importers_table, typeof (int), - typeof (sbyte), importer); - - importer = delegate (object input) { - return Convert.ToInt16 ((int) input); - }; - RegisterImporter (base_importers_table, typeof (int), - typeof (short), importer); - - importer = delegate (object input) { - return Convert.ToUInt16 ((int) input); - }; - RegisterImporter (base_importers_table, typeof (int), - typeof (ushort), importer); - - importer = delegate (object input) { - return Convert.ToUInt32 ((int) input); - }; - RegisterImporter (base_importers_table, typeof (int), - typeof (uint), importer); - - importer = delegate (object input) { - return Convert.ToSingle ((int) input); - }; - RegisterImporter (base_importers_table, typeof (int), - typeof (float), importer); - - importer = delegate (object input) { - return Convert.ToDouble ((int) input); - }; - RegisterImporter (base_importers_table, typeof (int), - typeof (double), importer); - - importer = delegate (object input) { - return Convert.ToDecimal ((double) input); - }; - RegisterImporter (base_importers_table, typeof (double), - typeof (decimal), importer); - - - importer = delegate (object input) { - return Convert.ToUInt32 ((long) input); - }; - RegisterImporter (base_importers_table, typeof (long), - typeof (uint), importer); - - importer = delegate (object input) { - return Convert.ToChar ((string) input); - }; - RegisterImporter (base_importers_table, typeof (string), - typeof (char), importer); - - importer = delegate (object input) { - return Convert.ToDateTime ((string) input, datetime_format); - }; - RegisterImporter (base_importers_table, typeof (string), - typeof (DateTime), importer); - } - - private static void RegisterImporter ( - IDictionary> table, - Type json_type, Type value_type, ImporterFunc importer) - { - if (! table.ContainsKey (json_type)) - table.Add (json_type, new Dictionary ()); - - table[json_type][value_type] = importer; - } - - private static void WriteValue (object obj, JsonWriter writer, - bool writer_is_private, - int depth) - { - if (depth > max_nesting_depth) - throw new JsonException ( - String.Format ("Max allowed object depth reached while " + - "trying to export from type {0}", - obj.GetType ())); - - if (obj == null) { - writer.Write (null); - return; - } - - if (obj is IJsonWrapper) { - if (writer_is_private) - writer.TextWriter.Write (((IJsonWrapper) obj).ToJson ()); - else - ((IJsonWrapper) obj).ToJson (writer); - - return; - } - - if (obj is String) { - writer.Write ((string) obj); - return; - } - - if (obj is Double) { - writer.Write ((double) obj); - return; - } - - if (obj is Int32) { - writer.Write ((int) obj); - return; - } - - if (obj is Boolean) { - writer.Write ((bool) obj); - return; - } - - if (obj is Int64) { - writer.Write ((long) obj); - return; - } - - if (obj is Array) { - writer.WriteArrayStart (); - - foreach (object elem in (Array) obj) - WriteValue (elem, writer, writer_is_private, depth + 1); - - writer.WriteArrayEnd (); - - return; - } - - if (obj is IList) { - writer.WriteArrayStart (); - foreach (object elem in (IList) obj) - WriteValue (elem, writer, writer_is_private, depth + 1); - writer.WriteArrayEnd (); - - return; - } - - if (obj is IDictionary) { - writer.WriteObjectStart (); - foreach (DictionaryEntry entry in (IDictionary) obj) { - writer.WritePropertyName ((string) entry.Key); - WriteValue (entry.Value, writer, writer_is_private, - depth + 1); - } - writer.WriteObjectEnd (); - - return; - } - - Type obj_type = obj.GetType (); - - // See if there's a custom exporter for the object - if (custom_exporters_table.ContainsKey (obj_type)) { - ExporterFunc exporter = custom_exporters_table[obj_type]; - exporter (obj, writer); - - return; - } - - // If not, maybe there's a base exporter - if (base_exporters_table.ContainsKey (obj_type)) { - ExporterFunc exporter = base_exporters_table[obj_type]; - exporter (obj, writer); - - return; - } - - // Last option, let's see if it's an enum - if (obj is Enum) { - Type e_type = Enum.GetUnderlyingType (obj_type); - - if (e_type == typeof (long) - || e_type == typeof (uint) - || e_type == typeof (ulong)) - writer.Write ((ulong) obj); - else - writer.Write ((int) obj); - - return; - } - - // Okay, so it looks like the input should be exported as an - // object - AddTypeProperties (obj_type); - IList props = type_properties[obj_type]; - - writer.WriteObjectStart (); - foreach (PropertyMetadata p_data in props) { - if (p_data.IsField) { - writer.WritePropertyName (p_data.Info.Name); - WriteValue (((FieldInfo) p_data.Info).GetValue (obj), - writer, writer_is_private, depth + 1); - } - else { - PropertyInfo p_info = (PropertyInfo) p_data.Info; - - if (p_info.CanRead) { - writer.WritePropertyName (p_data.Info.Name); - WriteValue (p_info.GetValue (obj, null), - writer, writer_is_private, depth + 1); - } - } - } - writer.WriteObjectEnd (); - } - #endregion - - - public static string ToJson (object obj) - { - lock (static_writer_lock) { - static_writer.Reset (); - - WriteValue (obj, static_writer, true, 0); - - return static_writer.ToString (); - } - } - - public static void ToJson (object obj, JsonWriter writer) - { - WriteValue (obj, writer, false, 0); - } - - public static JsonData ToObject (JsonReader reader) - { - return (JsonData) ToWrapper ( - delegate { return new JsonData (); }, reader); - } - - public static JsonData ToObject (TextReader reader) - { - JsonReader json_reader = new JsonReader (reader); - - return (JsonData) ToWrapper ( - delegate { return new JsonData (); }, json_reader); - } - - public static JsonData ToObject (string json) - { - return (JsonData) ToWrapper ( - delegate { return new JsonData (); }, json); - } - - public static T ToObject (JsonReader reader) - { - return (T) ReadValue (typeof (T), reader); - } - - public static T ToObject (TextReader reader) - { - JsonReader json_reader = new JsonReader (reader); - - return (T) ReadValue (typeof (T), json_reader); - } - - public static T ToObject (string json) - { - JsonReader reader = new JsonReader (json); - - return (T) ReadValue (typeof (T), reader); - } - - public static object ToObject(string json, Type ConvertType ) - { - JsonReader reader = new JsonReader(json); - - return ReadValue(ConvertType, reader); - } - - public static IJsonWrapper ToWrapper (WrapperFactory factory, - JsonReader reader) - { - return ReadValue (factory, reader); - } - - public static IJsonWrapper ToWrapper (WrapperFactory factory, - string json) - { - JsonReader reader = new JsonReader (json); - - return ReadValue (factory, reader); - } - - public static void RegisterExporter (ExporterFunc exporter) - { - ExporterFunc exporter_wrapper = - delegate (object obj, JsonWriter writer) { - exporter ((T) obj, writer); - }; - - custom_exporters_table[typeof (T)] = exporter_wrapper; - } - - public static void RegisterImporter ( - ImporterFunc importer) - { - ImporterFunc importer_wrapper = - delegate (object input) { - return importer ((TJson) input); - }; - - RegisterImporter (custom_importers_table, typeof (TJson), - typeof (TValue), importer_wrapper); - } - - public static void UnregisterExporters () - { - custom_exporters_table.Clear (); - } - - public static void UnregisterImporters () - { - custom_importers_table.Clear (); - } - } +#else + if (value_type.IsEnum) { + return Enum.ToObject(value_type, reader.Value); + } +#endif + // Try using an implicit conversion operator + MethodInfo conv_op = GetConvOp(value_type, json_type); + + if (conv_op != null) { + return conv_op.Invoke(null, new Object[] { reader.Value }); + } + + // No luck + throw new JsonException(String.Format("Can't assign value '{0}' (type {1}) to type {2}", reader.Value, json_type, inst_type)); + } + + Object instance = null; + + if (reader.Token == JsonToken.ArrayStart) { + + AddArrayMetadata(inst_type); + ArrayMetadata t_data = array_metadata[inst_type]; + + if (!t_data.IsArray && !t_data.IsList) { + throw new JsonException(String.Format("Type {0} can't act as an array", inst_type)); + } + + IList list; + Type elem_type; + + if (!t_data.IsArray) { + list = (IList)Activator.CreateInstance(inst_type); + elem_type = t_data.ElementType; + } else { + list = new ArrayList(); + elem_type = inst_type.GetElementType(); + } + + while (true) { + Object item = ReadValue(elem_type, reader); + if (item == null && reader.Token == JsonToken.ArrayEnd) { + break; + } + + list.Add(item); + } + + if (t_data.IsArray) { + Int32 n = list.Count; + instance = Array.CreateInstance(elem_type, n); + + for (Int32 i = 0; i < n; i++) { + ((Array)instance).SetValue(list[i], i); + } + } else { + instance = list; + } + } else if (reader.Token == JsonToken.ObjectStart) { + AddObjectMetadata(value_type); + ObjectMetadata t_data = object_metadata[value_type]; + + instance = Activator.CreateInstance(value_type); + + while (true) { + reader.Read(); + + if (reader.Token == JsonToken.ObjectEnd) { + break; + } + + String property = (String)reader.Value; + + if (t_data.Properties.ContainsKey(property)) { + PropertyMetadata prop_data = t_data.Properties[property]; + + if (prop_data.IsField) { + ((FieldInfo)prop_data.Info).SetValue(instance, ReadValue(prop_data.Type, reader)); + } else { + PropertyInfo p_info = (PropertyInfo)prop_data.Info; + + if (p_info.CanWrite) { + p_info.SetValue(instance, ReadValue(prop_data.Type, reader), null); + } else { + ReadValue(prop_data.Type, reader); + } + } + + } else { + if (!t_data.IsDictionary) { + + if (!reader.SkipNonMembers) { + throw new JsonException(String.Format("The type {0} doesn't have the property '{1}'", inst_type, property)); + } else { + ReadSkip(reader); + continue; + } + } + ((IDictionary)instance).Add(property, ReadValue(t_data.ElementType, reader)); + } + + } + + } + + return instance; + } + + private static IJsonWrapper ReadValue(WrapperFactory factory, JsonReader reader) { + reader.Read(); + + if (reader.Token == JsonToken.ArrayEnd || + reader.Token == JsonToken.Null) { + return null; + } + + IJsonWrapper instance = factory(); + + if (reader.Token == JsonToken.String) { + instance.SetString((String)reader.Value); + return instance; + } + + if (reader.Token == JsonToken.Double) { + instance.SetDouble((Double)reader.Value); + return instance; + } + + if (reader.Token == JsonToken.Int) { + instance.SetInt((Int32)reader.Value); + return instance; + } + + if (reader.Token == JsonToken.Long) { + instance.SetLong((Int64)reader.Value); + return instance; + } + + if (reader.Token == JsonToken.Boolean) { + instance.SetBoolean((Boolean)reader.Value); + return instance; + } + + if (reader.Token == JsonToken.ArrayStart) { + instance.SetJsonType(JsonType.Array); + + while (true) { + IJsonWrapper item = ReadValue(factory, reader); + if (item == null && reader.Token == JsonToken.ArrayEnd) { + break; + } + instance.Add(item); + } + } else if (reader.Token == JsonToken.ObjectStart) { + instance.SetJsonType(JsonType.Object); + + while (true) { + reader.Read(); + + if (reader.Token == JsonToken.ObjectEnd) { + break; + } + + String property = (String)reader.Value; + + instance[property] = ReadValue(factory, reader); + } + + } + + return instance; + } + + private static void ReadSkip(JsonReader reader) { + ToWrapper(delegate { return new JsonMockWrapper(); }, reader); + } + + private static void RegisterBaseExporters() { + base_exporters_table[typeof(Byte)] = delegate (Object obj, JsonWriter writer) { + writer.Write(Convert.ToInt32((Byte)obj)); + }; + + base_exporters_table[typeof(Char)] = delegate (Object obj, JsonWriter writer) { + writer.Write(Convert.ToString((Char)obj)); + }; + + base_exporters_table[typeof(DateTime)] = delegate (Object obj, JsonWriter writer) { + writer.Write(Convert.ToString((DateTime)obj, datetime_format)); + }; + base_exporters_table[typeof(TimeSpan)] = delegate (Object obj, JsonWriter writer) { + writer.Write(Convert.ToString((TimeSpan)obj, datetime_format)); + }; + + base_exporters_table[typeof(Decimal)] = delegate (Object obj, JsonWriter writer) { + writer.Write((Decimal)obj); + }; + + base_exporters_table[typeof(SByte)] = delegate (Object obj, JsonWriter writer) { + writer.Write(Convert.ToInt32((SByte)obj)); + }; + + base_exporters_table[typeof(Int16)] = delegate (Object obj, JsonWriter writer) { + writer.Write(Convert.ToInt32((Int16)obj)); + }; + + base_exporters_table[typeof(UInt16)] = delegate (Object obj, JsonWriter writer) { + writer.Write(Convert.ToInt32((UInt16)obj)); + }; + + base_exporters_table[typeof(UInt32)] = delegate (Object obj, JsonWriter writer) { + writer.Write(Convert.ToUInt64((UInt32)obj)); + }; + + base_exporters_table[typeof(UInt64)] = delegate (Object obj, JsonWriter writer) { + writer.Write((UInt64)obj); + }; + } + + private static void RegisterBaseImporters() { + ImporterFunc importer; + + importer = delegate (Object input) { + return Convert.ToByte((Int32)input); + }; + RegisterImporter(base_importers_table, typeof(Int32), typeof(Byte), importer); + + importer = delegate (Object input) { + return Convert.ToUInt64((Int32)input); + }; + RegisterImporter(base_importers_table, typeof(Int32), typeof(UInt64), importer); + + importer = delegate (Object input) { + return Convert.ToSByte((Int32)input); + }; + RegisterImporter(base_importers_table, typeof(Int32), typeof(SByte), importer); + + importer = delegate (Object input) { + return Convert.ToInt16((Int32)input); + }; + RegisterImporter(base_importers_table, typeof(Int32), typeof(Int16), importer); + + importer = delegate (Object input) { + return Convert.ToUInt16((Int32)input); + }; + RegisterImporter(base_importers_table, typeof(Int32), typeof(UInt16), importer); + + importer = delegate (Object input) { + return Convert.ToUInt32((Int32)input); + }; + RegisterImporter(base_importers_table, typeof(Int32), typeof(UInt32), importer); + + importer = delegate (Object input) { + return Convert.ToSingle((Int32)input); + }; + RegisterImporter(base_importers_table, typeof(Int32), typeof(Single), importer); + + importer = delegate (Object input) { + return Convert.ToDouble((Int32)input); + }; + RegisterImporter(base_importers_table, typeof(Int32), typeof(Double), importer); + + importer = delegate (Object input) { + return Convert.ToDecimal((Double)input); + }; + RegisterImporter(base_importers_table, typeof(Double), typeof(Decimal), importer); + + importer = delegate (Object input) { + return Convert.ToUInt32((Int64)input); + }; + RegisterImporter(base_importers_table, typeof(Int64), typeof(UInt32), importer); + + importer = delegate (Object input) { + return Convert.ToChar((String)input); + }; + RegisterImporter(base_importers_table, typeof(String), typeof(Char), importer); + + importer = delegate (Object input) { + return Convert.ToDateTime((String)input, datetime_format); + }; + RegisterImporter(base_importers_table, typeof(String), typeof(DateTime), importer); + } + + private static void RegisterImporter(IDictionary> table, Type json_type, Type value_type, ImporterFunc importer) { + if (!table.ContainsKey(json_type)) { + table.Add(json_type, new Dictionary()); + } + + table[json_type][value_type] = importer; + } + + private static void WriteValue(Object obj, JsonWriter writer, Boolean writer_is_private, Int32 depth) { + if (depth > max_nesting_depth) { + throw new JsonException(String.Format("Max allowed object depth reached while trying to export from type {0}", obj.GetType())); + } + + if (obj == null) { + writer.Write(null); + return; + } + + if (obj is IJsonWrapper) { + if (writer_is_private) { + writer.TextWriter.Write(((IJsonWrapper)obj).ToJson()); + } else { + ((IJsonWrapper)obj).ToJson(writer); + } + + return; + } + + if (obj is String) { + writer.Write((String)obj); + return; + } + + if (obj is Double) { + writer.Write((Double)obj); + return; + } + + if (obj is Int32) { + writer.Write((Int32)obj); + return; + } + + if (obj is Boolean) { + writer.Write((Boolean)obj); + return; + } + + if (obj is Int64) { + writer.Write((Int64)obj); + return; + } + + if (obj is Array) { + writer.WriteArrayStart(); + + foreach (Object elem in (Array)obj) { + WriteValue(elem, writer, writer_is_private, depth + 1); + } + + writer.WriteArrayEnd(); + + return; + } + + if (obj is IList) { + writer.WriteArrayStart(); + foreach (Object elem in (IList)obj) { + WriteValue(elem, writer, writer_is_private, depth + 1); + } + + writer.WriteArrayEnd(); + + return; + } + + if (obj is IDictionary) { + writer.WriteObjectStart(); + foreach (DictionaryEntry entry in (IDictionary)obj) { + writer.WritePropertyName((String)entry.Key); + WriteValue(entry.Value, writer, writer_is_private, + depth + 1); + } + writer.WriteObjectEnd(); + + return; + } + + Type obj_type = obj.GetType(); + + // See if there's a custom exporter for the object + if (custom_exporters_table.ContainsKey(obj_type)) { + ExporterFunc exporter = custom_exporters_table[obj_type]; + exporter(obj, writer); + + return; + } + + // If not, maybe there's a base exporter + if (base_exporters_table.ContainsKey(obj_type)) { + ExporterFunc exporter = base_exporters_table[obj_type]; + exporter(obj, writer); + + return; + } + + // Last option, let's see if it's an enum + if (obj is Enum) { + Type e_type = Enum.GetUnderlyingType(obj_type); + + if (e_type == typeof(Int64) + || e_type == typeof(UInt32) + || e_type == typeof(UInt64)) { + writer.Write((UInt64)obj); + } else { + writer.Write((Int32)obj); + } + + return; + } + + // Okay, so it looks like the input should be exported as an + // object + AddTypeProperties(obj_type); + IList props = type_properties[obj_type]; + + writer.WriteObjectStart(); + foreach (PropertyMetadata p_data in props) { + if (p_data.IsField) { + writer.WritePropertyName(p_data.Info.Name); + WriteValue(((FieldInfo)p_data.Info).GetValue(obj), + writer, writer_is_private, depth + 1); + } else { + PropertyInfo p_info = (PropertyInfo)p_data.Info; + + if (p_info.CanRead) { + writer.WritePropertyName(p_data.Info.Name); + WriteValue(p_info.GetValue(obj, null), + writer, writer_is_private, depth + 1); + } + } + } + writer.WriteObjectEnd(); + } + #endregion + + + public static String ToJson(Object obj) { + lock (static_writer_lock) { + static_writer.Reset(); + + WriteValue(obj, static_writer, true, 0); + + return static_writer.ToString(); + } + } + + public static void ToJson(Object obj, JsonWriter writer) { + WriteValue(obj, writer, false, 0); + } + + public static JsonData ToObject(JsonReader reader) { + return (JsonData)ToWrapper(delegate { return new JsonData(); }, reader); + } + + public static JsonData ToObject(TextReader reader) { + JsonReader json_reader = new JsonReader(reader); + + return (JsonData)ToWrapper(delegate { return new JsonData(); }, json_reader); + } + + public static JsonData ToObject(String json) { + return (JsonData)ToWrapper(delegate { return new JsonData(); }, json); + } + + public static T ToObject(JsonReader reader) { + return (T)ReadValue(typeof(T), reader); + } + + public static T ToObject(TextReader reader) { + JsonReader json_reader = new JsonReader(reader); + + return (T)ReadValue(typeof(T), json_reader); + } + + public static T ToObject(String json) { + JsonReader reader = new JsonReader(json); + + return (T)ReadValue(typeof(T), reader); + } + + public static Object ToObject(String json, Type ConvertType) { + JsonReader reader = new JsonReader(json); + + return ReadValue(ConvertType, reader); + } + + public static IJsonWrapper ToWrapper(WrapperFactory factory, JsonReader reader) { + return ReadValue(factory, reader); + } + + public static IJsonWrapper ToWrapper(WrapperFactory factory, String json) { + JsonReader reader = new JsonReader(json); + + return ReadValue(factory, reader); + } + + public static void RegisterExporter(ExporterFunc exporter) { + ExporterFunc exporter_wrapper = delegate (Object obj, JsonWriter writer) { + exporter((T)obj, writer); + }; + + custom_exporters_table[typeof(T)] = exporter_wrapper; + } + + public static void RegisterImporter(ImporterFunc importer) { + ImporterFunc importer_wrapper = delegate (Object input) { + return importer((TJson)input); + }; + + RegisterImporter(custom_importers_table, typeof(TJson), typeof(TValue), importer_wrapper); + } + + public static void UnregisterExporters() { + custom_exporters_table.Clear(); + } + + public static void UnregisterImporters() { + custom_importers_table.Clear(); + } + } } diff --git a/mqtt/M2Mqtt.sln b/mqtt/M2Mqtt.sln index f3d48da..c30b7f6 100644 --- a/mqtt/M2Mqtt.sln +++ b/mqtt/M2Mqtt.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27004.2010 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "M2Mqtt", "M2Mqtt\M2Mqtt.csproj", "{A11AEF5A-B246-4FE8-8330-06DB73CC8074}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "M2Mqtt", "M2Mqtt\M2Mqtt_4.7.1.csproj", "{A11AEF5A-B246-4FE8-8330-06DB73CC8074}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution