Skip to content

Commit 9ea2db5

Browse files
Add FlMessageCodec, FlBinaryCodec, FlStringCodec (flutter#18186)
Classs for binary message encoding/decoding that matches the ones in the Flutter services library.
1 parent 9b905d3 commit 9ea2db5

15 files changed

+788
-0
lines changed

ci/licenses_golden/licenses_flutter

+9
Original file line numberDiff line numberDiff line change
@@ -1184,22 +1184,31 @@ FILE: ../../../flutter/shell/platform/glfw/platform_handler.h
11841184
FILE: ../../../flutter/shell/platform/glfw/public/flutter_glfw.h
11851185
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.cc
11861186
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.h
1187+
FILE: ../../../flutter/shell/platform/linux/fl_binary_codec.cc
1188+
FILE: ../../../flutter/shell/platform/linux/fl_binary_codec_test.cc
11871189
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger.cc
11881190
FILE: ../../../flutter/shell/platform/linux/fl_binary_messenger_private.h
11891191
FILE: ../../../flutter/shell/platform/linux/fl_dart_project.cc
11901192
FILE: ../../../flutter/shell/platform/linux/fl_dart_project_test.cc
11911193
FILE: ../../../flutter/shell/platform/linux/fl_engine.cc
11921194
FILE: ../../../flutter/shell/platform/linux/fl_engine_private.h
1195+
FILE: ../../../flutter/shell/platform/linux/fl_message_codec.cc
1196+
FILE: ../../../flutter/shell/platform/linux/fl_message_codec_test.cc
11931197
FILE: ../../../flutter/shell/platform/linux/fl_renderer.cc
11941198
FILE: ../../../flutter/shell/platform/linux/fl_renderer.h
11951199
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.cc
11961200
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.h
1201+
FILE: ../../../flutter/shell/platform/linux/fl_string_codec.cc
1202+
FILE: ../../../flutter/shell/platform/linux/fl_string_codec_test.cc
11971203
FILE: ../../../flutter/shell/platform/linux/fl_value.cc
11981204
FILE: ../../../flutter/shell/platform/linux/fl_value_test.cc
11991205
FILE: ../../../flutter/shell/platform/linux/fl_view.cc
1206+
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_binary_codec.h
12001207
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h
12011208
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h
12021209
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_engine.h
1210+
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_message_codec.h
1211+
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_string_codec.h
12031212
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_value.h
12041213
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_view.h
12051214
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/flutter_linux.h

shell/platform/linux/BUILD.gn

+10
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,12 @@ if (build_glfw_shell) {
4444
}
4545

4646
_public_headers = [
47+
"public/flutter_linux/fl_binary_codec.h",
4748
"public/flutter_linux/fl_binary_messenger.h",
4849
"public/flutter_linux/fl_dart_project.h",
4950
"public/flutter_linux/fl_engine.h",
51+
"public/flutter_linux/fl_message_codec.h",
52+
"public/flutter_linux/fl_string_codec.h",
5053
"public/flutter_linux/fl_value.h",
5154
"public/flutter_linux/fl_view.h",
5255
"public/flutter_linux/flutter_linux.h",
@@ -60,11 +63,14 @@ source_set("flutter_linux") {
6063
public = _public_headers
6164

6265
sources = [
66+
"fl_binary_codec.cc",
6367
"fl_binary_messenger.cc",
6468
"fl_dart_project.cc",
6569
"fl_engine.cc",
70+
"fl_message_codec.cc",
6671
"fl_renderer.cc",
6772
"fl_renderer_x11.cc",
73+
"fl_string_codec.cc",
6874
"fl_value.cc",
6975
"fl_view.cc",
7076
]
@@ -91,8 +97,12 @@ executable("flutter_linux_unittests") {
9197
testonly = true
9298

9399
sources = [
100+
"fl_binary_codec_test.cc",
94101
"fl_dart_project_test.cc",
102+
"fl_message_codec_test.cc",
103+
"fl_string_codec_test.cc",
95104
"fl_value_test.cc",
105+
"testing/fl_test.cc",
96106
]
97107

98108
public_configs = [ "//flutter:config" ]
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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_binary_codec.h"
6+
7+
#include <gmodule.h>
8+
9+
G_DEFINE_QUARK(fl_binary_codec_error_quark, fl_binary_codec_error)
10+
11+
struct _FlBinaryCodec {
12+
FlMessageCodec parent_instance;
13+
};
14+
15+
G_DEFINE_TYPE(FlBinaryCodec, fl_binary_codec, fl_message_codec_get_type())
16+
17+
// Implements FlMessageCodec::encode_message
18+
static GBytes* fl_binary_codec_encode_message(FlMessageCodec* codec,
19+
FlValue* value,
20+
GError** error) {
21+
if (fl_value_get_type(value) != FL_VALUE_TYPE_UINT8_LIST) {
22+
g_set_error(error, FL_MESSAGE_CODEC_ERROR,
23+
FL_MESSAGE_CODEC_ERROR_UNSUPPORTED_TYPE,
24+
"Only uint8[] values supported");
25+
return nullptr;
26+
}
27+
28+
return g_bytes_new(fl_value_get_uint8_list(value),
29+
fl_value_get_length(value));
30+
}
31+
32+
// Implements FlMessageCodec::decode_message
33+
static FlValue* fl_binary_codec_decode_message(FlMessageCodec* codec,
34+
GBytes* message,
35+
GError** error) {
36+
gsize data_length;
37+
const uint8_t* data =
38+
static_cast<const uint8_t*>(g_bytes_get_data(message, &data_length));
39+
return fl_value_new_uint8_list(data, data_length);
40+
}
41+
42+
static void fl_binary_codec_class_init(FlBinaryCodecClass* klass) {
43+
FL_MESSAGE_CODEC_CLASS(klass)->encode_message =
44+
fl_binary_codec_encode_message;
45+
FL_MESSAGE_CODEC_CLASS(klass)->decode_message =
46+
fl_binary_codec_decode_message;
47+
}
48+
49+
static void fl_binary_codec_init(FlBinaryCodec* self) {}
50+
51+
G_MODULE_EXPORT FlBinaryCodec* fl_binary_codec_new() {
52+
return static_cast<FlBinaryCodec*>(
53+
g_object_new(fl_binary_codec_get_type(), nullptr));
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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_binary_codec.h"
6+
#include "flutter/shell/platform/linux/testing/fl_test.h"
7+
#include "gtest/gtest.h"
8+
9+
// Encode a message using a FlBinaryCodec. Return a hex string with the encoded
10+
// binary output.
11+
static gchar* encode_message(FlValue* value) {
12+
g_autoptr(FlBinaryCodec) codec = fl_binary_codec_new();
13+
g_autoptr(GError) error = nullptr;
14+
g_autoptr(GBytes) message =
15+
fl_message_codec_encode_message(FL_MESSAGE_CODEC(codec), value, &error);
16+
EXPECT_NE(message, nullptr);
17+
EXPECT_EQ(error, nullptr);
18+
19+
return bytes_to_hex_string(message);
20+
}
21+
22+
// Encode a message using a FlBinaryCodec. Expect the given error.
23+
static void encode_message_error(FlValue* value, GQuark domain, int code) {
24+
g_autoptr(FlBinaryCodec) codec = fl_binary_codec_new();
25+
g_autoptr(GError) error = nullptr;
26+
g_autoptr(GBytes) message =
27+
fl_message_codec_encode_message(FL_MESSAGE_CODEC(codec), value, &error);
28+
EXPECT_EQ(message, nullptr);
29+
EXPECT_TRUE(g_error_matches(error, domain, code));
30+
}
31+
32+
// Decode a message using a FlBinaryCodec. The binary data is given in the form
33+
// of a hex string.
34+
static FlValue* decode_message(const char* hex_string) {
35+
g_autoptr(FlBinaryCodec) codec = fl_binary_codec_new();
36+
g_autoptr(GBytes) data = hex_string_to_bytes(hex_string);
37+
g_autoptr(GError) error = nullptr;
38+
g_autoptr(FlValue) value =
39+
fl_message_codec_decode_message(FL_MESSAGE_CODEC(codec), data, &error);
40+
EXPECT_EQ(error, nullptr);
41+
EXPECT_NE(value, nullptr);
42+
return fl_value_ref(value);
43+
}
44+
45+
TEST(FlBinaryCodecTest, EncodeData) {
46+
uint8_t data[] = {0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF};
47+
g_autoptr(FlValue) value = fl_value_new_uint8_list(data, 6);
48+
g_autofree gchar* hex_string = encode_message(value);
49+
EXPECT_STREQ(hex_string, "000102fdfeff");
50+
}
51+
52+
TEST(FlBinaryCodecTest, EncodeEmpty) {
53+
g_autoptr(FlValue) value = fl_value_new_uint8_list(nullptr, 0);
54+
g_autofree gchar* hex_string = encode_message(value);
55+
EXPECT_STREQ(hex_string, "");
56+
}
57+
58+
TEST(FlBinaryCodecTest, EncodeNULL) {
59+
encode_message_error(nullptr, FL_MESSAGE_CODEC_ERROR,
60+
FL_MESSAGE_CODEC_ERROR_UNSUPPORTED_TYPE);
61+
}
62+
63+
TEST(FlBinaryCodecTest, EncodeUnknownType) {
64+
g_autoptr(FlValue) value = fl_value_new_null();
65+
encode_message_error(value, FL_MESSAGE_CODEC_ERROR,
66+
FL_MESSAGE_CODEC_ERROR_UNSUPPORTED_TYPE);
67+
}
68+
69+
TEST(FlBinaryCodecTest, DecodeData) {
70+
g_autoptr(FlValue) value = decode_message("000102fdfeff");
71+
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_UINT8_LIST);
72+
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(6));
73+
EXPECT_EQ(fl_value_get_uint8_list(value)[0], 0x00);
74+
EXPECT_EQ(fl_value_get_uint8_list(value)[1], 0x01);
75+
EXPECT_EQ(fl_value_get_uint8_list(value)[2], 0x02);
76+
EXPECT_EQ(fl_value_get_uint8_list(value)[3], 0xFD);
77+
EXPECT_EQ(fl_value_get_uint8_list(value)[4], 0xFE);
78+
EXPECT_EQ(fl_value_get_uint8_list(value)[5], 0xFF);
79+
}
80+
81+
TEST(FlBinaryCodecTest, DecodeEmpty) {
82+
g_autoptr(FlValue) value = decode_message("");
83+
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_UINT8_LIST);
84+
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(0));
85+
}
86+
87+
TEST(FlBinaryCodecTest, EncodeDecode) {
88+
g_autoptr(FlBinaryCodec) codec = fl_binary_codec_new();
89+
90+
uint8_t data[] = {0x00, 0x01, 0x02, 0xFD, 0xFE, 0xFF};
91+
g_autoptr(FlValue) input = fl_value_new_uint8_list(data, 6);
92+
93+
g_autoptr(GError) error = nullptr;
94+
g_autoptr(GBytes) message =
95+
fl_message_codec_encode_message(FL_MESSAGE_CODEC(codec), input, &error);
96+
EXPECT_NE(message, nullptr);
97+
EXPECT_EQ(error, nullptr);
98+
99+
g_autoptr(FlValue) output =
100+
fl_message_codec_decode_message(FL_MESSAGE_CODEC(codec), message, &error);
101+
EXPECT_EQ(error, nullptr);
102+
EXPECT_NE(output, nullptr);
103+
104+
ASSERT_TRUE(fl_value_equal(input, output));
105+
}
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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_message_codec.h"
6+
7+
#include <gmodule.h>
8+
9+
G_DEFINE_QUARK(fl_message_codec_error_quark, fl_message_codec_error)
10+
11+
// Added here to stop the compiler from optimising this function away
12+
G_MODULE_EXPORT GType fl_message_codec_get_type();
13+
14+
G_DEFINE_TYPE(FlMessageCodec, fl_message_codec, G_TYPE_OBJECT)
15+
16+
static void fl_message_codec_class_init(FlMessageCodecClass* klass) {}
17+
18+
static void fl_message_codec_init(FlMessageCodec* self) {}
19+
20+
G_MODULE_EXPORT GBytes* fl_message_codec_encode_message(FlMessageCodec* self,
21+
FlValue* value,
22+
GError** error) {
23+
g_return_val_if_fail(FL_IS_MESSAGE_CODEC(self), nullptr);
24+
25+
// If the user provided NULL, then make a temporary FlValue object for this to
26+
// make it simpler for the subclasses
27+
g_autoptr(FlValue) null_value = nullptr;
28+
if (value == nullptr) {
29+
null_value = fl_value_new_null();
30+
value = null_value;
31+
}
32+
33+
return FL_MESSAGE_CODEC_GET_CLASS(self)->encode_message(self, value, error);
34+
}
35+
36+
G_MODULE_EXPORT FlValue* fl_message_codec_decode_message(FlMessageCodec* self,
37+
GBytes* message,
38+
GError** error) {
39+
g_return_val_if_fail(FL_IS_MESSAGE_CODEC(self), nullptr);
40+
g_return_val_if_fail(message != nullptr, nullptr);
41+
42+
return FL_MESSAGE_CODEC_GET_CLASS(self)->decode_message(self, message, error);
43+
}

0 commit comments

Comments
 (0)