| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002 | #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. **/#endregionusing System;using System.Collections;using System.Collections.Generic;using System.Collections.Specialized;using System.IO;namespace 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; }        }        #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)                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)                throw new InvalidCastException (                    "Instance of JsonData doesn't hold an int");            return data.inst_long;        }        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 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<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 ();        }    }}
 |