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

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
« no previous file with comments | « sdk/lib/convert/encoding.dart ('k') | sdk/lib/convert/string_conversion.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) 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 * The default [reviver] (when not provided) is the identity function. 46 * The default [reviver] (when not provided) is the identity function.
47 */ 47 */
48 Object decode(String str, {reviver(var key, var value)}) { 48 Object decode(String str, {reviver(var key, var value)}) {
49 return new JsonDecoder(reviver).convert(str); 49 return new JsonDecoder(reviver).convert(str);
50 } 50 }
51 51
52 JsonEncoder get encoder => new JsonEncoder(); 52 JsonEncoder get encoder => new JsonEncoder();
53 JsonDecoder get decoder => new JsonDecoder(null); 53 JsonDecoder get decoder => new JsonDecoder(null);
54 } 54 }
55 55
56 typedef _Reviver(var key, var value);
57
56 class _ReviverJsonCodec extends JsonCodec { 58 class _ReviverJsonCodec extends JsonCodec {
57 final Function _reviver; 59 final _Reviver _reviver;
58 _ReviverJsonCodec(this._reviver); 60 _ReviverJsonCodec(this._reviver);
59 61
60 Object decode(String str, {reviver(var key, var value)}) { 62 Object decode(String str, {reviver(var key, var value)}) {
61 if (reviver == null) reviver = _reviver; 63 if (reviver == null) reviver = _reviver;
62 return new JsonDecoder(reviver).convert(str); 64 return new JsonDecoder(reviver).convert(str);
63 } 65 }
64 66
65 JsonDecoder get decoder => new JsonDecoder(_reviver); 67 JsonDecoder get decoder => new JsonDecoder(_reviver);
66 } 68 }
67 69
68 /** 70 /**
69 * A [JsonEncoder] converts JSON objects to strings. 71 * This class converts JSON objects to strings.
70 */ 72 */
71 class JsonEncoder extends Converter<Object, String> { 73 class JsonEncoder extends Converter<Object, String> {
72 JsonEncoder(); 74 JsonEncoder();
73 75
74 /** 76 /**
75 * Converts the given object [o] to its JSON representation. 77 * Converts the given object [o] to its JSON representation.
76 * 78 *
77 * Directly serializable values are [num], [String], [bool], and [Null], as 79 * Directly serializable values are [num], [String], [bool], and [Null], as
78 * well as some [List] and [Map] values. 80 * well as some [List] and [Map] values.
79 * For [List], the elements must all be serializable. 81 * 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 94 * 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 95 * other lists or maps, it cannot be serialized and a [JsonCyclicError] is
94 * thrown. 96 * thrown.
95 * 97 *
96 * Json Objects should not change during serialization. 98 * Json Objects should not change during serialization.
97 * If an object is serialized more than once, [stringify] is allowed to cache 99 * 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 100 * 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. 101 * serialized, the new values may or may not be reflected in the result.
100 */ 102 */
101 String convert(Object o) => OLD_JSON_LIB.stringify(o); 103 String convert(Object o) => OLD_JSON_LIB.stringify(o);
104
105 /**
106 * Starts a chunked conversion.
107 *
108 * The converter works more efficiently if the given [sink] is a
109 * [StringConversionSink].
110 *
111 * Returns a chunked-conversion sink that accepts at most one object. It is
112 * an error to invoke `add` more than once on the returned sink.
113 */
114 ChunkedConversionSink<Object> startChunkedConversion(
115 ChunkedConversionSink<String> sink) {
116 if (sink is! StringConversionSink) {
117 sink = new StringConversionSink.from(sink);
118 }
119 return new _JsonEncoderSink(sink);
120 }
102 } 121 }
103 122
104 typedef _Reviver(var key, var value); 123 /**
124 * Implements the chunked conversion from object to its JSON representation.
125 *
126 * The sink only accepts one value, but will produce output in a chunked way.
127 */
128 class _JsonEncoderSink extends ChunkedConversionSink<Object> {
129 final StringConversionSink _sink;
130 bool _isDone = false;
105 131
132 _JsonEncoderSink(this._sink);
133
134 /**
135 * Encodes the given object [o].
136 *
137 * It is an error to invoke this method more than once on any instance. While
138 * this makes the input effectly non-chunked the output will be generated in
139 * a chunked way.
140 */
141 void add(Object o) {
142 if (_isDone) {
143 throw new StateError("Only one call to add allowed");
144 }
145 _isDone = true;
146 ClosableStringSink stringSink = _sink.asStringSink();
147 OLD_JSON_LIB.printOn(o, stringSink);
148 stringSink.close();
149 }
150
151 void close() { /* do nothing */ }
152 }
106 153
107 /** 154 /**
108 * A [JsonDecoder] parses JSON strings and builds the corresponding objects. 155 * This class parses JSON strings and builds the corresponding objects.
109 */ 156 */
110 class JsonDecoder extends Converter<String, Object> { 157 class JsonDecoder extends Converter<String, Object> {
111 final _Reviver _reviver; 158 final _Reviver _reviver;
112 /** 159 /**
113 * Constructs a new JsonDecoder. 160 * Constructs a new JsonDecoder.
114 * 161 *
115 * The [reviver] may be `null`. 162 * The [reviver] may be `null`.
116 */ 163 */
117 JsonDecoder(reviver(var key, var value)) : this._reviver = reviver; 164 JsonDecoder(reviver(var key, var value)) : this._reviver = reviver;
118 165
119 /** 166 /**
120 * Converts the given Json-string [input] to its corresponding object. 167 * Converts the given JSON-string [input] to its corresponding object.
121 * 168 *
122 * Parsed JSON values are of the types [num], [String], [bool], [Null], 169 * 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 170 * [List]s of parsed JSON values or [Map]s from [String] to parsed
124 * JSON values. 171 * JSON values.
125 * 172 *
126 * If `this` was initialized with a reviver, then the parsing operation 173 * 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. 174 * 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 175 * 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 176 * 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. 177 * the value of that property instead the parsed value.
131 * 178 *
132 * Throws [FormatException] if the input is not valid JSON text. 179 * Throws [FormatException] if the input is not valid JSON text.
133 */ 180 */
134 Object convert(String input) => OLD_JSON_LIB.parse(input, _reviver); 181 Object convert(String input) => OLD_JSON_LIB.parse(input, _reviver);
182
183 /**
184 * Starts a conversion from a chunked JSON string to its corresponding
185 * object.
186 *
187 * The output [sink] receives exactly one decoded element through `add`.
188 */
189 StringConversionSink startChunkedConversion(
190 ChunkedConversionSink<Object> sink) {
191 return new _JsonDecoderSink(_reviver, sink);
192 }
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
« no previous file with comments | « sdk/lib/convert/encoding.dart ('k') | sdk/lib/convert/string_conversion.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698