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