corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 #region Header
2 /*
3 * JsonData.cs
4 * Generic type to hold JSON data (objects, arrays, and so on). This is
5 * the default type returned by JsonMapper.ToObject().
6 *
7 * The authors disclaim copyright to this source code. For more details, see
8 * the COPYING file included with this distribution.
9 */
10 #endregion
11  
12  
13 using System;
14 using System.Collections;
15 using System.Collections.Generic;
16 using System.Collections.Specialized;
17 using System.IO;
18  
19  
20 namespace LitJson
21 {
22 public class JsonData : IJsonWrapper, IEquatable<JsonData>
23 {
24 #region Fields
25 private IList<JsonData> inst_array;
26 private bool inst_boolean;
27 private double inst_double;
28 private int inst_int;
29 private long inst_long;
30 private IDictionary<string, JsonData> inst_object;
31 private string inst_string;
32 private string json;
33 private JsonType type;
34  
35 // Used to implement the IOrderedDictionary interface
36 private IList<KeyValuePair<string, JsonData>> object_list;
37 #endregion
38  
39  
40 #region Properties
41 public int Count {
42 get { return EnsureCollection ().Count; }
43 }
44  
45 public bool IsArray {
46 get { return type == JsonType.Array; }
47 }
48  
49 public bool IsBoolean {
50 get { return type == JsonType.Boolean; }
51 }
52  
53 public bool IsDouble {
54 get { return type == JsonType.Double; }
55 }
56  
57 public bool IsInt {
58 get { return type == JsonType.Int; }
59 }
60  
61 public bool IsLong {
62 get { return type == JsonType.Long; }
63 }
64  
65 public bool IsObject {
66 get { return type == JsonType.Object; }
67 }
68  
69 public bool IsString {
70 get { return type == JsonType.String; }
71 }
72 #endregion
73  
74  
75 #region ICollection Properties
76 int ICollection.Count {
77 get {
78 return Count;
79 }
80 }
81  
82 bool ICollection.IsSynchronized {
83 get {
84 return EnsureCollection ().IsSynchronized;
85 }
86 }
87  
88 object ICollection.SyncRoot {
89 get {
90 return EnsureCollection ().SyncRoot;
91 }
92 }
93 #endregion
94  
95  
96 #region IDictionary Properties
97 bool IDictionary.IsFixedSize {
98 get {
99 return EnsureDictionary ().IsFixedSize;
100 }
101 }
102  
103 bool IDictionary.IsReadOnly {
104 get {
105 return EnsureDictionary ().IsReadOnly;
106 }
107 }
108  
109 ICollection IDictionary.Keys {
110 get {
111 EnsureDictionary ();
112 IList<string> keys = new List<string> ();
113  
114 foreach (KeyValuePair<string, JsonData> entry in
115 object_list) {
116 keys.Add (entry.Key);
117 }
118  
119 return (ICollection) keys;
120 }
121 }
122  
123 ICollection IDictionary.Values {
124 get {
125 EnsureDictionary ();
126 IList<JsonData> values = new List<JsonData> ();
127  
128 foreach (KeyValuePair<string, JsonData> entry in
129 object_list) {
130 values.Add (entry.Value);
131 }
132  
133 return (ICollection) values;
134 }
135 }
136 #endregion
137  
138  
139  
140 #region IJsonWrapper Properties
141 bool IJsonWrapper.IsArray {
142 get { return IsArray; }
143 }
144  
145 bool IJsonWrapper.IsBoolean {
146 get { return IsBoolean; }
147 }
148  
149 bool IJsonWrapper.IsDouble {
150 get { return IsDouble; }
151 }
152  
153 bool IJsonWrapper.IsInt {
154 get { return IsInt; }
155 }
156  
157 bool IJsonWrapper.IsLong {
158 get { return IsLong; }
159 }
160  
161 bool IJsonWrapper.IsObject {
162 get { return IsObject; }
163 }
164  
165 bool IJsonWrapper.IsString {
166 get { return IsString; }
167 }
168 #endregion
169  
170  
171 #region IList Properties
172 bool IList.IsFixedSize {
173 get {
174 return EnsureList ().IsFixedSize;
175 }
176 }
177  
178 bool IList.IsReadOnly {
179 get {
180 return EnsureList ().IsReadOnly;
181 }
182 }
183 #endregion
184  
185  
186 #region IDictionary Indexer
187 object IDictionary.this[object key] {
188 get {
189 return EnsureDictionary ()[key];
190 }
191  
192 set {
193 if (! (key is String))
194 throw new ArgumentException (
195 "The key has to be a string");
196  
197 JsonData data = ToJsonData (value);
198  
199 this[(string) key] = data;
200 }
201 }
202 #endregion
203  
204  
205 #region IOrderedDictionary Indexer
206 object IOrderedDictionary.this[int idx] {
207 get {
208 EnsureDictionary ();
209 return object_list[idx].Value;
210 }
211  
212 set {
213 EnsureDictionary ();
214 JsonData data = ToJsonData (value);
215  
216 KeyValuePair<string, JsonData> old_entry = object_list[idx];
217  
218 inst_object[old_entry.Key] = data;
219  
220 KeyValuePair<string, JsonData> entry =
221 new KeyValuePair<string, JsonData> (old_entry.Key, data);
222  
223 object_list[idx] = entry;
224 }
225 }
226 #endregion
227  
228  
229 #region IList Indexer
230 object IList.this[int index] {
231 get {
232 return EnsureList ()[index];
233 }
234  
235 set {
236 EnsureList ();
237 JsonData data = ToJsonData (value);
238  
239 this[index] = data;
240 }
241 }
242 #endregion
243  
244  
245 #region Public Indexers
246 public JsonData this[string prop_name] {
247 get {
248 EnsureDictionary ();
249 return inst_object[prop_name];
250 }
251  
252 set {
253 EnsureDictionary ();
254  
255 KeyValuePair<string, JsonData> entry =
256 new KeyValuePair<string, JsonData> (prop_name, value);
257  
258 if (inst_object.ContainsKey (prop_name)) {
259 for (int i = 0; i < object_list.Count; i++) {
260 if (object_list[i].Key == prop_name) {
261 object_list[i] = entry;
262 break;
263 }
264 }
265 } else
266 object_list.Add (entry);
267  
268 inst_object[prop_name] = value;
269  
270 json = null;
271 }
272 }
273  
274 public JsonData this[int index] {
275 get {
276 EnsureCollection ();
277  
278 if (type == JsonType.Array)
279 return inst_array[index];
280  
281 return object_list[index].Value;
282 }
283  
284 set {
285 EnsureCollection ();
286  
287 if (type == JsonType.Array)
288 inst_array[index] = value;
289 else {
290 KeyValuePair<string, JsonData> entry = object_list[index];
291 KeyValuePair<string, JsonData> new_entry =
292 new KeyValuePair<string, JsonData> (entry.Key, value);
293  
294 object_list[index] = new_entry;
295 inst_object[entry.Key] = value;
296 }
297  
298 json = null;
299 }
300 }
301 #endregion
302  
303  
304 #region Constructors
305 public JsonData ()
306 {
307 }
308  
309 public JsonData (bool boolean)
310 {
311 type = JsonType.Boolean;
312 inst_boolean = boolean;
313 }
314  
315 public JsonData (double number)
316 {
317 type = JsonType.Double;
318 inst_double = number;
319 }
320  
321 public JsonData (int number)
322 {
323 type = JsonType.Int;
324 inst_int = number;
325 }
326  
327 public JsonData (long number)
328 {
329 type = JsonType.Long;
330 inst_long = number;
331 }
332  
333 public JsonData (object obj)
334 {
335 if (obj is Boolean) {
336 type = JsonType.Boolean;
337 inst_boolean = (bool) obj;
338 return;
339 }
340  
341 if (obj is Double) {
342 type = JsonType.Double;
343 inst_double = (double) obj;
344 return;
345 }
346  
347 if (obj is Int32) {
348 type = JsonType.Int;
349 inst_int = (int) obj;
350 return;
351 }
352  
353 if (obj is Int64) {
354 type = JsonType.Long;
355 inst_long = (long) obj;
356 return;
357 }
358  
359 if (obj is String) {
360 type = JsonType.String;
361 inst_string = (string) obj;
362 return;
363 }
364  
365 throw new ArgumentException (
366 "Unable to wrap the given object with JsonData");
367 }
368  
369 public JsonData (string str)
370 {
371 type = JsonType.String;
372 inst_string = str;
373 }
374 #endregion
375  
376  
377 #region Implicit Conversions
378 public static implicit operator JsonData (Boolean data)
379 {
380 return new JsonData (data);
381 }
382  
383 public static implicit operator JsonData (Double data)
384 {
385 return new JsonData (data);
386 }
387  
388 public static implicit operator JsonData (Int32 data)
389 {
390 return new JsonData (data);
391 }
392  
393 public static implicit operator JsonData (Int64 data)
394 {
395 return new JsonData (data);
396 }
397  
398 public static implicit operator JsonData (String data)
399 {
400 return new JsonData (data);
401 }
402 #endregion
403  
404  
405 #region Explicit Conversions
406 public static explicit operator Boolean (JsonData data)
407 {
408 if (data.type != JsonType.Boolean)
409 throw new InvalidCastException (
410 "Instance of JsonData doesn't hold a double");
411  
412 return data.inst_boolean;
413 }
414  
415 public static explicit operator Double (JsonData data)
416 {
417 if (data.type != JsonType.Double)
418 throw new InvalidCastException (
419 "Instance of JsonData doesn't hold a double");
420  
421 return data.inst_double;
422 }
423  
424 public static explicit operator Int32 (JsonData data)
425 {
426 if (data.type != JsonType.Int)
427 throw new InvalidCastException (
428 "Instance of JsonData doesn't hold an int");
429  
430 return data.inst_int;
431 }
432  
433 public static explicit operator Int64 (JsonData data)
434 {
435 if (data.type != JsonType.Long)
436 throw new InvalidCastException (
437 "Instance of JsonData doesn't hold an int");
438  
439 return data.inst_long;
440 }
441  
442 public static explicit operator String (JsonData data)
443 {
444 if (data.type != JsonType.String)
445 throw new InvalidCastException (
446 "Instance of JsonData doesn't hold a string");
447  
448 return data.inst_string;
449 }
450 #endregion
451  
452  
453 #region ICollection Methods
454 void ICollection.CopyTo (Array array, int index)
455 {
456 EnsureCollection ().CopyTo (array, index);
457 }
458 #endregion
459  
460  
461 #region IDictionary Methods
462 void IDictionary.Add (object key, object value)
463 {
464 JsonData data = ToJsonData (value);
465  
466 EnsureDictionary ().Add (key, data);
467  
468 KeyValuePair<string, JsonData> entry =
469 new KeyValuePair<string, JsonData> ((string) key, data);
470 object_list.Add (entry);
471  
472 json = null;
473 }
474  
475 void IDictionary.Clear ()
476 {
477 EnsureDictionary ().Clear ();
478 object_list.Clear ();
479 json = null;
480 }
481  
482 bool IDictionary.Contains (object key)
483 {
484 return EnsureDictionary ().Contains (key);
485 }
486  
487 IDictionaryEnumerator IDictionary.GetEnumerator ()
488 {
489 return ((IOrderedDictionary) this).GetEnumerator ();
490 }
491  
492 void IDictionary.Remove (object key)
493 {
494 EnsureDictionary ().Remove (key);
495  
496 for (int i = 0; i < object_list.Count; i++) {
497 if (object_list[i].Key == (string) key) {
498 object_list.RemoveAt (i);
499 break;
500 }
501 }
502  
503 json = null;
504 }
505 #endregion
506  
507  
508 #region IEnumerable Methods
509 IEnumerator IEnumerable.GetEnumerator ()
510 {
511 return EnsureCollection ().GetEnumerator ();
512 }
513 #endregion
514  
515  
516 #region IJsonWrapper Methods
517 bool IJsonWrapper.GetBoolean ()
518 {
519 if (type != JsonType.Boolean)
520 throw new InvalidOperationException (
521 "JsonData instance doesn't hold a boolean");
522  
523 return inst_boolean;
524 }
525  
526 double IJsonWrapper.GetDouble ()
527 {
528 if (type != JsonType.Double)
529 throw new InvalidOperationException (
530 "JsonData instance doesn't hold a double");
531  
532 return inst_double;
533 }
534  
535 int IJsonWrapper.GetInt ()
536 {
537 if (type != JsonType.Int)
538 throw new InvalidOperationException (
539 "JsonData instance doesn't hold an int");
540  
541 return inst_int;
542 }
543  
544 long IJsonWrapper.GetLong ()
545 {
546 if (type != JsonType.Long)
547 throw new InvalidOperationException (
548 "JsonData instance doesn't hold a long");
549  
550 return inst_long;
551 }
552  
553 string IJsonWrapper.GetString ()
554 {
555 if (type != JsonType.String)
556 throw new InvalidOperationException (
557 "JsonData instance doesn't hold a string");
558  
559 return inst_string;
560 }
561  
562 void IJsonWrapper.SetBoolean (bool val)
563 {
564 type = JsonType.Boolean;
565 inst_boolean = val;
566 json = null;
567 }
568  
569 void IJsonWrapper.SetDouble (double val)
570 {
571 type = JsonType.Double;
572 inst_double = val;
573 json = null;
574 }
575  
576 void IJsonWrapper.SetInt (int val)
577 {
578 type = JsonType.Int;
579 inst_int = val;
580 json = null;
581 }
582  
583 void IJsonWrapper.SetLong (long val)
584 {
585 type = JsonType.Long;
586 inst_long = val;
587 json = null;
588 }
589  
590 void IJsonWrapper.SetString (string val)
591 {
592 type = JsonType.String;
593 inst_string = val;
594 json = null;
595 }
596  
597 string IJsonWrapper.ToJson ()
598 {
599 return ToJson ();
600 }
601  
602 void IJsonWrapper.ToJson (JsonWriter writer)
603 {
604 ToJson (writer);
605 }
606 #endregion
607  
608  
609 #region IList Methods
610 int IList.Add (object value)
611 {
612 return Add (value);
613 }
614  
615 void IList.Clear ()
616 {
617 EnsureList ().Clear ();
618 json = null;
619 }
620  
621 bool IList.Contains (object value)
622 {
623 return EnsureList ().Contains (value);
624 }
625  
626 int IList.IndexOf (object value)
627 {
628 return EnsureList ().IndexOf (value);
629 }
630  
631 void IList.Insert (int index, object value)
632 {
633 EnsureList ().Insert (index, value);
634 json = null;
635 }
636  
637 void IList.Remove (object value)
638 {
639 EnsureList ().Remove (value);
640 json = null;
641 }
642  
643 void IList.RemoveAt (int index)
644 {
645 EnsureList ().RemoveAt (index);
646 json = null;
647 }
648 #endregion
649  
650  
651 #region IOrderedDictionary Methods
652 IDictionaryEnumerator IOrderedDictionary.GetEnumerator ()
653 {
654 EnsureDictionary ();
655  
656 return new OrderedDictionaryEnumerator (
657 object_list.GetEnumerator ());
658 }
659  
660 void IOrderedDictionary.Insert (int idx, object key, object value)
661 {
662 string property = (string) key;
663 JsonData data = ToJsonData (value);
664  
665 this[property] = data;
666  
667 KeyValuePair<string, JsonData> entry =
668 new KeyValuePair<string, JsonData> (property, data);
669  
670 object_list.Insert (idx, entry);
671 }
672  
673 void IOrderedDictionary.RemoveAt (int idx)
674 {
675 EnsureDictionary ();
676  
677 inst_object.Remove (object_list[idx].Key);
678 object_list.RemoveAt (idx);
679 }
680 #endregion
681  
682  
683 #region Private Methods
684 private ICollection EnsureCollection ()
685 {
686 if (type == JsonType.Array)
687 return (ICollection) inst_array;
688  
689 if (type == JsonType.Object)
690 return (ICollection) inst_object;
691  
692 throw new InvalidOperationException (
693 "The JsonData instance has to be initialized first");
694 }
695  
696 private IDictionary EnsureDictionary ()
697 {
698 if (type == JsonType.Object)
699 return (IDictionary) inst_object;
700  
701 if (type != JsonType.None)
702 throw new InvalidOperationException (
703 "Instance of JsonData is not a dictionary");
704  
705 type = JsonType.Object;
706 inst_object = new Dictionary<string, JsonData> ();
707 object_list = new List<KeyValuePair<string, JsonData>> ();
708  
709 return (IDictionary) inst_object;
710 }
711  
712 private IList EnsureList ()
713 {
714 if (type == JsonType.Array)
715 return (IList) inst_array;
716  
717 if (type != JsonType.None)
718 throw new InvalidOperationException (
719 "Instance of JsonData is not a list");
720  
721 type = JsonType.Array;
722 inst_array = new List<JsonData> ();
723  
724 return (IList) inst_array;
725 }
726  
727 private JsonData ToJsonData (object obj)
728 {
729 if (obj == null)
730 return null;
731  
732 if (obj is JsonData)
733 return (JsonData) obj;
734  
735 return new JsonData (obj);
736 }
737  
738 private static void WriteJson (IJsonWrapper obj, JsonWriter writer)
739 {
740 if (obj.IsString) {
741 writer.Write (obj.GetString ());
742 return;
743 }
744  
745 if (obj.IsBoolean) {
746 writer.Write (obj.GetBoolean ());
747 return;
748 }
749  
750 if (obj.IsDouble) {
751 writer.Write (obj.GetDouble ());
752 return;
753 }
754  
755 if (obj.IsInt) {
756 writer.Write (obj.GetInt ());
757 return;
758 }
759  
760 if (obj.IsLong) {
761 writer.Write (obj.GetLong ());
762 return;
763 }
764  
765 if (obj.IsArray) {
766 writer.WriteArrayStart ();
767 foreach (object elem in (IList) obj)
768 WriteJson ((JsonData) elem, writer);
769 writer.WriteArrayEnd ();
770  
771 return;
772 }
773  
774 if (obj.IsObject) {
775 writer.WriteObjectStart ();
776  
777 foreach (DictionaryEntry entry in ((IDictionary) obj)) {
778 writer.WritePropertyName ((string) entry.Key);
779 WriteJson ((JsonData) entry.Value, writer);
780 }
781 writer.WriteObjectEnd ();
782  
783 return;
784 }
785 }
786 #endregion
787  
788  
789 public int Add (object value)
790 {
791 JsonData data = ToJsonData (value);
792  
793 json = null;
794  
795 return EnsureList ().Add (data);
796 }
797  
798 public void Clear ()
799 {
800 if (IsObject) {
801 ((IDictionary) this).Clear ();
802 return;
803 }
804  
805 if (IsArray) {
806 ((IList) this).Clear ();
807 return;
808 }
809 }
810  
811 public bool Equals (JsonData x)
812 {
813 if (x == null)
814 return false;
815  
816 if (x.type != this.type)
817 return false;
818  
819 switch (this.type) {
820 case JsonType.None:
821 return true;
822  
823 case JsonType.Object:
824 return this.inst_object.Equals (x.inst_object);
825  
826 case JsonType.Array:
827 return this.inst_array.Equals (x.inst_array);
828  
829 case JsonType.String:
830 return this.inst_string.Equals (x.inst_string);
831  
832 case JsonType.Int:
833 return this.inst_int.Equals (x.inst_int);
834  
835 case JsonType.Long:
836 return this.inst_long.Equals (x.inst_long);
837  
838 case JsonType.Double:
839 return this.inst_double.Equals (x.inst_double);
840  
841 case JsonType.Boolean:
842 return this.inst_boolean.Equals (x.inst_boolean);
843 }
844  
845 return false;
846 }
847  
848 public JsonType GetJsonType ()
849 {
850 return type;
851 }
852  
853 public void SetJsonType (JsonType type)
854 {
855 if (this.type == type)
856 return;
857  
858 switch (type) {
859 case JsonType.None:
860 break;
861  
862 case JsonType.Object:
863 inst_object = new Dictionary<string, JsonData> ();
864 object_list = new List<KeyValuePair<string, JsonData>> ();
865 break;
866  
867 case JsonType.Array:
868 inst_array = new List<JsonData> ();
869 break;
870  
871 case JsonType.String:
872 inst_string = default (String);
873 break;
874  
875 case JsonType.Int:
876 inst_int = default (Int32);
877 break;
878  
879 case JsonType.Long:
880 inst_long = default (Int64);
881 break;
882  
883 case JsonType.Double:
884 inst_double = default (Double);
885 break;
886  
887 case JsonType.Boolean:
888 inst_boolean = default (Boolean);
889 break;
890 }
891  
892 this.type = type;
893 }
894  
895 public string ToJson ()
896 {
897 if (json != null)
898 return json;
899  
900 StringWriter sw = new StringWriter ();
901 JsonWriter writer = new JsonWriter (sw);
902 writer.Validate = false;
903  
904 WriteJson (this, writer);
905 json = sw.ToString ();
906  
907 return json;
908 }
909  
910 public void ToJson (JsonWriter writer)
911 {
912 bool old_validate = writer.Validate;
913  
914 writer.Validate = false;
915  
916 WriteJson (this, writer);
917  
918 writer.Validate = old_validate;
919 }
920  
921 public override string ToString ()
922 {
923 switch (type) {
924 case JsonType.Array:
925 return "JsonData array";
926  
927 case JsonType.Boolean:
928 return inst_boolean.ToString ();
929  
930 case JsonType.Double:
931 return inst_double.ToString ();
932  
933 case JsonType.Int:
934 return inst_int.ToString ();
935  
936 case JsonType.Long:
937 return inst_long.ToString ();
938  
939 case JsonType.Object:
940 return "JsonData object";
941  
942 case JsonType.String:
943 return inst_string;
944 }
945  
946 return "Uninitialized JsonData";
947 }
948 }
949  
950  
951 internal class OrderedDictionaryEnumerator : IDictionaryEnumerator
952 {
953 IEnumerator<KeyValuePair<string, JsonData>> list_enumerator;
954  
955  
956 public object Current {
957 get { return Entry; }
958 }
959  
960 public DictionaryEntry Entry {
961 get {
962 KeyValuePair<string, JsonData> curr = list_enumerator.Current;
963 return new DictionaryEntry (curr.Key, curr.Value);
964 }
965 }
966  
967 public object Key {
968 get { return list_enumerator.Current.Key; }
969 }
970  
971 public object Value {
972 get { return list_enumerator.Current.Value; }
973 }
974  
975  
976 public OrderedDictionaryEnumerator (
977 IEnumerator<KeyValuePair<string, JsonData>> enumerator)
978 {
979 list_enumerator = enumerator;
980 }
981  
982  
983 public bool MoveNext ()
984 {
985 return list_enumerator.MoveNext ();
986 }
987  
988 public void Reset ()
989 {
990 list_enumerator.Reset ();
991 }
992 }
993 }