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 JsonValue()
15 {
16 }
17 public virtual default ~JsonValue();
18 [nodiscard]
19 public abstract Result<string> ToString() const;
20 [nodiscard]
21 public virtual Result<bool> Write(CodeFormatter& formatter)
22 {
23 Result<string> toStringResult = ToString();
24 if (toStringResult.Error())
25 {
26 return Result<bool>(ErrorId(toStringResult.GetErrorId()));
27 }
28 auto result = formatter.Write(toStringResult.Value());
29 if (result.Error()) return result;
30 return Result<bool>(true);
31 }
32 }
33
34 public class JsonNull : JsonValue
35 {
36 public JsonNull() : base()
37 {
38 }
39 public override Result<string> ToString() const
40 {
41 return Result<string>("null");
42 }
43 }
44
45 public class JsonNumber : JsonValue
46 {
47 public JsonNumber() : base(), value(0.000000)
48 {
49 }
50 public explicit JsonNumber(double value_) : value(value_)
51 {
52 }
53 public override Result<string> ToString() const
54 {
55 if (value == cast<long>(value))
56 {
57 long x = cast<long>(value);
58 return Result<string>(System.ToString(x));
59 }
60 return Result<string>(System.ToString(value));
61 }
62 public inline double Value() const
63 {
64 return value;
65 }
66 public inline void SetValue(double value_)
67 {
68 value = value_;
69 }
70 private double value;
71 }
72
73 public class JsonBool : JsonValue
74 {
75 public JsonBool() : base(), value(false)
76 {
77 }
78 public explicit JsonBool(bool value_) : base(), value(value_)
79 {
80 }
81 public override Result<string> ToString() const
82 {
83 return Result<string>(System.ToString(value));
84 }
85 public inline bool Value() const
86 {
87 return value;
88 }
89 public inline void SetValue(bool value_)
90 {
91 value = value_;
92 }
93 private bool value;
94 }
95
96 public class JsonString : JsonValue
97 {
98 public JsonString() : base(), value()
99 {
100 }
101 public JsonString(const ustring& value_) : base(), value(value_)
102 {
103 }
104 public inline const ustring& Value() const
105 {
106 return value;
107 }
108 public inline void SetValue(const ustring& value_)
109 {
110 value = value_;
111 }
112 public JsonString& Append(uchar c)
113 {
114 value.Append(c);
115 return *this;
116 }
117 public JsonString& Append(const uchar* s)
118 {
119 value.Append(s);
120 return *this;
121 }
122 public JsonString& Append(const ustring& s)
123 {
124 value.Append(s);
125 return *this;
126 }
127 public override Result<string> ToString() const
128 {
129 wstring s = w'\"';
130 for (uchar c : value)
131 {
132 auto jsonCharStrResult = JsonCharStr(c);
133 if (jsonCharStrResult.Error()) return Result<string>(ErrorId(jsonCharStrResult.GetErrorId()));
134 s.Append(Rvalue(jsonCharStrResult.Value()));
135 }
136 s.Append(w'\"');
137 auto result = ToUtf8(s);
138 if (result.Error()) return Result<string>(ErrorId(result.GetErrorId()));
139 return Result<string>(Rvalue(result.Value()));
140 }
141 private Result<wstring> JsonCharStr(uchar c)
142 {
143 wstring result;
144 ustring s(c);
145 auto utf16result = ToUtf16(s);
146 if (utf16result.Error()) return Result<wstring>(ErrorId(utf16result.GetErrorId()));
147 wstring t = utf16result.Value();
148 for (wchar x : t)
149 {
150 switch (x)
151 {
152 case '\"':result.Append(w"\\\""); break;
153 case '\\': result.Append(w"\\\\"); break;
154 case '\b': result.Append(w"\\b"); break;
155 case '\f': result.Append(w"\\f"); break;
156 case '\n': result.Append(w"\\n"); break;
157 case '\r': result.Append(w"\\r"); break;
158 case '\t': result.Append(w"\\t"); break;
159 default:
160 {
161 if (cast<ushort>(x) >= 32u && cast<ushort>(x) <= 126u)
162 {
163 result.Append(x);
164 }
165 else
166 {
167 auto hexStringResult = ToHexString(cast<ushort>(x));
168 if (hexStringResult.Error())
169 {
170 return Result<wstring>(ErrorId(hexStringResult.GetErrorId()));
171 }
172 auto utf16Result = ToUtf16(hexStringResult.Value());
173 if (utf16Result.Error())
174 {
175 return Result<wstring>(ErrorId(utf16Result.GetErrorId()));
176 }
177 const wstring& s = utf16Result.Value();
178 result.Append(w"\\u").Append(s);
179 }
180 break;
181 }
182 }
183 }
184 return Result<wstring>(result);
185 }
186 private ustring value;
187 }
188
189 public class JsonObject : JsonValue
190 {
191 public JsonObject() : base(), fieldValues(), fieldMap()
192 {
193 }
194 [nodiscard]
195 public Result<bool> AddField(const string& fieldName, UniquePtr<JsonValue>&& fieldValue)
196 {
197 auto utf32Result = ToUtf32(fieldName);
198 if (utf32Result.Error())
199 {
200 return Result<bool>(ErrorId(utf32Result.GetErrorId()));
201 }
202 AddField(utf32Result.Value(), Rvalue(fieldValue));
203 return Result<bool>(true);
204 }
205 [nodiscard]
206 public Result<bool> AddField(const wstring& fieldName, UniquePtr<JsonValue>&& fieldValue)
207 {
208 auto utf32Result = ToUtf32(fieldName);
209 if (utf32Result.Error())
210 {
211 return Result<bool>(ErrorId(utf32Result.GetErrorId()));
212 }
213 AddField(utf32Result.Value(), Rvalue(fieldValue));
214 return Result<bool>(true);
215 }
216 public void AddField(const ustring& fieldName, UniquePtr<JsonValue>&& fieldValue)
217 {
218 fieldMap[fieldName] = fieldValue.Get();
219 fieldValues.Add(Rvalue(fieldValue));
220 }
221 [nodiscard]
222 public Result<bool> AddField(const string& fieldName, JsonValue* fieldValue)
223 {
224 auto utf32Result = ToUtf32(fieldName);
225 if (utf32Result.Error())
226 {
227 return Result<bool>(ErrorId(utf32Result.GetErrorId()));
228 }
229 AddField(utf32Result.Value(), fieldValue);
230 return Result<bool>(true);
231 }
232 [nodiscard]
233 public Result<bool> AddField(const wstring& fieldName, JsonValue* fieldValue)
234 {
235 auto utf32Result = ToUtf32(fieldName);
236 if (utf32Result.Error())
237 {
238 return Result<bool>(ErrorId(utf32Result.GetErrorId()));
239 }
240 AddField(utf32Result.Value(), fieldValue);
241 return Result<bool>(true);
242 }
243 public void AddField(const ustring& fieldName, JsonValue* fieldValue)
244 {
245 fieldMap[fieldName] = fieldValue;
246 fieldValues.Add(UniquePtr<JsonValue>(fieldValue));
247 }
248 public Result<JsonValue*> GetField(const string& fieldName) const
249 {
250 auto utf32Result = ToUtf32(fieldName);
251 if (utf32Result.Error())
252 {
253 return Result<JsonValue*>(ErrorId(utf32Result.GetErrorId()));
254 }
255 ustring ufieldName = Rvalue(utf32Result.Value());
256 Result<JsonValue*> fieldValue = GetField(ufieldName);
257 return fieldValue;
258 }
259 public Result<JsonValue*> GetField(const wstring& fieldName) const
260 {
261 auto utf32Result = ToUtf32(fieldName);
262 if (utf32Result.Error())
263 {
264 return Result<JsonValue*>(ErrorId(utf32Result.GetErrorId()));
265 }
266 ustring ufieldName = Rvalue(utf32Result.Value());
267 Result<JsonValue*> fieldValue = GetField(ufieldName);
268 return fieldValue;
269 }
270 public JsonValue* GetField(const ustring& fieldName) const
271 {
272 auto i = fieldMap.Find(fieldName);
273 if (i != fieldMap.End())
274 {
275 return i->second;
276 }
277 return null;
278 }
279 public const Map<ustring, JsonValue*>& Fields() const
280 {
281 return fieldMap;
282 }
283 public Map<ustring, JsonValue*>& Fields()
284 {
285 return fieldMap;
286 }
287 public override Result<string> ToString() const
288 {
289 string s = "{";
290 bool first = true;
291 for (const Pair<ustring, JsonValue*>& p : fieldMap)
292 {
293 JsonString fs = p.first;
294 JsonValue* fv = p.second;
295 if (first)
296 {
297 first = false;
298 }
299 else
300 {
301 s.Append(", ");
302 }
303 auto fsResult = fs.ToString();
304 if (fsResult.Error())
305 {
306 return Result<string>(ErrorId(fsResult.GetErrorId()));
307 }
308 auto fvResult = fv->ToString();
309 if (fvResult.Error())
310 {
311 return Result<string>(ErrorId(fvResult.GetErrorId()));
312 }
313 s.Append(fsResult.Value()).Append(":").Append(fvResult.Value());
314 }
315 s.Append("}");
316 return Result<string>(s);
317 }
318 [nodiscard]
319 public override Result<bool> Write(CodeFormatter& formatter)
320 {
321 auto result = formatter.WriteLine("{");
322 if (result.Error()) return result;
323 formatter.IncIndent();
324 bool first = true;
325 bool lastWasArrayOrObject = false;
326 for (const Pair<ustring, JsonValue*>& p : fieldMap)
327 {
328 JsonString s = p.first;
329 JsonValue* v = p.second;
330 if (first)
331 {
332 first = false;
333 }
334 else
335 {
336 result = formatter.WriteLine(", ");
337 if (result.Error()) return result;
338 }
339 result = s.Write(formatter);
340 if (result.Error()) return result;
341 result = formatter.Write(" : ");
342 if (result.Error()) return result;
343 if ((v is JsonArray*) || (v is JsonObject*))
344 {
345 result = formatter.WriteLine();
346 if (result.Error()) return result;
347 lastWasArrayOrObject = true;
348 }
349 else
350 {
351 lastWasArrayOrObject = false;
352 }
353 result = v->Write(formatter);
354 if (result.Error()) return result;
355 }
356 formatter.DecIndent();
357 if (!lastWasArrayOrObject)
358 {
359 auto result = formatter.WriteLine();
360 if (result.Error()) return result;
361 }
362 result = formatter.WriteLine("}");
363 if (result.Error()) return result;
364 return Result<bool>(true);
365 }
366 private List<UniquePtr<JsonValue>> fieldValues;
367 private Map<ustring, JsonValue*> fieldMap;
368 }
369
370 public class JsonArray : JsonValue
371 {
372 public JsonArray() : base(), items()
373 {
374 }
375 public void AddItem(UniquePtr<JsonValue>&& item)
376 {
377 items.Add(Rvalue(item));
378 }
379 public void AddItem(JsonValue* item)
380 {
381 items.Add(UniquePtr<JsonValue>(item));
382 }
383 public JsonValue* GetItem(long index) const
384 {
385 return items[index].Get();
386 }
387 public JsonValue* operator[](long index) const
388 {
389 return items[index].Get();
390 }
391 public inline long Count() const
392 {
393 return items.Count();
394 }
395 public override Result<string> ToString() const
396 {
397 string s = "[";
398 bool first = true;
399 for (const UniquePtr<JsonValue>& item : items)
400 {
401 if (first)
402 {
403 first = false;
404 }
405 else
406 {
407 s.Append(", ");
408 }
409 auto itemResult = item->ToString();
410 if (itemResult.Error())
411 {
412 return Result<string>(ErrorId(itemResult.GetErrorId()));
413 }
414 s.Append(itemResult.Value());
415 }
416 s.Append("]");
417 return Result<string>(s);
418 }
419 [nodiscard]
420 public override Result<bool> Write(CodeFormatter& formatter)
421 {
422 auto result = formatter.WriteLine("[");
423 if (result.Error()) return result;
424 formatter.IncIndent();
425 bool first = true;
426 bool lastWasArrayOrObject = false;
427 for (const UniquePtr<JsonValue>& item : items)
428 {
429 if (first)
430 {
431 first = false;
432 }
433 else
434 {
435 result = formatter.WriteLine(", ");
436 if (result.Error()) return result;
437 }
438 result = item->Write(formatter);
439 if (result.Error()) return result;
440 if ((item.Get() is JsonArray*) || (item.Get() is JsonObject*))
441 {
442 lastWasArrayOrObject = true;
443 }
444 else
445 {
446 lastWasArrayOrObject = false;
447 }
448 }
449 formatter.DecIndent();
450 if (!lastWasArrayOrObject)
451 {
452 result = formatter.WriteLine();
453 if (result.Error()) return result;
454 }
455 result = formatter.WriteLine("]");
456 if (result.Error()) return result;
457 return Result<bool>(true);
458 }
459 private List<UniquePtr<JsonValue>> items;
460 }
461
462 public Result<UniquePtr<JsonValue>> ParseJson(const string& jsonText)
463 {
464 auto utf32Result = ToUtf32(jsonText);
465 if (utf32Result.Error()) return Result<UniquePtr<JsonValue>>(ErrorId(utf32Result.GetErrorId()));
466 return ParseJson(utf32Result.Value());
467 }
468
469 public Result<UniquePtr<JsonValue>> ParseJson(const wstring& jsonText)
470 {
471 auto utf32Result = ToUtf32(jsonText);
472 if (utf32Result.Error()) return Result<UniquePtr<JsonValue>>(ErrorId(utf32Result.GetErrorId()));
473 return ParseJson(utf32Result.Value());
474 }
475
476 public Result<UniquePtr<JsonValue>> ParseJson(const ustring& jsonText)
477 {
478 JsonLexer jsonLexer(jsonText.Chars(), jsonText.Chars() + jsonText.Length(), "json");
479 Result<UniquePtr<JsonValue>> jsonValue = JsonParser<JsonLexer>.Parse(jsonLexer);
480 return Rvalue(jsonValue);
481 }