Add new exception types: communication, protocol, and invalid argument
[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
42 field_val = container_of(create_empty_field_val(
43 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT,
44 sizeof(*field_val)),
45 struct lttng_event_field_value_uint, parent);
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
65 field_val = container_of(create_empty_field_val(
66 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT,
67 sizeof(*field_val)),
68 struct lttng_event_field_value_int, parent);
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
89 field_val = container_of(create_empty_field_val(type, size),
90 struct lttng_event_field_value_enum, parent);
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
110 field_val = container_of(create_enum_field_val(
111 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM,
112 sizeof(*field_val)),
113 struct lttng_event_field_value_enum_uint, parent);
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
133 field_val = container_of(create_enum_field_val(
134 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM,
135 sizeof(*field_val)),
136 struct lttng_event_field_value_enum_int, parent);
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{
153 struct lttng_event_field_value_real *field_val = container_of(
154 create_empty_field_val(
155 LTTNG_EVENT_FIELD_VALUE_TYPE_REAL,
156 sizeof(*field_val)),
157 struct lttng_event_field_value_real, parent);
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{
176 struct lttng_event_field_value_string *field_val = container_of(
177 create_empty_field_val(
178 LTTNG_EVENT_FIELD_VALUE_TYPE_STRING,
179 sizeof(*field_val)),
180 struct lttng_event_field_value_string, parent);
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{
217 struct lttng_event_field_value_array *field_val = container_of(
218 create_empty_field_val(
219 LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY,
220 sizeof(*field_val)),
221 struct lttng_event_field_value_array, parent);
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 =
248 container_of(field_val,
249 struct lttng_event_field_value_enum, parent);
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 =
257 container_of(field_val,
258 struct lttng_event_field_value_string, parent);
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 =
266 container_of(field_val,
267 struct lttng_event_field_value_array,
268 parent);
269
270 lttng_dynamic_pointer_array_reset(&array_field_expr->elems);
271 break;
272 }
273 default:
274 break;
275 }
276
277 free(field_val);
278
279end:
280 return;
281}
282
d28fcdec
PP
283int lttng_event_field_value_enum_append_label_with_size(
284 struct lttng_event_field_value *field_val,
285 const char *label, size_t size)
286{
287 int ret;
288 char *new_label;
289
a0377dfe
FD
290 LTTNG_ASSERT(field_val);
291 LTTNG_ASSERT(label);
d28fcdec
PP
292 new_label = strndup(label, size);
293 if (!new_label) {
294 ret = -1;
295 goto end;
296 }
297
298 ret = lttng_dynamic_pointer_array_add_pointer(
299 &container_of(field_val,
300 struct lttng_event_field_value_enum, parent)->labels,
301 new_label);
302 if (ret == 0) {
303 new_label = NULL;
304 }
305
306end:
307 free(new_label);
308 return ret;
309}
310
d28fcdec
PP
311int lttng_event_field_value_enum_append_label(
312 struct lttng_event_field_value *field_val,
313 const char *label)
314{
a0377dfe 315 LTTNG_ASSERT(label);
d28fcdec
PP
316 return lttng_event_field_value_enum_append_label_with_size(field_val,
317 label, strlen(label));
318}
319
d28fcdec
PP
320int lttng_event_field_value_array_append(
321 struct lttng_event_field_value *array_field_val,
322 struct lttng_event_field_value *field_val)
323{
a0377dfe
FD
324 LTTNG_ASSERT(array_field_val);
325 LTTNG_ASSERT(field_val);
d28fcdec
PP
326 return lttng_dynamic_pointer_array_add_pointer(
327 &container_of(array_field_val,
328 struct lttng_event_field_value_array, parent)->elems,
329 field_val);
330}
331
d28fcdec
PP
332int lttng_event_field_value_array_append_unavailable(
333 struct lttng_event_field_value *array_field_val)
334{
a0377dfe 335 LTTNG_ASSERT(array_field_val);
d28fcdec
PP
336 return lttng_dynamic_pointer_array_add_pointer(
337 &container_of(array_field_val,
338 struct lttng_event_field_value_array, parent)->elems,
339 NULL);
340}
341
342enum lttng_event_field_value_type lttng_event_field_value_get_type(
343 const struct lttng_event_field_value *field_val)
344{
345 enum lttng_event_field_value_type type;
346
347 if (!field_val) {
348 type = LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID;
349 goto end;
350 }
351
352 type = field_val->type;
353
354end:
355 return type;
356}
357
358enum lttng_event_field_value_status
359lttng_event_field_value_unsigned_int_get_value(
360 const struct lttng_event_field_value *field_val, uint64_t *val)
361{
362 enum lttng_event_field_value_status status;
363
364 if (!field_val || !val) {
365 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
366 goto end;
367 }
368
369 switch (field_val->type) {
370 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT:
371 *val = container_of(field_val,
372 const struct lttng_event_field_value_uint,
373 parent)->val;
374 break;
375 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM:
9918e00a
SM
376 {
377 const struct lttng_event_field_value_enum *field_val_enum = container_of(
378 field_val,
379 const struct lttng_event_field_value_enum,
380 parent);
381 const struct lttng_event_field_value_enum_uint
382 *field_val_enum_uint = container_of(
383 field_val_enum,
384 const struct lttng_event_field_value_enum_uint,
385 parent);
386 *val = field_val_enum_uint->val;
d28fcdec 387 break;
9918e00a 388 }
d28fcdec
PP
389 default:
390 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
391 goto end;
392 }
393
394 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
395
396end:
397 return status;
398}
399
400enum lttng_event_field_value_status
401lttng_event_field_value_signed_int_get_value(
402 const struct lttng_event_field_value *field_val, int64_t *val)
403{
404 enum lttng_event_field_value_status status;
405
406 if (!field_val || !val) {
407 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
408 goto end;
409 }
410
411 switch (field_val->type) {
412 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT:
413 *val = container_of(field_val,
414 const struct lttng_event_field_value_int,
415 parent)->val;
416 break;
417 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM:
9918e00a
SM
418 {
419 const struct lttng_event_field_value_enum *field_val_enum = container_of(
420 field_val,
421 const struct lttng_event_field_value_enum,
422 parent);
423 const struct lttng_event_field_value_enum_int
424 *field_val_enum_uint = container_of(
425 field_val_enum,
426 const struct lttng_event_field_value_enum_int,
427 parent);
428 *val = field_val_enum_uint->val;
d28fcdec 429 break;
9918e00a 430 }
d28fcdec
PP
431 default:
432 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
433 goto end;
434 }
435
436 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
437
438end:
439 return status;
440}
441
442enum lttng_event_field_value_status
443lttng_event_field_value_real_get_value(
444 const struct lttng_event_field_value *field_val, double *val)
445{
446 enum lttng_event_field_value_status status;
447
448 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_REAL ||
449 !val) {
450 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
451 goto end;
452 }
453
454 *val = container_of(field_val,
455 const struct lttng_event_field_value_real, parent)->val;
456 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
457
458end:
459 return status;
460}
461
462static
463bool is_enum_field_val(const struct lttng_event_field_value *field_val)
464{
465 return field_val->type == LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM ||
466 field_val->type == LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM;
467}
468
469enum lttng_event_field_value_status
470lttng_event_field_value_enum_get_label_count(
471 const struct lttng_event_field_value *field_val,
472 unsigned int *count)
473{
474 enum lttng_event_field_value_status status;
475
476 if (!field_val || !is_enum_field_val(field_val) || !count) {
477 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
478 goto end;
479 }
480
481 *count = (unsigned int) lttng_dynamic_pointer_array_get_count(
482 &container_of(field_val,
483 const struct lttng_event_field_value_enum,
484 parent)->labels);
485 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
486
487end:
488 return status;
489}
490
491const char *lttng_event_field_value_enum_get_label_at_index(
492 const struct lttng_event_field_value *field_val,
493 unsigned int index)
494{
495 const char *ret;
496 const struct lttng_event_field_value_enum *enum_field_val;
497
498 if (!field_val || !is_enum_field_val(field_val)) {
499 ret = NULL;
500 goto end;
501 }
502
503 enum_field_val = container_of(field_val,
504 const struct lttng_event_field_value_enum, parent);
505
506 if (index >= lttng_dynamic_pointer_array_get_count(&enum_field_val->labels)) {
507 ret = NULL;
508 goto end;
509 }
510
a6bc4ca9 511 ret = (const char *) lttng_dynamic_pointer_array_get_pointer(&enum_field_val->labels,
d28fcdec
PP
512 index);
513
514end:
515 return ret;
516}
517
7c920b63
PP
518enum lttng_event_field_value_status lttng_event_field_value_string_get_value(
519 const struct lttng_event_field_value *field_val,
520 const char **value)
d28fcdec 521{
7c920b63 522 enum lttng_event_field_value_status status;
d28fcdec
PP
523
524 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_STRING) {
7c920b63 525 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
d28fcdec
PP
526 goto end;
527 }
528
7c920b63 529 *value = container_of(field_val,
d28fcdec 530 const struct lttng_event_field_value_string, parent)->val;
7c920b63 531 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
d28fcdec
PP
532
533end:
7c920b63 534 return status;
d28fcdec
PP
535}
536
537enum lttng_event_field_value_status lttng_event_field_value_array_get_length(
538 const struct lttng_event_field_value *field_val,
539 unsigned int *length)
540{
541 enum lttng_event_field_value_status status;
542
543 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY ||
544 !length) {
545 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
546 goto end;
547 }
548
549 *length = (unsigned int) lttng_dynamic_pointer_array_get_count(
550 &container_of(field_val,
551 const struct lttng_event_field_value_array,
552 parent)->elems);
553 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
554
555end:
556 return status;
557}
558
559enum lttng_event_field_value_status
560lttng_event_field_value_array_get_element_at_index(
561 const struct lttng_event_field_value *field_val,
562 unsigned int index,
563 const struct lttng_event_field_value **elem_field_val)
564{
565 enum lttng_event_field_value_status status;
566 const struct lttng_event_field_value_array *array_field_val;
567
568 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY ||
569 !elem_field_val) {
570 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
571 goto end;
572 }
573
574 array_field_val = container_of(field_val,
575 const struct lttng_event_field_value_array, parent);
576
577 if (index >= lttng_dynamic_pointer_array_get_count(&array_field_val->elems)) {
578 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
579 goto end;
580 }
581
a6bc4ca9 582 *elem_field_val = (lttng_event_field_value *) lttng_dynamic_pointer_array_get_pointer(
d28fcdec
PP
583 &array_field_val->elems, index);
584 if (*elem_field_val) {
585 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
586 } else {
587 status = LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE;
588 }
589
590end:
591 return status;
592}
This page took 0.060337 seconds and 4 git commands to generate.