mirror of
https://github.com/encounter/engine.git
synced 2026-03-30 11:09:55 -07:00
102 lines
4.1 KiB
Java
102 lines
4.1 KiB
Java
// Copyright 2017 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.
|
|
|
|
package io.flutter.plugin.common;
|
|
|
|
import io.flutter.plugin.common.StandardMessageCodec.ExposedByteArrayOutputStream;
|
|
import java.nio.ByteBuffer;
|
|
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 {
|
|
public static final StandardMethodCodec INSTANCE = new StandardMethodCodec(StandardMessageCodec.INSTANCE);
|
|
private final StandardMessageCodec messageCodec;
|
|
|
|
/**
|
|
* Creates a new method codec based on the specified message codec.
|
|
*/
|
|
public StandardMethodCodec(StandardMessageCodec messageCodec) {
|
|
this.messageCodec = messageCodec;
|
|
}
|
|
|
|
@Override
|
|
public ByteBuffer encodeMethodCall(MethodCall methodCall) {
|
|
final ExposedByteArrayOutputStream stream = new ExposedByteArrayOutputStream();
|
|
messageCodec.writeValue(stream, methodCall.method);
|
|
messageCodec.writeValue(stream, methodCall.arguments);
|
|
final ByteBuffer buffer = ByteBuffer.allocateDirect(stream.size());
|
|
buffer.put(stream.buffer(), 0, stream.size());
|
|
return buffer;
|
|
}
|
|
|
|
@Override
|
|
public MethodCall decodeMethodCall(ByteBuffer methodCall) {
|
|
methodCall.order(ByteOrder.nativeOrder());
|
|
final Object method = messageCodec.readValue(methodCall);
|
|
final Object arguments = messageCodec.readValue(methodCall);
|
|
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);
|
|
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);
|
|
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;
|
|
}
|
|
|
|
@Override
|
|
public Object decodeEnvelope(ByteBuffer envelope) {
|
|
envelope.order(ByteOrder.nativeOrder());
|
|
final byte flag = envelope.get();
|
|
switch (flag) {
|
|
case 0: {
|
|
final Object result = messageCodec.readValue(envelope);
|
|
if (!envelope.hasRemaining()) {
|
|
return result;
|
|
}
|
|
}
|
|
// Falls through intentionally.
|
|
case 1: {
|
|
final Object code = messageCodec.readValue(envelope);
|
|
final Object message = messageCodec.readValue(envelope);
|
|
final Object details = messageCodec.readValue(envelope);
|
|
if (code instanceof String
|
|
&& (message == null || message instanceof String)
|
|
&& !envelope.hasRemaining()) {
|
|
throw new FlutterException((String) code, (String) message, details);
|
|
}
|
|
}
|
|
}
|
|
throw new IllegalArgumentException("Envelope corrupted");
|
|
}
|
|
}
|