Files
engine/shell/platform/android/io/flutter/plugin/common/StandardMethodCodec.java
T

102 lines
4.1 KiB
Java
Raw Normal View History

2018-11-07 12:24:35 -08:00
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package io.flutter.plugin.common;
import io.flutter.plugin.common.StandardMessageCodec.ExposedByteArrayOutputStream;
import java.nio.ByteBuffer;
2017-03-13 23:57:46 +01:00
import java.nio.ByteOrder;
/**
* A {@link MethodCodec} using the Flutter standard binary encoding.
*
* <p>This codec is guaranteed to be compatible with the corresponding
* <a href="https://docs.flutter.io/flutter/services/StandardMethodCodec-class.html">StandardMethodCodec</a>
* on the Dart side. These parts of the Flutter SDK are evolved synchronously.</p>
*
* <p>Values supported as method arguments and result payloads are those supported by
* {@link StandardMessageCodec}.</p>
*/
public final class StandardMethodCodec implements MethodCodec {
2018-03-16 00:08:08 +00:00
public static final StandardMethodCodec INSTANCE = new StandardMethodCodec(StandardMessageCodec.INSTANCE);
private final StandardMessageCodec messageCodec;
2018-03-16 00:08:08 +00:00
/**
* Creates a new method codec based on the specified message codec.
*/
public StandardMethodCodec(StandardMessageCodec messageCodec) {
this.messageCodec = messageCodec;
}
2017-03-17 09:04:59 +01:00
@Override
public ByteBuffer encodeMethodCall(MethodCall methodCall) {
final ExposedByteArrayOutputStream stream = new ExposedByteArrayOutputStream();
2018-03-16 00:08:08 +00:00
messageCodec.writeValue(stream, methodCall.method);
messageCodec.writeValue(stream, methodCall.arguments);
2017-03-17 09:04:59 +01:00
final ByteBuffer buffer = ByteBuffer.allocateDirect(stream.size());
buffer.put(stream.buffer(), 0, stream.size());
return buffer;
}
@Override
public MethodCall decodeMethodCall(ByteBuffer methodCall) {
2017-03-13 23:57:46 +01:00
methodCall.order(ByteOrder.nativeOrder());
2018-03-16 00:08:08 +00:00
final Object method = messageCodec.readValue(methodCall);
final Object arguments = messageCodec.readValue(methodCall);
2017-03-17 09:04:59 +01:00
if (method instanceof String && !methodCall.hasRemaining()) {
return new MethodCall((String) method, arguments);
}
throw new IllegalArgumentException("Method call corrupted");
}
@Override
public ByteBuffer encodeSuccessEnvelope(Object result) {
final ExposedByteArrayOutputStream stream = new ExposedByteArrayOutputStream();
stream.write(0);
2018-03-16 00:08:08 +00:00
messageCodec.writeValue(stream, result);
final ByteBuffer buffer = ByteBuffer.allocateDirect(stream.size());
buffer.put(stream.buffer(), 0, stream.size());
return buffer;
}
@Override
public ByteBuffer encodeErrorEnvelope(String errorCode, String errorMessage,
Object errorDetails) {
final ExposedByteArrayOutputStream stream = new ExposedByteArrayOutputStream();
stream.write(1);
2018-03-16 00:08:08 +00:00
messageCodec.writeValue(stream, errorCode);
messageCodec.writeValue(stream, errorMessage);
messageCodec.writeValue(stream, errorDetails);
final ByteBuffer buffer = ByteBuffer.allocateDirect(stream.size());
buffer.put(stream.buffer(), 0, stream.size());
return buffer;
}
2017-03-17 09:04:59 +01:00
@Override
public Object decodeEnvelope(ByteBuffer envelope) {
envelope.order(ByteOrder.nativeOrder());
final byte flag = envelope.get();
switch (flag) {
case 0: {
2018-03-16 00:08:08 +00:00
final Object result = messageCodec.readValue(envelope);
2017-03-17 09:04:59 +01:00
if (!envelope.hasRemaining()) {
return result;
}
}
// Falls through intentionally.
2017-03-17 09:04:59 +01:00
case 1: {
2018-03-16 00:08:08 +00:00
final Object code = messageCodec.readValue(envelope);
final Object message = messageCodec.readValue(envelope);
final Object details = messageCodec.readValue(envelope);
2017-03-17 09:04:59 +01:00
if (code instanceof String
&& (message == null || message instanceof String)
&& !envelope.hasRemaining()) {
throw new FlutterException((String) code, (String) message, details);
}
}
}
throw new IllegalArgumentException("Envelope corrupted");
}
}