From 81b0cb3990d3c61e433c05c95264fc8c2237f213 Mon Sep 17 00:00:00 2001 From: Philip Schell Date: Tue, 23 Jul 2019 14:04:06 +0200 Subject: [PATCH] make it nice --- litjson/JsonData.cs | 1844 ++++++++++++++++++++--------------------- litjson/JsonMapper.cs | 137 +-- 2 files changed, 927 insertions(+), 1054 deletions(-) diff --git a/litjson/JsonData.cs b/litjson/JsonData.cs index 94fbeef..473e80c 100644 --- a/litjson/JsonData.cs +++ b/litjson/JsonData.cs @@ -19,994 +19,930 @@ 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; + public class JsonData : IJsonWrapper, IEquatable { + #region Fields + private IList inst_array; + private Boolean inst_boolean; + private Double inst_double; + private Int32 inst_int; + private Int64 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 + // Used to implement the IOrderedDictionary interface + private IList> object_list; + #endregion + #region Properties + public Int32 Count => this.EnsureCollection().Count; - #region Properties - public int Count { - get { return EnsureCollection ().Count; } - } + public Boolean IsArray => this.type == JsonType.Array; - public bool IsArray { - get { return type == JsonType.Array; } - } + public Boolean IsBoolean => this.type == JsonType.Boolean; - public bool IsBoolean { - get { return type == JsonType.Boolean; } - } + public Boolean IsDouble => this.type == JsonType.Double; - public bool IsDouble { - get { return type == JsonType.Double; } - } + public Boolean IsInt => this.type == JsonType.Int; - public bool IsInt { - get { return type == JsonType.Int; } - } + public Boolean IsLong => this.type == JsonType.Long; - public bool IsLong { - get { return type == JsonType.Long; } - } + public Boolean IsObject => this.type == JsonType.Object; - public bool IsObject { - get { return type == JsonType.Object; } - } + public Boolean IsString => this.type == JsonType.String; - public bool IsString { - get { return type == JsonType.String; } - } + public ICollection Keys { + get { + this.EnsureDictionary(); + return this.inst_object.Keys; + } + } - 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. public Boolean ContainsKey(String key) { - EnsureDictionary(); + this.EnsureDictionary(); return this.inst_object.Keys.Contains(key); } #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; - } + Int32 ICollection.Count => this.Count; - set { - EnsureCollection (); + Boolean ICollection.IsSynchronized => this.EnsureCollection().IsSynchronized; - if (type == JsonType.Array) - inst_array[index] = value; - else { - KeyValuePair entry = object_list[index]; - KeyValuePair new_entry = - new KeyValuePair (entry.Key, value); + Object ICollection.SyncRoot => this.EnsureCollection().SyncRoot; + #endregion - object_list[index] = new_entry; - inst_object[entry.Key] = value; - } + #region IDictionary Properties + Boolean IDictionary.IsFixedSize => this.EnsureDictionary().IsFixedSize; - 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; - } + Boolean IDictionary.IsReadOnly => this.EnsureDictionary().IsReadOnly; - 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"); - } + ICollection IDictionary.Keys { + get { + this.EnsureDictionary(); + IList keys = new List(); - public JsonData (string str) - { - type = JsonType.String; - inst_string = str; + foreach (KeyValuePair entry in this.object_list) { + keys.Add(entry.Key); } - #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"; - } + return (ICollection)keys; + } } + ICollection IDictionary.Values { + get { + this.EnsureDictionary(); + IList values = new List(); - internal class OrderedDictionaryEnumerator : IDictionaryEnumerator + foreach (KeyValuePair entry in this.object_list) { + values.Add(entry.Value); + } + + return (ICollection)values; + } + } + #endregion + + #region IJsonWrapper Properties + Boolean IJsonWrapper.IsArray => this.IsArray; + + Boolean IJsonWrapper.IsBoolean => this.IsBoolean; + + Boolean IJsonWrapper.IsDouble => this.IsDouble; + + Boolean IJsonWrapper.IsInt => this.IsInt; + + Boolean IJsonWrapper.IsLong => this.IsLong; + + Boolean IJsonWrapper.IsObject => this.IsObject; + + Boolean IJsonWrapper.IsString => this.IsString; + #endregion + + #region IList Properties + Boolean IList.IsFixedSize => this.EnsureList().IsFixedSize; + + Boolean IList.IsReadOnly => this.EnsureList().IsReadOnly; + #endregion + + #region IDictionary Indexer + Object IDictionary.this[Object key] { + get => this.EnsureDictionary()[key]; + set { + if (!(key is String)) { + throw new ArgumentException("The key has to be a string"); + } + + JsonData data = this.ToJsonData(value); + + this[(String)key] = data; + } + } + #endregion + + #region IOrderedDictionary Indexer + Object IOrderedDictionary.this[Int32 idx] { + get { + this.EnsureDictionary(); + return this.object_list[idx].Value; + } + set { + this.EnsureDictionary(); + JsonData data = this.ToJsonData(value); + + KeyValuePair old_entry = this.object_list[idx]; + + this.inst_object[old_entry.Key] = data; + + KeyValuePair entry = new KeyValuePair(old_entry.Key, data); + + this.object_list[idx] = entry; + } + } + #endregion + + #region IList Indexer + object IList.this[int index] { - IEnumerator> list_enumerator; + get { + return EnsureList()[index]; + } + set { + EnsureList(); + JsonData data = ToJsonData(value); - 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 (); - } + 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(); + } + } +} \ No newline at end of file diff --git a/litjson/JsonMapper.cs b/litjson/JsonMapper.cs index 79ed51b..ff84a1f 100644 --- a/litjson/JsonMapper.cs +++ b/litjson/JsonMapper.cs @@ -28,15 +28,8 @@ namespace LitJson { 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; } + get => this.element_type ?? typeof(JsonData); + set => this.element_type = value; } public Boolean IsArray { get; set; } @@ -48,15 +41,8 @@ namespace LitJson { 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; } + get => this.element_type ?? typeof(JsonData); + set => this.element_type = value; } public Boolean IsDictionary { get; set; } @@ -64,7 +50,6 @@ namespace LitJson { public IDictionary Properties { get; set; } } - internal delegate void ExporterFunc(Object obj, JsonWriter writer); public delegate void ExporterFunc(T obj, JsonWriter writer); @@ -291,15 +276,15 @@ namespace LitJson { 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 + #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)); } @@ -339,14 +324,15 @@ namespace LitJson { } // 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 + #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); @@ -514,9 +500,7 @@ namespace LitJson { return instance; } - private static void ReadSkip(JsonReader reader) { - ToWrapper(delegate { return new JsonMockWrapper(); }, reader); - } + 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) { @@ -769,7 +753,6 @@ namespace LitJson { } #endregion - public static String ToJson(Object obj) { lock (static_writer_lock) { static_writer.Reset(); @@ -780,78 +763,32 @@ namespace LitJson { } } - public static void ToJson(Object obj, JsonWriter writer) { - WriteValue(obj, writer, false, 0); - } + 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(JsonReader reader) => (JsonData)ToWrapper(delegate { return new JsonData(); }, reader); - public static JsonData ToObject(TextReader reader) { - JsonReader json_reader = new JsonReader(reader); + public static JsonData ToObject(TextReader reader) => (JsonData)ToWrapper(delegate { return new JsonData(); }, new JsonReader(reader)); - return (JsonData)ToWrapper(delegate { return new JsonData(); }, json_reader); - } + public static JsonData ToObject(String json) => (JsonData)ToWrapper(delegate { return new JsonData(); }, json); - public static JsonData ToObject(String json) { - return (JsonData)ToWrapper(delegate { return new JsonData(); }, json); - } + public static T ToObject(JsonReader reader) => (T)ReadValue(typeof(T), reader); - public static T ToObject(JsonReader reader) { - return (T)ReadValue(typeof(T), reader); - } + public static T ToObject(TextReader reader) => (T)ReadValue(typeof(T), new JsonReader(reader)); - public static T ToObject(TextReader reader) { - JsonReader json_reader = new JsonReader(reader); + public static T ToObject(String json) => (T)ReadValue(typeof(T), new JsonReader(json)); - return (T)ReadValue(typeof(T), json_reader); - } + public static Object ToObject(String json, Type ConvertType) => ReadValue(ConvertType, new JsonReader(json)); - public static T ToObject(String json) { - JsonReader reader = new JsonReader(json); + public static IJsonWrapper ToWrapper(WrapperFactory factory, JsonReader reader) => ReadValue(factory, reader); - return (T)ReadValue(typeof(T), reader); - } + public static IJsonWrapper ToWrapper(WrapperFactory factory, String json) => ReadValue(factory, new JsonReader(json)); - public static Object ToObject(String json, Type ConvertType) { - JsonReader reader = new JsonReader(json); + public static void RegisterExporter(ExporterFunc exporter) => custom_exporters_table[typeof(T)] = (Object obj, JsonWriter writer) => { exporter((T)obj, writer); }; - return ReadValue(ConvertType, reader); - } + public static void RegisterImporter(ImporterFunc importer) => RegisterImporter(custom_importers_table, typeof(TJson), typeof(TValue), (Object input) => { return importer((TJson)input); }); - public static IJsonWrapper ToWrapper(WrapperFactory factory, JsonReader reader) { - return ReadValue(factory, reader); - } + public static void UnregisterExporters() => custom_exporters_table.Clear(); - 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(); - } + public static void UnregisterImporters() => custom_importers_table.Clear(); } }