Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Side by Side Diff: third_party/WebKit/Source/platform/JSONValues.cpp

Issue 2293493003: Move blink platform's JSON code into a directory. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "platform/JSONValues.h"
32
33 #include "platform/Decimal.h"
34 #include "wtf/MathExtras.h"
35 #include "wtf/text/StringBuilder.h"
36 #include <algorithm>
37 #include <cmath>
38
39 namespace blink {
40
41 namespace {
42
43 const char* const nullString = "null";
44 const char* const trueString = "true";
45 const char* const falseString = "false";
46
47 inline bool escapeChar(UChar c, StringBuilder* dst)
48 {
49 switch (c) {
50 case '\b': dst->append("\\b"); break;
51 case '\f': dst->append("\\f"); break;
52 case '\n': dst->append("\\n"); break;
53 case '\r': dst->append("\\r"); break;
54 case '\t': dst->append("\\t"); break;
55 case '\\': dst->append("\\\\"); break;
56 case '"': dst->append("\\\""); break;
57 default:
58 return false;
59 }
60 return true;
61 }
62
63 const LChar hexDigits[17] = "0123456789ABCDEF";
64
65 void appendUnsignedAsHex(UChar number, StringBuilder* dst)
66 {
67 dst->append("\\u");
68 for (size_t i = 0; i < 4; ++i) {
69 dst->append(hexDigits[(number & 0xF000) >> 12]);
70 number <<= 4;
71 }
72 }
73
74 void writeIndent(int depth, StringBuilder* output)
75 {
76 for (int i = 0; i < depth; ++i)
77 output->append(" ");
78 }
79
80 } // anonymous namespace
81
82 void escapeStringForJSON(const String& str, StringBuilder* dst)
83 {
84 for (unsigned i = 0; i < str.length(); ++i) {
85 UChar c = str[i];
86 if (!escapeChar(c, dst)) {
87 if (c < 32 || c > 126 || c == '<' || c == '>') {
88 // 1. Escaping <, > to prevent script execution.
89 // 2. Technically, we could also pass through c > 126 as UTF8, b ut this
90 // is also optional. It would also be a pain to implement her e.
91 appendUnsignedAsHex(c, dst);
92 } else {
93 dst->append(c);
94 }
95 }
96 }
97 }
98
99 void doubleQuoteStringForJSON(const String& str, StringBuilder* dst)
100 {
101 dst->append('"');
102 escapeStringForJSON(str, dst);
103 dst->append('"');
104 }
105
106 String JSONValue::quoteString(const String& input)
107 {
108 StringBuilder builder;
109 doubleQuoteStringForJSON(input, &builder);
110 return builder.toString();
111 }
112
113 bool JSONValue::asBoolean(bool*) const
114 {
115 return false;
116 }
117
118 bool JSONValue::asDouble(double*) const
119 {
120 return false;
121 }
122
123 bool JSONValue::asInteger(int*) const
124 {
125 return false;
126 }
127
128 bool JSONValue::asString(String*) const
129 {
130 return false;
131 }
132
133 String JSONValue::toJSONString() const
134 {
135 StringBuilder result;
136 result.reserveCapacity(512);
137 writeJSON(&result);
138 return result.toString();
139 }
140
141 String JSONValue::toPrettyJSONString() const
142 {
143 StringBuilder result;
144 result.reserveCapacity(512);
145 prettyWriteJSON(&result);
146 return result.toString();
147 }
148
149 void JSONValue::writeJSON(StringBuilder* output) const
150 {
151 DCHECK(m_type == TypeNull);
152 output->append(nullString, 4);
153 }
154
155 void JSONValue::prettyWriteJSON(StringBuilder* output) const
156 {
157 prettyWriteJSONInternal(output, 0);
158 output->append('\n');
159 }
160
161 void JSONValue::prettyWriteJSONInternal(StringBuilder* output, int depth) const
162 {
163 writeJSON(output);
164 }
165
166 std::unique_ptr<JSONValue> JSONValue::clone() const
167 {
168 return JSONValue::null();
169 }
170
171 bool JSONBasicValue::asBoolean(bool* output) const
172 {
173 if (getType() != TypeBoolean)
174 return false;
175 *output = m_boolValue;
176 return true;
177 }
178
179 bool JSONBasicValue::asDouble(double* output) const
180 {
181 if (getType() == TypeDouble) {
182 *output = m_doubleValue;
183 return true;
184 }
185 if (getType() == TypeInteger) {
186 *output = m_integerValue;
187 return true;
188 }
189 return false;
190 }
191
192 bool JSONBasicValue::asInteger(int* output) const
193 {
194 if (getType() != TypeInteger)
195 return false;
196 *output = m_integerValue;
197 return true;
198 }
199
200 void JSONBasicValue::writeJSON(StringBuilder* output) const
201 {
202 DCHECK(getType() == TypeBoolean || getType() == TypeInteger || getType() == TypeDouble);
203 if (getType() == TypeBoolean) {
204 if (m_boolValue)
205 output->append(trueString, 4);
206 else
207 output->append(falseString, 5);
208 } else if (getType() == TypeDouble) {
209 if (!std::isfinite(m_doubleValue)) {
210 output->append(nullString, 4);
211 return;
212 }
213 output->append(Decimal::fromDouble(m_doubleValue).toString());
214 } else if (getType() == TypeInteger) {
215 output->append(String::number(m_integerValue));
216 }
217 }
218
219 std::unique_ptr<JSONValue> JSONBasicValue::clone() const
220 {
221 switch (getType()) {
222 case TypeDouble: return JSONBasicValue::create(m_doubleValue);
223 case TypeInteger: return JSONBasicValue::create(m_integerValue);
224 case TypeBoolean: return JSONBasicValue::create(m_boolValue);
225 default:
226 NOTREACHED();
227 }
228 return nullptr;
229 }
230
231 bool JSONString::asString(String* output) const
232 {
233 *output = m_stringValue;
234 return true;
235 }
236
237 void JSONString::writeJSON(StringBuilder* output) const
238 {
239 DCHECK(getType() == TypeString);
240 doubleQuoteStringForJSON(m_stringValue, output);
241 }
242
243 std::unique_ptr<JSONValue> JSONString::clone() const
244 {
245 return JSONString::create(m_stringValue);
246 }
247
248 JSONObject::~JSONObject()
249 {
250 }
251
252 void JSONObject::setBoolean(const String& name, bool value)
253 {
254 setValue(name, JSONBasicValue::create(value));
255 }
256
257 void JSONObject::setInteger(const String& name, int value)
258 {
259 setValue(name, JSONBasicValue::create(value));
260 }
261
262 void JSONObject::setDouble(const String& name, double value)
263 {
264 setValue(name, JSONBasicValue::create(value));
265 }
266
267 void JSONObject::setString(const String& name, const String& value)
268 {
269 setValue(name, JSONString::create(value));
270 }
271
272 void JSONObject::setValue(const String& name, std::unique_ptr<JSONValue> value)
273 {
274 set(name, value);
275 }
276
277 void JSONObject::setObject(const String& name, std::unique_ptr<JSONObject> value )
278 {
279 set(name, value);
280 }
281
282 void JSONObject::setArray(const String& name, std::unique_ptr<JSONArray> value)
283 {
284 set(name, value);
285 }
286
287 bool JSONObject::getBoolean(const String& name, bool* output) const
288 {
289 JSONValue* value = get(name);
290 if (!value)
291 return false;
292 return value->asBoolean(output);
293 }
294
295 bool JSONObject::getInteger(const String& name, int* output) const
296 {
297 JSONValue* value = get(name);
298 if (!value)
299 return false;
300 return value->asInteger(output);
301 }
302
303 bool JSONObject::getDouble(const String& name, double* output) const
304 {
305 JSONValue* value = get(name);
306 if (!value)
307 return false;
308 return value->asDouble(output);
309 }
310
311 bool JSONObject::getString(const String& name, String* output) const
312 {
313 JSONValue* value = get(name);
314 if (!value)
315 return false;
316 return value->asString(output);
317 }
318
319 JSONObject* JSONObject::getObject(const String& name) const
320 {
321 return JSONObject::cast(get(name));
322 }
323
324 JSONArray* JSONObject::getArray(const String& name) const
325 {
326 return JSONArray::cast(get(name));
327 }
328
329 JSONValue* JSONObject::get(const String& name) const
330 {
331 Dictionary::const_iterator it = m_data.find(name);
332 if (it == m_data.end())
333 return nullptr;
334 return it->value.get();
335 }
336
337 JSONObject::Entry JSONObject::at(size_t index) const
338 {
339 const String key = m_order[index];
340 return std::make_pair(key, m_data.find(key)->value.get());
341 }
342
343 bool JSONObject::booleanProperty(const String& name, bool defaultValue) const
344 {
345 bool result = defaultValue;
346 getBoolean(name, &result);
347 return result;
348 }
349
350 int JSONObject::integerProperty(const String& name, int defaultValue) const
351 {
352 int result = defaultValue;
353 getInteger(name, &result);
354 return result;
355 }
356
357 double JSONObject::doubleProperty(const String& name, double defaultValue) const
358 {
359 double result = defaultValue;
360 getDouble(name, &result);
361 return result;
362 }
363
364 void JSONObject::remove(const String& name)
365 {
366 m_data.remove(name);
367 for (size_t i = 0; i < m_order.size(); ++i) {
368 if (m_order[i] == name) {
369 m_order.remove(i);
370 break;
371 }
372 }
373 }
374
375 void JSONObject::writeJSON(StringBuilder* output) const
376 {
377 output->append('{');
378 for (size_t i = 0; i < m_order.size(); ++i) {
379 Dictionary::const_iterator it = m_data.find(m_order[i]);
380 CHECK(it != m_data.end());
381 if (i)
382 output->append(',');
383 doubleQuoteStringForJSON(it->key, output);
384 output->append(':');
385 it->value->writeJSON(output);
386 }
387 output->append('}');
388 }
389
390 void JSONObject::prettyWriteJSONInternal(StringBuilder* output, int depth) const
391 {
392 output->append("{\n");
393 for (size_t i = 0; i < m_order.size(); ++i) {
394 Dictionary::const_iterator it = m_data.find(m_order[i]);
395 CHECK(it != m_data.end());
396 if (i)
397 output->append(",\n");
398 writeIndent(depth + 1, output);
399 doubleQuoteStringForJSON(it->key, output);
400 output->append(": ");
401 it->value->prettyWriteJSONInternal(output, depth + 1);
402 }
403 output->append('\n');
404 writeIndent(depth, output);
405 output->append('}');
406 }
407
408 std::unique_ptr<JSONValue> JSONObject::clone() const
409 {
410 std::unique_ptr<JSONObject> result = JSONObject::create();
411 for (size_t i = 0; i < m_order.size(); ++i) {
412 String key = m_order[i];
413 Dictionary::const_iterator value = m_data.find(key);
414 DCHECK(value != m_data.end() && value->value);
415 result->setValue(key, value->value->clone());
416 }
417 return std::move(result);
418 }
419
420 JSONObject::JSONObject()
421 : JSONValue(TypeObject)
422 , m_data()
423 , m_order()
424 {
425 }
426
427 JSONArray::~JSONArray()
428 {
429 }
430
431 void JSONArray::writeJSON(StringBuilder* output) const
432 {
433 output->append('[');
434 bool first = true;
435 for (const std::unique_ptr<JSONValue>& value : m_data) {
436 if (!first)
437 output->append(',');
438 value->writeJSON(output);
439 first = false;
440 }
441 output->append(']');
442 }
443
444 void JSONArray::prettyWriteJSONInternal(StringBuilder* output, int depth) const
445 {
446 output->append('[');
447 bool first = true;
448 bool lastInsertedNewLine = false;
449 for (const std::unique_ptr<JSONValue>& value : m_data) {
450 bool insertNewLine = value->getType() == JSONValue::TypeObject || value- >getType() == JSONValue::TypeArray || value->getType() == JSONValue::TypeString;
451 if (first) {
452 if (insertNewLine) {
453 output->append('\n');
454 writeIndent(depth + 1, output);
455 }
456 first = false;
457 } else {
458 output->append(',');
459 if (lastInsertedNewLine) {
460 output->append('\n');
461 writeIndent(depth + 1, output);
462 } else {
463 output->append(' ');
464 }
465 }
466 value->prettyWriteJSONInternal(output, depth + 1);
467 lastInsertedNewLine = insertNewLine;
468 }
469 if (lastInsertedNewLine) {
470 output->append('\n');
471 writeIndent(depth, output);
472 }
473 output->append(']');
474 }
475
476 std::unique_ptr<JSONValue> JSONArray::clone() const
477 {
478 std::unique_ptr<JSONArray> result = JSONArray::create();
479 for (const std::unique_ptr<JSONValue>& value : m_data)
480 result->pushValue(value->clone());
481 return std::move(result);
482 }
483
484 JSONArray::JSONArray()
485 : JSONValue(TypeArray)
486 {
487 }
488
489 void JSONArray::pushBoolean(bool value)
490 {
491 m_data.append(JSONBasicValue::create(value));
492 }
493
494 void JSONArray::pushInteger(int value)
495 {
496 m_data.append(JSONBasicValue::create(value));
497 }
498
499 void JSONArray::pushDouble(double value)
500 {
501 m_data.append(JSONBasicValue::create(value));
502 }
503
504 void JSONArray::pushString(const String& value)
505 {
506 m_data.append(JSONString::create(value));
507 }
508
509 void JSONArray::pushValue(std::unique_ptr<JSONValue> value)
510 {
511 DCHECK(value);
512 m_data.append(std::move(value));
513 }
514
515 void JSONArray::pushObject(std::unique_ptr<JSONObject> value)
516 {
517 DCHECK(value);
518 m_data.append(std::move(value));
519 }
520
521 void JSONArray::pushArray(std::unique_ptr<JSONArray> value)
522 {
523 DCHECK(value);
524 m_data.append(std::move(value));
525 }
526
527 JSONValue* JSONArray::at(size_t index)
528 {
529 DCHECK_LT(index, m_data.size());
530 return m_data[index].get();
531 }
532
533 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/JSONValues.h ('k') | third_party/WebKit/Source/platform/blink_platform.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698