Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / platform / JSONValues.cpp
blob72a5af5a10d99392f2e3be8a4ee5676fb42acc26
1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
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.
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.
31 #include "config.h"
32 #include "platform/JSONValues.h"
34 #include "platform/Decimal.h"
35 #include "wtf/MathExtras.h"
36 #include "wtf/text/StringBuilder.h"
38 namespace blink {
40 namespace {
42 const char* const nullString = "null";
43 const char* const trueString = "true";
44 const char* const falseString = "false";
46 inline bool escapeChar(UChar c, StringBuilder* dst)
48 switch (c) {
49 case '\b': dst->appendLiteral("\\b"); break;
50 case '\f': dst->appendLiteral("\\f"); break;
51 case '\n': dst->appendLiteral("\\n"); break;
52 case '\r': dst->appendLiteral("\\r"); break;
53 case '\t': dst->appendLiteral("\\t"); break;
54 case '\\': dst->appendLiteral("\\\\"); break;
55 case '"': dst->appendLiteral("\\\""); break;
56 default:
57 return false;
59 return true;
62 void writeIndent(int depth, StringBuilder* output)
64 for (int i = 0; i < depth; ++i)
65 output->appendLiteral(" ");
68 } // anonymous namespace
70 void doubleQuoteStringForJSON(const String& str, StringBuilder* dst)
72 dst->append('"');
73 for (unsigned i = 0; i < str.length(); ++i) {
74 UChar c = str[i];
75 if (!escapeChar(c, dst)) {
76 if (c < 32 || c > 126 || c == '<' || c == '>') {
77 // 1. Escaping <, > to prevent script execution.
78 // 2. Technically, we could also pass through c > 126 as UTF8, but this
79 // is also optional. It would also be a pain to implement here.
80 unsigned symbol = static_cast<unsigned>(c);
81 String symbolCode = String::format("\\u%04X", symbol);
82 dst->append(symbolCode);
83 } else {
84 dst->append(c);
88 dst->append('"');
91 String JSONValue::quoteString(const String& input)
93 StringBuilder builder;
94 doubleQuoteStringForJSON(input, &builder);
95 return builder.toString();
98 bool JSONValue::asBoolean(bool*) const
100 return false;
103 bool JSONValue::asNumber(double*) const
105 return false;
108 bool JSONValue::asNumber(long*) const
110 return false;
113 bool JSONValue::asNumber(int*) const
115 return false;
118 bool JSONValue::asNumber(unsigned long*) const
120 return false;
123 bool JSONValue::asNumber(unsigned*) const
125 return false;
128 bool JSONValue::asString(String*) const
130 return false;
133 bool JSONValue::asObject(RefPtr<JSONObject>*)
135 return false;
138 bool JSONValue::asArray(RefPtr<JSONArray>*)
140 return false;
143 PassRefPtr<JSONObject> JSONValue::asObject()
145 return nullptr;
148 PassRefPtr<JSONArray> JSONValue::asArray()
150 return nullptr;
153 String JSONValue::toJSONString() const
155 StringBuilder result;
156 result.reserveCapacity(512);
157 writeJSON(&result);
158 return result.toString();
161 String JSONValue::toPrettyJSONString() const
163 StringBuilder result;
164 result.reserveCapacity(512);
165 prettyWriteJSON(&result);
166 return result.toString();
169 void JSONValue::writeJSON(StringBuilder* output) const
171 ASSERT(m_type == TypeNull);
172 output->append(nullString, 4);
175 void JSONValue::prettyWriteJSON(StringBuilder* output) const
177 prettyWriteJSONInternal(output, 0);
178 output->append('\n');
181 void JSONValue::prettyWriteJSONInternal(StringBuilder* output, int depth) const
183 writeJSON(output);
186 bool JSONBasicValue::asBoolean(bool* output) const
188 if (type() != TypeBoolean)
189 return false;
190 *output = m_boolValue;
191 return true;
194 bool JSONBasicValue::asNumber(double* output) const
196 if (type() != TypeNumber)
197 return false;
198 *output = m_doubleValue;
199 return true;
202 bool JSONBasicValue::asNumber(long* output) const
204 if (type() != TypeNumber)
205 return false;
206 *output = static_cast<long>(m_doubleValue);
207 return true;
210 bool JSONBasicValue::asNumber(int* output) const
212 if (type() != TypeNumber)
213 return false;
214 *output = static_cast<int>(m_doubleValue);
215 return true;
218 bool JSONBasicValue::asNumber(unsigned long* output) const
220 if (type() != TypeNumber)
221 return false;
222 *output = static_cast<unsigned long>(m_doubleValue);
223 return true;
226 bool JSONBasicValue::asNumber(unsigned* output) const
228 if (type() != TypeNumber)
229 return false;
230 *output = static_cast<unsigned>(m_doubleValue);
231 return true;
234 void JSONBasicValue::writeJSON(StringBuilder* output) const
236 ASSERT(type() == TypeBoolean || type() == TypeNumber);
237 if (type() == TypeBoolean) {
238 if (m_boolValue)
239 output->append(trueString, 4);
240 else
241 output->append(falseString, 5);
242 } else if (type() == TypeNumber) {
243 if (!std::isfinite(m_doubleValue)) {
244 output->append(nullString, 4);
245 return;
247 output->append(Decimal::fromDouble(m_doubleValue).toString());
251 bool JSONString::asString(String* output) const
253 *output = m_stringValue;
254 return true;
257 void JSONString::writeJSON(StringBuilder* output) const
259 ASSERT(type() == TypeString);
260 doubleQuoteStringForJSON(m_stringValue, output);
263 JSONObjectBase::~JSONObjectBase()
267 bool JSONObjectBase::asObject(RefPtr<JSONObject>* output)
269 static_assert(sizeof(JSONObject) == sizeof(JSONObjectBase), "cannot cast");
270 *output = static_cast<JSONObject*>(this);
271 return true;
274 PassRefPtr<JSONObject> JSONObjectBase::asObject()
276 return openAccessors();
279 void JSONObjectBase::setBoolean(const String& name, bool value)
281 setValue(name, JSONBasicValue::create(value));
284 void JSONObjectBase::setNumber(const String& name, double value)
286 setValue(name, JSONBasicValue::create(value));
289 void JSONObjectBase::setString(const String& name, const String& value)
291 setValue(name, JSONString::create(value));
294 void JSONObjectBase::setValue(const String& name, PassRefPtr<JSONValue> value)
296 ASSERT(value);
297 if (m_data.set(name, value).isNewEntry)
298 m_order.append(name);
301 void JSONObjectBase::setObject(const String& name, PassRefPtr<JSONObject> value)
303 ASSERT(value);
304 if (m_data.set(name, value).isNewEntry)
305 m_order.append(name);
308 void JSONObjectBase::setArray(const String& name, PassRefPtr<JSONArray> value)
310 ASSERT(value);
311 if (m_data.set(name, value).isNewEntry)
312 m_order.append(name);
315 JSONObject* JSONObjectBase::openAccessors()
317 static_assert(sizeof(JSONObject) == sizeof(JSONObjectBase), "cannot cast");
318 return static_cast<JSONObject*>(this);
321 JSONObjectBase::iterator JSONObjectBase::find(const String& name)
323 return m_data.find(name);
326 JSONObjectBase::const_iterator JSONObjectBase::find(const String& name) const
328 return m_data.find(name);
331 bool JSONObjectBase::getBoolean(const String& name, bool* output) const
333 RefPtr<JSONValue> value = get(name);
334 if (!value)
335 return false;
336 return value->asBoolean(output);
339 bool JSONObjectBase::getString(const String& name, String* output) const
341 RefPtr<JSONValue> value = get(name);
342 if (!value)
343 return false;
344 return value->asString(output);
347 PassRefPtr<JSONObject> JSONObjectBase::getObject(const String& name) const
349 RefPtr<JSONValue> value = get(name);
350 if (!value)
351 return nullptr;
352 return value->asObject();
355 PassRefPtr<JSONArray> JSONObjectBase::getArray(const String& name) const
357 RefPtr<JSONValue> value = get(name);
358 if (!value)
359 return nullptr;
360 return value->asArray();
363 PassRefPtr<JSONValue> JSONObjectBase::get(const String& name) const
365 Dictionary::const_iterator it = m_data.find(name);
366 if (it == m_data.end())
367 return nullptr;
368 return it->value;
371 void JSONObjectBase::remove(const String& name)
373 m_data.remove(name);
374 for (size_t i = 0; i < m_order.size(); ++i) {
375 if (m_order[i] == name) {
376 m_order.remove(i);
377 break;
382 void JSONObjectBase::writeJSON(StringBuilder* output) const
384 output->append('{');
385 for (size_t i = 0; i < m_order.size(); ++i) {
386 Dictionary::const_iterator it = m_data.find(m_order[i]);
387 ASSERT_WITH_SECURITY_IMPLICATION(it != m_data.end());
388 if (i)
389 output->append(',');
390 doubleQuoteStringForJSON(it->key, output);
391 output->append(':');
392 it->value->writeJSON(output);
394 output->append('}');
397 void JSONObjectBase::prettyWriteJSONInternal(StringBuilder* output, int depth) const
399 output->appendLiteral("{\n");
400 for (size_t i = 0; i < m_order.size(); ++i) {
401 Dictionary::const_iterator it = m_data.find(m_order[i]);
402 ASSERT_WITH_SECURITY_IMPLICATION(it != m_data.end());
403 if (i)
404 output->appendLiteral(",\n");
405 writeIndent(depth + 1, output);
406 doubleQuoteStringForJSON(it->key, output);
407 output->appendLiteral(": ");
408 it->value->prettyWriteJSONInternal(output, depth + 1);
410 output->append('\n');
411 writeIndent(depth, output);
412 output->append('}');
415 JSONObjectBase::JSONObjectBase()
416 : JSONValue(TypeObject)
417 , m_data()
418 , m_order()
422 JSONArrayBase::~JSONArrayBase()
426 bool JSONArrayBase::asArray(RefPtr<JSONArray>* output)
428 static_assert(sizeof(JSONArrayBase) == sizeof(JSONArray), "cannot cast");
429 *output = static_cast<JSONArray*>(this);
430 return true;
433 PassRefPtr<JSONArray> JSONArrayBase::asArray()
435 static_assert(sizeof(JSONArrayBase) == sizeof(JSONArray), "cannot cast");
436 return static_cast<JSONArray*>(this);
439 void JSONArrayBase::writeJSON(StringBuilder* output) const
441 output->append('[');
442 for (Vector<RefPtr<JSONValue>>::const_iterator it = m_data.begin(); it != m_data.end(); ++it) {
443 if (it != m_data.begin())
444 output->append(',');
445 (*it)->writeJSON(output);
447 output->append(']');
450 void JSONArrayBase::prettyWriteJSONInternal(StringBuilder* output, int depth) const
452 output->append('[');
453 bool lastInsertedNewLine = false;
454 for (Vector<RefPtr<JSONValue>>::const_iterator it = m_data.begin(); it != m_data.end(); ++it) {
455 bool insertNewLine = (*it)->type() == JSONValue::TypeObject || (*it)->type() == JSONValue::TypeArray || (*it)->type() == JSONValue::TypeString;
456 if (it == m_data.begin()) {
457 if (insertNewLine) {
458 output->append('\n');
459 writeIndent(depth + 1, output);
461 } else {
462 output->append(',');
463 if (lastInsertedNewLine) {
464 output->append('\n');
465 writeIndent(depth + 1, output);
466 } else {
467 output->append(' ');
470 (*it)->prettyWriteJSONInternal(output, depth + 1);
471 lastInsertedNewLine = insertNewLine;
473 if (lastInsertedNewLine) {
474 output->append('\n');
475 writeIndent(depth, output);
477 output->append(']');
480 JSONArrayBase::JSONArrayBase()
481 : JSONValue(TypeArray)
482 , m_data()
486 void JSONArrayBase::pushBoolean(bool value)
488 m_data.append(JSONBasicValue::create(value));
491 void JSONArrayBase::pushInt(int value)
493 m_data.append(JSONBasicValue::create(value));
496 void JSONArrayBase::pushNumber(double value)
498 m_data.append(JSONBasicValue::create(value));
501 void JSONArrayBase::pushString(const String& value)
503 m_data.append(JSONString::create(value));
506 void JSONArrayBase::pushValue(PassRefPtr<JSONValue> value)
508 ASSERT(value);
509 m_data.append(value);
512 void JSONArrayBase::pushObject(PassRefPtr<JSONObject> value)
514 ASSERT(value);
515 m_data.append(value);
518 void JSONArrayBase::pushArray(PassRefPtr<JSONArray> value)
520 ASSERT(value);
521 m_data.append(value);
524 PassRefPtr<JSONValue> JSONArrayBase::get(size_t index)
526 ASSERT_WITH_SECURITY_IMPLICATION(index < m_data.size());
527 return m_data[index];
530 } // namespace blink