1060 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			1060 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C#
		
	
	
	
| #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 AnyThinkAds.ThirdParty.LitJson
 | |
| {
 | |
|     public class JsonData : IJsonWrapper, IEquatable<JsonData>
 | |
|     {
 | |
|         #region Fields
 | |
|         private IList<JsonData>               inst_array;
 | |
|         private bool                          inst_boolean;
 | |
|         private double                        inst_double;
 | |
|         private int                           inst_int;
 | |
|         private long                          inst_long;
 | |
|         private IDictionary<string, JsonData> inst_object;
 | |
|         private string                        inst_string;
 | |
|         private string                        json;
 | |
|         private JsonType                      type;
 | |
| 
 | |
|         // Used to implement the IOrderedDictionary interface
 | |
|         private IList<KeyValuePair<string, JsonData>> 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<string> Keys {
 | |
|             get { EnsureDictionary (); return inst_object.Keys; }
 | |
|         }
 | |
|         
 | |
|         /// <summary>
 | |
|         /// Determines whether the json contains an element that has the specified key.
 | |
|         /// </summary>
 | |
|         /// <param name="key">The key to locate in the json.</param>
 | |
|         /// <returns>true if the json contains an element that has the specified key; otherwise, false.</returns>
 | |
|         public Boolean ContainsKey(String key) {
 | |
|             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<string> keys = new List<string> ();
 | |
| 
 | |
|                 foreach (KeyValuePair<string, JsonData> entry in
 | |
|                          object_list) {
 | |
|                     keys.Add (entry.Key);
 | |
|                 }
 | |
| 
 | |
|                 return (ICollection) keys;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         ICollection IDictionary.Values {
 | |
|             get {
 | |
|                 EnsureDictionary ();
 | |
|                 IList<JsonData> values = new List<JsonData> ();
 | |
| 
 | |
|                 foreach (KeyValuePair<string, JsonData> 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<string, JsonData> old_entry = object_list[idx];
 | |
| 
 | |
|                 inst_object[old_entry.Key] = data;
 | |
| 
 | |
|                 KeyValuePair<string, JsonData> entry =
 | |
|                     new KeyValuePair<string, JsonData> (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<string, JsonData> entry =
 | |
|                     new KeyValuePair<string, JsonData> (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<string, JsonData> entry = object_list[index];
 | |
|                     KeyValuePair<string, JsonData> new_entry =
 | |
|                         new KeyValuePair<string, JsonData> (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 && data.type != JsonType.Long)
 | |
|             {
 | |
|                 throw new InvalidCastException(
 | |
|                     "Instance of JsonData doesn't hold an int");
 | |
|             }
 | |
| 
 | |
|             // cast may truncate data... but that's up to the user to consider
 | |
|             return data.type == JsonType.Int ? data.inst_int : (int)data.inst_long;
 | |
|         }
 | |
| 
 | |
|         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 a long");
 | |
|             }
 | |
| 
 | |
|             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<string, JsonData> entry =
 | |
|                 new KeyValuePair<string, JsonData> ((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<string, JsonData> entry =
 | |
|                 new KeyValuePair<string, JsonData> (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<string, JsonData> ();
 | |
|             object_list = new List<KeyValuePair<string, JsonData>> ();
 | |
| 
 | |
|             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<JsonData> ();
 | |
| 
 | |
|             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 bool Remove(object obj)
 | |
|         {
 | |
|             json = null;
 | |
|             if(IsObject)
 | |
|             {
 | |
|                 JsonData value = null;
 | |
|                 if (inst_object.TryGetValue((string)obj, out value))
 | |
|                     return inst_object.Remove((string)obj) && object_list.Remove(new KeyValuePair<string, JsonData>((string)obj, value));
 | |
|                 else
 | |
|                     throw new KeyNotFoundException("The specified key was not found in the JsonData object.");
 | |
|             }
 | |
|             if(IsArray)
 | |
|             {
 | |
|                 return inst_array.Remove(ToJsonData(obj));
 | |
|             }
 | |
|             throw new InvalidOperationException (
 | |
|                     "Instance of JsonData is not an object or a list.");
 | |
|         }
 | |
| 
 | |
|         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)
 | |
|             {
 | |
|                 // further check to see if this is a long to int comparison
 | |
|                 if ((x.type != JsonType.Int && x.type != JsonType.Long)
 | |
|                     || (this.type != JsonType.Int && this.type != JsonType.Long))
 | |
|                 {
 | |
|                     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:
 | |
|             {
 | |
|                 if (x.IsLong)
 | |
|                 {
 | |
|                     if (x.inst_long < Int32.MinValue || x.inst_long > Int32.MaxValue)
 | |
|                         return false;
 | |
|                     return this.inst_int.Equals((int)x.inst_long);
 | |
|                 }
 | |
|                 return this.inst_int.Equals(x.inst_int);
 | |
|             }
 | |
| 
 | |
|             case JsonType.Long:
 | |
|             {
 | |
|                 if (x.IsInt)
 | |
|                 {
 | |
|                     if (this.inst_long < Int32.MinValue || this.inst_long > Int32.MaxValue)
 | |
|                         return false;
 | |
|                     return x.inst_int.Equals((int)this.inst_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<string, JsonData> ();
 | |
|                 object_list = new List<KeyValuePair<string, JsonData>> ();
 | |
|                 break;
 | |
| 
 | |
|             case JsonType.Array:
 | |
|                 inst_array = new List<JsonData> ();
 | |
|                 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<KeyValuePair<string, JsonData>> list_enumerator;
 | |
| 
 | |
| 
 | |
|         public object Current {
 | |
|             get { return Entry; }
 | |
|         }
 | |
| 
 | |
|         public DictionaryEntry Entry {
 | |
|             get {
 | |
|                 KeyValuePair<string, JsonData> 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<KeyValuePair<string, JsonData>> enumerator)
 | |
|         {
 | |
|             list_enumerator = enumerator;
 | |
|         }
 | |
| 
 | |
| 
 | |
|         public bool MoveNext ()
 | |
|         {
 | |
|             return list_enumerator.MoveNext ();
 | |
|         }
 | |
| 
 | |
|         public void Reset ()
 | |
|         {
 | |
|             list_enumerator.Reset ();
 | |
|         }
 | |
|     }
 | |
| }
 |