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.hpp>
17 #include <common/macros.hpp>
18 #include <lttng/event-field-value-internal.hpp>
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
<lttng_event_field_value
>(size
);
31 field_val
->type
= type
;
37 struct lttng_event_field_value
*lttng_event_field_value_uint_create(
40 struct lttng_event_field_value_uint
*field_val
;
42 field_val
= lttng::utils::container_of(create_empty_field_val(
43 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
,
45 <tng_event_field_value_uint::parent
);
54 lttng_event_field_value_destroy(&field_val
->parent
);
57 return &field_val
->parent
;
60 struct lttng_event_field_value
*lttng_event_field_value_int_create(
63 struct lttng_event_field_value_int
*field_val
;
65 field_val
= lttng::utils::container_of(create_empty_field_val(
66 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
,
68 <tng_event_field_value_int::parent
);
77 lttng_event_field_value_destroy(&field_val
->parent
);
80 return &field_val
->parent
;
84 struct lttng_event_field_value_enum
*create_enum_field_val(
85 enum lttng_event_field_value_type type
, size_t size
)
87 struct lttng_event_field_value_enum
*field_val
;
89 field_val
= lttng::utils::container_of(create_empty_field_val(type
, size
),
90 <tng_event_field_value_enum::parent
);
95 lttng_dynamic_pointer_array_init(&field_val
->labels
, free
);
99 lttng_event_field_value_destroy(&field_val
->parent
);
105 struct lttng_event_field_value
*lttng_event_field_value_enum_uint_create(
108 struct lttng_event_field_value_enum_uint
*field_val
;
110 field_val
= lttng::utils::container_of(create_enum_field_val(
111 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
,
113 <tng_event_field_value_enum_uint::parent
);
118 field_val
->val
= val
;
122 lttng_event_field_value_destroy(&field_val
->parent
.parent
);
125 return &field_val
->parent
.parent
;
128 struct lttng_event_field_value
*lttng_event_field_value_enum_int_create(
131 struct lttng_event_field_value_enum_int
*field_val
;
133 field_val
= lttng::utils::container_of(create_enum_field_val(
134 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
,
136 <tng_event_field_value_enum_int::parent
);
141 field_val
->val
= val
;
145 lttng_event_field_value_destroy(&field_val
->parent
.parent
);
148 return &field_val
->parent
.parent
;
151 struct lttng_event_field_value
*lttng_event_field_value_real_create(double val
)
153 struct lttng_event_field_value_real
*field_val
= lttng::utils::container_of(
154 create_empty_field_val(
155 LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
,
157 <tng_event_field_value_real::parent
);
163 field_val
->val
= val
;
167 lttng_event_field_value_destroy(&field_val
->parent
);
170 return &field_val
->parent
;
173 struct lttng_event_field_value
*lttng_event_field_value_string_create_with_size(
174 const char *val
, size_t size
)
176 struct lttng_event_field_value_string
*field_val
= lttng::utils::container_of(
177 create_empty_field_val(
178 LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
,
180 <tng_event_field_value_string::parent
);
188 field_val
->val
= strndup(val
, size
);
191 * User code do not expect a NULL string pointer. Populate with
192 * an empty string when length is 0.
194 field_val
->val
= strdup("");
196 if (!field_val
->val
) {
203 lttng_event_field_value_destroy(&field_val
->parent
);
206 return &field_val
->parent
;
209 struct lttng_event_field_value
*lttng_event_field_value_string_create(
213 return lttng_event_field_value_string_create_with_size(val
,
218 void destroy_field_val(void *field_val
)
220 lttng_event_field_value_destroy((lttng_event_field_value
*) field_val
);
223 struct lttng_event_field_value
*lttng_event_field_value_array_create(void)
225 struct lttng_event_field_value_array
*field_val
= lttng::utils::container_of(
226 create_empty_field_val(
227 LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
,
229 <tng_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
;
245 void lttng_event_field_value_destroy(struct lttng_event_field_value
*field_val
)
251 switch (field_val
->type
) {
252 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
253 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
255 struct lttng_event_field_value_enum
*enum_field_val
=
256 lttng::utils::container_of(field_val
,
257 <tng_event_field_value_enum::parent
);
259 lttng_dynamic_pointer_array_reset(&enum_field_val
->labels
);
262 case LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
:
264 struct lttng_event_field_value_string
*str_field_val
=
265 lttng::utils::container_of(field_val
,
266 <tng_event_field_value_string::parent
);
268 free(str_field_val
->val
);
271 case LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
:
273 struct lttng_event_field_value_array
*array_field_expr
=
274 lttng::utils::container_of(field_val
,
275 <tng_event_field_value_array::parent
);
277 lttng_dynamic_pointer_array_reset(&array_field_expr
->elems
);
290 int lttng_event_field_value_enum_append_label_with_size(
291 struct lttng_event_field_value
*field_val
,
292 const char *label
, size_t size
)
297 LTTNG_ASSERT(field_val
);
299 new_label
= strndup(label
, size
);
305 ret
= lttng_dynamic_pointer_array_add_pointer(
306 <tng::utils::container_of(field_val
,
307 <tng_event_field_value_enum::parent
)->labels
,
318 int lttng_event_field_value_enum_append_label(
319 struct lttng_event_field_value
*field_val
,
323 return lttng_event_field_value_enum_append_label_with_size(field_val
,
324 label
, strlen(label
));
327 int lttng_event_field_value_array_append(
328 struct lttng_event_field_value
*array_field_val
,
329 struct lttng_event_field_value
*field_val
)
331 LTTNG_ASSERT(array_field_val
);
332 LTTNG_ASSERT(field_val
);
333 return lttng_dynamic_pointer_array_add_pointer(
334 <tng::utils::container_of(array_field_val
,
335 <tng_event_field_value_array::parent
)->elems
,
339 int lttng_event_field_value_array_append_unavailable(
340 struct lttng_event_field_value
*array_field_val
)
342 LTTNG_ASSERT(array_field_val
);
343 return lttng_dynamic_pointer_array_add_pointer(
344 <tng::utils::container_of(array_field_val
,
345 <tng_event_field_value_array::parent
)->elems
,
349 enum lttng_event_field_value_type
lttng_event_field_value_get_type(
350 const struct lttng_event_field_value
*field_val
)
352 enum lttng_event_field_value_type type
;
355 type
= LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID
;
359 type
= field_val
->type
;
365 enum lttng_event_field_value_status
366 lttng_event_field_value_unsigned_int_get_value(
367 const struct lttng_event_field_value
*field_val
, uint64_t *val
)
369 enum lttng_event_field_value_status status
;
371 if (!field_val
|| !val
) {
372 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
376 switch (field_val
->type
) {
377 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
:
378 *val
= lttng::utils::container_of(field_val
,
379 <tng_event_field_value_uint::parent
)->val
;
381 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
383 const struct lttng_event_field_value_enum
*field_val_enum
=
384 lttng::utils::container_of(
385 field_val
, <tng_event_field_value_enum::parent
);
386 const struct lttng_event_field_value_enum_uint
*field_val_enum_uint
=
387 lttng::utils::container_of(field_val_enum
,
388 <tng_event_field_value_enum_uint::parent
);
389 *val
= field_val_enum_uint
->val
;
393 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
397 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
403 enum lttng_event_field_value_status
404 lttng_event_field_value_signed_int_get_value(
405 const struct lttng_event_field_value
*field_val
, int64_t *val
)
407 enum lttng_event_field_value_status status
;
409 if (!field_val
|| !val
) {
410 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
414 switch (field_val
->type
) {
415 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
:
416 *val
= lttng::utils::container_of(field_val
,
417 <tng_event_field_value_int::parent
)->val
;
419 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
421 const struct lttng_event_field_value_enum
*field_val_enum
= lttng::utils::container_of(
423 <tng_event_field_value_enum::parent
);
424 const struct lttng_event_field_value_enum_int
*field_val_enum_uint
=
425 lttng::utils::container_of(field_val_enum
,
426 <tng_event_field_value_enum_int::parent
);
427 *val
= field_val_enum_uint
->val
;
431 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
435 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
441 enum lttng_event_field_value_status
442 lttng_event_field_value_real_get_value(
443 const struct lttng_event_field_value
*field_val
, double *val
)
445 enum lttng_event_field_value_status status
;
447 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
||
449 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
453 *val
= lttng::utils::container_of(field_val
,
454 <tng_event_field_value_real::parent
)->val
;
455 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
462 bool is_enum_field_val(const struct lttng_event_field_value
*field_val
)
464 return field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
||
465 field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
;
468 enum lttng_event_field_value_status
469 lttng_event_field_value_enum_get_label_count(
470 const struct lttng_event_field_value
*field_val
,
473 enum lttng_event_field_value_status status
;
475 if (!field_val
|| !is_enum_field_val(field_val
) || !count
) {
476 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
480 *count
= (unsigned int) lttng_dynamic_pointer_array_get_count(
481 <tng::utils::container_of(field_val
,
482 <tng_event_field_value_enum::parent
)->labels
);
483 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
489 const char *lttng_event_field_value_enum_get_label_at_index(
490 const struct lttng_event_field_value
*field_val
,
494 const struct lttng_event_field_value_enum
*enum_field_val
;
496 if (!field_val
|| !is_enum_field_val(field_val
)) {
501 enum_field_val
= lttng::utils::container_of(field_val
,
502 <tng_event_field_value_enum::parent
);
504 if (index
>= lttng_dynamic_pointer_array_get_count(&enum_field_val
->labels
)) {
509 ret
= (const char *) lttng_dynamic_pointer_array_get_pointer(&enum_field_val
->labels
,
516 enum lttng_event_field_value_status
lttng_event_field_value_string_get_value(
517 const struct lttng_event_field_value
*field_val
,
520 enum lttng_event_field_value_status status
;
522 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
) {
523 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
527 *value
= lttng::utils::container_of(field_val
,
528 <tng_event_field_value_string::parent
)->val
;
529 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
535 enum lttng_event_field_value_status
lttng_event_field_value_array_get_length(
536 const struct lttng_event_field_value
*field_val
,
537 unsigned int *length
)
539 enum lttng_event_field_value_status status
;
541 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
||
543 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
547 *length
= (unsigned int) lttng_dynamic_pointer_array_get_count(
548 <tng::utils::container_of(field_val
,
549 <tng_event_field_value_array::parent
)->elems
);
550 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
556 enum lttng_event_field_value_status
557 lttng_event_field_value_array_get_element_at_index(
558 const struct lttng_event_field_value
*field_val
,
560 const struct lttng_event_field_value
**elem_field_val
)
562 enum lttng_event_field_value_status status
;
563 const struct lttng_event_field_value_array
*array_field_val
;
565 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
||
567 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
571 array_field_val
= lttng::utils::container_of(
572 field_val
, <tng_event_field_value_array::parent
);
574 if (index
>= lttng_dynamic_pointer_array_get_count(&array_field_val
->elems
)) {
575 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
579 *elem_field_val
= (lttng_event_field_value
*) lttng_dynamic_pointer_array_get_pointer(
580 &array_field_val
->elems
, index
);
581 if (*elem_field_val
) {
582 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
584 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE
;