Force usage of assert() condition when NDEBUG is defined
[lttng-tools.git] / src / common / event-field-value.c
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
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
20 static
21 struct 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
33 end:
34 return field_val;
35 }
36
37 LTTNG_HIDDEN
38 struct 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
54 error:
55 lttng_event_field_value_destroy(&field_val->parent);
56
57 end:
58 return &field_val->parent;
59 }
60
61 LTTNG_HIDDEN
62 struct 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
78 error:
79 lttng_event_field_value_destroy(&field_val->parent);
80
81 end:
82 return &field_val->parent;
83 }
84
85 static
86 struct 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
100 error:
101 lttng_event_field_value_destroy(&field_val->parent);
102
103 end:
104 return field_val;
105 }
106
107 LTTNG_HIDDEN
108 struct 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
124 error:
125 lttng_event_field_value_destroy(&field_val->parent.parent);
126
127 end:
128 return &field_val->parent.parent;
129 }
130
131 LTTNG_HIDDEN
132 struct 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
148 error:
149 lttng_event_field_value_destroy(&field_val->parent.parent);
150
151 end:
152 return &field_val->parent.parent;
153 }
154
155 LTTNG_HIDDEN
156 struct 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
171 error:
172 lttng_event_field_value_destroy(&field_val->parent);
173
174 end:
175 return &field_val->parent;
176 }
177
178 LTTNG_HIDDEN
179 struct 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
192 LTTNG_ASSERT(val);
193 field_val->val = strndup(val, size);
194 if (!field_val->val) {
195 goto error;
196 }
197
198 goto end;
199
200 error:
201 lttng_event_field_value_destroy(&field_val->parent);
202
203 end:
204 return &field_val->parent;
205 }
206
207 LTTNG_HIDDEN
208 struct lttng_event_field_value *lttng_event_field_value_string_create(
209 const char *val)
210 {
211 LTTNG_ASSERT(val);
212 return lttng_event_field_value_string_create_with_size(val,
213 strlen(val));
214 }
215
216 static
217 void destroy_field_val(void *field_val)
218 {
219 lttng_event_field_value_destroy(field_val);
220 }
221
222 LTTNG_HIDDEN
223 struct 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
238 error:
239 lttng_event_field_value_destroy(&field_val->parent);
240
241 end:
242 return &field_val->parent;
243 }
244
245 LTTNG_HIDDEN
246 void 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
288 end:
289 return;
290 }
291
292 LTTNG_HIDDEN
293 int 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
300 LTTNG_ASSERT(field_val);
301 LTTNG_ASSERT(label);
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
316 end:
317 free(new_label);
318 return ret;
319 }
320
321 LTTNG_HIDDEN
322 int lttng_event_field_value_enum_append_label(
323 struct lttng_event_field_value *field_val,
324 const char *label)
325 {
326 LTTNG_ASSERT(label);
327 return lttng_event_field_value_enum_append_label_with_size(field_val,
328 label, strlen(label));
329 }
330
331 LTTNG_HIDDEN
332 int lttng_event_field_value_array_append(
333 struct lttng_event_field_value *array_field_val,
334 struct lttng_event_field_value *field_val)
335 {
336 LTTNG_ASSERT(array_field_val);
337 LTTNG_ASSERT(field_val);
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
344 LTTNG_HIDDEN
345 int lttng_event_field_value_array_append_unavailable(
346 struct lttng_event_field_value *array_field_val)
347 {
348 LTTNG_ASSERT(array_field_val);
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
355 enum 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
367 end:
368 return type;
369 }
370
371 enum lttng_event_field_value_status
372 lttng_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:
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;
400 break;
401 }
402 default:
403 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
404 goto end;
405 }
406
407 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
408
409 end:
410 return status;
411 }
412
413 enum lttng_event_field_value_status
414 lttng_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:
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;
442 break;
443 }
444 default:
445 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
446 goto end;
447 }
448
449 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
450
451 end:
452 return status;
453 }
454
455 enum lttng_event_field_value_status
456 lttng_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
471 end:
472 return status;
473 }
474
475 static
476 bool 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
482 enum lttng_event_field_value_status
483 lttng_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
500 end:
501 return status;
502 }
503
504 const 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
527 end:
528 return ret;
529 }
530
531 enum 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)
534 {
535 enum lttng_event_field_value_status status;
536
537 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_STRING) {
538 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
539 goto end;
540 }
541
542 *value = container_of(field_val,
543 const struct lttng_event_field_value_string, parent)->val;
544 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
545
546 end:
547 return status;
548 }
549
550 enum 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
568 end:
569 return status;
570 }
571
572 enum lttng_event_field_value_status
573 lttng_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
603 end:
604 return status;
605 }
This page took 0.040688 seconds and 4 git commands to generate.