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