mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add FlStandardMessageCodec (#18213)
This commit is contained in:
parent
b1622c2ba4
commit
2f6bcdeb94
@ -1199,6 +1199,9 @@ FILE: ../../../flutter/shell/platform/linux/fl_renderer.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_renderer.h
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_renderer_x11.h
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_standard_message_codec.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_standard_message_codec_private.h
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_standard_message_codec_test.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_string_codec.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_string_codec_test.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_value.cc
|
||||
@ -1209,6 +1212,7 @@ FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_binary_messe
|
||||
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h
|
||||
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_engine.h
|
||||
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_message_codec.h
|
||||
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_standard_message_codec.h
|
||||
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_string_codec.h
|
||||
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_value.h
|
||||
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_view.h
|
||||
|
||||
@ -49,6 +49,7 @@ _public_headers = [
|
||||
"public/flutter_linux/fl_dart_project.h",
|
||||
"public/flutter_linux/fl_engine.h",
|
||||
"public/flutter_linux/fl_message_codec.h",
|
||||
"public/flutter_linux/fl_standard_message_codec.h",
|
||||
"public/flutter_linux/fl_string_codec.h",
|
||||
"public/flutter_linux/fl_value.h",
|
||||
"public/flutter_linux/fl_view.h",
|
||||
@ -70,6 +71,7 @@ source_set("flutter_linux") {
|
||||
"fl_message_codec.cc",
|
||||
"fl_renderer.cc",
|
||||
"fl_renderer_x11.cc",
|
||||
"fl_standard_message_codec.cc",
|
||||
"fl_string_codec.cc",
|
||||
"fl_value.cc",
|
||||
"fl_view.cc",
|
||||
@ -100,6 +102,7 @@ executable("flutter_linux_unittests") {
|
||||
"fl_binary_codec_test.cc",
|
||||
"fl_dart_project_test.cc",
|
||||
"fl_message_codec_test.cc",
|
||||
"fl_standard_message_codec_test.cc",
|
||||
"fl_string_codec_test.cc",
|
||||
"fl_value_test.cc",
|
||||
"testing/fl_test.cc",
|
||||
|
||||
563
shell/platform/linux/fl_standard_message_codec.cc
Normal file
563
shell/platform/linux/fl_standard_message_codec.cc
Normal file
@ -0,0 +1,563 @@
|
||||
// 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.
|
||||
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_message_codec.h"
|
||||
#include "flutter/shell/platform/linux/fl_standard_message_codec_private.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
// See lib/src/services/message_codecs.dart in Flutter source for description of
|
||||
// encoding.
|
||||
|
||||
// Type values.
|
||||
static constexpr int kValueNull = 0;
|
||||
static constexpr int kValueTrue = 1;
|
||||
static constexpr int kValueFalse = 2;
|
||||
static constexpr int kValueInt32 = 3;
|
||||
static constexpr int kValueInt64 = 4;
|
||||
static constexpr int kValueFloat64 = 6;
|
||||
static constexpr int kValueString = 7;
|
||||
static constexpr int kValueUint8List = 8;
|
||||
static constexpr int kValueInt32List = 9;
|
||||
static constexpr int kValueInt64List = 10;
|
||||
static constexpr int kValueFloat64List = 11;
|
||||
static constexpr int kValueList = 12;
|
||||
static constexpr int kValueMap = 13;
|
||||
|
||||
struct _FlStandardMessageCodec {
|
||||
FlMessageCodec parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FlStandardMessageCodec,
|
||||
fl_standard_message_codec,
|
||||
fl_message_codec_get_type())
|
||||
|
||||
// Functions to write standard C number types.
|
||||
|
||||
static void write_uint8(GByteArray* buffer, uint8_t value) {
|
||||
g_byte_array_append(buffer, &value, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
static void write_uint16(GByteArray* buffer, uint16_t value) {
|
||||
g_byte_array_append(buffer, reinterpret_cast<uint8_t*>(&value),
|
||||
sizeof(uint16_t));
|
||||
}
|
||||
|
||||
static void write_uint32(GByteArray* buffer, uint32_t value) {
|
||||
g_byte_array_append(buffer, reinterpret_cast<uint8_t*>(&value),
|
||||
sizeof(uint32_t));
|
||||
}
|
||||
|
||||
static void write_int32(GByteArray* buffer, int32_t value) {
|
||||
g_byte_array_append(buffer, reinterpret_cast<uint8_t*>(&value),
|
||||
sizeof(int32_t));
|
||||
}
|
||||
|
||||
static void write_int64(GByteArray* buffer, int64_t value) {
|
||||
g_byte_array_append(buffer, reinterpret_cast<uint8_t*>(&value),
|
||||
sizeof(int64_t));
|
||||
}
|
||||
|
||||
static void write_float64(GByteArray* buffer, double value) {
|
||||
g_byte_array_append(buffer, reinterpret_cast<uint8_t*>(&value),
|
||||
sizeof(double));
|
||||
}
|
||||
|
||||
// Checks there is enough data in @buffer to be read.
|
||||
static gboolean check_size(GBytes* buffer,
|
||||
size_t offset,
|
||||
size_t required,
|
||||
GError** error) {
|
||||
if (offset + required > g_bytes_get_size(buffer)) {
|
||||
g_set_error(error, FL_MESSAGE_CODEC_ERROR,
|
||||
FL_MESSAGE_CODEC_ERROR_OUT_OF_DATA, "Unexpected end of data");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Gets a pointer to the given offset in @buffer.
|
||||
static const uint8_t* get_data(GBytes* buffer, size_t* offset) {
|
||||
return static_cast<const uint8_t*>(g_bytes_get_data(buffer, nullptr)) +
|
||||
*offset;
|
||||
}
|
||||
|
||||
// Reads an unsigned 8 bit number from @buffer and writes it to @value.
|
||||
// Returns TRUE if successful, otherwise sets an error.
|
||||
static gboolean read_uint8(GBytes* buffer,
|
||||
size_t* offset,
|
||||
uint8_t* value,
|
||||
GError** error) {
|
||||
if (!check_size(buffer, *offset, sizeof(uint8_t), error))
|
||||
return FALSE;
|
||||
|
||||
*value = get_data(buffer, offset)[0];
|
||||
(*offset)++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Reads an unsigned 16 bit integer from @buffer and writes it to @value.
|
||||
// Returns TRUE if successful, otherwise sets an error.
|
||||
static gboolean read_uint16(GBytes* buffer,
|
||||
size_t* offset,
|
||||
uint16_t* value,
|
||||
GError** error) {
|
||||
if (!check_size(buffer, *offset, sizeof(uint16_t), error))
|
||||
return FALSE;
|
||||
|
||||
*value = reinterpret_cast<const uint16_t*>(get_data(buffer, offset))[0];
|
||||
*offset += sizeof(uint16_t);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Reads an unsigned 32 bit integer from @buffer and writes it to @value.
|
||||
// Returns TRUE if successful, otherwise sets an error.
|
||||
static gboolean read_uint32(GBytes* buffer,
|
||||
size_t* offset,
|
||||
uint32_t* value,
|
||||
GError** error) {
|
||||
if (!check_size(buffer, *offset, sizeof(uint32_t), error))
|
||||
return FALSE;
|
||||
|
||||
*value = reinterpret_cast<const uint32_t*>(get_data(buffer, offset))[0];
|
||||
*offset += sizeof(uint32_t);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Reads a #FL_VALUE_TYPE_INT stored as a signed 32 bit integer from @buffer.
|
||||
// Returns a new #FlValue of type #FL_VALUE_TYPE_INT if successful or %NULL on
|
||||
// error.
|
||||
static FlValue* read_int32_value(GBytes* buffer,
|
||||
size_t* offset,
|
||||
GError** error) {
|
||||
if (!check_size(buffer, *offset, sizeof(int32_t), error))
|
||||
return nullptr;
|
||||
|
||||
FlValue* value = fl_value_new_int(
|
||||
reinterpret_cast<const int32_t*>(get_data(buffer, offset))[0]);
|
||||
*offset += sizeof(int32_t);
|
||||
return value;
|
||||
}
|
||||
|
||||
// Reads a #FL_VALUE_TYPE_INT stored as a signed 64 bit integer from @buffer.
|
||||
// Returns a new #FlValue of type #FL_VALUE_TYPE_INT if successful or %NULL on
|
||||
// error.
|
||||
static FlValue* read_int64_value(GBytes* buffer,
|
||||
size_t* offset,
|
||||
GError** error) {
|
||||
if (!check_size(buffer, *offset, sizeof(int64_t), error))
|
||||
return nullptr;
|
||||
|
||||
FlValue* value = fl_value_new_int(
|
||||
reinterpret_cast<const int64_t*>(get_data(buffer, offset))[0]);
|
||||
*offset += sizeof(int64_t);
|
||||
return value;
|
||||
}
|
||||
|
||||
// Reads a 64 bit floating point number from @buffer and writes it to @value.
|
||||
// Returns a new #FlValue of type #FL_VALUE_TYPE_FLOAT if successful or %NULL on
|
||||
// error.
|
||||
static FlValue* read_float64_value(GBytes* buffer,
|
||||
size_t* offset,
|
||||
GError** error) {
|
||||
if (!check_size(buffer, *offset, sizeof(double), error))
|
||||
return nullptr;
|
||||
|
||||
FlValue* value = fl_value_new_float(
|
||||
reinterpret_cast<const double*>(get_data(buffer, offset))[0]);
|
||||
*offset += sizeof(double);
|
||||
return value;
|
||||
}
|
||||
|
||||
// Reads an UTF-8 text string from @buffer in standard codec format.
|
||||
// Returns a new #FlValue of type #FL_VALUE_TYPE_STRING if successful or %NULL
|
||||
// on error.
|
||||
static FlValue* read_string_value(FlStandardMessageCodec* self,
|
||||
GBytes* buffer,
|
||||
size_t* offset,
|
||||
GError** error) {
|
||||
uint32_t length;
|
||||
if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
|
||||
error))
|
||||
return nullptr;
|
||||
if (!check_size(buffer, *offset, length, error))
|
||||
return nullptr;
|
||||
FlValue* value = fl_value_new_string_sized(
|
||||
reinterpret_cast<const gchar*>(get_data(buffer, offset)), length);
|
||||
*offset += length;
|
||||
return value;
|
||||
}
|
||||
|
||||
// Reads an unsigned 8 bit list from @buffer in standard codec format.
|
||||
// Returns a new #FlValue of type #FL_VALUE_TYPE_UINT8_LIST if successful or
|
||||
// %NULL on error.
|
||||
static FlValue* read_uint8_list_value(FlStandardMessageCodec* self,
|
||||
GBytes* buffer,
|
||||
size_t* offset,
|
||||
GError** error) {
|
||||
uint32_t length;
|
||||
if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
|
||||
error))
|
||||
return nullptr;
|
||||
if (!check_size(buffer, *offset, sizeof(uint8_t) * length, error))
|
||||
return nullptr;
|
||||
FlValue* value = fl_value_new_uint8_list(get_data(buffer, offset), length);
|
||||
*offset += length;
|
||||
return value;
|
||||
}
|
||||
|
||||
// Reads a signed 32 bit list from @buffer in standard codec format.
|
||||
// Returns a new #FlValue of type #FL_VALUE_TYPE_INT32_LIST if successful or
|
||||
// %NULL on error.
|
||||
static FlValue* read_int32_list_value(FlStandardMessageCodec* self,
|
||||
GBytes* buffer,
|
||||
size_t* offset,
|
||||
GError** error) {
|
||||
uint32_t length;
|
||||
if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
|
||||
error))
|
||||
return nullptr;
|
||||
if (!check_size(buffer, *offset, sizeof(int32_t) * length, error))
|
||||
return nullptr;
|
||||
FlValue* value = fl_value_new_int32_list(
|
||||
reinterpret_cast<const int32_t*>(get_data(buffer, offset)), length);
|
||||
*offset += sizeof(int32_t) * length;
|
||||
return value;
|
||||
}
|
||||
|
||||
// Reads a signed 64 bit list from @buffer in standard codec format.
|
||||
// Returns a new #FlValue of type #FL_VALUE_TYPE_INT64_LIST if successful or
|
||||
// %NULL on error.
|
||||
static FlValue* read_int64_list_value(FlStandardMessageCodec* self,
|
||||
GBytes* buffer,
|
||||
size_t* offset,
|
||||
GError** error) {
|
||||
uint32_t length;
|
||||
if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
|
||||
error))
|
||||
return nullptr;
|
||||
if (!check_size(buffer, *offset, sizeof(int64_t) * length, error))
|
||||
return nullptr;
|
||||
FlValue* value = fl_value_new_int64_list(
|
||||
reinterpret_cast<const int64_t*>(get_data(buffer, offset)), length);
|
||||
*offset += sizeof(int64_t) * length;
|
||||
return value;
|
||||
}
|
||||
|
||||
// Reads a floating point number list from @buffer in standard codec format.
|
||||
// Returns a new #FlValue of type #FL_VALUE_TYPE_FLOAT_LIST if successful or
|
||||
// %NULL on error.
|
||||
static FlValue* read_float64_list_value(FlStandardMessageCodec* self,
|
||||
GBytes* buffer,
|
||||
size_t* offset,
|
||||
GError** error) {
|
||||
uint32_t length;
|
||||
if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
|
||||
error))
|
||||
return nullptr;
|
||||
if (!check_size(buffer, *offset, sizeof(double) * length, error))
|
||||
return nullptr;
|
||||
FlValue* value = fl_value_new_float_list(
|
||||
reinterpret_cast<const double*>(get_data(buffer, offset)), length);
|
||||
*offset += sizeof(double) * length;
|
||||
return value;
|
||||
}
|
||||
|
||||
// Reads a list from @buffer in standard codec format.
|
||||
// Returns a new #FlValue of type #FL_VALUE_TYPE_LIST if successful or %NULL on
|
||||
// error.
|
||||
static FlValue* read_list_value(FlStandardMessageCodec* self,
|
||||
GBytes* buffer,
|
||||
size_t* offset,
|
||||
GError** error) {
|
||||
uint32_t length;
|
||||
if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
|
||||
error))
|
||||
return nullptr;
|
||||
|
||||
g_autoptr(FlValue) list = fl_value_new_list();
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
g_autoptr(FlValue) child =
|
||||
fl_standard_message_codec_read_value(self, buffer, offset, error);
|
||||
if (child == nullptr)
|
||||
return nullptr;
|
||||
fl_value_append(list, child);
|
||||
}
|
||||
|
||||
return fl_value_ref(list);
|
||||
}
|
||||
|
||||
// Reads a map from @buffer in standard codec format.
|
||||
// Returns a new #FlValue of type #FL_VALUE_TYPE_MAP if successful or %NULL on
|
||||
// error.
|
||||
static FlValue* read_map_value(FlStandardMessageCodec* self,
|
||||
GBytes* buffer,
|
||||
size_t* offset,
|
||||
GError** error) {
|
||||
uint32_t length;
|
||||
if (!fl_standard_message_codec_read_size(self, buffer, offset, &length,
|
||||
error))
|
||||
return nullptr;
|
||||
|
||||
g_autoptr(FlValue) map = fl_value_new_map();
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
g_autoptr(FlValue) key =
|
||||
fl_standard_message_codec_read_value(self, buffer, offset, error);
|
||||
if (key == nullptr)
|
||||
return nullptr;
|
||||
g_autoptr(FlValue) value =
|
||||
fl_standard_message_codec_read_value(self, buffer, offset, error);
|
||||
if (value == nullptr)
|
||||
return nullptr;
|
||||
fl_value_set(map, key, value);
|
||||
}
|
||||
|
||||
return fl_value_ref(map);
|
||||
}
|
||||
|
||||
// Implements FlMessageCodec::encode_message.
|
||||
static GBytes* fl_standard_message_codec_encode_message(FlMessageCodec* codec,
|
||||
FlValue* message,
|
||||
GError** error) {
|
||||
FlStandardMessageCodec* self =
|
||||
reinterpret_cast<FlStandardMessageCodec*>(codec);
|
||||
|
||||
g_autoptr(GByteArray) buffer = g_byte_array_new();
|
||||
if (!fl_standard_message_codec_write_value(self, buffer, message, error))
|
||||
return nullptr;
|
||||
return g_byte_array_free_to_bytes(
|
||||
static_cast<GByteArray*>(g_steal_pointer(&buffer)));
|
||||
}
|
||||
|
||||
// Implements FlMessageCodec::decode_message.
|
||||
static FlValue* fl_standard_message_codec_decode_message(FlMessageCodec* codec,
|
||||
GBytes* message,
|
||||
GError** error) {
|
||||
FlStandardMessageCodec* self =
|
||||
reinterpret_cast<FlStandardMessageCodec*>(codec);
|
||||
|
||||
size_t offset = 0;
|
||||
g_autoptr(FlValue) value =
|
||||
fl_standard_message_codec_read_value(self, message, &offset, error);
|
||||
if (value == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (offset != g_bytes_get_size(message)) {
|
||||
g_set_error(error, FL_MESSAGE_CODEC_ERROR,
|
||||
FL_MESSAGE_CODEC_ERROR_ADDITIONAL_DATA,
|
||||
"Unused %zi bytes after standard message",
|
||||
g_bytes_get_size(message) - offset);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return fl_value_ref(value);
|
||||
}
|
||||
|
||||
static void fl_standard_message_codec_class_init(
|
||||
FlStandardMessageCodecClass* klass) {
|
||||
FL_MESSAGE_CODEC_CLASS(klass)->encode_message =
|
||||
fl_standard_message_codec_encode_message;
|
||||
FL_MESSAGE_CODEC_CLASS(klass)->decode_message =
|
||||
fl_standard_message_codec_decode_message;
|
||||
}
|
||||
|
||||
static void fl_standard_message_codec_init(FlStandardMessageCodec* self) {}
|
||||
|
||||
G_MODULE_EXPORT FlStandardMessageCodec* fl_standard_message_codec_new() {
|
||||
return static_cast<FlStandardMessageCodec*>(
|
||||
g_object_new(fl_standard_message_codec_get_type(), nullptr));
|
||||
}
|
||||
|
||||
void fl_standard_message_codec_write_size(FlStandardMessageCodec* codec,
|
||||
GByteArray* buffer,
|
||||
uint32_t size) {
|
||||
if (size < 254)
|
||||
write_uint8(buffer, size);
|
||||
else if (size <= 0xffff) {
|
||||
write_uint8(buffer, 254);
|
||||
write_uint16(buffer, size);
|
||||
} else {
|
||||
write_uint8(buffer, 255);
|
||||
write_uint32(buffer, size);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean fl_standard_message_codec_read_size(FlStandardMessageCodec* codec,
|
||||
GBytes* buffer,
|
||||
size_t* offset,
|
||||
uint32_t* value,
|
||||
GError** error) {
|
||||
uint8_t value8;
|
||||
if (!read_uint8(buffer, offset, &value8, error))
|
||||
return FALSE;
|
||||
|
||||
if (value8 == 255) {
|
||||
if (!read_uint32(buffer, offset, value, error))
|
||||
return FALSE;
|
||||
} else if (value8 == 254) {
|
||||
uint16_t value16;
|
||||
if (!read_uint16(buffer, offset, &value16, error))
|
||||
return FALSE;
|
||||
*value = value16;
|
||||
} else
|
||||
*value = value8;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean fl_standard_message_codec_write_value(FlStandardMessageCodec* self,
|
||||
GByteArray* buffer,
|
||||
FlValue* value,
|
||||
GError** error) {
|
||||
if (value == nullptr) {
|
||||
write_uint8(buffer, kValueNull);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
switch (fl_value_get_type(value)) {
|
||||
case FL_VALUE_TYPE_NULL:
|
||||
write_uint8(buffer, kValueNull);
|
||||
return TRUE;
|
||||
case FL_VALUE_TYPE_BOOL:
|
||||
if (fl_value_get_bool(value))
|
||||
write_uint8(buffer, kValueTrue);
|
||||
else
|
||||
write_uint8(buffer, kValueFalse);
|
||||
return TRUE;
|
||||
case FL_VALUE_TYPE_INT: {
|
||||
int64_t v = fl_value_get_int(value);
|
||||
if (v >= INT32_MIN && v <= INT32_MAX) {
|
||||
write_uint8(buffer, kValueInt32);
|
||||
write_int32(buffer, v);
|
||||
} else {
|
||||
write_uint8(buffer, kValueInt64);
|
||||
write_int64(buffer, v);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
case FL_VALUE_TYPE_FLOAT:
|
||||
write_uint8(buffer, kValueFloat64);
|
||||
write_float64(buffer, fl_value_get_float(value));
|
||||
return TRUE;
|
||||
case FL_VALUE_TYPE_STRING: {
|
||||
write_uint8(buffer, kValueString);
|
||||
const char* text = fl_value_get_string(value);
|
||||
size_t length = strlen(text);
|
||||
fl_standard_message_codec_write_size(self, buffer, length);
|
||||
g_byte_array_append(buffer, reinterpret_cast<const uint8_t*>(text),
|
||||
length);
|
||||
return TRUE;
|
||||
}
|
||||
case FL_VALUE_TYPE_UINT8_LIST: {
|
||||
write_uint8(buffer, kValueUint8List);
|
||||
size_t length = fl_value_get_length(value);
|
||||
fl_standard_message_codec_write_size(self, buffer, length);
|
||||
g_byte_array_append(buffer, fl_value_get_uint8_list(value),
|
||||
sizeof(uint8_t) * length);
|
||||
return TRUE;
|
||||
}
|
||||
case FL_VALUE_TYPE_INT32_LIST: {
|
||||
write_uint8(buffer, kValueInt32List);
|
||||
size_t length = fl_value_get_length(value);
|
||||
fl_standard_message_codec_write_size(self, buffer, length);
|
||||
g_byte_array_append(
|
||||
buffer,
|
||||
reinterpret_cast<const uint8_t*>(fl_value_get_int32_list(value)),
|
||||
sizeof(int32_t) * length);
|
||||
return TRUE;
|
||||
}
|
||||
case FL_VALUE_TYPE_INT64_LIST: {
|
||||
write_uint8(buffer, kValueInt64List);
|
||||
size_t length = fl_value_get_length(value);
|
||||
fl_standard_message_codec_write_size(self, buffer, length);
|
||||
g_byte_array_append(
|
||||
buffer,
|
||||
reinterpret_cast<const uint8_t*>(fl_value_get_int64_list(value)),
|
||||
sizeof(int64_t) * length);
|
||||
return TRUE;
|
||||
}
|
||||
case FL_VALUE_TYPE_FLOAT_LIST: {
|
||||
write_uint8(buffer, kValueFloat64List);
|
||||
size_t length = fl_value_get_length(value);
|
||||
fl_standard_message_codec_write_size(self, buffer, length);
|
||||
g_byte_array_append(
|
||||
buffer,
|
||||
reinterpret_cast<const uint8_t*>(fl_value_get_float_list(value)),
|
||||
sizeof(double) * length);
|
||||
return TRUE;
|
||||
}
|
||||
case FL_VALUE_TYPE_LIST:
|
||||
write_uint8(buffer, kValueList);
|
||||
fl_standard_message_codec_write_size(self, buffer,
|
||||
fl_value_get_length(value));
|
||||
for (size_t i = 0; i < fl_value_get_length(value); i++) {
|
||||
if (!fl_standard_message_codec_write_value(
|
||||
self, buffer, fl_value_get_list_value(value, i), error))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
case FL_VALUE_TYPE_MAP:
|
||||
write_uint8(buffer, kValueMap);
|
||||
fl_standard_message_codec_write_size(self, buffer,
|
||||
fl_value_get_length(value));
|
||||
for (size_t i = 0; i < fl_value_get_length(value); i++) {
|
||||
if (!fl_standard_message_codec_write_value(
|
||||
self, buffer, fl_value_get_map_key(value, i), error) ||
|
||||
!fl_standard_message_codec_write_value(
|
||||
self, buffer, fl_value_get_map_value(value, i), error))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_set_error(error, FL_MESSAGE_CODEC_ERROR,
|
||||
FL_MESSAGE_CODEC_ERROR_UNSUPPORTED_TYPE,
|
||||
"Unexpected FlValue type %d", fl_value_get_type(value));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FlValue* fl_standard_message_codec_read_value(FlStandardMessageCodec* self,
|
||||
GBytes* buffer,
|
||||
size_t* offset,
|
||||
GError** error) {
|
||||
uint8_t type;
|
||||
if (!read_uint8(buffer, offset, &type, error))
|
||||
return nullptr;
|
||||
|
||||
g_autoptr(FlValue) value = nullptr;
|
||||
if (type == kValueNull)
|
||||
return fl_value_new_null();
|
||||
else if (type == kValueTrue)
|
||||
return fl_value_new_bool(TRUE);
|
||||
else if (type == kValueFalse)
|
||||
return fl_value_new_bool(FALSE);
|
||||
else if (type == kValueInt32)
|
||||
value = read_int32_value(buffer, offset, error);
|
||||
else if (type == kValueInt64)
|
||||
value = read_int64_value(buffer, offset, error);
|
||||
else if (type == kValueFloat64)
|
||||
value = read_float64_value(buffer, offset, error);
|
||||
else if (type == kValueString)
|
||||
value = read_string_value(self, buffer, offset, error);
|
||||
else if (type == kValueUint8List)
|
||||
value = read_uint8_list_value(self, buffer, offset, error);
|
||||
else if (type == kValueInt32List)
|
||||
value = read_int32_list_value(self, buffer, offset, error);
|
||||
else if (type == kValueInt64List)
|
||||
value = read_int64_list_value(self, buffer, offset, error);
|
||||
else if (type == kValueFloat64List)
|
||||
value = read_float64_list_value(self, buffer, offset, error);
|
||||
else if (type == kValueList)
|
||||
value = read_list_value(self, buffer, offset, error);
|
||||
else if (type == kValueMap)
|
||||
value = read_map_value(self, buffer, offset, error);
|
||||
else {
|
||||
g_set_error(error, FL_MESSAGE_CODEC_ERROR,
|
||||
FL_MESSAGE_CODEC_ERROR_UNSUPPORTED_TYPE,
|
||||
"Unexpected standard codec type %02x", type);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return value == nullptr ? nullptr : fl_value_ref(value);
|
||||
}
|
||||
77
shell/platform/linux/fl_standard_message_codec_private.h
Normal file
77
shell/platform/linux/fl_standard_message_codec_private.h
Normal file
@ -0,0 +1,77 @@
|
||||
// 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.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_STANDARD_MESSAGE_CODEC_PRIVATE_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_STANDARD_MESSAGE_CODEC_PRIVATE_H_
|
||||
|
||||
#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_message_codec.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* fl_standard_message_codec_write_size:
|
||||
* @codec: a #FlStandardMessageCodec
|
||||
* @buffer: buffer to write into
|
||||
* @size: size value to write
|
||||
*
|
||||
* Writes a size field in Flutter Standard encoding.
|
||||
*/
|
||||
void fl_standard_message_codec_write_size(FlStandardMessageCodec* codec,
|
||||
GByteArray* buffer,
|
||||
uint32_t size);
|
||||
|
||||
/**
|
||||
* fl_standard_message_codec_read_size:
|
||||
* @codec: a #FlStandardMessageCodec
|
||||
* @buffer: buffer to read from
|
||||
* @offset: (inout): read position in @buffer
|
||||
* @value: location to read size
|
||||
* @error: (allow-none): #GError location to store the error occurring, or %NULL
|
||||
*
|
||||
* Reads a size field in Flutter Standard encoding.
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean fl_standard_message_codec_read_size(FlStandardMessageCodec* codec,
|
||||
GBytes* buffer,
|
||||
size_t* offset,
|
||||
uint32_t* value,
|
||||
GError** error);
|
||||
|
||||
/**
|
||||
* fl_standard_message_codec_write_value:
|
||||
* @codec: a #FlStandardMessageCodec
|
||||
* @buffer: buffer to write into
|
||||
* @value: (allow-none): value to write
|
||||
* @error: (allow-none): #GError location to store the error occurring, or %NULL
|
||||
*
|
||||
* Writes a #FlValue in Flutter Standard encoding.
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean fl_standard_message_codec_write_value(FlStandardMessageCodec* codec,
|
||||
GByteArray* buffer,
|
||||
FlValue* value,
|
||||
GError** error);
|
||||
|
||||
/**
|
||||
* fl_standard_message_codec_read_value:
|
||||
* @codec: a #FlStandardMessageCodec
|
||||
* @buffer: buffer to read from
|
||||
* @offset: (inout): read position in @buffer
|
||||
* @value: location to read size
|
||||
* @error: (allow-none): #GError location to store the error occurring, or %NULL
|
||||
*
|
||||
* Reads a #FlValue in Flutter Standard encoding.
|
||||
*
|
||||
* Returns: a new #FlValue or %NULL on error.
|
||||
*/
|
||||
FlValue* fl_standard_message_codec_read_value(FlStandardMessageCodec* codec,
|
||||
GBytes* buffer,
|
||||
size_t* offset,
|
||||
GError** error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_STANDARD_MESSAGE_CODEC_PRIVATE_H_
|
||||
1032
shell/platform/linux/fl_standard_message_codec_test.cc
Normal file
1032
shell/platform/linux/fl_standard_message_codec_test.cc
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,47 @@
|
||||
// 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.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_STANDARD_MESSAGE_CODEC_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_STANDARD_MESSAGE_CODEC_H_
|
||||
|
||||
#if !defined(__FLUTTER_LINUX_INSIDE__) && !defined(FLUTTER_LINUX_COMPILATION)
|
||||
#error "Only <flutter_linux/flutter_linux.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "fl_message_codec.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FlStandardMessageCodec,
|
||||
fl_standard_message_codec,
|
||||
FL,
|
||||
STANDARD_CODEC,
|
||||
FlMessageCodec)
|
||||
|
||||
/**
|
||||
* FlStandardMessageCodec:
|
||||
*
|
||||
* #FlStandardMessageCodec is an #FlMessageCodec that implements the Flutter
|
||||
* standard message encoding. This encodes and decodes #FlValue of type
|
||||
* #FL_VALUE_TYPE_NULL, #FL_VALUE_TYPE_BOOL, #FL_VALUE_TYPE_INT,
|
||||
* #FL_VALUE_TYPE_FLOAT, #FL_VALUE_TYPE_STRING, #FL_VALUE_TYPE_UINT8_LIST,
|
||||
* #FL_VALUE_TYPE_INT32_LIST, #FL_VALUE_TYPE_INT64_LIST,
|
||||
* #FL_VALUE_TYPE_FLOAT_LIST, #FL_VALUE_TYPE_LIST, and #FL_VALUE_TYPE_MAP
|
||||
*
|
||||
* #FlStandardMessageCodec matches the StandardCodec class in the Flutter
|
||||
* services library.
|
||||
*/
|
||||
|
||||
/*
|
||||
* fl_standard_message_codec_new:
|
||||
*
|
||||
* Creates a #FlStandardMessageCodec.
|
||||
*
|
||||
* Returns: a new #FlStandardMessageCodec
|
||||
*/
|
||||
FlStandardMessageCodec* fl_standard_message_codec_new();
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_STANDARD_MESSAGE_CODEC_H_
|
||||
@ -12,6 +12,7 @@
|
||||
#include <flutter_linux/fl_dart_project.h>
|
||||
#include <flutter_linux/fl_engine.h>
|
||||
#include <flutter_linux/fl_message_codec.h>
|
||||
#include <flutter_linux/fl_standard_message_codec.h>
|
||||
#include <flutter_linux/fl_string_codec.h>
|
||||
#include <flutter_linux/fl_value.h>
|
||||
#include <flutter_linux/fl_view.h>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user