Add jsonDecode, jsonEncode, base64Decode, base64Encode, base64UrlEncode functions.

Change-Id: Ic65ada3b107cc8e6c3459459c4bea389feef2168
Reviewed-on: https://dart-review.googlesource.com/23664
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
This commit is contained in:
Lasse Reichstein Holst Nielsen 2018-03-12 09:16:27 +00:00 committed by commit-bot@chromium.org
parent 6cef6625ef
commit 414a3318ea
5 changed files with 80 additions and 5 deletions

View file

@ -1,10 +1,13 @@
### Core library changes
* Temporarily disabled the `whereType` method until generic methods are enabled
on all platforms ([issue 32463]).
[issue 32463]: https://github.com/dart-lang/sdk/issues/32463
* `dart:core`
* Temporarily disabled the `whereType` method until generic methods are
enabled on all platforms
([issue 32463](https://github.com/dart-lang/sdk/issues/32463)).
* `dart:convert`
* Added `jsonEncode`, `jsonDecode`, `base64Encode`, `base64UrlEncode` and
`base64Decode` top-level functions.
## 2.0.0

View file

@ -38,6 +38,27 @@ const Base64Codec base64Url = const Base64Codec.urlSafe();
@Deprecated("Use base64Url instead")
const Base64Codec BASE64URL = base64Url;
/**
* Encodes [bytes] using [base64](https://tools.ietf.org/html/rfc4648) encoding.
*
* Shorthand for [base64.encode].
*/
String base64Encode(List<int> bytes) => base64.encode(bytes);
/**
* Encodes [bytes] using [base64url](https://tools.ietf.org/html/rfc4648) encoding.
*
* Shorthand for [base64url.encode].
*/
String base64UrlEncode(List<int> bytes) => base64Url.encode(bytes);
/**
* Decodes [base64](https://tools.ietf.org/html/rfc4648) or [base64url](https://tools.ietf.org/html/rfc4648) encoded bytes.
*
* Shorthand for [base64.decode].
*/
List<int> base64Decode(String source) => base64.decode(source);
// Constants used in more than one class.
const int _paddingChar = 0x3d; // '='.

View file

@ -69,6 +69,37 @@ const JsonCodec json = const JsonCodec();
@Deprecated("Use json instead")
const JsonCodec JSON = json;
/**
* 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 a function that returns the
* result of calling `.toJson()` on the unencodable object.
*
* Shorthand for [json.encode].
*/
String jsonEncode(Object object, {Object toEncodable(Object nonEncodable)}) =>
json.encode(object, toEncodable: toEncodable);
/**
* Parses the string and returns the resulting Json object.
*
* The optional [reviver] function is called once for each object or list
* property that has been parsed during decoding. The `key` argument is either
* the integer list index for a list property, the string map key for object
* properties, or `null` for the final result.
*
* The default [reviver] (when not provided) is the identity function.
*
* Shorthand for [json.decode].
*/
dynamic jsonDecode(String source, {Object reviver(Object key, Object value)}) =>
json.decode(source, reviver: reviver);
typedef _Reviver(Object key, Object value);
typedef _ToEncodable(var o);

View file

@ -107,6 +107,10 @@ void testRoundtrip(List<int> list, String name) {
}
}
}
// Using .encode
Expect.equals(uriEncoded, base64Url.encode(list), ".encode($list)");
// Using base64UrlEncode
Expect.equals(uriEncoded, base64UrlEncode(list), ".encode($list)");
for (var encoded in [encodedNormal, encodedPercent, uriEncoded]) {
increment = encoded.length ~/ 7 + 1;
@ -141,6 +145,9 @@ void testRoundtrip(List<int> list, String name) {
}
}
}
Expect.listEquals(list, base64.decode(encoded), ".decode($encoded)");
Expect.listEquals(list, base64Url.decode(encoded), "url.decode($encoded)");
Expect.listEquals(list, base64Decode(encoded), "base64Decode($encoded)");
}
}

View file

@ -35,7 +35,7 @@ void testJson(jsonText, expected) {
}
for (var reviver in [null, (k, v) => v]) {
for (var split in [0, 1, 2, 3]) {
for (var split in [0, 1, 2, 3, 4, 5]) {
var name = (reviver == null) ? "" : "reviver:";
var sink = new ChunkedConversionSink.withCallback((values) {
var value = values[0];
@ -72,6 +72,14 @@ void testJson(jsonText, expected) {
decoderSink.add(jsonText.substring(2 * third));
decoderSink.close();
break;
case 4:
// Use .decode
sink.add([json.decode(jsonText)]);
break;
case 5:
// Use jsonDecode
sink.add([jsonDecode(jsonText)]);
break;
}
}
}
@ -98,6 +106,8 @@ String escape(String s) {
void testThrows(jsonText) {
Expect.throwsFormatException(() => json.decode(jsonText),
"json = '${escape(jsonText)}'");
Expect.throwsFormatException(() => jsonDecode(jsonText),
"json = '${escape(jsonText)}'");
}
testNumbers() {
@ -187,6 +197,9 @@ testNumbers() {
Expect.throws(() => json.encode(double.nan));
Expect.throws(() => json.encode(double.infinity));
Expect.throws(() => json.encode(double.negativeInfinity));
Expect.throws(() => jsonEncode(double.nan));
Expect.throws(() => jsonEncode(double.infinity));
Expect.throws(() => jsonEncode(double.negativeInfinity));
}
testStrings() {