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