Commit | Line | Data |
---|---|---|
16ca5ff0 | 1 | /* |
0235b0db | 2 | * SPDX-License-Identifier: MIT |
16ca5ff0 PP |
3 | * |
4 | * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation | |
5 | * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com> | |
6 | * | |
0235b0db | 7 | * Babeltrace CTF writer - Attributes |
16ca5ff0 PP |
8 | */ |
9 | ||
350ad6c1 | 10 | #define BT_LOG_TAG "CTF-WRITER/ATTRS" |
67d2ce02 | 11 | #include "logging.h" |
16ca5ff0 | 12 | |
7c7301d5 SM |
13 | #include "attributes.h" |
14 | ||
578e048b | 15 | #include "common/assert.h" |
91d81473 | 16 | #include "common/macros.h" |
578e048b | 17 | #include "compat/string.h" |
217cf9d3 | 18 | #include <babeltrace2-ctf-writer/object.h> |
16ca5ff0 PP |
19 | #include <inttypes.h> |
20 | ||
578e048b MJ |
21 | #include "values.h" |
22 | ||
16ca5ff0 PP |
23 | #define BT_CTF_ATTR_NAME_INDEX 0 |
24 | #define BT_CTF_ATTR_VALUE_INDEX 1 | |
25 | ||
e1e02a22 | 26 | struct bt_ctf_private_value *bt_ctf_attributes_create(void) |
16ca5ff0 | 27 | { |
e1e02a22 | 28 | struct bt_ctf_private_value *attr_obj; |
16ca5ff0 PP |
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."); | |
e1e02a22 | 45 | attr_obj = bt_ctf_private_value_array_create(); |
16ca5ff0 PP |
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 | ||
e1e02a22 | 56 | void bt_ctf_attributes_destroy(struct bt_ctf_private_value *attr_obj) |
16ca5ff0 PP |
57 | { |
58 | BT_LOGD("Destroying attributes object: addr=%p", attr_obj); | |
e1e02a22 | 59 | bt_ctf_object_put_ref(attr_obj); |
16ca5ff0 PP |
60 | } |
61 | ||
e1e02a22 | 62 | int64_t bt_ctf_attributes_get_count(struct bt_ctf_private_value *attr_obj) |
16ca5ff0 | 63 | { |
393729a6 | 64 | return bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj)); |
16ca5ff0 PP |
65 | } |
66 | ||
e1e02a22 | 67 | const char *bt_ctf_attributes_get_field_name(struct bt_ctf_private_value *attr_obj, |
16ca5ff0 PP |
68 | uint64_t index) |
69 | { | |
16ca5ff0 | 70 | const char *ret = NULL; |
e1e02a22 PP |
71 | struct bt_ctf_private_value *attr_field_obj = NULL; |
72 | struct bt_ctf_private_value *attr_field_name_obj = NULL; | |
16ca5ff0 PP |
73 | |
74 | if (!attr_obj) { | |
75 | BT_LOGW_STR("Invalid parameter: attributes object is NULL."); | |
76 | goto end; | |
77 | } | |
78 | ||
393729a6 | 79 | if (index >= bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj))) { |
16ca5ff0 PP |
80 | BT_LOGW("Invalid parameter: index is out of bounds: " |
81 | "index=%" PRIu64 ", count=%" PRId64, | |
393729a6 | 82 | index, bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj))); |
16ca5ff0 PP |
83 | goto end; |
84 | } | |
85 | ||
e1e02a22 | 86 | attr_field_obj = bt_ctf_private_value_array_borrow_element_by_index( |
da91b29a | 87 | attr_obj, index); |
16ca5ff0 PP |
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 | ||
da91b29a | 94 | attr_field_name_obj = |
e1e02a22 | 95 | bt_ctf_private_value_array_borrow_element_by_index( |
da91b29a | 96 | attr_field_obj, BT_CTF_ATTR_NAME_INDEX); |
16ca5ff0 PP |
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 | ||
e1e02a22 PP |
104 | ret = bt_ctf_value_string_get( |
105 | bt_ctf_private_value_as_value(attr_field_name_obj)); | |
16ca5ff0 PP |
106 | |
107 | end: | |
108 | return ret; | |
109 | } | |
110 | ||
e1e02a22 | 111 | struct bt_ctf_private_value *bt_ctf_attributes_borrow_field_value(struct bt_ctf_private_value *attr_obj, |
16ca5ff0 PP |
112 | uint64_t index) |
113 | { | |
e1e02a22 PP |
114 | struct bt_ctf_private_value *value_obj = NULL; |
115 | struct bt_ctf_private_value *attr_field_obj = NULL; | |
16ca5ff0 PP |
116 | |
117 | if (!attr_obj) { | |
118 | BT_LOGW_STR("Invalid parameter: attributes object is NULL."); | |
119 | goto end; | |
120 | } | |
121 | ||
393729a6 | 122 | if (index >= bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj))) { |
16ca5ff0 PP |
123 | BT_LOGW("Invalid parameter: index is out of bounds: " |
124 | "index=%" PRIu64 ", count=%" PRId64, | |
393729a6 | 125 | index, bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj))); |
16ca5ff0 PP |
126 | goto end; |
127 | } | |
128 | ||
e1e02a22 | 129 | attr_field_obj = bt_ctf_private_value_array_borrow_element_by_index( |
da91b29a | 130 | attr_obj, index); |
16ca5ff0 PP |
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 | ||
e1e02a22 | 137 | value_obj = bt_ctf_private_value_array_borrow_element_by_index(attr_field_obj, |
16ca5ff0 PP |
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 | |
e1e02a22 PP |
150 | struct bt_ctf_private_value *bt_ctf_attributes_borrow_field_by_name( |
151 | struct bt_ctf_private_value *attr_obj, const char *name) | |
16ca5ff0 PP |
152 | { |
153 | uint64_t i; | |
154 | int64_t attr_size; | |
e1e02a22 PP |
155 | struct bt_ctf_private_value *value_obj = NULL; |
156 | struct bt_ctf_private_value *attr_field_name_obj = NULL; | |
16ca5ff0 | 157 | |
393729a6 | 158 | attr_size = bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj)); |
16ca5ff0 PP |
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) { | |
16ca5ff0 PP |
166 | const char *field_name; |
167 | ||
e1e02a22 | 168 | value_obj = bt_ctf_private_value_array_borrow_element_by_index(attr_obj, i); |
16ca5ff0 PP |
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 | ||
e1e02a22 | 175 | attr_field_name_obj = bt_ctf_private_value_array_borrow_element_by_index(value_obj, |
16ca5ff0 PP |
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 | ||
e1e02a22 PP |
184 | field_name = bt_ctf_value_string_get( |
185 | bt_ctf_private_value_as_value(attr_field_name_obj)); | |
16ca5ff0 | 186 | |
2242b43d | 187 | if (strcmp(field_name, name) == 0) { |
16ca5ff0 PP |
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 | ||
e1e02a22 PP |
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) | |
16ca5ff0 PP |
203 | { |
204 | int ret = 0; | |
e1e02a22 | 205 | struct bt_ctf_private_value *attr_field_obj = NULL; |
16ca5ff0 PP |
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) { | |
e1e02a22 | 217 | ret = bt_ctf_private_value_array_set_element_by_index( |
da91b29a | 218 | attr_field_obj, BT_CTF_ATTR_VALUE_INDEX, |
e1e02a22 | 219 | bt_ctf_private_value_as_value(value_obj)); |
16ca5ff0 PP |
220 | attr_field_obj = NULL; |
221 | goto end; | |
222 | } | |
223 | ||
e1e02a22 | 224 | attr_field_obj = bt_ctf_private_value_array_create(); |
16ca5ff0 PP |
225 | if (!attr_field_obj) { |
226 | BT_LOGE_STR("Failed to create empty array value."); | |
227 | ret = -1; | |
228 | goto end; | |
229 | } | |
230 | ||
e1e02a22 PP |
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)); | |
16ca5ff0 PP |
234 | if (ret) { |
235 | BT_LOGE("Cannot append elements to array value: addr=%p", | |
236 | attr_field_obj); | |
237 | goto end; | |
238 | } | |
239 | ||
e1e02a22 PP |
240 | ret = bt_ctf_private_value_array_append_element(attr_obj, |
241 | bt_ctf_private_value_as_value(attr_field_obj)); | |
16ca5ff0 PP |
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: | |
e1e02a22 | 249 | bt_ctf_object_put_ref(attr_field_obj); |
16ca5ff0 PP |
250 | return ret; |
251 | } | |
252 | ||
e1e02a22 PP |
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) | |
16ca5ff0 | 255 | { |
e1e02a22 PP |
256 | struct bt_ctf_private_value *value_obj = NULL; |
257 | struct bt_ctf_private_value *attr_field_obj = NULL; | |
16ca5ff0 PP |
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 | ||
e1e02a22 | 272 | value_obj = bt_ctf_private_value_array_borrow_element_by_index(attr_field_obj, |
16ca5ff0 PP |
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 | ||
e1e02a22 | 284 | int bt_ctf_attributes_freeze(struct bt_ctf_private_value *attr_obj) |
16ca5ff0 PP |
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); | |
393729a6 | 297 | count = bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj)); |
98b15851 | 298 | BT_ASSERT_DBG(count >= 0); |
16ca5ff0 PP |
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) { | |
e1e02a22 | 306 | struct bt_ctf_private_value *obj = NULL; |
16ca5ff0 PP |
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 | ||
e1e02a22 | 317 | bt_ctf_value_freeze(bt_ctf_private_value_as_value(obj)); |
16ca5ff0 PP |
318 | } |
319 | ||
320 | end: | |
321 | return ret; | |
322 | } |