| Index: sdk/lib/convert/json.dart
|
| diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
|
| index 845d53fc791a0c1c883b8c2f3b8f0cab5c24f9b4..9780200836a060e892e8ef7644df49c4dda5e5b2 100644
|
| --- a/sdk/lib/convert/json.dart
|
| +++ b/sdk/lib/convert/json.dart
|
| @@ -90,6 +90,21 @@ class JsonCodec extends Codec<Object, String> {
|
| return new JsonDecoder(reviver).convert(str);
|
| }
|
|
|
| + /**
|
| + * Converts [value] to a JSON string.
|
| + *
|
| + * If value contains objects that are not directly encodable to a JSON
|
| + * string (a value that is not a number, boolean, string, null, list or a map
|
| + * with string keys), the [toEncodable] function is used to convert it to an
|
| + * object that must be directly encodable.
|
| + *
|
| + * If [toEncodable] is omitted, it defaults to calling `.toJson()` on the
|
| + * unencodable object.
|
| + */
|
| + Object encode(Object value, {toEncodable(var object)}) {
|
| + return new JsonEncoder(toEncodable).convert(value);
|
| + }
|
| +
|
| JsonEncoder get encoder => new JsonEncoder();
|
| JsonDecoder get decoder => new JsonDecoder(null);
|
| }
|
| @@ -112,7 +127,22 @@ class _ReviverJsonCodec extends JsonCodec {
|
| * This class converts JSON objects to strings.
|
| */
|
| class JsonEncoder extends Converter<Object, String> {
|
| - JsonEncoder();
|
| + final _toEncodableFunction;
|
| +
|
| + /**
|
| + * Creates a JSON encoder.
|
| + *
|
| + * The JSON encoder handles numbers, strings, booleans, null, lists and
|
| + * maps directly.
|
| + *
|
| + * Any other object is attempted converted by [toEncodable] to an
|
| + * object that is of one of the convertible types.
|
| + *
|
| + * If [toEncodable] is omitted, it defaults to calling `.toJson()` on
|
| + * the object.
|
| + */
|
| + JsonEncoder([Object toEncodable(Object nonSerializable)])
|
| + : this._toEncodableFunction = toEncodable;
|
|
|
| /**
|
| * Converts the given object [o] to its JSON representation.
|
| @@ -122,14 +152,14 @@ class JsonEncoder extends Converter<Object, String> {
|
| * For [List], the elements must all be serializable.
|
| * For [Map], the keys must be [String] and the values must be serializable.
|
| *
|
| - * If a value is any other type is attempted serialized, a "toJson()" method
|
| - * is invoked on the object and the result, which must be a directly
|
| - * serializable value, is serialized instead of the original value.
|
| + * If a value is any other type is attempted serialized, the conversion
|
| + * function provided in the constructor is invoked with the object as argument
|
| + * and the result, which must be a directly serializable value,
|
| + * is serialized instead of the original value.
|
| *
|
| - * If the object does not support this method, throws, or returns a
|
| - * value that is not directly serializable, a [JsonUnsupportedObjectError]
|
| - * exception is thrown. If the call throws (including the case where there
|
| - * is no nullary "toJson" method, the error is caught and stored in the
|
| + * If the conversion throws, or returns a value that is not directly
|
| + * serializable, a [JsonUnsupportedObjectError] exception is thrown.
|
| + * If the call throws, the error is caught and stored in the
|
| * [JsonUnsupportedObjectError]'s [:cause:] field.
|
| *
|
| * If a [List] or [Map] contains a reference to itself, directly or through
|
| @@ -141,7 +171,7 @@ class JsonEncoder extends Converter<Object, String> {
|
| * the JSON text for it. I.e., if an object changes after it is first
|
| * serialized, the new values may or may not be reflected in the result.
|
| */
|
| - String convert(Object o) => OLD_JSON_LIB.stringify(o);
|
| + String convert(Object o) => OLD_JSON_LIB.stringify(o, _toEncodableFunction);
|
|
|
| /**
|
| * Starts a chunked conversion.
|
| @@ -157,7 +187,7 @@ class JsonEncoder extends Converter<Object, String> {
|
| if (sink is! StringConversionSink) {
|
| sink = new StringConversionSink.from(sink);
|
| }
|
| - return new _JsonEncoderSink(sink);
|
| + return new _JsonEncoderSink(sink, _toEncodableFunction);
|
| }
|
|
|
| // Override the base-classes bind, to provide a better type.
|
| @@ -170,10 +200,11 @@ class JsonEncoder extends Converter<Object, String> {
|
| * The sink only accepts one value, but will produce output in a chunked way.
|
| */
|
| class _JsonEncoderSink extends ChunkedConversionSink<Object> {
|
| + final Function _toEncodableFunction;
|
| final StringConversionSink _sink;
|
| bool _isDone = false;
|
|
|
| - _JsonEncoderSink(this._sink);
|
| + _JsonEncoderSink(this._sink, this._toEncodableFunction);
|
|
|
| /**
|
| * Encodes the given object [o].
|
| @@ -188,7 +219,7 @@ class _JsonEncoderSink extends ChunkedConversionSink<Object> {
|
| }
|
| _isDone = true;
|
| ClosableStringSink stringSink = _sink.asStringSink();
|
| - OLD_JSON_LIB.printOn(o, stringSink);
|
| + OLD_JSON_LIB.printOn(o, stringSink, _toEncodableFunction);
|
| stringSink.close();
|
| }
|
|
|
|
|