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 | ||
26 | BT_HIDDEN | |
e1e02a22 | 27 | struct bt_ctf_private_value *bt_ctf_attributes_create(void) |
16ca5ff0 | 28 | { |
e1e02a22 | 29 | struct bt_ctf_private_value *attr_obj; |
16ca5ff0 PP |
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."); | |
e1e02a22 | 46 | attr_obj = bt_ctf_private_value_array_create(); |
16ca5ff0 PP |
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 | |
e1e02a22 | 58 | void bt_ctf_attributes_destroy(struct bt_ctf_private_value *attr_obj) |
16ca5ff0 PP |
59 | { |
60 | BT_LOGD("Destroying attributes object: addr=%p", attr_obj); | |
e1e02a22 | 61 | bt_ctf_object_put_ref(attr_obj); |
16ca5ff0 PP |
62 | } |
63 | ||
64 | BT_HIDDEN | |
e1e02a22 | 65 | int64_t bt_ctf_attributes_get_count(struct bt_ctf_private_value *attr_obj) |
16ca5ff0 | 66 | { |
393729a6 | 67 | return bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj)); |
16ca5ff0 PP |
68 | } |
69 | ||
70 | BT_HIDDEN | |
e1e02a22 | 71 | const char *bt_ctf_attributes_get_field_name(struct bt_ctf_private_value *attr_obj, |
16ca5ff0 PP |
72 | uint64_t index) |
73 | { | |
16ca5ff0 | 74 | const char *ret = NULL; |
e1e02a22 PP |
75 | struct bt_ctf_private_value *attr_field_obj = NULL; |
76 | struct bt_ctf_private_value *attr_field_name_obj = NULL; | |
16ca5ff0 PP |
77 | |
78 | if (!attr_obj) { | |
79 | BT_LOGW_STR("Invalid parameter: attributes object is NULL."); | |
80 | goto end; | |
81 | } | |
82 | ||
393729a6 | 83 | if (index >= bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj))) { |
16ca5ff0 PP |
84 | BT_LOGW("Invalid parameter: index is out of bounds: " |
85 | "index=%" PRIu64 ", count=%" PRId64, | |
393729a6 | 86 | index, bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj))); |
16ca5ff0 PP |
87 | goto end; |
88 | } | |
89 | ||
e1e02a22 | 90 | attr_field_obj = bt_ctf_private_value_array_borrow_element_by_index( |
da91b29a | 91 | attr_obj, index); |
16ca5ff0 PP |
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 | ||
da91b29a | 98 | attr_field_name_obj = |
e1e02a22 | 99 | bt_ctf_private_value_array_borrow_element_by_index( |
da91b29a | 100 | attr_field_obj, BT_CTF_ATTR_NAME_INDEX); |
16ca5ff0 PP |
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 | ||
e1e02a22 PP |
108 | ret = bt_ctf_value_string_get( |
109 | bt_ctf_private_value_as_value(attr_field_name_obj)); | |
16ca5ff0 PP |
110 | |
111 | end: | |
112 | return ret; | |
113 | } | |
114 | ||
115 | BT_HIDDEN | |
e1e02a22 | 116 | struct bt_ctf_private_value *bt_ctf_attributes_borrow_field_value(struct bt_ctf_private_value *attr_obj, |
16ca5ff0 PP |
117 | uint64_t index) |
118 | { | |
e1e02a22 PP |
119 | struct bt_ctf_private_value *value_obj = NULL; |
120 | struct bt_ctf_private_value *attr_field_obj = NULL; | |
16ca5ff0 PP |
121 | |
122 | if (!attr_obj) { | |
123 | BT_LOGW_STR("Invalid parameter: attributes object is NULL."); | |
124 | goto end; | |
125 | } | |
126 | ||
393729a6 | 127 | if (index >= bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj))) { |
16ca5ff0 PP |
128 | BT_LOGW("Invalid parameter: index is out of bounds: " |
129 | "index=%" PRIu64 ", count=%" PRId64, | |
393729a6 | 130 | index, bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj))); |
16ca5ff0 PP |
131 | goto end; |
132 | } | |
133 | ||
e1e02a22 | 134 | attr_field_obj = bt_ctf_private_value_array_borrow_element_by_index( |
da91b29a | 135 | attr_obj, index); |
16ca5ff0 PP |
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 | ||
e1e02a22 | 142 | value_obj = bt_ctf_private_value_array_borrow_element_by_index(attr_field_obj, |
16ca5ff0 PP |
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 | |
e1e02a22 PP |
155 | struct bt_ctf_private_value *bt_ctf_attributes_borrow_field_by_name( |
156 | struct bt_ctf_private_value *attr_obj, const char *name) | |
16ca5ff0 PP |
157 | { |
158 | uint64_t i; | |
159 | int64_t attr_size; | |
e1e02a22 PP |
160 | struct bt_ctf_private_value *value_obj = NULL; |
161 | struct bt_ctf_private_value *attr_field_name_obj = NULL; | |
16ca5ff0 | 162 | |
393729a6 | 163 | attr_size = bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj)); |
16ca5ff0 PP |
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) { | |
16ca5ff0 PP |
171 | const char *field_name; |
172 | ||
e1e02a22 | 173 | value_obj = bt_ctf_private_value_array_borrow_element_by_index(attr_obj, i); |
16ca5ff0 PP |
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 | ||
e1e02a22 | 180 | attr_field_name_obj = bt_ctf_private_value_array_borrow_element_by_index(value_obj, |
16ca5ff0 PP |
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 | ||
e1e02a22 PP |
189 | field_name = bt_ctf_value_string_get( |
190 | bt_ctf_private_value_as_value(attr_field_name_obj)); | |
16ca5ff0 | 191 | |
2242b43d | 192 | if (strcmp(field_name, name) == 0) { |
16ca5ff0 PP |
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 | |
e1e02a22 PP |
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) | |
16ca5ff0 PP |
209 | { |
210 | int ret = 0; | |
e1e02a22 | 211 | struct bt_ctf_private_value *attr_field_obj = NULL; |
16ca5ff0 PP |
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) { | |
e1e02a22 | 223 | ret = bt_ctf_private_value_array_set_element_by_index( |
da91b29a | 224 | attr_field_obj, BT_CTF_ATTR_VALUE_INDEX, |
e1e02a22 | 225 | bt_ctf_private_value_as_value(value_obj)); |
16ca5ff0 PP |
226 | attr_field_obj = NULL; |
227 | goto end; | |
228 | } | |
229 | ||
e1e02a22 | 230 | attr_field_obj = bt_ctf_private_value_array_create(); |
16ca5ff0 PP |
231 | if (!attr_field_obj) { |
232 | BT_LOGE_STR("Failed to create empty array value."); | |
233 | ret = -1; | |
234 | goto end; | |
235 | } | |
236 | ||
e1e02a22 PP |
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)); | |
16ca5ff0 PP |
240 | if (ret) { |
241 | BT_LOGE("Cannot append elements to array value: addr=%p", | |
242 | attr_field_obj); | |
243 | goto end; | |
244 | } | |
245 | ||
e1e02a22 PP |
246 | ret = bt_ctf_private_value_array_append_element(attr_obj, |
247 | bt_ctf_private_value_as_value(attr_field_obj)); | |
16ca5ff0 PP |
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: | |
e1e02a22 | 255 | bt_ctf_object_put_ref(attr_field_obj); |
16ca5ff0 PP |
256 | return ret; |
257 | } | |
258 | ||
259 | BT_HIDDEN | |
e1e02a22 PP |
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) | |
16ca5ff0 | 262 | { |
e1e02a22 PP |
263 | struct bt_ctf_private_value *value_obj = NULL; |
264 | struct bt_ctf_private_value *attr_field_obj = NULL; | |
16ca5ff0 PP |
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 | ||
e1e02a22 | 279 | value_obj = bt_ctf_private_value_array_borrow_element_by_index(attr_field_obj, |
16ca5ff0 PP |
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 | |
e1e02a22 | 292 | int bt_ctf_attributes_freeze(struct bt_ctf_private_value *attr_obj) |
16ca5ff0 PP |
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); | |
393729a6 | 305 | count = bt_ctf_value_array_get_length(bt_ctf_private_value_as_value(attr_obj)); |
98b15851 | 306 | BT_ASSERT_DBG(count >= 0); |
16ca5ff0 PP |
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) { | |
e1e02a22 | 314 | struct bt_ctf_private_value *obj = NULL; |
16ca5ff0 PP |
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 | ||
e1e02a22 | 325 | bt_ctf_value_freeze(bt_ctf_private_value_as_value(obj)); |
16ca5ff0 PP |
326 | } |
327 | ||
328 | end: | |
329 | return ret; | |
330 | } |