Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: runtime/lib/convert_patch.dart

Issue 689043002: Make JSON.fuse(UTF8) be more efficient by not creating intermediate string. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/js_lib/convert_patch.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/js_lib/convert_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698