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
= container_of(create_empty_field_val(
43 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
,
45 struct lttng_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
= container_of(create_empty_field_val(
66 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
,
68 struct lttng_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
= container_of(create_empty_field_val(type
, size
),
90 struct lttng_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
= container_of(create_enum_field_val(
111 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
,
113 struct lttng_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
= container_of(create_enum_field_val(
134 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
,
136 struct lttng_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
= container_of(
154 create_empty_field_val(
155 LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
,
157 struct lttng_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
= container_of(
177 create_empty_field_val(
178 LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
,
180 struct lttng_event_field_value_string
, parent
);
187 field_val
->val
= strndup(val
, size
);
188 if (!field_val
->val
) {
195 lttng_event_field_value_destroy(&field_val
->parent
);
198 return &field_val
->parent
;
201 struct lttng_event_field_value
*lttng_event_field_value_string_create(
205 return lttng_event_field_value_string_create_with_size(val
,
210 void destroy_field_val(void *field_val
)
212 lttng_event_field_value_destroy((lttng_event_field_value
*) field_val
);
215 struct lttng_event_field_value
*lttng_event_field_value_array_create(void)
217 struct lttng_event_field_value_array
*field_val
= container_of(
218 create_empty_field_val(
219 LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
,
221 struct lttng_event_field_value_array
, parent
);
227 lttng_dynamic_pointer_array_init(&field_val
->elems
, destroy_field_val
);
231 lttng_event_field_value_destroy(&field_val
->parent
);
234 return &field_val
->parent
;
237 void lttng_event_field_value_destroy(struct lttng_event_field_value
*field_val
)
243 switch (field_val
->type
) {
244 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
245 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
247 struct lttng_event_field_value_enum
*enum_field_val
=
248 container_of(field_val
,
249 struct lttng_event_field_value_enum
, parent
);
251 lttng_dynamic_pointer_array_reset(&enum_field_val
->labels
);
254 case LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
:
256 struct lttng_event_field_value_string
*str_field_val
=
257 container_of(field_val
,
258 struct lttng_event_field_value_string
, parent
);
260 free(str_field_val
->val
);
263 case LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
:
265 struct lttng_event_field_value_array
*array_field_expr
=
266 container_of(field_val
,
267 struct lttng_event_field_value_array
,
270 lttng_dynamic_pointer_array_reset(&array_field_expr
->elems
);
283 int lttng_event_field_value_enum_append_label_with_size(
284 struct lttng_event_field_value
*field_val
,
285 const char *label
, size_t size
)
290 LTTNG_ASSERT(field_val
);
292 new_label
= strndup(label
, size
);
298 ret
= lttng_dynamic_pointer_array_add_pointer(
299 &container_of(field_val
,
300 struct lttng_event_field_value_enum
, parent
)->labels
,
311 int lttng_event_field_value_enum_append_label(
312 struct lttng_event_field_value
*field_val
,
316 return lttng_event_field_value_enum_append_label_with_size(field_val
,
317 label
, strlen(label
));
320 int lttng_event_field_value_array_append(
321 struct lttng_event_field_value
*array_field_val
,
322 struct lttng_event_field_value
*field_val
)
324 LTTNG_ASSERT(array_field_val
);
325 LTTNG_ASSERT(field_val
);
326 return lttng_dynamic_pointer_array_add_pointer(
327 &container_of(array_field_val
,
328 struct lttng_event_field_value_array
, parent
)->elems
,
332 int lttng_event_field_value_array_append_unavailable(
333 struct lttng_event_field_value
*array_field_val
)
335 LTTNG_ASSERT(array_field_val
);
336 return lttng_dynamic_pointer_array_add_pointer(
337 &container_of(array_field_val
,
338 struct lttng_event_field_value_array
, parent
)->elems
,
342 enum lttng_event_field_value_type
lttng_event_field_value_get_type(
343 const struct lttng_event_field_value
*field_val
)
345 enum lttng_event_field_value_type type
;
348 type
= LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID
;
352 type
= field_val
->type
;
358 enum lttng_event_field_value_status
359 lttng_event_field_value_unsigned_int_get_value(
360 const struct lttng_event_field_value
*field_val
, uint64_t *val
)
362 enum lttng_event_field_value_status status
;
364 if (!field_val
|| !val
) {
365 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
369 switch (field_val
->type
) {
370 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
:
371 *val
= container_of(field_val
,
372 const struct lttng_event_field_value_uint
,
375 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
377 const struct lttng_event_field_value_enum
*field_val_enum
= container_of(
379 const struct lttng_event_field_value_enum
,
381 const struct lttng_event_field_value_enum_uint
382 *field_val_enum_uint
= container_of(
384 const struct lttng_event_field_value_enum_uint
,
386 *val
= field_val_enum_uint
->val
;
390 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
394 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
400 enum lttng_event_field_value_status
401 lttng_event_field_value_signed_int_get_value(
402 const struct lttng_event_field_value
*field_val
, int64_t *val
)
404 enum lttng_event_field_value_status status
;
406 if (!field_val
|| !val
) {
407 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
411 switch (field_val
->type
) {
412 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
:
413 *val
= container_of(field_val
,
414 const struct lttng_event_field_value_int
,
417 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
419 const struct lttng_event_field_value_enum
*field_val_enum
= container_of(
421 const struct lttng_event_field_value_enum
,
423 const struct lttng_event_field_value_enum_int
424 *field_val_enum_uint
= container_of(
426 const struct lttng_event_field_value_enum_int
,
428 *val
= field_val_enum_uint
->val
;
432 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
436 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
442 enum lttng_event_field_value_status
443 lttng_event_field_value_real_get_value(
444 const struct lttng_event_field_value
*field_val
, double *val
)
446 enum lttng_event_field_value_status status
;
448 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
||
450 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
454 *val
= container_of(field_val
,
455 const struct lttng_event_field_value_real
, parent
)->val
;
456 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
463 bool is_enum_field_val(const struct lttng_event_field_value
*field_val
)
465 return field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
||
466 field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
;
469 enum lttng_event_field_value_status
470 lttng_event_field_value_enum_get_label_count(
471 const struct lttng_event_field_value
*field_val
,
474 enum lttng_event_field_value_status status
;
476 if (!field_val
|| !is_enum_field_val(field_val
) || !count
) {
477 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
481 *count
= (unsigned int) lttng_dynamic_pointer_array_get_count(
482 &container_of(field_val
,
483 const struct lttng_event_field_value_enum
,
485 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
491 const char *lttng_event_field_value_enum_get_label_at_index(
492 const struct lttng_event_field_value
*field_val
,
496 const struct lttng_event_field_value_enum
*enum_field_val
;
498 if (!field_val
|| !is_enum_field_val(field_val
)) {
503 enum_field_val
= container_of(field_val
,
504 const struct lttng_event_field_value_enum
, parent
);
506 if (index
>= lttng_dynamic_pointer_array_get_count(&enum_field_val
->labels
)) {
511 ret
= (const char *) lttng_dynamic_pointer_array_get_pointer(&enum_field_val
->labels
,
518 enum lttng_event_field_value_status
lttng_event_field_value_string_get_value(
519 const struct lttng_event_field_value
*field_val
,
522 enum lttng_event_field_value_status status
;
524 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
) {
525 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
529 *value
= container_of(field_val
,
530 const struct lttng_event_field_value_string
, parent
)->val
;
531 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
537 enum lttng_event_field_value_status
lttng_event_field_value_array_get_length(
538 const struct lttng_event_field_value
*field_val
,
539 unsigned int *length
)
541 enum lttng_event_field_value_status status
;
543 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
||
545 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
549 *length
= (unsigned int) lttng_dynamic_pointer_array_get_count(
550 &container_of(field_val
,
551 const struct lttng_event_field_value_array
,
553 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
559 enum lttng_event_field_value_status
560 lttng_event_field_value_array_get_element_at_index(
561 const struct lttng_event_field_value
*field_val
,
563 const struct lttng_event_field_value
**elem_field_val
)
565 enum lttng_event_field_value_status status
;
566 const struct lttng_event_field_value_array
*array_field_val
;
568 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
||
570 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
574 array_field_val
= container_of(field_val
,
575 const struct lttng_event_field_value_array
, parent
);
577 if (index
>= lttng_dynamic_pointer_array_get_count(&array_field_val
->elems
)) {
578 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
582 *elem_field_val
= (lttng_event_field_value
*) lttng_dynamic_pointer_array_get_pointer(
583 &array_field_val
->elems
, index
);
584 if (*elem_field_val
) {
585 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
587 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE
;