4 * Linux Trace Toolkit Control Library
6 * Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com>
8 * SPDX-License-Identifier: LGPL-2.1-only
17 #include <common/error.h>
18 #include <common/macros.h>
19 #include <lttng/event-field-value-internal.h>
22 struct lttng_event_field_value
*create_empty_field_val(
23 enum lttng_event_field_value_type type
, size_t size
)
25 struct lttng_event_field_value
*field_val
;
27 field_val
= zmalloc(size
);
32 field_val
->type
= type
;
39 struct lttng_event_field_value
*lttng_event_field_value_uint_create(
42 struct lttng_event_field_value_uint
*field_val
;
44 field_val
= container_of(create_empty_field_val(
45 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
,
47 struct lttng_event_field_value_uint
, parent
);
56 lttng_event_field_value_destroy(&field_val
->parent
);
59 return &field_val
->parent
;
63 struct lttng_event_field_value
*lttng_event_field_value_int_create(
66 struct lttng_event_field_value_int
*field_val
;
68 field_val
= container_of(create_empty_field_val(
69 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
,
71 struct lttng_event_field_value_int
, parent
);
80 lttng_event_field_value_destroy(&field_val
->parent
);
83 return &field_val
->parent
;
87 struct lttng_event_field_value_enum
*create_enum_field_val(
88 enum lttng_event_field_value_type type
, size_t size
)
90 struct lttng_event_field_value_enum
*field_val
;
92 field_val
= container_of(create_empty_field_val(type
, size
),
93 struct lttng_event_field_value_enum
, parent
);
98 lttng_dynamic_pointer_array_init(&field_val
->labels
, free
);
102 lttng_event_field_value_destroy(&field_val
->parent
);
109 struct lttng_event_field_value
*lttng_event_field_value_enum_uint_create(
112 struct lttng_event_field_value_enum_uint
*field_val
;
114 field_val
= container_of(create_enum_field_val(
115 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
,
117 struct lttng_event_field_value_enum_uint
, parent
);
122 field_val
->val
= val
;
126 lttng_event_field_value_destroy(&field_val
->parent
.parent
);
129 return &field_val
->parent
.parent
;
133 struct lttng_event_field_value
*lttng_event_field_value_enum_int_create(
136 struct lttng_event_field_value_enum_int
*field_val
;
138 field_val
= container_of(create_enum_field_val(
139 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
,
141 struct lttng_event_field_value_enum_int
, parent
);
146 field_val
->val
= val
;
150 lttng_event_field_value_destroy(&field_val
->parent
.parent
);
153 return &field_val
->parent
.parent
;
157 struct lttng_event_field_value
*lttng_event_field_value_real_create(double val
)
159 struct lttng_event_field_value_real
*field_val
= container_of(
160 create_empty_field_val(
161 LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
,
163 struct lttng_event_field_value_real
, parent
);
169 field_val
->val
= val
;
173 lttng_event_field_value_destroy(&field_val
->parent
);
176 return &field_val
->parent
;
180 struct lttng_event_field_value
*lttng_event_field_value_string_create_with_size(
181 const char *val
, size_t size
)
183 struct lttng_event_field_value_string
*field_val
= container_of(
184 create_empty_field_val(
185 LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
,
187 struct lttng_event_field_value_string
, parent
);
194 field_val
->val
= strndup(val
, size
);
195 if (!field_val
->val
) {
202 lttng_event_field_value_destroy(&field_val
->parent
);
205 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(field_val
);
224 struct lttng_event_field_value
*lttng_event_field_value_array_create(void)
226 struct lttng_event_field_value_array
*field_val
= container_of(
227 create_empty_field_val(
228 LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
,
230 struct lttng_event_field_value_array
, parent
);
236 lttng_dynamic_pointer_array_init(&field_val
->elems
, destroy_field_val
);
240 lttng_event_field_value_destroy(&field_val
->parent
);
243 return &field_val
->parent
;
247 void lttng_event_field_value_destroy(struct lttng_event_field_value
*field_val
)
253 switch (field_val
->type
) {
254 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
255 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
257 struct lttng_event_field_value_enum
*enum_field_val
=
258 container_of(field_val
,
259 struct lttng_event_field_value_enum
, parent
);
261 lttng_dynamic_pointer_array_reset(&enum_field_val
->labels
);
264 case LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
:
266 struct lttng_event_field_value_string
*str_field_val
=
267 container_of(field_val
,
268 struct lttng_event_field_value_string
, parent
);
270 free(str_field_val
->val
);
273 case LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
:
275 struct lttng_event_field_value_array
*array_field_expr
=
276 container_of(field_val
,
277 struct lttng_event_field_value_array
,
280 lttng_dynamic_pointer_array_reset(&array_field_expr
->elems
);
294 int lttng_event_field_value_enum_append_label_with_size(
295 struct lttng_event_field_value
*field_val
,
296 const char *label
, size_t size
)
303 new_label
= strndup(label
, size
);
309 ret
= lttng_dynamic_pointer_array_add_pointer(
310 &container_of(field_val
,
311 struct lttng_event_field_value_enum
, parent
)->labels
,
323 int lttng_event_field_value_enum_append_label(
324 struct lttng_event_field_value
*field_val
,
328 return lttng_event_field_value_enum_append_label_with_size(field_val
,
329 label
, strlen(label
));
333 int lttng_event_field_value_array_append(
334 struct lttng_event_field_value
*array_field_val
,
335 struct lttng_event_field_value
*field_val
)
337 assert(array_field_val
);
339 return lttng_dynamic_pointer_array_add_pointer(
340 &container_of(array_field_val
,
341 struct lttng_event_field_value_array
, parent
)->elems
,
346 int lttng_event_field_value_array_append_unavailable(
347 struct lttng_event_field_value
*array_field_val
)
349 assert(array_field_val
);
350 return lttng_dynamic_pointer_array_add_pointer(
351 &container_of(array_field_val
,
352 struct lttng_event_field_value_array
, parent
)->elems
,
356 enum lttng_event_field_value_type
lttng_event_field_value_get_type(
357 const struct lttng_event_field_value
*field_val
)
359 enum lttng_event_field_value_type type
;
362 type
= LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID
;
366 type
= field_val
->type
;
372 enum lttng_event_field_value_status
373 lttng_event_field_value_unsigned_int_get_value(
374 const struct lttng_event_field_value
*field_val
, uint64_t *val
)
376 enum lttng_event_field_value_status status
;
378 if (!field_val
|| !val
) {
379 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
383 switch (field_val
->type
) {
384 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
:
385 *val
= container_of(field_val
,
386 const struct lttng_event_field_value_uint
,
389 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
391 container_of(field_val
,
392 const struct lttng_event_field_value_enum
,
394 const struct lttng_event_field_value_enum_uint
,
398 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
402 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
408 enum lttng_event_field_value_status
409 lttng_event_field_value_signed_int_get_value(
410 const struct lttng_event_field_value
*field_val
, int64_t *val
)
412 enum lttng_event_field_value_status status
;
414 if (!field_val
|| !val
) {
415 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
419 switch (field_val
->type
) {
420 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
:
421 *val
= container_of(field_val
,
422 const struct lttng_event_field_value_int
,
425 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
427 container_of(field_val
,
428 const struct lttng_event_field_value_enum
,
430 const struct lttng_event_field_value_enum_int
,
434 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
438 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
444 enum lttng_event_field_value_status
445 lttng_event_field_value_real_get_value(
446 const struct lttng_event_field_value
*field_val
, double *val
)
448 enum lttng_event_field_value_status status
;
450 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
||
452 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
456 *val
= container_of(field_val
,
457 const struct lttng_event_field_value_real
, parent
)->val
;
458 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
465 bool is_enum_field_val(const struct lttng_event_field_value
*field_val
)
467 return field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
||
468 field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
;
471 enum lttng_event_field_value_status
472 lttng_event_field_value_enum_get_label_count(
473 const struct lttng_event_field_value
*field_val
,
476 enum lttng_event_field_value_status status
;
478 if (!field_val
|| !is_enum_field_val(field_val
) || !count
) {
479 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
483 *count
= (unsigned int) lttng_dynamic_pointer_array_get_count(
484 &container_of(field_val
,
485 const struct lttng_event_field_value_enum
,
487 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
493 const char *lttng_event_field_value_enum_get_label_at_index(
494 const struct lttng_event_field_value
*field_val
,
498 const struct lttng_event_field_value_enum
*enum_field_val
;
500 if (!field_val
|| !is_enum_field_val(field_val
)) {
505 enum_field_val
= container_of(field_val
,
506 const struct lttng_event_field_value_enum
, parent
);
508 if (index
>= lttng_dynamic_pointer_array_get_count(&enum_field_val
->labels
)) {
513 ret
= lttng_dynamic_pointer_array_get_pointer(&enum_field_val
->labels
,
520 const char *lttng_event_field_value_string_get_value(
521 const struct lttng_event_field_value
*field_val
)
525 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
) {
530 ret
= container_of(field_val
,
531 const struct lttng_event_field_value_string
, parent
)->val
;
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_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
;