Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
fl_standard_method_codec.cc
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
5#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h"
6
7#include <gmodule.h>
8
9#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_message_codec.h"
10
11// See lib/src/services/message_codecs.dart in Flutter source for description of
12// encoding.
13
14// Envelope codes.
15static constexpr guint8 kEnvelopeTypeSuccess = 0;
16static constexpr guint8 kEnvelopeTypeError = 1;
17
19 FlMethodCodec parent_instance;
20
21 FlStandardMessageCodec* message_codec;
22};
23
25
26G_DEFINE_TYPE(FlStandardMethodCodec,
27 fl_standard_method_codec,
28 fl_method_codec_get_type())
29
30static void fl_standard_method_codec_set_property(GObject* object,
31 guint prop_id,
32 const GValue* value,
33 GParamSpec* pspec) {
34 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(object);
35
36 switch (prop_id) {
38 g_set_object(&self->message_codec,
39 FL_STANDARD_MESSAGE_CODEC(g_value_get_object(value)));
40 break;
41 default:
42 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
43 break;
44 }
45}
46
47static void fl_standard_method_codec_get_property(GObject* object,
48 guint prop_id,
49 GValue* value,
50 GParamSpec* pspec) {
51 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(object);
52
53 switch (prop_id) {
55 g_value_set_object(value, self->message_codec);
56 break;
57 default:
58 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
59 break;
60 }
61}
62
63static void fl_standard_method_codec_dispose(GObject* object) {
64 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(object);
65
66 g_clear_object(&self->message_codec);
67
68 G_OBJECT_CLASS(fl_standard_method_codec_parent_class)->dispose(object);
69}
70
71// Implements FlMethodCodec::encode_method_call.
72static GBytes* fl_standard_method_codec_encode_method_call(FlMethodCodec* codec,
73 const gchar* name,
75 GError** error) {
76 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(codec);
77
78 g_autoptr(GByteArray) buffer = g_byte_array_new();
79 g_autoptr(FlValue) name_value = fl_value_new_string(name);
81 name_value, error)) {
82 return nullptr;
83 }
85 error)) {
86 return nullptr;
87 }
88
89 return g_byte_array_free_to_bytes(
90 static_cast<GByteArray*>(g_steal_pointer(&buffer)));
91}
92
93// Implements FlMethodCodec::decode_method_call.
95 FlMethodCodec* codec,
96 GBytes* message,
97 gchar** name,
98 FlValue** args,
99 GError** error) {
100 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(codec);
101
102 size_t offset = 0;
103 g_autoptr(FlValue) name_value = fl_standard_message_codec_read_value(
104 self->message_codec, message, &offset, error);
105 if (name_value == nullptr) {
106 return FALSE;
107 }
108 if (fl_value_get_type(name_value) != FL_VALUE_TYPE_STRING) {
110 "Method call name wrong type");
111 return FALSE;
112 }
113
114 g_autoptr(FlValue) args_value = fl_standard_message_codec_read_value(
115 self->message_codec, message, &offset, error);
116 if (args_value == nullptr) {
117 return FALSE;
118 }
119
120 if (offset != g_bytes_get_size(message)) {
122 "Unexpected extra data");
123 return FALSE;
124 }
125
126 *name = g_strdup(fl_value_get_string(name_value));
127 *args = fl_value_ref(args_value);
128
129 return TRUE;
130}
131
132// Implements FlMethodCodec::encode_success_envelope.
134 FlMethodCodec* codec,
136 GError** error) {
137 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(codec);
138
139 g_autoptr(GByteArray) buffer = g_byte_array_new();
140 guint8 type = kEnvelopeTypeSuccess;
143 result, error)) {
144 return nullptr;
145 }
146
147 return g_byte_array_free_to_bytes(
148 static_cast<GByteArray*>(g_steal_pointer(&buffer)));
149}
150
151// Implements FlMethodCodec::encode_error_envelope.
153 FlMethodCodec* codec,
154 const gchar* code,
155 const gchar* message,
156 FlValue* details,
157 GError** error) {
158 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(codec);
159
160 g_autoptr(GByteArray) buffer = g_byte_array_new();
161 guint8 type = kEnvelopeTypeError;
163 g_autoptr(FlValue) code_value = fl_value_new_string(code);
165 code_value, error)) {
166 return nullptr;
167 }
168 g_autoptr(FlValue) message_value =
169 message != nullptr ? fl_value_new_string(message) : nullptr;
171 message_value, error)) {
172 return nullptr;
173 }
175 details, error)) {
176 return nullptr;
177 }
178
179 return g_byte_array_free_to_bytes(
180 static_cast<GByteArray*>(g_steal_pointer(&buffer)));
181}
182
183// Implements FlMethodCodec::encode_decode_response.
185 FlMethodCodec* codec,
186 GBytes* message,
187 GError** error) {
188 FlStandardMethodCodec* self = FL_STANDARD_METHOD_CODEC(codec);
189
190 if (g_bytes_get_size(message) == 0) {
191 g_set_error(error, FL_MESSAGE_CODEC_ERROR,
192 FL_MESSAGE_CODEC_ERROR_OUT_OF_DATA, "Empty response");
193 return nullptr;
194 }
195
196 // First byte is response type.
197 const guint8* data =
198 static_cast<const guint8*>(g_bytes_get_data(message, nullptr));
199 guint8 type = data[0];
200 size_t offset = 1;
201
202 g_autoptr(FlMethodResponse) response = nullptr;
203 if (type == kEnvelopeTypeError) {
205 self->message_codec, message, &offset, error);
206 if (code == nullptr) {
207 return nullptr;
208 }
211 "Error code wrong type");
212 return nullptr;
213 }
214
215 g_autoptr(FlValue) error_message = fl_standard_message_codec_read_value(
216 self->message_codec, message, &offset, error);
217 if (error_message == nullptr) {
218 return nullptr;
219 }
220 if (fl_value_get_type(error_message) != FL_VALUE_TYPE_STRING &&
221 fl_value_get_type(error_message) != FL_VALUE_TYPE_NULL) {
223 "Error message wrong type");
224 return nullptr;
225 }
226
228 self->message_codec, message, &offset, error);
229 if (details == nullptr) {
230 return nullptr;
231 }
232
233 response = FL_METHOD_RESPONSE(fl_method_error_response_new(
236 ? fl_value_get_string(error_message)
237 : nullptr,
238 fl_value_get_type(details) != FL_VALUE_TYPE_NULL ? details : nullptr));
239 } else if (type == kEnvelopeTypeSuccess) {
241 self->message_codec, message, &offset, error);
242
243 if (result == nullptr) {
244 return nullptr;
245 }
246
247 response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
248 } else {
250 "Unknown envelope type %02x", type);
251 return nullptr;
252 }
253
254 if (offset != g_bytes_get_size(message)) {
256 "Unexpected extra data");
257 return nullptr;
258 }
259
260 return FL_METHOD_RESPONSE(g_object_ref(response));
261}
262
264 FlStandardMethodCodecClass* klass) {
265 G_OBJECT_CLASS(klass)->set_property = fl_standard_method_codec_set_property;
266 G_OBJECT_CLASS(klass)->get_property = fl_standard_method_codec_get_property;
267 G_OBJECT_CLASS(klass)->dispose = fl_standard_method_codec_dispose;
268
269 FL_METHOD_CODEC_CLASS(klass)->encode_method_call =
271 FL_METHOD_CODEC_CLASS(klass)->decode_method_call =
273 FL_METHOD_CODEC_CLASS(klass)->encode_success_envelope =
275 FL_METHOD_CODEC_CLASS(klass)->encode_error_envelope =
277 FL_METHOD_CODEC_CLASS(klass)->decode_response =
279
280 g_object_class_install_property(
281 G_OBJECT_CLASS(klass), kPropMessageCodec,
282 g_param_spec_object(
283 "message-codec", "message-codec", "Message codec to use",
284 fl_message_codec_get_type(),
285 static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
286 G_PARAM_STATIC_STRINGS)));
287}
288
289static void fl_standard_method_codec_init(FlStandardMethodCodec* self) {}
290
291G_MODULE_EXPORT FlStandardMethodCodec* fl_standard_method_codec_new() {
292 g_autoptr(FlStandardMessageCodec) message_codec =
295}
296
297G_MODULE_EXPORT FlStandardMethodCodec*
299 FlStandardMessageCodec* message_codec) {
300 return FL_STANDARD_METHOD_CODEC(
301 g_object_new(fl_standard_method_codec_get_type(), "message-codec",
302 message_codec, nullptr));
303}
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
@ FL_MESSAGE_CODEC_ERROR_OUT_OF_DATA
@ FL_MESSAGE_CODEC_ERROR_FAILED
#define FL_MESSAGE_CODEC_ERROR
G_MODULE_EXPORT FlMethodErrorResponse * fl_method_error_response_new(const gchar *code, const gchar *message, FlValue *details)
G_MODULE_EXPORT FlMethodSuccessResponse * fl_method_success_response_new(FlValue *result)
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
G_MODULE_EXPORT gboolean fl_standard_message_codec_write_value(FlStandardMessageCodec *self, GByteArray *buffer, FlValue *value, GError **error)
G_MODULE_EXPORT FlValue * fl_standard_message_codec_read_value(FlStandardMessageCodec *self, GBytes *buffer, size_t *offset, GError **error)
G_MODULE_EXPORT FlStandardMessageCodec * fl_standard_message_codec_new()
g_byte_array_append(buffer, &type, sizeof(uint8_t))
static constexpr guint8 kEnvelopeTypeError
static void fl_standard_method_codec_dispose(GObject *object)
G_MODULE_EXPORT FlStandardMethodCodec * fl_standard_method_codec_new_with_message_codec(FlStandardMessageCodec *message_codec)
static void fl_standard_method_codec_class_init(FlStandardMethodCodecClass *klass)
static void fl_standard_method_codec_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
static FlMethodResponse * fl_standard_method_codec_decode_response(FlMethodCodec *codec, GBytes *message, GError **error)
G_MODULE_EXPORT FlStandardMethodCodec * fl_standard_method_codec_new()
static gboolean fl_standard_method_codec_decode_method_call(FlMethodCodec *codec, GBytes *message, gchar **name, FlValue **args, GError **error)
static constexpr guint8 kEnvelopeTypeSuccess
guint const GValue * value
static GBytes * fl_standard_method_codec_encode_method_call(FlMethodCodec *codec, const gchar *name, FlValue *args, GError **error)
static void fl_standard_method_codec_init(FlStandardMethodCodec *self)
guint const GValue GParamSpec * pspec
static GBytes * fl_standard_method_codec_encode_success_envelope(FlMethodCodec *codec, FlValue *result, GError **error)
G_DEFINE_TYPE(FlStandardMethodCodec, fl_standard_method_codec, fl_method_codec_get_type()) static void fl_standard_method_codec_set_property(GObject *object
static GBytes * fl_standard_method_codec_encode_error_envelope(FlMethodCodec *codec, const gchar *code, const gchar *message, FlValue *details, GError **error)
GAsyncResult * result
G_MODULE_EXPORT FlValue * fl_value_ref(FlValue *self)
Definition fl_value.cc:394
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition fl_value.cc:466
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition fl_value.cc:276
G_MODULE_EXPORT const gchar * fl_value_get_string(FlValue *self)
Definition fl_value.cc:682
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition fl_value.h:42
@ FL_VALUE_TYPE_STRING
Definition fl_value.h:69
@ FL_VALUE_TYPE_NULL
Definition fl_value.h:65
const char * name
Definition fuchsia.cc:50
Win32Message message
return FALSE
Point offset
FlStandardMessageCodec * message_codec