1
2
3
4
5
6 using System;
7 using System.Collections;
8 using System.Text;
9
10 namespace System.Json
11 {
12 public abstract class JsonValue
13 {
14 public virtual default ~JsonValue();
15 public abstract string ToString() const;
16 public virtual void Write(CodeFormatter& formatter)
17 {
18 formatter.Write(ToString());
19 }
20 }
21
22 public class JsonNull : JsonValue
23 {
24 public override string ToString() const
25 {
26 return "null";
27 }
28 }
29
30 public class JsonNumber : JsonValue
31 {
32 public nothrow JsonNumber() : value(0.0)
33 {
34 }
35 public explicit nothrow JsonNumber(double value_) : value(value_)
36 {
37 }
38 public override string ToString() const
39 {
40 return System.ToString(value);
41 }
42 public inline nothrow double Value() const
43 {
44 return value;
45 }
46 public inline nothrow void SetValue(double value_)
47 {
48 value = value_;
49 }
50 private double value;
51 }
52
53 public class JsonBool : JsonValue
54 {
55 public nothrow JsonBool() : value(false)
56 {
57 }
58 public explicit nothrow JsonBool(bool value_) : value(value_)
59 {
60 }
61 public override string ToString() const
62 {
63 return System.ToString(value);
64 }
65 public inline nothrow bool Value() const
66 {
67 return value;
68 }
69 public inline nothrow void SetValue(bool value_)
70 {
71 value = value_;
72 }
73 private bool value;
74 }
75
76 public class JsonString : JsonValue
77 {
78 public nothrow JsonString() : value()
79 {
80 }
81 public nothrow JsonString(const ustring& value_) : value(value_)
82 {
83 }
84 public inline nothrow const ustring& Value() const
85 {
86 return value;
87 }
88 public inline nothrow void SetValue(const ustring& value_)
89 {
90 value = value_;
91 }
92 public nothrow JsonString& Append(uchar c)
93 {
94 value.Append(c);
95 return *this;
96 }
97 public nothrow JsonString& Append(const uchar* s)
98 {
99 value.Append(s);
100 return *this;
101 }
102 public nothrow JsonString& Append(const ustring& s)
103 {
104 value.Append(s);
105 return *this;
106 }
107 public override string ToString() const
108 {
109 wstring s = w'"';
110 for (uchar c : value)
111 {
112 s.Append(JsonCharStr(c));
113 }
114 s.Append(w'"');
115 return ToUtf8(s);
116 }
117 private wstring JsonCharStr(uchar c)
118 {
119 wstring result;
120 ustring s(c);
121 wstring t = ToUtf16(s);
122 for (wchar x : t)
123 {
124 switch (x)
125 {
126 case '"': result.Append(w"\\\""); break;
127 case '\\': result.Append(w"\\\\"); break;
128 case '/': result.Append(w"\\/"); break;
129 case '\b': result.Append(w"\\b"); break;
130 case '\f': result.Append(w"\\f"); break;
131 case '\n': result.Append(w"\\n"); break;
132 case '\r': result.Append(w"\\r"); break;
133 case '\t': result.Append(w"\\t"); break;
134 default:
135 {
136 if (cast<ushort>(x) >= 32u && cast<ushort>(x) <= 126u)
137 {
138 result.Append(x);
139 }
140 else
141 {
142 result.Append(w"\\u").Append(ToUtf16(ToHexString(cast<ushort>(x))));
143 }
144 break;
145 }
146 }
147 }
148 return result;
149 }
150 private ustring value;
151 }
152
153 public class JsonObject : JsonValue
154 {
155 public JsonObject() : fieldValues(), fieldMap()
156 {
157 }
158 public void AddField(const string& fieldName, UniquePtr<JsonValue>&& fieldValue)
159 {
160 AddField(ToUtf32(fieldName), fieldValue);
161 }
162 public void AddField(const wstring& fieldName, UniquePtr<JsonValue>&& fieldValue)
163 {
164 AddField(ToUtf32(fieldName), fieldValue);
165 }
166 public void AddField(const ustring& fieldName, UniquePtr<JsonValue>&& fieldValue)
167 {
168 fieldMap[fieldName] = fieldValue.Get();
169 fieldValues.Add(Rvalue(fieldValue));
170 }
171 public void AddField(const string& fieldName, JsonValue* fieldValue)
172 {
173 AddField(ToUtf32(fieldName), fieldValue);
174 }
175 public void AddField(const wstring& fieldName, JsonValue* fieldValue)
176 {
177 AddField(ToUtf32(fieldName), fieldValue);
178 }
179 public void AddField(const ustring& fieldName, JsonValue* fieldValue)
180 {
181 fieldMap[fieldName] = fieldValue;
182 fieldValues.Add(UniquePtr<JsonValue>(fieldValue));
183 }
184 public JsonValue* GetField(const string& fieldName) const
185 {
186 return GetField(ToUtf32(fieldName));
187 }
188 public JsonValue* GetField(const wstring& fieldName) const
189 {
190 return GetField(ToUtf32(fieldName));
191 }
192 public JsonValue* GetField(const ustring& fieldName) const
193 {
194 Map<ustring, JsonValue*>.ConstIterator i = fieldMap.CFind(fieldName);
195 if (i != fieldMap.CEnd())
196 {
197 return i->second;
198 }
199 return null;
200 }
201 public nothrow const Map<ustring, JsonValue*>& Fields() const
202 {
203 return fieldMap;
204 }
205 public nothrow Map<ustring, JsonValue*>& Fields()
206 {
207 return fieldMap;
208 }
209 public override string ToString() const
210 {
211 string s = "{";
212 bool first = true;
213 for (const Pair<ustring, JsonValue*>& p : fieldMap)
214 {
215 JsonString fs = p.first;
216 JsonValue* fv = p.second;
217 if (first)
218 {
219 first = false;
220 }
221 else
222 {
223 s.Append(", ");
224 }
225 s.Append(fs.ToString()).Append(":").Append(fv->ToString());
226 }
227 s.Append("}");
228 return s;
229 }
230 public override void Write(CodeFormatter& formatter)
231 {
232 formatter.WriteLine("{");
233 formatter.IncIndent();
234 bool first = true;
235 bool lastWasArrayOrObject = false;
236 for (const Pair<ustring, JsonValue*>& p : fieldMap)
237 {
238 JsonString s(p.first);
239 JsonValue* v(p.second);
240 if (first)
241 {
242 first = false;
243 }
244 else
245 {
246 formatter.WriteLine(", ");
247 }
248 s.Write(formatter);
249 formatter.Write(" : ");
250 if ((v is JsonArray*) || (v is JsonObject*))
251 {
252 formatter.WriteLine();
253 lastWasArrayOrObject = true;
254 }
255 else
256 {
257 lastWasArrayOrObject = false;
258 }
259 v->Write(formatter);
260 }
261 formatter.DecIndent();
262 if (!lastWasArrayOrObject)
263 {
264 formatter.WriteLine();
265 }
266 formatter.WriteLine("}");
267 }
268 private List<UniquePtr<JsonValue>> fieldValues;
269 private Map<ustring, JsonValue*> fieldMap;
270 }
271
272 public class JsonArray : JsonValue
273 {
274 public nothrow JsonArray() : items()
275 {
276 }
277 public void AddItem(UniquePtr<JsonValue>&& item)
278 {
279 items.Add(Rvalue(item));
280 }
281 public void AddItem(JsonValue* item)
282 {
283 items.Add(UniquePtr<JsonValue>(item));
284 }
285 public JsonValue* operator[](long index) const
286 {
287 return items[index].Get();
288 }
289 public inline nothrow long Count() const
290 {
291 return items.Count();
292 }
293 public override string ToString() const
294 {
295 string s = "[";
296 bool first = true;
297 for (const UniquePtr<JsonValue>& item : items)
298 {
299 if (first)
300 {
301 first = false;
302 }
303 else
304 {
305 s.Append(", ");
306 }
307 s.Append(item->ToString());
308 }
309 s.Append("]");
310 return s;
311 }
312 public override void Write(CodeFormatter& formatter)
313 {
314 formatter.WriteLine("[");
315 formatter.IncIndent();
316 bool first = true;
317 bool lastWasArrayOrObject = false;
318 for (const UniquePtr<JsonValue>& item : items)
319 {
320 if (first)
321 {
322 first = false;
323 }
324 else
325 {
326 formatter.WriteLine(", ");
327 }
328 item->Write(formatter);
329 if ((item.Get() is JsonArray*) || (item.Get() is JsonObject*))
330 {
331 lastWasArrayOrObject = true;
332 }
333 else
334 {
335 lastWasArrayOrObject = false;
336 }
337 }
338 formatter.DecIndent();
339 if (!lastWasArrayOrObject)
340 {
341 formatter.WriteLine();
342 }
343 formatter.WriteLine("]");
344 }
345 private List<UniquePtr<JsonValue>> items;
346 }
347
348 public UniquePtr<JsonValue> ParseJson(const string& jsonText)
349 {
350 return ParseJson(ToUtf32(jsonText));
351 }
352
353 public UniquePtr<JsonValue> ParseJson(const wstring& jsonText)
354 {
355 return ParseJson(ToUtf32(jsonText));
356 }
357
358 public UniquePtr<JsonValue> ParseJson(const ustring& jsonText)
359 {
360 JsonLexer jsonLexer(jsonText, "", 0);
361 UniquePtr<JsonValue> jsonValue = JsonParser.Parse(jsonLexer);
362 return jsonValue;
363 }
364 }