common: compile libcommon as C++
[lttng-tools.git] / src / common / actions / path.cpp
CommitLineData
27993cc2
JG
1/*
2 * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8#include <lttng/action/path-internal.h>
9
10struct lttng_action_path_comm {
11 uint32_t index_count;
12 uint64_t indexes[];
13} LTTNG_PACKED;
14
15struct lttng_action_path *lttng_action_path_create(
16 const uint64_t *indexes, size_t index_count)
17{
18 int ret;
19 size_t i;
20 struct lttng_action_path *path = NULL;
21
22 if (!indexes && index_count > 0) {
23 goto error;
24 }
25
a6bc4ca9 26 path = (lttng_action_path *) zmalloc(sizeof(*path));
27993cc2
JG
27 if (!path) {
28 goto error;
29 }
30
31 lttng_dynamic_array_init(&path->indexes, sizeof(uint64_t), NULL);
27993cc2
JG
32
33 for (i = 0; i < index_count; i++) {
34 ret = lttng_dynamic_array_add_element(
35 &path->indexes, &indexes[i]);
36 if (ret) {
37 goto error;
38 }
39 }
40
41 goto end;
42error:
43 lttng_action_path_destroy(path);
44 path = NULL;
45end:
46 return path;
47}
48
49enum lttng_action_path_status lttng_action_path_get_index_count(
50 const struct lttng_action_path *path, size_t *index_count)
51{
52 enum lttng_action_path_status status;
53
54 if (!path || !index_count) {
55 status = LTTNG_ACTION_PATH_STATUS_INVALID;
56 goto end;
57 }
58
59 *index_count = lttng_dynamic_array_get_count(&path->indexes);
60 status = LTTNG_ACTION_PATH_STATUS_OK;
61end:
62 return status;
63}
64
65enum lttng_action_path_status lttng_action_path_get_index_at_index(
66 const struct lttng_action_path *path,
67 size_t path_index,
68 uint64_t *out_index)
69{
70 enum lttng_action_path_status status;
71
72 if (!path || !out_index ||
73 path_index >= lttng_dynamic_array_get_count(
74 &path->indexes)) {
75 status = LTTNG_ACTION_PATH_STATUS_INVALID;
76 goto end;
77 }
78
79 *out_index = *((typeof(out_index)) lttng_dynamic_array_get_element(
80 &path->indexes, path_index));
81 status = LTTNG_ACTION_PATH_STATUS_OK;
82end:
83 return status;
84}
85
86void lttng_action_path_destroy(struct lttng_action_path *action_path)
87{
88 if (!action_path) {
89 goto end;
90 }
91
92 lttng_dynamic_array_reset(&action_path->indexes);
93 free(action_path);
94end:
95 return;
96}
97
27993cc2
JG
98int lttng_action_path_copy(const struct lttng_action_path *src,
99 struct lttng_action_path *dst)
100{
101 int ret;
102 size_t i, src_count;
103
a0377dfe
FD
104 LTTNG_ASSERT(src);
105 LTTNG_ASSERT(dst);
27993cc2
JG
106
107 lttng_dynamic_array_init(&dst->indexes, sizeof(uint64_t), NULL);
108 src_count = lttng_dynamic_array_get_count(&src->indexes);
109
27993cc2
JG
110 for (i = 0; i < src_count; i++) {
111 const void *index = lttng_dynamic_array_get_element(
112 &src->indexes, i);
113
114 ret = lttng_dynamic_array_add_element(&dst->indexes, index);
115 if (ret) {
116 goto error;
117 }
118 }
119
120 ret = 0;
121 goto end;
122error:
123 lttng_dynamic_array_reset(&dst->indexes);
124end:
125 return ret;
126}
127
27993cc2
JG
128ssize_t lttng_action_path_create_from_payload(
129 struct lttng_payload_view *view,
130 struct lttng_action_path **_action_path)
131{
132 ssize_t consumed_size = 0, ret = -1;
133 const struct lttng_action_path_comm *header;
134 struct lttng_action_path *action_path = NULL;
135 const struct lttng_payload_view header_view =
136 lttng_payload_view_from_view(view, 0, sizeof(*header));
137
138 if (!lttng_payload_view_is_valid(&header_view)) {
139 goto end;
140 }
141
142 header = (typeof(header)) header_view.buffer.data;
143 consumed_size += header_view.buffer.size;
7afaf43b
JR
144
145 /*
146 * An action path of size 0 can exist and represents a trigger with a
147 * single non-list action. Handle it differently since a payload view of
148 * size 0 is considered invalid.
149 */
150 if (header->index_count != 0)
27993cc2
JG
151 {
152 const struct lttng_payload_view indexes_view =
153 lttng_payload_view_from_view(view,
154 consumed_size,
155 header->index_count *
156 sizeof(uint64_t));
157
158 if (!lttng_payload_view_is_valid(&indexes_view)) {
159 goto end;
160 }
161
162 consumed_size += indexes_view.buffer.size;
163 action_path = lttng_action_path_create(
164 (const uint64_t *) indexes_view.buffer.data,
165 header->index_count);
166 if (!action_path) {
167 goto end;
168 }
7afaf43b
JR
169 } else {
170 action_path = lttng_action_path_create(NULL, 0);
171 if (!action_path) {
172 goto end;
173 }
27993cc2
JG
174 }
175
176 ret = consumed_size;
cb9222ff 177 *_action_path = action_path;
27993cc2
JG
178end:
179 return ret;
180}
181
27993cc2
JG
182int lttng_action_path_serialize(const struct lttng_action_path *action_path,
183 struct lttng_payload *payload)
184{
185 int ret;
186 size_t index_count, i;
187 enum lttng_action_path_status status;
a6bc4ca9 188 lttng_action_path_comm comm;
27993cc2
JG
189
190 status = lttng_action_path_get_index_count(action_path, &index_count);
191 if (status != LTTNG_ACTION_PATH_STATUS_OK) {
192 ret = -1;
193 goto end;
194 }
195
a6bc4ca9
SM
196 comm = {
197 .index_count = (uint32_t) index_count,
198 };
27993cc2 199 ret = lttng_dynamic_buffer_append(&payload->buffer,
a6bc4ca9 200 &comm,
27993cc2
JG
201 sizeof(struct lttng_action_path_comm));
202
203 for (i = 0; i < index_count; i++) {
204 uint64_t path_index;
205
206 status = lttng_action_path_get_index_at_index(
207 action_path, i, &path_index);
208 if (status != LTTNG_ACTION_PATH_STATUS_OK) {
209 ret = -1;
210 goto end;
211 }
212
213 ret = lttng_dynamic_buffer_append(&payload->buffer, &path_index,
214 sizeof(path_index));
215 if (ret) {
216 goto end;
217 }
218 }
219
220 ret = 0;
221end:
222 return ret;
223}
This page took 0.032049 seconds and 4 git commands to generate.