mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
696 lines
23 KiB
C++
696 lines
23 KiB
C++
// 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;
|
|
}
|
|
|
|
// 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));
|
|
}
|
|
|
|
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) {
|
|
g_return_val_if_fail(self != nullptr, nullptr);
|
|
self->ref_count++;
|
|
return self;
|
|
}
|
|
|
|
G_MODULE_EXPORT void fl_value_unref(FlValue* self) {
|
|
g_return_if_fail(self != nullptr);
|
|
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 != nullptr);
|
|
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 != nullptr);
|
|
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 != nullptr);
|
|
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 != nullptr);
|
|
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 != nullptr);
|
|
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 != nullptr);
|
|
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 != nullptr, FALSE);
|
|
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 != nullptr, 0);
|
|
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 != nullptr, 0.0);
|
|
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 != nullptr, nullptr);
|
|
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 != nullptr, nullptr);
|
|
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 != nullptr, nullptr);
|
|
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 != nullptr, nullptr);
|
|
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 != nullptr, nullptr);
|
|
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 != nullptr, 0);
|
|
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 != nullptr, nullptr);
|
|
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 != nullptr, nullptr);
|
|
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 != nullptr, nullptr);
|
|
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 != nullptr, nullptr);
|
|
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);
|
|
}
|
|
|
|
G_MODULE_EXPORT FlValue* fl_value_lookup_string(FlValue* self,
|
|
const gchar* key) {
|
|
g_return_val_if_fail(self != nullptr, nullptr);
|
|
g_autoptr(FlValue) string_key = fl_value_new_string(key);
|
|
return fl_value_lookup(self, string_key);
|
|
}
|
|
|
|
G_MODULE_EXPORT gchar* fl_value_to_string(FlValue* value) {
|
|
GString* buffer = g_string_new("");
|
|
value_to_string(value, buffer);
|
|
return g_string_free(buffer, FALSE);
|
|
}
|