Visibility hidden by default
[babeltrace.git] / src / ctf-writer / attributes.c
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
5 * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
6 *
7 * Babeltrace CTF writer - Attributes
8 */
9
10 #define BT_LOG_TAG "CTF-WRITER/ATTRS"
11 #include "logging.h"
12
13 #include "attributes.h"
14
15 #include "common/assert.h"
16 #include "common/macros.h"
17 #include "compat/string.h"
18 #include <babeltrace2-ctf-writer/object.h>
19 #include <inttypes.h>
20
21 #include "values.h"
22
23 #define BT_CTF_ATTR_NAME_INDEX 0
24 #define BT_CTF_ATTR_VALUE_INDEX 1
25
26 struct bt_ctf_private_value *bt_ctf_attributes_create(void)
27 {
28 struct bt_ctf_private_value *attr_obj;
29
30 /*
31 * Attributes: array value object of array value objects, each one
32 * containing two entries: a string value object (attributes
33 * field name), and a value object (attributes field value).
34 *
35 * Example (JSON representation):
36 *
37 * [
38 * ["hostname", "eeppdesk"],
39 * ["sysname", "Linux"],
40 * ["tracer_major", 2],
41 * ["tracer_minor", 5]
42 * ]
43 */
44 BT_LOGD_STR("Creating attributes object.");
45 attr_obj = bt_ctf_private_value_array_create();
46 if (!attr_obj) {
47 BT_LOGE_STR("Failed to create array value.");
48 } else {
49 BT_LOGD("Created attributes object: addr=%p",
50 attr_obj);
51 }
52
53 return attr_obj;
54 }
55
56 void bt_ctf_attributes_destroy(struct bt_ctf_private_value *attr_obj)
57 {
58 BT_LOGD("Destroying attributes object: addr=%p", attr_obj);
59 bt_ctf_object_put_ref(attr_obj);
60 }
61
62 int64_t bt_ctf_attributes_get_count(struct bt_ctf_private_value *attr_obj)
63 {
64 return bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj));
65 }
66
67 const char *bt_ctf_attributes_get_field_name(struct bt_ctf_private_value *attr_obj,
68 uint64_t index)
69 {
70 const char *ret = NULL;
71 struct bt_ctf_private_value *attr_field_obj = NULL;
72 struct bt_ctf_private_value *attr_field_name_obj = NULL;
73
74 if (!attr_obj) {
75 BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
76 goto end;
77 }
78
79 if (index >= bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj))) {
80 BT_LOGW("Invalid parameter: index is out of bounds: "
81 "index=%" PRIu64 ", count=%" PRId64,
82 index, bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj)));
83 goto end;
84 }
85
86 attr_field_obj = bt_ctf_private_value_array_borrow_element_by_index(
87 attr_obj, index);
88 if (!attr_field_obj) {
89 BT_LOGE("Cannot get attributes object's array value's element by index: "
90 "value-addr=%p, index=%" PRIu64, attr_obj, index);
91 goto end;
92 }
93
94 attr_field_name_obj =
95 bt_ctf_private_value_array_borrow_element_by_index(
96 attr_field_obj, BT_CTF_ATTR_NAME_INDEX);
97 if (!attr_field_name_obj) {
98 BT_LOGE("Cannot get attribute array value's element by index: "
99 "value-addr=%p, index=%" PRIu64, attr_field_obj,
100 (uint64_t) BT_CTF_ATTR_NAME_INDEX);
101 goto end;
102 }
103
104 ret = bt_ctf_value_string_get(
105 bt_ctf_private_value_as_value(attr_field_name_obj));
106
107 end:
108 return ret;
109 }
110
111 struct bt_ctf_private_value *bt_ctf_attributes_borrow_field_value(struct bt_ctf_private_value *attr_obj,
112 uint64_t index)
113 {
114 struct bt_ctf_private_value *value_obj = NULL;
115 struct bt_ctf_private_value *attr_field_obj = NULL;
116
117 if (!attr_obj) {
118 BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
119 goto end;
120 }
121
122 if (index >= bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj))) {
123 BT_LOGW("Invalid parameter: index is out of bounds: "
124 "index=%" PRIu64 ", count=%" PRId64,
125 index, bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj)));
126 goto end;
127 }
128
129 attr_field_obj = bt_ctf_private_value_array_borrow_element_by_index(
130 attr_obj, index);
131 if (!attr_field_obj) {
132 BT_LOGE("Cannot get attributes object's array value's element by index: "
133 "value-addr=%p, index=%" PRIu64, attr_obj, index);
134 goto end;
135 }
136
137 value_obj = bt_ctf_private_value_array_borrow_element_by_index(attr_field_obj,
138 BT_CTF_ATTR_VALUE_INDEX);
139 if (!value_obj) {
140 BT_LOGE("Cannot get attribute array value's element by index: "
141 "value-addr=%p, index=%" PRIu64, attr_field_obj,
142 (uint64_t) BT_CTF_ATTR_VALUE_INDEX);
143 }
144
145 end:
146 return value_obj;
147 }
148
149 static
150 struct bt_ctf_private_value *bt_ctf_attributes_borrow_field_by_name(
151 struct bt_ctf_private_value *attr_obj, const char *name)
152 {
153 uint64_t i;
154 int64_t attr_size;
155 struct bt_ctf_private_value *value_obj = NULL;
156 struct bt_ctf_private_value *attr_field_name_obj = NULL;
157
158 attr_size = bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj));
159 if (attr_size < 0) {
160 BT_LOGE("Cannot get array value's size: value-addr=%p",
161 attr_obj);
162 goto error;
163 }
164
165 for (i = 0; i < attr_size; ++i) {
166 const char *field_name;
167
168 value_obj = bt_ctf_private_value_array_borrow_element_by_index(attr_obj, i);
169 if (!value_obj) {
170 BT_LOGE("Cannot get attributes object's array value's element by index: "
171 "value-addr=%p, index=%" PRIu64, attr_obj, i);
172 goto error;
173 }
174
175 attr_field_name_obj = bt_ctf_private_value_array_borrow_element_by_index(value_obj,
176 BT_CTF_ATTR_NAME_INDEX);
177 if (!attr_field_name_obj) {
178 BT_LOGE("Cannot get attribute array value's element by index: "
179 "value-addr=%p, index=%" PRIu64,
180 value_obj, (int64_t) BT_CTF_ATTR_NAME_INDEX);
181 goto error;
182 }
183
184 field_name = bt_ctf_value_string_get(
185 bt_ctf_private_value_as_value(attr_field_name_obj));
186
187 if (strcmp(field_name, name) == 0) {
188 break;
189 }
190
191 value_obj = NULL;
192 }
193
194 return value_obj;
195
196 error:
197 value_obj = NULL;
198 return value_obj;
199 }
200
201 int bt_ctf_attributes_set_field_value(struct bt_ctf_private_value *attr_obj,
202 const char *name, struct bt_ctf_private_value *value_obj)
203 {
204 int ret = 0;
205 struct bt_ctf_private_value *attr_field_obj = NULL;
206
207 if (!attr_obj || !name || !value_obj) {
208 BT_LOGW("Invalid parameter: attributes object, name, or value object is NULL: "
209 "attr-value-addr=%p, name-addr=%p, value-addr=%p",
210 attr_obj, name, value_obj);
211 ret = -1;
212 goto end;
213 }
214
215 attr_field_obj = bt_ctf_attributes_borrow_field_by_name(attr_obj, name);
216 if (attr_field_obj) {
217 ret = bt_ctf_private_value_array_set_element_by_index(
218 attr_field_obj, BT_CTF_ATTR_VALUE_INDEX,
219 bt_ctf_private_value_as_value(value_obj));
220 attr_field_obj = NULL;
221 goto end;
222 }
223
224 attr_field_obj = bt_ctf_private_value_array_create();
225 if (!attr_field_obj) {
226 BT_LOGE_STR("Failed to create empty array value.");
227 ret = -1;
228 goto end;
229 }
230
231 ret = bt_ctf_private_value_array_append_string_element(attr_field_obj, name);
232 ret |= bt_ctf_private_value_array_append_element(attr_field_obj,
233 bt_ctf_private_value_as_value(value_obj));
234 if (ret) {
235 BT_LOGE("Cannot append elements to array value: addr=%p",
236 attr_field_obj);
237 goto end;
238 }
239
240 ret = bt_ctf_private_value_array_append_element(attr_obj,
241 bt_ctf_private_value_as_value(attr_field_obj));
242 if (ret) {
243 BT_LOGE("Cannot append element to array value: "
244 "array-value-addr=%p, element-value-addr=%p",
245 attr_obj, attr_field_obj);
246 }
247
248 end:
249 bt_ctf_object_put_ref(attr_field_obj);
250 return ret;
251 }
252
253 struct bt_ctf_private_value *bt_ctf_attributes_borrow_field_value_by_name(
254 struct bt_ctf_private_value *attr_obj, const char *name)
255 {
256 struct bt_ctf_private_value *value_obj = NULL;
257 struct bt_ctf_private_value *attr_field_obj = NULL;
258
259 if (!attr_obj || !name) {
260 BT_LOGW("Invalid parameter: attributes object or name is NULL: "
261 "value-addr=%p, name-addr=%p", attr_obj, name);
262 goto end;
263 }
264
265 attr_field_obj = bt_ctf_attributes_borrow_field_by_name(attr_obj, name);
266 if (!attr_field_obj) {
267 BT_LOGD("Cannot find attributes object's field by name: "
268 "value-addr=%p, name=\"%s\"", attr_obj, name);
269 goto end;
270 }
271
272 value_obj = bt_ctf_private_value_array_borrow_element_by_index(attr_field_obj,
273 BT_CTF_ATTR_VALUE_INDEX);
274 if (!value_obj) {
275 BT_LOGE("Cannot get attribute array value's element by index: "
276 "value-addr=%p, index=%" PRIu64, attr_field_obj,
277 (uint64_t) BT_CTF_ATTR_VALUE_INDEX);
278 }
279
280 end:
281 return value_obj;
282 }
283
284 int bt_ctf_attributes_freeze(struct bt_ctf_private_value *attr_obj)
285 {
286 uint64_t i;
287 int64_t count;
288 int ret = 0;
289
290 if (!attr_obj) {
291 BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
292 ret = -1;
293 goto end;
294 }
295
296 BT_LOGD("Freezing attributes object: value-addr=%p", attr_obj);
297 count = bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj));
298 BT_ASSERT_DBG(count >= 0);
299
300 /*
301 * We do not freeze the array value object itself here, since
302 * internal stuff could need to modify/add attributes. Each
303 * attribute is frozen one by one.
304 */
305 for (i = 0; i < count; ++i) {
306 struct bt_ctf_private_value *obj = NULL;
307
308 obj = bt_ctf_attributes_borrow_field_value(attr_obj, i);
309 if (!obj) {
310 BT_LOGE("Cannot get attributes object's field value by index: "
311 "value-addr=%p, index=%" PRIu64,
312 attr_obj, i);
313 ret = -1;
314 goto end;
315 }
316
317 bt_ctf_value_freeze(bt_ctf_private_value_as_value(obj));
318 }
319
320 end:
321 return ret;
322 }
This page took 0.03615 seconds and 4 git commands to generate.