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 const struct lttng_event_field_value_enum
*field_val_enum
= container_of(
393 const struct lttng_event_field_value_enum
,
395 const struct lttng_event_field_value_enum_uint
396 *field_val_enum_uint
= container_of(
398 const struct lttng_event_field_value_enum_uint
,
400 *val
= field_val_enum_uint
->val
;
404 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
408 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
414 enum lttng_event_field_value_status
415 lttng_event_field_value_signed_int_get_value(
416 const struct lttng_event_field_value
*field_val
, int64_t *val
)
418 enum lttng_event_field_value_status status
;
420 if (!field_val
|| !val
) {
421 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
425 switch (field_val
->type
) {
426 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
:
427 *val
= container_of(field_val
,
428 const struct lttng_event_field_value_int
,
431 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
433 const struct lttng_event_field_value_enum
*field_val_enum
= container_of(
435 const struct lttng_event_field_value_enum
,
437 const struct lttng_event_field_value_enum_int
438 *field_val_enum_uint
= container_of(
440 const struct lttng_event_field_value_enum_int
,
442 *val
= field_val_enum_uint
->val
;
446 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
450 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
456 enum lttng_event_field_value_status
457 lttng_event_field_value_real_get_value(
458 const struct lttng_event_field_value
*field_val
, double *val
)
460 enum lttng_event_field_value_status status
;
462 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
||
464 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
468 *val
= container_of(field_val
,
469 const struct lttng_event_field_value_real
, parent
)->val
;
470 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
477 bool is_enum_field_val(const struct lttng_event_field_value
*field_val
)
479 return field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
||
480 field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
;
483 enum lttng_event_field_value_status
484 lttng_event_field_value_enum_get_label_count(
485 const struct lttng_event_field_value
*field_val
,
488 enum lttng_event_field_value_status status
;
490 if (!field_val
|| !is_enum_field_val(field_val
) || !count
) {
491 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
495 *count
= (unsigned int) lttng_dynamic_pointer_array_get_count(
496 &container_of(field_val
,
497 const struct lttng_event_field_value_enum
,
499 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
505 const char *lttng_event_field_value_enum_get_label_at_index(
506 const struct lttng_event_field_value
*field_val
,
510 const struct lttng_event_field_value_enum
*enum_field_val
;
512 if (!field_val
|| !is_enum_field_val(field_val
)) {
517 enum_field_val
= container_of(field_val
,
518 const struct lttng_event_field_value_enum
, parent
);
520 if (index
>= lttng_dynamic_pointer_array_get_count(&enum_field_val
->labels
)) {
525 ret
= lttng_dynamic_pointer_array_get_pointer(&enum_field_val
->labels
,
532 enum lttng_event_field_value_status
lttng_event_field_value_string_get_value(
533 const struct lttng_event_field_value
*field_val
,
536 enum lttng_event_field_value_status status
;
538 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
) {
539 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
543 *value
= container_of(field_val
,
544 const struct lttng_event_field_value_string
, parent
)->val
;
545 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
551 enum lttng_event_field_value_status
lttng_event_field_value_array_get_length(
552 const struct lttng_event_field_value
*field_val
,
553 unsigned int *length
)
555 enum lttng_event_field_value_status status
;
557 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
||
559 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
563 *length
= (unsigned int) lttng_dynamic_pointer_array_get_count(
564 &container_of(field_val
,
565 const struct lttng_event_field_value_array
,
567 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
573 enum lttng_event_field_value_status
574 lttng_event_field_value_array_get_element_at_index(
575 const struct lttng_event_field_value
*field_val
,
577 const struct lttng_event_field_value
**elem_field_val
)
579 enum lttng_event_field_value_status status
;
580 const struct lttng_event_field_value_array
*array_field_val
;
582 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
||
584 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
588 array_field_val
= container_of(field_val
,
589 const struct lttng_event_field_value_array
, parent
);
591 if (index
>= lttng_dynamic_pointer_array_get_count(&array_field_val
->elems
)) {
592 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
596 *elem_field_val
= lttng_dynamic_pointer_array_get_pointer(
597 &array_field_val
->elems
, index
);
598 if (*elem_field_val
) {
599 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
601 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE
;