Unverified Commit d05fa45f authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Undeprecated BigInteger support, but document what it actually does. (#24511)

Also, some code cleanup.
parent e2398725
...@@ -209,14 +209,21 @@ class JSONMethodCodec implements MethodCodec { ...@@ -209,14 +209,21 @@ class JSONMethodCodec implements MethodCodec {
/// * [List]\: `NSArray` /// * [List]\: `NSArray`
/// * [Map]\: `NSDictionary` /// * [Map]\: `NSDictionary`
/// ///
/// When sending a `java.math.BigInteger` from Java, it is converted into a
/// [String] with the hexadecimal representation of the integer. (The value is
/// tagged as being a big integer; subclasses of this class could be made to
/// support it natively; see the discussion at [writeValue].) This codec does
/// not support sending big integers from Dart.
///
/// The codec is extensible by subclasses overriding [writeValue] and /// The codec is extensible by subclasses overriding [writeValue] and
/// [readValueOfType]. /// [readValueOfType].
class StandardMessageCodec implements MessageCodec<dynamic> { class StandardMessageCodec implements MessageCodec<dynamic> {
/// Creates a [MessageCodec] using the Flutter standard binary encoding. /// Creates a [MessageCodec] using the Flutter standard binary encoding.
const StandardMessageCodec(); const StandardMessageCodec();
// The codec serializes messages as outlined below. This format must // The codec serializes messages as outlined below. This format must match the
// match the Android and iOS counterparts. // Android and iOS counterparts and cannot change (as it's possible for
// someone to end up using this for persistent storage).
// //
// * A single byte with one of the constant values below determines the // * A single byte with one of the constant values below determines the
// type of the value. // type of the value.
...@@ -230,7 +237,7 @@ class StandardMessageCodec implements MessageCodec<dynamic> { ...@@ -230,7 +237,7 @@ class StandardMessageCodec implements MessageCodec<dynamic> {
// * values 2^16+1..2^32 inclusive using five bytes, the first of which is // * values 2^16+1..2^32 inclusive using five bytes, the first of which is
// 255, the next four the usual unsigned representation of the value. // 255, the next four the usual unsigned representation of the value.
// * null, true, and false have empty serialization; they are encoded directly // * null, true, and false have empty serialization; they are encoded directly
// in the type byte (using _kNull, _kTrue, _kFalse) // in the type byte (using _valueNull, _valueTrue, _valueFalse)
// * Integers representable in 32 bits are encoded using 4 bytes two's // * Integers representable in 32 bits are encoded using 4 bytes two's
// complement representation. // complement representation.
// * Larger integers are encoded using 8 bytes two's complement // * Larger integers are encoded using 8 bytes two's complement
...@@ -252,6 +259,9 @@ class StandardMessageCodec implements MessageCodec<dynamic> { ...@@ -252,6 +259,9 @@ class StandardMessageCodec implements MessageCodec<dynamic> {
// * Maps are encoded by first encoding their length in the expanding format, // * Maps are encoded by first encoding their length in the expanding format,
// then follows the recursive encoding of each key/value pair, including the // then follows the recursive encoding of each key/value pair, including the
// type byte for both (Maps are assumed to be heterogeneous). // type byte for both (Maps are assumed to be heterogeneous).
//
// The type labels below must not change, since it's possible for this interface
// to be used for persistent storage.
static const int _valueNull = 0; static const int _valueNull = 0;
static const int _valueTrue = 1; static const int _valueTrue = 1;
static const int _valueFalse = 2; static const int _valueFalse = 2;
...@@ -293,12 +303,36 @@ class StandardMessageCodec implements MessageCodec<dynamic> { ...@@ -293,12 +303,36 @@ class StandardMessageCodec implements MessageCodec<dynamic> {
/// This method may be called recursively to serialize container values. /// This method may be called recursively to serialize container values.
/// ///
/// Type discriminators 0 through 127 inclusive are reserved for use by the /// Type discriminators 0 through 127 inclusive are reserved for use by the
/// base class. /// base class, as follows:
///
/// * null = 0
/// * true = 1
/// * false = 2
/// * 32 bit integer = 3
/// * 64 bit integer = 4
/// * larger integers = 5 (see below)
/// * 64 bit floating-point number = 6
/// * String = 7
/// * Uint8List = 8
/// * Int32List = 9
/// * Int64List = 10
/// * Float64List = 11
/// * List = 12
/// * Map = 13
/// * Reserved for future expansion: 14..127
/// ///
/// The codec can be extended by overriding this method, calling super /// The codec can be extended by overriding this method, calling super
/// for values that the extension does not handle. Type discriminators /// for values that the extension does not handle. Type discriminators
/// used by extensions must be greater than or equal to 128 in order to avoid /// used by extensions must be greater than or equal to 128 in order to avoid
/// clashes with any later extensions to the base class. /// clashes with any later extensions to the base class.
///
/// The "larger integers" type, 5, is never used by [writeValue]. A subclass
/// could represent big integers from another package using that type. The
/// format is first the type byte (0x05), then the actual number as an ASCII
/// string giving the hexadecimal representation of the integer, with the
/// string's length as encoded by [writeSize] followed by the string bytes. On
/// Android, that would get converted to a `java.math.BigInteger` object. On
/// iOS, the string representation is returned.
void writeValue(WriteBuffer buffer, dynamic value) { void writeValue(WriteBuffer buffer, dynamic value) {
if (value == null) { if (value == null) {
buffer.putUint8(_valueNull); buffer.putUint8(_valueNull);
...@@ -367,74 +401,53 @@ class StandardMessageCodec implements MessageCodec<dynamic> { ...@@ -367,74 +401,53 @@ class StandardMessageCodec implements MessageCodec<dynamic> {
/// Reads a value of the indicated [type] from [buffer]. /// Reads a value of the indicated [type] from [buffer].
/// ///
/// The codec can be extended by overriding this method, calling super /// The codec can be extended by overriding this method, calling super for
/// for types that the extension does not handle. /// types that the extension does not handle. See the discussion at
/// [writeValue].
dynamic readValueOfType(int type, ReadBuffer buffer) { dynamic readValueOfType(int type, ReadBuffer buffer) {
dynamic result;
switch (type) { switch (type) {
case _valueNull: case _valueNull:
result = null; return null;
break;
case _valueTrue: case _valueTrue:
result = true; return true;
break;
case _valueFalse: case _valueFalse:
result = false; return false;
break;
case _valueInt32: case _valueInt32:
result = buffer.getInt32(); return buffer.getInt32();
break;
case _valueInt64: case _valueInt64:
result = buffer.getInt64(); return buffer.getInt64();
break;
case _valueLargeInt:
// Flutter Engine APIs to use large ints have been deprecated on
// 2018-01-09 and will be made unavailable.
// TODO(mravn): remove this case once the APIs are unavailable.
final int length = readSize(buffer);
final String hex = utf8.decoder.convert(buffer.getUint8List(length));
result = int.parse(hex, radix: 16);
break;
case _valueFloat64: case _valueFloat64:
result = buffer.getFloat64(); return buffer.getFloat64();
break; case _valueLargeInt:
case _valueString: case _valueString:
final int length = readSize(buffer); final int length = readSize(buffer);
result = utf8.decoder.convert(buffer.getUint8List(length)); return utf8.decoder.convert(buffer.getUint8List(length));
break;
case _valueUint8List: case _valueUint8List:
final int length = readSize(buffer); final int length = readSize(buffer);
result = buffer.getUint8List(length); return buffer.getUint8List(length);
break;
case _valueInt32List: case _valueInt32List:
final int length = readSize(buffer); final int length = readSize(buffer);
result = buffer.getInt32List(length); return buffer.getInt32List(length);
break;
case _valueInt64List: case _valueInt64List:
final int length = readSize(buffer); final int length = readSize(buffer);
result = buffer.getInt64List(length); return buffer.getInt64List(length);
break;
case _valueFloat64List: case _valueFloat64List:
final int length = readSize(buffer); final int length = readSize(buffer);
result = buffer.getFloat64List(length); return buffer.getFloat64List(length);
break;
case _valueList: case _valueList:
final int length = readSize(buffer); final int length = readSize(buffer);
result = List<dynamic>(length); final dynamic result = List<dynamic>(length);
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++)
result[i] = readValue(buffer); result[i] = readValue(buffer);
} return result;
break;
case _valueMap: case _valueMap:
final int length = readSize(buffer); final int length = readSize(buffer);
result = <dynamic, dynamic>{}; final dynamic result = <dynamic, dynamic>{};
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++)
result[readValue(buffer)] = readValue(buffer); result[readValue(buffer)] = readValue(buffer);
} return result;
break;
default: throw const FormatException('Message corrupted'); default: throw const FormatException('Message corrupted');
} }
return result;
} }
/// Writes a non-negative 32-bit integer [value] to [buffer] /// Writes a non-negative 32-bit integer [value] to [buffer]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment