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 
6 
7 #include <gmodule.h>
8 
9 #include <cstring>
10 
11 struct _FlValue {
13  int ref_count;
14 };
15 
16 typedef struct {
18  bool value;
19 } FlValueBool;
20 
21 typedef struct {
23  int64_t value;
24 } FlValueInt;
25 
26 typedef struct {
28  double value;
30 
31 typedef struct {
33  gchar* value;
35 
36 typedef struct {
38  uint8_t* values;
39  size_t values_length;
41 
42 typedef struct {
44  int32_t* values;
45  size_t values_length;
47 
48 typedef struct {
50  int64_t* values;
51  size_t values_length;
53 
54 typedef struct {
56  float* values;
57  size_t values_length;
59 
60 typedef struct {
62  double* values;
63  size_t values_length;
65 
66 typedef struct {
68  GPtrArray* values;
69 } FlValueList;
70 
71 typedef struct {
73  GPtrArray* keys;
74  GPtrArray* values;
75 } FlValueMap;
76 
77 typedef struct {
79  int type;
80  gconstpointer value;
81  GDestroyNotify destroy_notify;
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:
150  return;
151  case FL_VALUE_TYPE_FLOAT:
153  return;
154  case FL_VALUE_TYPE_STRING: {
155  g_string_append(buffer, fl_value_get_string(value));
156  return;
157  }
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  }
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  }
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  }
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  }
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  }
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  }
236  g_string_append(buffer, ": ");
238  }
239  g_string_append(buffer, "}");
240  return;
241  }
243  g_string_append_printf(buffer, "(custom %d)",
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*>(
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*>(
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*>(
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*>(
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*>(
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*>(
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*>(
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*>(
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*>(
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*>(
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*>(
352  self->values = g_ptr_array_new_with_free_func(fl_value_destroy);
353  return reinterpret_cast<FlValue*>(self);
354 }
355 
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++) {
362  }
363  return fl_value_ref(value);
364 }
365 
366 G_MODULE_EXPORT FlValue* fl_value_new_map() {
367  FlValueMap* self = reinterpret_cast<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*>(
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 
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  }
415  FlValueUint8List* v = reinterpret_cast<FlValueUint8List*>(self);
416  g_free(v->values);
417  break;
418  }
420  FlValueInt32List* v = reinterpret_cast<FlValueInt32List*>(self);
421  g_free(v->values);
422  break;
423  }
425  FlValueInt64List* v = reinterpret_cast<FlValueInt64List*>(self);
426  g_free(v->values);
427  break;
428  }
430  FlValueFloat32List* v = reinterpret_cast<FlValueFloat32List*>(self);
431  g_free(v->values);
432  break;
433  }
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((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  }
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  }
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  }
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  }
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  }
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: {
560  return false;
561  }
562  for (size_t i = 0; i < fl_value_get_length(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: {
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  }
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 
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 
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 
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 
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) {
737  FlValueUint8List* v = reinterpret_cast<FlValueUint8List*>(self);
738  return v->values_length;
739  }
741  FlValueInt32List* v = reinterpret_cast<FlValueInt32List*>(self);
742  return v->values_length;
743  }
745  FlValueInt64List* v = reinterpret_cast<FlValueInt64List*>(self);
746  return v->values_length;
747  }
749  FlValueFloat32List* v = reinterpret_cast<FlValueFloat32List*>(self);
750  return v->values_length;
751  }
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:
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("");
849  return g_string_free(buffer, FALSE);
850 }
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:696
FL_VALUE_TYPE_UINT8_LIST
@ FL_VALUE_TYPE_UINT8_LIST
Definition: fl_value.h:70
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_TYPE_MAP
@ FL_VALUE_TYPE_MAP
Definition: fl_value.h:75
int_to_string
static void int_to_string(int64_t value, GString *buffer)
Definition: fl_value.cc:112
fl_value_new
static FlValue * fl_value_new(FlValueType type, size_t size)
Definition: fl_value.cc:84
fl_value_get_custom_value_object
G_MODULE_EXPORT GObject * fl_value_get_custom_value_object(FlValue *self)
Definition: fl_value.cc:838
FlValueInt::parent
FlValue parent
Definition: fl_value.cc:22
type
uint8_t type
Definition: fl_standard_message_codec_test.cc:1115
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:650
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:92
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:349
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:329
fl_value_get_float_list
const G_MODULE_EXPORT double * fl_value_get_float_list(FlValue *self)
Definition: fl_value.cc:717
fl_value_new_bool
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
Definition: fl_value.cc:255
FlValue
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
FlValueUint8List::parent
FlValue parent
Definition: fl_value.cc:37
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_set_take
G_MODULE_EXPORT void fl_value_set_take(FlValue *self, FlValue *key, FlValue *value)
Definition: fl_value.cc:618
FlValueInt
Definition: fl_value.cc:21
fl_value_new_custom
G_MODULE_EXPORT FlValue * fl_value_new_custom(int type, gconstpointer value, GDestroyNotify destroy_notify)
Definition: fl_value.cc:374
fl_value_new_null
G_MODULE_EXPORT FlValue * fl_value_new_null()
Definition: fl_value.cc:251
FL_VALUE_TYPE_LIST
@ FL_VALUE_TYPE_LIST
Definition: fl_value.h:74
FlValueType
FlValueType
Definition: fl_value.h:62
fl_value_get_bool
G_MODULE_EXPORT bool fl_value_get_bool(FlValue *self)
Definition: fl_value.cc:661
fl_value_get_uint8_list
const G_MODULE_EXPORT uint8_t * fl_value_get_uint8_list(FlValue *self)
Definition: fl_value.cc:689
FlValueCustom::destroy_notify
GDestroyNotify destroy_notify
Definition: fl_value.cc:81
fl_value_set
G_MODULE_EXPORT void fl_value_set(FlValue *self, FlValue *key, FlValue *value)
Definition: fl_value.cc:609
fl_value_lookup_string
G_MODULE_EXPORT FlValue * fl_value_lookup_string(FlValue *self, const gchar *key)
Definition: fl_value.cc:811
fl_value_new_int
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
Definition: fl_value.cc:262
fl_value_get_string
const G_MODULE_EXPORT gchar * fl_value_get_string(FlValue *self)
Definition: fl_value.cc:682
FlValueCustom::value
gconstpointer value
Definition: fl_value.cc:80
FlValueFloatList
Definition: fl_value.cc:60
_FlValue::type
FlValueType type
Definition: fl_value.cc:12
FlValueCustom
Definition: fl_value.cc:77
fl_value_get_float32_list
const G_MODULE_EXPORT float * fl_value_get_float32_list(FlValue *self)
Definition: fl_value.cc:710
FL_VALUE_TYPE_NULL
@ FL_VALUE_TYPE_NULL
Definition: fl_value.h:65
value_to_string
static void value_to_string(FlValue *value, GString *buffer)
Definition: fl_value.cc:136
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:668
fl_value_unref
G_MODULE_EXPORT void fl_value_unref(FlValue *self)
Definition: fl_value.cc:400
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:394
FlValueInt32List::values
int32_t * values
Definition: fl_value.cc:44
FL_VALUE_TYPE_CUSTOM
@ FL_VALUE_TYPE_CUSTOM
Definition: fl_value.h:77
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:366
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:466
fl_value_get_list_value
G_MODULE_EXPORT FlValue * fl_value_get_list_value(FlValue *self, size_t index)
Definition: fl_value.cc:776
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_TYPE_FLOAT32_LIST
@ FL_VALUE_TYPE_FLOAT32_LIST
Definition: fl_value.h:76
FlValueCustom::parent
FlValue parent
Definition: fl_value.cc:78
FL_VALUE_TYPE_STRING
@ FL_VALUE_TYPE_STRING
Definition: fl_value.h:69
FlValueBool::value
bool value
Definition: fl_value.cc:18
FlValueDouble::parent
FlValue parent
Definition: fl_value.cc:27
fl_value_get_custom_value
G_MODULE_EXPORT gconstpointer fl_value_get_custom_value(FlValue *self)
Definition: fl_value.cc:830
FlValueCustom::type
int type
Definition: fl_value.cc:79
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
float_to_string
static void float_to_string(double value, GString *buffer)
Definition: fl_value.cc:117
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
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:675
fl_value_append_take
G_MODULE_EXPORT void fl_value_append_take(FlValue *self, FlValue *value)
Definition: fl_value.cc:600
fl_value_get_length
G_MODULE_EXPORT size_t fl_value_get_length(FlValue *self)
Definition: fl_value.cc:724
FL_VALUE_TYPE_INT64_LIST
@ FL_VALUE_TYPE_INT64_LIST
Definition: fl_value.h:72
fl_value_equal
G_MODULE_EXPORT bool fl_value_equal(FlValue *a, FlValue *b)
Definition: fl_value.cc:471
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_TYPE_INT
@ FL_VALUE_TYPE_INT
Definition: fl_value.h:67
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
FlValueString::parent
FlValue parent
Definition: fl_value.cc:32
FlValueList::values
GPtrArray * values
Definition: fl_value.cc:68
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
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:356
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_get_custom_type
G_MODULE_EXPORT int fl_value_get_custom_type(FlValue *self)
Definition: fl_value.cc:822
FL_VALUE_TYPE_FLOAT_LIST
@ FL_VALUE_TYPE_FLOAT_LIST
Definition: fl_value.h:73
_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:292
fl_value_append
G_MODULE_EXPORT void fl_value_append(FlValue *self, FlValue *value)
Definition: fl_value.cc:592
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:68
FlValueDouble
Definition: fl_value.cc:26
FL_VALUE_TYPE_INT32_LIST
@ FL_VALUE_TYPE_INT32_LIST
Definition: fl_value.h:71
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:269
_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:99
FlValueUint8List
Definition: fl_value.cc:36
fl_value_lookup
G_MODULE_EXPORT FlValue * fl_value_lookup(FlValue *self, FlValue *key)
Definition: fl_value.cc:800
fl_value_get_map_key
G_MODULE_EXPORT FlValue * fl_value_get_map_key(FlValue *self, size_t index)
Definition: fl_value.cc:784
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:703
FlValueFloatList::parent
FlValue parent
Definition: fl_value.cc:61
FL_VALUE_TYPE_BOOL
@ FL_VALUE_TYPE_BOOL
Definition: fl_value.h:66
value
uint8_t value
Definition: fl_standard_message_codec.cc:36
length
size_t length
Definition: fl_standard_message_codec_test.cc:1113
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_to_string
G_MODULE_EXPORT gchar * fl_value_to_string(FlValue *value)
Definition: fl_value.cc:846
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:276