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 |