2010-06-21 Atsushi Enomoto <atsushi@ximian.com>
[mcs.git] / class / System.Json / System.Json / JsonObject.cs
blobe2f0a9917468214c03d7a54d50b65ef3b357e55a
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Globalization;
5 using System.IO;
6 using System.Text;
8 using JsonPair = System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>;
9 using JsonPairEnumerable = System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>>;
12 namespace System.Json
14 public class JsonObject : JsonValue, IDictionary<string, JsonValue>, ICollection<KeyValuePair<string, JsonValue>>
16 int known_count = -1;
17 Dictionary<string, JsonValue> map;
18 JsonPairEnumerable source;
20 public JsonObject (params KeyValuePair<string, JsonValue> [] items)
21 : this ((JsonPairEnumerable) items)
25 public JsonObject (JsonPairEnumerable items)
27 if (items == null)
28 throw new ArgumentNullException ("items");
29 this.source = items;
32 public override int Count {
33 get {
34 if (known_count < 0) {
35 if (map != null)
36 known_count = map.Count;
37 else {
38 known_count = 0;
39 foreach (JsonPair p in source)
40 known_count++;
43 return known_count;
47 public IEnumerator<JsonPair> GetEnumerator ()
49 return AsEnumerable ().GetEnumerator ();
52 IEnumerator IEnumerable.GetEnumerator ()
54 return AsEnumerable ().GetEnumerator ();
57 JsonPairEnumerable AsEnumerable ()
59 return map ?? source;
62 public bool IsReadOnly {
63 get { return false; }
66 bool ICollection<JsonPair>.IsReadOnly {
67 get { return ((ICollection<JsonPair>) map).IsReadOnly; }
70 public override sealed JsonValue this [string key] {
71 get {
72 foreach (JsonPair pair in AsEnumerable ())
73 if (pair.Key == key)
74 return pair.Value;
75 throw new KeyNotFoundException (String.Format ("key '{0}' was not found.", key));
77 set {
78 PopulateMap ();
79 map [key] = value;
83 public override JsonType JsonType {
84 get { return JsonType.Object; }
87 public ICollection<string> Keys {
88 get {
89 PopulateMap ();
90 return map.Keys;
94 public ICollection<JsonValue> Values {
95 get {
96 PopulateMap ();
97 return map.Values;
101 public void Add (string key, JsonValue value)
103 if (key == null)
104 throw new ArgumentNullException ("key");
105 if (value == null)
106 throw new ArgumentNullException ("value");
107 PopulateMap ();
108 map [key] = value;
111 public void Add (JsonPair pair)
113 Add (pair.Key, pair.Value);
116 public void AddRange (JsonPairEnumerable items)
118 if (items == null)
119 throw new ArgumentNullException ("items");
120 source = new MergedEnumerable<JsonPair> (source, items);
121 map = null;
124 public void AddRange (JsonPair [] items)
126 AddRange ((JsonPairEnumerable) items);
129 static readonly JsonPair [] empty = new JsonPair [0];
131 public void Clear ()
133 if (map != null)
134 map.Clear ();
135 else
136 source = empty;
139 bool ICollection<JsonPair>.Contains (JsonPair item)
141 return ContainsKey (item.Key);
144 public override bool ContainsKey (string key)
146 if (key == null)
147 throw new ArgumentNullException ("key");
148 foreach (JsonPair p in AsEnumerable ())
149 if (p.Key == key)
150 return true;
151 return false;
154 public void CopyTo (JsonPair [] array, int arrayIndex)
156 foreach (JsonPair p in AsEnumerable ())
157 array [arrayIndex++] = p;
160 public bool Remove (string key)
162 PopulateMap ();
163 return map.Remove (key);
166 bool ICollection<JsonPair>.Remove (JsonPair item)
168 return ((ICollection<JsonPair>) map).Remove (item);
171 public override void Save (Stream stream)
173 if (stream == null)
174 throw new ArgumentNullException ("stream");
175 stream.WriteByte ((byte) '{');
176 foreach (JsonPair pair in this) {
177 stream.WriteByte ((byte) '"');
178 byte [] bytes = Encoding.UTF8.GetBytes (EscapeString (pair.Key));
179 stream.Write (bytes, 0, bytes.Length);
180 stream.WriteByte ((byte) '"');
181 stream.WriteByte ((byte) ',');
182 stream.WriteByte ((byte) ' ');
183 pair.Value.Save (stream);
185 stream.WriteByte ((byte) '}');
188 public bool TryGetValue (string key, out JsonValue value)
190 foreach (JsonPair p in AsEnumerable ())
191 if (p.Key == key) {
192 value = p.Value;
193 return true;
195 value = null;
196 return false;
199 void PopulateMap ()
201 if (map == null) {
202 map = new Dictionary<string, JsonValue> ();
203 foreach (JsonPair pair in source)
204 map.Add (pair.Key, pair.Value);