| 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; |
| 11 if (reviver == null) { | 11 if (reviver == null) { |
| 12 listener = new _BuildJsonListener(); | 12 listener = new _BuildJsonListener(); |
| 13 } else { | 13 } else { |
| 14 listener = new _ReviverJsonListener(reviver); | 14 listener = new _ReviverJsonListener(reviver); |
| 15 } | 15 } |
| 16 var parser = new _JsonStringParser(listener); | 16 var parser = new _JsonStringParser(listener); |
| 17 parser.chunk = json; | 17 parser.chunk = json; |
| 18 parser.chunkEnd = json.length; | 18 parser.chunkEnd = json.length; |
| 19 parser.parse(0); | 19 parser.parse(0); |
| 20 parser.close(); | 20 parser.close(); |
| 21 return listener.result; | 21 return listener.result; |
| 22 } | 22 } |
| 23 | 23 |
| 24 patch class Utf8Decoder { |
| 25 /* patch */ |
| 26 Converter<List<int>, dynamic> fuse(Converter<String, dynamic> next) { |
| 27 if (next is JsonDecoder) { |
| 28 return new _JsonUtf8Decoder(next._reviver, this._allowMalformed); |
| 29 } |
| 30 // TODO(lrn): Recognize a fused decoder where the next step is JsonDecoder. |
| 31 return super.fuse(next); |
| 32 } |
| 33 } |
| 34 |
| 35 class _JsonUtf8Decoder extends Converter<List<int>, Object> { |
| 36 final _Reviver _reviver; |
| 37 final bool _allowMalformed; |
| 38 |
| 39 _JsonUtf8Decoder(this._reviver, this._allowMalformed); |
| 40 |
| 41 dynamic convert(List<int> input) { |
| 42 var parser = _JsonUtf8DecoderSink._createParser(_reviver, _allowMalformed); |
| 43 parser.chunk = input; |
| 44 parser.chunkEnd = input.length; |
| 45 parser.parse(0); |
| 46 return parser.result; |
| 47 } |
| 48 |
| 49 ByteConversionSink startChunkedConversion(Sink<Object> sink) { |
| 50 return new _JsonUtf8DecoderSink(_reviver, sink, _allowMalformed); |
| 51 } |
| 52 } |
| 53 |
| 24 //// Implementation /////////////////////////////////////////////////////////// | 54 //// Implementation /////////////////////////////////////////////////////////// |
| 25 | 55 |
| 26 // Simple API for JSON parsing. | 56 // Simple API for JSON parsing. |
| 27 | 57 |
| 28 /** | 58 /** |
| 29 * Listener for parsing events from [_ChunkedJsonParser]. | 59 * Listener for parsing events from [_ChunkedJsonParser]. |
| 30 */ | 60 */ |
| 31 abstract class _JsonListener { | 61 abstract class _JsonListener { |
| 32 void handleString(String value) {} | 62 void handleString(String value) {} |
| 33 void handleNumber(num value) {} | 63 void handleNumber(num value) {} |
| (...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 */ | 783 */ |
| 754 void parse(int position) { | 784 void parse(int position) { |
| 755 int length = chunkEnd; | 785 int length = chunkEnd; |
| 756 if (partialState != NO_PARTIAL) { | 786 if (partialState != NO_PARTIAL) { |
| 757 position = parsePartial(position); | 787 position = parsePartial(position); |
| 758 if (position == length) return; | 788 if (position == length) return; |
| 759 } | 789 } |
| 760 int state = this.state; | 790 int state = this.state; |
| 761 while (position < length) { | 791 while (position < length) { |
| 762 int char = getChar(position); | 792 int char = getChar(position); |
| 793 if (char == null) { |
| 794 print("[[[$chunk]]] - $position - ${chunk.runtimeType}"); |
| 795 } |
| 763 switch (char) { | 796 switch (char) { |
| 764 case SPACE: | 797 case SPACE: |
| 765 case CARRIAGE_RETURN: | 798 case CARRIAGE_RETURN: |
| 766 case NEWLINE: | 799 case NEWLINE: |
| 767 case TAB: | 800 case TAB: |
| 768 position++; | 801 position++; |
| 769 break; | 802 break; |
| 770 case QUOTE: | 803 case QUOTE: |
| 771 if ((state & ALLOW_STRING_MASK) != 0) return fail(position); | 804 if ((state & ALLOW_STRING_MASK) != 0) return fail(position); |
| 772 state |= VALUE_READ_BITS; | 805 state |= VALUE_READ_BITS; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 listener.endObject(); | 873 listener.endObject(); |
| 841 } else { | 874 } else { |
| 842 return fail(position); | 875 return fail(position); |
| 843 } | 876 } |
| 844 state = restoreState() | VALUE_READ_BITS; | 877 state = restoreState() | VALUE_READ_BITS; |
| 845 position++; | 878 position++; |
| 846 break; | 879 break; |
| 847 default: | 880 default: |
| 848 if ((state & ALLOW_VALUE_MASK) != 0) fail(position); | 881 if ((state & ALLOW_VALUE_MASK) != 0) fail(position); |
| 849 state |= VALUE_READ_BITS; | 882 state |= VALUE_READ_BITS; |
| 883 if (char == null) print("$chunk - $position"); |
| 850 position = parseNumber(char, position); | 884 position = parseNumber(char, position); |
| 851 break; | 885 break; |
| 852 } | 886 } |
| 853 } | 887 } |
| 854 this.state = state; | 888 this.state = state; |
| 855 } | 889 } |
| 856 | 890 |
| 857 /** | 891 /** |
| 858 * Parses a "true" literal starting at [position]. | 892 * Parses a "true" literal starting at [position]. |
| 859 * | 893 * |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1233 char = getChar(position); | 1267 char = getChar(position); |
| 1234 digit = char ^ CHAR_0; | 1268 digit = char ^ CHAR_0; |
| 1235 } while (digit <= 9); | 1269 } while (digit <= 9); |
| 1236 intValue += expSign * exponent; | 1270 intValue += expSign * exponent; |
| 1237 } | 1271 } |
| 1238 } | 1272 } |
| 1239 if (!isDouble) { | 1273 if (!isDouble) { |
| 1240 listener.handleNumber(sign * intValue); | 1274 listener.handleNumber(sign * intValue); |
| 1241 return position; | 1275 return position; |
| 1242 } | 1276 } |
| 1243 // Double values at or above this value (2**53) may have lost precission. | 1277 // Double values at or above this value (2 ** 53) may have lost precission. |
| 1244 // Only trust results that are below this value. | 1278 // Only trust results that are below this value. |
| 1245 const double maxExactDouble = 9007199254740992.0; | 1279 const double maxExactDouble = 9007199254740992.0; |
| 1246 if (doubleValue < maxExactDouble) { | 1280 if (doubleValue < maxExactDouble) { |
| 1247 int exponent = intValue; | 1281 int exponent = intValue; |
| 1248 double signedMantissa = doubleValue * sign; | 1282 double signedMantissa = doubleValue * sign; |
| 1249 if (exponent >= -22) { | 1283 if (exponent >= -22) { |
| 1250 if (exponent < 0) { | 1284 if (exponent < 0) { |
| 1251 listener.handleNumber(signedMantissa / POWERS_OF_TEN[-exponent]); | 1285 listener.handleNumber(signedMantissa / POWERS_OF_TEN[-exponent]); |
| 1252 return position; | 1286 return position; |
| 1253 } | 1287 } |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1711 _parser.parse(start); | 1745 _parser.parse(start); |
| 1712 } | 1746 } |
| 1713 | 1747 |
| 1714 void close() { | 1748 void close() { |
| 1715 _parser.close(); | 1749 _parser.close(); |
| 1716 var decoded = _parser.result; | 1750 var decoded = _parser.result; |
| 1717 _sink.add(decoded); | 1751 _sink.add(decoded); |
| 1718 _sink.close(); | 1752 _sink.close(); |
| 1719 } | 1753 } |
| 1720 } | 1754 } |
| OLD | NEW |