Build fix: missing stdio.h include in signal-helper.hpp
[lttng-tools.git] / src / common / event-field-value.cpp
CommitLineData
d28fcdec
PP
1/*
2 * event-field-value.c
3 *
4 * Linux Trace Toolkit Control Library
5 *
6 * Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com>
7 *
8 * SPDX-License-Identifier: LGPL-2.1-only
9 *
10 */
11
12#define _LGPL_SOURCE
d28fcdec
PP
13#include <stddef.h>
14#include <stdbool.h>
15
c9e313bc
SM
16#include <common/error.hpp>
17#include <common/macros.hpp>
18#include <lttng/event-field-value-internal.hpp>
d28fcdec
PP
19
20static
21struct lttng_event_field_value *create_empty_field_val(
22 enum lttng_event_field_value_type type, size_t size)
23{
24 struct lttng_event_field_value *field_val;
25
64803277 26 field_val = zmalloc<lttng_event_field_value>(size);
d28fcdec
PP
27 if (!field_val) {
28 goto end;
29 }
30
31 field_val->type = type;
32
33end:
34 return field_val;
35}
36
d28fcdec
PP
37struct lttng_event_field_value *lttng_event_field_value_uint_create(
38 uint64_t val)
39{
40 struct lttng_event_field_value_uint *field_val;
41
0114db0e 42 field_val = lttng::utils::container_of(create_empty_field_val(
d28fcdec
PP
43 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT,
44 sizeof(*field_val)),
0114db0e 45 &lttng_event_field_value_uint::parent);
d28fcdec
PP
46 if (!field_val) {
47 goto error;
48 }
49
50 field_val->val = val;
51 goto end;
52
53error:
54 lttng_event_field_value_destroy(&field_val->parent);
55
56end:
57 return &field_val->parent;
58}
59
d28fcdec
PP
60struct lttng_event_field_value *lttng_event_field_value_int_create(
61 int64_t val)
62{
63 struct lttng_event_field_value_int *field_val;
64
0114db0e 65 field_val = lttng::utils::container_of(create_empty_field_val(
d28fcdec
PP
66 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT,
67 sizeof(*field_val)),
0114db0e 68 &lttng_event_field_value_int::parent);
d28fcdec
PP
69 if (!field_val) {
70 goto error;
71 }
72
73 field_val->val = val;
74 goto end;
75
76error:
77 lttng_event_field_value_destroy(&field_val->parent);
78
79end:
80 return &field_val->parent;
81}
82
83static
84struct lttng_event_field_value_enum *create_enum_field_val(
85 enum lttng_event_field_value_type type, size_t size)
86{
87 struct lttng_event_field_value_enum *field_val;
88
0114db0e
JG
89 field_val = lttng::utils::container_of(create_empty_field_val(type, size),
90 &lttng_event_field_value_enum::parent);
d28fcdec
PP
91 if (!field_val) {
92 goto error;
93 }
94
95 lttng_dynamic_pointer_array_init(&field_val->labels, free);
96 goto end;
97
98error:
99 lttng_event_field_value_destroy(&field_val->parent);
100
101end:
102 return field_val;
103}
104
d28fcdec
PP
105struct lttng_event_field_value *lttng_event_field_value_enum_uint_create(
106 uint64_t val)
107{
108 struct lttng_event_field_value_enum_uint *field_val;
109
0114db0e 110 field_val = lttng::utils::container_of(create_enum_field_val(
d28fcdec
PP
111 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM,
112 sizeof(*field_val)),
0114db0e 113 &lttng_event_field_value_enum_uint::parent);
d28fcdec
PP
114 if (!field_val) {
115 goto error;
116 }
117
118 field_val->val = val;
119 goto end;
120
121error:
122 lttng_event_field_value_destroy(&field_val->parent.parent);
123
124end:
125 return &field_val->parent.parent;
126}
127
d28fcdec
PP
128struct lttng_event_field_value *lttng_event_field_value_enum_int_create(
129 int64_t val)
130{
131 struct lttng_event_field_value_enum_int *field_val;
132
0114db0e 133 field_val = lttng::utils::container_of(create_enum_field_val(
d28fcdec
PP
134 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM,
135 sizeof(*field_val)),
0114db0e 136 &lttng_event_field_value_enum_int::parent);
d28fcdec
PP
137 if (!field_val) {
138 goto error;
139 }
140
141 field_val->val = val;
142 goto end;
143
144error:
145 lttng_event_field_value_destroy(&field_val->parent.parent);
146
147end:
148 return &field_val->parent.parent;
149}
150
d28fcdec
PP
151struct lttng_event_field_value *lttng_event_field_value_real_create(double val)
152{
0114db0e 153 struct lttng_event_field_value_real *field_val = lttng::utils::container_of(
d28fcdec
PP
154 create_empty_field_val(
155 LTTNG_EVENT_FIELD_VALUE_TYPE_REAL,
156 sizeof(*field_val)),
0114db0e 157 &lttng_event_field_value_real::parent);
d28fcdec
PP
158
159 if (!field_val) {
160 goto error;
161 }
162
163 field_val->val = val;
164 goto end;
165
166error:
167 lttng_event_field_value_destroy(&field_val->parent);
168
169end:
170 return &field_val->parent;
171}
172
d28fcdec
PP
173struct lttng_event_field_value *lttng_event_field_value_string_create_with_size(
174 const char *val, size_t size)
175{
0114db0e 176 struct lttng_event_field_value_string *field_val = lttng::utils::container_of(
d28fcdec
PP
177 create_empty_field_val(
178 LTTNG_EVENT_FIELD_VALUE_TYPE_STRING,
179 sizeof(*field_val)),
0114db0e 180 &lttng_event_field_value_string::parent);
d28fcdec
PP
181
182 if (!field_val) {
183 goto error;
184 }
185
ceaa850a
MD
186 if (size) {
187 LTTNG_ASSERT(val);
188 field_val->val = strndup(val, size);
189 } else {
190 /*
191 * User code do not expect a NULL string pointer. Populate with
192 * an empty string when length is 0.
193 */
194 field_val->val = strdup("");
195 }
d28fcdec
PP
196 if (!field_val->val) {
197 goto error;
198 }
199
200 goto end;
201
202error:
203 lttng_event_field_value_destroy(&field_val->parent);
204
205end:
206 return &field_val->parent;
207}
208
d28fcdec
PP
209struct lttng_event_field_value *lttng_event_field_value_string_create(
210 const char *val)
211{
a0377dfe 212 LTTNG_ASSERT(val);
d28fcdec
PP
213 return lttng_event_field_value_string_create_with_size(val,
214 strlen(val));
215}
216
217static
218void destroy_field_val(void *field_val)
219{
a6bc4ca9 220 lttng_event_field_value_destroy((lttng_event_field_value *) field_val);
d28fcdec
PP
221}
222
d28fcdec
PP
223struct lttng_event_field_value *lttng_event_field_value_array_create(void)
224{
0114db0e 225 struct lttng_event_field_value_array *field_val = lttng::utils::container_of(
d28fcdec
PP
226 create_empty_field_val(
227 LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY,
228 sizeof(*field_val)),
0114db0e 229 &lttng_event_field_value_array::parent);
d28fcdec
PP
230
231 if (!field_val) {
232 goto error;
233 }
234
235 lttng_dynamic_pointer_array_init(&field_val->elems, destroy_field_val);
236 goto end;
237
238error:
239 lttng_event_field_value_destroy(&field_val->parent);
240
241end:
242 return &field_val->parent;
243}
244
d28fcdec
PP
245void lttng_event_field_value_destroy(struct lttng_event_field_value *field_val)
246{
247 if (!field_val) {
248 goto end;
249 }
250
251 switch (field_val->type) {
252 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM:
253 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM:
254 {
255 struct lttng_event_field_value_enum *enum_field_val =
0114db0e
JG
256 lttng::utils::container_of(field_val,
257 &lttng_event_field_value_enum::parent);
d28fcdec
PP
258
259 lttng_dynamic_pointer_array_reset(&enum_field_val->labels);
260 break;
261 }
262 case LTTNG_EVENT_FIELD_VALUE_TYPE_STRING:
263 {
264 struct lttng_event_field_value_string *str_field_val =
0114db0e
JG
265 lttng::utils::container_of(field_val,
266 &lttng_event_field_value_string::parent);
d28fcdec
PP
267
268 free(str_field_val->val);
269 break;
270 }
271 case LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY:
272 {
273 struct lttng_event_field_value_array *array_field_expr =
0114db0e
JG
274 lttng::utils::container_of(field_val,
275 &lttng_event_field_value_array::parent);
d28fcdec
PP
276
277 lttng_dynamic_pointer_array_reset(&array_field_expr->elems);
278 break;
279 }
280 default:
281 break;
282 }
283
284 free(field_val);
285
286end:
287 return;
288}
289
d28fcdec
PP
290int lttng_event_field_value_enum_append_label_with_size(
291 struct lttng_event_field_value *field_val,
292 const char *label, size_t size)
293{
294 int ret;
295 char *new_label;
296
a0377dfe
FD
297 LTTNG_ASSERT(field_val);
298 LTTNG_ASSERT(label);
d28fcdec
PP
299 new_label = strndup(label, size);
300 if (!new_label) {
301 ret = -1;
302 goto end;
303 }
304
305 ret = lttng_dynamic_pointer_array_add_pointer(
0114db0e
JG
306 &lttng::utils::container_of(field_val,
307 &lttng_event_field_value_enum::parent)->labels,
d28fcdec
PP
308 new_label);
309 if (ret == 0) {
310 new_label = NULL;
311 }
312
313end:
314 free(new_label);
315 return ret;
316}
317
d28fcdec
PP
318int lttng_event_field_value_enum_append_label(
319 struct lttng_event_field_value *field_val,
320 const char *label)
321{
a0377dfe 322 LTTNG_ASSERT(label);
d28fcdec
PP
323 return lttng_event_field_value_enum_append_label_with_size(field_val,
324 label, strlen(label));
325}
326
d28fcdec
PP
327int lttng_event_field_value_array_append(
328 struct lttng_event_field_value *array_field_val,
329 struct lttng_event_field_value *field_val)
330{
a0377dfe
FD
331 LTTNG_ASSERT(array_field_val);
332 LTTNG_ASSERT(field_val);
d28fcdec 333 return lttng_dynamic_pointer_array_add_pointer(
0114db0e
JG
334 &lttng::utils::container_of(array_field_val,
335 &lttng_event_field_value_array::parent)->elems,
d28fcdec
PP
336 field_val);
337}
338
d28fcdec
PP
339int lttng_event_field_value_array_append_unavailable(
340 struct lttng_event_field_value *array_field_val)
341{
a0377dfe 342 LTTNG_ASSERT(array_field_val);
d28fcdec 343 return lttng_dynamic_pointer_array_add_pointer(
0114db0e
JG
344 &lttng::utils::container_of(array_field_val,
345 &lttng_event_field_value_array::parent)->elems,
d28fcdec
PP
346 NULL);
347}
348
349enum lttng_event_field_value_type lttng_event_field_value_get_type(
350 const struct lttng_event_field_value *field_val)
351{
352 enum lttng_event_field_value_type type;
353
354 if (!field_val) {
355 type = LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID;
356 goto end;
357 }
358
359 type = field_val->type;
360
361end:
362 return type;
363}
364
365enum lttng_event_field_value_status
366lttng_event_field_value_unsigned_int_get_value(
367 const struct lttng_event_field_value *field_val, uint64_t *val)
368{
369 enum lttng_event_field_value_status status;
370
371 if (!field_val || !val) {
372 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
373 goto end;
374 }
375
376 switch (field_val->type) {
377 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT:
0114db0e
JG
378 *val = lttng::utils::container_of(field_val,
379 &lttng_event_field_value_uint::parent)->val;
d28fcdec
PP
380 break;
381 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM:
9918e00a 382 {
0114db0e
JG
383 const struct lttng_event_field_value_enum *field_val_enum =
384 lttng::utils::container_of(
385 field_val, &lttng_event_field_value_enum::parent);
386 const struct lttng_event_field_value_enum_uint *field_val_enum_uint =
387 lttng::utils::container_of(field_val_enum,
388 &lttng_event_field_value_enum_uint::parent);
9918e00a 389 *val = field_val_enum_uint->val;
d28fcdec 390 break;
9918e00a 391 }
d28fcdec
PP
392 default:
393 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
394 goto end;
395 }
396
397 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
398
399end:
400 return status;
401}
402
403enum lttng_event_field_value_status
404lttng_event_field_value_signed_int_get_value(
405 const struct lttng_event_field_value *field_val, int64_t *val)
406{
407 enum lttng_event_field_value_status status;
408
409 if (!field_val || !val) {
410 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
411 goto end;
412 }
413
414 switch (field_val->type) {
415 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT:
0114db0e
JG
416 *val = lttng::utils::container_of(field_val,
417 &lttng_event_field_value_int::parent)->val;
d28fcdec
PP
418 break;
419 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM:
9918e00a 420 {
0114db0e 421 const struct lttng_event_field_value_enum *field_val_enum = lttng::utils::container_of(
9918e00a 422 field_val,
0114db0e
JG
423 &lttng_event_field_value_enum::parent);
424 const struct lttng_event_field_value_enum_int *field_val_enum_uint =
425 lttng::utils::container_of(field_val_enum,
426 &lttng_event_field_value_enum_int::parent);
9918e00a 427 *val = field_val_enum_uint->val;
d28fcdec 428 break;
9918e00a 429 }
d28fcdec
PP
430 default:
431 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
432 goto end;
433 }
434
435 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
436
437end:
438 return status;
439}
440
441enum lttng_event_field_value_status
442lttng_event_field_value_real_get_value(
443 const struct lttng_event_field_value *field_val, double *val)
444{
445 enum lttng_event_field_value_status status;
446
447 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_REAL ||
448 !val) {
449 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
450 goto end;
451 }
452
0114db0e
JG
453 *val = lttng::utils::container_of(field_val,
454 &lttng_event_field_value_real::parent)->val;
d28fcdec
PP
455 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
456
457end:
458 return status;
459}
460
461static
462bool is_enum_field_val(const struct lttng_event_field_value *field_val)
463{
464 return field_val->type == LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM ||
465 field_val->type == LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM;
466}
467
468enum lttng_event_field_value_status
469lttng_event_field_value_enum_get_label_count(
470 const struct lttng_event_field_value *field_val,
471 unsigned int *count)
472{
473 enum lttng_event_field_value_status status;
474
475 if (!field_val || !is_enum_field_val(field_val) || !count) {
476 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
477 goto end;
478 }
479
480 *count = (unsigned int) lttng_dynamic_pointer_array_get_count(
0114db0e
JG
481 &lttng::utils::container_of(field_val,
482 &lttng_event_field_value_enum::parent)->labels);
d28fcdec
PP
483 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
484
485end:
486 return status;
487}
488
489const char *lttng_event_field_value_enum_get_label_at_index(
490 const struct lttng_event_field_value *field_val,
491 unsigned int index)
492{
493 const char *ret;
494 const struct lttng_event_field_value_enum *enum_field_val;
495
496 if (!field_val || !is_enum_field_val(field_val)) {
497 ret = NULL;
498 goto end;
499 }
500
0114db0e
JG
501 enum_field_val = lttng::utils::container_of(field_val,
502 &lttng_event_field_value_enum::parent);
d28fcdec
PP
503
504 if (index >= lttng_dynamic_pointer_array_get_count(&enum_field_val->labels)) {
505 ret = NULL;
506 goto end;
507 }
508
a6bc4ca9 509 ret = (const char *) lttng_dynamic_pointer_array_get_pointer(&enum_field_val->labels,
d28fcdec
PP
510 index);
511
512end:
513 return ret;
514}
515
7c920b63
PP
516enum lttng_event_field_value_status lttng_event_field_value_string_get_value(
517 const struct lttng_event_field_value *field_val,
518 const char **value)
d28fcdec 519{
7c920b63 520 enum lttng_event_field_value_status status;
d28fcdec
PP
521
522 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_STRING) {
7c920b63 523 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
d28fcdec
PP
524 goto end;
525 }
526
0114db0e
JG
527 *value = lttng::utils::container_of(field_val,
528 &lttng_event_field_value_string::parent)->val;
7c920b63 529 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
d28fcdec
PP
530
531end:
7c920b63 532 return status;
d28fcdec
PP
533}
534
535enum lttng_event_field_value_status lttng_event_field_value_array_get_length(
536 const struct lttng_event_field_value *field_val,
537 unsigned int *length)
538{
539 enum lttng_event_field_value_status status;
540
541 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY ||
542 !length) {
543 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
544 goto end;
545 }
546
547 *length = (unsigned int) lttng_dynamic_pointer_array_get_count(
0114db0e
JG
548 &lttng::utils::container_of(field_val,
549 &lttng_event_field_value_array::parent)->elems);
d28fcdec
PP
550 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
551
552end:
553 return status;
554}
555
556enum lttng_event_field_value_status
557lttng_event_field_value_array_get_element_at_index(
558 const struct lttng_event_field_value *field_val,
559 unsigned int index,
560 const struct lttng_event_field_value **elem_field_val)
561{
562 enum lttng_event_field_value_status status;
563 const struct lttng_event_field_value_array *array_field_val;
564
565 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY ||
566 !elem_field_val) {
567 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
568 goto end;
569 }
570
0114db0e
JG
571 array_field_val = lttng::utils::container_of(
572 field_val, &lttng_event_field_value_array::parent);
d28fcdec
PP
573
574 if (index >= lttng_dynamic_pointer_array_get_count(&array_field_val->elems)) {
575 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
576 goto end;
577 }
578
a6bc4ca9 579 *elem_field_val = (lttng_event_field_value *) lttng_dynamic_pointer_array_get_pointer(
d28fcdec
PP
580 &array_field_val->elems, index);
581 if (*elem_field_val) {
582 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
583 } else {
584 status = LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE;
585 }
586
587end:
588 return status;
589}
This page took 0.064744 seconds and 4 git commands to generate.