| Flutter Linux Embedder |

fl_value.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "flutter/shell/platform/linux/public/flutter_linux/fl_value.h"
6
7 #include <gmodule.h>
8
9 #include <cstring>
10
11 struct _FlValue {
12 FlValueType type;
13 int ref_count;
14 };
15
16 typedef struct {
17 FlValue parent;
18 bool value;
19 } FlValueBool;
20
21 typedef struct {
22 FlValue parent;
23 int64_t value;
24 } FlValueInt;
25
26 typedef struct {
27 FlValue parent;
28 double value;
29 } FlValueDouble;
30
31 typedef struct {
32 FlValue parent;
33 gchar* value;
34 } FlValueString;
35
36 typedef struct {
37 FlValue parent;
38 uint8_t* values;
39 size_t values_length;
40 } FlValueUint8List;
41
42 typedef struct {
43 FlValue parent;
44 int32_t* values;
45 size_t values_length;
46 } FlValueInt32List;
47
48 typedef struct {
49 FlValue parent;
50 int64_t* values;
51 size_t values_length;
52 } FlValueInt64List;
53
54 typedef struct {
55 FlValue parent;
56 float* values;
57 size_t values_length;
58 } FlValueFloat32List;
59
60 typedef struct {
61 FlValue parent;
62 double* values;
63 size_t values_length;
64 } FlValueFloatList;
65
66 typedef struct {
67 FlValue parent;
68 GPtrArray* values;
69 } FlValueList;
70
71 typedef struct {
72 FlValue parent;
73 GPtrArray* keys;
74 GPtrArray* values;
75 } FlValueMap;
76
77 typedef struct {
78 FlValue parent;
79 int type;
80 gconstpointer value;
81 GDestroyNotify destroy_notify;
82 } FlValueCustom;
83
84 static FlValue* fl_value_new(FlValueType type, size_t size) {
85 FlValue* self = static_cast<FlValue*>(g_malloc0(size));
86 self->type = type;
87 self->ref_count = 1;
88 return self;
89 }
90
91 // Helper function to match GDestroyNotify type.
92 static void fl_value_destroy(gpointer value) {
93 fl_value_unref(static_cast<FlValue*>(value));
94 }
95
96 // Finds the index of a key in a FlValueMap.
97 // FIXME(robert-ancell) This is highly inefficient, and should be optimized if
98 // necessary.
99 static ssize_t fl_value_lookup_index(FlValue* self, FlValue* key) {
100 g_return_val_if_fail(self->type == FL_VALUE_TYPE_MAP, -1);
101
102 for (size_t i = 0; i < fl_value_get_length(self); i++) {
103 FlValue* k = fl_value_get_map_key(self, i);
104 if (fl_value_equal(k, key)) {
105 return i;
106 }
107 }
108 return -1;
109 }
110
111 // Converts an integer to a string and adds it to the buffer.
112 static void int_to_string(int64_t value, GString* buffer) {
113 g_string_append_printf(buffer, "%" G_GINT64_FORMAT, value);
114 }
115
116 // Converts a floating point number to a string and adds it to the buffer.
117 static void float_to_string(double value, GString* buffer) {
118 g_string_append_printf(buffer, "%.16f", value);
119
120 // Strip trailing zeros.
121 int zero_count = 0;
122 for (int i = buffer->len - 1; i >= 0; i--) {
123 // Leave one zero after a decimal point.
124 if (buffer->str[i] == '.') {
125 zero_count = zero_count == 0 ? 0 : zero_count - 1;
126 break;
127 }
128 if (buffer->str[i] != '0') {
129 break;
130 }
131 zero_count++;
132 }
133 g_string_truncate(buffer, buffer->len - zero_count);
134 }
135
136 static void value_to_string(FlValue* value, GString* buffer) {
137 switch (value->type) {
138 case FL_VALUE_TYPE_NULL:
139 g_string_append(buffer, "null");
140 return;
141 case FL_VALUE_TYPE_BOOL:
142 if (fl_value_get_bool(value)) {
143 g_string_append(buffer, "true");
144 } else {
145 g_string_append(buffer, "false");
146 }
147 return;
148 case FL_VALUE_TYPE_INT:
149 int_to_string(fl_value_get_int(value), buffer);
150 return;
151 case FL_VALUE_TYPE_FLOAT:
152 float_to_string(fl_value_get_float(value), buffer);
153 return;
154 case FL_VALUE_TYPE_STRING: {
155 g_string_append(buffer, fl_value_get_string(value));
156 return;
157 }
158 case FL_VALUE_TYPE_UINT8_LIST: {
159 g_string_append(buffer, "[");
160 const uint8_t* values = fl_value_get_uint8_list(value);
161 for (size_t i = 0; i < fl_value_get_length(value); i++) {
162 if (i != 0) {
163 g_string_append(buffer, ", ");
164 }
165 int_to_string(values[i], buffer);
166 }
167 g_string_append(buffer, "]");
168 return;
169 }
170 case FL_VALUE_TYPE_INT32_LIST: {
171 g_string_append(buffer, "[");
172 const int32_t* values = fl_value_get_int32_list(value);
173 for (size_t i = 0; i < fl_value_get_length(value); i++) {
174 if (i != 0) {
175 g_string_append(buffer, ", ");
176 }
177 int_to_string(values[i], buffer);
178 }
179 g_string_append(buffer, "]");
180 return;
181 }
182 case FL_VALUE_TYPE_INT64_LIST: {
183 g_string_append(buffer, "[");
184 const int64_t* values = fl_value_get_int64_list(value);
185 for (size_t i = 0; i < fl_value_get_length(value); i++) {
186 if (i != 0) {
187 g_string_append(buffer, ", ");
188 }
189 int_to_string(values[i], buffer);
190 }
191 g_string_append(buffer, "]");
192 return;
193 }
194 case FL_VALUE_TYPE_FLOAT32_LIST: {
195 g_string_append(buffer, "[");
196 const float* values = fl_value_get_float32_list(value);
197 for (size_t i = 0; i < fl_value_get_length(value); i++) {
198 if (i != 0) {
199 g_string_append(buffer, ", ");
200 }
201 float_to_string(values[i], buffer);
202 }
203 g_string_append(buffer, "]");
204 return;
205 }
206 case FL_VALUE_TYPE_FLOAT_LIST: {
207 g_string_append(buffer, "[");
208 const double* values = fl_value_get_float_list(value);
209 for (size_t i = 0; i < fl_value_get_length(value); i++) {
210 if (i != 0) {
211 g_string_append(buffer, ", ");
212 }
213 float_to_string(values[i], buffer);
214 }
215 g_string_append(buffer, "]");
216 return;
217 }
218 case FL_VALUE_TYPE_LIST: {
219 g_string_append(buffer, "[");
220 for (size_t i = 0; i < fl_value_get_length(value); i++) {
221 if (i != 0) {
222 g_string_append(buffer, ", ");
223 }
224 value_to_string(fl_value_get_list_value(value, i), buffer);
225 }
226 g_string_append(buffer, "]");
227 return;
228 }
229 case FL_VALUE_TYPE_MAP: {
230 g_string_append(buffer, "{");
231 for (size_t i = 0; i < fl_value_get_length(value); i++) {
232 if (i != 0) {
233 g_string_append(buffer, ", ");
234 }
235 value_to_string(fl_value_get_map_key(value, i), buffer);
236 g_string_append(buffer, ": ");
237 value_to_string(fl_value_get_map_value(value, i), buffer);
238 }
239 g_string_append(buffer, "}");
240 return;
241 }
242 case FL_VALUE_TYPE_CUSTOM:
243 g_string_append_printf(buffer, "(custom %d)",
244 fl_value_get_custom_type(value));
245 return;
246 default:
247 g_string_append_printf(buffer, "<unknown type %d>", value->type);
248 }
249 }
250
251 G_MODULE_EXPORT FlValue* fl_value_new_null() {
252 return fl_value_new(FL_VALUE_TYPE_NULL, sizeof(FlValue));
253 }
254
255 G_MODULE_EXPORT FlValue* fl_value_new_bool(bool value) {
256 FlValueBool* self = reinterpret_cast<FlValueBool*>(
257 fl_value_new(FL_VALUE_TYPE_BOOL, sizeof(FlValueBool)));
258 self->value = value ? true : false;
259 return reinterpret_cast<FlValue*>(self);
260 }
261
262 G_MODULE_EXPORT FlValue* fl_value_new_int(int64_t value) {
263 FlValueInt* self = reinterpret_cast<FlValueInt*>(
264 fl_value_new(FL_VALUE_TYPE_INT, sizeof(FlValueInt)));
265 self->value = value;
266 return reinterpret_cast<FlValue*>(self);
267 }
268
269 G_MODULE_EXPORT FlValue* fl_value_new_float(double value) {
270 FlValueDouble* self = reinterpret_cast<FlValueDouble*>(
271 fl_value_new(FL_VALUE_TYPE_FLOAT, sizeof(FlValueDouble)));
272 self->value = value;
273 return reinterpret_cast<FlValue*>(self);
274 }
275
276 G_MODULE_EXPORT FlValue* fl_value_new_string(const gchar* value) {
277 FlValueString* self = reinterpret_cast<FlValueString*>(
278 fl_value_new(FL_VALUE_TYPE_STRING, sizeof(FlValueString)));
279 self->value = g_strdup(value);
280 return reinterpret_cast<FlValue*>(self);
281 }
282
283 G_MODULE_EXPORT FlValue* fl_value_new_string_sized(const gchar* value,
284 size_t value_length) {
285 FlValueString* self = reinterpret_cast<FlValueString*>(
286 fl_value_new(FL_VALUE_TYPE_STRING, sizeof(FlValueString)));
287 self->value =
288 value_length == 0 ? g_strdup("") : g_strndup(value, value_length);
289 return reinterpret_cast<FlValue*>(self);
290 }
291
292 G_MODULE_EXPORT FlValue* fl_value_new_uint8_list(const uint8_t* data,
293 size_t data_length) {
294 FlValueUint8List* self = reinterpret_cast<FlValueUint8List*>(
295 fl_value_new(FL_VALUE_TYPE_UINT8_LIST, sizeof(FlValueUint8List)));
296 self->values_length = data_length;
297 self->values = static_cast<uint8_t*>(g_malloc(sizeof(uint8_t) * data_length));
298 memcpy(self->values, data, sizeof(uint8_t) * data_length);
299 return reinterpret_cast<FlValue*>(self);
300 }
301
302 G_MODULE_EXPORT FlValue* fl_value_new_uint8_list_from_bytes(GBytes* data) {
303 gsize length;
304 const uint8_t* d =
305 static_cast<const uint8_t*>(g_bytes_get_data(data, &length));
306 return fl_value_new_uint8_list(d, length);
307 }
308
309 G_MODULE_EXPORT FlValue* fl_value_new_int32_list(const int32_t* data,
310 size_t data_length) {
311 FlValueInt32List* self = reinterpret_cast<FlValueInt32List*>(
312 fl_value_new(FL_VALUE_TYPE_INT32_LIST, sizeof(FlValueInt32List)));
313 self->values_length = data_length;
314 self->values = static_cast<int32_t*>(g_malloc(sizeof(int32_t) * data_length));
315 memcpy(self->values, data, sizeof(int32_t) * data_length);
316 return reinterpret_cast<FlValue*>(self);
317 }
318
319 G_MODULE_EXPORT FlValue* fl_value_new_int64_list(const int64_t* data,
320 size_t data_length) {
321 FlValueInt64List* self = reinterpret_cast<FlValueInt64List*>(
322 fl_value_new(FL_VALUE_TYPE_INT64_LIST, sizeof(FlValueInt64List)));
323 self->values_length = data_length;
324 self->values = static_cast<int64_t*>(g_malloc(sizeof(int64_t) * data_length));
325 memcpy(self->values, data, sizeof(int64_t) * data_length);
326 return reinterpret_cast<FlValue*>(self);
327 }
328
329 G_MODULE_EXPORT FlValue* fl_value_new_float32_list(const float* data,
330 size_t data_length) {
331 FlValueFloat32List* self = reinterpret_cast<FlValueFloat32List*>(
332 fl_value_new(FL_VALUE_TYPE_FLOAT32_LIST, sizeof(FlValueFloat32List)));
333 self->values_length = data_length;
334 self->values = static_cast<float*>(g_malloc(sizeof(float) * data_length));
335 memcpy(self->values, data, sizeof(float) * data_length);
336 return reinterpret_cast<FlValue*>(self);
337 }
338
339 G_MODULE_EXPORT FlValue* fl_value_new_float_list(const double* data,
340 size_t data_length) {
341 FlValueFloatList* self = reinterpret_cast<FlValueFloatList*>(
342 fl_value_new(FL_VALUE_TYPE_FLOAT_LIST, sizeof(FlValueFloatList)));
343 self->values_length = data_length;
344 self->values = static_cast<double*>(g_malloc(sizeof(double) * data_length));
345 memcpy(self->values, data, sizeof(double) * data_length);
346 return reinterpret_cast<FlValue*>(self);
347 }
348
349 G_MODULE_EXPORT FlValue* fl_value_new_list() {
350 FlValueList* self = reinterpret_cast<FlValueList*>(
351 fl_value_new(FL_VALUE_TYPE_LIST, sizeof(FlValueList)));
352 self->values = g_ptr_array_new_with_free_func(fl_value_destroy);
353 return reinterpret_cast<FlValue*>(self);
354 }
355
356 G_MODULE_EXPORT FlValue* fl_value_new_list_from_strv(
357 const gchar* const* str_array) {
358 g_return_val_if_fail(str_array != nullptr, nullptr);
359 g_autoptr(FlValue) value = fl_value_new_list();
360 for (int i = 0; str_array[i] != nullptr; i++) {
361 fl_value_append_take(value, fl_value_new_string(str_array[i]));
362 }
363 return fl_value_ref(value);
364 }
365
366 G_MODULE_EXPORT FlValue* fl_value_new_map() {
367 FlValueMap* self = reinterpret_cast<FlValueMap*>(
368 fl_value_new(FL_VALUE_TYPE_MAP, sizeof(FlValueMap)));
369 self->keys = g_ptr_array_new_with_free_func(fl_value_destroy);
370 self->values = g_ptr_array_new_with_free_func(fl_value_destroy);
371 return reinterpret_cast<FlValue*>(self);
372 }
373
374 G_MODULE_EXPORT FlValue* fl_value_new_custom(int type,
375 gconstpointer value,
376 GDestroyNotify destroy_notify) {
377 FlValueCustom* self = reinterpret_cast<FlValueCustom*>(
378 fl_value_new(FL_VALUE_TYPE_CUSTOM, sizeof(FlValueCustom)));
379 self->type = type;
380 self->value = value;
381 self->destroy_notify = destroy_notify;
382 return reinterpret_cast<FlValue*>(self);
383 }
384
385 G_MODULE_EXPORT FlValue* fl_value_new_custom_object(int type, GObject* object) {
386 return fl_value_new_custom(type, g_object_ref(object), g_object_unref);
387 }
388
389 G_MODULE_EXPORT FlValue* fl_value_new_custom_object_take(int type,
390 GObject* object) {
391 return fl_value_new_custom(type, object, g_object_unref);
392 }
393
394 G_MODULE_EXPORT FlValue* fl_value_ref(FlValue* self) {
395 g_return_val_if_fail(self != nullptr, nullptr);
396 self->ref_count++;
397 return self;
398 }
399
400 G_MODULE_EXPORT void fl_value_unref(FlValue* self) {
401 g_return_if_fail(self != nullptr);
402 g_return_if_fail(self->ref_count > 0);
403 self->ref_count--;
404 if (self->ref_count != 0) {
405 return;
406 }
407
408 switch (self->type) {
409 case FL_VALUE_TYPE_STRING: {
410 FlValueString* v = reinterpret_cast<FlValueString*>(self);
411 g_free(v->value);
412 break;
413 }
414 case FL_VALUE_TYPE_UINT8_LIST: {
415 FlValueUint8List* v = reinterpret_cast<FlValueUint8List*>(self);
416 g_free(v->values);
417 break;
418 }
419 case FL_VALUE_TYPE_INT32_LIST: {
420 FlValueInt32List* v = reinterpret_cast<FlValueInt32List*>(self);
421 g_free(v->values);
422 break;
423 }
424 case FL_VALUE_TYPE_INT64_LIST: {
425 FlValueInt64List* v = reinterpret_cast<FlValueInt64List*>(self);
426 g_free(v->values);
427 break;
428 }
429 case FL_VALUE_TYPE_FLOAT32_LIST: {
430 FlValueFloat32List* v = reinterpret_cast<FlValueFloat32List*>(self);
431 g_free(v->values);
432 break;
433 }
434 case FL_VALUE_TYPE_FLOAT_LIST: {
435 FlValueFloatList* v = reinterpret_cast<FlValueFloatList*>(self);
436 g_free(v->values);
437 break;
438 }
439 case FL_VALUE_TYPE_LIST: {
440 FlValueList* v = reinterpret_cast<FlValueList*>(self);
441 g_ptr_array_unref(v->values);
442 break;
443 }
444 case FL_VALUE_TYPE_MAP: {
445 FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
446 g_ptr_array_unref(v->keys);
447 g_ptr_array_unref(v->values);
448 break;
449 }
450 case FL_VALUE_TYPE_CUSTOM: {
451 FlValueCustom* v = reinterpret_cast<FlValueCustom*>(self);
452 if (v->destroy_notify != nullptr) {
453 v->destroy_notify(const_cast<gpointer>(v->value));
454 }
455 break;
456 }
457 case FL_VALUE_TYPE_NULL:
458 case FL_VALUE_TYPE_BOOL:
459 case FL_VALUE_TYPE_INT:
460 case FL_VALUE_TYPE_FLOAT:
461 break;
462 }
463 g_free(self);
464 }
465
466 G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue* self) {
467 g_return_val_if_fail(self != nullptr, FL_VALUE_TYPE_NULL);
468 return self->type;
469 }
470
471 G_MODULE_EXPORT bool fl_value_equal(FlValue* a, FlValue* b) {
472 g_return_val_if_fail(a != nullptr, false);
473 g_return_val_if_fail(b != nullptr, false);
474
475 if (a->type != b->type) {
476 return false;
477 }
478
479 switch (a->type) {
480 case FL_VALUE_TYPE_NULL:
481 return true;
482 case FL_VALUE_TYPE_BOOL:
483 return fl_value_get_bool(a) == fl_value_get_bool(b);
484 case FL_VALUE_TYPE_INT:
485 return fl_value_get_int(a) == fl_value_get_int(b);
486 case FL_VALUE_TYPE_FLOAT:
487 return fl_value_get_float(a) == fl_value_get_float(b);
488 case FL_VALUE_TYPE_STRING: {
489 FlValueString* a_ = reinterpret_cast<FlValueString*>(a);
490 FlValueString* b_ = reinterpret_cast<FlValueString*>(b);
491 return g_strcmp0(a_->value, b_->value) == 0;
492 }
493 case FL_VALUE_TYPE_UINT8_LIST: {
494 if (fl_value_get_length(a) != fl_value_get_length(b)) {
495 return false;
496 }
497 const uint8_t* values_a = fl_value_get_uint8_list(a);
498 const uint8_t* values_b = fl_value_get_uint8_list(b);
499 for (size_t i = 0; i < fl_value_get_length(a); i++) {
500 if (values_a[i] != values_b[i]) {
501 return false;
502 }
503 }
504 return true;
505 }
506 case FL_VALUE_TYPE_INT32_LIST: {
507 if (fl_value_get_length(a) != fl_value_get_length(b)) {
508 return false;
509 }
510 const int32_t* values_a = fl_value_get_int32_list(a);
511 const int32_t* values_b = fl_value_get_int32_list(b);
512 for (size_t i = 0; i < fl_value_get_length(a); i++) {
513 if (values_a[i] != values_b[i]) {
514 return false;
515 }
516 }
517 return true;
518 }
519 case FL_VALUE_TYPE_INT64_LIST: {
520 if (fl_value_get_length(a) != fl_value_get_length(b)) {
521 return false;
522 }
523 const int64_t* values_a = fl_value_get_int64_list(a);
524 const int64_t* values_b = fl_value_get_int64_list(b);
525 for (size_t i = 0; i < fl_value_get_length(a); i++) {
526 if (values_a[i] != values_b[i]) {
527 return false;
528 }
529 }
530 return true;
531 }
532 case FL_VALUE_TYPE_FLOAT32_LIST: {
533 if (fl_value_get_length(a) != fl_value_get_length(b)) {
534 return false;
535 }
536 const float* values_a = fl_value_get_float32_list(a);
537 const float* values_b = fl_value_get_float32_list(b);
538 for (size_t i = 0; i < fl_value_get_length(a); i++) {
539 if (values_a[i] != values_b[i]) {
540 return false;
541 }
542 }
543 return true;
544 }
545 case FL_VALUE_TYPE_FLOAT_LIST: {
546 if (fl_value_get_length(a) != fl_value_get_length(b)) {
547 return false;
548 }
549 const double* values_a = fl_value_get_float_list(a);
550 const double* values_b = fl_value_get_float_list(b);
551 for (size_t i = 0; i < fl_value_get_length(a); i++) {
552 if (values_a[i] != values_b[i]) {
553 return false;
554 }
555 }
556 return true;
557 }
558 case FL_VALUE_TYPE_LIST: {
559 if (fl_value_get_length(a) != fl_value_get_length(b)) {
560 return false;
561 }
562 for (size_t i = 0; i < fl_value_get_length(a); i++) {
563 if (!fl_value_equal(fl_value_get_list_value(a, i),
564 fl_value_get_list_value(b, i))) {
565 return false;
566 }
567 }
568 return true;
569 }
570 case FL_VALUE_TYPE_MAP: {
571 if (fl_value_get_length(a) != fl_value_get_length(b)) {
572 return false;
573 }
574 for (size_t i = 0; i < fl_value_get_length(a); i++) {
575 FlValue* key = fl_value_get_map_key(a, i);
576 FlValue* value_b = fl_value_lookup(b, key);
577 if (value_b == nullptr) {
578 return false;
579 }
580 FlValue* value_a = fl_value_get_map_value(a, i);
581 if (!fl_value_equal(value_a, value_b)) {
582 return false;
583 }
584 }
585 return true;
586 }
587 case FL_VALUE_TYPE_CUSTOM:
588 return false;
589 }
590 }
591
592 G_MODULE_EXPORT void fl_value_append(FlValue* self, FlValue* value) {
593 g_return_if_fail(self != nullptr);
594 g_return_if_fail(self->type == FL_VALUE_TYPE_LIST);
595 g_return_if_fail(value != nullptr);
596
597 fl_value_append_take(self, fl_value_ref(value));
598 }
599
600 G_MODULE_EXPORT void fl_value_append_take(FlValue* self, FlValue* value) {
601 g_return_if_fail(self != nullptr);
602 g_return_if_fail(self->type == FL_VALUE_TYPE_LIST);
603 g_return_if_fail(value != nullptr);
604
605 FlValueList* v = reinterpret_cast<FlValueList*>(self);
606 g_ptr_array_add(v->values, value);
607 }
608
609 G_MODULE_EXPORT void fl_value_set(FlValue* self, FlValue* key, FlValue* value) {
610 g_return_if_fail(self != nullptr);
611 g_return_if_fail(self->type == FL_VALUE_TYPE_MAP);
612 g_return_if_fail(key != nullptr);
613 g_return_if_fail(value != nullptr);
614
615 fl_value_set_take(self, fl_value_ref(key), fl_value_ref(value));
616 }
617
618 G_MODULE_EXPORT void fl_value_set_take(FlValue* self,
619 FlValue* key,
620 FlValue* value) {
621 g_return_if_fail(self != nullptr);
622 g_return_if_fail(self->type == FL_VALUE_TYPE_MAP);
623 g_return_if_fail(key != nullptr);
624 g_return_if_fail(value != nullptr);
625
626 FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
627 ssize_t index = fl_value_lookup_index(self, key);
628 if (index < 0) {
629 g_ptr_array_add(v->keys, key);
630 g_ptr_array_add(v->values, value);
631 } else {
632 fl_value_destroy(v->keys->pdata[index]);
633 v->keys->pdata[index] = key;
634 fl_value_destroy(v->values->pdata[index]);
635 v->values->pdata[index] = value;
636 }
637 }
638
639 G_MODULE_EXPORT void fl_value_set_string(FlValue* self,
640 const gchar* key,
641 FlValue* value) {
642 g_return_if_fail(self != nullptr);
643 g_return_if_fail(self->type == FL_VALUE_TYPE_MAP);
644 g_return_if_fail(key != nullptr);
645 g_return_if_fail(value != nullptr);
646
647 fl_value_set_take(self, fl_value_new_string(key), fl_value_ref(value));
648 }
649
650 G_MODULE_EXPORT void fl_value_set_string_take(FlValue* self,
651 const gchar* key,
652 FlValue* value) {
653 g_return_if_fail(self != nullptr);
654 g_return_if_fail(self->type == FL_VALUE_TYPE_MAP);
655 g_return_if_fail(key != nullptr);
656 g_return_if_fail(value != nullptr);
657
658 fl_value_set_take(self, fl_value_new_string(key), value);
659 }
660
661 G_MODULE_EXPORT bool fl_value_get_bool(FlValue* self) {
662 g_return_val_if_fail(self != nullptr, FALSE);
663 g_return_val_if_fail(self->type == FL_VALUE_TYPE_BOOL, FALSE);
664 FlValueBool* v = reinterpret_cast<FlValueBool*>(self);
665 return v->value;
666 }
667
668 G_MODULE_EXPORT int64_t fl_value_get_int(FlValue* self) {
669 g_return_val_if_fail(self != nullptr, 0);
670 g_return_val_if_fail(self->type == FL_VALUE_TYPE_INT, 0);
671 FlValueInt* v = reinterpret_cast<FlValueInt*>(self);
672 return v->value;
673 }
674
675 G_MODULE_EXPORT double fl_value_get_float(FlValue* self) {
676 g_return_val_if_fail(self != nullptr, 0.0);
677 g_return_val_if_fail(self->type == FL_VALUE_TYPE_FLOAT, 0.0);
678 FlValueDouble* v = reinterpret_cast<FlValueDouble*>(self);
679 return v->value;
680 }
681
682 G_MODULE_EXPORT const gchar* fl_value_get_string(FlValue* self) {
683 g_return_val_if_fail(self != nullptr, nullptr);
684 g_return_val_if_fail(self->type == FL_VALUE_TYPE_STRING, nullptr);
685 FlValueString* v = reinterpret_cast<FlValueString*>(self);
686 return v->value;
687 }
688
689 G_MODULE_EXPORT const uint8_t* fl_value_get_uint8_list(FlValue* self) {
690 g_return_val_if_fail(self != nullptr, nullptr);
691 g_return_val_if_fail(self->type == FL_VALUE_TYPE_UINT8_LIST, nullptr);
692 FlValueUint8List* v = reinterpret_cast<FlValueUint8List*>(self);
693 return v->values;
694 }
695
696 G_MODULE_EXPORT const int32_t* fl_value_get_int32_list(FlValue* self) {
697 g_return_val_if_fail(self != nullptr, nullptr);
698 g_return_val_if_fail(self->type == FL_VALUE_TYPE_INT32_LIST, nullptr);
699 FlValueInt32List* v = reinterpret_cast<FlValueInt32List*>(self);
700 return v->values;
701 }
702
703 G_MODULE_EXPORT const int64_t* fl_value_get_int64_list(FlValue* self) {
704 g_return_val_if_fail(self != nullptr, nullptr);
705 g_return_val_if_fail(self->type == FL_VALUE_TYPE_INT64_LIST, nullptr);
706 FlValueInt64List* v = reinterpret_cast<FlValueInt64List*>(self);
707 return v->values;
708 }
709
710 G_MODULE_EXPORT const float* fl_value_get_float32_list(FlValue* self) {
711 g_return_val_if_fail(self != nullptr, nullptr);
712 g_return_val_if_fail(self->type == FL_VALUE_TYPE_FLOAT32_LIST, nullptr);
713 FlValueFloat32List* v = reinterpret_cast<FlValueFloat32List*>(self);
714 return v->values;
715 }
716
717 G_MODULE_EXPORT const double* fl_value_get_float_list(FlValue* self) {
718 g_return_val_if_fail(self != nullptr, nullptr);
719 g_return_val_if_fail(self->type == FL_VALUE_TYPE_FLOAT_LIST, nullptr);
720 FlValueFloatList* v = reinterpret_cast<FlValueFloatList*>(self);
721 return v->values;
722 }
723
724 G_MODULE_EXPORT size_t fl_value_get_length(FlValue* self) {
725 g_return_val_if_fail(self != nullptr, 0);
726 g_return_val_if_fail(self->type == FL_VALUE_TYPE_UINT8_LIST ||
727 self->type == FL_VALUE_TYPE_INT32_LIST ||
728 self->type == FL_VALUE_TYPE_INT64_LIST ||
729 self->type == FL_VALUE_TYPE_FLOAT32_LIST ||
730 self->type == FL_VALUE_TYPE_FLOAT_LIST ||
731 self->type == FL_VALUE_TYPE_LIST ||
732 self->type == FL_VALUE_TYPE_MAP,
733 0);
734
735 switch (self->type) {
736 case FL_VALUE_TYPE_UINT8_LIST: {
737 FlValueUint8List* v = reinterpret_cast<FlValueUint8List*>(self);
738 return v->values_length;
739 }
740 case FL_VALUE_TYPE_INT32_LIST: {
741 FlValueInt32List* v = reinterpret_cast<FlValueInt32List*>(self);
742 return v->values_length;
743 }
744 case FL_VALUE_TYPE_INT64_LIST: {
745 FlValueInt64List* v = reinterpret_cast<FlValueInt64List*>(self);
746 return v->values_length;
747 }
748 case FL_VALUE_TYPE_FLOAT32_LIST: {
749 FlValueFloat32List* v = reinterpret_cast<FlValueFloat32List*>(self);
750 return v->values_length;
751 }
752 case FL_VALUE_TYPE_FLOAT_LIST: {
753 FlValueFloatList* v = reinterpret_cast<FlValueFloatList*>(self);
754 return v->values_length;
755 }
756 case FL_VALUE_TYPE_LIST: {
757 FlValueList* v = reinterpret_cast<FlValueList*>(self);
758 return v->values->len;
759 }
760 case FL_VALUE_TYPE_MAP: {
761 FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
762 return v->keys->len;
763 }
764 case FL_VALUE_TYPE_NULL:
765 case FL_VALUE_TYPE_BOOL:
766 case FL_VALUE_TYPE_INT:
767 case FL_VALUE_TYPE_FLOAT:
768 case FL_VALUE_TYPE_STRING:
769 case FL_VALUE_TYPE_CUSTOM:
770 return 0;
771 }
772
773 return 0;
774 }
775
776 G_MODULE_EXPORT FlValue* fl_value_get_list_value(FlValue* self, size_t index) {
777 g_return_val_if_fail(self != nullptr, nullptr);
778 g_return_val_if_fail(self->type == FL_VALUE_TYPE_LIST, nullptr);
779
780 FlValueList* v = reinterpret_cast<FlValueList*>(self);
781 return static_cast<FlValue*>(g_ptr_array_index(v->values, index));
782 }
783
784 G_MODULE_EXPORT FlValue* fl_value_get_map_key(FlValue* self, size_t index) {
785 g_return_val_if_fail(self != nullptr, nullptr);
786 g_return_val_if_fail(self->type == FL_VALUE_TYPE_MAP, nullptr);
787
788 FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
789 return static_cast<FlValue*>(g_ptr_array_index(v->keys, index));
790 }
791
792 G_MODULE_EXPORT FlValue* fl_value_get_map_value(FlValue* self, size_t index) {
793 g_return_val_if_fail(self != nullptr, nullptr);
794 g_return_val_if_fail(self->type == FL_VALUE_TYPE_MAP, nullptr);
795
796 FlValueMap* v = reinterpret_cast<FlValueMap*>(self);
797 return static_cast<FlValue*>(g_ptr_array_index(v->values, index));
798 }
799
800 G_MODULE_EXPORT FlValue* fl_value_lookup(FlValue* self, FlValue* key) {
801 g_return_val_if_fail(self != nullptr, nullptr);
802 g_return_val_if_fail(self->type == FL_VALUE_TYPE_MAP, nullptr);
803
804 ssize_t index = fl_value_lookup_index(self, key);
805 if (index < 0) {
806 return nullptr;
807 }
808 return fl_value_get_map_value(self, index);
809 }
810
811 G_MODULE_EXPORT FlValue* fl_value_lookup_string(FlValue* self,
812 const gchar* key) {
813 g_return_val_if_fail(self != nullptr, nullptr);
814 FlValue* string_key = fl_value_new_string(key);
815 FlValue* value = fl_value_lookup(self, string_key);
816 // Explicit unref used because the g_autoptr is triggering a false positive
817 // with clang-tidy.
818 fl_value_unref(string_key);
819 return value;
820 }
821
822 G_MODULE_EXPORT int fl_value_get_custom_type(FlValue* self) {
823 g_return_val_if_fail(self != nullptr, -1);
824 g_return_val_if_fail(self->type == FL_VALUE_TYPE_CUSTOM, -1);
825
826 FlValueCustom* v = reinterpret_cast<FlValueCustom*>(self);
827 return v->type;
828 }
829
830 G_MODULE_EXPORT gconstpointer fl_value_get_custom_value(FlValue* self) {
831 g_return_val_if_fail(self != nullptr, nullptr);
832 g_return_val_if_fail(self->type == FL_VALUE_TYPE_CUSTOM, nullptr);
833
834 FlValueCustom* v = reinterpret_cast<FlValueCustom*>(self);
835 return v->value;
836 }
837
838 G_MODULE_EXPORT GObject* fl_value_get_custom_value_object(FlValue* self) {
839 g_return_val_if_fail(self != nullptr, nullptr);
840 g_return_val_if_fail(self->type == FL_VALUE_TYPE_CUSTOM, nullptr);
841
842 FlValueCustom* v = reinterpret_cast<FlValueCustom*>(self);
843 return G_OBJECT(v->value);
844 }
845
846 G_MODULE_EXPORT gchar* fl_value_to_string(FlValue* value) {
847 GString* buffer = g_string_new("");
848 value_to_string(value, buffer);
849 return g_string_free(buffer, FALSE);
850 }
g_autoptr
g_autoptr(FlEngine) engine
buffer
static const uint8_t buffer[]
Definition: fl_pixel_buffer_texture_test.cc:44
i
int i
Definition: fl_socket_accessible.cc:18
value
uint8_t value
Definition: fl_standard_message_codec.cc:36
type
uint8_t type
Definition: fl_standard_message_codec_test.cc:1117
length
size_t length
Definition: fl_standard_message_codec_test.cc:1115
fl_value_new_int32_list
G_MODULE_EXPORT FlValue * fl_value_new_int32_list(const int32_t *data, size_t data_length)
Definition: fl_value.cc:309
fl_value_get_map_value
G_MODULE_EXPORT FlValue * fl_value_get_map_value(FlValue *self, size_t index)
Definition: fl_value.cc:792
fl_value_set_string
G_MODULE_EXPORT void fl_value_set_string(FlValue *self, const gchar *key, FlValue *value)
Definition: fl_value.cc:639
fl_value_new_float
G_MODULE_EXPORT FlValue * fl_value_new_float(double value)
Definition: fl_value.cc:269
fl_value_new_custom_object
G_MODULE_EXPORT FlValue * fl_value_new_custom_object(int type, GObject *object)
Definition: fl_value.cc:385
fl_value_lookup
G_MODULE_EXPORT FlValue * fl_value_lookup(FlValue *self, FlValue *key)
Definition: fl_value.cc:800
fl_value_new
static FlValue * fl_value_new(FlValueType type, size_t size)
Definition: fl_value.cc:84
fl_value_lookup_string
G_MODULE_EXPORT FlValue * fl_value_lookup_string(FlValue *self, const gchar *key)
Definition: fl_value.cc:811
fl_value_set_string_take
G_MODULE_EXPORT void fl_value_set_string_take(FlValue *self, const gchar *key, FlValue *value)
Definition: fl_value.cc:650
fl_value_new_custom
G_MODULE_EXPORT FlValue * fl_value_new_custom(int type, gconstpointer value, GDestroyNotify destroy_notify)
Definition: fl_value.cc:374
int_to_string
static void int_to_string(int64_t value, GString *buffer)
Definition: fl_value.cc:112
fl_value_get_float_list
G_MODULE_EXPORT const double * fl_value_get_float_list(FlValue *self)
Definition: fl_value.cc:717
fl_value_get_list_value
G_MODULE_EXPORT FlValue * fl_value_get_list_value(FlValue *self, size_t index)
Definition: fl_value.cc:776
value_to_string
static void value_to_string(FlValue *value, GString *buffer)
Definition: fl_value.cc:136
fl_value_new_int64_list
G_MODULE_EXPORT FlValue * fl_value_new_int64_list(const int64_t *data, size_t data_length)
Definition: fl_value.cc:319
fl_value_to_string
G_MODULE_EXPORT gchar * fl_value_to_string(FlValue *value)
Definition: fl_value.cc:846
fl_value_destroy
static void fl_value_destroy(gpointer value)
Definition: fl_value.cc:92
fl_value_get_uint8_list
G_MODULE_EXPORT const uint8_t * fl_value_get_uint8_list(FlValue *self)
Definition: fl_value.cc:689
fl_value_get_int
G_MODULE_EXPORT int64_t fl_value_get_int(FlValue *self)
Definition: fl_value.cc:668
fl_value_new_string
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition: fl_value.cc:276
fl_value_unref
G_MODULE_EXPORT void fl_value_unref(FlValue *self)
Definition: fl_value.cc:400
fl_value_get_type
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition: fl_value.cc:466
fl_value_new_bool
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
Definition: fl_value.cc:255
fl_value_ref
G_MODULE_EXPORT FlValue * fl_value_ref(FlValue *self)
Definition: fl_value.cc:394
fl_value_get_float32_list
G_MODULE_EXPORT const float * fl_value_get_float32_list(FlValue *self)
Definition: fl_value.cc:710
fl_value_append
G_MODULE_EXPORT void fl_value_append(FlValue *self, FlValue *value)
Definition: fl_value.cc:592
fl_value_set_take
G_MODULE_EXPORT void fl_value_set_take(FlValue *self, FlValue *key, FlValue *value)
Definition: fl_value.cc:618
fl_value_get_custom_type
G_MODULE_EXPORT int fl_value_get_custom_type(FlValue *self)
Definition: fl_value.cc:822
fl_value_new_uint8_list_from_bytes
G_MODULE_EXPORT FlValue * fl_value_new_uint8_list_from_bytes(GBytes *data)
Definition: fl_value.cc:302
fl_value_lookup_index
static ssize_t fl_value_lookup_index(FlValue *self, FlValue *key)
Definition: fl_value.cc:99
fl_value_new_list
G_MODULE_EXPORT FlValue * fl_value_new_list()
Definition: fl_value.cc:349
fl_value_append_take
G_MODULE_EXPORT void fl_value_append_take(FlValue *self, FlValue *value)
Definition: fl_value.cc:600
fl_value_new_string_sized
G_MODULE_EXPORT FlValue * fl_value_new_string_sized(const gchar *value, size_t value_length)
Definition: fl_value.cc:283
fl_value_get_custom_value
G_MODULE_EXPORT gconstpointer fl_value_get_custom_value(FlValue *self)
Definition: fl_value.cc:830
fl_value_get_bool
G_MODULE_EXPORT bool fl_value_get_bool(FlValue *self)
Definition: fl_value.cc:661
fl_value_new_float_list
G_MODULE_EXPORT FlValue * fl_value_new_float_list(const double *data, size_t data_length)
Definition: fl_value.cc:339
fl_value_new_null
G_MODULE_EXPORT FlValue * fl_value_new_null()
Definition: fl_value.cc:251
fl_value_equal
G_MODULE_EXPORT bool fl_value_equal(FlValue *a, FlValue *b)
Definition: fl_value.cc:471
float_to_string
static void float_to_string(double value, GString *buffer)
Definition: fl_value.cc:117
fl_value_get_map_key
G_MODULE_EXPORT FlValue * fl_value_get_map_key(FlValue *self, size_t index)
Definition: fl_value.cc:784
fl_value_get_string
G_MODULE_EXPORT const gchar * fl_value_get_string(FlValue *self)
Definition: fl_value.cc:682
fl_value_new_custom_object_take
G_MODULE_EXPORT FlValue * fl_value_new_custom_object_take(int type, GObject *object)
Definition: fl_value.cc:389
fl_value_get_int64_list
G_MODULE_EXPORT const int64_t * fl_value_get_int64_list(FlValue *self)
Definition: fl_value.cc:703
fl_value_new_int
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
Definition: fl_value.cc:262
fl_value_get_custom_value_object
G_MODULE_EXPORT GObject * fl_value_get_custom_value_object(FlValue *self)
Definition: fl_value.cc:838
fl_value_new_list_from_strv
G_MODULE_EXPORT FlValue * fl_value_new_list_from_strv(const gchar *const *str_array)
Definition: fl_value.cc:356
fl_value_new_map
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition: fl_value.cc:366
fl_value_new_float32_list
G_MODULE_EXPORT FlValue * fl_value_new_float32_list(const float *data, size_t data_length)
Definition: fl_value.cc:329
fl_value_new_uint8_list
G_MODULE_EXPORT FlValue * fl_value_new_uint8_list(const uint8_t *data, size_t data_length)
Definition: fl_value.cc:292
fl_value_get_float
G_MODULE_EXPORT double fl_value_get_float(FlValue *self)
Definition: fl_value.cc:675
fl_value_get_int32_list
G_MODULE_EXPORT const int32_t * fl_value_get_int32_list(FlValue *self)
Definition: fl_value.cc:696
fl_value_get_length
G_MODULE_EXPORT size_t fl_value_get_length(FlValue *self)
Definition: fl_value.cc:724
fl_value_set
G_MODULE_EXPORT void fl_value_set(FlValue *self, FlValue *key, FlValue *value)
Definition: fl_value.cc:609
fl_value.h
FlValue
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
FlValueType
FlValueType
Definition: fl_value.h:62
FL_VALUE_TYPE_STRING
@ FL_VALUE_TYPE_STRING
Definition: fl_value.h:68
FL_VALUE_TYPE_NULL
@ FL_VALUE_TYPE_NULL
Definition: fl_value.h:64
FL_VALUE_TYPE_INT
@ FL_VALUE_TYPE_INT
Definition: fl_value.h:66
FL_VALUE_TYPE_BOOL
@ FL_VALUE_TYPE_BOOL
Definition: fl_value.h:65
FL_VALUE_TYPE_FLOAT32_LIST
@ FL_VALUE_TYPE_FLOAT32_LIST
Definition: fl_value.h:75
FL_VALUE_TYPE_INT32_LIST
@ FL_VALUE_TYPE_INT32_LIST
Definition: fl_value.h:70
FL_VALUE_TYPE_UINT8_LIST
@ FL_VALUE_TYPE_UINT8_LIST
Definition: fl_value.h:69
FL_VALUE_TYPE_LIST
@ FL_VALUE_TYPE_LIST
Definition: fl_value.h:73
FL_VALUE_TYPE_MAP
@ FL_VALUE_TYPE_MAP
Definition: fl_value.h:74
FL_VALUE_TYPE_INT64_LIST
@ FL_VALUE_TYPE_INT64_LIST
Definition: fl_value.h:71
FL_VALUE_TYPE_FLOAT_LIST
@ FL_VALUE_TYPE_FLOAT_LIST
Definition: fl_value.h:72
FL_VALUE_TYPE_CUSTOM
@ FL_VALUE_TYPE_CUSTOM
Definition: fl_value.h:76
FL_VALUE_TYPE_FLOAT
@ FL_VALUE_TYPE_FLOAT
Definition: fl_value.h:67
_FlValue
Definition: fl_value.cc:11
_FlValue::type
FlValueType type
Definition: fl_value.cc:12
_FlValue::ref_count
int ref_count
Definition: fl_value.cc:13
FlValueBool
Definition: fl_value.cc:16
FlValueBool::value
bool value
Definition: fl_value.cc:18
FlValueBool::parent
FlValue parent
Definition: fl_value.cc:17
FlValueCustom
Definition: fl_value.cc:77
FlValueCustom::value
gconstpointer value
Definition: fl_value.cc:80
FlValueCustom::parent
FlValue parent
Definition: fl_value.cc:78
FlValueCustom::type
int type
Definition: fl_value.cc:79
FlValueCustom::destroy_notify
GDestroyNotify destroy_notify
Definition: fl_value.cc:81
FlValueDouble
Definition: fl_value.cc:26
FlValueDouble::value
double value
Definition: fl_value.cc:28
FlValueDouble::parent
FlValue parent
Definition: fl_value.cc:27
FlValueFloat32List
Definition: fl_value.cc:54
FlValueFloat32List::values_length
size_t values_length
Definition: fl_value.cc:57
FlValueFloat32List::parent
FlValue parent
Definition: fl_value.cc:55
FlValueFloat32List::values
float * values
Definition: fl_value.cc:56
FlValueFloatList
Definition: fl_value.cc:60
FlValueFloatList::values_length
size_t values_length
Definition: fl_value.cc:63
FlValueFloatList::parent
FlValue parent
Definition: fl_value.cc:61
FlValueFloatList::values
double * values
Definition: fl_value.cc:62
FlValueInt32List
Definition: fl_value.cc:42
FlValueInt32List::parent
FlValue parent
Definition: fl_value.cc:43
FlValueInt32List::values_length
size_t values_length
Definition: fl_value.cc:45
FlValueInt32List::values
int32_t * values
Definition: fl_value.cc:44
FlValueInt64List
Definition: fl_value.cc:48
FlValueInt64List::values
int64_t * values
Definition: fl_value.cc:50
FlValueInt64List::values_length
size_t values_length
Definition: fl_value.cc:51
FlValueInt64List::parent
FlValue parent
Definition: fl_value.cc:49
FlValueInt
Definition: fl_value.cc:21
FlValueInt::parent
FlValue parent
Definition: fl_value.cc:22
FlValueInt::value
int64_t value
Definition: fl_value.cc:23
FlValueList
Definition: fl_value.cc:66
FlValueList::values
GPtrArray * values
Definition: fl_value.cc:68
FlValueList::parent
FlValue parent
Definition: fl_value.cc:67
FlValueMap
Definition: fl_value.cc:71
FlValueMap::values
GPtrArray * values
Definition: fl_value.cc:74
FlValueMap::keys
GPtrArray * keys
Definition: fl_value.cc:73
FlValueMap::parent
FlValue parent
Definition: fl_value.cc:72
FlValueString
Definition: fl_value.cc:31
FlValueString::parent
FlValue parent
Definition: fl_value.cc:32
FlValueString::value
gchar * value
Definition: fl_value.cc:33
FlValueUint8List
Definition: fl_value.cc:36
FlValueUint8List::parent
FlValue parent
Definition: fl_value.cc:37
FlValueUint8List::values_length
size_t values_length
Definition: fl_value.cc:39
FlValueUint8List::values
uint8_t * values
Definition: fl_value.cc:38