Force usage of assert() condition when NDEBUG is defined
[lttng-tools.git] / src / common / actions / path.c
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
26 path = zmalloc(sizeof(*path));
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
98LTTNG_HIDDEN
99int lttng_action_path_copy(const struct lttng_action_path *src,
100 struct lttng_action_path *dst)
101{
102 int ret;
103 size_t i, src_count;
104
a0377dfe
FD
105 LTTNG_ASSERT(src);
106 LTTNG_ASSERT(dst);
27993cc2
JG
107
108 lttng_dynamic_array_init(&dst->indexes, sizeof(uint64_t), NULL);
109 src_count = lttng_dynamic_array_get_count(&src->indexes);
110
27993cc2
JG
111 for (i = 0; i < src_count; i++) {
112 const void *index = lttng_dynamic_array_get_element(
113 &src->indexes, i);
114
115 ret = lttng_dynamic_array_add_element(&dst->indexes, index);
116 if (ret) {
117 goto error;
118 }
119 }
120
121 ret = 0;
122 goto end;
123error:
124 lttng_dynamic_array_reset(&dst->indexes);
125end:
126 return ret;
127}
128
129LTTNG_HIDDEN
130ssize_t lttng_action_path_create_from_payload(
131 struct lttng_payload_view *view,
132 struct lttng_action_path **_action_path)
133{
134 ssize_t consumed_size = 0, ret = -1;
135 const struct lttng_action_path_comm *header;
136 struct lttng_action_path *action_path = NULL;
137 const struct lttng_payload_view header_view =
138 lttng_payload_view_from_view(view, 0, sizeof(*header));
139
140 if (!lttng_payload_view_is_valid(&header_view)) {
141 goto end;
142 }
143
144 header = (typeof(header)) header_view.buffer.data;
145 consumed_size += header_view.buffer.size;
7afaf43b
JR
146
147 /*
148 * An action path of size 0 can exist and represents a trigger with a
149 * single non-list action. Handle it differently since a payload view of
150 * size 0 is considered invalid.
151 */
152 if (header->index_count != 0)
27993cc2
JG
153 {
154 const struct lttng_payload_view indexes_view =
155 lttng_payload_view_from_view(view,
156 consumed_size,
157 header->index_count *
158 sizeof(uint64_t));
159
160 if (!lttng_payload_view_is_valid(&indexes_view)) {
161 goto end;
162 }
163
164 consumed_size += indexes_view.buffer.size;
165 action_path = lttng_action_path_create(
166 (const uint64_t *) indexes_view.buffer.data,
167 header->index_count);
168 if (!action_path) {
169 goto end;
170 }
7afaf43b
JR
171 } else {
172 action_path = lttng_action_path_create(NULL, 0);
173 if (!action_path) {
174 goto end;
175 }
27993cc2
JG
176 }
177
178 ret = consumed_size;
cb9222ff 179 *_action_path = action_path;
27993cc2
JG
180end:
181 return ret;
182}
183
184LTTNG_HIDDEN
185int lttng_action_path_serialize(const struct lttng_action_path *action_path,
186 struct lttng_payload *payload)
187{
188 int ret;
189 size_t index_count, i;
190 enum lttng_action_path_status status;
191
192 status = lttng_action_path_get_index_count(action_path, &index_count);
193 if (status != LTTNG_ACTION_PATH_STATUS_OK) {
194 ret = -1;
195 goto end;
196 }
197
198 ret = lttng_dynamic_buffer_append(&payload->buffer,
199 &((struct lttng_action_path_comm) {
200 .index_count = index_count
201 }),
202 sizeof(struct lttng_action_path_comm));
203
204 for (i = 0; i < index_count; i++) {
205 uint64_t path_index;
206
207 status = lttng_action_path_get_index_at_index(
208 action_path, i, &path_index);
209 if (status != LTTNG_ACTION_PATH_STATUS_OK) {
210 ret = -1;
211 goto end;
212 }
213
214 ret = lttng_dynamic_buffer_append(&payload->buffer, &path_index,
215 sizeof(path_index));
216 if (ret) {
217 goto end;
218 }
219 }
220
221 ret = 0;
222end:
223 return ret;
224}
This page took 0.030688 seconds and 4 git commands to generate.