Commit | Line | Data |
---|---|---|
44e0a4f5 JG |
1 | /* |
2 | * attributes.c | |
3 | * | |
56e18c4c | 4 | * Babeltrace trace IR - Attributes |
44e0a4f5 JG |
5 | * |
6 | * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation | |
7 | * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com> | |
8 | * | |
9 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
10 | * of this software and associated documentation files (the "Software"), to deal | |
11 | * in the Software without restriction, including without limitation the rights | |
12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
13 | * copies of the Software, and to permit persons to whom the Software is | |
14 | * furnished to do so, subject to the following conditions: | |
15 | * | |
16 | * The above copyright notice and this permission notice shall be included in | |
17 | * all copies or substantial portions of the Software. | |
18 | * | |
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
25 | * SOFTWARE. | |
26 | */ | |
27 | ||
0f5e83e5 | 28 | #define BT_LOG_TAG "ATTRS" |
40547d22 | 29 | #include <babeltrace/lib-logging-internal.h> |
0f5e83e5 | 30 | |
65300d60 | 31 | #include <babeltrace/object.h> |
44e0a4f5 | 32 | #include <babeltrace/babeltrace-internal.h> |
dac5c838 | 33 | #include <babeltrace/values.h> |
da91b29a | 34 | #include <babeltrace/private-values.h> |
f6ccaed9 | 35 | #include <babeltrace/values-internal.h> |
561ad8c1 | 36 | #include <inttypes.h> |
ee389f01 | 37 | #include <babeltrace/compat/string-internal.h> |
f6ccaed9 | 38 | #include <babeltrace/assert-internal.h> |
44e0a4f5 | 39 | |
50842bdc PP |
40 | #define BT_ATTR_NAME_INDEX 0 |
41 | #define BT_ATTR_VALUE_INDEX 1 | |
44e0a4f5 JG |
42 | |
43 | BT_HIDDEN | |
da91b29a | 44 | struct bt_private_value *bt_attributes_create(void) |
44e0a4f5 | 45 | { |
da91b29a | 46 | struct bt_private_value *attr_obj; |
561ad8c1 | 47 | |
44e0a4f5 | 48 | /* |
dac5c838 PP |
49 | * Attributes: array value object of array value objects, each one |
50 | * containing two entries: a string value object (attributes | |
51 | * field name), and a value object (attributes field value). | |
44e0a4f5 JG |
52 | * |
53 | * Example (JSON representation): | |
54 | * | |
55 | * [ | |
56 | * ["hostname", "eeppdesk"], | |
57 | * ["sysname", "Linux"], | |
58 | * ["tracer_major", 2], | |
59 | * ["tracer_minor", 5] | |
60 | * ] | |
61 | */ | |
561ad8c1 | 62 | BT_LOGD_STR("Creating attributes object."); |
da91b29a | 63 | attr_obj = bt_private_value_array_create(); |
561ad8c1 PP |
64 | if (!attr_obj) { |
65 | BT_LOGE_STR("Failed to create array value."); | |
66 | } else { | |
67 | BT_LOGD("Created attributes object: addr=%p", | |
68 | attr_obj); | |
69 | } | |
70 | ||
71 | return attr_obj; | |
44e0a4f5 JG |
72 | } |
73 | ||
74 | BT_HIDDEN | |
da91b29a | 75 | void bt_attributes_destroy(struct bt_private_value *attr_obj) |
44e0a4f5 | 76 | { |
561ad8c1 | 77 | BT_LOGD("Destroying attributes object: addr=%p", attr_obj); |
65300d60 | 78 | bt_object_put_ref(attr_obj); |
44e0a4f5 JG |
79 | } |
80 | ||
81 | BT_HIDDEN | |
da91b29a | 82 | int64_t bt_attributes_get_count(struct bt_private_value *attr_obj) |
44e0a4f5 | 83 | { |
da91b29a | 84 | return bt_value_array_get_size(bt_value_borrow_from_private(attr_obj)); |
44e0a4f5 JG |
85 | } |
86 | ||
87 | BT_HIDDEN | |
da91b29a | 88 | const char *bt_attributes_get_field_name(struct bt_private_value *attr_obj, |
dcf0cc71 | 89 | uint64_t index) |
44e0a4f5 | 90 | { |
44e0a4f5 | 91 | const char *ret = NULL; |
da91b29a PP |
92 | struct bt_private_value *attr_field_obj = NULL; |
93 | struct bt_private_value *attr_field_name_obj = NULL; | |
44e0a4f5 | 94 | |
561ad8c1 PP |
95 | if (!attr_obj) { |
96 | BT_LOGW_STR("Invalid parameter: attributes object is NULL."); | |
44e0a4f5 JG |
97 | goto end; |
98 | } | |
99 | ||
da91b29a PP |
100 | if (index >= bt_value_array_get_size( |
101 | bt_value_borrow_from_private(attr_obj))) { | |
f6ccaed9 PP |
102 | BT_LOGW("Invalid parameter: index is out of bounds: " |
103 | "index=%" PRIu64 ", count=%" PRId64, | |
da91b29a PP |
104 | index, bt_value_array_get_size( |
105 | bt_value_borrow_from_private(attr_obj))); | |
f6ccaed9 PP |
106 | goto end; |
107 | } | |
108 | ||
da91b29a PP |
109 | attr_field_obj = bt_private_value_array_borrow_element_by_index( |
110 | attr_obj, index); | |
44e0a4f5 | 111 | if (!attr_field_obj) { |
561ad8c1 PP |
112 | BT_LOGE("Cannot get attributes object's array value's element by index: " |
113 | "value-addr=%p, index=%" PRIu64, attr_obj, index); | |
44e0a4f5 JG |
114 | goto end; |
115 | } | |
116 | ||
da91b29a PP |
117 | attr_field_name_obj = |
118 | bt_private_value_array_borrow_element_by_index(attr_field_obj, | |
119 | BT_ATTR_NAME_INDEX); | |
44e0a4f5 | 120 | if (!attr_field_name_obj) { |
561ad8c1 PP |
121 | BT_LOGE("Cannot get attribute array value's element by index: " |
122 | "value-addr=%p, index=%" PRIu64, attr_field_obj, | |
50842bdc | 123 | (uint64_t) BT_ATTR_NAME_INDEX); |
44e0a4f5 JG |
124 | goto end; |
125 | } | |
126 | ||
601b0d3c PP |
127 | ret = bt_value_string_get( |
128 | bt_value_borrow_from_private(attr_field_name_obj)); | |
44e0a4f5 JG |
129 | |
130 | end: | |
44e0a4f5 JG |
131 | return ret; |
132 | } | |
133 | ||
134 | BT_HIDDEN | |
da91b29a PP |
135 | struct bt_private_value *bt_attributes_borrow_field_value( |
136 | struct bt_private_value *attr_obj, uint64_t index) | |
44e0a4f5 | 137 | { |
da91b29a PP |
138 | struct bt_private_value *value_obj = NULL; |
139 | struct bt_private_value *attr_field_obj = NULL; | |
44e0a4f5 | 140 | |
561ad8c1 PP |
141 | if (!attr_obj) { |
142 | BT_LOGW_STR("Invalid parameter: attributes object is NULL."); | |
44e0a4f5 JG |
143 | goto end; |
144 | } | |
145 | ||
da91b29a | 146 | if (index >= bt_value_array_get_size(bt_value_borrow_from_private(attr_obj))) { |
f6ccaed9 PP |
147 | BT_LOGW("Invalid parameter: index is out of bounds: " |
148 | "index=%" PRIu64 ", count=%" PRId64, | |
da91b29a PP |
149 | index, bt_value_array_get_size( |
150 | bt_value_borrow_from_private(attr_obj))); | |
f6ccaed9 PP |
151 | goto end; |
152 | } | |
153 | ||
da91b29a PP |
154 | attr_field_obj = |
155 | bt_private_value_array_borrow_element_by_index(attr_obj, index); | |
44e0a4f5 | 156 | if (!attr_field_obj) { |
561ad8c1 PP |
157 | BT_LOGE("Cannot get attributes object's array value's element by index: " |
158 | "value-addr=%p, index=%" PRIu64, attr_obj, index); | |
44e0a4f5 JG |
159 | goto end; |
160 | } | |
161 | ||
da91b29a PP |
162 | value_obj = bt_private_value_array_borrow_element_by_index( |
163 | attr_field_obj, BT_ATTR_VALUE_INDEX); | |
561ad8c1 PP |
164 | if (!value_obj) { |
165 | BT_LOGE("Cannot get attribute array value's element by index: " | |
166 | "value-addr=%p, index=%" PRIu64, attr_field_obj, | |
50842bdc | 167 | (uint64_t) BT_ATTR_VALUE_INDEX); |
561ad8c1 | 168 | } |
44e0a4f5 JG |
169 | |
170 | end: | |
44e0a4f5 JG |
171 | return value_obj; |
172 | } | |
173 | ||
174 | static | |
da91b29a PP |
175 | struct bt_private_value *bt_attributes_borrow_field_by_name( |
176 | struct bt_private_value *attr_obj, const char *name) | |
44e0a4f5 | 177 | { |
dcf0cc71 PP |
178 | uint64_t i; |
179 | int64_t attr_size; | |
da91b29a PP |
180 | struct bt_private_value *value_obj = NULL; |
181 | struct bt_private_value *attr_field_name_obj = NULL; | |
44e0a4f5 | 182 | |
da91b29a PP |
183 | attr_size = bt_value_array_get_size( |
184 | bt_value_borrow_from_private(attr_obj)); | |
44e0a4f5 | 185 | if (attr_size < 0) { |
561ad8c1 PP |
186 | BT_LOGE("Cannot get array value's size: value-addr=%p", |
187 | attr_obj); | |
44e0a4f5 JG |
188 | goto error; |
189 | } | |
190 | ||
191 | for (i = 0; i < attr_size; ++i) { | |
44e0a4f5 JG |
192 | const char *field_name; |
193 | ||
da91b29a PP |
194 | value_obj = bt_private_value_array_borrow_element_by_index( |
195 | attr_obj, i); | |
44e0a4f5 | 196 | if (!value_obj) { |
561ad8c1 PP |
197 | BT_LOGE("Cannot get attributes object's array value's element by index: " |
198 | "value-addr=%p, index=%" PRIu64, attr_obj, i); | |
44e0a4f5 JG |
199 | goto error; |
200 | } | |
201 | ||
da91b29a PP |
202 | attr_field_name_obj = |
203 | bt_private_value_array_borrow_element_by_index( | |
204 | value_obj, BT_ATTR_NAME_INDEX); | |
44e0a4f5 | 205 | if (!attr_field_name_obj) { |
561ad8c1 PP |
206 | BT_LOGE("Cannot get attribute array value's element by index: " |
207 | "value-addr=%p, index=%" PRIu64, | |
094ff7c0 | 208 | value_obj, (int64_t) BT_ATTR_NAME_INDEX); |
44e0a4f5 JG |
209 | goto error; |
210 | } | |
211 | ||
601b0d3c PP |
212 | field_name = bt_value_string_get( |
213 | bt_value_borrow_from_private(attr_field_name_obj)); | |
44e0a4f5 JG |
214 | |
215 | if (!strcmp(field_name, name)) { | |
44e0a4f5 JG |
216 | break; |
217 | } | |
218 | ||
094ff7c0 | 219 | value_obj = NULL; |
44e0a4f5 JG |
220 | } |
221 | ||
222 | return value_obj; | |
223 | ||
224 | error: | |
094ff7c0 | 225 | value_obj = NULL; |
44e0a4f5 JG |
226 | return value_obj; |
227 | } | |
228 | ||
229 | BT_HIDDEN | |
da91b29a PP |
230 | int bt_attributes_set_field_value(struct bt_private_value *attr_obj, |
231 | const char *name, struct bt_private_value *value_obj) | |
44e0a4f5 JG |
232 | { |
233 | int ret = 0; | |
da91b29a | 234 | struct bt_private_value *attr_field_obj = NULL; |
44e0a4f5 JG |
235 | |
236 | if (!attr_obj || !name || !value_obj) { | |
561ad8c1 PP |
237 | BT_LOGW("Invalid parameter: attributes object, name, or value object is NULL: " |
238 | "attr-value-addr=%p, name-addr=%p, value-addr=%p", | |
239 | attr_obj, name, value_obj); | |
44e0a4f5 JG |
240 | ret = -1; |
241 | goto end; | |
242 | } | |
243 | ||
094ff7c0 | 244 | attr_field_obj = bt_attributes_borrow_field_by_name(attr_obj, name); |
44e0a4f5 | 245 | if (attr_field_obj) { |
da91b29a PP |
246 | ret = bt_private_value_array_set_element_by_index( |
247 | attr_field_obj, BT_ATTR_VALUE_INDEX, | |
248 | bt_value_borrow_from_private(value_obj)); | |
094ff7c0 | 249 | attr_field_obj = NULL; |
44e0a4f5 JG |
250 | goto end; |
251 | } | |
252 | ||
da91b29a | 253 | attr_field_obj = bt_private_value_array_create(); |
44e0a4f5 | 254 | if (!attr_field_obj) { |
561ad8c1 | 255 | BT_LOGE_STR("Failed to create empty array value."); |
44e0a4f5 JG |
256 | ret = -1; |
257 | goto end; | |
258 | } | |
259 | ||
da91b29a PP |
260 | ret = bt_private_value_array_append_string_element(attr_field_obj, |
261 | name); | |
262 | ret |= bt_private_value_array_append_element(attr_field_obj, | |
263 | bt_value_borrow_from_private(value_obj)); | |
44e0a4f5 | 264 | if (ret) { |
561ad8c1 PP |
265 | BT_LOGE("Cannot append elements to array value: addr=%p", |
266 | attr_field_obj); | |
44e0a4f5 JG |
267 | goto end; |
268 | } | |
269 | ||
da91b29a PP |
270 | ret = bt_private_value_array_append_element(attr_obj, |
271 | bt_value_borrow_from_private(attr_field_obj)); | |
561ad8c1 PP |
272 | if (ret) { |
273 | BT_LOGE("Cannot append element to array value: " | |
274 | "array-value-addr=%p, element-value-addr=%p", | |
275 | attr_obj, attr_field_obj); | |
276 | } | |
44e0a4f5 JG |
277 | |
278 | end: | |
65300d60 | 279 | bt_object_put_ref(attr_field_obj); |
44e0a4f5 JG |
280 | return ret; |
281 | } | |
282 | ||
283 | BT_HIDDEN | |
da91b29a PP |
284 | struct bt_private_value *bt_attributes_borrow_field_value_by_name( |
285 | struct bt_private_value *attr_obj, const char *name) | |
44e0a4f5 | 286 | { |
da91b29a PP |
287 | struct bt_private_value *value_obj = NULL; |
288 | struct bt_private_value *attr_field_obj = NULL; | |
44e0a4f5 JG |
289 | |
290 | if (!attr_obj || !name) { | |
561ad8c1 PP |
291 | BT_LOGW("Invalid parameter: attributes object or name is NULL: " |
292 | "value-addr=%p, name-addr=%p", attr_obj, name); | |
44e0a4f5 JG |
293 | goto end; |
294 | } | |
295 | ||
094ff7c0 | 296 | attr_field_obj = bt_attributes_borrow_field_by_name(attr_obj, name); |
44e0a4f5 | 297 | if (!attr_field_obj) { |
561ad8c1 PP |
298 | BT_LOGD("Cannot find attributes object's field by name: " |
299 | "value-addr=%p, name=\"%s\"", attr_obj, name); | |
44e0a4f5 JG |
300 | goto end; |
301 | } | |
302 | ||
da91b29a PP |
303 | value_obj = bt_private_value_array_borrow_element_by_index( |
304 | attr_field_obj, BT_ATTR_VALUE_INDEX); | |
561ad8c1 PP |
305 | if (!value_obj) { |
306 | BT_LOGE("Cannot get attribute array value's element by index: " | |
307 | "value-addr=%p, index=%" PRIu64, attr_field_obj, | |
50842bdc | 308 | (uint64_t) BT_ATTR_VALUE_INDEX); |
561ad8c1 | 309 | } |
44e0a4f5 JG |
310 | |
311 | end: | |
44e0a4f5 JG |
312 | return value_obj; |
313 | } | |
314 | ||
315 | BT_HIDDEN | |
da91b29a | 316 | int bt_attributes_freeze(struct bt_private_value *attr_obj) |
44e0a4f5 | 317 | { |
dcf0cc71 PP |
318 | uint64_t i; |
319 | int64_t count; | |
44e0a4f5 JG |
320 | int ret = 0; |
321 | ||
322 | if (!attr_obj) { | |
561ad8c1 | 323 | BT_LOGW_STR("Invalid parameter: attributes object is NULL."); |
44e0a4f5 JG |
324 | ret = -1; |
325 | goto end; | |
326 | } | |
327 | ||
561ad8c1 | 328 | BT_LOGD("Freezing attributes object: value-addr=%p", attr_obj); |
da91b29a | 329 | count = bt_value_array_get_size(bt_value_borrow_from_private(attr_obj)); |
f6ccaed9 | 330 | BT_ASSERT(count >= 0); |
44e0a4f5 JG |
331 | |
332 | /* | |
dac5c838 PP |
333 | * We do not freeze the array value object itself here, since |
334 | * internal stuff could need to modify/add attributes. Each | |
335 | * attribute is frozen one by one. | |
44e0a4f5 JG |
336 | */ |
337 | for (i = 0; i < count; ++i) { | |
da91b29a | 338 | struct bt_private_value *obj = NULL; |
44e0a4f5 | 339 | |
094ff7c0 | 340 | obj = bt_attributes_borrow_field_value(attr_obj, i); |
44e0a4f5 | 341 | if (!obj) { |
561ad8c1 PP |
342 | BT_LOGE("Cannot get attributes object's field value by index: " |
343 | "value-addr=%p, index=%" PRIu64, | |
344 | attr_obj, i); | |
44e0a4f5 JG |
345 | ret = -1; |
346 | goto end; | |
347 | } | |
348 | ||
da91b29a | 349 | bt_value_freeze(bt_value_borrow_from_private(obj)); |
44e0a4f5 JG |
350 | } |
351 | ||
352 | end: | |
44e0a4f5 JG |
353 | return ret; |
354 | } |