Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
340c6803
Unverified
Commit
340c6803
authored
Mar 16, 2018
by
Mikkel Nygaard Ravn
Committed by
GitHub
Mar 16, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make standard codecs extensible (#15414)
parent
2d5ebd2a
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
314 additions
and
74 deletions
+314
-74
MainActivity.java
.../src/main/java/com/yourcompany/channels/MainActivity.java
+50
-2
AppDelegate.m
dev/integration_tests/channels/ios/Runner/AppDelegate.m
+79
-2
main.dart
dev/integration_tests/channels/lib/main.dart
+11
-1
basic_messaging.dart
dev/integration_tests/channels/lib/src/basic_messaging.dart
+36
-2
method_calls.dart
dev/integration_tests/channels/lib/src/method_calls.dart
+13
-6
pair.dart
dev/integration_tests/channels/lib/src/pair.dart
+14
-0
test_step.dart
dev/integration_tests/channels/lib/src/test_step.dart
+8
-0
message_codecs.dart
packages/flutter/lib/src/services/message_codecs.dart
+103
-61
No files found.
dev/integration_tests/channels/android/app/src/main/java/com/yourcompany/channels/MainActivity.java
View file @
340c6803
...
...
@@ -4,7 +4,9 @@
package
com
.
yourcompany
.
channels
;
import
java.io.ByteArrayOutputStream
;
import
java.nio.ByteBuffer
;
import
java.util.Date
;
import
android.os.Bundle
;
...
...
@@ -20,9 +22,9 @@ public class MainActivity extends FlutterActivity {
setupMessageHandshake
(
new
BasicMessageChannel
<>(
getFlutterView
(),
"binary-msg"
,
BinaryCodec
.
INSTANCE
));
setupMessageHandshake
(
new
BasicMessageChannel
<>(
getFlutterView
(),
"string-msg"
,
StringCodec
.
INSTANCE
));
setupMessageHandshake
(
new
BasicMessageChannel
<>(
getFlutterView
(),
"json-msg"
,
JSONMessageCodec
.
INSTANCE
));
setupMessageHandshake
(
new
BasicMessageChannel
<>(
getFlutterView
(),
"std-msg"
,
StandardMessageCodec
.
INSTANCE
));
setupMessageHandshake
(
new
BasicMessageChannel
<>(
getFlutterView
(),
"std-msg"
,
Extended
StandardMessageCodec
.
INSTANCE
));
setupMethodHandshake
(
new
MethodChannel
(
getFlutterView
(),
"json-method"
,
JSONMethodCodec
.
INSTANCE
));
setupMethodHandshake
(
new
MethodChannel
(
getFlutterView
(),
"std-method"
,
StandardMethodCodec
.
INSTANCE
));
setupMethodHandshake
(
new
MethodChannel
(
getFlutterView
(),
"std-method"
,
new
StandardMethodCodec
(
ExtendedStandardMessageCodec
.
INSTANCE
)
));
}
private
<
T
>
void
setupMessageHandshake
(
final
BasicMessageChannel
<
T
>
channel
)
{
...
...
@@ -135,3 +137,49 @@ public class MainActivity extends FlutterActivity {
});
}
}
final
class
ExtendedStandardMessageCodec
extends
StandardMessageCodec
{
public
static
final
ExtendedStandardMessageCodec
INSTANCE
=
new
ExtendedStandardMessageCodec
();
private
static
final
byte
DATE
=
(
byte
)
128
;
private
static
final
byte
PAIR
=
(
byte
)
129
;
@Override
protected
void
writeValue
(
ByteArrayOutputStream
stream
,
Object
value
)
{
if
(
value
instanceof
Date
)
{
stream
.
write
(
DATE
);
writeLong
(
stream
,
((
Date
)
value
).
getTime
());
}
else
if
(
value
instanceof
Pair
)
{
stream
.
write
(
PAIR
);
writeValue
(
stream
,
((
Pair
)
value
).
left
);
writeValue
(
stream
,
((
Pair
)
value
).
right
);
}
else
{
super
.
writeValue
(
stream
,
value
);
}
}
@Override
protected
Object
readValueOfType
(
byte
type
,
ByteBuffer
buffer
)
{
switch
(
type
)
{
case
DATE:
return
new
Date
(
buffer
.
getLong
());
case
PAIR:
return
new
Pair
(
readValue
(
buffer
),
readValue
(
buffer
));
default
:
return
super
.
readValueOfType
(
type
,
buffer
);
}
}
}
final
class
Pair
{
public
final
Object
left
;
public
final
Object
right
;
public
Pair
(
Object
left
,
Object
right
)
{
this
.
left
=
left
;
this
.
right
=
right
;
}
@Override
public
String
toString
()
{
return
"Pair["
+
left
+
", "
+
right
+
"]"
;
}
}
dev/integration_tests/channels/ios/Runner/AppDelegate.m
View file @
340c6803
...
...
@@ -5,6 +5,82 @@
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
@interface
Pair
:
NSObject
@property
(
atomic
,
readonly
,
strong
,
nullable
)
NSObject
*
left
;
@property
(
atomic
,
readonly
,
strong
,
nullable
)
NSObject
*
right
;
-
(
instancetype
)
initWithLeft
:(
NSObject
*
)
first
right
:(
NSObject
*
)
right
;
@end
@implementation
Pair
-
(
instancetype
)
initWithLeft
:(
NSObject
*
)
left
right
:(
NSObject
*
)
right
{
self
=
[
super
init
];
_left
=
left
;
_right
=
right
;
return
self
;
}
@end
const
UInt8
DATE
=
128
;
const
UInt8
PAIR
=
129
;
@interface
ExtendedWriter
:
FlutterStandardWriter
-
(
void
)
writeValue
:(
id
)
value
;
@end
@implementation
ExtendedWriter
-
(
void
)
writeValue
:(
id
)
value
{
if
([
value
isKindOfClass
:[
NSDate
class
]])
{
[
self
writeByte
:
DATE
];
NSDate
*
date
=
value
;
NSTimeInterval
time
=
date
.
timeIntervalSince1970
;
SInt64
ms
=
(
SInt64
)
(
time
*
1000
.
0
);
[
self
writeBytes
:
&
ms
length
:
8
];
}
else
if
([
value
isKindOfClass
:[
Pair
class
]])
{
Pair
*
pair
=
value
;
[
self
writeByte
:
PAIR
];
[
self
writeValue
:
pair
.
left
];
[
self
writeValue
:
pair
.
right
];
}
else
{
[
super
writeValue
:
value
];
}
}
@end
@interface
ExtendedReader
:
FlutterStandardReader
-
(
id
)
readValueOfType
:(
UInt8
)
type
;
@end
@implementation
ExtendedReader
-
(
id
)
readValueOfType
:(
UInt8
)
type
{
switch
(
type
)
{
case
DATE
:
{
SInt64
value
;
[
self
readBytes
:
&
value
length
:
8
];
NSTimeInterval
time
=
[
NSNumber
numberWithLong
:
value
].
doubleValue
/
1000
.
0
;
return
[
NSDate
dateWithTimeIntervalSince1970
:
time
];
}
case
PAIR
:
{
return
[[
Pair
alloc
]
initWithLeft
:[
self
readValue
]
right
:[
self
readValue
]];
}
default:
return
[
super
readValueOfType
:
type
];
}
}
@end
@interface
ExtendedReaderWriter
:
FlutterStandardReaderWriter
-
(
FlutterStandardWriter
*
)
writerWithData
:(
NSMutableData
*
)
data
;
-
(
FlutterStandardReader
*
)
readerWithData
:(
NSData
*
)
data
;
@end
@implementation
ExtendedReaderWriter
-
(
FlutterStandardWriter
*
)
writerWithData
:(
NSMutableData
*
)
data
{
return
[[
ExtendedWriter
alloc
]
initWithData
:
data
];
}
-
(
FlutterStandardReader
*
)
readerWithData
:(
NSData
*
)
data
{
return
[[
ExtendedReader
alloc
]
initWithData
:
data
];
}
@end
@implementation
AppDelegate
-
(
BOOL
)
application
:(
UIApplication
*
)
application
didFinishLaunchingWithOptions
:(
NSDictionary
*
)
launchOptions
{
...
...
@@ -13,6 +89,7 @@
FlutterViewController
*
flutterController
=
(
FlutterViewController
*
)
self
.
window
.
rootViewController
;
ExtendedReaderWriter
*
extendedReaderWriter
=
[
ExtendedReaderWriter
new
];
[
self
setupMessagingHandshakeOnChannel
:
[
FlutterBasicMessageChannel
messageChannelWithName
:
@"binary-msg"
binaryMessenger
:
flutterController
...
...
@@ -28,7 +105,7 @@
[
self
setupMessagingHandshakeOnChannel
:
[
FlutterBasicMessageChannel
messageChannelWithName
:
@"std-msg"
binaryMessenger
:
flutterController
codec
:[
FlutterStandardMessageCodec
sharedInstance
]]];
codec
:[
FlutterStandardMessageCodec
codecWithReaderWriter
:
extendedReaderWriter
]]];
[
self
setupMethodCallSuccessHandshakeOnChannel
:
[
FlutterMethodChannel
methodChannelWithName
:
@"json-method"
binaryMessenger
:
flutterController
...
...
@@ -36,7 +113,7 @@
[
self
setupMethodCallSuccessHandshakeOnChannel
:
[
FlutterMethodChannel
methodChannelWithName
:
@"std-method"
binaryMessenger
:
flutterController
codec
:[
FlutterStandardMethodCodec
sharedInstance
]]];
codec
:[
FlutterStandardMethodCodec
codecWithReaderWriter
:
extendedReaderWriter
]]];
return
[
super
application
:
application
didFinishLaunchingWithOptions
:
launchOptions
];
}
...
...
dev/integration_tests/channels/lib/main.dart
View file @
340c6803
...
...
@@ -10,6 +10,7 @@ import 'package:flutter_driver/driver_extension.dart';
import
'src/basic_messaging.dart'
;
import
'src/method_calls.dart'
;
import
'src/pair.dart'
;
import
'src/test_step.dart'
;
void
main
(
)
{
...
...
@@ -23,6 +24,7 @@ class TestApp extends StatefulWidget {
}
class
_TestAppState
extends
State
<
TestApp
>
{
static
final
dynamic
anUnknownValue
=
new
DateTime
.
fromMillisecondsSinceEpoch
(
1520777802314
);
static
final
List
<
dynamic
>
aList
=
<
dynamic
>[
false
,
0
,
...
...
@@ -39,7 +41,7 @@ class _TestAppState extends State<TestApp> {
'd'
:
'hello'
,
'e'
:
<
dynamic
>[
<
String
,
dynamic
>{
'key'
:
42
}
]
]
,
};
static
final
Uint8List
someUint8s
=
new
Uint8List
.
fromList
(<
int
>[
0xBA
,
...
...
@@ -69,6 +71,10 @@ class _TestAppState extends State<TestApp> {
double
.
maxFinite
,
double
.
infinity
,
]);
static
final
dynamic
aCompoundUnknownValue
=
<
dynamic
>[
anUnknownValue
,
new
Pair
(
anUnknownValue
,
aList
),
];
static
final
List
<
TestStep
>
steps
=
<
TestStep
>[
()
=>
methodCallJsonSuccessHandshake
(
null
),
()
=>
methodCallJsonSuccessHandshake
(
true
),
...
...
@@ -83,6 +89,8 @@ class _TestAppState extends State<TestApp> {
()
=>
methodCallStandardSuccessHandshake
(
'world'
),
()
=>
methodCallStandardSuccessHandshake
(
aList
),
()
=>
methodCallStandardSuccessHandshake
(
aMap
),
()
=>
methodCallStandardSuccessHandshake
(
anUnknownValue
),
()
=>
methodCallStandardSuccessHandshake
(
aCompoundUnknownValue
),
()
=>
methodCallJsonErrorHandshake
(
null
),
()
=>
methodCallJsonErrorHandshake
(
'world'
),
()
=>
methodCallStandardErrorHandshake
(
null
),
...
...
@@ -138,6 +146,8 @@ class _TestAppState extends State<TestApp> {
()
=>
basicStandardHandshake
(<
String
,
dynamic
>{}),
()
=>
basicStandardHandshake
(<
dynamic
,
dynamic
>{
7
:
true
,
false
:
-
7
}),
()
=>
basicStandardHandshake
(
aMap
),
()
=>
basicStandardHandshake
(
anUnknownValue
),
()
=>
basicStandardHandshake
(
aCompoundUnknownValue
),
()
=>
basicBinaryMessageToUnknownChannel
(),
()
=>
basicStringMessageToUnknownChannel
(),
()
=>
basicJsonMessageToUnknownChannel
(),
...
...
dev/integration_tests/channels/lib/src/basic_messaging.dart
View file @
340c6803
...
...
@@ -5,8 +5,42 @@
import
'dart:async'
;
import
'dart:typed_data'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/foundation.dart'
show
ReadBuffer
,
WriteBuffer
;
import
'pair.dart'
;
import
'test_step.dart'
;
class
ExtendedStandardMessageCodec
extends
StandardMessageCodec
{
const
ExtendedStandardMessageCodec
();
static
const
int
_kDateTime
=
128
;
static
const
int
_kPair
=
129
;
@override
void
writeValue
(
WriteBuffer
buffer
,
dynamic
value
)
{
if
(
value
is
DateTime
)
{
buffer
.
putUint8
(
_kDateTime
);
buffer
.
putInt64
(
value
.
millisecondsSinceEpoch
);
}
else
if
(
value
is
Pair
)
{
buffer
.
putUint8
(
_kPair
);
writeValue
(
buffer
,
value
.
left
);
writeValue
(
buffer
,
value
.
right
);
}
else
{
super
.
writeValue
(
buffer
,
value
);
}
}
@override
dynamic
readValueOfType
(
int
type
,
ReadBuffer
buffer
)
{
switch
(
type
)
{
case
_kDateTime:
return
new
DateTime
.
fromMillisecondsSinceEpoch
(
buffer
.
getInt64
());
case
_kPair:
return
new
Pair
(
readValue
(
buffer
),
readValue
(
buffer
));
default
:
return
super
.
readValueOfType
(
type
,
buffer
);
}
}
}
Future
<
TestStepResult
>
basicBinaryHandshake
(
ByteData
message
)
async
{
const
BasicMessageChannel
<
ByteData
>
channel
=
const
BasicMessageChannel
<
ByteData
>(
...
...
@@ -38,7 +72,7 @@ Future<TestStepResult> basicStandardHandshake(dynamic message) async {
const
BasicMessageChannel
<
dynamic
>
channel
=
const
BasicMessageChannel
<
dynamic
>(
'std-msg'
,
const
StandardMessageCodec
(),
const
Extended
StandardMessageCodec
(),
);
return
_basicMessageHandshake
<
dynamic
>(
'Standard >
${toString(message)}
<'
,
channel
,
message
);
...
...
@@ -74,7 +108,7 @@ Future<TestStepResult> basicStandardMessageToUnknownChannel() async {
const
BasicMessageChannel
<
dynamic
>
channel
=
const
BasicMessageChannel
<
dynamic
>(
'std-unknown'
,
const
StandardMessageCodec
(),
const
Extended
StandardMessageCodec
(),
);
return
_basicMessageToUnknownChannel
<
dynamic
>(
'Standard'
,
channel
);
}
...
...
dev/integration_tests/channels/lib/src/method_calls.dart
View file @
340c6803
...
...
@@ -4,6 +4,7 @@
import
'dart:async'
;
import
'package:flutter/services.dart'
;
import
'basic_messaging.dart'
;
import
'test_step.dart'
;
Future
<
TestStepResult
>
methodCallJsonSuccessHandshake
(
dynamic
payload
)
async
{
...
...
@@ -27,22 +28,28 @@ Future<TestStepResult> methodCallJsonNotImplementedHandshake() async {
Future
<
TestStepResult
>
methodCallStandardSuccessHandshake
(
dynamic
payload
)
async
{
const
MethodChannel
channel
=
const
MethodChannel
(
'std-method'
,
const
StandardMethodCodec
());
const
MethodChannel
channel
=
const
MethodChannel
(
'std-method'
,
const
StandardMethodCodec
(
const
ExtendedStandardMessageCodec
()),
);
return
_methodCallSuccessHandshake
(
'Standard success(
$payload
)'
,
channel
,
payload
);
}
Future
<
TestStepResult
>
methodCallStandardErrorHandshake
(
dynamic
payload
)
async
{
const
MethodChannel
channel
=
const
MethodChannel
(
'std-method'
,
const
StandardMethodCodec
());
const
MethodChannel
channel
=
const
MethodChannel
(
'std-method'
,
const
StandardMethodCodec
(
const
ExtendedStandardMessageCodec
()),
);
return
_methodCallErrorHandshake
(
'Standard error(
$payload
)'
,
channel
,
payload
);
}
Future
<
TestStepResult
>
methodCallStandardNotImplementedHandshake
()
async
{
const
MethodChannel
channel
=
const
MethodChannel
(
'std-method'
,
const
StandardMethodCodec
());
const
MethodChannel
channel
=
const
MethodChannel
(
'std-method'
,
const
StandardMethodCodec
(
const
ExtendedStandardMessageCodec
()),
);
return
_methodCallNotImplementedHandshake
(
'Standard notImplemented()'
,
channel
);
}
...
...
dev/integration_tests/channels/lib/src/pair.dart
0 → 100644
View file @
340c6803
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/// A pair of values. Used for testing custom codecs.
class
Pair
{
final
dynamic
left
;
final
dynamic
right
;
Pair
(
this
.
left
,
this
.
right
);
@override
String
toString
()
=>
'Pair[
$left
,
$right
]'
;
}
dev/integration_tests/channels/lib/src/test_step.dart
View file @
340c6803
...
...
@@ -7,6 +7,8 @@ import 'dart:typed_data';
import
'package:flutter/material.dart'
;
import
'pair.dart'
;
enum
TestStatus
{
ok
,
pending
,
failed
,
complete
}
typedef
Future
<
TestStepResult
>
TestStep
();
...
...
@@ -147,6 +149,8 @@ bool _deepEquals(dynamic a, dynamic b) {
return
b
is
List
&&
_deepEqualsList
(
a
,
b
);
if
(
a
is
Map
)
return
b
is
Map
&&
_deepEqualsMap
(
a
,
b
);
if
(
a
is
Pair
)
return
b
is
Pair
&&
_deepEqualsPair
(
a
,
b
);
return
false
;
}
...
...
@@ -176,3 +180,7 @@ bool _deepEqualsMap(Map<dynamic, dynamic> a, Map<dynamic, dynamic> b) {
}
return
true
;
}
bool
_deepEqualsPair
(
Pair
a
,
Pair
b
)
{
return
_deepEquals
(
a
.
left
,
b
.
left
)
&&
_deepEquals
(
a
.
right
,
b
.
right
);
}
packages/flutter/lib/src/services/message_codecs.dart
View file @
340c6803
...
...
@@ -201,6 +201,9 @@ class JSONMethodCodec implements MethodCodec {
/// `FlutterStandardTypedData`
/// * [List]\: `NSArray`
/// * [Map]\: `NSDictionary`
///
/// The codec is extensible by subclasses overriding [writeValue] and
/// [readValueOfType].
class
StandardMessageCodec
implements
MessageCodec
<
dynamic
>
{
// The codec serializes messages as outlined below. This format must
// match the Android and iOS counterparts.
...
...
@@ -262,7 +265,7 @@ class StandardMessageCodec implements MessageCodec<dynamic> {
if
(
message
==
null
)
return
null
;
final
WriteBuffer
buffer
=
new
WriteBuffer
();
_
writeValue
(
buffer
,
message
);
writeValue
(
buffer
,
message
);
return
buffer
.
done
();
}
...
...
@@ -271,26 +274,25 @@ class StandardMessageCodec implements MessageCodec<dynamic> {
if
(
message
==
null
)
return
null
;
final
ReadBuffer
buffer
=
new
ReadBuffer
(
message
);
final
dynamic
result
=
_
readValue
(
buffer
);
final
dynamic
result
=
readValue
(
buffer
);
if
(
buffer
.
hasRemaining
)
throw
const
FormatException
(
'Message corrupted'
);
return
result
;
}
static
void
_writeSize
(
WriteBuffer
buffer
,
int
value
)
{
assert
(
0
<=
value
&&
value
<=
0xffffffff
);
if
(
value
<
254
)
{
buffer
.
putUint8
(
value
);
}
else
if
(
value
<=
0xffff
)
{
buffer
.
putUint8
(
254
);
buffer
.
putUint16
(
value
);
}
else
{
buffer
.
putUint8
(
255
);
buffer
.
putUint32
(
value
);
}
}
static
void
_writeValue
(
WriteBuffer
buffer
,
dynamic
value
)
{
/// Writes [value] to [buffer] by first writing a type discriminator
/// byte, then the value itself.
///
/// This method may be called recursively to serialize container values.
///
/// Type discriminators 0 through 127 inclusive are reserved for use by the
/// base class.
///
/// The codec can be extended by overriding this method, calling super
/// 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
/// clashes with any later extensions to the base class.
void
writeValue
(
WriteBuffer
buffer
,
dynamic
value
)
{
if
(
value
==
null
)
{
buffer
.
putUint8
(
_kNull
);
}
else
if
(
value
is
bool
)
{
...
...
@@ -309,57 +311,60 @@ class StandardMessageCodec implements MessageCodec<dynamic> {
}
else
if
(
value
is
String
)
{
buffer
.
putUint8
(
_kString
);
final
List
<
int
>
bytes
=
utf8
.
encoder
.
convert
(
value
);
_
writeSize
(
buffer
,
bytes
.
length
);
writeSize
(
buffer
,
bytes
.
length
);
buffer
.
putUint8List
(
bytes
);
}
else
if
(
value
is
Uint8List
)
{
buffer
.
putUint8
(
_kUint8List
);
_
writeSize
(
buffer
,
value
.
length
);
writeSize
(
buffer
,
value
.
length
);
buffer
.
putUint8List
(
value
);
}
else
if
(
value
is
Int32List
)
{
buffer
.
putUint8
(
_kInt32List
);
_
writeSize
(
buffer
,
value
.
length
);
writeSize
(
buffer
,
value
.
length
);
buffer
.
putInt32List
(
value
);
}
else
if
(
value
is
Int64List
)
{
buffer
.
putUint8
(
_kInt64List
);
_
writeSize
(
buffer
,
value
.
length
);
writeSize
(
buffer
,
value
.
length
);
buffer
.
putInt64List
(
value
);
}
else
if
(
value
is
Float64List
)
{
buffer
.
putUint8
(
_kFloat64List
);
_
writeSize
(
buffer
,
value
.
length
);
writeSize
(
buffer
,
value
.
length
);
buffer
.
putFloat64List
(
value
);
}
else
if
(
value
is
List
)
{
buffer
.
putUint8
(
_kList
);
_
writeSize
(
buffer
,
value
.
length
);
writeSize
(
buffer
,
value
.
length
);
for
(
final
dynamic
item
in
value
)
{
_
writeValue
(
buffer
,
item
);
writeValue
(
buffer
,
item
);
}
}
else
if
(
value
is
Map
)
{
buffer
.
putUint8
(
_kMap
);
_
writeSize
(
buffer
,
value
.
length
);
writeSize
(
buffer
,
value
.
length
);
value
.
forEach
((
dynamic
key
,
dynamic
value
)
{
_
writeValue
(
buffer
,
key
);
_
writeValue
(
buffer
,
value
);
writeValue
(
buffer
,
key
);
writeValue
(
buffer
,
value
);
});
}
else
{
throw
new
ArgumentError
.
value
(
value
);
}
}
static
int
_readSize
(
ReadBuffer
buffer
)
{
final
int
value
=
buffer
.
getUint8
();
if
(
value
<
254
)
return
value
;
else
if
(
value
==
254
)
return
buffer
.
getUint16
();
else
return
buffer
.
getUint32
();
}
static
dynamic
_readValue
(
ReadBuffer
buffer
)
{
/// Reads a value from [buffer] as written by [writeValue].
///
/// This method is intended for use by subclasses overriding
/// [readValueOfType].
dynamic
readValue
(
ReadBuffer
buffer
)
{
if
(!
buffer
.
hasRemaining
)
throw
const
FormatException
(
'Message corrupted'
);
final
int
type
=
buffer
.
getUint8
();
return
readValueOfType
(
type
,
buffer
);
}
/// Reads a value of the indicated [type] from [buffer].
///
/// The codec can be extended by overriding this method, calling super
/// for types that the extension does not handle.
dynamic
readValueOfType
(
int
type
,
ReadBuffer
buffer
)
{
dynamic
result
;
switch
(
buffer
.
getUint8
()
)
{
switch
(
type
)
{
case
_kNull:
result
=
null
;
break
;
...
...
@@ -379,7 +384,7 @@ class StandardMessageCodec implements MessageCodec<dynamic> {
// 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
int
length
=
readSize
(
buffer
);
final
String
hex
=
utf8
.
decoder
.
convert
(
buffer
.
getUint8List
(
length
));
result
=
int
.
parse
(
hex
,
radix:
16
);
break
;
...
...
@@ -387,43 +392,77 @@ class StandardMessageCodec implements MessageCodec<dynamic> {
result
=
buffer
.
getFloat64
();
break
;
case
_kString:
final
int
length
=
_
readSize
(
buffer
);
final
int
length
=
readSize
(
buffer
);
result
=
utf8
.
decoder
.
convert
(
buffer
.
getUint8List
(
length
));
break
;
case
_kUint8List:
final
int
length
=
_
readSize
(
buffer
);
final
int
length
=
readSize
(
buffer
);
result
=
buffer
.
getUint8List
(
length
);
break
;
case
_kInt32List:
final
int
length
=
_
readSize
(
buffer
);
final
int
length
=
readSize
(
buffer
);
result
=
buffer
.
getInt32List
(
length
);
break
;
case
_kInt64List:
final
int
length
=
_
readSize
(
buffer
);
final
int
length
=
readSize
(
buffer
);
result
=
buffer
.
getInt64List
(
length
);
break
;
case
_kFloat64List:
final
int
length
=
_
readSize
(
buffer
);
final
int
length
=
readSize
(
buffer
);
result
=
buffer
.
getFloat64List
(
length
);
break
;
case
_kList:
final
int
length
=
_
readSize
(
buffer
);
final
int
length
=
readSize
(
buffer
);
result
=
new
List
<
dynamic
>(
length
);
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
result
[
i
]
=
_
readValue
(
buffer
);
result
[
i
]
=
readValue
(
buffer
);
}
break
;
case
_kMap:
final
int
length
=
_
readSize
(
buffer
);
final
int
length
=
readSize
(
buffer
);
result
=
<
dynamic
,
dynamic
>{};
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
result
[
_readValue
(
buffer
)]
=
_
readValue
(
buffer
);
result
[
readValue
(
buffer
)]
=
readValue
(
buffer
);
}
break
;
default
:
throw
const
FormatException
(
'Message corrupted'
);
}
return
result
;
}
/// Writes a non-negative 32-bit integer [value] to [buffer]
/// using an expanding 1-5 byte encoding that optimizes for small values.
///
/// This method is intended for use by subclasses overriding
/// [writeValue].
void
writeSize
(
WriteBuffer
buffer
,
int
value
)
{
assert
(
0
<=
value
&&
value
<=
0xffffffff
);
if
(
value
<
254
)
{
buffer
.
putUint8
(
value
);
}
else
if
(
value
<=
0xffff
)
{
buffer
.
putUint8
(
254
);
buffer
.
putUint16
(
value
);
}
else
{
buffer
.
putUint8
(
255
);
buffer
.
putUint32
(
value
);
}
}
/// Reads a non-negative int from [buffer] as written by [writeSize].
///
/// This method is intended for use by subclasses overriding
/// [readValueOfType].
int
readSize
(
ReadBuffer
buffer
)
{
final
int
value
=
buffer
.
getUint8
();
switch
(
value
)
{
case
254
:
return
buffer
.
getUint16
();
case
255
:
return
buffer
.
getUint32
();
default
:
return
value
;
}
}
}
/// [MethodCodec] using the Flutter standard binary encoding.
...
...
@@ -448,21 +487,24 @@ class StandardMethodCodec implements MethodCodec {
// string, the error message string, and the error details value.
/// Creates a [MethodCodec] using the Flutter standard binary encoding.
const
StandardMethodCodec
();
const
StandardMethodCodec
([
this
.
messageCodec
=
const
StandardMessageCodec
()]);
/// The message codec that this method codec uses for encoding values.
final
StandardMessageCodec
messageCodec
;
@override
ByteData
encodeMethodCall
(
MethodCall
call
)
{
final
WriteBuffer
buffer
=
new
WriteBuffer
();
StandardMessageCodec
.
_
writeValue
(
buffer
,
call
.
method
);
StandardMessageCodec
.
_
writeValue
(
buffer
,
call
.
arguments
);
messageCodec
.
writeValue
(
buffer
,
call
.
method
);
messageCodec
.
writeValue
(
buffer
,
call
.
arguments
);
return
buffer
.
done
();
}
@override
MethodCall
decodeMethodCall
(
ByteData
methodCall
)
{
final
ReadBuffer
buffer
=
new
ReadBuffer
(
methodCall
);
final
dynamic
method
=
StandardMessageCodec
.
_
readValue
(
buffer
);
final
dynamic
arguments
=
StandardMessageCodec
.
_
readValue
(
buffer
);
final
dynamic
method
=
messageCodec
.
readValue
(
buffer
);
final
dynamic
arguments
=
messageCodec
.
readValue
(
buffer
);
if
(
method
is
String
&&
!
buffer
.
hasRemaining
)
return
new
MethodCall
(
method
,
arguments
);
else
...
...
@@ -473,7 +515,7 @@ class StandardMethodCodec implements MethodCodec {
ByteData
encodeSuccessEnvelope
(
dynamic
result
)
{
final
WriteBuffer
buffer
=
new
WriteBuffer
();
buffer
.
putUint8
(
0
);
StandardMessageCodec
.
_
writeValue
(
buffer
,
result
);
messageCodec
.
writeValue
(
buffer
,
result
);
return
buffer
.
done
();
}
...
...
@@ -481,9 +523,9 @@ class StandardMethodCodec implements MethodCodec {
ByteData
encodeErrorEnvelope
({
@required
String
code
,
String
message
,
dynamic
details
})
{
final
WriteBuffer
buffer
=
new
WriteBuffer
();
buffer
.
putUint8
(
1
);
StandardMessageCodec
.
_
writeValue
(
buffer
,
code
);
StandardMessageCodec
.
_
writeValue
(
buffer
,
message
);
StandardMessageCodec
.
_
writeValue
(
buffer
,
details
);
messageCodec
.
writeValue
(
buffer
,
code
);
messageCodec
.
writeValue
(
buffer
,
message
);
messageCodec
.
writeValue
(
buffer
,
details
);
return
buffer
.
done
();
}
...
...
@@ -494,10 +536,10 @@ class StandardMethodCodec implements MethodCodec {
throw
const
FormatException
(
'Expected envelope, got nothing'
);
final
ReadBuffer
buffer
=
new
ReadBuffer
(
envelope
);
if
(
buffer
.
getUint8
()
==
0
)
return
StandardMessageCodec
.
_
readValue
(
buffer
);
final
dynamic
errorCode
=
StandardMessageCodec
.
_
readValue
(
buffer
);
final
dynamic
errorMessage
=
StandardMessageCodec
.
_
readValue
(
buffer
);
final
dynamic
errorDetails
=
StandardMessageCodec
.
_
readValue
(
buffer
);
return
messageCodec
.
readValue
(
buffer
);
final
dynamic
errorCode
=
messageCodec
.
readValue
(
buffer
);
final
dynamic
errorMessage
=
messageCodec
.
readValue
(
buffer
);
final
dynamic
errorDetails
=
messageCodec
.
readValue
(
buffer
);
if
(
errorCode
is
String
&&
(
errorMessage
==
null
||
errorMessage
is
String
)
&&
!
buffer
.
hasRemaining
)
throw
new
PlatformException
(
code:
errorCode
,
message:
errorMessage
,
details:
errorDetails
);
else
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment