4 * Linux Trace Toolkit Control Library
6 * Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com>
8 * SPDX-License-Identifier: LGPL-2.1-only
16 #include <common/error.h>
17 #include <common/macros.h>
18 #include <lttng/event-field-value-internal.h>
21 struct lttng_event_field_value
*create_empty_field_val(
22 enum lttng_event_field_value_type type
, size_t size
)
24 struct lttng_event_field_value
*field_val
;
26 field_val
= zmalloc(size
);
31 field_val
->type
= type
;
38 struct lttng_event_field_value
*lttng_event_field_value_uint_create(
41 struct lttng_event_field_value_uint
*field_val
;
43 field_val
= container_of(create_empty_field_val(
44 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
,
46 struct lttng_event_field_value_uint
, parent
);
55 lttng_event_field_value_destroy(&field_val
->parent
);
58 return &field_val
->parent
;
62 struct lttng_event_field_value
*lttng_event_field_value_int_create(
65 struct lttng_event_field_value_int
*field_val
;
67 field_val
= container_of(create_empty_field_val(
68 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
,
70 struct lttng_event_field_value_int
, parent
);
79 lttng_event_field_value_destroy(&field_val
->parent
);
82 return &field_val
->parent
;
86 struct lttng_event_field_value_enum
*create_enum_field_val(
87 enum lttng_event_field_value_type type
, size_t size
)
89 struct lttng_event_field_value_enum
*field_val
;
91 field_val
= container_of(create_empty_field_val(type
, size
),
92 struct lttng_event_field_value_enum
, parent
);
97 lttng_dynamic_pointer_array_init(&field_val
->labels
, free
);
101 lttng_event_field_value_destroy(&field_val
->parent
);
108 struct lttng_event_field_value
*lttng_event_field_value_enum_uint_create(
111 struct lttng_event_field_value_enum_uint
*field_val
;
113 field_val
= container_of(create_enum_field_val(
114 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
,
116 struct lttng_event_field_value_enum_uint
, parent
);
121 field_val
->val
= val
;
125 lttng_event_field_value_destroy(&field_val
->parent
.parent
);
128 return &field_val
->parent
.parent
;
132 struct lttng_event_field_value
*lttng_event_field_value_enum_int_create(
135 struct lttng_event_field_value_enum_int
*field_val
;
137 field_val
= container_of(create_enum_field_val(
138 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
,
140 struct lttng_event_field_value_enum_int
, parent
);
145 field_val
->val
= val
;
149 lttng_event_field_value_destroy(&field_val
->parent
.parent
);
152 return &field_val
->parent
.parent
;
156 struct lttng_event_field_value
*lttng_event_field_value_real_create(double val
)
158 struct lttng_event_field_value_real
*field_val
= container_of(
159 create_empty_field_val(
160 LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
,
162 struct lttng_event_field_value_real
, parent
);
168 field_val
->val
= val
;
172 lttng_event_field_value_destroy(&field_val
->parent
);
175 return &field_val
->parent
;
179 struct lttng_event_field_value
*lttng_event_field_value_string_create_with_size(
180 const char *val
, size_t size
)
182 struct lttng_event_field_value_string
*field_val
= container_of(
183 create_empty_field_val(
184 LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
,
186 struct lttng_event_field_value_string
, parent
);
193 field_val
->val
= strndup(val
, size
);
194 if (!field_val
->val
) {
201 lttng_event_field_value_destroy(&field_val
->parent
);
204 return &field_val
->parent
;
208 struct lttng_event_field_value
*lttng_event_field_value_string_create(
212 return lttng_event_field_value_string_create_with_size(val
,
217 void destroy_field_val(void *field_val
)
219 lttng_event_field_value_destroy(field_val
);
223 struct lttng_event_field_value
*lttng_event_field_value_array_create(void)
225 struct lttng_event_field_value_array
*field_val
= container_of(
226 create_empty_field_val(
227 LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
,
229 struct lttng_event_field_value_array
, parent
);
235 lttng_dynamic_pointer_array_init(&field_val
->elems
, destroy_field_val
);
239 lttng_event_field_value_destroy(&field_val
->parent
);
242 return &field_val
->parent
;
246 void lttng_event_field_value_destroy(struct lttng_event_field_value
*field_val
)
252 switch (field_val
->type
) {
253 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
254 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
256 struct lttng_event_field_value_enum
*enum_field_val
=
257 container_of(field_val
,
258 struct lttng_event_field_value_enum
, parent
);
260 lttng_dynamic_pointer_array_reset(&enum_field_val
->labels
);
263 case LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
:
265 struct lttng_event_field_value_string
*str_field_val
=
266 container_of(field_val
,
267 struct lttng_event_field_value_string
, parent
);
269 free(str_field_val
->val
);
272 case LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
:
274 struct lttng_event_field_value_array
*array_field_expr
=
275 container_of(field_val
,
276 struct lttng_event_field_value_array
,
279 lttng_dynamic_pointer_array_reset(&array_field_expr
->elems
);
293 int lttng_event_field_value_enum_append_label_with_size(
294 struct lttng_event_field_value
*field_val
,
295 const char *label
, size_t size
)
300 LTTNG_ASSERT(field_val
);
302 new_label
= strndup(label
, size
);
308 ret
= lttng_dynamic_pointer_array_add_pointer(
309 &container_of(field_val
,
310 struct lttng_event_field_value_enum
, parent
)->labels
,
322 int lttng_event_field_value_enum_append_label(
323 struct lttng_event_field_value
*field_val
,
327 return lttng_event_field_value_enum_append_label_with_size(field_val
,
328 label
, strlen(label
));
332 int lttng_event_field_value_array_append(
333 struct lttng_event_field_value
*array_field_val
,
334 struct lttng_event_field_value
*field_val
)
336 LTTNG_ASSERT(array_field_val
);
337 LTTNG_ASSERT(field_val
);
338 return lttng_dynamic_pointer_array_add_pointer(
339 &container_of(array_field_val
,
340 struct lttng_event_field_value_array
, parent
)->elems
,
345 int lttng_event_field_value_array_append_unavailable(
346 struct lttng_event_field_value
*array_field_val
)
348 LTTNG_ASSERT(array_field_val
);
349 return lttng_dynamic_pointer_array_add_pointer(
350 &container_of(array_field_val
,
351 struct lttng_event_field_value_array
, parent
)->elems
,
355 enum lttng_event_field_value_type
lttng_event_field_value_get_type(
356 const struct lttng_event_field_value
*field_val
)
358 enum lttng_event_field_value_type type
;
361 type
= LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID
;
365 type
= field_val
->type
;
371 enum lttng_event_field_value_status
372 lttng_event_field_value_unsigned_int_get_value(
373 const struct lttng_event_field_value
*field_val
, uint64_t *val
)
375 enum lttng_event_field_value_status status
;
377 if (!field_val
|| !val
) {
378 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
382 switch (field_val
->type
) {
383 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
:
384 *val
= container_of(field_val
,
385 const struct lttng_event_field_value_uint
,
388 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
390 const struct lttng_event_field_value_enum
*field_val_enum
= container_of(
392 const struct lttng_event_field_value_enum
,
394 const struct lttng_event_field_value_enum_uint
395 *field_val_enum_uint
= container_of(
397 const struct lttng_event_field_value_enum_uint
,
399 *val
= field_val_enum_uint
->val
;
403 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
407 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
413 enum lttng_event_field_value_status
414 lttng_event_field_value_signed_int_get_value(
415 const struct lttng_event_field_value
*field_val
, int64_t *val
)
417 enum lttng_event_field_value_status status
;
419 if (!field_val
|| !val
) {
420 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
424 switch (field_val
->type
) {
425 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
:
426 *val
= container_of(field_val
,
427 const struct lttng_event_field_value_int
,
430 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
432 const struct lttng_event_field_value_enum
*field_val_enum
= container_of(
434 const struct lttng_event_field_value_enum
,
436 const struct lttng_event_field_value_enum_int
437 *field_val_enum_uint
= container_of(
439 const struct lttng_event_field_value_enum_int
,
441 *val
= field_val_enum_uint
->val
;
445 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
449 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
455 enum lttng_event_field_value_status
456 lttng_event_field_value_real_get_value(
457 const struct lttng_event_field_value
*field_val
, double *val
)
459 enum lttng_event_field_value_status status
;
461 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
||
463 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
467 *val
= container_of(field_val
,
468 const struct lttng_event_field_value_real
, parent
)->val
;
469 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
476 bool is_enum_field_val(const struct lttng_event_field_value
*field_val
)
478 return field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
||
479 field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
;
482 enum lttng_event_field_value_status
483 lttng_event_field_value_enum_get_label_count(
484 const struct lttng_event_field_value
*field_val
,
487 enum lttng_event_field_value_status status
;
489 if (!field_val
|| !is_enum_field_val(field_val
) || !count
) {
490 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
494 *count
= (unsigned int) lttng_dynamic_pointer_array_get_count(
495 &container_of(field_val
,
496 const struct lttng_event_field_value_enum
,
498 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
504 const char *lttng_event_field_value_enum_get_label_at_index(
505 const struct lttng_event_field_value
*field_val
,
509 const struct lttng_event_field_value_enum
*enum_field_val
;
511 if (!field_val
|| !is_enum_field_val(field_val
)) {
516 enum_field_val
= container_of(field_val
,
517 const struct lttng_event_field_value_enum
, parent
);
519 if (index
>= lttng_dynamic_pointer_array_get_count(&enum_field_val
->labels
)) {
524 ret
= lttng_dynamic_pointer_array_get_pointer(&enum_field_val
->labels
,
531 enum lttng_event_field_value_status
lttng_event_field_value_string_get_value(
532 const struct lttng_event_field_value
*field_val
,
535 enum lttng_event_field_value_status status
;
537 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
) {
538 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
542 *value
= container_of(field_val
,
543 const struct lttng_event_field_value_string
, parent
)->val
;
544 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
550 enum lttng_event_field_value_status
lttng_event_field_value_array_get_length(
551 const struct lttng_event_field_value
*field_val
,
552 unsigned int *length
)
554 enum lttng_event_field_value_status status
;
556 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
||
558 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
562 *length
= (unsigned int) lttng_dynamic_pointer_array_get_count(
563 &container_of(field_val
,
564 const struct lttng_event_field_value_array
,
566 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
572 enum lttng_event_field_value_status
573 lttng_event_field_value_array_get_element_at_index(
574 const struct lttng_event_field_value
*field_val
,
576 const struct lttng_event_field_value
**elem_field_val
)
578 enum lttng_event_field_value_status status
;
579 const struct lttng_event_field_value_array
*array_field_val
;
581 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
||
583 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
587 array_field_val
= container_of(field_val
,
588 const struct lttng_event_field_value_array
, parent
);
590 if (index
>= lttng_dynamic_pointer_array_get_count(&array_field_val
->elems
)) {
591 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
595 *elem_field_val
= lttng_dynamic_pointer_array_get_pointer(
596 &array_field_val
->elems
, index
);
597 if (*elem_field_val
) {
598 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
600 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE
;