1
2
3
4
5
6 #include <soulng/util/Json.hpp>
7 #include <soulng/util/CodeFormatter.hpp>
8 #include <soulng/util/TextUtils.hpp>
9 #include <soulng/util/Unicode.hpp>
10
11 namespace soulng { namespace util {
12
13 using namespace soulng::unicode;
14
15 JsonValue::JsonValue(JsonValueType type_) : type(type_)
16 {
17 }
18
19 JsonValue::~JsonValue()
20 {
21 }
22
23 void JsonValue::Write(CodeFormatter& formatter)
24 {
25 formatter.Write(ToString());
26 }
27
28 JsonString::JsonString() : JsonValue(JsonValueType::string), value()
29 {
30 }
31
32 JsonString::JsonString(const std::u32string& value_) : JsonValue(JsonValueType::string), value(value_)
33 {
34 }
35
36 JsonValue* JsonString::Clone() const
37 {
38 return new JsonString(value);
39 }
40
41 void JsonString::SetValue(const std::u32string& value_)
42 {
43 value = value_;
44 }
45
46 void JsonString::Append(char32_t c)
47 {
48 value.append(1, c);
49 }
50
51 std::u16string JsonString::JsonCharStr(char32_t c) const
52 {
53 std::u16string result;
54 std::u32string s(1, c);
55 std::u16string t = ToUtf16(s);
56 for (char16_t x : t)
57 {
58 switch (x)
59 {
60 case '"': result.append(u"\\\""); break;
61 case '\\': result.append(u"\\\\"); break;
62 case '/': result.append(u"\\/"); break;
63 case '\b': result.append(u"\\b"); break;
64 case '\f': result.append(u"\\f"); break;
65 case '\n': result.append(u"\\n"); break;
66 case '\r': result.append(u"\\r"); break;
67 case '\t': result.append(u"\\t"); break;
68 default:
69 {
70 if (x >= 32 && x <= 126)
71 {
72 result.append(1, x);
73 }
74 else
75 {
76 result.append(u"\\u").append(ToUtf16(ToHexString(static_cast<uint16_t>(x))));
77 }
78 }
79 }
80 }
81 return result;
82 }
83
84 std::string JsonString::ToString() const
85 {
86 std::u16string s;
87 for (char32_t c : value)
88 {
89 s.append(JsonCharStr(c));
90 }
91 return "\"" + ToUtf8(s) + "\"";
92 }
93
94 JsonNumber::JsonNumber() : JsonValue(JsonValueType::number), value(0.0)
95 {
96 }
97
98 JsonNumber::JsonNumber(double value_) : JsonValue(JsonValueType::number), value(value_)
99 {
100 }
101
102 JsonValue* JsonNumber::Clone() const
103 {
104 return new JsonNumber(value);
105 }
106
107 std::string JsonNumber::ToString() const
108 {
109 return std::to_string(value);
110 }
111
112 JsonBool::JsonBool() : JsonValue(JsonValueType::boolean), value(false)
113 {
114 }
115
116 JsonBool::JsonBool(bool value_) : JsonValue(JsonValueType::boolean), value(value_)
117 {
118 }
119
120 JsonValue* JsonBool::Clone() const
121 {
122 return new JsonBool(value);
123 }
124
125 std::string JsonBool::ToString() const
126 {
127 return value ? "true" : "false";
128 }
129
130 JsonObject::JsonObject() : JsonValue(JsonValueType::object), fieldValues(), fieldMap()
131 {
132 }
133
134 void JsonObject::AddField(const std::u32string& fieldName, std::std::unique_ptr<JsonValue>&&fieldValue)
135 {
136 fieldMap[fieldName] = fieldValue.get();
137 fieldValues.push_back(std::move(fieldValue));
138 }
139
140 JsonValue* JsonObject::GetField(const std::u32string& fieldName)
141 {
142 auto it = fieldMap.find(fieldName);
143 if (it != fieldMap.cend())
144 {
145 return it->second;
146 }
147 else
148 {
149 return nullptr;
150 }
151 }
152
153 std::string JsonObject::GetStringField(const std::u32string& fieldName)
154 {
155 JsonValue* value = GetField(fieldName);
156 if (value)
157 {
158 if (value->Type() == JsonValueType::string)
159 {
160 JsonString* str = static_cast<JsonString*>(value);
161 return ToUtf8(str->Value());
162 }
163 else
164 {
165 throw std::runtime_error("error getting field " + ToUtf8(fieldName) + ": string field expected");
166 }
167 }
168 else
169 {
170 return std::string();
171 }
172 }
173
174 JsonValue* JsonObject::Clone() const
175 {
176 JsonObject* clone = new JsonObject();
177 for (const auto& p : fieldMap)
178 {
179 clone->AddField(p.first, std::unique_ptr<JsonValue>(p.second->Clone()));
180 }
181 return clone;
182 }
183
184 std::string JsonObject::ToString() const
185 {
186 std::string str = "{";
187 bool first = true;
188 for (const auto& p : fieldMap)
189 {
190 JsonString s(p.first);
191 JsonValue * v(p.second);
192 if (first)
193 {
194 first = false;
195 }
196 else
197 {
198 str.append(", ");
199 }
200 str.append(s.ToString()).append(":").append(v->ToString());
201 }
202 str.append("}");
203 return str;
204 }
205
206 void JsonObject::Write(CodeFormatter& formatter)
207 {
208 formatter.WriteLine("{");
209 formatter.IncIndent();
210 JsonValueType lastItemType = JsonValueType::object;
211 bool first = true;
212 for (const auto& p : fieldMap)
213 {
214 JsonString s(p.first);
215 JsonValue * v(p.second);
216 if (first)
217 {
218 first = false;
219 }
220 else
221 {
222 formatter.WriteLine(", ");
223 }
224 s.Write(formatter);
225 formatter.Write(" : ");
226 if (v->Type() == JsonValueType::array || v->Type() == JsonValueType::object)
227 {
228 formatter.WriteLine();
229 }
230 if (s.Value() == U"content")
231 {
232 formatter.BeginContent();
233 }
234 v->Write(formatter);
235 if (s.Value() == U"content")
236 {
237 formatter.EndContent();
238 }
239 lastItemType = v->Type();
240 }
241 formatter.DecIndent();
242 if (lastItemType != JsonValueType::array && lastItemType != JsonValueType::object)
243 {
244 formatter.WriteLine();
245 }
246 formatter.WriteLine("}");
247 }
248
249 JsonArray::JsonArray() : JsonValue(JsonValueType::array)
250 {
251 }
252
253 void JsonArray::AddItem(std::std::unique_ptr<JsonValue>&&item)
254 {
255 items.push_back(std::move(item));
256 }
257
258 JsonValue* JsonArray::Clone() const
259 {
260 JsonArray* clone = new JsonArray();
261 for (const std::std::unique_ptr<JsonValue>&item : items)
262 {
263 clone->AddItem(std::unique_ptr<JsonValue>(item->Clone()));
264 }
265 return clone;
266 }
267
268 JsonValue* JsonArray::operator[](int index) const
269 {
270 return items[index].get();
271 }
272
273 std::string JsonArray::ToString() const
274 {
275 std::string str = "[";
276 bool first = true;
277 for (const std::std::unique_ptr<JsonValue>&item : items)
278 {
279 if (first)
280 {
281 first = false;
282 }
283 else
284 {
285 str.append(", ");
286 }
287 str.append(item->ToString());
288 }
289 str.append("]");
290 return str;
291 }
292
293 void JsonArray::Write(CodeFormatter& formatter)
294 {
295 formatter.WriteLine("[");
296 formatter.IncIndent();
297 JsonValueType lastItemType = JsonValueType::array;
298 bool first = true;
299 for (const std::std::unique_ptr<JsonValue>&item : items)
300 {
301 if (first)
302 {
303 first = false;
304 }
305 else
306 {
307 formatter.WriteLine(", ");
308 }
309 item->Write(formatter);
310 lastItemType = item->Type();
311 }
312 formatter.DecIndent();
313 if (lastItemType != JsonValueType::array && lastItemType != JsonValueType::object)
314 {
315 formatter.WriteLine();
316 }
317 formatter.WriteLine("]");
318 }
319
320 JsonNull::JsonNull() : JsonValue(JsonValueType::null)
321 {
322 }
323
324 JsonValue* JsonNull::Clone() const
325 {
326 return new JsonNull();
327 }
328
329 std::string JsonNull::ToString() const
330 {
331 return "null";
332 }
333
334 } }