4 * Linux Trace Toolkit Control Library
6 * Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com>
8 * SPDX-License-Identifier: LGPL-2.1-only
13 #include <common/error.hpp>
14 #include <common/macros.hpp>
16 #include <lttng/event-field-value-internal.hpp>
21 static struct lttng_event_field_value
*
22 create_empty_field_val(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(uint64_t val
)
39 struct lttng_event_field_value_uint
*field_val
;
41 field_val
= lttng::utils::container_of(
42 create_empty_field_val(LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
,
44 <tng_event_field_value_uint::parent
);
53 lttng_event_field_value_destroy(&field_val
->parent
);
56 return &field_val
->parent
;
59 struct lttng_event_field_value
*lttng_event_field_value_int_create(int64_t val
)
61 struct lttng_event_field_value_int
*field_val
;
63 field_val
= lttng::utils::container_of(
64 create_empty_field_val(LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT
, sizeof(*field_val
)),
65 <tng_event_field_value_int::parent
);
74 lttng_event_field_value_destroy(&field_val
->parent
);
77 return &field_val
->parent
;
80 static struct lttng_event_field_value_enum
*
81 create_enum_field_val(enum lttng_event_field_value_type type
, size_t size
)
83 struct lttng_event_field_value_enum
*field_val
;
85 field_val
= lttng::utils::container_of(create_empty_field_val(type
, size
),
86 <tng_event_field_value_enum::parent
);
91 lttng_dynamic_pointer_array_init(&field_val
->labels
, free
);
95 lttng_event_field_value_destroy(&field_val
->parent
);
101 struct lttng_event_field_value
*lttng_event_field_value_enum_uint_create(uint64_t val
)
103 struct lttng_event_field_value_enum_uint
*field_val
;
105 field_val
= lttng::utils::container_of(
106 create_enum_field_val(LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
,
108 <tng_event_field_value_enum_uint::parent
);
113 field_val
->val
= val
;
117 lttng_event_field_value_destroy(&field_val
->parent
.parent
);
120 return &field_val
->parent
.parent
;
123 struct lttng_event_field_value
*lttng_event_field_value_enum_int_create(int64_t val
)
125 struct lttng_event_field_value_enum_int
*field_val
;
127 field_val
= lttng::utils::container_of(
128 create_enum_field_val(LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
, sizeof(*field_val
)),
129 <tng_event_field_value_enum_int::parent
);
134 field_val
->val
= val
;
138 lttng_event_field_value_destroy(&field_val
->parent
.parent
);
141 return &field_val
->parent
.parent
;
144 struct lttng_event_field_value
*lttng_event_field_value_real_create(double val
)
146 struct lttng_event_field_value_real
*field_val
= lttng::utils::container_of(
147 create_empty_field_val(LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
, sizeof(*field_val
)),
148 <tng_event_field_value_real::parent
);
154 field_val
->val
= val
;
158 lttng_event_field_value_destroy(&field_val
->parent
);
161 return &field_val
->parent
;
164 struct lttng_event_field_value
*lttng_event_field_value_string_create_with_size(const char *val
,
167 struct lttng_event_field_value_string
*field_val
= lttng::utils::container_of(
168 create_empty_field_val(LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
, sizeof(*field_val
)),
169 <tng_event_field_value_string::parent
);
177 field_val
->val
= strndup(val
, size
);
180 * User code do not expect a NULL string pointer. Populate with
181 * an empty string when length is 0.
183 field_val
->val
= strdup("");
185 if (!field_val
->val
) {
192 lttng_event_field_value_destroy(&field_val
->parent
);
195 return &field_val
->parent
;
198 struct lttng_event_field_value
*lttng_event_field_value_string_create(const char *val
)
201 return lttng_event_field_value_string_create_with_size(val
, strlen(val
));
204 static void destroy_field_val(void *field_val
)
206 lttng_event_field_value_destroy((lttng_event_field_value
*) field_val
);
209 struct lttng_event_field_value
*lttng_event_field_value_array_create()
211 struct lttng_event_field_value_array
*field_val
= lttng::utils::container_of(
212 create_empty_field_val(LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
, sizeof(*field_val
)),
213 <tng_event_field_value_array::parent
);
219 lttng_dynamic_pointer_array_init(&field_val
->elems
, destroy_field_val
);
223 lttng_event_field_value_destroy(&field_val
->parent
);
226 return &field_val
->parent
;
229 void lttng_event_field_value_destroy(struct lttng_event_field_value
*field_val
)
235 switch (field_val
->type
) {
236 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
237 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
239 struct lttng_event_field_value_enum
*enum_field_val
= lttng::utils::container_of(
240 field_val
, <tng_event_field_value_enum::parent
);
242 lttng_dynamic_pointer_array_reset(&enum_field_val
->labels
);
245 case LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
:
247 struct lttng_event_field_value_string
*str_field_val
= lttng::utils::container_of(
248 field_val
, <tng_event_field_value_string::parent
);
250 free(str_field_val
->val
);
253 case LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
:
255 struct lttng_event_field_value_array
*array_field_expr
= lttng::utils::container_of(
256 field_val
, <tng_event_field_value_array::parent
);
258 lttng_dynamic_pointer_array_reset(&array_field_expr
->elems
);
271 int lttng_event_field_value_enum_append_label_with_size(struct lttng_event_field_value
*field_val
,
278 LTTNG_ASSERT(field_val
);
280 new_label
= strndup(label
, size
);
286 ret
= lttng_dynamic_pointer_array_add_pointer(
287 <tng::utils::container_of(field_val
, <tng_event_field_value_enum::parent
)
299 int lttng_event_field_value_enum_append_label(struct lttng_event_field_value
*field_val
,
303 return lttng_event_field_value_enum_append_label_with_size(field_val
, label
, strlen(label
));
306 int lttng_event_field_value_array_append(struct lttng_event_field_value
*array_field_val
,
307 struct lttng_event_field_value
*field_val
)
309 LTTNG_ASSERT(array_field_val
);
310 LTTNG_ASSERT(field_val
);
311 return lttng_dynamic_pointer_array_add_pointer(
312 <tng::utils::container_of(array_field_val
, <tng_event_field_value_array::parent
)
317 int lttng_event_field_value_array_append_unavailable(struct lttng_event_field_value
*array_field_val
)
319 LTTNG_ASSERT(array_field_val
);
320 return lttng_dynamic_pointer_array_add_pointer(
321 <tng::utils::container_of(array_field_val
, <tng_event_field_value_array::parent
)
326 enum lttng_event_field_value_type
327 lttng_event_field_value_get_type(const struct lttng_event_field_value
*field_val
)
329 enum lttng_event_field_value_type type
;
332 type
= LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID
;
336 type
= field_val
->type
;
342 enum lttng_event_field_value_status
343 lttng_event_field_value_unsigned_int_get_value(const struct lttng_event_field_value
*field_val
,
346 enum lttng_event_field_value_status status
;
348 if (!field_val
|| !val
) {
349 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
353 switch (field_val
->type
) {
354 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT
:
355 *val
= lttng::utils::container_of(field_val
, <tng_event_field_value_uint::parent
)
358 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
:
360 const struct lttng_event_field_value_enum
*field_val_enum
=
361 lttng::utils::container_of(field_val
,
362 <tng_event_field_value_enum::parent
);
363 const struct lttng_event_field_value_enum_uint
*field_val_enum_uint
=
364 lttng::utils::container_of(field_val_enum
,
365 <tng_event_field_value_enum_uint::parent
);
366 *val
= field_val_enum_uint
->val
;
370 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
374 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
380 enum lttng_event_field_value_status
381 lttng_event_field_value_signed_int_get_value(const struct lttng_event_field_value
*field_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_SIGNED_INT
:
393 *val
= lttng::utils::container_of(field_val
, <tng_event_field_value_int::parent
)
396 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
:
398 const struct lttng_event_field_value_enum
*field_val_enum
=
399 lttng::utils::container_of(field_val
,
400 <tng_event_field_value_enum::parent
);
401 const struct lttng_event_field_value_enum_int
*field_val_enum_uint
=
402 lttng::utils::container_of(field_val_enum
,
403 <tng_event_field_value_enum_int::parent
);
404 *val
= field_val_enum_uint
->val
;
408 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
412 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
418 enum lttng_event_field_value_status
419 lttng_event_field_value_real_get_value(const struct lttng_event_field_value
*field_val
, double *val
)
421 enum lttng_event_field_value_status status
;
423 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
|| !val
) {
424 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
428 *val
= lttng::utils::container_of(field_val
, <tng_event_field_value_real::parent
)->val
;
429 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
435 static bool is_enum_field_val(const struct lttng_event_field_value
*field_val
)
437 return field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
||
438 field_val
->type
== LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
;
441 enum lttng_event_field_value_status
442 lttng_event_field_value_enum_get_label_count(const struct lttng_event_field_value
*field_val
,
445 enum lttng_event_field_value_status status
;
447 if (!field_val
|| !is_enum_field_val(field_val
) || !count
) {
448 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
452 *count
= (unsigned int) lttng_dynamic_pointer_array_get_count(
453 <tng::utils::container_of(field_val
, <tng_event_field_value_enum::parent
)
455 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
462 lttng_event_field_value_enum_get_label_at_index(const struct lttng_event_field_value
*field_val
,
466 const struct lttng_event_field_value_enum
*enum_field_val
;
468 if (!field_val
|| !is_enum_field_val(field_val
)) {
474 lttng::utils::container_of(field_val
, <tng_event_field_value_enum::parent
);
476 if (index
>= lttng_dynamic_pointer_array_get_count(&enum_field_val
->labels
)) {
481 ret
= (const char *) lttng_dynamic_pointer_array_get_pointer(&enum_field_val
->labels
,
488 enum lttng_event_field_value_status
489 lttng_event_field_value_string_get_value(const struct lttng_event_field_value
*field_val
,
492 enum lttng_event_field_value_status status
;
494 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
) {
495 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
500 lttng::utils::container_of(field_val
, <tng_event_field_value_string::parent
)->val
;
501 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
507 enum lttng_event_field_value_status
508 lttng_event_field_value_array_get_length(const struct lttng_event_field_value
*field_val
,
509 unsigned int *length
)
511 enum lttng_event_field_value_status status
;
513 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
|| !length
) {
514 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
518 *length
= (unsigned int) lttng_dynamic_pointer_array_get_count(
519 <tng::utils::container_of(field_val
, <tng_event_field_value_array::parent
)
521 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
527 enum lttng_event_field_value_status
lttng_event_field_value_array_get_element_at_index(
528 const struct lttng_event_field_value
*field_val
,
530 const struct lttng_event_field_value
**elem_field_val
)
532 enum lttng_event_field_value_status status
;
533 const struct lttng_event_field_value_array
*array_field_val
;
535 if (!field_val
|| field_val
->type
!= LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
||
537 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
542 lttng::utils::container_of(field_val
, <tng_event_field_value_array::parent
);
544 if (index
>= lttng_dynamic_pointer_array_get_count(&array_field_val
->elems
)) {
545 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID
;
549 *elem_field_val
= (lttng_event_field_value
*) lttng_dynamic_pointer_array_get_pointer(
550 &array_field_val
->elems
, index
);
551 if (*elem_field_val
) {
552 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_OK
;
554 status
= LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE
;