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