未验证 提交 680eb90a 编写于 作者: R Robert Ancell 提交者: GitHub

Add fl_value_to_string (#18540)

上级 c1c7ab96
......@@ -92,6 +92,122 @@ static ssize_t fl_value_lookup_index(FlValue* self, FlValue* key) {
return -1;
}
// Converts an integer to a string and adds it to the buffer
static void int_to_string(int64_t value, GString* buffer) {
g_string_append_printf(buffer, "%" G_GINT64_FORMAT, value);
}
// Converts a floating point number to a string and adds it to the buffer
static void float_to_string(double value, GString* buffer) {
g_string_append_printf(buffer, "%.16f", value);
// Strip trailing zeros
int zero_count = 0;
for (int i = buffer->len - 1; i >= 0; i--) {
// Leave one zero after a decimal point
if (buffer->str[i] == '.') {
zero_count = zero_count == 0 ? 0 : zero_count - 1;
break;
}
if (buffer->str[i] != '0')
break;
zero_count++;
}
g_string_truncate(buffer, buffer->len - zero_count);
}
static void value_to_string(FlValue* value, GString* buffer) {
switch (value->type) {
case FL_VALUE_TYPE_NULL:
g_string_append(buffer, "null");
return;
case FL_VALUE_TYPE_BOOL:
if (fl_value_get_bool(value))
g_string_append(buffer, "true");
else
g_string_append(buffer, "false");
return;
case FL_VALUE_TYPE_INT:
int_to_string(fl_value_get_int(value), buffer);
return;
case FL_VALUE_TYPE_FLOAT:
float_to_string(fl_value_get_float(value), buffer);
return;
case FL_VALUE_TYPE_STRING: {
g_string_append(buffer, fl_value_get_string(value));
return;
}
case FL_VALUE_TYPE_UINT8_LIST: {
g_string_append(buffer, "[");
const uint8_t* values = fl_value_get_uint8_list(value);
for (size_t i = 0; i < fl_value_get_length(value); i++) {
if (i != 0)
g_string_append(buffer, ", ");
int_to_string(values[i], buffer);
}
g_string_append(buffer, "]");
return;
}
case FL_VALUE_TYPE_INT32_LIST: {
g_string_append(buffer, "[");
const int32_t* values = fl_value_get_int32_list(value);
for (size_t i = 0; i < fl_value_get_length(value); i++) {
if (i != 0)
g_string_append(buffer, ", ");
int_to_string(values[i], buffer);
}
g_string_append(buffer, "]");
return;
}
case FL_VALUE_TYPE_INT64_LIST: {
g_string_append(buffer, "[");
const int64_t* values = fl_value_get_int64_list(value);
for (size_t i = 0; i < fl_value_get_length(value); i++) {
if (i != 0)
g_string_append(buffer, ", ");
int_to_string(values[i], buffer);
}
g_string_append(buffer, "]");
return;
}
case FL_VALUE_TYPE_FLOAT_LIST: {
g_string_append(buffer, "[");
const double* values = fl_value_get_float_list(value);
for (size_t i = 0; i < fl_value_get_length(value); i++) {
if (i != 0)
g_string_append(buffer, ", ");
float_to_string(values[i], buffer);
}
g_string_append(buffer, "]");
return;
}
case FL_VALUE_TYPE_LIST: {
g_string_append(buffer, "[");
for (size_t i = 0; i < fl_value_get_length(value); i++) {
if (i != 0)
g_string_append(buffer, ", ");
value_to_string(fl_value_get_list_value(value, i), buffer);
}
g_string_append(buffer, "]");
return;
}
case FL_VALUE_TYPE_MAP: {
g_string_append(buffer, "{");
for (size_t i = 0; i < fl_value_get_length(value); i++) {
if (i != 0)
g_string_append(buffer, ", ");
value_to_string(fl_value_get_map_key(value, i), buffer);
g_string_append(buffer, ": ");
value_to_string(fl_value_get_map_value(value, i), buffer);
}
g_string_append(buffer, "}");
return;
}
default:
g_string_append_printf(buffer, "<unknown type %d>", value->type);
}
}
G_MODULE_EXPORT FlValue* fl_value_new_null() {
return fl_value_new(FL_VALUE_TYPE_NULL, sizeof(FlValue));
}
......@@ -570,3 +686,9 @@ FlValue* fl_value_lookup_string(FlValue* self, const gchar* key) {
g_autoptr(FlValue) string_key = fl_value_new_string(key);
return fl_value_lookup(self, string_key);
}
gchar* fl_value_to_string(FlValue* value) {
GString* buffer = g_string_new("");
value_to_string(value, buffer);
return g_string_free(buffer, FALSE);
}
......@@ -18,6 +18,12 @@ TEST(FlValueTest, NullEqual) {
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, NullToString) {
g_autoptr(FlValue) value = fl_value_new_null();
g_autofree gchar* text = fl_value_to_string(value);
EXPECT_STREQ(text, "null");
}
TEST(FlValueTest, BoolTrue) {
g_autoptr(FlValue) value = fl_value_new_bool(TRUE);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_BOOL);
......@@ -42,6 +48,18 @@ TEST(FlValueTest, BoolNotEqual) {
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, BoolTrueToString) {
g_autoptr(FlValue) value = fl_value_new_bool(TRUE);
g_autofree gchar* text = fl_value_to_string(value);
EXPECT_STREQ(text, "true");
}
TEST(FlValueTest, BoolFalseToString) {
g_autoptr(FlValue) value = fl_value_new_bool(FALSE);
g_autofree gchar* text = fl_value_to_string(value);
EXPECT_STREQ(text, "false");
}
TEST(FlValueTest, IntZero) {
g_autoptr(FlValue) value = fl_value_new_int(0);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT);
......@@ -84,6 +102,12 @@ TEST(FlValueTest, IntNotEqual) {
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, IntToString) {
g_autoptr(FlValue) value = fl_value_new_int(42);
g_autofree gchar* text = fl_value_to_string(value);
EXPECT_STREQ(text, "42");
}
TEST(FlValueTest, FloatZero) {
g_autoptr(FlValue) value = fl_value_new_float(0.0);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
......@@ -120,6 +144,12 @@ TEST(FlValueTest, FloatNotEqual) {
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, FloatToString) {
g_autoptr(FlValue) value = fl_value_new_float(M_PI);
g_autofree gchar* text = fl_value_to_string(value);
EXPECT_STREQ(text, "3.1415926535897931");
}
TEST(FlValueTest, String) {
g_autoptr(FlValue) value = fl_value_new_string("hello");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
......@@ -162,6 +192,12 @@ TEST(FlValueTest, StringNotEqual) {
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, StringToString) {
g_autoptr(FlValue) value = fl_value_new_string("hello");
g_autofree gchar* text = fl_value_to_string(value);
EXPECT_STREQ(text, "hello");
}
TEST(FlValueTest, Uint8List) {
uint8_t data[] = {0x00, 0x01, 0xFE, 0xFF};
g_autoptr(FlValue) value = fl_value_new_uint8_list(data, 4);
......@@ -216,6 +252,13 @@ TEST(FlValueTest, Uint8ListEmptyNotEqual) {
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Uint8ListToString) {
uint8_t data[] = {0x00, 0x01, 0xFE, 0xFF};
g_autoptr(FlValue) value = fl_value_new_uint8_list(data, 4);
g_autofree gchar* text = fl_value_to_string(value);
EXPECT_STREQ(text, "[0, 1, 254, 255]");
}
TEST(FlValueTest, Int32List) {
int32_t data[] = {0, -1, G_MAXINT32, G_MININT32};
g_autoptr(FlValue) value = fl_value_new_int32_list(data, 4);
......@@ -270,6 +313,13 @@ TEST(FlValueTest, Int32ListEmptyNotEqual) {
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int32ListToString) {
int32_t data[] = {0, G_MAXINT32, G_MININT32};
g_autoptr(FlValue) value = fl_value_new_int32_list(data, 3);
g_autofree gchar* text = fl_value_to_string(value);
EXPECT_STREQ(text, "[0, 2147483647, -2147483648]");
}
TEST(FlValueTest, Int64List) {
int64_t data[] = {0, -1, G_MAXINT64, G_MININT64};
g_autoptr(FlValue) value = fl_value_new_int64_list(data, 4);
......@@ -324,6 +374,13 @@ TEST(FlValueTest, Int64ListEmptyNotEqual) {
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int64ListToString) {
int64_t data[] = {0, G_MAXINT64, G_MININT64};
g_autoptr(FlValue) value = fl_value_new_int64_list(data, 3);
g_autofree gchar* text = fl_value_to_string(value);
EXPECT_STREQ(text, "[0, 9223372036854775807, -9223372036854775808]");
}
TEST(FlValueTest, FloatList) {
double data[] = {0.0, -1.0, M_PI};
g_autoptr(FlValue) value = fl_value_new_float_list(data, 4);
......@@ -377,6 +434,13 @@ TEST(FlValueTest, FloatListEmptyNotEqual) {
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, FloatListToString) {
double data[] = {0, -0.5, M_PI};
g_autoptr(FlValue) value = fl_value_new_float_list(data, 3);
g_autofree gchar* text = fl_value_to_string(value);
EXPECT_STREQ(text, "[0.0, -0.5, 3.1415926535897931]");
}
TEST(FlValueTest, ListEmpty) {
g_autoptr(FlValue) value = fl_value_new_list();
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_LIST);
......@@ -510,6 +574,23 @@ TEST(FlValueTest, ListEmptyNotEqual) {
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, ListToString) {
g_autoptr(FlValue) value = fl_value_new_list();
fl_value_append_take(value, fl_value_new_null());
fl_value_append_take(value, fl_value_new_bool(TRUE));
fl_value_append_take(value, fl_value_new_int(42));
fl_value_append_take(value, fl_value_new_float(M_PI));
fl_value_append_take(value, fl_value_new_uint8_list(nullptr, 0));
fl_value_append_take(value, fl_value_new_int32_list(nullptr, 0));
fl_value_append_take(value, fl_value_new_int64_list(nullptr, 0));
fl_value_append_take(value, fl_value_new_float_list(nullptr, 0));
fl_value_append_take(value, fl_value_new_list());
fl_value_append_take(value, fl_value_new_map());
g_autofree gchar* text = fl_value_to_string(value);
EXPECT_STREQ(text,
"[null, true, 42, 3.1415926535897931, [], [], [], [], [], {}]");
}
TEST(FlValueTest, MapEmpty) {
g_autoptr(FlValue) value = fl_value_new_map();
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_MAP);
......@@ -600,6 +681,90 @@ TEST(FlValueTest, MapLookupString) {
ASSERT_EQ(v, nullptr);
}
TEST(FlValueTest, MapValueypes) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_string("null"), fl_value_new_null());
fl_value_set_take(value, fl_value_new_string("bool"),
fl_value_new_bool(TRUE));
fl_value_set_take(value, fl_value_new_string("int"), fl_value_new_int(42));
fl_value_set_take(value, fl_value_new_string("float"),
fl_value_new_float(M_PI));
fl_value_set_take(value, fl_value_new_string("uint8_list"),
fl_value_new_uint8_list(nullptr, 0));
fl_value_set_take(value, fl_value_new_string("int32_list"),
fl_value_new_int32_list(nullptr, 0));
fl_value_set_take(value, fl_value_new_string("int64_list"),
fl_value_new_int64_list(nullptr, 0));
fl_value_set_take(value, fl_value_new_string("float_list"),
fl_value_new_float_list(nullptr, 0));
fl_value_set_take(value, fl_value_new_string("list"), fl_value_new_list());
fl_value_set_take(value, fl_value_new_string("map"), fl_value_new_map());
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_MAP);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(10));
EXPECT_EQ(fl_value_get_type(fl_value_get_map_value(value, 0)),
FL_VALUE_TYPE_NULL);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_value(value, 1)),
FL_VALUE_TYPE_BOOL);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_value(value, 2)),
FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_value(value, 3)),
FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_value(value, 4)),
FL_VALUE_TYPE_UINT8_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_value(value, 5)),
FL_VALUE_TYPE_INT32_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_value(value, 6)),
FL_VALUE_TYPE_INT64_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_value(value, 7)),
FL_VALUE_TYPE_FLOAT_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_value(value, 8)),
FL_VALUE_TYPE_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_value(value, 9)),
FL_VALUE_TYPE_MAP);
}
TEST(FlValueTest, MapKeyTypes) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_null(), fl_value_new_string("null"));
fl_value_set_take(value, fl_value_new_bool(TRUE),
fl_value_new_string("bool"));
fl_value_set_take(value, fl_value_new_int(42), fl_value_new_string("int"));
fl_value_set_take(value, fl_value_new_float(M_PI),
fl_value_new_string("float"));
fl_value_set_take(value, fl_value_new_uint8_list(nullptr, 0),
fl_value_new_string("uint8_list"));
fl_value_set_take(value, fl_value_new_int32_list(nullptr, 0),
fl_value_new_string("int32_list"));
fl_value_set_take(value, fl_value_new_int64_list(nullptr, 0),
fl_value_new_string("int64_list"));
fl_value_set_take(value, fl_value_new_float_list(nullptr, 0),
fl_value_new_string("float_list"));
fl_value_set_take(value, fl_value_new_list(), fl_value_new_string("list"));
fl_value_set_take(value, fl_value_new_map(), fl_value_new_string("map"));
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_MAP);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(10));
EXPECT_EQ(fl_value_get_type(fl_value_get_map_key(value, 0)),
FL_VALUE_TYPE_NULL);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_key(value, 1)),
FL_VALUE_TYPE_BOOL);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_key(value, 2)),
FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_key(value, 3)),
FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_key(value, 4)),
FL_VALUE_TYPE_UINT8_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_key(value, 5)),
FL_VALUE_TYPE_INT32_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_key(value, 6)),
FL_VALUE_TYPE_INT64_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_key(value, 7)),
FL_VALUE_TYPE_FLOAT_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_key(value, 8)),
FL_VALUE_TYPE_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_map_key(value, 9)),
FL_VALUE_TYPE_MAP);
}
TEST(FlValueTest, MapEqual) {
g_autoptr(FlValue) value1 = fl_value_new_map();
fl_value_set_string_take(value1, "one", fl_value_new_int(1));
......@@ -676,6 +841,49 @@ TEST(FlValueTest, MapEmptyNotEqual) {
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, MapToString) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_string("null"), fl_value_new_null());
fl_value_set_take(value, fl_value_new_string("bool"),
fl_value_new_bool(TRUE));
fl_value_set_take(value, fl_value_new_string("int"), fl_value_new_int(42));
fl_value_set_take(value, fl_value_new_string("float"),
fl_value_new_float(M_PI));
fl_value_set_take(value, fl_value_new_string("uint8_list"),
fl_value_new_uint8_list(nullptr, 0));
fl_value_set_take(value, fl_value_new_string("int32_list"),
fl_value_new_int32_list(nullptr, 0));
fl_value_set_take(value, fl_value_new_string("int64_list"),
fl_value_new_int64_list(nullptr, 0));
fl_value_set_take(value, fl_value_new_string("float_list"),
fl_value_new_float_list(nullptr, 0));
fl_value_set_take(value, fl_value_new_string("list"), fl_value_new_list());
fl_value_set_take(value, fl_value_new_string("map"), fl_value_new_map());
fl_value_set_take(value, fl_value_new_null(), fl_value_new_string("null"));
fl_value_set_take(value, fl_value_new_bool(TRUE),
fl_value_new_string("bool"));
fl_value_set_take(value, fl_value_new_int(42), fl_value_new_string("int"));
fl_value_set_take(value, fl_value_new_float(M_PI),
fl_value_new_string("float"));
fl_value_set_take(value, fl_value_new_uint8_list(nullptr, 0),
fl_value_new_string("uint8_list"));
fl_value_set_take(value, fl_value_new_int32_list(nullptr, 0),
fl_value_new_string("int32_list"));
fl_value_set_take(value, fl_value_new_int64_list(nullptr, 0),
fl_value_new_string("int64_list"));
fl_value_set_take(value, fl_value_new_float_list(nullptr, 0),
fl_value_new_string("float_list"));
fl_value_set_take(value, fl_value_new_list(), fl_value_new_string("list"));
fl_value_set_take(value, fl_value_new_map(), fl_value_new_string("map"));
g_autofree gchar* text = fl_value_to_string(value);
EXPECT_STREQ(text,
"{null: null, bool: true, int: 42, float: 3.1415926535897931, "
"uint8_list: [], int32_list: [], int64_list: [], float_list: "
"[], list: [], map: {}, null: null, true: bool, 42: int, "
"3.1415926535897931: float, []: uint8_list, []: int32_list, []: "
"int64_list, []: float_list, []: list, {}: map}");
}
TEST(FlValueTest, EqualSameObject) {
g_autoptr(FlValue) value = fl_value_new_null();
EXPECT_TRUE(fl_value_equal(value, value));
......
......@@ -22,7 +22,7 @@ G_BEGIN_DECLS
* channel used by Flutter.
*
* In Dart the values are represented as follows:
* - #FL_VALUE_TYPE_NULL: null
* - #FL_VALUE_TYPE_NULL: Null
* - #FL_VALUE_TYPE_BOOL: bool
* - #FL_VALUE_TYPE_INT: num
* - #FL_VALUE_TYPE_FLOAT: num
......@@ -31,8 +31,8 @@ G_BEGIN_DECLS
* - #FL_VALUE_TYPE_INT32_LIST: Int32List
* - #FL_VALUE_TYPE_INT64_LIST: Int64List
* - #FL_VALUE_TYPE_FLOAT_LIST: Float64List
* - #FL_VALUE_TYPE_LIST: List
* - #FL_VALUE_TYPE_MAP: Map
* - #FL_VALUE_TYPE_LIST: List<dynamic>
* - #FL_VALUE_TYPE_MAP: Map<dynamic>
*
* See #FlMessageCodec to encode and decode these values.
*/
......@@ -198,7 +198,7 @@ FlValue* fl_value_new_float_list(const double* value, size_t value_length);
*
* Creates an ordered list. Children can be added to the list using
* fl_value_append(). The children are accessed using fl_value_get_length()
* and fl_value_get_list_value(). The equivalent Dart type is a List.
* and fl_value_get_list_value(). The equivalent Dart type is a List<dynamic>.
*
* The following example shows a simple list of values:
*
......@@ -241,7 +241,7 @@ FlValue* fl_value_new_list_from_strv(const gchar* const* value);
* fl_value_set_string_take(). The children are accessed using
* fl_value_get_length(), fl_value_get_map_key(), fl_value_get_map_value(),
* fl_value_lookup() and fl_value_lookup_string(). The equivalent Dart type is a
* Map.
* Map<dynamic>.
*
* The following example shows how to create a map of values keyed by strings:
*
......@@ -568,6 +568,17 @@ FlValue* fl_value_lookup(FlValue* value, FlValue* key);
*/
FlValue* fl_value_lookup_string(FlValue* value, const gchar* key);
/**
* fl_value_to_string:
* @value: an #FlValue.
*
* Converts an #FlValue to a text representation, suitable for logging purposes.
* The text is formatted to be match the equivalent Dart toString() methods.
*
* Returns: UTF-8 text.
*/
gchar* fl_value_to_string(FlValue* value);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(FlValue, fl_value_unref)
G_END_DECLS
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册