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

Side by Side Diff: sdk/lib/convert/json.dart

Issue 19883003: Add chunked conversion to converters. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 7 years, 4 months 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
OLDNEW
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 part of dart.convert; 5 part of dart.convert;
6 6
7 /** 7 /**
8 * An instance of the default implementation of the [JsonCodec]. 8 * An instance of the default implementation of the [JsonCodec].
9 * 9 *
10 * This instance provides a convenient access to the most common JSON 10 * This instance provides a convenient access to the most common JSON
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 59
60 Object decode(String str, {reviver(var key, var value)}) { 60 Object decode(String str, {reviver(var key, var value)}) {
61 if (reviver == null) reviver = _reviver; 61 if (reviver == null) reviver = _reviver;
62 return new JsonDecoder(reviver).convert(str); 62 return new JsonDecoder(reviver).convert(str);
63 } 63 }
64 64
65 JsonDecoder get decoder => new JsonDecoder(_reviver); 65 JsonDecoder get decoder => new JsonDecoder(_reviver);
66 } 66 }
67 67
68 /** 68 /**
69 * A [JsonEncoder] converts JSON objects to strings. 69 * This class converts JSON objects to strings.
70 */ 70 */
71 class JsonEncoder extends Converter<Object, String> { 71 class JsonEncoder extends Converter<Object, String> {
72 JsonEncoder(); 72 JsonEncoder();
73 73
74 /** 74 /**
75 * Converts the given object [o] to its JSON representation. 75 * Converts the given object [o] to its JSON representation.
76 * 76 *
77 * Directly serializable values are [num], [String], [bool], and [Null], as 77 * Directly serializable values are [num], [String], [bool], and [Null], as
78 * well as some [List] and [Map] values. 78 * well as some [List] and [Map] values.
79 * For [List], the elements must all be serializable. 79 * For [List], the elements must all be serializable.
(...skipping 12 matching lines...) Expand all
92 * If a [List] or [Map] contains a reference to itself, directly or through 92 * If a [List] or [Map] contains a reference to itself, directly or through
93 * other lists or maps, it cannot be serialized and a [JsonCyclicError] is 93 * other lists or maps, it cannot be serialized and a [JsonCyclicError] is
94 * thrown. 94 * thrown.
95 * 95 *
96 * Json Objects should not change during serialization. 96 * Json Objects should not change during serialization.
97 * If an object is serialized more than once, [stringify] is allowed to cache 97 * If an object is serialized more than once, [stringify] is allowed to cache
98 * the JSON text for it. I.e., if an object changes after it is first 98 * the JSON text for it. I.e., if an object changes after it is first
99 * serialized, the new values may or may not be reflected in the result. 99 * serialized, the new values may or may not be reflected in the result.
100 */ 100 */
101 String convert(Object o) => OLD_JSON_LIB.stringify(o); 101 String convert(Object o) => OLD_JSON_LIB.stringify(o);
102
103 ChunkedConversionSink<Object> startChunkedConversion(
104 ChunkedConversionSink sink) {
105 return new _JsonEncoderSink(sink.adaptTo(outputInterface));
106 }
107
108 ChunkedConversionInterface get inputInterface =>
109 ChunkedConversionSink.INTERFACE;
110 ChunkedConversionInterface get outputInterface =>
111 StringConversionSink.INTERFACE;
102 } 112 }
103 113
114 /**
115 * Implements the chunked conversion from object to its JSON representation.
116 *
117 * The sink only accepts one value, but will produce output in a chunked way.
118 */
119 class _JsonEncoderSink extends ChunkedConversionSink<Object> {
120 final StringConversionSink _sink;
121 bool _isDone = false;
122
123 _JsonEncoderSink(this._sink);
124
125 /**
126 * Encodes the given object [o].
127 *
128 * It is an error to invoke this method more than once on any instance. While
129 * this makes the input effectly non-chunked the output will be generated in
130 * a chunked way.
131 */
132 void add(Object o) {
133 if (_isDone) {
134 throw new StateError("Only one call to add allowed");
135 }
136 _isDone = true;
137 ClosableStringSink stringSink = _sink.asStringSink();
138 OLD_JSON_LIB.printOn(o, stringSink);
139 stringSink.close();
140 }
141
142 void close() { /* do nothing */ }
143 }
144
145
104 typedef _Reviver(var key, var value); 146 typedef _Reviver(var key, var value);
105 147
106
107 /** 148 /**
108 * A [JsonDecoder] parses JSON strings and builds the corresponding objects. 149 * This class parses JSON strings and builds the corresponding objects.
109 */ 150 */
110 class JsonDecoder extends Converter<String, Object> { 151 class JsonDecoder extends Converter<String, Object> {
111 final _Reviver _reviver; 152 final _Reviver _reviver;
112 /** 153 /**
113 * Constructs a new JsonDecoder. 154 * Constructs a new JsonDecoder.
114 * 155 *
115 * The [reviver] may be `null`. 156 * The [reviver] may be `null`.
116 */ 157 */
117 JsonDecoder(reviver(var key, var value)) : this._reviver = reviver; 158 JsonDecoder(reviver(var key, var value)) : this._reviver = reviver;
118 159
119 /** 160 /**
120 * Converts the given Json-string [input] to its corresponding object. 161 * Converts the given JSON-string [input] to its corresponding object.
121 * 162 *
122 * Parsed JSON values are of the types [num], [String], [bool], [Null], 163 * Parsed JSON values are of the types [num], [String], [bool], [Null],
123 * [List]s of parsed JSON values or [Map]s from [String] to parsed 164 * [List]s of parsed JSON values or [Map]s from [String] to parsed
124 * JSON values. 165 * JSON values.
125 * 166 *
126 * If `this` was initialized with a reviver, then the parsing operation 167 * If `this` was initialized with a reviver, then the parsing operation
127 * invokes the reviver on every object or list property that has been parsed. 168 * invokes the reviver on every object or list property that has been parsed.
128 * The arguments are the property name ([String]) or list index ([int]), and 169 * The arguments are the property name ([String]) or list index ([int]), and
129 * the value is the parsed value. The return value of the reviver is used as 170 * the value is the parsed value. The return value of the reviver is used as
130 * the value of that property instead the parsed value. 171 * the value of that property instead the parsed value.
131 * 172 *
132 * Throws [FormatException] if the input is not valid JSON text. 173 * Throws [FormatException] if the input is not valid JSON text.
133 */ 174 */
134 Object convert(String input) => OLD_JSON_LIB.parse(input, _reviver); 175 Object convert(String input) => OLD_JSON_LIB.parse(input, _reviver);
176
177 /**
178 * Starts a conversion from a chunked JSON string to its corresponding
179 * object.
180 *
181 * The output [sink] receives exactly one decoded element through `add`.
182 */
183 StringConversionSink startChunkedConversion(ChunkedConversionSink sink) {
184 // In theory we don't need to go through the `adaptTo` dance, but it
185 // shouldn't hurt.
186 return new _JsonDecoderSink(_reviver, sink.adaptTo(outputInterface));
187 }
188
189 ChunkedConversionInterface get inputInterface =>
190 StringConversionSink.INTERFACE;
191 ChunkedConversionInterface get outputInterface =>
192 ChunkedConversionSink.INTERFACE;
135 } 193 }
194
195 /**
196 * Implements the chunked conversion from a JSON string to its corresponding
197 * object.
198 *
199 * The sink only creates one object, but its input can be chunked.
200 */
201 // TODO(floitsch): don't accumulate everything before starting to decode.
202 class _JsonDecoderSink extends _StringSinkConversionSink {
203 final _Reviver _reviver;
204 final ChunkedConversionSink<Object> _chunkedSink;
205
206 _JsonDecoderSink(this._reviver, this._chunkedSink)
207 : super(new StringBuffer());
208
209 void close() {
210 super.close();
211 StringBuffer buffer = _stringSink;
212 String accumulated = buffer.toString();
213 buffer.clear();
214 Object decoded = OLD_JSON_LIB.parse(accumulated, _reviver);
215 _chunkedSink.add(decoded);
216 _chunkedSink.close();
217 }
218 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698