Commit | Line | Data |
---|---|---|
04c0ba87 | 1 | /* |
0235b0db | 2 | * SPDX-License-Identifier: MIT |
04c0ba87 JG |
3 | * |
4 | * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
5 | * | |
0235b0db | 6 | * Babeltrace CTF file system Reader Component queries |
04c0ba87 JG |
7 | */ |
8 | ||
98903a3e PP |
9 | #define BT_LOG_OUTPUT_LEVEL log_level |
10 | #define BT_LOG_TAG "PLUGIN/SRC.CTF.FS/QUERY" | |
11 | #include "logging/log.h" | |
12 | ||
04c0ba87 JG |
13 | #include "query.h" |
14 | #include <stdbool.h> | |
493917ba SM |
15 | #include <glib.h> |
16 | #include <glib/gstdio.h> | |
17 | #include <fcntl.h> | |
18 | #include <sys/types.h> | |
19 | #include <sys/stat.h> | |
578e048b | 20 | #include "common/assert.h" |
04c0ba87 JG |
21 | #include "metadata.h" |
22 | #include "../common/metadata/decoder.h" | |
578e048b | 23 | #include "common/common.h" |
91d81473 | 24 | #include "common/macros.h" |
3fadfbc0 | 25 | #include <babeltrace2/babeltrace.h> |
97ade20b | 26 | #include "fs.h" |
d23b766e | 27 | #include "logging/comp-logging.h" |
55314f2a | 28 | |
04c0ba87 JG |
29 | #define METADATA_TEXT_SIG "/* CTF 1.8" |
30 | ||
97ade20b JG |
31 | struct range { |
32 | int64_t begin_ns; | |
33 | int64_t end_ns; | |
34 | bool set; | |
35 | }; | |
36 | ||
04c0ba87 | 37 | BT_HIDDEN |
d24d5663 | 38 | bt_component_class_query_method_status metadata_info_query( |
d23b766e | 39 | bt_self_component_class_source *self_comp_class_src, |
98903a3e | 40 | const bt_value *params, bt_logging_level log_level, |
b19ff26f | 41 | const bt_value **user_result) |
04c0ba87 | 42 | { |
d24d5663 PP |
43 | bt_component_class_query_method_status status = |
44 | BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; | |
d23b766e SM |
45 | bt_self_component_class *self_comp_class = |
46 | bt_self_component_class_source_as_self_component_class(self_comp_class_src); | |
b19ff26f PP |
47 | bt_value *result = NULL; |
48 | const bt_value *path_value = NULL; | |
04c0ba87 | 49 | FILE *metadata_fp = NULL; |
04c0ba87 JG |
50 | int ret; |
51 | int bo; | |
52 | const char *path; | |
53 | bool is_packetized; | |
06be9946 PP |
54 | struct ctf_metadata_decoder *decoder = NULL; |
55 | struct ctf_metadata_decoder_config decoder_cfg = { 0 }; | |
56 | enum ctf_metadata_decoder_status decoder_status; | |
04c0ba87 | 57 | |
05e21286 | 58 | result = bt_value_map_create(); |
da91b29a | 59 | if (!result) { |
d24d5663 | 60 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; |
04c0ba87 JG |
61 | goto error; |
62 | } | |
63 | ||
f6ccaed9 PP |
64 | BT_ASSERT(params); |
65 | ||
04c0ba87 | 66 | if (!bt_value_is_map(params)) { |
d23b766e SM |
67 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
68 | "Query parameters is not a map value object."); | |
a635e507 | 69 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
04c0ba87 JG |
70 | goto error; |
71 | } | |
72 | ||
05e21286 | 73 | path_value = bt_value_map_borrow_entry_value_const(params, "path"); |
07330b50 | 74 | if (!path_value) { |
d23b766e SM |
75 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
76 | "Mandatory `path` parameter missing"); | |
a635e507 | 77 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
07330b50 FD |
78 | goto error; |
79 | } | |
80 | ||
81 | if (!bt_value_is_string(path_value)) { | |
d23b766e SM |
82 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
83 | "`path` parameter is required to be a string value"); | |
a635e507 | 84 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
07330b50 FD |
85 | goto error; |
86 | } | |
87 | ||
601b0d3c | 88 | path = bt_value_string_get(path_value); |
04c0ba87 | 89 | |
f6ccaed9 | 90 | BT_ASSERT(path); |
04c0ba87 JG |
91 | metadata_fp = ctf_fs_metadata_open_file(path); |
92 | if (!metadata_fp) { | |
d23b766e SM |
93 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
94 | "Cannot open trace metadata: path=\"%s\".", path); | |
04c0ba87 JG |
95 | goto error; |
96 | } | |
97 | ||
06be9946 | 98 | ret = ctf_metadata_decoder_is_packetized(metadata_fp, &is_packetized, |
98903a3e | 99 | &bo, log_level, NULL); |
06be9946 PP |
100 | if (ret) { |
101 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, | |
102 | "Cannot check whether or not the metadata stream is packetized: path=\"%s\".", | |
103 | path); | |
104 | goto error; | |
04c0ba87 JG |
105 | } |
106 | ||
06be9946 | 107 | decoder_cfg.log_level = log_level; |
50f6fce8 | 108 | decoder_cfg.self_comp_class = self_comp_class; |
06be9946 PP |
109 | decoder_cfg.keep_plain_text = true; |
110 | decoder = ctf_metadata_decoder_create(&decoder_cfg); | |
111 | if (!decoder) { | |
112 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, | |
113 | "Cannot create metadata decoder: path=\"%s\".", path); | |
04c0ba87 JG |
114 | goto error; |
115 | } | |
116 | ||
06be9946 PP |
117 | rewind(metadata_fp); |
118 | decoder_status = ctf_metadata_decoder_append_content(decoder, | |
119 | metadata_fp); | |
120 | if (decoder_status) { | |
121 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, | |
122 | "Cannot update metadata decoder's content: path=\"%s\".", | |
123 | path); | |
124 | goto error; | |
04c0ba87 JG |
125 | } |
126 | ||
05e21286 | 127 | ret = bt_value_map_insert_string_entry(result, "text", |
06be9946 | 128 | ctf_metadata_decoder_get_text(decoder)); |
04c0ba87 | 129 | if (ret) { |
d23b766e SM |
130 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
131 | "Cannot insert metadata text into query result."); | |
04c0ba87 JG |
132 | goto error; |
133 | } | |
134 | ||
05e21286 | 135 | ret = bt_value_map_insert_bool_entry(result, "is-packetized", |
04c0ba87 JG |
136 | is_packetized); |
137 | if (ret) { | |
d23b766e SM |
138 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
139 | "Cannot insert \"is-packetized\" attribute into query result."); | |
04c0ba87 JG |
140 | goto error; |
141 | } | |
142 | ||
143 | goto end; | |
144 | ||
145 | error: | |
c5b9b441 | 146 | BT_VALUE_PUT_REF_AND_RESET(result); |
d94d92ac | 147 | result = NULL; |
c7eee084 | 148 | |
d94d92ac | 149 | if (status >= 0) { |
d24d5663 | 150 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
c7eee084 | 151 | } |
04c0ba87 JG |
152 | |
153 | end: | |
06be9946 | 154 | ctf_metadata_decoder_destroy(decoder); |
04c0ba87 JG |
155 | |
156 | if (metadata_fp) { | |
a8bd1d0f FD |
157 | ret = fclose(metadata_fp); |
158 | if (ret) { | |
159 | BT_LOGE_ERRNO("Cannot close metatada file stream", | |
160 | ": path=\"%s\"", path); | |
161 | } | |
04c0ba87 | 162 | } |
c7eee084 | 163 | |
05e21286 | 164 | *user_result = result; |
d94d92ac | 165 | return status; |
97ade20b | 166 | } |
9ec238a8 | 167 | |
97ade20b | 168 | static |
b19ff26f | 169 | int add_range(bt_value *info, struct range *range, |
97ade20b JG |
170 | const char *range_name) |
171 | { | |
172 | int ret = 0; | |
d24d5663 | 173 | bt_value_map_insert_entry_status status; |
760b266c | 174 | bt_value *range_map; |
97ade20b JG |
175 | |
176 | if (!range->set) { | |
177 | /* Not an error. */ | |
178 | goto end; | |
179 | } | |
180 | ||
760b266c SM |
181 | status = bt_value_map_insert_empty_map_entry(info, range_name, |
182 | &range_map); | |
183 | if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { | |
97ade20b JG |
184 | ret = -1; |
185 | goto end; | |
186 | } | |
187 | ||
fdd3a2da | 188 | status = bt_value_map_insert_signed_integer_entry(range_map, "begin", |
97ade20b | 189 | range->begin_ns); |
d24d5663 | 190 | if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { |
97ade20b JG |
191 | ret = -1; |
192 | goto end; | |
193 | } | |
194 | ||
fdd3a2da | 195 | status = bt_value_map_insert_signed_integer_entry(range_map, "end", |
97ade20b | 196 | range->end_ns); |
d24d5663 | 197 | if (status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { |
97ade20b JG |
198 | ret = -1; |
199 | goto end; | |
200 | } | |
201 | ||
97ade20b | 202 | end: |
97ade20b JG |
203 | return ret; |
204 | } | |
205 | ||
97ade20b JG |
206 | static |
207 | int populate_stream_info(struct ctf_fs_ds_file_group *group, | |
b19ff26f | 208 | bt_value *group_info, struct range *stream_range) |
97ade20b JG |
209 | { |
210 | int ret = 0; | |
d24d5663 | 211 | bt_value_map_insert_entry_status insert_status; |
b1c001b6 | 212 | struct ctf_fs_ds_index_entry *first_ds_index_entry, *last_ds_index_entry; |
a38d7650 | 213 | gchar *port_name = NULL; |
97ade20b | 214 | |
b1c001b6 | 215 | /* |
7ed5243a FD |
216 | * Since each `struct ctf_fs_ds_file_group` has a sorted array of |
217 | * `struct ctf_fs_ds_index_entry`, we can compute the stream range from | |
218 | * the timestamp_begin of the first index entry and the timestamp_end | |
219 | * of the last index entry. | |
b1c001b6 | 220 | */ |
7ed5243a FD |
221 | BT_ASSERT(group->index); |
222 | BT_ASSERT(group->index->entries); | |
223 | BT_ASSERT(group->index->entries->len > 0); | |
b1c001b6 | 224 | |
7ed5243a FD |
225 | /* First entry. */ |
226 | first_ds_index_entry = (struct ctf_fs_ds_index_entry *) g_ptr_array_index( | |
227 | group->index->entries, 0); | |
b1c001b6 | 228 | |
7ed5243a FD |
229 | /* Last entry. */ |
230 | last_ds_index_entry = (struct ctf_fs_ds_index_entry *) g_ptr_array_index( | |
231 | group->index->entries, group->index->entries->len - 1); | |
b1c001b6 FD |
232 | |
233 | stream_range->begin_ns = first_ds_index_entry->timestamp_begin_ns; | |
234 | stream_range->end_ns = last_ds_index_entry->timestamp_end_ns; | |
b1c001b6 | 235 | |
1d4ac4b6 FD |
236 | /* |
237 | * If any of the begin and end timestamps is not set it means that | |
238 | * packets don't include `timestamp_begin` _and_ `timestamp_end` fields | |
239 | * in their packet context so we can't set the range. | |
240 | */ | |
241 | stream_range->set = stream_range->begin_ns != UINT64_C(-1) && | |
242 | stream_range->end_ns != UINT64_C(-1); | |
243 | ||
244 | ret = add_range(group_info, stream_range, "range-ns"); | |
245 | if (ret) { | |
246 | goto end; | |
97ade20b JG |
247 | } |
248 | ||
a38d7650 SM |
249 | port_name = ctf_fs_make_port_name(group); |
250 | if (!port_name) { | |
251 | ret = -1; | |
252 | goto end; | |
253 | } | |
254 | ||
d24d5663 PP |
255 | insert_status = bt_value_map_insert_string_entry(group_info, |
256 | "port-name", port_name); | |
257 | if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { | |
a38d7650 SM |
258 | ret = -1; |
259 | goto end; | |
260 | } | |
261 | ||
97ade20b | 262 | end: |
19bbdc9b | 263 | g_free(port_name); |
97ade20b JG |
264 | return ret; |
265 | } | |
266 | ||
267 | static | |
064b8bc4 SM |
268 | int populate_trace_info(const struct ctf_fs_trace *trace, bt_value *trace_info, |
269 | bt_logging_level log_level, | |
270 | bt_self_component_class *self_comp_class) | |
97ade20b JG |
271 | { |
272 | int ret = 0; | |
273 | size_t group_idx; | |
d24d5663 PP |
274 | bt_value_map_insert_entry_status insert_status; |
275 | bt_value_array_append_element_status append_status; | |
f280892e | 276 | bt_value *file_groups = NULL; |
97ade20b | 277 | |
f280892e SM |
278 | BT_ASSERT(trace->ds_file_groups); |
279 | /* Add trace range info only if it contains streams. */ | |
280 | if (trace->ds_file_groups->len == 0) { | |
281 | ret = -1; | |
064b8bc4 SM |
282 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
283 | "Trace has no streams: trace-path=%s", trace->path->str); | |
f280892e SM |
284 | goto end; |
285 | } | |
286 | ||
760b266c | 287 | insert_status = bt_value_map_insert_empty_array_entry(trace_info, |
5f2a1585 | 288 | "stream-infos", &file_groups); |
760b266c SM |
289 | if (insert_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { |
290 | ret = -1; | |
97ade20b JG |
291 | goto end; |
292 | } | |
293 | ||
97ade20b JG |
294 | /* Find range of all stream groups, and of the trace. */ |
295 | for (group_idx = 0; group_idx < trace->ds_file_groups->len; | |
296 | group_idx++) { | |
b19ff26f | 297 | bt_value *group_info; |
97ade20b JG |
298 | struct range group_range = { .set = false }; |
299 | struct ctf_fs_ds_file_group *group = g_ptr_array_index( | |
300 | trace->ds_file_groups, group_idx); | |
301 | ||
760b266c SM |
302 | append_status = bt_value_array_append_empty_map_element( |
303 | file_groups, &group_info); | |
304 | if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { | |
97ade20b JG |
305 | ret = -1; |
306 | goto end; | |
307 | } | |
308 | ||
309 | ret = populate_stream_info(group, group_info, &group_range); | |
310 | if (ret) { | |
7233204d FD |
311 | goto end; |
312 | } | |
97ade20b JG |
313 | } |
314 | ||
97ade20b | 315 | end: |
97ade20b JG |
316 | return ret; |
317 | } | |
318 | ||
319 | BT_HIDDEN | |
5f2a1585 | 320 | bt_component_class_query_method_status trace_infos_query( |
d23b766e | 321 | bt_self_component_class_source *self_comp_class_src, |
98903a3e | 322 | const bt_value *params, bt_logging_level log_level, |
b19ff26f | 323 | const bt_value **user_result) |
97ade20b | 324 | { |
f280892e | 325 | struct ctf_fs_component *ctf_fs = NULL; |
d24d5663 PP |
326 | bt_component_class_query_method_status status = |
327 | BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; | |
d23b766e SM |
328 | bt_self_component_class *self_comp_class = |
329 | bt_self_component_class_source_as_self_component_class( | |
330 | self_comp_class_src); | |
b19ff26f | 331 | bt_value *result = NULL; |
73760435 | 332 | const bt_value *inputs_value = NULL; |
005d49d6 | 333 | const bt_value *trace_name_value; |
97ade20b | 334 | int ret = 0; |
a0cd55ad SM |
335 | bt_value *trace_info = NULL; |
336 | bt_value_array_append_element_status append_status; | |
97ade20b | 337 | |
f6ccaed9 PP |
338 | BT_ASSERT(params); |
339 | ||
97ade20b | 340 | if (!bt_value_is_map(params)) { |
d23b766e SM |
341 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, |
342 | "Query parameters is not a map value object."); | |
a635e507 | 343 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
97ade20b JG |
344 | goto error; |
345 | } | |
346 | ||
4c65a157 | 347 | ctf_fs = ctf_fs_component_create(log_level, NULL); |
d907165c | 348 | if (!ctf_fs) { |
97ade20b JG |
349 | goto error; |
350 | } | |
97ade20b | 351 | |
005d49d6 SM |
352 | if (!read_src_fs_parameters(params, &inputs_value, &trace_name_value, |
353 | ctf_fs, NULL, self_comp_class)) { | |
a635e507 | 354 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
97ade20b JG |
355 | goto error; |
356 | } | |
357 | ||
005d49d6 SM |
358 | if (ctf_fs_component_create_ctf_fs_trace(ctf_fs, inputs_value, |
359 | trace_name_value, NULL, self_comp_class)) { | |
97ade20b JG |
360 | goto error; |
361 | } | |
362 | ||
05e21286 | 363 | result = bt_value_array_create(); |
da91b29a | 364 | if (!result) { |
d24d5663 | 365 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; |
97ade20b JG |
366 | goto error; |
367 | } | |
368 | ||
a0cd55ad SM |
369 | append_status = bt_value_array_append_empty_map_element(result, |
370 | &trace_info); | |
371 | if (append_status != BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK) { | |
372 | BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, | |
373 | "Failed to create trace info map."); | |
374 | goto error; | |
375 | } | |
97ade20b | 376 | |
064b8bc4 SM |
377 | ret = populate_trace_info(ctf_fs->trace, trace_info, log_level, |
378 | self_comp_class); | |
a0cd55ad SM |
379 | if (ret) { |
380 | goto error; | |
97ade20b JG |
381 | } |
382 | ||
383 | goto end; | |
384 | ||
385 | error: | |
c5b9b441 | 386 | BT_VALUE_PUT_REF_AND_RESET(result); |
c7eee084 | 387 | |
d94d92ac | 388 | if (status >= 0) { |
d24d5663 | 389 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; |
c7eee084 PP |
390 | } |
391 | ||
97ade20b | 392 | end: |
f280892e SM |
393 | if (ctf_fs) { |
394 | ctf_fs_destroy(ctf_fs); | |
395 | ctf_fs = NULL; | |
97ade20b | 396 | } |
d94d92ac | 397 | |
05e21286 | 398 | *user_result = result; |
d94d92ac | 399 | return status; |
04c0ba87 | 400 | } |
73760435 SM |
401 | |
402 | BT_HIDDEN | |
403 | bt_component_class_query_method_status support_info_query( | |
404 | bt_self_component_class_source *comp_class, | |
405 | const bt_value *params, bt_logging_level log_level, | |
406 | const bt_value **user_result) | |
407 | { | |
408 | const bt_value *input_type_value; | |
409 | const char *input_type; | |
410 | bt_component_class_query_method_status status; | |
493917ba | 411 | bt_value_map_insert_entry_status insert_entry_status; |
73760435 SM |
412 | double weight = 0; |
413 | gchar *metadata_path = NULL; | |
414 | bt_value *result = NULL; | |
493917ba SM |
415 | struct ctf_metadata_decoder *metadata_decoder = NULL; |
416 | FILE *metadata_file = NULL; | |
417 | char uuid_str[BT_UUID_STR_LEN + 1]; | |
418 | bool has_uuid = false; | |
419 | const bt_value *input_value; | |
420 | const char *input; | |
73760435 SM |
421 | |
422 | input_type_value = bt_value_map_borrow_entry_value_const(params, "type"); | |
423 | BT_ASSERT(input_type_value); | |
424 | BT_ASSERT(bt_value_get_type(input_type_value) == BT_VALUE_TYPE_STRING); | |
425 | input_type = bt_value_string_get(input_type_value); | |
426 | ||
493917ba SM |
427 | if (strcmp(input_type, "directory") != 0) { |
428 | goto create_result; | |
429 | } | |
430 | ||
431 | input_value = bt_value_map_borrow_entry_value_const(params, "input"); | |
432 | BT_ASSERT(input_value); | |
433 | BT_ASSERT(bt_value_get_type(input_value) == BT_VALUE_TYPE_STRING); | |
434 | input = bt_value_string_get(input_value); | |
435 | ||
436 | metadata_path = g_build_filename(input, CTF_FS_METADATA_FILENAME, NULL); | |
437 | if (!metadata_path) { | |
73760435 SM |
438 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; |
439 | goto end; | |
440 | } | |
441 | ||
8c41c571 | 442 | metadata_file = g_fopen(metadata_path, "rb"); |
493917ba SM |
443 | if (metadata_file) { |
444 | struct ctf_metadata_decoder_config metadata_decoder_config = { 0 }; | |
445 | enum ctf_metadata_decoder_status decoder_status; | |
446 | bt_uuid_t uuid; | |
73760435 | 447 | |
493917ba | 448 | metadata_decoder_config.log_level = log_level; |
50f6fce8 SM |
449 | metadata_decoder_config.self_comp_class = |
450 | bt_self_component_class_source_as_self_component_class(comp_class); | |
73760435 | 451 | |
493917ba SM |
452 | metadata_decoder = ctf_metadata_decoder_create( |
453 | &metadata_decoder_config); | |
454 | if (!metadata_decoder) { | |
455 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; | |
456 | goto end; | |
457 | } | |
458 | ||
459 | decoder_status = ctf_metadata_decoder_append_content( | |
460 | metadata_decoder, metadata_file); | |
461 | if (decoder_status != CTF_METADATA_DECODER_STATUS_OK) { | |
462 | BT_LOGW("cannot append metadata content: metadata-decoder-status=%d", | |
463 | decoder_status); | |
464 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR; | |
73760435 SM |
465 | goto end; |
466 | } | |
467 | ||
468 | /* | |
493917ba SM |
469 | * We were able to parse the metadata file, so we are |
470 | * confident it's a CTF trace. | |
73760435 | 471 | */ |
493917ba SM |
472 | weight = 0.75; |
473 | ||
474 | /* If the trace has a UUID, return the stringified UUID as the group. */ | |
475 | if (ctf_metadata_decoder_get_trace_class_uuid(metadata_decoder, uuid) == 0) { | |
476 | bt_uuid_to_str(uuid, uuid_str); | |
477 | has_uuid = true; | |
73760435 SM |
478 | } |
479 | } | |
480 | ||
493917ba SM |
481 | create_result: |
482 | result = bt_value_map_create(); | |
483 | if (!result) { | |
73760435 SM |
484 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR; |
485 | goto end; | |
486 | } | |
487 | ||
493917ba SM |
488 | insert_entry_status = bt_value_map_insert_real_entry(result, "weight", weight); |
489 | if (insert_entry_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { | |
490 | status = (int) insert_entry_status; | |
73760435 SM |
491 | goto end; |
492 | } | |
493 | ||
493917ba SM |
494 | /* We are not supposed to have weight == 0 and a UUID. */ |
495 | BT_ASSERT(weight > 0 || !has_uuid); | |
496 | ||
497 | if (weight > 0 && has_uuid) { | |
498 | insert_entry_status = bt_value_map_insert_string_entry(result, "group", uuid_str); | |
499 | if (insert_entry_status != BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) { | |
500 | status = (int) insert_entry_status; | |
501 | goto end; | |
502 | } | |
503 | } | |
504 | ||
73760435 SM |
505 | *user_result = result; |
506 | result = NULL; | |
507 | status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK; | |
508 | ||
509 | end: | |
510 | g_free(metadata_path); | |
511 | bt_value_put_ref(result); | |
493917ba | 512 | ctf_metadata_decoder_destroy(metadata_decoder); |
73760435 SM |
513 | |
514 | return status; | |
515 | } |