Run clang-format on the whole tree
[lttng-tools.git] / src / common / actions / path.cpp
... / ...
CommitLineData
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.hpp>
9
10namespace {
11struct lttng_action_path_comm {
12 uint32_t index_count;
13 uint64_t indexes[];
14} LTTNG_PACKED;
15} /* namespace */
16
17struct lttng_action_path *lttng_action_path_create(const uint64_t *indexes, size_t index_count)
18{
19 int ret;
20 size_t i;
21 struct lttng_action_path *path = NULL;
22
23 if (!indexes && index_count > 0) {
24 goto error;
25 }
26
27 path = zmalloc<lttng_action_path>();
28 if (!path) {
29 goto error;
30 }
31
32 lttng_dynamic_array_init(&path->indexes, sizeof(uint64_t), NULL);
33
34 for (i = 0; i < index_count; i++) {
35 ret = lttng_dynamic_array_add_element(&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
50lttng_action_path_get_index_count(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, size_t path_index, uint64_t *out_index)
67{
68 enum lttng_action_path_status status;
69
70 if (!path || !out_index || path_index >= lttng_dynamic_array_get_count(&path->indexes)) {
71 status = LTTNG_ACTION_PATH_STATUS_INVALID;
72 goto end;
73 }
74
75 *out_index =
76 *((typeof(out_index)) lttng_dynamic_array_get_element(&path->indexes, path_index));
77 status = LTTNG_ACTION_PATH_STATUS_OK;
78end:
79 return status;
80}
81
82void lttng_action_path_destroy(struct lttng_action_path *action_path)
83{
84 if (!action_path) {
85 goto end;
86 }
87
88 lttng_dynamic_array_reset(&action_path->indexes);
89 free(action_path);
90end:
91 return;
92}
93
94int lttng_action_path_copy(const struct lttng_action_path *src, struct lttng_action_path **dst)
95{
96 int ret;
97 struct lttng_action_path *new_path;
98
99 LTTNG_ASSERT(src);
100 LTTNG_ASSERT(dst);
101
102 new_path = lttng_action_path_create(
103 (uint64_t *) lttng_dynamic_array_get_element(&src->indexes, 0),
104 lttng_dynamic_array_get_count(&src->indexes));
105 if (!new_path) {
106 ret = -1;
107 } else {
108 ret = 0;
109 *dst = new_path;
110 }
111
112 return ret;
113}
114
115ssize_t lttng_action_path_create_from_payload(struct lttng_payload_view *view,
116 struct lttng_action_path **_action_path)
117{
118 ssize_t consumed_size = 0, ret = -1;
119 const struct lttng_action_path_comm *header;
120 struct lttng_action_path *action_path = NULL;
121 const struct lttng_payload_view header_view =
122 lttng_payload_view_from_view(view, 0, sizeof(*header));
123
124 if (!lttng_payload_view_is_valid(&header_view)) {
125 goto end;
126 }
127
128 header = (typeof(header)) header_view.buffer.data;
129 consumed_size += header_view.buffer.size;
130
131 /*
132 * An action path of size 0 can exist and represents a trigger with a
133 * single non-list action. Handle it differently since a payload view of
134 * size 0 is considered invalid.
135 */
136 if (header->index_count != 0) {
137 const struct lttng_payload_view indexes_view = lttng_payload_view_from_view(
138 view, consumed_size, header->index_count * sizeof(uint64_t));
139
140 if (!lttng_payload_view_is_valid(&indexes_view)) {
141 goto end;
142 }
143
144 consumed_size += indexes_view.buffer.size;
145 action_path = lttng_action_path_create((const uint64_t *) indexes_view.buffer.data,
146 header->index_count);
147 if (!action_path) {
148 goto end;
149 }
150 } else {
151 action_path = lttng_action_path_create(NULL, 0);
152 if (!action_path) {
153 goto end;
154 }
155 }
156
157 ret = consumed_size;
158 *_action_path = action_path;
159end:
160 return ret;
161}
162
163int lttng_action_path_serialize(const struct lttng_action_path *action_path,
164 struct lttng_payload *payload)
165{
166 int ret;
167 size_t index_count, i;
168 enum lttng_action_path_status status;
169 lttng_action_path_comm comm;
170
171 status = lttng_action_path_get_index_count(action_path, &index_count);
172 if (status != LTTNG_ACTION_PATH_STATUS_OK) {
173 ret = -1;
174 goto end;
175 }
176
177 comm.index_count = (uint32_t) index_count;
178 ret = lttng_dynamic_buffer_append(
179 &payload->buffer, &comm, sizeof(struct lttng_action_path_comm));
180
181 for (i = 0; i < index_count; i++) {
182 uint64_t path_index;
183
184 status = lttng_action_path_get_index_at_index(action_path, i, &path_index);
185 if (status != LTTNG_ACTION_PATH_STATUS_OK) {
186 ret = -1;
187 goto end;
188 }
189
190 ret = lttng_dynamic_buffer_append(
191 &payload->buffer, &path_index, sizeof(path_index));
192 if (ret) {
193 goto end;
194 }
195 }
196
197 ret = 0;
198end:
199 return ret;
200}
This page took 0.022445 seconds and 4 git commands to generate.