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