| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 namespace blink { | 5 {% for namespace in config.protocol.namespace %} |
| 6 namespace protocol { | 6 namespace {{namespace}} { |
| 7 {% endfor %} |
| 7 | 8 |
| 8 namespace { | 9 namespace { |
| 9 | 10 |
| 10 const int stackLimit = 1000; | 11 const int stackLimit = 1000; |
| 11 | 12 |
| 12 enum Token { | 13 enum Token { |
| 13 ObjectBegin, | 14 ObjectBegin, |
| 14 ObjectEnd, | 15 ObjectEnd, |
| 15 ArrayBegin, | 16 ArrayBegin, |
| 16 ArrayEnd, | 17 ArrayEnd, |
| 17 StringLiteral, | 18 StringLiteral, |
| 18 Number, | 19 Number, |
| 19 BoolTrue, | 20 BoolTrue, |
| 20 BoolFalse, | 21 BoolFalse, |
| 21 NullToken, | 22 NullToken, |
| 22 ListSeparator, | 23 ListSeparator, |
| 23 ObjectPairSeparator, | 24 ObjectPairSeparator, |
| 24 InvalidToken, | 25 InvalidToken, |
| 25 }; | 26 }; |
| 26 | 27 |
| 27 const char* const nullString = "null"; | 28 const char* const nullString = "null"; |
| 28 const char* const trueString = "true"; | 29 const char* const trueString = "true"; |
| 29 const char* const falseString = "false"; | 30 const char* const falseString = "false"; |
| 30 | 31 |
| 31 bool isASCII(uint16_t c) | 32 bool isASCII(uint16_t c) |
| 32 { | 33 { |
| 33 return !(c & ~0x7F); | 34 return !(c & ~0x7F); |
| 34 } | 35 } |
| 35 | 36 |
| 37 bool isSpaceOrNewLine(uint16_t c) |
| 38 { |
| 39 return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); |
| 40 } |
| 41 |
| 36 double charactersToDouble(const uint16_t* characters, size_t length, bool* ok) | 42 double charactersToDouble(const uint16_t* characters, size_t length, bool* ok) |
| 37 { | 43 { |
| 38 std::vector<char> buffer; | 44 std::vector<char> buffer; |
| 39 buffer.reserve(length + 1); | 45 buffer.reserve(length + 1); |
| 40 for (size_t i = 0; i < length; ++i) { | 46 for (size_t i = 0; i < length; ++i) { |
| 41 if (!isASCII(characters[i])) { | 47 if (!isASCII(characters[i])) { |
| 42 *ok = false; | 48 *ok = false; |
| 43 return 0; | 49 return 0; |
| 44 } | 50 } |
| 45 buffer.push_back(static_cast<char>(characters[i])); | 51 buffer.push_back(static_cast<char>(characters[i])); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 return false; | 233 return false; |
| 228 } | 234 } |
| 229 | 235 |
| 230 return false; | 236 return false; |
| 231 } | 237 } |
| 232 | 238 |
| 233 template<typename Char> | 239 template<typename Char> |
| 234 void skipWhitespaceAndComments(const Char* start, const Char* end, const Char**
whitespaceEnd) | 240 void skipWhitespaceAndComments(const Char* start, const Char* end, const Char**
whitespaceEnd) |
| 235 { | 241 { |
| 236 while (start < end) { | 242 while (start < end) { |
| 237 if (String16::isSpaceOrNewLine(*start)) { | 243 if (isSpaceOrNewLine(*start)) { |
| 238 ++start; | 244 ++start; |
| 239 } else if (*start == '/') { | 245 } else if (*start == '/') { |
| 240 const Char* commentEnd; | 246 const Char* commentEnd; |
| 241 if (!skipComment(start, end, &commentEnd)) | 247 if (!skipComment(start, end, &commentEnd)) |
| 242 break; | 248 break; |
| 243 start = commentEnd; | 249 start = commentEnd; |
| 244 } else { | 250 } else { |
| 245 break; | 251 break; |
| 246 } | 252 } |
| 247 } | 253 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 return c - '0'; | 323 return c - '0'; |
| 318 if ('A' <= c && c <= 'F') | 324 if ('A' <= c && c <= 'F') |
| 319 return c - 'A' + 10; | 325 return c - 'A' + 10; |
| 320 if ('a' <= c && c <= 'f') | 326 if ('a' <= c && c <= 'f') |
| 321 return c - 'a' + 10; | 327 return c - 'a' + 10; |
| 322 NOTREACHED(); | 328 NOTREACHED(); |
| 323 return 0; | 329 return 0; |
| 324 } | 330 } |
| 325 | 331 |
| 326 template<typename Char> | 332 template<typename Char> |
| 327 bool decodeString(const Char* start, const Char* end, String16Builder* output) | 333 bool decodeString(const Char* start, const Char* end, StringBuilder* output) |
| 328 { | 334 { |
| 329 while (start < end) { | 335 while (start < end) { |
| 330 UChar c = *start++; | 336 uint16_t c = *start++; |
| 331 if ('\\' != c) { | 337 if ('\\' != c) { |
| 332 output->append(c); | 338 output->append(c); |
| 333 continue; | 339 continue; |
| 334 } | 340 } |
| 335 c = *start++; | 341 c = *start++; |
| 336 | 342 |
| 337 if (c == 'x') { | 343 if (c == 'x') { |
| 338 // \x is not supported. | 344 // \x is not supported. |
| 339 return false; | 345 return false; |
| 340 } | 346 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 371 break; | 377 break; |
| 372 default: | 378 default: |
| 373 return false; | 379 return false; |
| 374 } | 380 } |
| 375 output->append(c); | 381 output->append(c); |
| 376 } | 382 } |
| 377 return true; | 383 return true; |
| 378 } | 384 } |
| 379 | 385 |
| 380 template<typename Char> | 386 template<typename Char> |
| 381 bool decodeString(const Char* start, const Char* end, String16* output) | 387 bool decodeString(const Char* start, const Char* end, String* output) |
| 382 { | 388 { |
| 383 if (start == end) { | 389 if (start == end) { |
| 384 *output = ""; | 390 *output = ""; |
| 385 return true; | 391 return true; |
| 386 } | 392 } |
| 387 if (start > end) | 393 if (start > end) |
| 388 return false; | 394 return false; |
| 389 String16Builder buffer; | 395 StringBuilder buffer; |
| 390 buffer.reserveCapacity(end - start); | 396 StringUtil::builderReserve(buffer, end - start); |
| 391 if (!decodeString(start, end, &buffer)) | 397 if (!decodeString(start, end, &buffer)) |
| 392 return false; | 398 return false; |
| 393 *output = buffer.toString(); | 399 *output = buffer.toString(); |
| 394 return true; | 400 return true; |
| 395 } | 401 } |
| 396 | 402 |
| 397 template<typename Char> | 403 template<typename Char> |
| 398 std::unique_ptr<Value> buildValue(const Char* start, const Char* end, const Char
** valueTokenEnd, int depth) | 404 std::unique_ptr<Value> buildValue(const Char* start, const Char* end, const Char
** valueTokenEnd, int depth) |
| 399 { | 405 { |
| 400 if (depth > stackLimit) | 406 if (depth > stackLimit) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 422 if (!ok) | 428 if (!ok) |
| 423 return nullptr; | 429 return nullptr; |
| 424 int number = static_cast<int>(value); | 430 int number = static_cast<int>(value); |
| 425 if (number == value) | 431 if (number == value) |
| 426 result = FundamentalValue::create(number); | 432 result = FundamentalValue::create(number); |
| 427 else | 433 else |
| 428 result = FundamentalValue::create(value); | 434 result = FundamentalValue::create(value); |
| 429 break; | 435 break; |
| 430 } | 436 } |
| 431 case StringLiteral: { | 437 case StringLiteral: { |
| 432 String16 value; | 438 String value; |
| 433 bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value); | 439 bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value); |
| 434 if (!ok) | 440 if (!ok) |
| 435 return nullptr; | 441 return nullptr; |
| 436 result = StringValue::create(value); | 442 result = StringValue::create(value); |
| 437 break; | 443 break; |
| 438 } | 444 } |
| 439 case ArrayBegin: { | 445 case ArrayBegin: { |
| 440 std::unique_ptr<ListValue> array = ListValue::create(); | 446 std::unique_ptr<ListValue> array = ListValue::create(); |
| 441 start = tokenEnd; | 447 start = tokenEnd; |
| 442 token = parseToken(start, end, &tokenStart, &tokenEnd); | 448 token = parseToken(start, end, &tokenStart, &tokenEnd); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 464 result = std::move(array); | 470 result = std::move(array); |
| 465 break; | 471 break; |
| 466 } | 472 } |
| 467 case ObjectBegin: { | 473 case ObjectBegin: { |
| 468 std::unique_ptr<DictionaryValue> object = DictionaryValue::create(); | 474 std::unique_ptr<DictionaryValue> object = DictionaryValue::create(); |
| 469 start = tokenEnd; | 475 start = tokenEnd; |
| 470 token = parseToken(start, end, &tokenStart, &tokenEnd); | 476 token = parseToken(start, end, &tokenStart, &tokenEnd); |
| 471 while (token != ObjectEnd) { | 477 while (token != ObjectEnd) { |
| 472 if (token != StringLiteral) | 478 if (token != StringLiteral) |
| 473 return nullptr; | 479 return nullptr; |
| 474 String16 key; | 480 String key; |
| 475 if (!decodeString(tokenStart + 1, tokenEnd - 1, &key)) | 481 if (!decodeString(tokenStart + 1, tokenEnd - 1, &key)) |
| 476 return nullptr; | 482 return nullptr; |
| 477 start = tokenEnd; | 483 start = tokenEnd; |
| 478 | 484 |
| 479 token = parseToken(start, end, &tokenStart, &tokenEnd); | 485 token = parseToken(start, end, &tokenStart, &tokenEnd); |
| 480 if (token != ObjectPairSeparator) | 486 if (token != ObjectPairSeparator) |
| 481 return nullptr; | 487 return nullptr; |
| 482 start = tokenEnd; | 488 start = tokenEnd; |
| 483 | 489 |
| 484 std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, dep
th + 1); | 490 std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, dep
th + 1); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 std::unique_ptr<Value> parseJSON(const uint16_t* characters, unsigned length) | 537 std::unique_ptr<Value> parseJSON(const uint16_t* characters, unsigned length) |
| 532 { | 538 { |
| 533 return parseJSONInternal<uint16_t>(characters, length); | 539 return parseJSONInternal<uint16_t>(characters, length); |
| 534 } | 540 } |
| 535 | 541 |
| 536 std::unique_ptr<Value> parseJSON(const uint8_t* characters, unsigned length) | 542 std::unique_ptr<Value> parseJSON(const uint8_t* characters, unsigned length) |
| 537 { | 543 { |
| 538 return parseJSONInternal<uint8_t>(characters, length); | 544 return parseJSONInternal<uint8_t>(characters, length); |
| 539 } | 545 } |
| 540 | 546 |
| 541 std::unique_ptr<Value> parseJSON(const String16& json) | 547 {% for namespace in config.protocol.namespace %} |
| 542 { | 548 } // namespace {{namespace}} |
| 543 if (json.isEmpty()) | 549 {% endfor %} |
| 544 return nullptr; | |
| 545 return parseJSONInternal<uint16_t>(reinterpret_cast<const uint16_t*>(json.ch
aracters16()), json.length()); | |
| 546 } | |
| 547 | |
| 548 } // namespace protocol | |
| 549 } // namespace blink | |
| OLD | NEW |