Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import "dart:typed_data"; | 5 import "dart:typed_data"; |
| 6 | 6 |
| 7 // JSON conversion. | 7 // JSON conversion. |
| 8 | 8 |
| 9 patch _parseJson(String json, reviver(var key, var value)) { | 9 patch _parseJson(String json, reviver(var key, var value)) { |
| 10 _BuildJsonListener listener; | 10 _BuildJsonListener listener; |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 384 fail(position); | 384 fail(position); |
| 385 } | 385 } |
| 386 listener.handleNull(); | 386 listener.handleNull(); |
| 387 return position + 4; | 387 return position + 4; |
| 388 } | 388 } |
| 389 | 389 |
| 390 int parseString(int position) { | 390 int parseString(int position) { |
| 391 // Format: '"'([^\x00-\x1f\\\"]|'\\'[bfnrt/\\"])*'"' | 391 // Format: '"'([^\x00-\x1f\\\"]|'\\'[bfnrt/\\"])*'"' |
| 392 // Initial position is right after first '"'. | 392 // Initial position is right after first '"'. |
| 393 int start = position; | 393 int start = position; |
| 394 int char; | 394 while (position < source.length) { |
| 395 do { | 395 int char = source.codeUnitAt(position); |
| 396 if (position == source.length) { | 396 if (char <= BACKSLASH) { // BACKSLASH is larger than QUOTE. |
|
Søren Gjesse
2014/03/24 08:33:57
and SPACE :-)
Lasse Reichstein Nielsen
2014/03/24 12:13:49
SPACE is *obviously* smaller than anything :)
But
| |
| 397 fail(start - 1, "Unterminated string"); | 397 if (char == BACKSLASH) { |
| 398 } | 398 return parseStringWithEscapes(start, position); |
| 399 char = source.codeUnitAt(position); | 399 } |
| 400 if (char == QUOTE) { | 400 if (char == QUOTE) { |
| 401 listener.handleString(source.substring(start, position)); | 401 listener.handleString(source.substring(start, position)); |
| 402 return position + 1; | 402 return position + 1; |
| 403 } | 403 } |
| 404 if (char < SPACE) { | 404 if (char < SPACE) { |
| 405 fail(position, "Control character in string"); | 405 fail(position, "Control character in string"); |
| 406 } | |
| 406 } | 407 } |
| 407 position++; | 408 position++; |
| 408 } while (char != BACKSLASH); | 409 } |
| 410 fail(start - 1, "Unterminated string"); | |
| 411 } | |
| 412 | |
| 413 int parseStringWithEscapes(string, position) { | |
|
Lasse Reichstein Nielsen
2014/03/07 10:40:27
string -> start.
Lasse Reichstein Nielsen
2014/03/24 08:30:54
string -> source even.
| |
| 409 // Backslash escape detected. Collect character codes for rest of string. | 414 // Backslash escape detected. Collect character codes for rest of string. |
| 410 int firstEscape = position - 1; | 415 int firstEscape = position - 1; |
| 411 List<int> chars = <int>[]; | 416 List<int> chars = <int>[]; |
| 412 while (true) { | 417 while (true) { |
| 413 if (position == source.length) { | 418 if (position == source.length) { |
| 414 fail(start - 1, "Unterminated string"); | 419 fail(start - 1, "Unterminated string"); |
| 415 } | 420 } |
| 416 char = source.codeUnitAt(position); | 421 char = source.codeUnitAt(position); |
| 417 switch (char) { | 422 switch (char) { |
| 418 case CHAR_b: char = BACKSPACE; break; | 423 case CHAR_b: char = BACKSPACE; break; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 465 return position + 1; | 470 return position + 1; |
| 466 } | 471 } |
| 467 if (char < SPACE) { | 472 if (char < SPACE) { |
| 468 fail(position, "Control character in string"); | 473 fail(position, "Control character in string"); |
| 469 } | 474 } |
| 470 } while (char != BACKSLASH); | 475 } while (char != BACKSLASH); |
| 471 position++; | 476 position++; |
| 472 } | 477 } |
| 473 } | 478 } |
| 474 | 479 |
| 475 int _handleLiteral(start, position, isDouble) { | |
| 476 String literal = source.substring(start, position); | |
| 477 // This correctly creates -0 for doubles. | |
| 478 num value = (isDouble ? double.parse(literal) : int.parse(literal)); | |
| 479 listener.handleNumber(value); | |
| 480 return position; | |
| 481 } | |
| 482 | |
| 483 int parseNumber(int char, int position) { | 480 int parseNumber(int char, int position) { |
| 484 // Format: | 481 // Format: |
| 485 // '-'?('0'|[1-9][0-9]*)('.'[0-9]+)?([eE][+-]?[0-9]+)? | 482 // '-'?('0'|[1-9][0-9]*)('.'[0-9]+)?([eE][+-]?[0-9]+)? |
| 486 int start = position; | 483 int start = position; |
| 487 int length = source.length; | 484 int length = source.length; |
| 485 int intValue = 0; // Collect int value while parsing. | |
| 486 int intSign = 1; | |
| 488 bool isDouble = false; | 487 bool isDouble = false; |
| 489 if (char == MINUS) { | 488 // Break this block when the end of the number literal is reached. |
| 490 position++; | 489 // At that time, position points to the next character, and isDouble |
| 491 if (position == length) fail(position, "Missing expected digit"); | 490 // is set if the literal contains a decimal point or an exponential. |
| 492 char = source.codeUnitAt(position); | 491 parsing: { |
| 493 } | 492 if (char == MINUS) { |
| 494 if (char < CHAR_0 || char > CHAR_9) { | 493 intSign = -1; |
| 495 fail(position, "Missing expected digit"); | |
| 496 } | |
| 497 if (char == CHAR_0) { | |
| 498 position++; | |
| 499 if (position == length) return _handleLiteral(start, position, false); | |
| 500 char = source.codeUnitAt(position); | |
| 501 if (CHAR_0 <= char && char <= CHAR_9) { | |
| 502 fail(position); | |
| 503 } | |
| 504 } else { | |
| 505 do { | |
| 506 position++; | |
| 507 if (position == length) return _handleLiteral(start, position, false); | |
| 508 char = source.codeUnitAt(position); | |
| 509 } while (CHAR_0 <= char && char <= CHAR_9); | |
| 510 } | |
| 511 if (char == DECIMALPOINT) { | |
| 512 isDouble = true; | |
| 513 position++; | |
| 514 if (position == length) fail(position, "Missing expected digit"); | |
| 515 char = source.codeUnitAt(position); | |
| 516 if (char < CHAR_0 || char > CHAR_9) fail(position); | |
| 517 do { | |
| 518 position++; | |
| 519 if (position == length) return _handleLiteral(start, position, true); | |
| 520 char = source.codeUnitAt(position); | |
| 521 } while (CHAR_0 <= char && char <= CHAR_9); | |
| 522 } | |
| 523 if (char == CHAR_e || char == CHAR_E) { | |
| 524 isDouble = true; | |
| 525 position++; | |
| 526 if (position == length) fail(position, "Missing expected digit"); | |
| 527 char = source.codeUnitAt(position); | |
| 528 if (char == PLUS || char == MINUS) { | |
| 529 position++; | 494 position++; |
| 530 if (position == length) fail(position, "Missing expected digit"); | 495 if (position == length) fail(position, "Missing expected digit"); |
| 531 char = source.codeUnitAt(position); | 496 char = source.codeUnitAt(position); |
| 532 } | 497 } |
| 533 if (char < CHAR_0 || char > CHAR_9) { | 498 if (char < CHAR_0 || char > CHAR_9) { |
| 534 fail(position, "Missing expected digit"); | 499 fail(position, "Missing expected digit"); |
| 535 } | 500 } |
| 536 do { | 501 if (char == CHAR_0) { |
| 537 position++; | 502 position++; |
| 538 if (position == length) return _handleLiteral(start, position, true); | 503 if (position == length) break parsing; |
| 539 char = source.codeUnitAt(position); | 504 char = source.codeUnitAt(position); |
| 540 } while (CHAR_0 <= char && char <= CHAR_9); | 505 if (CHAR_0 <= char && char <= CHAR_9) { |
| 506 fail(position); | |
| 507 } | |
| 508 } else { | |
| 509 do { | |
| 510 intValue = intValue * 10 + (char - CHAR_0); | |
| 511 position++; | |
| 512 if (position == length) break parsing; | |
| 513 char = source.codeUnitAt(position); | |
| 514 } while (CHAR_0 <= char && char <= CHAR_9); | |
| 515 } | |
| 516 if (char == DECIMALPOINT) { | |
| 517 isDouble = true; | |
| 518 position++; | |
| 519 if (position == length) fail(position, "Missing expected digit"); | |
| 520 char = source.codeUnitAt(position); | |
| 521 if (char < CHAR_0 || char > CHAR_9) fail(position); | |
| 522 do { | |
| 523 position++; | |
| 524 if (position == length) break parsing; | |
| 525 char = source.codeUnitAt(position); | |
| 526 } while (CHAR_0 <= char && char <= CHAR_9); | |
| 527 } | |
| 528 if (char == CHAR_e || char == CHAR_E) { | |
| 529 isDouble = true; | |
| 530 position++; | |
| 531 if (position == length) fail(position, "Missing expected digit"); | |
| 532 char = source.codeUnitAt(position); | |
| 533 if (char == PLUS || char == MINUS) { | |
| 534 position++; | |
| 535 if (position == length) fail(position, "Missing expected digit"); | |
| 536 char = source.codeUnitAt(position); | |
| 537 } | |
| 538 if (char < CHAR_0 || char > CHAR_9) { | |
| 539 fail(position, "Missing expected digit"); | |
| 540 } | |
| 541 do { | |
| 542 position++; | |
| 543 if (position == length) break parsing; | |
| 544 char = source.codeUnitAt(position); | |
| 545 } while (CHAR_0 <= char && char <= CHAR_9); | |
| 546 } | |
| 541 } | 547 } |
| 542 return _handleLiteral(start, position, isDouble); | 548 if (!isDouble) { |
| 549 listener.handleNumber(intSign * intValue); | |
| 550 return position; | |
| 551 } | |
| 552 // Consider whether we can have an int/double.parse that works on part of | |
| 553 // a string, to avoid creating the substring. | |
| 554 String literal = source.substring(start, position); | |
| 555 // This correctly creates -0.0 for doubles. | |
| 556 listener.handleNumber(double.parse(literal)); | |
|
Søren Gjesse
2014/03/24 08:33:57
There is no simpler way to create the double now y
Lasse Reichstein Nielsen
2014/03/24 12:13:49
In simple cases, there probably is.
Parsing a doub
| |
| 557 return position; | |
| 543 } | 558 } |
| 544 | 559 |
| 545 void fail(int position, [String message]) { | 560 void fail(int position, [String message]) { |
| 546 if (message == null) message = "Unexpected character"; | 561 if (message == null) message = "Unexpected character"; |
| 547 listener.fail(source, position, message); | 562 listener.fail(source, position, message); |
| 548 // If the listener didn't throw, do it here. | 563 // If the listener didn't throw, do it here. |
| 549 String slice; | 564 String slice; |
| 550 int sliceEnd = position + 20; | 565 int sliceEnd = position + 20; |
| 551 if (sliceEnd > source.length) { | 566 if (sliceEnd > source.length) { |
| 552 slice = "'${source.substring(position)}'"; | 567 slice = "'${source.substring(position)}'"; |
| 553 } else { | 568 } else { |
| 554 slice = "'${source.substring(position, sliceEnd)}...'"; | 569 slice = "'${source.substring(position, sliceEnd)}...'"; |
| 555 } | 570 } |
| 556 throw new FormatException("Unexpected character at $position: $slice"); | 571 throw new FormatException("Unexpected character at $position: $slice"); |
| 557 } | 572 } |
| 558 } | 573 } |
| 559 | 574 |
| 560 // UTF-8 conversion. | 575 // UTF-8 conversion. |
| 561 | 576 |
| 562 patch class _Utf8Encoder { | 577 patch class _Utf8Encoder { |
| 563 /* patch */ static List<int> _createBuffer(int size) => new Uint8List(size); | 578 /* patch */ static List<int> _createBuffer(int size) => new Uint8List(size); |
| 564 } | 579 } |
| OLD | NEW |