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