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
);
195 field_val
->val
= strndup(val
, size
);
198 * User code do not expect a NULL string pointer. Populate with
199 * an empty string when length is 0.
201 field_val
->val
= strdup("");
203 if (!field_val
->val
) {
210 lttng_event_field_value_destroy(&field_val
->parent
);
213 return &field_val
->parent
;
217 struct lttng_event_field_value
*lttng_event_field_value_string_create(
221 return lttng_event_field_value_string_create_with_size(val
,
226 void destroy_field_val(void *field_val
)
228 lttng_event_field_value_destroy(field_val
);
232 struct lttng_event_field_value
*lttng_event_field_value_array_create(void)
234 struct lttng_event_field_value_array
*field_val
= container_of(
235 create_empty_field_val(
236 LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
,
238 struct lttng_event_field_value_array
, parent
);
244 lttng_dynamic_pointer_array_init(&field_val
->elems
, destroy_field_val
);
248 lttng_event_field_value_destroy(&field_val
->parent
);
251 return &field_val
->parent
;
255 void lttng_event_field_value_destroy(struct lttng_event_field_value
*field_val
)
261 switch (field_val
->type
) {
262 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
263 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
265 struct lttng_event_field_value_enum
*enum_field_val
=
266 container_of(field_val
,
267 struct lttng_event_field_value_enum
, parent
);
269 lttng_dynamic_pointer_array_reset(&enum_field_val
->labels
);
272 case LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
:
274 struct lttng_event_field_value_string
*str_field_val
=
275 container_of(field_val
,
276 struct lttng_event_field_value_string
, parent
);
278 free(str_field_val
->val
);
281 case LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
:
283 struct lttng_event_field_value_array
*array_field_expr
=
284 container_of(field_val
,
285 struct lttng_event_field_value_array
,
288 lttng_dynamic_pointer_array_reset(&array_field_expr
->elems
);
302 int lttng_event_field_value_enum_append_label_with_size(
303 struct lttng_event_field_value
*field_val
,
304 const char *label
, size_t size
)
311 new_label
= strndup(label
, size
);
317 ret
= lttng_dynamic_pointer_array_add_pointer(
318 &container_of(field_val
,
319 struct lttng_event_field_value_enum
, parent
)->labels
,
331 int lttng_event_field_value_enum_append_label(
332 struct lttng_event_field_value
*field_val
,
336 return lttng_event_field_value_enum_append_label_with_size(field_val
,
337 label
, strlen(label
));
341 int lttng_event_field_value_array_append(
342 struct lttng_event_field_value
*array_field_val
,
343 struct lttng_event_field_value
*field_val
)
345 assert(array_field_val
);
347 return lttng_dynamic_pointer_array_add_pointer(
348 &container_of(array_field_val
,
349 struct lttng_event_field_value_array
, parent
)->elems
,
354 int lttng_event_field_value_array_append_unavailable(
355 struct lttng_event_field_value
*array_field_val
)
357 assert(array_field_val
);
358 return lttng_dynamic_pointer_array_add_pointer(
359 &container_of(array_field_val
,
360 struct lttng_event_field_value_array
, parent
)->elems
,
364 enum lttng_event_field_value_type
lttng_event_field_value_get_type(
365 const struct lttng_event_field_value
*field_val
)
367 enum lttng_event_field_value_type type
;
370 type
= LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID
;
374 type
= field_val
->type
;
380 enum lttng_event_field_value_status
381 lttng_event_field_value_unsigned_int_get_value(
382 const struct lttng_event_field_value
*field_val
, uint64_t *val
)
384 enum lttng_event_field_value_status status
;
386 if (!field_val
|| !val
) {
387 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
391 switch (field_val
->type
) {
392 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
:
393 *val
= container_of(field_val
,
394 const struct lttng_event_field_value_uint
,
397 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
399 const struct lttng_event_field_value_enum
*field_val_enum
= container_of(
401 const struct lttng_event_field_value_enum
,
403 const struct lttng_event_field_value_enum_uint
404 *field_val_enum_uint
= container_of(
406 const struct lttng_event_field_value_enum_uint
,
408 *val
= field_val_enum_uint
->val
;
412 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
416 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
422 enum lttng_event_field_value_status
423 lttng_event_field_value_signed_int_get_value(
424 const struct lttng_event_field_value
*field_val
, int64_t *val
)
426 enum lttng_event_field_value_status status
;
428 if (!field_val
|| !val
) {
429 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
433 switch (field_val
->type
) {
434 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
:
435 *val
= container_of(field_val
,
436 const struct lttng_event_field_value_int
,
439 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
441 const struct lttng_event_field_value_enum
*field_val_enum
= container_of(
443 const struct lttng_event_field_value_enum
,
445 const struct lttng_event_field_value_enum_int
446 *field_val_enum_uint
= container_of(
448 const struct lttng_event_field_value_enum_int
,
450 *val
= field_val_enum_uint
->val
;
454 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
458 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
464 enum lttng_event_field_value_status
465 lttng_event_field_value_real_get_value(
466 const struct lttng_event_field_value
*field_val
, double *val
)
468 enum lttng_event_field_value_status status
;
470 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
||
472 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
476 *val
= container_of(field_val
,
477 const struct lttng_event_field_value_real
, parent
)->val
;
478 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
485 bool is_enum_field_val(const struct lttng_event_field_value
*field_val
)
487 return field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
||
488 field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
;
491 enum lttng_event_field_value_status
492 lttng_event_field_value_enum_get_label_count(
493 const struct lttng_event_field_value
*field_val
,
496 enum lttng_event_field_value_status status
;
498 if (!field_val
|| !is_enum_field_val(field_val
) || !count
) {
499 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
503 *count
= (unsigned int) lttng_dynamic_pointer_array_get_count(
504 &container_of(field_val
,
505 const struct lttng_event_field_value_enum
,
507 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
513 const char *lttng_event_field_value_enum_get_label_at_index(
514 const struct lttng_event_field_value
*field_val
,
518 const struct lttng_event_field_value_enum
*enum_field_val
;
520 if (!field_val
|| !is_enum_field_val(field_val
)) {
525 enum_field_val
= container_of(field_val
,
526 const struct lttng_event_field_value_enum
, parent
);
528 if (index
>= lttng_dynamic_pointer_array_get_count(&enum_field_val
->labels
)) {
533 ret
= lttng_dynamic_pointer_array_get_pointer(&enum_field_val
->labels
,
540 enum lttng_event_field_value_status
lttng_event_field_value_string_get_value(
541 const struct lttng_event_field_value
*field_val
,
544 enum lttng_event_field_value_status status
;
546 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
) {
547 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
551 *value
= container_of(field_val
,
552 const struct lttng_event_field_value_string
, parent
)->val
;
553 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
559 enum lttng_event_field_value_status
lttng_event_field_value_array_get_length(
560 const struct lttng_event_field_value
*field_val
,
561 unsigned int *length
)
563 enum lttng_event_field_value_status status
;
565 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
||
567 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
571 *length
= (unsigned int) lttng_dynamic_pointer_array_get_count(
572 &container_of(field_val
,
573 const struct lttng_event_field_value_array
,
575 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
581 enum lttng_event_field_value_status
582 lttng_event_field_value_array_get_element_at_index(
583 const struct lttng_event_field_value
*field_val
,
585 const struct lttng_event_field_value
**elem_field_val
)
587 enum lttng_event_field_value_status status
;
588 const struct lttng_event_field_value_array
*array_field_val
;
590 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
||
592 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
596 array_field_val
= container_of(field_val
,
597 const struct lttng_event_field_value_array
, parent
);
599 if (index
>= lttng_dynamic_pointer_array_get_count(&array_field_val
->elems
)) {
600 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
604 *elem_field_val
= lttng_dynamic_pointer_array_get_pointer(
605 &array_field_val
->elems
, index
);
606 if (*elem_field_val
) {
607 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
609 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE
;