FlValue is a lightweight object used to contain the value types that Flutter
uses on platform channels.
This commit is contained in:
Robert Ancell 2020-05-08 13:48:41 +12:00 committed by GitHub
parent ded9b51e21
commit e85dbdde88
6 changed files with 1795 additions and 0 deletions

View File

@ -1194,10 +1194,13 @@ 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_value.cc
FILE: ../../../flutter/shell/platform/linux/fl_value_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_view.cc
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h
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_value.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_view.h
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/flutter_linux.h
FILE: ../../../flutter/shell/platform/windows/angle_surface_manager.cc

View File

@ -47,6 +47,7 @@ _public_headers = [
"public/flutter_linux/fl_binary_messenger.h",
"public/flutter_linux/fl_dart_project.h",
"public/flutter_linux/fl_engine.h",
"public/flutter_linux/fl_value.h",
"public/flutter_linux/fl_view.h",
"public/flutter_linux/flutter_linux.h",
]
@ -64,6 +65,7 @@ source_set("flutter_linux") {
"fl_engine.cc",
"fl_renderer.cc",
"fl_renderer_x11.cc",
"fl_value.cc",
"fl_view.cc",
]
@ -90,6 +92,7 @@ executable("flutter_linux_unittests") {
sources = [
"fl_dart_project_test.cc",
"fl_value_test.cc",
]
public_configs = [ "//flutter:config" ]

View File

@ -0,0 +1,550 @@
// 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_value.h"
#include <gmodule.h>
struct _FlValue {
FlValueType type;
int ref_count;
};
typedef struct {
FlValue parent;
bool value;
} FlValueBool;
typedef struct {
FlValue parent;
int64_t value;
} FlValueInt;
typedef struct {
FlValue parent;
double value;
} FlValueDouble;
typedef struct {
FlValue parent;
gchar* value;
} FlValueString;
typedef struct {
FlValue parent;
uint8_t* values;
size_t values_length;
} FlValueUint8List;
typedef struct {
FlValue parent;
int32_t* values;
size_t values_length;
} FlValueInt32List;
typedef struct {
FlValue parent;
int64_t* values;
size_t values_length;
} FlValueInt64List;
typedef struct {
FlValue parent;
double* values;
size_t values_length;
} FlValueFloatList;
typedef struct {
FlValue parent;
GPtrArray* values;
} FlValueList;
typedef struct {
FlValue parent;
GPtrArray* keys;
GPtrArray* values;
} FlValueMap;
static FlValue* fl_value_new(FlValueType type, size_t size) {
FlValue* self = static_cast<FlValue*>(g_malloc0(size));
self->type = type;
self->ref_count = 1;
return self;
}
// Helper function to match GDestroyNotify type.
static void fl_value_destroy(gpointer value) {
fl_value_unref(static_cast<FlValue*>(value));
}
// Finds the index of a key in a FlValueMap.
// FIXME(robert-ancell) This is highly inefficient, and should be optimised if
// necessary.
static ssize_t fl_value_lookup_index(FlValue* self, FlValue* key) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_MAP, -1);
for (size_t i = 0; i < fl_value_get_length(self); i++) {
FlValue* k = fl_value_get_map_key(self, i);
if (fl_value_equal(k, key))
return i;
}
return -1;
}
G_MODULE_EXPORT FlValue* fl_value_new_null() {
return fl_value_new(FL_VALUE_TYPE_NULL, sizeof(FlValue));
}
G_MODULE_EXPORT FlValue* fl_value_new_bool(bool value) {
FlValueBool* self = reinterpret_cast<FlValueBool*>(
fl_value_new(FL_VALUE_TYPE_BOOL, sizeof(FlValueBool)));
self->value = value ? true : false;
return reinterpret_cast<FlValue*>(self);
}
G_MODULE_EXPORT FlValue* fl_value_new_int(int64_t value) {
FlValueInt* self = reinterpret_cast<FlValueInt*>(
fl_value_new(FL_VALUE_TYPE_INT, sizeof(FlValueInt)));
self->value = value;
return reinterpret_cast<FlValue*>(self);
}
G_MODULE_EXPORT FlValue* fl_value_new_float(double value) {
FlValueDouble* self = reinterpret_cast<FlValueDouble*>(
fl_value_new(FL_VALUE_TYPE_FLOAT, sizeof(FlValueDouble)));
self->value = value;
return reinterpret_cast<FlValue*>(self);
}
G_MODULE_EXPORT FlValue* fl_value_new_string(const gchar* value) {
FlValueString* self = reinterpret_cast<FlValueString*>(
fl_value_new(FL_VALUE_TYPE_STRING, sizeof(FlValueString)));
self->value = g_strdup(value);
return reinterpret_cast<FlValue*>(self);
}
G_MODULE_EXPORT FlValue* fl_value_new_string_sized(const gchar* value,
size_t value_length) {
FlValueString* self = reinterpret_cast<FlValueString*>(
fl_value_new(FL_VALUE_TYPE_STRING, sizeof(FlValueString)));
self->value =
value_length == 0 ? g_strdup("") : g_strndup(value, value_length);
return reinterpret_cast<FlValue*>(self);
}
G_MODULE_EXPORT FlValue* fl_value_new_uint8_list(const uint8_t* data,
size_t data_length) {
FlValueUint8List* self = reinterpret_cast<FlValueUint8List*>(
fl_value_new(FL_VALUE_TYPE_UINT8_LIST, sizeof(FlValueUint8List)));
self->values_length = data_length;
self->values = static_cast<uint8_t*>(g_malloc(sizeof(uint8_t) * data_length));
memcpy(self->values, data, sizeof(uint8_t) * data_length);
return reinterpret_cast<FlValue*>(self);
}
G_MODULE_EXPORT FlValue* fl_value_new_uint8_list_from_bytes(GBytes* data) {
gsize length;
const uint8_t* d =
static_cast<const uint8_t*>(g_bytes_get_data(data, &length));
return fl_value_new_uint8_list(d, length);
}
G_MODULE_EXPORT FlValue* fl_value_new_int32_list(const int32_t* data,
size_t data_length) {
FlValueInt32List* self = reinterpret_cast<FlValueInt32List*>(
fl_value_new(FL_VALUE_TYPE_INT32_LIST, sizeof(FlValueInt32List)));
self->values_length = data_length;
self->values = static_cast<int32_t*>(g_malloc(sizeof(int32_t) * data_length));
memcpy(self->values, data, sizeof(int32_t) * data_length);
return reinterpret_cast<FlValue*>(self);
}
G_MODULE_EXPORT FlValue* fl_value_new_int64_list(const int64_t* data,
size_t data_length) {
FlValueInt64List* self = reinterpret_cast<FlValueInt64List*>(
fl_value_new(FL_VALUE_TYPE_INT64_LIST, sizeof(FlValueInt64List)));
self->values_length = data_length;
self->values = static_cast<int64_t*>(g_malloc(sizeof(int64_t) * data_length));
memcpy(self->values, data, sizeof(int64_t) * data_length);
return reinterpret_cast<FlValue*>(self);
}
G_MODULE_EXPORT FlValue* fl_value_new_float_list(const double* data,
size_t data_length) {
FlValueFloatList* self = reinterpret_cast<FlValueFloatList*>(
fl_value_new(FL_VALUE_TYPE_FLOAT_LIST, sizeof(FlValueFloatList)));
self->values_length = data_length;
self->values = static_cast<double*>(g_malloc(sizeof(double) * data_length));
memcpy(self->values, data, sizeof(double) * data_length);
return reinterpret_cast<FlValue*>(self);
}
G_MODULE_EXPORT FlValue* fl_value_new_list() {
FlValueList* self = reinterpret_cast<FlValueList*>(
fl_value_new(FL_VALUE_TYPE_LIST, sizeof(FlValueList)));
self->values = g_ptr_array_new_with_free_func(fl_value_destroy);
return reinterpret_cast<FlValue*>(self);
}
G_MODULE_EXPORT FlValue* fl_value_new_list_from_strv(
const gchar* const* str_array) {
g_return_val_if_fail(str_array != nullptr, nullptr);
g_autoptr(FlValue) value = fl_value_new_list();
for (int i = 0; str_array[i] != nullptr; i++)
fl_value_append_take(value, fl_value_new_string(str_array[i]));
return fl_value_ref(value);
}
G_MODULE_EXPORT FlValue* fl_value_new_map() {
FlValueMap* self = reinterpret_cast<FlValueMap*>(
fl_value_new(FL_VALUE_TYPE_MAP, sizeof(FlValueMap)));
self->keys = g_ptr_array_new_with_free_func(fl_value_destroy);
self->values = g_ptr_array_new_with_free_func(fl_value_destroy);
return reinterpret_cast<FlValue*>(self);
}
G_MODULE_EXPORT FlValue* fl_value_ref(FlValue* self) {
self->ref_count++;
return self;
}
G_MODULE_EXPORT void fl_value_unref(FlValue* self) {
g_return_if_fail(self->ref_count > 0);
self->ref_count--;
if (self->ref_count != 0)
return;
switch (self->type) {
case FL_VALUE_TYPE_STRING: {
FlValueString* v = reinterpret_cast<FlValueString*>(self);
g_free(v->value);
break;
}
case FL_VALUE_TYPE_UINT8_LIST: {
FlValueUint8List* v = reinterpret_cast<FlValueUint8List*>(self);
g_free(v->values);
break;
}
case FL_VALUE_TYPE_INT32_LIST: {
FlValueInt32List* v = reinterpret_cast<FlValueInt32List*>(self);
g_free(v->values);
break;
}
case FL_VALUE_TYPE_INT64_LIST: {
FlValueInt64List* v = reinterpret_cast<FlValueInt64List*>(self);
g_free(v->values);
break;
}
case FL_VALUE_TYPE_FLOAT_LIST: {
FlValueFloatList* v = reinterpret_cast<FlValueFloatList*>(self);
g_free(v->values);
break;
}
case FL_VALUE_TYPE_LIST: {
FlValueList* v = reinterpret_cast<FlValueList*>(self);
g_ptr_array_unref(v->values);
break;
}
case FL_VALUE_TYPE_MAP: {
FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
g_ptr_array_unref(v->keys);
g_ptr_array_unref(v->values);
break;
}
case FL_VALUE_TYPE_NULL:
case FL_VALUE_TYPE_BOOL:
case FL_VALUE_TYPE_INT:
case FL_VALUE_TYPE_FLOAT:
break;
}
g_free(self);
}
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue* self) {
g_return_val_if_fail(self != nullptr, FL_VALUE_TYPE_NULL);
return self->type;
}
G_MODULE_EXPORT bool fl_value_equal(FlValue* a, FlValue* b) {
g_return_val_if_fail(a != nullptr, false);
g_return_val_if_fail(b != nullptr, false);
if (a->type != b->type)
return false;
switch (a->type) {
case FL_VALUE_TYPE_NULL:
return true;
case FL_VALUE_TYPE_BOOL:
return fl_value_get_bool(a) == fl_value_get_bool(b);
case FL_VALUE_TYPE_INT:
return fl_value_get_int(a) == fl_value_get_int(b);
case FL_VALUE_TYPE_FLOAT:
return fl_value_get_float(a) == fl_value_get_float(b);
case FL_VALUE_TYPE_STRING: {
FlValueString* a_ = reinterpret_cast<FlValueString*>(a);
FlValueString* b_ = reinterpret_cast<FlValueString*>(b);
return g_strcmp0(a_->value, b_->value) == 0;
}
case FL_VALUE_TYPE_UINT8_LIST: {
if (fl_value_get_length(a) != fl_value_get_length(b))
return false;
const uint8_t* values_a = fl_value_get_uint8_list(a);
const uint8_t* values_b = fl_value_get_uint8_list(b);
for (size_t i = 0; i < fl_value_get_length(a); i++) {
if (values_a[i] != values_b[i])
return false;
}
return true;
}
case FL_VALUE_TYPE_INT32_LIST: {
if (fl_value_get_length(a) != fl_value_get_length(b))
return false;
const int32_t* values_a = fl_value_get_int32_list(a);
const int32_t* values_b = fl_value_get_int32_list(b);
for (size_t i = 0; i < fl_value_get_length(a); i++) {
if (values_a[i] != values_b[i])
return false;
}
return true;
}
case FL_VALUE_TYPE_INT64_LIST: {
if (fl_value_get_length(a) != fl_value_get_length(b))
return false;
const int64_t* values_a = fl_value_get_int64_list(a);
const int64_t* values_b = fl_value_get_int64_list(b);
for (size_t i = 0; i < fl_value_get_length(a); i++) {
if (values_a[i] != values_b[i])
return false;
}
return true;
}
case FL_VALUE_TYPE_FLOAT_LIST: {
if (fl_value_get_length(a) != fl_value_get_length(b))
return false;
const double* values_a = fl_value_get_float_list(a);
const double* values_b = fl_value_get_float_list(b);
for (size_t i = 0; i < fl_value_get_length(a); i++) {
if (values_a[i] != values_b[i])
return false;
}
return true;
}
case FL_VALUE_TYPE_LIST: {
if (fl_value_get_length(a) != fl_value_get_length(b))
return false;
for (size_t i = 0; i < fl_value_get_length(a); i++) {
if (!fl_value_equal(fl_value_get_list_value(a, i),
fl_value_get_list_value(b, i)))
return false;
}
return true;
}
case FL_VALUE_TYPE_MAP: {
if (fl_value_get_length(a) != fl_value_get_length(b))
return false;
for (size_t i = 0; i < fl_value_get_length(a); i++) {
FlValue* key = fl_value_get_map_key(a, i);
FlValue* value_b = fl_value_lookup(b, key);
if (value_b == nullptr)
return false;
FlValue* value_a = fl_value_get_map_value(a, i);
if (!fl_value_equal(value_a, value_b))
return false;
}
return true;
}
}
}
G_MODULE_EXPORT void fl_value_append(FlValue* self, FlValue* value) {
g_return_if_fail(self->type == FL_VALUE_TYPE_LIST);
g_return_if_fail(value != nullptr);
fl_value_append_take(self, fl_value_ref(value));
}
G_MODULE_EXPORT void fl_value_append_take(FlValue* self, FlValue* value) {
g_return_if_fail(self->type == FL_VALUE_TYPE_LIST);
g_return_if_fail(value != nullptr);
FlValueList* v = reinterpret_cast<FlValueList*>(self);
g_ptr_array_add(v->values, value);
}
G_MODULE_EXPORT void fl_value_set(FlValue* self, FlValue* key, FlValue* value) {
g_return_if_fail(self->type == FL_VALUE_TYPE_MAP);
g_return_if_fail(key != nullptr);
g_return_if_fail(value != nullptr);
fl_value_set_take(self, fl_value_ref(key), fl_value_ref(value));
}
G_MODULE_EXPORT void fl_value_set_take(FlValue* self,
FlValue* key,
FlValue* value) {
g_return_if_fail(self->type == FL_VALUE_TYPE_MAP);
g_return_if_fail(key != nullptr);
g_return_if_fail(value != nullptr);
FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
ssize_t index = fl_value_lookup_index(self, key);
if (index < 0) {
g_ptr_array_add(v->keys, key);
g_ptr_array_add(v->values, value);
} else {
fl_value_destroy(v->keys->pdata[index]);
v->keys->pdata[index] = key;
fl_value_destroy(v->values->pdata[index]);
v->values->pdata[index] = value;
}
}
G_MODULE_EXPORT void fl_value_set_string(FlValue* self,
const gchar* key,
FlValue* value) {
g_return_if_fail(self->type == FL_VALUE_TYPE_MAP);
g_return_if_fail(key != nullptr);
g_return_if_fail(value != nullptr);
fl_value_set_take(self, fl_value_new_string(key), fl_value_ref(value));
}
G_MODULE_EXPORT void fl_value_set_string_take(FlValue* self,
const gchar* key,
FlValue* value) {
g_return_if_fail(self->type == FL_VALUE_TYPE_MAP);
g_return_if_fail(key != nullptr);
g_return_if_fail(value != nullptr);
fl_value_set_take(self, fl_value_new_string(key), value);
}
G_MODULE_EXPORT bool fl_value_get_bool(FlValue* self) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_BOOL, FALSE);
FlValueBool* v = reinterpret_cast<FlValueBool*>(self);
return v->value;
}
G_MODULE_EXPORT int64_t fl_value_get_int(FlValue* self) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_INT, 0);
FlValueInt* v = reinterpret_cast<FlValueInt*>(self);
return v->value;
}
G_MODULE_EXPORT double fl_value_get_float(FlValue* self) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_FLOAT, 0.0);
FlValueDouble* v = reinterpret_cast<FlValueDouble*>(self);
return v->value;
}
G_MODULE_EXPORT const gchar* fl_value_get_string(FlValue* self) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_STRING, nullptr);
FlValueString* v = reinterpret_cast<FlValueString*>(self);
return v->value;
}
G_MODULE_EXPORT const uint8_t* fl_value_get_uint8_list(FlValue* self) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_UINT8_LIST, nullptr);
FlValueUint8List* v = reinterpret_cast<FlValueUint8List*>(self);
return v->values;
}
G_MODULE_EXPORT const int32_t* fl_value_get_int32_list(FlValue* self) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_INT32_LIST, nullptr);
FlValueInt32List* v = reinterpret_cast<FlValueInt32List*>(self);
return v->values;
}
G_MODULE_EXPORT const int64_t* fl_value_get_int64_list(FlValue* self) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_INT64_LIST, nullptr);
FlValueInt64List* v = reinterpret_cast<FlValueInt64List*>(self);
return v->values;
}
G_MODULE_EXPORT const double* fl_value_get_float_list(FlValue* self) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_FLOAT_LIST, nullptr);
FlValueFloatList* v = reinterpret_cast<FlValueFloatList*>(self);
return v->values;
}
G_MODULE_EXPORT size_t fl_value_get_length(FlValue* self) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_UINT8_LIST ||
self->type == FL_VALUE_TYPE_INT32_LIST ||
self->type == FL_VALUE_TYPE_INT64_LIST ||
self->type == FL_VALUE_TYPE_FLOAT_LIST ||
self->type == FL_VALUE_TYPE_LIST ||
self->type == FL_VALUE_TYPE_MAP,
0);
switch (self->type) {
case FL_VALUE_TYPE_UINT8_LIST: {
FlValueUint8List* v = reinterpret_cast<FlValueUint8List*>(self);
return v->values_length;
}
case FL_VALUE_TYPE_INT32_LIST: {
FlValueInt32List* v = reinterpret_cast<FlValueInt32List*>(self);
return v->values_length;
}
case FL_VALUE_TYPE_INT64_LIST: {
FlValueInt64List* v = reinterpret_cast<FlValueInt64List*>(self);
return v->values_length;
}
case FL_VALUE_TYPE_FLOAT_LIST: {
FlValueFloatList* v = reinterpret_cast<FlValueFloatList*>(self);
return v->values_length;
}
case FL_VALUE_TYPE_LIST: {
FlValueList* v = reinterpret_cast<FlValueList*>(self);
return v->values->len;
}
case FL_VALUE_TYPE_MAP: {
FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
return v->keys->len;
}
case FL_VALUE_TYPE_NULL:
case FL_VALUE_TYPE_BOOL:
case FL_VALUE_TYPE_INT:
case FL_VALUE_TYPE_FLOAT:
case FL_VALUE_TYPE_STRING:
return 0;
}
return 0;
}
G_MODULE_EXPORT FlValue* fl_value_get_list_value(FlValue* self, size_t index) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_LIST, nullptr);
FlValueList* v = reinterpret_cast<FlValueList*>(self);
return static_cast<FlValue*>(g_ptr_array_index(v->values, index));
}
G_MODULE_EXPORT FlValue* fl_value_get_map_key(FlValue* self, size_t index) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_MAP, nullptr);
FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
return static_cast<FlValue*>(g_ptr_array_index(v->keys, index));
}
G_MODULE_EXPORT FlValue* fl_value_get_map_value(FlValue* self, size_t index) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_MAP, nullptr);
FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
return static_cast<FlValue*>(g_ptr_array_index(v->values, index));
}
G_MODULE_EXPORT FlValue* fl_value_lookup(FlValue* self, FlValue* key) {
g_return_val_if_fail(self->type == FL_VALUE_TYPE_MAP, nullptr);
ssize_t index = fl_value_lookup_index(self, key);
if (index < 0)
return nullptr;
return fl_value_get_map_value(self, index);
}
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);
}

View File

@ -0,0 +1,731 @@
// 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_value.h"
#include "gtest/gtest.h"
#include <gmodule.h>
TEST(FlDartProjectTest, Null) {
g_autoptr(FlValue) value = fl_value_new_null();
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_NULL);
}
TEST(FlValueTest, NullEqual) {
g_autoptr(FlValue) value1 = fl_value_new_null();
g_autoptr(FlValue) value2 = fl_value_new_null();
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, BoolTrue) {
g_autoptr(FlValue) value = fl_value_new_bool(TRUE);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_BOOL);
EXPECT_TRUE(fl_value_get_bool(value));
}
TEST(FlValueTest, BoolFalse) {
g_autoptr(FlValue) value = fl_value_new_bool(FALSE);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_BOOL);
EXPECT_FALSE(fl_value_get_bool(value));
}
TEST(FlValueTest, BoolEqual) {
g_autoptr(FlValue) value1 = fl_value_new_bool(TRUE);
g_autoptr(FlValue) value2 = fl_value_new_bool(TRUE);
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, BoolNotEqual) {
g_autoptr(FlValue) value1 = fl_value_new_bool(TRUE);
g_autoptr(FlValue) value2 = fl_value_new_bool(FALSE);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, IntZero) {
g_autoptr(FlValue) value = fl_value_new_int(0);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(value), 0);
}
TEST(FlValueTest, IntOne) {
g_autoptr(FlValue) value = fl_value_new_int(1);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(value), 1);
}
TEST(FlValueTest, IntMinusOne) {
g_autoptr(FlValue) value = fl_value_new_int(-1);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(value), -1);
}
TEST(FlValueTest, IntMin) {
g_autoptr(FlValue) value = fl_value_new_int(G_MININT64);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(value), G_MININT64);
}
TEST(FlValueTest, IntMax) {
g_autoptr(FlValue) value = fl_value_new_int(G_MAXINT64);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(value), G_MAXINT64);
}
TEST(FlValueTest, IntEqual) {
g_autoptr(FlValue) value1 = fl_value_new_int(42);
g_autoptr(FlValue) value2 = fl_value_new_int(42);
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, IntNotEqual) {
g_autoptr(FlValue) value1 = fl_value_new_int(42);
g_autoptr(FlValue) value2 = fl_value_new_int(99);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, FloatZero) {
g_autoptr(FlValue) value = fl_value_new_float(0.0);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_float(value), 0.0);
}
TEST(FlValueTest, FloatOne) {
g_autoptr(FlValue) value = fl_value_new_float(1.0);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_float(value), 1.0);
}
TEST(FlValueTest, FloatMinusOne) {
g_autoptr(FlValue) value = fl_value_new_float(-1.0);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_float(value), -1.0);
}
TEST(FlValueTest, FloatPi) {
g_autoptr(FlValue) value = fl_value_new_float(M_PI);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_float(value), M_PI);
}
TEST(FlValueTest, FloatEqual) {
g_autoptr(FlValue) value1 = fl_value_new_float(M_PI);
g_autoptr(FlValue) value2 = fl_value_new_float(M_PI);
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, FloatNotEqual) {
g_autoptr(FlValue) value1 = fl_value_new_float(M_PI);
g_autoptr(FlValue) value2 = fl_value_new_float(M_E);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, String) {
g_autoptr(FlValue) value = fl_value_new_string("hello");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "hello");
}
TEST(FlValueTest, StringEmpty) {
g_autoptr(FlValue) value = fl_value_new_string("");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "");
}
TEST(FlValueTest, StringSized) {
g_autoptr(FlValue) value = fl_value_new_string_sized("hello", 2);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "he");
}
TEST(FlValueTest, StringSizedNULL) {
g_autoptr(FlValue) value = fl_value_new_string_sized(nullptr, 0);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "");
}
TEST(FlValueTest, StringSizedZeroLength) {
g_autoptr(FlValue) value = fl_value_new_string_sized("hello", 0);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "");
}
TEST(FlValueTest, StringEqual) {
g_autoptr(FlValue) value1 = fl_value_new_string("hello");
g_autoptr(FlValue) value2 = fl_value_new_string("hello");
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, StringNotEqual) {
g_autoptr(FlValue) value1 = fl_value_new_string("hello");
g_autoptr(FlValue) value2 = fl_value_new_string("world");
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Uint8List) {
uint8_t data[] = {0x00, 0x01, 0xFE, 0xFF};
g_autoptr(FlValue) value = fl_value_new_uint8_list(data, 4);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_UINT8_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(4));
EXPECT_EQ(fl_value_get_uint8_list(value)[0], 0x00);
EXPECT_EQ(fl_value_get_uint8_list(value)[1], 0x01);
EXPECT_EQ(fl_value_get_uint8_list(value)[2], 0xFE);
EXPECT_EQ(fl_value_get_uint8_list(value)[3], 0xFF);
}
TEST(FlValueTest, Uint8ListNULL) {
g_autoptr(FlValue) value = fl_value_new_uint8_list(nullptr, 0);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_UINT8_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(0));
}
TEST(FlValueTest, Uint8ListEqual) {
uint8_t data1[] = {1, 2, 3};
g_autoptr(FlValue) value1 = fl_value_new_uint8_list(data1, 3);
uint8_t data2[] = {1, 2, 3};
g_autoptr(FlValue) value2 = fl_value_new_uint8_list(data2, 3);
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Uint8ListEmptyEqual) {
g_autoptr(FlValue) value1 = fl_value_new_uint8_list(nullptr, 0);
g_autoptr(FlValue) value2 = fl_value_new_uint8_list(nullptr, 0);
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Uint8ListNotEqualSameSize) {
uint8_t data1[] = {1, 2, 3};
g_autoptr(FlValue) value1 = fl_value_new_uint8_list(data1, 3);
uint8_t data2[] = {1, 2, 4};
g_autoptr(FlValue) value2 = fl_value_new_uint8_list(data2, 3);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Uint8ListNotEqualDifferentSize) {
uint8_t data1[] = {1, 2, 3};
g_autoptr(FlValue) value1 = fl_value_new_uint8_list(data1, 3);
uint8_t data2[] = {1, 2, 3, 4};
g_autoptr(FlValue) value2 = fl_value_new_uint8_list(data2, 4);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Uint8ListEmptyNotEqual) {
g_autoptr(FlValue) value1 = fl_value_new_uint8_list(nullptr, 0);
uint8_t data[] = {1, 2, 3};
g_autoptr(FlValue) value2 = fl_value_new_uint8_list(data, 3);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int32List) {
int32_t data[] = {0, -1, G_MAXINT32, G_MININT32};
g_autoptr(FlValue) value = fl_value_new_int32_list(data, 4);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT32_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(4));
EXPECT_EQ(fl_value_get_int32_list(value)[0], 0);
EXPECT_EQ(fl_value_get_int32_list(value)[1], -1);
EXPECT_EQ(fl_value_get_int32_list(value)[2], G_MAXINT32);
EXPECT_EQ(fl_value_get_int32_list(value)[3], G_MININT32);
}
TEST(FlValueTest, Int32ListNULL) {
g_autoptr(FlValue) value = fl_value_new_int32_list(nullptr, 0);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT32_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(0));
}
TEST(FlValueTest, Int32ListEqual) {
int32_t data1[] = {0, G_MAXINT32, G_MININT32};
g_autoptr(FlValue) value1 = fl_value_new_int32_list(data1, 3);
int32_t data2[] = {0, G_MAXINT32, G_MININT32};
g_autoptr(FlValue) value2 = fl_value_new_int32_list(data2, 3);
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int32ListEmptyEqual) {
g_autoptr(FlValue) value1 = fl_value_new_int32_list(nullptr, 0);
g_autoptr(FlValue) value2 = fl_value_new_int32_list(nullptr, 0);
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int32ListNotEqualSameSize) {
int32_t data1[] = {0, G_MAXINT32, G_MININT32};
g_autoptr(FlValue) value1 = fl_value_new_int32_list(data1, 3);
int32_t data2[] = {0, G_MININT32, G_MAXINT32};
g_autoptr(FlValue) value2 = fl_value_new_int32_list(data2, 3);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int32ListNotEqualDifferentSize) {
int32_t data1[] = {0, G_MAXINT32, G_MININT32};
g_autoptr(FlValue) value1 = fl_value_new_int32_list(data1, 3);
int32_t data2[] = {0, G_MAXINT32, G_MININT32, -1};
g_autoptr(FlValue) value2 = fl_value_new_int32_list(data2, 4);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int32ListEmptyNotEqual) {
g_autoptr(FlValue) value1 = fl_value_new_int32_list(nullptr, 0);
int32_t data[] = {0, G_MAXINT32, G_MININT32};
g_autoptr(FlValue) value2 = fl_value_new_int32_list(data, 3);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int64List) {
int64_t data[] = {0, -1, G_MAXINT64, G_MININT64};
g_autoptr(FlValue) value = fl_value_new_int64_list(data, 4);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT64_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(4));
EXPECT_EQ(fl_value_get_int64_list(value)[0], 0);
EXPECT_EQ(fl_value_get_int64_list(value)[1], -1);
EXPECT_EQ(fl_value_get_int64_list(value)[2], G_MAXINT64);
EXPECT_EQ(fl_value_get_int64_list(value)[3], G_MININT64);
}
TEST(FlValueTest, Int64ListNULL) {
g_autoptr(FlValue) value = fl_value_new_int64_list(nullptr, 0);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT64_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(0));
}
TEST(FlValueTest, Int64ListEqual) {
int64_t data1[] = {0, G_MAXINT64, G_MININT64};
g_autoptr(FlValue) value1 = fl_value_new_int64_list(data1, 3);
int64_t data2[] = {0, G_MAXINT64, G_MININT64};
g_autoptr(FlValue) value2 = fl_value_new_int64_list(data2, 3);
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int64ListEmptyEqual) {
g_autoptr(FlValue) value1 = fl_value_new_int64_list(nullptr, 0);
g_autoptr(FlValue) value2 = fl_value_new_int64_list(nullptr, 0);
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int64ListNotEqualSameSize) {
int64_t data1[] = {0, G_MAXINT64, G_MININT64};
g_autoptr(FlValue) value1 = fl_value_new_int64_list(data1, 3);
int64_t data2[] = {0, G_MININT64, G_MAXINT64};
g_autoptr(FlValue) value2 = fl_value_new_int64_list(data2, 3);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int64ListNotEqualDifferentSize) {
int64_t data1[] = {0, G_MAXINT64, G_MININT64};
g_autoptr(FlValue) value1 = fl_value_new_int64_list(data1, 3);
int64_t data2[] = {0, G_MAXINT64, G_MININT64, -1};
g_autoptr(FlValue) value2 = fl_value_new_int64_list(data2, 4);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int64ListEmptyNotEqual) {
g_autoptr(FlValue) value1 = fl_value_new_int64_list(nullptr, 0);
int64_t data[] = {0, G_MAXINT64, G_MININT64};
g_autoptr(FlValue) value2 = fl_value_new_int64_list(data, 3);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, FloatList) {
double data[] = {0.0, -1.0, M_PI};
g_autoptr(FlValue) value = fl_value_new_float_list(data, 4);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(4));
EXPECT_EQ(fl_value_get_float_list(value)[0], 0);
EXPECT_EQ(fl_value_get_float_list(value)[1], -1.0);
EXPECT_EQ(fl_value_get_float_list(value)[2], M_PI);
}
TEST(FlValueTest, FloatListNULL) {
g_autoptr(FlValue) value = fl_value_new_float_list(nullptr, 0);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(0));
}
TEST(FlValueTest, FloatListEqual) {
double data1[] = {0, -0.5, M_PI};
g_autoptr(FlValue) value1 = fl_value_new_float_list(data1, 3);
double data2[] = {0, -0.5, M_PI};
g_autoptr(FlValue) value2 = fl_value_new_float_list(data2, 3);
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, FloatListEmptyEqual) {
g_autoptr(FlValue) value1 = fl_value_new_float_list(nullptr, 0);
g_autoptr(FlValue) value2 = fl_value_new_float_list(nullptr, 0);
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, FloatListNotEqualSameSize) {
double data1[] = {0, -0.5, M_PI};
g_autoptr(FlValue) value1 = fl_value_new_float_list(data1, 3);
double data2[] = {0, -0.5, M_E};
g_autoptr(FlValue) value2 = fl_value_new_float_list(data2, 3);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, FloatListNotEqualDifferentSize) {
double data1[] = {0, -0.5, M_PI};
g_autoptr(FlValue) value1 = fl_value_new_float_list(data1, 3);
double data2[] = {0, -0.5, M_PI, 42};
g_autoptr(FlValue) value2 = fl_value_new_float_list(data2, 4);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, FloatListEmptyNotEqual) {
g_autoptr(FlValue) value1 = fl_value_new_float_list(nullptr, 0);
double data[] = {0, -0.5, M_PI};
g_autoptr(FlValue) value2 = fl_value_new_float_list(data, 3);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, ListEmpty) {
g_autoptr(FlValue) value = fl_value_new_list();
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(0));
}
TEST(FlValueTest, ListAdd) {
g_autoptr(FlValue) value = fl_value_new_list();
g_autoptr(FlValue) child = fl_value_new_null();
fl_value_append(value, child);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(1));
EXPECT_EQ(fl_value_get_type(fl_value_get_list_value(value, 0)),
FL_VALUE_TYPE_NULL);
}
TEST(FlValueTest, ListAddTake) {
g_autoptr(FlValue) value = fl_value_new_list();
fl_value_append_take(value, fl_value_new_null());
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(1));
EXPECT_EQ(fl_value_get_type(fl_value_get_list_value(value, 0)),
FL_VALUE_TYPE_NULL);
}
TEST(FlValueTest, ListChildTypes) {
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());
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(10));
EXPECT_EQ(fl_value_get_type(fl_value_get_list_value(value, 0)),
FL_VALUE_TYPE_NULL);
EXPECT_EQ(fl_value_get_type(fl_value_get_list_value(value, 1)),
FL_VALUE_TYPE_BOOL);
EXPECT_EQ(fl_value_get_type(fl_value_get_list_value(value, 2)),
FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_type(fl_value_get_list_value(value, 3)),
FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_type(fl_value_get_list_value(value, 4)),
FL_VALUE_TYPE_UINT8_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_list_value(value, 5)),
FL_VALUE_TYPE_INT32_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_list_value(value, 6)),
FL_VALUE_TYPE_INT64_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_list_value(value, 7)),
FL_VALUE_TYPE_FLOAT_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_list_value(value, 8)),
FL_VALUE_TYPE_LIST);
EXPECT_EQ(fl_value_get_type(fl_value_get_list_value(value, 9)),
FL_VALUE_TYPE_MAP);
}
TEST(FlValueTest, ListStrv) {
g_auto(GStrv) words = g_strsplit("hello:world", ":", -1);
g_autoptr(FlValue) value = fl_value_new_list_from_strv(words);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(2));
ASSERT_EQ(fl_value_get_type(fl_value_get_list_value(value, 0)),
FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(fl_value_get_list_value(value, 0)), "hello");
ASSERT_EQ(fl_value_get_type(fl_value_get_list_value(value, 1)),
FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(fl_value_get_list_value(value, 1)), "world");
}
TEST(FlValueTest, ListStrvEmpty) {
g_auto(GStrv) words = g_strsplit("", ":", -1);
g_autoptr(FlValue) value = fl_value_new_list_from_strv(words);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_LIST);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(0));
}
TEST(FlValueTest, ListEqual) {
g_autoptr(FlValue) value1 = fl_value_new_list();
fl_value_append_take(value1, fl_value_new_int(1));
fl_value_append_take(value1, fl_value_new_int(2));
fl_value_append_take(value1, fl_value_new_int(3));
g_autoptr(FlValue) value2 = fl_value_new_list();
fl_value_append_take(value2, fl_value_new_int(1));
fl_value_append_take(value2, fl_value_new_int(2));
fl_value_append_take(value2, fl_value_new_int(3));
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, ListEmptyEqual) {
g_autoptr(FlValue) value1 = fl_value_new_list();
g_autoptr(FlValue) value2 = fl_value_new_list();
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, ListNotEqualSameSize) {
g_autoptr(FlValue) value1 = fl_value_new_list();
fl_value_append_take(value1, fl_value_new_int(1));
fl_value_append_take(value1, fl_value_new_int(2));
fl_value_append_take(value1, fl_value_new_int(3));
g_autoptr(FlValue) value2 = fl_value_new_list();
fl_value_append_take(value2, fl_value_new_int(1));
fl_value_append_take(value2, fl_value_new_int(2));
fl_value_append_take(value2, fl_value_new_int(4));
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, ListNotEqualDifferentSize) {
g_autoptr(FlValue) value1 = fl_value_new_list();
fl_value_append_take(value1, fl_value_new_int(1));
fl_value_append_take(value1, fl_value_new_int(2));
fl_value_append_take(value1, fl_value_new_int(3));
g_autoptr(FlValue) value2 = fl_value_new_list();
fl_value_append_take(value2, fl_value_new_int(1));
fl_value_append_take(value2, fl_value_new_int(2));
fl_value_append_take(value2, fl_value_new_int(3));
fl_value_append_take(value2, fl_value_new_int(4));
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, ListEmptyNotEqual) {
g_autoptr(FlValue) value1 = fl_value_new_list();
g_autoptr(FlValue) value2 = fl_value_new_list();
fl_value_append_take(value2, fl_value_new_int(1));
fl_value_append_take(value2, fl_value_new_int(2));
fl_value_append_take(value2, fl_value_new_int(3));
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, MapEmpty) {
g_autoptr(FlValue) value = 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>(0));
}
TEST(FlValueTest, MapSet) {
g_autoptr(FlValue) value = fl_value_new_map();
g_autoptr(FlValue) k = fl_value_new_string("count");
g_autoptr(FlValue) v = fl_value_new_int(42);
fl_value_set(value, k, v);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_MAP);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(1));
ASSERT_EQ(fl_value_get_type(fl_value_get_map_key(value, 0)),
FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(fl_value_get_map_key(value, 0)), "count");
ASSERT_EQ(fl_value_get_type(fl_value_get_map_value(value, 0)),
FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(fl_value_get_map_value(value, 0)), 42);
}
TEST(FlValueTest, MapSetTake) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_string("count"), fl_value_new_int(42));
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_MAP);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(1));
ASSERT_EQ(fl_value_get_type(fl_value_get_map_key(value, 0)),
FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(fl_value_get_map_key(value, 0)), "count");
ASSERT_EQ(fl_value_get_type(fl_value_get_map_value(value, 0)),
FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(fl_value_get_map_value(value, 0)), 42);
}
TEST(FlValueTest, MapSetString) {
g_autoptr(FlValue) value = fl_value_new_map();
g_autoptr(FlValue) v = fl_value_new_int(42);
fl_value_set_string(value, "count", v);
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_MAP);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(1));
ASSERT_EQ(fl_value_get_type(fl_value_get_map_key(value, 0)),
FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(fl_value_get_map_key(value, 0)), "count");
ASSERT_EQ(fl_value_get_type(fl_value_get_map_value(value, 0)),
FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(fl_value_get_map_value(value, 0)), 42);
}
TEST(FlValueTest, MapSetStringTake) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_string_take(value, "count", fl_value_new_int(42));
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_MAP);
ASSERT_EQ(fl_value_get_length(value), static_cast<size_t>(1));
ASSERT_EQ(fl_value_get_type(fl_value_get_map_key(value, 0)),
FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(fl_value_get_map_key(value, 0)), "count");
ASSERT_EQ(fl_value_get_type(fl_value_get_map_value(value, 0)),
FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(fl_value_get_map_value(value, 0)), 42);
}
TEST(FlValueTest, MapLookup) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_string_take(value, "one", fl_value_new_int(1));
fl_value_set_string_take(value, "two", fl_value_new_int(2));
fl_value_set_string_take(value, "three", fl_value_new_int(3));
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_MAP);
g_autoptr(FlValue) two_key = fl_value_new_string("two");
FlValue* v = fl_value_lookup(value, two_key);
ASSERT_NE(v, nullptr);
ASSERT_EQ(fl_value_get_type(v), FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(v), 2);
g_autoptr(FlValue) four_key = fl_value_new_string("four");
v = fl_value_lookup(value, four_key);
ASSERT_EQ(v, nullptr);
}
TEST(FlValueTest, MapLookupString) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_string_take(value, "one", fl_value_new_int(1));
fl_value_set_string_take(value, "two", fl_value_new_int(2));
fl_value_set_string_take(value, "three", fl_value_new_int(3));
FlValue* v = fl_value_lookup_string(value, "two");
ASSERT_NE(v, nullptr);
ASSERT_EQ(fl_value_get_type(v), FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(v), 2);
v = fl_value_lookup_string(value, "four");
ASSERT_EQ(v, nullptr);
}
TEST(FlValueTest, MapEqual) {
g_autoptr(FlValue) value1 = fl_value_new_map();
fl_value_set_string_take(value1, "one", fl_value_new_int(1));
fl_value_set_string_take(value1, "two", fl_value_new_int(2));
fl_value_set_string_take(value1, "three", fl_value_new_int(3));
g_autoptr(FlValue) value2 = fl_value_new_map();
fl_value_set_string_take(value2, "one", fl_value_new_int(1));
fl_value_set_string_take(value2, "two", fl_value_new_int(2));
fl_value_set_string_take(value2, "three", fl_value_new_int(3));
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, MapEqualDifferentOrder) {
g_autoptr(FlValue) value1 = fl_value_new_map();
fl_value_set_string_take(value1, "one", fl_value_new_int(1));
fl_value_set_string_take(value1, "two", fl_value_new_int(2));
fl_value_set_string_take(value1, "three", fl_value_new_int(3));
g_autoptr(FlValue) value2 = fl_value_new_map();
fl_value_set_string_take(value2, "one", fl_value_new_int(1));
fl_value_set_string_take(value2, "three", fl_value_new_int(3));
fl_value_set_string_take(value2, "two", fl_value_new_int(2));
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, MapEmptyEqual) {
g_autoptr(FlValue) value1 = fl_value_new_map();
g_autoptr(FlValue) value2 = fl_value_new_map();
EXPECT_TRUE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, MapNotEqualSameSizeDifferentKeys) {
g_autoptr(FlValue) value1 = fl_value_new_map();
fl_value_set_string_take(value1, "one", fl_value_new_int(1));
fl_value_set_string_take(value1, "two", fl_value_new_int(2));
fl_value_set_string_take(value1, "three", fl_value_new_int(3));
g_autoptr(FlValue) value2 = fl_value_new_map();
fl_value_set_string_take(value2, "one", fl_value_new_int(1));
fl_value_set_string_take(value2, "two", fl_value_new_int(2));
fl_value_set_string_take(value2, "four", fl_value_new_int(3));
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, MapNotEqualSameSizeDifferentValues) {
g_autoptr(FlValue) value1 = fl_value_new_map();
fl_value_set_string_take(value1, "one", fl_value_new_int(1));
fl_value_set_string_take(value1, "two", fl_value_new_int(2));
fl_value_set_string_take(value1, "three", fl_value_new_int(3));
g_autoptr(FlValue) value2 = fl_value_new_map();
fl_value_set_string_take(value2, "one", fl_value_new_int(1));
fl_value_set_string_take(value2, "two", fl_value_new_int(2));
fl_value_set_string_take(value2, "three", fl_value_new_int(4));
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, MapNotEqualDifferentSize) {
g_autoptr(FlValue) value1 = fl_value_new_map();
fl_value_set_string_take(value1, "one", fl_value_new_int(1));
fl_value_set_string_take(value1, "two", fl_value_new_int(2));
fl_value_set_string_take(value1, "three", fl_value_new_int(3));
g_autoptr(FlValue) value2 = fl_value_new_map();
fl_value_set_string_take(value2, "one", fl_value_new_int(1));
fl_value_set_string_take(value2, "two", fl_value_new_int(2));
fl_value_set_string_take(value2, "three", fl_value_new_int(3));
fl_value_set_string_take(value2, "four", fl_value_new_int(4));
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, MapEmptyNotEqual) {
g_autoptr(FlValue) value1 = fl_value_new_map();
g_autoptr(FlValue) value2 = fl_value_new_map();
fl_value_set_string_take(value2, "one", fl_value_new_int(1));
fl_value_set_string_take(value2, "two", fl_value_new_int(2));
fl_value_set_string_take(value2, "three", fl_value_new_int(3));
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, EqualSameObject) {
g_autoptr(FlValue) value = fl_value_new_null();
EXPECT_TRUE(fl_value_equal(value, value));
}
TEST(FlValueTest, NullIntNotEqual) {
g_autoptr(FlValue) value1 = fl_value_new_null();
g_autoptr(FlValue) value2 = fl_value_new_int(0);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, NullBoolNotEqual) {
g_autoptr(FlValue) value1 = fl_value_new_bool(FALSE);
g_autoptr(FlValue) value2 = fl_value_new_int(0);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, StringUint8ListNotEqual) {
uint8_t data[] = {'h', 'e', 'l', 'l', 'o'};
g_autoptr(FlValue) value1 = fl_value_new_uint8_list(data, 5);
g_autoptr(FlValue) value2 = fl_value_new_string("hello");
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Uint8ListInt32ListNotEqual) {
uint8_t data8[] = {0, 1, 2, 3, 4};
int32_t data32[] = {0, 1, 2, 3, 4};
g_autoptr(FlValue) value1 = fl_value_new_uint8_list(data8, 5);
g_autoptr(FlValue) value2 = fl_value_new_int32_list(data32, 5);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int32ListInt64ListNotEqual) {
int32_t data32[] = {0, 1, 2, 3, 4};
int64_t data64[] = {0, 1, 2, 3, 4};
g_autoptr(FlValue) value1 = fl_value_new_int32_list(data32, 5);
g_autoptr(FlValue) value2 = fl_value_new_int64_list(data64, 5);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, Int64ListFloatListNotEqual) {
int64_t data64[] = {0, 1, 2, 3, 4};
double dataf[] = {0.0, 1.0, 2.0, 3.0, 4.0};
g_autoptr(FlValue) value1 = fl_value_new_int64_list(data64, 5);
g_autoptr(FlValue) value2 = fl_value_new_float_list(dataf, 5);
EXPECT_FALSE(fl_value_equal(value1, value2));
}
TEST(FlValueTest, ListMapNotEqual) {
g_autoptr(FlValue) value1 = fl_value_new_list();
g_autoptr(FlValue) value2 = fl_value_new_map();
EXPECT_FALSE(fl_value_equal(value1, value2));
}

View File

@ -0,0 +1,507 @@
// 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_VALUE_H_
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_VALUE_H_
#include <glib.h>
#include <stdbool.h>
#include <stdint.h>
#if !defined(__FLUTTER_LINUX_INSIDE__) && !defined(FLUTTER_LINUX_COMPILATION)
#error "Only <flutter_linux/flutter_linux.h> can be included directly."
#endif
G_BEGIN_DECLS
/**
* FlValue:
*
* #FlValue is an object that contains the data types used in the platform
* channel codecs provided by Flutter.
*
* In Dart the values are represented as follows:
* - #FL_VALUE_TYPE_NULL: null
* - #FL_VALUE_TYPE_BOOL: bool
* - #FL_VALUE_TYPE_INT: num
* - #FL_VALUE_TYPE_FLOAT: num
* - #FL_VALUE_TYPE_STRING: String
* - #FL_VALUE_TYPE_UINT8_LIST: Uint8List
* - #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
*/
typedef struct _FlValue FlValue;
/**
* FlValueType:
* @FL_VALUE_TYPE_NULL: The null value.
* @FL_VALUE_TYPE_BOOL: A boolean.
* @FL_VALUE_TYPE_INT: A 64 bit signed integer.
* @FL_VALUE_TYPE_FLOAT: A 64 bit floating point number.
* @FL_VALUE_TYPE_STRING: UTF-8 text.
* @FL_VALUE_TYPE_UINT8_LIST: An ordered list of unsigned 8 bit integers.
* @FL_VALUE_TYPE_INT32_LIST: An ordered list of 32 bit integers.
* @FL_VALUE_TYPE_INT64_LIST: An ordered list of 64 bit integers.
* @FL_VALUE_TYPE_FLOAT_LIST: An ordered list of floating point numbers.
* @FL_VALUE_TYPE_LIST: An ordered list of #FlValue objects.
* @FL_VALUE_TYPE_MAP: A map of #FlValue objects keyed by #FlValue object.
*
* Types of #FlValue.
*/
typedef enum {
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,
FL_VALUE_TYPE_MAP,
} FlValueType;
/**
* fl_value_new_null:
*
* Creates an #FlValue that contains a null value.
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_null();
/**
* fl_value_new_bool:
* @value: the value.
*
* Creates an #FlValue that contains a boolean value.
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_bool(bool value);
/**
* fl_value_new_int:
* @value: the value.
*
* Creates an #FlValue that contains an integer number.
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_int(int64_t value);
/**
* fl_value_new_float:
* @value: the value.
*
* Creates an #FlValue that contains a floating point number.
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_float(double value);
/**
* fl_value_new_string:
* @value: a nul terminated UTF-8 string.
*
* Creates an #FlValue that contains UTF-8 text.
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_string(const gchar* value);
/**
* fl_value_new_string:
* @value: a buffer containing UTF-8 text. It does not require a nul terminator.
* @value_length: the number of bytes to use from @value.
*
* Creates an #FlValue that contains UTF-8 text.
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_string_sized(const gchar* value, size_t value_length);
/**
* fl_value_new_uint8_list:
* @data: Data to copy.
* @data_length: number of elements in @data.
*
* Creates an ordered list containing 8 bit unsigned integers.
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_uint8_list(const uint8_t* data, size_t data_length);
/**
* fl_value_new_uint8_list:
* @data: Data to copy
*
* Creates an ordered list containing 8 bit unsigned integers.
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_uint8_list_from_bytes(GBytes* data);
/**
* fl_value_new_int32_list:
*
* Creates an ordered list containing 32 bit integers.
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_int32_list(const int32_t* data, size_t data_length);
/**
* fl_value_new_int64_list:
*
* Creates an ordered list containing 64 bit integers.
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_int64_list(const int64_t* data, size_t data_length);
/**
* fl_value_new_float_list:
*
* Creates an ordered list containing floating point numbers.
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_float_list(const double* data, size_t data_length);
/**
* fl_value_new_list:
*
* 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().
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_list();
/**
* fl_value_new_list_from_strv:
* @str_array: a %NULL-terminated array of strings.
*
* Creates an ordered list containing #FlString values.
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_list_from_strv(const gchar* const* str_array);
/**
* fl_value_new_map:
*
* Creates an ordered associative array. Children can be added to the map
* using fl_value_set(), fl_value_set_take(), fl_value_set_string(),
* 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().
*
* Returns: a new #FlValue.
*/
FlValue* fl_value_new_map();
/**
* fl_value_ref:
* @value: an #FlValue
*
* Increases the reference count of an #FlValue.
*
* Returns: the value that was referenced.
*/
FlValue* fl_value_ref(FlValue* value);
/**
* fl_value_ref:
* @value: an #FlValue
*
* Dereases the reference count of an #FlValue. When the refernece count hits
* zero @value is destroyed and no longer valid.
*/
void fl_value_unref(FlValue* value);
/**
* fl_value_get_type:
* @value: an #FlValue
*
* Gets the type of @value.
*
* Returns: an #FlValueType.
*/
FlValueType fl_value_get_type(FlValue* value);
/**
* fl_value_equal:
* @a: an #FlValue
* @b: an #FlValue
*
* Compares two #FlValue to see if they are equivalent. Two values are
* considered equivalent if they are of the same type and their data is the same
* including any child values. For values of type #FL_VALUE_TYPE_MAP the order
* of the values does not matter.
*
* Returns: %TRUE if both values are equivalent.
*/
bool fl_value_equal(FlValue* a, FlValue* b);
/**
* fl_value_append:
* @value: an #FlValue of type #FL_VALUE_TYPE_LIST
* @child: an #FlValue
*
* Adds @child to the end of @value. Calling this with an #FlValue that is not
* of type #FL_VALUE_TYPE_LIST is a programming error.
*/
void fl_value_append(FlValue* value, FlValue* child);
/**
* fl_value_append:
* @value: an #FlValue of type #FL_VALUE_TYPE_LIST
* @child: (transfer full): an #FlValue
*
* Adds @child to the end of @value. Ownership of @child is taken by @value.
* Calling this with an #FlValue that is not of type #FL_VALUE_TYPE_LIST is a
* programming error.
*/
void fl_value_append_take(FlValue* value, FlValue* child);
/**
* fl_value_set:
* @value: an #FlValue of type #FL_VALUE_TYPE_MAP
* @key: an #FlValue
* @child_value: an #FlValue
*
* Sets @key in @value to @child_value. If an existing value was in the map with
* the same key it is replaced. Calling this with an #FlValue that is not of
* type #FL_VALUE_TYPE_MAP is a programming error.
*/
void fl_value_set(FlValue* value, FlValue* key, FlValue* child_value);
/**
* fl_value_set_take:
* @value: an #FlValue of type #FL_VALUE_TYPE_MAP
* @key: (transfer full): an #FlValue
* @child_value: (transfer full): an #FlValue
*
* Sets @key in @value to @child_value. Ownership of both @key and @child_value
* is taken by @value. If an existing value was in the map with the same key it
* is replaced. Calling this with an #FlValue that is not of type
* #FL_VALUE_TYPE_MAP is a programming error.
*/
void fl_value_set_take(FlValue* value, FlValue* key, FlValue* child_value);
/**
* fl_value_set_string:
* @value: an #FlValue of type #FL_VALUE_TYPE_MAP
* @key: a UTF-8 text key
* @child_value: an #FlValue
*
* Sets a value in the map with a text key. If an existing value was in the map
* with the same key it is replaced. Calling this with an #FlValue that is not
* of type #FL_VALUE_TYPE_MAP is a programming error.
*/
void fl_value_set_string(FlValue* value,
const gchar* key,
FlValue* child_value);
/**
* fl_value_set_string_take:
* @value: an #FlValue of type #FL_VALUE_TYPE_MAP
* @key: a UTF-8 text key
* @child_value: (transfer full): an #FlValue
*
* Sets a value in the map with a text key, taking ownership of the value. If an
* existing value was in the map with the same key it is replaced. Calling this
* with an #FlValue that is not of type #FL_VALUE_TYPE_MAP is a programming
* error.
*/
void fl_value_set_string_take(FlValue* value,
const gchar* key,
FlValue* child_value);
/**
* fl_value_get_bool:
* @value: an #FlValue of type #FL_VALUE_TYPE_BOOL
*
* Gets the boolean value of @value. Calling this with an #FlValue that is
* not of type #FL_VALUE_TYPE_BOOL is a programming error.
*
* Returns: a boolean value.
*/
bool fl_value_get_bool(FlValue* value);
/**
* fl_value_get_int:
* @value: an #FlValue of type #FL_VALUE_TYPE_INT
*
* Gets the integer number of @value. Calling this with an #FlValue that is
* not of type #FL_VALUE_TYPE_INT is a programming error.
*
* Returns: an integer number.
*/
int64_t fl_value_get_int(FlValue* value);
/**
* fl_value_get_double:
* @value: an #FlValue of type #FL_VALUE_TYPE_FLOAT
*
* Gets the floating point number of @value. Calling this with an #FlValue
* that is not of type #FL_VALUE_TYPE_FLOAT is a programming error.
*
* Returns: a UTF-8 encoded string.
*/
double fl_value_get_float(FlValue* value);
/**
* fl_value_get_string:
* @value: an #FlValue of type #FL_VALUE_TYPE_STRING
*
* Gets the UTF-8 text contained in @value. Calling this with an #FlValue
* that is not of type #FL_VALUE_TYPE_STRING is a programming error.
*
* Returns: a UTF-8 encoded string.
*/
const gchar* fl_value_get_string(FlValue* value);
/**
* fl_value_get_length:
* @value: an #FlValue of type #FL_VALUE_TYPE_UINT8_LIST,
* #FL_VALUE_TYPE_INT32_LIST, #FL_VALUE_TYPE_INT64_LIST,
* #FL_VALUE_TYPE_FLOAT_LIST, #FL_VALUE_TYPE_LIST or #FL_VALUE_TYPE_MAP.
*
* Gets the number of elements @value contains. This is only valid for list
* and map types. Calling this with other types is a programming error.
*
* Returns: the number of elements inside @value.
*/
size_t fl_value_get_length(FlValue* value);
/**
* fl_value_get_uint8_list:
* @value: an #FlValue of type #FL_VALUE_TYPE_UINT8_LIST
*
* Gets the array of unisigned 8 bit integers @value contains. The data
* contains fl_get_length() elements. Calling this with an #FlValue that is
* not of type #FL_VALUE_TYPE_UINT8_LIST is a programming error.
*
* Returns: an array of unsigned 8 bit integers.
*/
const uint8_t* fl_value_get_uint8_list(FlValue* value);
/**
* fl_value_get_int32_list:
* @value: an #FlValue of type #FL_VALUE_TYPE_INT32_LIST
*
* Gets the array of 32 bit integers @value contains. The data contains
* fl_get_length() elements. Calling this with an #FlValue that is not of
* type #FL_VALUE_TYPE_INT32_LIST is a programming error.
*
* Returns: an array of 32 bit integers.
*/
const int32_t* fl_value_get_int32_list(FlValue* value);
/**
* fl_value_get_int64_list:
* @value: an #FlValue of type #FL_VALUE_TYPE_INT64_LIST
*
* Gets the array of 64 bit integers @value contains. The data contains
* fl_get_length() elements. Calling this with an #FlValue that is not of
* type #FL_VALUE_TYPE_INT64_LIST is a programming error.
*
* Returns: an array of 64 bit integers.
*/
const int64_t* fl_value_get_int64_list(FlValue* value);
/**
* fl_value_get_float_list:
* @value: an #FlValue of type #FL_VALUE_TYPE_FLOAT_LIST
*
* Gets the array of floating point numbers @value contains. The data
* contains fl_get_length() elements. Calling this with an #FlValue that is
* not of type #FL_VALUE_TYPE_FLOAT_LIST is a programming error.
*
* Returns: an array of floating point numbers.
*/
const double* fl_value_get_float_list(FlValue* value);
/**
* fl_value_get_list_value:
* @value: an #FlValue of type #FL_VALUE_TYPE_LIST.
* @index: an index in the list.
*
* Gets a child element of the list. It is a programming error to request an
* index that is outside the size of the list as returned from
* fl_value_get_length().
*
* Returns: an #FlValue
*/
FlValue* fl_value_get_list_value(FlValue* value, size_t index);
/**
* fl_value_get_map_key:
* @value: an #FlValue of type #FL_VALUE_TYPE_MAP.
* @index: an index in the map.
*
* Gets an key from the map. It is a programming error to request an index that
* is outside the size of the list as returned from fl_value_get_length().
*
* Returns: an #FlValue
*/
FlValue* fl_value_get_map_key(FlValue* value, size_t index);
/**
* fl_value_get_map_key:
* @value: an #FlValue of type #FL_VALUE_TYPE_MAP.
* @index: an index in the map.
*
* Gets a value from the map. It is a programming error to request an index that
* is outside the size of the list as returned from fl_value_get_length().
*
* Returns: an #FlValue
*/
FlValue* fl_value_get_map_value(FlValue* value, size_t index);
/**
* fl_value_lookup:
* @value: an #FlValue of type #FL_VALUE_TYPE_MAP
* @key: a key value
*
* Gets the map entry that matches @key. Keys are checked using
* fl_value_equal().
*
* Map lookups are not optimised for performance - if have a large map or need
* frequent access you should copy the data into another structure, e.g.
* #GHashTable.
*
* Returns: (allow-none): the value with this key or %NULL if not one present.
*/
FlValue* fl_value_lookup(FlValue* value, FlValue* key);
/**
* fl_value_lookup_string:
* @value: an #FlValue of type #FL_VALUE_TYPE_MAP
* @key: a key value
*
* Gets the map entry that matches @key. Keys are checked using
* fl_value_equal().
*
* Map lookups are not optimised for performance - if have a large map or need
* frequent access you should copy the data into another structure, e.g.
* #GHashTable.
*
* Returns: (allow-none): the value with this key or %NULL if not one present.
*/
FlValue* fl_value_lookup_string(FlValue* value, const gchar* key);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(FlValue, fl_value_unref)
G_END_DECLS
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_VALUE_H_

View File

@ -10,6 +10,7 @@
#include <flutter_linux/fl_binary_messenger.h>
#include <flutter_linux/fl_dart_project.h>
#include <flutter_linux/fl_engine.h>
#include <flutter_linux/fl_value.h>
#include <flutter_linux/fl_view.h>
#undef __FLUTTER_LINUX_INSIDE__