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

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

Issue 25548010: Make JSON encoder take extra function argument to use instead of toJson calls. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rename convert function to "toEncodable". Created 7 years, 2 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 | « pkg/json/lib/json.dart ('k') | sdk/lib/json/json.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 * Error thrown by JSON serialization if an object cannot be serialized. 8 * Error thrown by JSON serialization if an object cannot be serialized.
9 * 9 *
10 * The [unsupportedObject] field holds that object that failed to be serialized. 10 * The [unsupportedObject] field holds that object that failed to be serialized.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 * property that has been parsed during decoding. The `key` argument is either 83 * property that has been parsed during decoding. The `key` argument is either
84 * the integer list index for a list property, the map string for object 84 * the integer list index for a list property, the map string for object
85 * properties, or `null` for the final result. 85 * properties, or `null` for the final result.
86 * 86 *
87 * The default [reviver] (when not provided) is the identity function. 87 * The default [reviver] (when not provided) is the identity function.
88 */ 88 */
89 Object decode(String str, {reviver(var key, var value)}) { 89 Object decode(String str, {reviver(var key, var value)}) {
90 return new JsonDecoder(reviver).convert(str); 90 return new JsonDecoder(reviver).convert(str);
91 } 91 }
92 92
93 /**
94 * Converts [value] to a JSON string.
95 *
96 * If value contains objects that are not directly encodable to a JSON
97 * string (a value that is not a number, boolean, string, null, list or a map
98 * with string keys), the [toEncodable] function is used to convert it to an
99 * object that must be directly encodable.
100 *
101 * If [toEncodable] is omitted, it defaults to calling `.toJson()` on the
102 * unencodable object.
103 */
104 Object encode(Object value, {toEncodable(var object)}) {
105 return new JsonEncoder(toEncodable).convert(value);
106 }
107
93 JsonEncoder get encoder => new JsonEncoder(); 108 JsonEncoder get encoder => new JsonEncoder();
94 JsonDecoder get decoder => new JsonDecoder(null); 109 JsonDecoder get decoder => new JsonDecoder(null);
95 } 110 }
96 111
97 typedef _Reviver(var key, var value); 112 typedef _Reviver(var key, var value);
98 113
99 class _ReviverJsonCodec extends JsonCodec { 114 class _ReviverJsonCodec extends JsonCodec {
100 final _Reviver _reviver; 115 final _Reviver _reviver;
101 _ReviverJsonCodec(this._reviver); 116 _ReviverJsonCodec(this._reviver);
102 117
103 Object decode(String str, {reviver(var key, var value)}) { 118 Object decode(String str, {reviver(var key, var value)}) {
104 if (reviver == null) reviver = _reviver; 119 if (reviver == null) reviver = _reviver;
105 return new JsonDecoder(reviver).convert(str); 120 return new JsonDecoder(reviver).convert(str);
106 } 121 }
107 122
108 JsonDecoder get decoder => new JsonDecoder(_reviver); 123 JsonDecoder get decoder => new JsonDecoder(_reviver);
109 } 124 }
110 125
111 /** 126 /**
112 * This class converts JSON objects to strings. 127 * This class converts JSON objects to strings.
113 */ 128 */
114 class JsonEncoder extends Converter<Object, String> { 129 class JsonEncoder extends Converter<Object, String> {
115 JsonEncoder(); 130 final _toEncodableFunction;
131
132 /**
133 * Creates a JSON encoder.
134 *
135 * The JSON encoder handles numbers, strings, booleans, null, lists and
136 * maps directly.
137 *
138 * Any other object is attempted converted by [toEncodable] to an
139 * object that is of one of the convertible types.
140 *
141 * If [toEncodable] is omitted, it defaults to calling `.toJson()` on
142 * the object.
143 */
144 JsonEncoder([Object toEncodable(Object nonSerializable)])
145 : this._toEncodableFunction = toEncodable;
116 146
117 /** 147 /**
118 * Converts the given object [o] to its JSON representation. 148 * Converts the given object [o] to its JSON representation.
119 * 149 *
120 * Directly serializable values are [num], [String], [bool], and [Null], as 150 * Directly serializable values are [num], [String], [bool], and [Null], as
121 * well as some [List] and [Map] values. 151 * well as some [List] and [Map] values.
122 * For [List], the elements must all be serializable. 152 * For [List], the elements must all be serializable.
123 * For [Map], the keys must be [String] and the values must be serializable. 153 * For [Map], the keys must be [String] and the values must be serializable.
124 * 154 *
125 * If a value is any other type is attempted serialized, a "toJson()" method 155 * If a value is any other type is attempted serialized, the conversion
126 * is invoked on the object and the result, which must be a directly 156 * function provided in the constructor is invoked with the object as argument
127 * serializable value, is serialized instead of the original value. 157 * and the result, which must be a directly serializable value,
158 * is serialized instead of the original value.
128 * 159 *
129 * If the object does not support this method, throws, or returns a 160 * If the conversion throws, or returns a value that is not directly
130 * value that is not directly serializable, a [JsonUnsupportedObjectError] 161 * serializable, a [JsonUnsupportedObjectError] exception is thrown.
131 * exception is thrown. If the call throws (including the case where there 162 * If the call throws, the error is caught and stored in the
132 * is no nullary "toJson" method, the error is caught and stored in the
133 * [JsonUnsupportedObjectError]'s [:cause:] field. 163 * [JsonUnsupportedObjectError]'s [:cause:] field.
134 * 164 *
135 * If a [List] or [Map] contains a reference to itself, directly or through 165 * If a [List] or [Map] contains a reference to itself, directly or through
136 * other lists or maps, it cannot be serialized and a [JsonCyclicError] is 166 * other lists or maps, it cannot be serialized and a [JsonCyclicError] is
137 * thrown. 167 * thrown.
138 * 168 *
139 * Json Objects should not change during serialization. 169 * Json Objects should not change during serialization.
140 * If an object is serialized more than once, [stringify] is allowed to cache 170 * If an object is serialized more than once, [stringify] is allowed to cache
141 * the JSON text for it. I.e., if an object changes after it is first 171 * the JSON text for it. I.e., if an object changes after it is first
142 * serialized, the new values may or may not be reflected in the result. 172 * serialized, the new values may or may not be reflected in the result.
143 */ 173 */
144 String convert(Object o) => OLD_JSON_LIB.stringify(o); 174 String convert(Object o) => OLD_JSON_LIB.stringify(o, _toEncodableFunction);
145 175
146 /** 176 /**
147 * Starts a chunked conversion. 177 * Starts a chunked conversion.
148 * 178 *
149 * The converter works more efficiently if the given [sink] is a 179 * The converter works more efficiently if the given [sink] is a
150 * [StringConversionSink]. 180 * [StringConversionSink].
151 * 181 *
152 * Returns a chunked-conversion sink that accepts at most one object. It is 182 * Returns a chunked-conversion sink that accepts at most one object. It is
153 * an error to invoke `add` more than once on the returned sink. 183 * an error to invoke `add` more than once on the returned sink.
154 */ 184 */
155 ChunkedConversionSink<Object> startChunkedConversion( 185 ChunkedConversionSink<Object> startChunkedConversion(
156 ChunkedConversionSink<String> sink) { 186 ChunkedConversionSink<String> sink) {
157 if (sink is! StringConversionSink) { 187 if (sink is! StringConversionSink) {
158 sink = new StringConversionSink.from(sink); 188 sink = new StringConversionSink.from(sink);
159 } 189 }
160 return new _JsonEncoderSink(sink); 190 return new _JsonEncoderSink(sink, _toEncodableFunction);
161 } 191 }
162 192
163 // Override the base-classes bind, to provide a better type. 193 // Override the base-classes bind, to provide a better type.
164 Stream<String> bind(Stream<Object> stream) => super.bind(stream); 194 Stream<String> bind(Stream<Object> stream) => super.bind(stream);
165 } 195 }
166 196
167 /** 197 /**
168 * Implements the chunked conversion from object to its JSON representation. 198 * Implements the chunked conversion from object to its JSON representation.
169 * 199 *
170 * The sink only accepts one value, but will produce output in a chunked way. 200 * The sink only accepts one value, but will produce output in a chunked way.
171 */ 201 */
172 class _JsonEncoderSink extends ChunkedConversionSink<Object> { 202 class _JsonEncoderSink extends ChunkedConversionSink<Object> {
203 final Function _toEncodableFunction;
173 final StringConversionSink _sink; 204 final StringConversionSink _sink;
174 bool _isDone = false; 205 bool _isDone = false;
175 206
176 _JsonEncoderSink(this._sink); 207 _JsonEncoderSink(this._sink, this._toEncodableFunction);
177 208
178 /** 209 /**
179 * Encodes the given object [o]. 210 * Encodes the given object [o].
180 * 211 *
181 * It is an error to invoke this method more than once on any instance. While 212 * It is an error to invoke this method more than once on any instance. While
182 * this makes the input effectly non-chunked the output will be generated in 213 * this makes the input effectly non-chunked the output will be generated in
183 * a chunked way. 214 * a chunked way.
184 */ 215 */
185 void add(Object o) { 216 void add(Object o) {
186 if (_isDone) { 217 if (_isDone) {
187 throw new StateError("Only one call to add allowed"); 218 throw new StateError("Only one call to add allowed");
188 } 219 }
189 _isDone = true; 220 _isDone = true;
190 ClosableStringSink stringSink = _sink.asStringSink(); 221 ClosableStringSink stringSink = _sink.asStringSink();
191 OLD_JSON_LIB.printOn(o, stringSink); 222 OLD_JSON_LIB.printOn(o, stringSink, _toEncodableFunction);
192 stringSink.close(); 223 stringSink.close();
193 } 224 }
194 225
195 void close() { /* do nothing */ } 226 void close() { /* do nothing */ }
196 } 227 }
197 228
198 /** 229 /**
199 * This class parses JSON strings and builds the corresponding objects. 230 * This class parses JSON strings and builds the corresponding objects.
200 */ 231 */
201 class JsonDecoder extends Converter<String, Object> { 232 class JsonDecoder extends Converter<String, Object> {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 String accumulated = buffer.toString(); 290 String accumulated = buffer.toString();
260 buffer.clear(); 291 buffer.clear();
261 Object decoded = _parseJson(accumulated, _reviver); 292 Object decoded = _parseJson(accumulated, _reviver);
262 _chunkedSink.add(decoded); 293 _chunkedSink.add(decoded);
263 _chunkedSink.close(); 294 _chunkedSink.close();
264 } 295 }
265 } 296 }
266 297
267 // Internal optimized JSON parsing implementation. 298 // Internal optimized JSON parsing implementation.
268 external _parseJson(String source, reviver(key, value)); 299 external _parseJson(String source, reviver(key, value));
OLDNEW
« no previous file with comments | « pkg/json/lib/json.dart ('k') | sdk/lib/json/json.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698