Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
StandardMethodCodec.java
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package io.flutter.plugin.common;
6
7import androidx.annotation.NonNull;
8import io.flutter.Log;
9import io.flutter.plugin.common.StandardMessageCodec.ExposedByteArrayOutputStream;
10import java.nio.ByteBuffer;
11import java.nio.ByteOrder;
12
13/**
14 * A {@link MethodCodec} using the Flutter standard binary encoding.
15 *
16 * <p>This codec is guaranteed to be compatible with the corresponding <a
17 * href="https://api.flutter.dev/flutter/services/StandardMethodCodec-class.html">StandardMethodCodec</a>
18 * on the Dart side. These parts of the Flutter SDK are evolved synchronously.
19 *
20 * <p>Values supported as method arguments and result payloads are those supported by {@link
21 * StandardMessageCodec}.
22 */
23public final class StandardMethodCodec implements MethodCodec {
24 public static final StandardMethodCodec INSTANCE =
26 private final StandardMessageCodec messageCodec;
27
28 /** Creates a new method codec based on the specified message codec. */
29 public StandardMethodCodec(@NonNull StandardMessageCodec messageCodec) {
30 this.messageCodec = messageCodec;
31 }
32
33 @Override
34 @NonNull
35 public ByteBuffer encodeMethodCall(@NonNull MethodCall methodCall) {
36 final ExposedByteArrayOutputStream stream = new ExposedByteArrayOutputStream();
37 messageCodec.writeValue(stream, methodCall.method);
38 messageCodec.writeValue(stream, methodCall.arguments);
39 final ByteBuffer buffer = ByteBuffer.allocateDirect(stream.size());
40 buffer.put(stream.buffer(), 0, stream.size());
41 return buffer;
42 }
43
44 @Override
45 @NonNull
46 public MethodCall decodeMethodCall(@NonNull ByteBuffer methodCall) {
47 methodCall.order(ByteOrder.nativeOrder());
48 final Object method = messageCodec.readValue(methodCall);
49 final Object arguments = messageCodec.readValue(methodCall);
50 if (method instanceof String && !methodCall.hasRemaining()) {
51 return new MethodCall((String) method, arguments);
52 }
53 throw new IllegalArgumentException("Method call corrupted");
54 }
55
56 @Override
57 @NonNull
58 public ByteBuffer encodeSuccessEnvelope(@NonNull Object result) {
59 final ExposedByteArrayOutputStream stream = new ExposedByteArrayOutputStream();
60 stream.write(0);
61 messageCodec.writeValue(stream, result);
62 final ByteBuffer buffer = ByteBuffer.allocateDirect(stream.size());
63 buffer.put(stream.buffer(), 0, stream.size());
64 return buffer;
65 }
66
67 @Override
68 @NonNull
69 public ByteBuffer encodeErrorEnvelope(
70 @NonNull String errorCode, @NonNull String errorMessage, @NonNull Object errorDetails) {
71 final ExposedByteArrayOutputStream stream = new ExposedByteArrayOutputStream();
72 stream.write(1);
73 messageCodec.writeValue(stream, errorCode);
74 messageCodec.writeValue(stream, errorMessage);
75 if (errorDetails instanceof Throwable) {
76 messageCodec.writeValue(stream, Log.getStackTraceString((Throwable) errorDetails));
77 } else {
78 messageCodec.writeValue(stream, errorDetails);
79 }
80 final ByteBuffer buffer = ByteBuffer.allocateDirect(stream.size());
81 buffer.put(stream.buffer(), 0, stream.size());
82 return buffer;
83 }
84
85 @Override
86 @NonNull
88 @NonNull String errorCode,
89 @NonNull String errorMessage,
90 @NonNull Object errorDetails,
91 @NonNull String errorStacktrace) {
92 final ExposedByteArrayOutputStream stream = new ExposedByteArrayOutputStream();
93 stream.write(1);
94 messageCodec.writeValue(stream, errorCode);
95 messageCodec.writeValue(stream, errorMessage);
96 if (errorDetails instanceof Throwable) {
97 messageCodec.writeValue(stream, Log.getStackTraceString((Throwable) errorDetails));
98 } else {
99 messageCodec.writeValue(stream, errorDetails);
100 }
101 messageCodec.writeValue(stream, errorStacktrace);
102 final ByteBuffer buffer = ByteBuffer.allocateDirect(stream.size());
103 buffer.put(stream.buffer(), 0, stream.size());
104 return buffer;
105 }
106
107 @Override
108 @NonNull
109 public Object decodeEnvelope(@NonNull ByteBuffer envelope) {
110 envelope.order(ByteOrder.nativeOrder());
111 final byte flag = envelope.get();
112 switch (flag) {
113 case 0:
114 {
115 final Object result = messageCodec.readValue(envelope);
116 if (!envelope.hasRemaining()) {
117 return result;
118 }
119 }
120 // Falls through intentionally.
121 case 1:
122 {
123 final Object code = messageCodec.readValue(envelope);
124 final Object message = messageCodec.readValue(envelope);
125 final Object details = messageCodec.readValue(envelope);
126 if (code instanceof String
127 && (message == null || message instanceof String)
128 && !envelope.hasRemaining()) {
129 throw new FlutterException((String) code, (String) message, details);
130 }
131 }
132 }
133 throw new IllegalArgumentException("Envelope corrupted");
134 }
135}
static String getStackTraceString(@Nullable Throwable tr)
Definition Log.java:101
final Object readValue(@NonNull ByteBuffer buffer)
void writeValue(@NonNull ByteArrayOutputStream stream, @Nullable Object value)
StandardMethodCodec(@NonNull StandardMessageCodec messageCodec)
ByteBuffer encodeSuccessEnvelope(@NonNull Object result)
ByteBuffer encodeErrorEnvelopeWithStacktrace( @NonNull String errorCode, @NonNull String errorMessage, @NonNull Object errorDetails, @NonNull String errorStacktrace)
ByteBuffer encodeErrorEnvelope( @NonNull String errorCode, @NonNull String errorMessage, @NonNull Object errorDetails)
Object decodeEnvelope(@NonNull ByteBuffer envelope)
ByteBuffer encodeMethodCall(@NonNull MethodCall methodCall)
MethodCall decodeMethodCall(@NonNull ByteBuffer methodCall)
FlutterSemanticsFlag flag
static const uint8_t buffer[]
GAsyncResult * result
Win32Message message