| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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:_internal" show POWERS_OF_TEN; | 5 import "dart:_internal" show POWERS_OF_TEN; |
| 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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 // Grows to the exact size asked for. | 209 // Grows to the exact size asked for. |
| 210 void ensureCapacity(int newCapacity) { | 210 void ensureCapacity(int newCapacity) { |
| 211 Uint8List list = this.list; | 211 Uint8List list = this.list; |
| 212 if (newCapacity <= list.length) return; | 212 if (newCapacity <= list.length) return; |
| 213 Uint8List newList = new Uint8List(newCapacity); | 213 Uint8List newList = new Uint8List(newCapacity); |
| 214 newList.setRange(0, list.length, list, 0); | 214 newList.setRange(0, list.length, list, 0); |
| 215 this.list = newList; | 215 this.list = newList; |
| 216 } | 216 } |
| 217 | 217 |
| 218 String getString() { | 218 String getString() { |
| 219 var list = this.list; | 219 String result = new String.fromCharCodes(list, 0, length); |
| 220 if (length < list.length) { | |
| 221 list = new Uint8List.view(list.buffer, 0, length); | |
| 222 } | |
| 223 String result = new String.fromCharCodes(list); | |
| 224 return result; | 220 return result; |
| 225 } | 221 } |
| 226 | 222 |
| 227 // TODO(lrn): See if parsing of numbers can be abstracted to something | 223 // TODO(lrn): See if parsing of numbers can be abstracted to something |
| 228 // not only working on strings, but also on char-code lists, without lossing | 224 // not only working on strings, but also on char-code lists, without lossing |
| 229 // performance. | 225 // performance. |
| 230 int parseInt() => int.parse(getString()); | 226 int parseInt() => int.parse(getString()); |
| 231 double parseDouble() => double.parse(getString()); | 227 double parseDouble() => double.parse(getString()); |
| 232 } | 228 } |
| 233 | 229 |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 | 537 |
| 542 /** | 538 /** |
| 543 * Extracts a literal string from a slice of the current chunk. | 539 * Extracts a literal string from a slice of the current chunk. |
| 544 * | 540 * |
| 545 * No interpretation of the content is performed, except for converting | 541 * No interpretation of the content is performed, except for converting |
| 546 * the source format to string. | 542 * the source format to string. |
| 547 * This can be implemented more or less efficiently depending on the | 543 * This can be implemented more or less efficiently depending on the |
| 548 * underlying source. | 544 * underlying source. |
| 549 * | 545 * |
| 550 * This is used for string literals that contain no escapes. | 546 * This is used for string literals that contain no escapes. |
| 547 * |
| 548 * The [bits] integer is an upper bound on the code point in the range |
| 549 * from `start` to `end`. |
| 550 * Usually found by doing bitwise or of all the values. |
| 551 * The function may choose to optimize depending on the value. |
| 551 */ | 552 */ |
| 552 String getString(int start, int end); | 553 String getString(int start, int end, int bits); |
| 553 | 554 |
| 554 /** | 555 /** |
| 555 * Parse a slice of the current chunk as an integer. | 556 * Parse a slice of the current chunk as an integer. |
| 556 * | 557 * |
| 557 * The format is expected to be correct. | 558 * The format is expected to be correct. |
| 558 */ | 559 */ |
| 559 int parseInt(int start, int end) { | 560 int parseInt(int start, int end) { |
| 560 return int.parse(getString(start, end)); | 561 const int asciiBits = 0x7f; // Integer literals are ASCII only. |
| 562 return int.parse(getString(start, end, asciiBits)); |
| 561 } | 563 } |
| 562 | 564 |
| 563 /** | 565 /** |
| 564 * Parse a slice of the current chunk as a double. | 566 * Parse a slice of the current chunk as a double. |
| 565 * | 567 * |
| 566 * The format is expected to be correct. | 568 * The format is expected to be correct. |
| 567 * This is used by [parseNumber] when the double value cannot be | 569 * This is used by [parseNumber] when the double value cannot be |
| 568 * built exactly during parsing. | 570 * built exactly during parsing. |
| 569 */ | 571 */ |
| 570 double parseDouble(int start, int end) { | 572 double parseDouble(int start, int end) { |
| 571 return double.parse(getString(start, end)); | 573 const int asciiBits = 0x7f; // Double literals are ASCII only. |
| 574 return double.parse(getString(start, end, asciiBits)); |
| 572 } | 575 } |
| 573 | 576 |
| 574 /** | 577 /** |
| 575 * Create a _NumberBuffer containing the digits from [start] to [chunkEnd]. | 578 * Create a _NumberBuffer containing the digits from [start] to [chunkEnd]. |
| 576 * | 579 * |
| 577 * This creates a number buffer and initializes it with the part of the | 580 * This creates a number buffer and initializes it with the part of the |
| 578 * number literal ending the current chunk | 581 * number literal ending the current chunk |
| 579 */ | 582 */ |
| 580 void createNumberBuffer(int start) { | 583 void createNumberBuffer(int start) { |
| 581 assert(start >= 0); | 584 assert(start >= 0); |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 * Parses a string value. | 967 * Parses a string value. |
| 965 * | 968 * |
| 966 * Initial [position] is right after the initial quote. | 969 * Initial [position] is right after the initial quote. |
| 967 * Returned position right after the final quote. | 970 * Returned position right after the final quote. |
| 968 */ | 971 */ |
| 969 int parseString(int position) { | 972 int parseString(int position) { |
| 970 // Format: '"'([^\x00-\x1f\\\"]|'\\'[bfnrt/\\"])*'"' | 973 // Format: '"'([^\x00-\x1f\\\"]|'\\'[bfnrt/\\"])*'"' |
| 971 // Initial position is right after first '"'. | 974 // Initial position is right after first '"'. |
| 972 int start = position; | 975 int start = position; |
| 973 int end = chunkEnd; | 976 int end = chunkEnd; |
| 977 int bits = 0; |
| 974 while (position < end) { | 978 while (position < end) { |
| 975 int char = getChar(position++); | 979 int char = getChar(position++); |
| 980 bits |= char; // Includes final '"', but that never matters. |
| 976 // BACKSLASH is larger than QUOTE and SPACE. | 981 // BACKSLASH is larger than QUOTE and SPACE. |
| 977 if (char > BACKSLASH) { | 982 if (char > BACKSLASH) { |
| 978 continue; | 983 continue; |
| 979 } | 984 } |
| 980 if (char == BACKSLASH) { | 985 if (char == BACKSLASH) { |
| 981 beginString(); | 986 beginString(); |
| 982 int sliceEnd = position - 1; | 987 int sliceEnd = position - 1; |
| 983 if (start < sliceEnd) addSliceToString(start, sliceEnd); | 988 if (start < sliceEnd) addSliceToString(start, sliceEnd); |
| 984 return parseStringToBuffer(position - 1); | 989 return parseStringToBuffer(sliceEnd); |
| 985 } | 990 } |
| 986 if (char == QUOTE) { | 991 if (char == QUOTE) { |
| 987 listener.handleString(getString(start, position - 1)); | 992 listener.handleString(getString(start, position - 1, bits)); |
| 988 return position; | 993 return position; |
| 989 } | 994 } |
| 990 if (char < SPACE) { | 995 if (char < SPACE) { |
| 991 fail(position - 1, "Control character in string"); | 996 fail(position - 1, "Control character in string"); |
| 992 } | 997 } |
| 993 } | 998 } |
| 994 beginString(); | 999 beginString(); |
| 995 if (start < end) addSliceToString(start, end); | 1000 if (start < end) addSliceToString(start, end); |
| 996 return chunkString(STR_PLAIN); | 1001 return chunkString(STR_PLAIN); |
| 997 } | 1002 } |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1315 * Chunked JSON parser that parses [String] chunks. | 1320 * Chunked JSON parser that parses [String] chunks. |
| 1316 */ | 1321 */ |
| 1317 class _JsonStringParser extends _ChunkedJsonParser { | 1322 class _JsonStringParser extends _ChunkedJsonParser { |
| 1318 String chunk; | 1323 String chunk; |
| 1319 int chunkEnd; | 1324 int chunkEnd; |
| 1320 | 1325 |
| 1321 _JsonStringParser(_JsonListener listener) : super(listener); | 1326 _JsonStringParser(_JsonListener listener) : super(listener); |
| 1322 | 1327 |
| 1323 int getChar(int position) => chunk.codeUnitAt(position); | 1328 int getChar(int position) => chunk.codeUnitAt(position); |
| 1324 | 1329 |
| 1325 String getString(int start, int end) { | 1330 String getString(int start, int end, int bits) { |
| 1326 return chunk.substring(start, end); | 1331 return chunk.substring(start, end); |
| 1327 } | 1332 } |
| 1328 | 1333 |
| 1329 void beginString() { | 1334 void beginString() { |
| 1330 this.buffer = new StringBuffer(); | 1335 this.buffer = new StringBuffer(); |
| 1331 } | 1336 } |
| 1332 | 1337 |
| 1333 void addSliceToString(int start, int end) { | 1338 void addSliceToString(int start, int end) { |
| 1334 StringBuffer buffer = this.buffer; | 1339 StringBuffer buffer = this.buffer; |
| 1335 buffer.write(chunk.substring(start, end)); | 1340 buffer.write(chunk.substring(start, end)); |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1661 class _JsonUtf8Parser extends _ChunkedJsonParser { | 1666 class _JsonUtf8Parser extends _ChunkedJsonParser { |
| 1662 final bool allowMalformed; | 1667 final bool allowMalformed; |
| 1663 List<int> chunk; | 1668 List<int> chunk; |
| 1664 int chunkEnd; | 1669 int chunkEnd; |
| 1665 | 1670 |
| 1666 _JsonUtf8Parser(_JsonListener listener, this.allowMalformed) | 1671 _JsonUtf8Parser(_JsonListener listener, this.allowMalformed) |
| 1667 : super(listener); | 1672 : super(listener); |
| 1668 | 1673 |
| 1669 int getChar(int position) => chunk[position]; | 1674 int getChar(int position) => chunk[position]; |
| 1670 | 1675 |
| 1671 String getString(int start, int end) { | 1676 String getString(int start, int end, int bits) { |
| 1677 const int maxAsciiChar = 0x7f; |
| 1678 if (bits <= maxAsciiChar) { |
| 1679 return new String.fromCharCodes(chunk, start, end); |
| 1680 } |
| 1672 beginString(); | 1681 beginString(); |
| 1673 if (start < end) addSliceToString(start, end); | 1682 if (start < end) addSliceToString(start, end); |
| 1674 String result = endString(); | 1683 String result = endString(); |
| 1675 return result; | 1684 return result; |
| 1676 } | 1685 } |
| 1677 | 1686 |
| 1678 void beginString() { | 1687 void beginString() { |
| 1679 this.buffer = new _Utf8StringBuffer(allowMalformed); | 1688 this.buffer = new _Utf8StringBuffer(allowMalformed); |
| 1680 } | 1689 } |
| 1681 | 1690 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1694 this.buffer = null; | 1703 this.buffer = null; |
| 1695 return buffer.toString(); | 1704 return buffer.toString(); |
| 1696 } | 1705 } |
| 1697 | 1706 |
| 1698 void copyCharsToList(int start, int end, List target, int offset) { | 1707 void copyCharsToList(int start, int end, List target, int offset) { |
| 1699 int length = end - start; | 1708 int length = end - start; |
| 1700 target.setRange(offset, offset + length, chunk, start); | 1709 target.setRange(offset, offset + length, chunk, start); |
| 1701 } | 1710 } |
| 1702 | 1711 |
| 1703 double parseDouble(int start, int end) { | 1712 double parseDouble(int start, int end) { |
| 1704 String string = getString(start, end); | 1713 String string = getString(start, end, 0x7f); |
| 1705 return _parseDouble(string, 0, string.length); | 1714 return _parseDouble(string, 0, string.length); |
| 1706 } | 1715 } |
| 1707 } | 1716 } |
| 1708 | 1717 |
| 1709 double _parseDouble(String source, int start, int end) | 1718 double _parseDouble(String source, int start, int end) |
| 1710 native "Double_parse"; | 1719 native "Double_parse"; |
| 1711 | 1720 |
| 1712 /** | 1721 /** |
| 1713 * Implements the chunked conversion from a UTF-8 encoding of JSON | 1722 * Implements the chunked conversion from a UTF-8 encoding of JSON |
| 1714 * to its corresponding object. | 1723 * to its corresponding object. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1745 _parser.parse(start); | 1754 _parser.parse(start); |
| 1746 } | 1755 } |
| 1747 | 1756 |
| 1748 void close() { | 1757 void close() { |
| 1749 _parser.close(); | 1758 _parser.close(); |
| 1750 var decoded = _parser.result; | 1759 var decoded = _parser.result; |
| 1751 _sink.add(decoded); | 1760 _sink.add(decoded); |
| 1752 _sink.close(); | 1761 _sink.close(); |
| 1753 } | 1762 } |
| 1754 } | 1763 } |
| OLD | NEW |