port: BSD cut doesn't support '\0' as a delimiter
[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
a0377dfe 186 LTTNG_ASSERT(val);
d28fcdec
PP
187 field_val->val = strndup(val, size);
188 if (!field_val->val) {
189 goto error;
190 }
191
192 goto end;
193
194error:
195 lttng_event_field_value_destroy(&field_val->parent);
196
197end:
198 return &field_val->parent;
199}
200
d28fcdec
PP
201struct lttng_event_field_value *lttng_event_field_value_string_create(
202 const char *val)
203{
a0377dfe 204 LTTNG_ASSERT(val);
d28fcdec
PP
205 return lttng_event_field_value_string_create_with_size(val,
206 strlen(val));
207}
208
209static
210void destroy_field_val(void *field_val)
211{
a6bc4ca9 212 lttng_event_field_value_destroy((lttng_event_field_value *) field_val);
d28fcdec
PP
213}
214
d28fcdec
PP
215struct lttng_event_field_value *lttng_event_field_value_array_create(void)
216{
0114db0e 217 struct lttng_event_field_value_array *field_val = lttng::utils::container_of(
d28fcdec
PP
218 create_empty_field_val(
219 LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY,
220 sizeof(*field_val)),
0114db0e 221 &lttng_event_field_value_array::parent);
d28fcdec
PP
222
223 if (!field_val) {
224 goto error;
225 }
226
227 lttng_dynamic_pointer_array_init(&field_val->elems, destroy_field_val);
228 goto end;
229
230error:
231 lttng_event_field_value_destroy(&field_val->parent);
232
233end:
234 return &field_val->parent;
235}
236
d28fcdec
PP
237void lttng_event_field_value_destroy(struct lttng_event_field_value *field_val)
238{
239 if (!field_val) {
240 goto end;
241 }
242
243 switch (field_val->type) {
244 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM:
245 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM:
246 {
247 struct lttng_event_field_value_enum *enum_field_val =
0114db0e
JG
248 lttng::utils::container_of(field_val,
249 &lttng_event_field_value_enum::parent);
d28fcdec
PP
250
251 lttng_dynamic_pointer_array_reset(&enum_field_val->labels);
252 break;
253 }
254 case LTTNG_EVENT_FIELD_VALUE_TYPE_STRING:
255 {
256 struct lttng_event_field_value_string *str_field_val =
0114db0e
JG
257 lttng::utils::container_of(field_val,
258 &lttng_event_field_value_string::parent);
d28fcdec
PP
259
260 free(str_field_val->val);
261 break;
262 }
263 case LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY:
264 {
265 struct lttng_event_field_value_array *array_field_expr =
0114db0e
JG
266 lttng::utils::container_of(field_val,
267 &lttng_event_field_value_array::parent);
d28fcdec
PP
268
269 lttng_dynamic_pointer_array_reset(&array_field_expr->elems);
270 break;
271 }
272 default:
273 break;
274 }
275
276 free(field_val);
277
278end:
279 return;
280}
281
d28fcdec
PP
282int lttng_event_field_value_enum_append_label_with_size(
283 struct lttng_event_field_value *field_val,
284 const char *label, size_t size)
285{
286 int ret;
287 char *new_label;
288
a0377dfe
FD
289 LTTNG_ASSERT(field_val);
290 LTTNG_ASSERT(label);
d28fcdec
PP
291 new_label = strndup(label, size);
292 if (!new_label) {
293 ret = -1;
294 goto end;
295 }
296
297 ret = lttng_dynamic_pointer_array_add_pointer(
0114db0e
JG
298 &lttng::utils::container_of(field_val,
299 &lttng_event_field_value_enum::parent)->labels,
d28fcdec
PP
300 new_label);
301 if (ret == 0) {
302 new_label = NULL;
303 }
304
305end:
306 free(new_label);
307 return ret;
308}
309
d28fcdec
PP
310int lttng_event_field_value_enum_append_label(
311 struct lttng_event_field_value *field_val,
312 const char *label)
313{
a0377dfe 314 LTTNG_ASSERT(label);
d28fcdec
PP
315 return lttng_event_field_value_enum_append_label_with_size(field_val,
316 label, strlen(label));
317}
318
d28fcdec
PP
319int lttng_event_field_value_array_append(
320 struct lttng_event_field_value *array_field_val,
321 struct lttng_event_field_value *field_val)
322{
a0377dfe
FD
323 LTTNG_ASSERT(array_field_val);
324 LTTNG_ASSERT(field_val);
d28fcdec 325 return lttng_dynamic_pointer_array_add_pointer(
0114db0e
JG
326 &lttng::utils::container_of(array_field_val,
327 &lttng_event_field_value_array::parent)->elems,
d28fcdec
PP
328 field_val);
329}
330
d28fcdec
PP
331int lttng_event_field_value_array_append_unavailable(
332 struct lttng_event_field_value *array_field_val)
333{
a0377dfe 334 LTTNG_ASSERT(array_field_val);
d28fcdec 335 return lttng_dynamic_pointer_array_add_pointer(
0114db0e
JG
336 &lttng::utils::container_of(array_field_val,
337 &lttng_event_field_value_array::parent)->elems,
d28fcdec
PP
338 NULL);
339}
340
341enum lttng_event_field_value_type lttng_event_field_value_get_type(
342 const struct lttng_event_field_value *field_val)
343{
344 enum lttng_event_field_value_type type;
345
346 if (!field_val) {
347 type = LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID;
348 goto end;
349 }
350
351 type = field_val->type;
352
353end:
354 return type;
355}
356
357enum lttng_event_field_value_status
358lttng_event_field_value_unsigned_int_get_value(
359 const struct lttng_event_field_value *field_val, uint64_t *val)
360{
361 enum lttng_event_field_value_status status;
362
363 if (!field_val || !val) {
364 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
365 goto end;
366 }
367
368 switch (field_val->type) {
369 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT:
0114db0e
JG
370 *val = lttng::utils::container_of(field_val,
371 &lttng_event_field_value_uint::parent)->val;
d28fcdec
PP
372 break;
373 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM:
9918e00a 374 {
0114db0e
JG
375 const struct lttng_event_field_value_enum *field_val_enum =
376 lttng::utils::container_of(
377 field_val, &lttng_event_field_value_enum::parent);
378 const struct lttng_event_field_value_enum_uint *field_val_enum_uint =
379 lttng::utils::container_of(field_val_enum,
380 &lttng_event_field_value_enum_uint::parent);
9918e00a 381 *val = field_val_enum_uint->val;
d28fcdec 382 break;
9918e00a 383 }
d28fcdec
PP
384 default:
385 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
386 goto end;
387 }
388
389 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
390
391end:
392 return status;
393}
394
395enum lttng_event_field_value_status
396lttng_event_field_value_signed_int_get_value(
397 const struct lttng_event_field_value *field_val, int64_t *val)
398{
399 enum lttng_event_field_value_status status;
400
401 if (!field_val || !val) {
402 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
403 goto end;
404 }
405
406 switch (field_val->type) {
407 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT:
0114db0e
JG
408 *val = lttng::utils::container_of(field_val,
409 &lttng_event_field_value_int::parent)->val;
d28fcdec
PP
410 break;
411 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM:
9918e00a 412 {
0114db0e 413 const struct lttng_event_field_value_enum *field_val_enum = lttng::utils::container_of(
9918e00a 414 field_val,
0114db0e
JG
415 &lttng_event_field_value_enum::parent);
416 const struct lttng_event_field_value_enum_int *field_val_enum_uint =
417 lttng::utils::container_of(field_val_enum,
418 &lttng_event_field_value_enum_int::parent);
9918e00a 419 *val = field_val_enum_uint->val;
d28fcdec 420 break;
9918e00a 421 }
d28fcdec
PP
422 default:
423 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
424 goto end;
425 }
426
427 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
428
429end:
430 return status;
431}
432
433enum lttng_event_field_value_status
434lttng_event_field_value_real_get_value(
435 const struct lttng_event_field_value *field_val, double *val)
436{
437 enum lttng_event_field_value_status status;
438
439 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_REAL ||
440 !val) {
441 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
442 goto end;
443 }
444
0114db0e
JG
445 *val = lttng::utils::container_of(field_val,
446 &lttng_event_field_value_real::parent)->val;
d28fcdec
PP
447 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
448
449end:
450 return status;
451}
452
453static
454bool is_enum_field_val(const struct lttng_event_field_value *field_val)
455{
456 return field_val->type == LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM ||
457 field_val->type == LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM;
458}
459
460enum lttng_event_field_value_status
461lttng_event_field_value_enum_get_label_count(
462 const struct lttng_event_field_value *field_val,
463 unsigned int *count)
464{
465 enum lttng_event_field_value_status status;
466
467 if (!field_val || !is_enum_field_val(field_val) || !count) {
468 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
469 goto end;
470 }
471
472 *count = (unsigned int) lttng_dynamic_pointer_array_get_count(
0114db0e
JG
473 &lttng::utils::container_of(field_val,
474 &lttng_event_field_value_enum::parent)->labels);
d28fcdec
PP
475 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
476
477end:
478 return status;
479}
480
481const char *lttng_event_field_value_enum_get_label_at_index(
482 const struct lttng_event_field_value *field_val,
483 unsigned int index)
484{
485 const char *ret;
486 const struct lttng_event_field_value_enum *enum_field_val;
487
488 if (!field_val || !is_enum_field_val(field_val)) {
489 ret = NULL;
490 goto end;
491 }
492
0114db0e
JG
493 enum_field_val = lttng::utils::container_of(field_val,
494 &lttng_event_field_value_enum::parent);
d28fcdec
PP
495
496 if (index >= lttng_dynamic_pointer_array_get_count(&enum_field_val->labels)) {
497 ret = NULL;
498 goto end;
499 }
500
a6bc4ca9 501 ret = (const char *) lttng_dynamic_pointer_array_get_pointer(&enum_field_val->labels,
d28fcdec
PP
502 index);
503
504end:
505 return ret;
506}
507
7c920b63
PP
508enum lttng_event_field_value_status lttng_event_field_value_string_get_value(
509 const struct lttng_event_field_value *field_val,
510 const char **value)
d28fcdec 511{
7c920b63 512 enum lttng_event_field_value_status status;
d28fcdec
PP
513
514 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_STRING) {
7c920b63 515 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
d28fcdec
PP
516 goto end;
517 }
518
0114db0e
JG
519 *value = lttng::utils::container_of(field_val,
520 &lttng_event_field_value_string::parent)->val;
7c920b63 521 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
d28fcdec
PP
522
523end:
7c920b63 524 return status;
d28fcdec
PP
525}
526
527enum lttng_event_field_value_status lttng_event_field_value_array_get_length(
528 const struct lttng_event_field_value *field_val,
529 unsigned int *length)
530{
531 enum lttng_event_field_value_status status;
532
533 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY ||
534 !length) {
535 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
536 goto end;
537 }
538
539 *length = (unsigned int) lttng_dynamic_pointer_array_get_count(
0114db0e
JG
540 &lttng::utils::container_of(field_val,
541 &lttng_event_field_value_array::parent)->elems);
d28fcdec
PP
542 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
543
544end:
545 return status;
546}
547
548enum lttng_event_field_value_status
549lttng_event_field_value_array_get_element_at_index(
550 const struct lttng_event_field_value *field_val,
551 unsigned int index,
552 const struct lttng_event_field_value **elem_field_val)
553{
554 enum lttng_event_field_value_status status;
555 const struct lttng_event_field_value_array *array_field_val;
556
557 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY ||
558 !elem_field_val) {
559 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
560 goto end;
561 }
562
0114db0e
JG
563 array_field_val = lttng::utils::container_of(
564 field_val, &lttng_event_field_value_array::parent);
d28fcdec
PP
565
566 if (index >= lttng_dynamic_pointer_array_get_count(&array_field_val->elems)) {
567 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
568 goto end;
569 }
570
a6bc4ca9 571 *elem_field_val = (lttng_event_field_value *) lttng_dynamic_pointer_array_get_pointer(
d28fcdec
PP
572 &array_field_val->elems, index);
573 if (*elem_field_val) {
574 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
575 } else {
576 status = LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE;
577 }
578
579end:
580 return status;
581}
This page took 0.066281 seconds and 4 git commands to generate.