Flutter Engine
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 {
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 
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  }
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  }
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  }
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  }
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  }
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*>(
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*>(
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*>(
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*>(
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*>(
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*>(
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*>(
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*>(
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*>(
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*>(
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*>(
341  self->values = g_ptr_array_new_with_free_func(fl_value_destroy);
342  return reinterpret_cast<FlValue*>(self);
343 }
344 
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++) {
351  }
352  return fl_value_ref(value);
353 }
354 
355 G_MODULE_EXPORT FlValue* fl_value_new_map() {
356  FlValueMap* self = reinterpret_cast<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  }
384  FlValueUint8List* v = reinterpret_cast<FlValueUint8List*>(self);
385  g_free(v->values);
386  break;
387  }
389  FlValueInt32List* v = reinterpret_cast<FlValueInt32List*>(self);
390  g_free(v->values);
391  break;
392  }
394  FlValueInt64List* v = reinterpret_cast<FlValueInt64List*>(self);
395  g_free(v->values);
396  break;
397  }
399  FlValueFloat32List* v = reinterpret_cast<FlValueFloat32List*>(self);
400  g_free(v->values);
401  break;
402  }
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  }
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  }
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  }
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  }
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  }
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: {
522  return false;
523  }
524  for (size_t i = 0; i < fl_value_get_length(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: {
534  return false;
535  }
536  for (size_t i = 0; i < fl_value_get_length(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 
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) {
697  FlValueUint8List* v = reinterpret_cast<FlValueUint8List*>(self);
698  return v->values_length;
699  }
701  FlValueInt32List* v = reinterpret_cast<FlValueInt32List*>(self);
702  return v->values_length;
703  }
705  FlValueInt64List* v = reinterpret_cast<FlValueInt64List*>(self);
706  return v->values_length;
707  }
709  FlValueFloat32List* v = reinterpret_cast<FlValueFloat32List*>(self);
710  return v->values_length;
711  }
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:
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 }
FlValue parent
Definition: fl_value.cc:72
G_MODULE_EXPORT FlValue * fl_value_new_list()
Definition: fl_value.cc:338
FlValue parent
Definition: fl_value.cc:67
G_MODULE_EXPORT FlValue * fl_value_new_float(double value)
Definition: fl_value.cc:258
int ref_count
Definition: fl_value.cc:13
G_MODULE_EXPORT const float * fl_value_get_float32_list(FlValue *self)
Definition: fl_value.cc:670
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition: fl_value.cc:428
G_MODULE_EXPORT FlValue * fl_value_new_uint8_list(const uint8_t *data, size_t data_length)
Definition: fl_value.cc:281
G_MODULE_EXPORT FlValue * fl_value_new_int64_list(const int64_t *data, size_t data_length)
Definition: fl_value.cc:308
FlValue parent
Definition: fl_value.cc:49
G_MODULE_EXPORT void fl_value_unref(FlValue *self)
Definition: fl_value.cc:369
G_MODULE_EXPORT void fl_value_set(FlValue *self, FlValue *key, FlValue *value)
Definition: fl_value.cc:569
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:40
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition: fl_value.cc:355
FlValue parent
Definition: fl_value.cc:22
double * values
Definition: fl_value.cc:62
static ssize_t fl_value_lookup_index(FlValue *self, FlValue *key)
Definition: fl_value.cc:92
size_t values_length
Definition: fl_value.cc:51
bool value
Definition: fl_value.cc:18
static void int_to_string(int64_t value, GString *buffer)
Definition: fl_value.cc:105
G_MODULE_EXPORT FlValue * fl_value_new_int32_list(const int32_t *data, size_t data_length)
Definition: fl_value.cc:298
size_t values_length
Definition: fl_value.cc:57
GPtrArray * keys
Definition: fl_value.cc:73
G_MODULE_EXPORT const double * fl_value_get_float_list(FlValue *self)
Definition: fl_value.cc:677
int64_t * values
Definition: fl_value.cc:50
G_MODULE_EXPORT int64_t fl_value_get_int(FlValue *self)
Definition: fl_value.cc:628
GPtrArray * values
Definition: fl_value.cc:68
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
FlValueType
Definition: fl_value.h:59
FlValue parent
Definition: fl_value.cc:37
G_MODULE_EXPORT FlValue * fl_value_new_list_from_strv(const gchar *const *str_array)
Definition: fl_value.cc:345
G_MODULE_EXPORT const int64_t * fl_value_get_int64_list(FlValue *self)
Definition: fl_value.cc:663
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
Definition: fl_value.cc:244
G_MODULE_EXPORT const uint8_t * fl_value_get_uint8_list(FlValue *self)
Definition: fl_value.cc:649
G_MODULE_EXPORT bool fl_value_equal(FlValue *a, FlValue *b)
Definition: fl_value.cc:433
static void float_to_string(double value, GString *buffer)
Definition: fl_value.cc:110
G_MODULE_EXPORT void fl_value_append(FlValue *self, FlValue *value)
Definition: fl_value.cc:552
uint8_t * values
Definition: fl_value.cc:38
static void fl_value_destroy(gpointer value)
Definition: fl_value.cc:85
G_MODULE_EXPORT double fl_value_get_float(FlValue *self)
Definition: fl_value.cc:635
G_MODULE_EXPORT void fl_value_append_take(FlValue *self, FlValue *value)
Definition: fl_value.cc:560
uint8_t value
G_MODULE_EXPORT void fl_value_set_take(FlValue *self, FlValue *key, FlValue *value)
Definition: fl_value.cc:578
FlValueType type
Definition: fl_value.cc:12
int64_t value
Definition: fl_value.cc:23
FlValue parent
Definition: fl_value.cc:17
FlValue parent
Definition: fl_value.cc:32
G_MODULE_EXPORT FlValue * fl_value_lookup_string(FlValue *self, const gchar *key)
Definition: fl_value.cc:770
G_MODULE_EXPORT FlValue * fl_value_new_float32_list(const float *data, size_t data_length)
Definition: fl_value.cc:318
gchar * value
Definition: fl_value.cc:33
GPtrArray * values
Definition: fl_value.cc:74
G_MODULE_EXPORT FlValue * fl_value_get_list_value(FlValue *self, size_t index)
Definition: fl_value.cc:735
static FlValue * fl_value_new(FlValueType type, size_t size)
Definition: fl_value.cc:77
size_t length
FlValue parent
Definition: fl_value.cc:27
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
Definition: fl_value.cc:251
G_MODULE_EXPORT FlValue * fl_value_get_map_value(FlValue *self, size_t index)
Definition: fl_value.cc:751
G_MODULE_EXPORT gchar * fl_value_to_string(FlValue *value)
Definition: fl_value.cc:781
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition: fl_value.cc:265
G_MODULE_EXPORT FlValue * fl_value_ref(FlValue *self)
Definition: fl_value.cc:363
G_MODULE_EXPORT FlValue * fl_value_lookup(FlValue *self, FlValue *key)
Definition: fl_value.cc:759
G_MODULE_EXPORT FlValue * fl_value_get_map_key(FlValue *self, size_t index)
Definition: fl_value.cc:743
G_MODULE_EXPORT const int32_t * fl_value_get_int32_list(FlValue *self)
Definition: fl_value.cc:656
G_MODULE_EXPORT const gchar * fl_value_get_string(FlValue *self)
Definition: fl_value.cc:642
size_t values_length
Definition: fl_value.cc:45
int32_t * values
Definition: fl_value.cc:44
static const uint8_t buffer[]
size_t values_length
Definition: fl_value.cc:63
double value
Definition: fl_value.cc:28
G_MODULE_EXPORT void fl_value_set_string(FlValue *self, const gchar *key, FlValue *value)
Definition: fl_value.cc:599
G_MODULE_EXPORT void fl_value_set_string_take(FlValue *self, const gchar *key, FlValue *value)
Definition: fl_value.cc:610
G_MODULE_EXPORT FlValue * fl_value_new_float_list(const double *data, size_t data_length)
Definition: fl_value.cc:328
return FALSE
FlValue parent
Definition: fl_value.cc:61
G_MODULE_EXPORT FlValue * fl_value_new_string_sized(const gchar *value, size_t value_length)
Definition: fl_value.cc:272
G_MODULE_EXPORT size_t fl_value_get_length(FlValue *self)
Definition: fl_value.cc:684
G_MODULE_EXPORT FlValue * fl_value_new_uint8_list_from_bytes(GBytes *data)
Definition: fl_value.cc:291
G_MODULE_EXPORT FlValue * fl_value_new_null()
Definition: fl_value.cc:240
static void value_to_string(FlValue *value, GString *buffer)
Definition: fl_value.cc:129
FlValue parent
Definition: fl_value.cc:43
G_MODULE_EXPORT bool fl_value_get_bool(FlValue *self)
Definition: fl_value.cc:621
size_t values_length
Definition: fl_value.cc:39