Commit | Line | Data |
---|---|---|
bc506aa5 JD |
1 | /* |
2 | * writer.c | |
3 | * | |
4 | * Babeltrace CTF Writer Output Plugin Event Handling | |
5 | * | |
6 | * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
7 | * | |
8 | * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
9 | * | |
10 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
11 | * of this software and associated documentation files (the "Software"), to deal | |
12 | * in the Software without restriction, including without limitation the rights | |
13 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
14 | * copies of the Software, and to permit persons to whom the Software is | |
15 | * furnished to do so, subject to the following conditions: | |
16 | * | |
17 | * The above copyright notice and this permission notice shall be included in | |
18 | * all copies or substantial portions of the Software. | |
19 | * | |
20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
25 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
26 | * SOFTWARE. | |
27 | */ | |
28 | ||
29 | #include <babeltrace/ctf-ir/event.h> | |
30 | #include <babeltrace/ctf-ir/packet.h> | |
31 | #include <babeltrace/ctf-ir/event-class.h> | |
32 | #include <babeltrace/ctf-ir/stream.h> | |
33 | #include <babeltrace/ctf-ir/stream-class.h> | |
34 | #include <babeltrace/ctf-ir/clock.h> | |
35 | #include <babeltrace/ctf-ir/fields.h> | |
36 | #include <babeltrace/ctf-writer/stream-class.h> | |
37 | #include <babeltrace/ctf-writer/stream.h> | |
38 | ||
39 | #include "writer.h" | |
40 | ||
41 | static | |
42 | void tmp_clock(struct bt_ctf_writer *writer, | |
43 | struct bt_ctf_stream_class *writer_stream_class, | |
44 | struct bt_ctf_clock *writer_clock) | |
45 | { | |
46 | const char *clock_description = "This is a test clock"; | |
47 | const uint64_t frequency = 1000000000ULL; | |
48 | const uint64_t offset_s = 1351530929945824323; | |
49 | const uint64_t precision = 10; | |
50 | const int is_absolute = 0xFF; | |
51 | ||
52 | bt_ctf_clock_set_description(writer_clock, clock_description); | |
53 | bt_ctf_clock_set_frequency(writer_clock, frequency); | |
54 | bt_ctf_clock_set_offset_s(writer_clock, offset_s); | |
55 | bt_ctf_clock_set_precision(writer_clock, precision); | |
56 | bt_ctf_clock_set_is_absolute(writer_clock, is_absolute); | |
57 | bt_ctf_writer_add_clock(writer, writer_clock); | |
58 | bt_ctf_stream_class_set_clock(writer_stream_class, writer_clock); | |
59 | } | |
60 | ||
61 | static | |
62 | enum bt_component_status copy_clock(FILE *err, struct bt_ctf_writer *writer, | |
63 | struct bt_ctf_stream_class *writer_stream_class, | |
64 | struct bt_ctf_clock *clock, | |
65 | struct bt_ctf_clock *writer_clock) | |
66 | { | |
67 | enum bt_component_status ret; | |
68 | int64_t offset, offset_s; | |
69 | int int_ret; | |
70 | uint64_t u64_ret; | |
71 | const char *name, *description; | |
72 | ||
73 | name = bt_ctf_clock_get_name(clock); | |
74 | if (!name) { | |
75 | ret = BT_COMPONENT_STATUS_ERROR; | |
76 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
77 | __LINE__); | |
78 | goto end; | |
79 | } | |
80 | ||
81 | writer_clock = bt_ctf_clock_create(name); | |
82 | if (!writer_clock) { | |
83 | ret = BT_COMPONENT_STATUS_ERROR; | |
84 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
85 | __LINE__); | |
86 | goto end; | |
87 | } | |
88 | ||
89 | description = bt_ctf_clock_get_description(clock); | |
90 | if (!description) { | |
91 | ret = BT_COMPONENT_STATUS_ERROR; | |
92 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
93 | __LINE__); | |
94 | goto end_destroy; | |
95 | } | |
96 | ||
97 | int_ret = bt_ctf_clock_set_description(writer_clock, | |
98 | description); | |
99 | if (int_ret != 0) { | |
100 | ret = BT_COMPONENT_STATUS_ERROR; | |
101 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
102 | __LINE__); | |
103 | goto end_destroy; | |
104 | } | |
105 | ||
106 | u64_ret = bt_ctf_clock_get_frequency(clock); | |
107 | if (u64_ret == -1ULL) { | |
108 | ret = BT_COMPONENT_STATUS_ERROR; | |
109 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
110 | __LINE__); | |
111 | goto end_destroy; | |
112 | } | |
113 | int_ret = bt_ctf_clock_set_frequency(writer_clock, u64_ret); | |
114 | if (int_ret != 0) { | |
115 | ret = BT_COMPONENT_STATUS_ERROR; | |
116 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
117 | __LINE__); | |
118 | goto end_destroy; | |
119 | } | |
120 | ||
121 | u64_ret = bt_ctf_clock_get_precision(clock); | |
122 | if (u64_ret == -1ULL) { | |
123 | ret = BT_COMPONENT_STATUS_ERROR; | |
124 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
125 | __LINE__); | |
126 | goto end_destroy; | |
127 | } | |
128 | int_ret = bt_ctf_clock_set_precision(writer_clock, u64_ret); | |
129 | if (int_ret != 0) { | |
130 | ret = BT_COMPONENT_STATUS_ERROR; | |
131 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
132 | __LINE__); | |
133 | goto end_destroy; | |
134 | } | |
135 | ||
136 | int_ret = bt_ctf_clock_get_offset_s(clock, &offset_s); | |
137 | if (int_ret != 0) { | |
138 | ret = BT_COMPONENT_STATUS_ERROR; | |
139 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
140 | __LINE__); | |
141 | goto end_destroy; | |
142 | } | |
143 | ||
144 | int_ret = bt_ctf_clock_set_offset_s(writer_clock, offset_s); | |
145 | if (int_ret != 0) { | |
146 | ret = BT_COMPONENT_STATUS_ERROR; | |
147 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
148 | __LINE__); | |
149 | goto end_destroy; | |
150 | } | |
151 | ||
152 | int_ret = bt_ctf_clock_get_offset(clock, &offset); | |
153 | if (int_ret != 0) { | |
154 | ret = BT_COMPONENT_STATUS_ERROR; | |
155 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
156 | __LINE__); | |
157 | goto end_destroy; | |
158 | } | |
159 | ||
160 | int_ret = bt_ctf_clock_set_offset(writer_clock, offset); | |
161 | if (int_ret != 0) { | |
162 | ret = BT_COMPONENT_STATUS_ERROR; | |
163 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
164 | __LINE__); | |
165 | goto end_destroy; | |
166 | } | |
167 | ||
168 | int_ret = bt_ctf_clock_get_is_absolute(clock); | |
169 | if (int_ret == -1) { | |
170 | ret = BT_COMPONENT_STATUS_ERROR; | |
171 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
172 | __LINE__); | |
173 | goto end_destroy; | |
174 | } | |
175 | int_ret = bt_ctf_clock_set_is_absolute(writer_clock, int_ret); | |
176 | if (int_ret != 0) { | |
177 | ret = BT_COMPONENT_STATUS_ERROR; | |
178 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
179 | __LINE__); | |
180 | goto end_destroy; | |
181 | } | |
182 | ||
183 | ret = bt_ctf_writer_add_clock(writer, writer_clock); | |
184 | if (ret != 0) { | |
185 | ret = BT_COMPONENT_STATUS_ERROR; | |
186 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
187 | __LINE__); | |
188 | goto end_destroy; | |
189 | } | |
190 | ||
191 | ret = bt_ctf_stream_class_set_clock(writer_stream_class, | |
192 | writer_clock); | |
193 | if (ret != 0) { | |
194 | ret = BT_COMPONENT_STATUS_ERROR; | |
195 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
196 | __LINE__); | |
197 | goto end_destroy; | |
198 | } | |
199 | /* | |
200 | * Ownership transferred to the writer and the stream_class. | |
201 | */ | |
202 | bt_put(writer_clock); | |
203 | ||
204 | ret = BT_COMPONENT_STATUS_OK; | |
205 | goto end; | |
206 | ||
207 | end_destroy: | |
208 | bt_put(writer_clock); | |
209 | end: | |
210 | return ret; | |
211 | } | |
212 | ||
213 | static | |
214 | struct bt_ctf_event_class *copy_event_class(FILE *err, struct bt_ctf_event_class *event_class) | |
215 | { | |
216 | struct bt_ctf_event_class *writer_event_class = NULL; | |
217 | const char *name; | |
218 | struct bt_ctf_field_type *context; | |
219 | int count, i, ret; | |
220 | ||
221 | name = bt_ctf_event_class_get_name(event_class); | |
222 | if (!name) { | |
223 | fprintf(err, "[error] %s in %s:%d\n", __func__, | |
224 | __FILE__, __LINE__); | |
225 | goto end; | |
226 | } | |
227 | ||
228 | writer_event_class = bt_ctf_event_class_create(name); | |
229 | if (!writer_event_class) { | |
230 | fprintf(err, "[error] %s in %s:%d\n", __func__, | |
231 | __FILE__, __LINE__); | |
232 | goto end; | |
233 | } | |
234 | ||
235 | count = bt_ctf_event_class_get_attribute_count(event_class); | |
236 | for (i = 0; i < count; i++) { | |
237 | const char *attr_name; | |
238 | struct bt_value *attr_value; | |
239 | int ret; | |
240 | ||
241 | attr_name = bt_ctf_event_class_get_attribute_name(event_class, i); | |
242 | if (!attr_name) { | |
243 | fprintf(err, "[error] %s in %s:%d\n", __func__, | |
244 | __FILE__, __LINE__); | |
245 | BT_PUT(writer_event_class); | |
246 | goto end; | |
247 | } | |
248 | attr_value = bt_ctf_event_class_get_attribute_value(event_class, i); | |
249 | if (!attr_value) { | |
250 | fprintf(err, "[error] %s in %s:%d\n", __func__, | |
251 | __FILE__, __LINE__); | |
252 | BT_PUT(writer_event_class); | |
253 | goto end; | |
254 | } | |
255 | ||
256 | ret = bt_ctf_event_class_set_attribute(writer_event_class, | |
257 | attr_name, attr_value); | |
258 | if (ret < 0) { | |
259 | fprintf(err, "[error] %s in %s:%d\n", __func__, | |
260 | __FILE__, __LINE__); | |
261 | BT_PUT(writer_event_class); | |
262 | goto end; | |
263 | } | |
264 | } | |
265 | ||
266 | context = bt_ctf_event_class_get_context_type(event_class); | |
267 | if (!context) { | |
268 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
269 | __LINE__); | |
270 | goto end; | |
271 | } | |
272 | ||
273 | ret = bt_ctf_event_class_set_context_type(writer_event_class, context); | |
274 | if (ret < 0) { | |
275 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
276 | __LINE__); | |
277 | goto end; | |
278 | } | |
279 | ||
280 | count = bt_ctf_event_class_get_field_count(event_class); | |
281 | for (i = 0; i < count; i++) { | |
282 | const char *field_name; | |
283 | struct bt_ctf_field_type *field_type; | |
284 | int ret; | |
285 | ||
286 | ret = bt_ctf_event_class_get_field(event_class, &field_name, | |
287 | &field_type, i); | |
288 | if (ret < 0) { | |
289 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); | |
290 | BT_PUT(writer_event_class); | |
291 | goto end; | |
292 | } | |
293 | ||
294 | ret = bt_ctf_event_class_add_field(writer_event_class, field_type, | |
295 | field_name); | |
296 | if (ret < 0) { | |
297 | fprintf(err, "[error] Cannot add field %s\n", field_name); | |
298 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); | |
299 | bt_put(field_type); | |
300 | BT_PUT(writer_event_class); | |
301 | goto end; | |
302 | } | |
303 | bt_put(field_type); | |
304 | } | |
305 | ||
306 | end: | |
307 | return writer_event_class; | |
308 | } | |
309 | ||
310 | static | |
311 | enum bt_component_status copy_event_classes(FILE *err, | |
312 | struct bt_ctf_writer *writer, | |
313 | struct bt_ctf_stream_class *stream_class, | |
314 | struct bt_ctf_stream_class *writer_stream_class) | |
315 | { | |
316 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
317 | int count, i; | |
318 | ||
319 | count = bt_ctf_stream_class_get_event_class_count(stream_class); | |
320 | if (count < 0) { | |
321 | fprintf(err, "[error] %s in %s:%d\n", __func__, | |
322 | __FILE__, __LINE__); | |
323 | goto end; | |
324 | } | |
325 | ||
326 | for (i = 0; i < count; i++) { | |
327 | struct bt_ctf_event_class *event_class, *writer_event_class; | |
328 | int int_ret; | |
329 | ||
330 | event_class = bt_ctf_stream_class_get_event_class( | |
331 | stream_class, i); | |
332 | if (!event_class) { | |
333 | fprintf(err, "[error] %s in %s:%d\n", __func__, | |
334 | __FILE__, __LINE__); | |
335 | ret = BT_COMPONENT_STATUS_ERROR; | |
336 | bt_put(event_class); | |
337 | goto end; | |
338 | } | |
339 | writer_event_class = copy_event_class(err, event_class); | |
340 | if (!writer_event_class) { | |
341 | fprintf(err, "[error] %s in %s:%d\n", __func__, | |
342 | __FILE__, __LINE__); | |
343 | ret = BT_COMPONENT_STATUS_ERROR; | |
344 | bt_put(event_class); | |
345 | goto end; | |
346 | } | |
347 | int_ret = bt_ctf_stream_class_add_event_class(writer_stream_class, | |
348 | writer_event_class); | |
349 | if (int_ret < 0) { | |
350 | fprintf(err, "[error] Failed to add event class\n"); | |
351 | fprintf(err, "[error] %s in %s:%d\n", __func__, | |
352 | __FILE__, __LINE__); | |
353 | ret = BT_COMPONENT_STATUS_ERROR; | |
354 | bt_put(event_class); | |
355 | goto end; | |
356 | } | |
357 | bt_put(event_class); | |
358 | } | |
359 | ||
360 | end: | |
361 | return ret; | |
362 | } | |
363 | ||
364 | static | |
365 | enum bt_component_status copy_stream_class(FILE *err, | |
366 | struct bt_ctf_writer *writer, | |
367 | struct bt_ctf_stream_class *stream_class, | |
368 | struct bt_ctf_stream_class *writer_stream_class) | |
369 | { | |
370 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
371 | struct bt_ctf_field_type *type; | |
372 | int ret_int; | |
373 | struct bt_ctf_clock *writer_clock; | |
374 | ||
375 | writer_clock = bt_ctf_clock_create("monotonic"); | |
376 | if (!writer_clock) { | |
377 | ret = BT_COMPONENT_STATUS_ERROR; | |
378 | fprintf(err, "[error] Failed to create clock\n"); | |
379 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
380 | __LINE__); | |
381 | goto end; | |
382 | } | |
383 | ||
384 | tmp_clock(writer, writer_stream_class, writer_clock); | |
385 | ||
386 | /* | |
387 | * FIXME: waiting for the clock to work | |
388 | * | |
389 | struct bt_ctf_clock *clock; | |
390 | clock = bt_ctf_stream_class_get_clock(stream_class); | |
391 | if (!clock) { | |
392 | ret = BT_COMPONENT_STATUS_ERROR; | |
393 | goto end; | |
394 | } | |
395 | ret = copy_clock(err, writer, writer_stream_class, clock, writer_clock); | |
396 | if (ret != BT_COMPONENT_STATUS_OK) { | |
397 | goto end_put_clock; | |
398 | } | |
399 | */ | |
400 | ||
401 | type = bt_ctf_stream_class_get_packet_context_type(stream_class); | |
402 | if (!type) { | |
403 | ret = BT_COMPONENT_STATUS_ERROR; | |
404 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
405 | __LINE__); | |
406 | goto end_put_clock; | |
407 | } | |
408 | ||
409 | ret_int = bt_ctf_stream_class_set_packet_context_type( | |
410 | writer_stream_class, type); | |
411 | if (ret_int < 0) { | |
412 | ret = BT_COMPONENT_STATUS_ERROR; | |
413 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
414 | __LINE__); | |
415 | goto end_put_clock; | |
416 | } | |
417 | ||
418 | type = bt_ctf_stream_class_get_event_header_type(stream_class); | |
419 | if (!type) { | |
420 | ret = BT_COMPONENT_STATUS_ERROR; | |
421 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
422 | __LINE__); | |
423 | goto end_put_clock; | |
424 | } | |
425 | ||
426 | ret_int = bt_ctf_stream_class_set_event_header_type( | |
427 | writer_stream_class, type); | |
428 | if (ret_int < 0) { | |
429 | ret = BT_COMPONENT_STATUS_ERROR; | |
430 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
431 | __LINE__); | |
432 | goto end_put_clock; | |
433 | } | |
434 | ||
435 | type = bt_ctf_stream_class_get_event_context_type(stream_class); | |
436 | if (!type) { | |
437 | ret = BT_COMPONENT_STATUS_ERROR; | |
438 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
439 | __LINE__); | |
440 | goto end_put_clock; | |
441 | } | |
442 | ||
443 | ret_int = bt_ctf_stream_class_set_event_context_type( | |
444 | writer_stream_class, type); | |
445 | if (ret_int < 0) { | |
446 | ret = BT_COMPONENT_STATUS_ERROR; | |
447 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
448 | __LINE__); | |
449 | goto end_put_clock; | |
450 | } | |
451 | ||
452 | ret = copy_event_classes(err, writer, stream_class, writer_stream_class); | |
453 | if (ret != BT_COMPONENT_STATUS_OK) { | |
454 | fprintf(err, "[error] Failed to copy event classes\n"); | |
455 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
456 | __LINE__); | |
457 | goto end_put_clock; | |
458 | } | |
459 | ||
460 | end_put_clock: | |
461 | // bt_put(clock); | |
462 | end: | |
463 | return ret; | |
464 | } | |
465 | ||
466 | static | |
467 | enum bt_component_status copy_trace(FILE *err, struct bt_ctf_writer *ctf_writer, | |
468 | struct bt_ctf_trace *trace) | |
469 | { | |
470 | struct bt_ctf_trace *writer_trace; | |
471 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
472 | int field_count, i, int_ret; | |
473 | struct bt_ctf_field_type *header_type; | |
474 | ||
475 | writer_trace = bt_ctf_writer_get_trace(ctf_writer); | |
476 | if (!writer_trace) { | |
477 | ret = BT_COMPONENT_STATUS_ERROR; | |
478 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
479 | __LINE__); | |
480 | goto end; | |
481 | } | |
482 | ||
483 | field_count = bt_ctf_trace_get_environment_field_count(trace); | |
484 | for (i = 0; i < field_count; i++) { | |
485 | int ret_int; | |
486 | const char *name; | |
487 | struct bt_value *value; | |
488 | ||
489 | name = bt_ctf_trace_get_environment_field_name(trace, i); | |
490 | if (!name) { | |
491 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
492 | __LINE__); | |
493 | ret = BT_COMPONENT_STATUS_ERROR; | |
494 | goto end_put_writer_trace; | |
495 | } | |
496 | value = bt_ctf_trace_get_environment_field_value(trace, i); | |
497 | if (!value) { | |
498 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
499 | __LINE__); | |
500 | ret = BT_COMPONENT_STATUS_ERROR; | |
501 | goto end_put_writer_trace; | |
502 | } | |
503 | ||
504 | ret_int = bt_ctf_trace_set_environment_field(writer_trace, | |
505 | name, value); | |
506 | if (ret_int < 0) { | |
507 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
508 | __LINE__); | |
509 | fprintf(err, "[error] Unable to set environment field %s\n", | |
510 | name); | |
511 | ret = BT_COMPONENT_STATUS_ERROR; | |
512 | goto end_put_writer_trace; | |
513 | } | |
514 | } | |
515 | ||
516 | header_type = bt_ctf_trace_get_packet_header_type(writer_trace); | |
517 | if (!header_type) { | |
518 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); | |
519 | ret = BT_COMPONENT_STATUS_ERROR; | |
520 | goto end_put_writer_trace; | |
521 | } | |
522 | ||
523 | int_ret = bt_ctf_trace_set_packet_header_type(writer_trace, header_type); | |
524 | if (int_ret < 0) { | |
525 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); | |
526 | ret = BT_COMPONENT_STATUS_ERROR; | |
527 | goto end_put_header_type; | |
528 | } | |
529 | ||
530 | end_put_header_type: | |
531 | bt_put(header_type); | |
532 | end_put_writer_trace: | |
533 | bt_put(writer_trace); | |
534 | end: | |
535 | return ret; | |
536 | } | |
537 | ||
538 | static | |
539 | struct bt_ctf_stream_class *insert_new_stream_class( | |
540 | struct writer_component *writer_component, | |
541 | struct bt_ctf_writer *ctf_writer, | |
542 | struct bt_ctf_stream_class *stream_class) | |
543 | { | |
544 | struct bt_ctf_stream_class *writer_stream_class; | |
545 | const char *name = bt_ctf_stream_class_get_name(stream_class); | |
546 | enum bt_component_status ret; | |
547 | ||
548 | if (strlen(name) == 0) { | |
549 | name = NULL; | |
550 | } | |
551 | ||
552 | writer_stream_class = bt_ctf_stream_class_create(name); | |
553 | if (!writer_stream_class) { | |
554 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
555 | __func__, __FILE__, __LINE__); | |
556 | goto end; | |
557 | } | |
558 | ||
559 | ret = copy_stream_class(writer_component->err, | |
560 | ctf_writer, stream_class, writer_stream_class); | |
561 | if (ret != BT_COMPONENT_STATUS_OK) { | |
562 | fprintf(writer_component->err, "[error] Failed to copy stream class\n"); | |
563 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
564 | __func__, __FILE__, __LINE__); | |
565 | BT_PUT(writer_stream_class); | |
566 | goto end; | |
567 | } | |
568 | g_hash_table_insert(writer_component->stream_class_map, | |
569 | (gpointer) stream_class, writer_stream_class); | |
570 | ||
571 | end: | |
572 | return writer_stream_class; | |
573 | } | |
574 | ||
575 | static | |
576 | struct bt_ctf_stream *insert_new_stream( | |
577 | struct writer_component *writer_component, | |
578 | struct bt_ctf_writer *ctf_writer, | |
579 | struct bt_ctf_stream_class *stream_class, | |
580 | struct bt_ctf_stream *stream) | |
581 | { | |
582 | struct bt_ctf_stream *writer_stream; | |
583 | struct bt_ctf_stream_class *writer_stream_class; | |
584 | ||
585 | writer_stream_class = g_hash_table_lookup( | |
586 | writer_component->stream_class_map, | |
587 | (gpointer) stream_class); | |
588 | if (writer_stream_class) { | |
589 | if (!bt_get(writer_stream_class)) { | |
590 | writer_stream = NULL; | |
591 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
592 | __func__, __FILE__, __LINE__); | |
593 | goto end; | |
594 | } | |
595 | } else { | |
596 | writer_stream_class = insert_new_stream_class( | |
597 | writer_component, ctf_writer, stream_class); | |
598 | if (!writer_stream_class) { | |
599 | writer_stream = NULL; | |
600 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
601 | __func__, __FILE__, __LINE__); | |
602 | goto end_put; | |
603 | } | |
604 | } | |
605 | ||
606 | writer_stream = bt_ctf_writer_create_stream(ctf_writer, | |
607 | writer_stream_class); | |
608 | if (!writer_stream) { | |
609 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
610 | __func__, __FILE__, __LINE__); | |
611 | goto end_put; | |
612 | } | |
613 | ||
614 | g_hash_table_insert(writer_component->stream_map, (gpointer) stream, | |
615 | writer_stream); | |
616 | ||
617 | bt_ctf_writer_flush_metadata(ctf_writer); | |
618 | ||
619 | end_put: | |
620 | bt_put(writer_stream_class); | |
621 | end: | |
622 | return writer_stream; | |
623 | } | |
624 | ||
625 | static | |
626 | struct bt_ctf_stream *lookup_stream(struct writer_component *writer_component, | |
627 | struct bt_ctf_stream *stream) | |
628 | { | |
629 | return (struct bt_ctf_stream *) g_hash_table_lookup( | |
630 | writer_component->stream_map, | |
631 | (gpointer) stream); | |
632 | } | |
633 | ||
634 | static | |
635 | struct bt_ctf_event_class *get_event_class(struct writer_component *writer_component, | |
636 | struct bt_ctf_stream_class *writer_stream_class, | |
637 | struct bt_ctf_event_class *event_class) | |
638 | { | |
639 | return bt_ctf_stream_class_get_event_class_by_name(writer_stream_class, | |
640 | bt_ctf_event_class_get_name(event_class)); | |
641 | } | |
642 | ||
643 | struct bt_ctf_writer *insert_new_writer( | |
644 | struct writer_component *writer_component, | |
645 | struct bt_ctf_trace *trace) | |
646 | { | |
647 | struct bt_ctf_writer *ctf_writer; | |
648 | char trace_name[PATH_MAX]; | |
649 | enum bt_component_status ret; | |
650 | ||
651 | snprintf(trace_name, PATH_MAX, "%s/%s_%03d", | |
9057f037 JD |
652 | writer_component->base_path->str, |
653 | writer_component->trace_name_base->str, | |
bc506aa5 JD |
654 | writer_component->trace_id++); |
655 | printf_verbose("CTF-Writer creating trace in %s\n", trace_name); | |
9057f037 | 656 | |
bc506aa5 JD |
657 | ctf_writer = bt_ctf_writer_create(trace_name); |
658 | if (!ctf_writer) { | |
659 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
660 | __func__, __FILE__, __LINE__); | |
661 | goto end; | |
662 | } | |
663 | ||
664 | ret = copy_trace(writer_component->err, ctf_writer, trace); | |
665 | if (ret != BT_COMPONENT_STATUS_OK) { | |
666 | fprintf(writer_component->err, "[error] Failed to copy trace\n"); | |
667 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
668 | __func__, __FILE__, __LINE__); | |
669 | BT_PUT(ctf_writer); | |
670 | goto end; | |
671 | } | |
672 | ||
673 | g_hash_table_insert(writer_component->trace_map, (gpointer) trace, | |
674 | ctf_writer); | |
675 | ||
676 | end: | |
677 | return ctf_writer; | |
678 | } | |
679 | ||
680 | static | |
681 | struct bt_ctf_writer *get_writer(struct writer_component *writer_component, | |
682 | struct bt_ctf_stream_class *stream_class) | |
683 | { | |
684 | struct bt_ctf_trace *trace; | |
685 | struct bt_ctf_writer *ctf_writer; | |
686 | ||
687 | trace = bt_ctf_stream_class_get_trace(stream_class); | |
688 | if (!trace) { | |
689 | ctf_writer = NULL; | |
690 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
691 | __func__, __FILE__, __LINE__); | |
692 | goto end; | |
693 | } | |
694 | ||
695 | ctf_writer = g_hash_table_lookup(writer_component->trace_map, | |
696 | (gpointer) trace); | |
697 | if (ctf_writer) { | |
698 | if (!bt_get(ctf_writer)) { | |
699 | ctf_writer = NULL; | |
700 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
701 | __func__, __FILE__, __LINE__); | |
702 | goto end; | |
703 | } | |
704 | } else { | |
705 | ctf_writer = insert_new_writer(writer_component, trace); | |
706 | } | |
707 | bt_put(trace); | |
708 | ||
709 | end: | |
710 | return ctf_writer; | |
711 | } | |
712 | ||
713 | static | |
714 | struct bt_ctf_stream *get_writer_stream( | |
715 | struct writer_component *writer_component, | |
716 | struct bt_ctf_packet *packet, struct bt_ctf_stream *stream) | |
717 | { | |
718 | struct bt_ctf_stream_class *stream_class; | |
719 | struct bt_ctf_writer *ctf_writer; | |
720 | struct bt_ctf_stream *writer_stream; | |
721 | ||
722 | stream_class = bt_ctf_stream_get_class(stream); | |
723 | if (!stream_class) { | |
724 | writer_stream = NULL; | |
725 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
726 | __func__, __FILE__, __LINE__); | |
727 | goto end; | |
728 | } | |
729 | ||
730 | ctf_writer = get_writer(writer_component, stream_class); | |
731 | if (!ctf_writer) { | |
732 | writer_stream = NULL; | |
733 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
734 | __func__, __FILE__, __LINE__); | |
735 | goto end_put_stream_class; | |
736 | } | |
737 | ||
738 | writer_stream = lookup_stream(writer_component, stream); | |
739 | ||
740 | if (writer_stream) { | |
741 | if (!bt_get(writer_stream)) { | |
742 | writer_stream = NULL; | |
743 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
744 | __func__, __FILE__, __LINE__); | |
745 | goto end_put_stream_class; | |
746 | } | |
747 | } else { | |
748 | writer_stream = insert_new_stream(writer_component, ctf_writer, | |
749 | stream_class, stream); | |
750 | } | |
751 | ||
752 | bt_put(ctf_writer); | |
753 | end_put_stream_class: | |
754 | bt_put(stream_class); | |
755 | end: | |
756 | return writer_stream; | |
757 | } | |
758 | ||
759 | BT_HIDDEN | |
760 | enum bt_component_status writer_new_packet( | |
761 | struct writer_component *writer_component, | |
762 | struct bt_ctf_packet *packet) | |
763 | { | |
764 | struct bt_ctf_stream *stream, *writer_stream; | |
765 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
766 | ||
767 | stream = bt_ctf_packet_get_stream(packet); | |
768 | if (!stream) { | |
769 | ret = BT_COMPONENT_STATUS_ERROR; | |
770 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
771 | __func__, __FILE__, __LINE__); | |
772 | goto end; | |
773 | } | |
774 | ||
775 | /* TODO: copy values for event discarded and packet_seq_num */ | |
776 | writer_stream = get_writer_stream(writer_component, packet, stream); | |
777 | if (!writer_stream) { | |
778 | ret = BT_COMPONENT_STATUS_ERROR; | |
779 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
780 | __func__, __FILE__, __LINE__); | |
781 | goto end_put; | |
782 | } | |
783 | ||
784 | bt_put(writer_stream); | |
785 | ||
786 | end_put: | |
787 | bt_put(stream); | |
788 | end: | |
789 | return ret; | |
790 | } | |
791 | ||
792 | static | |
793 | enum bt_component_status copy_packet_context_field(FILE *err, | |
794 | struct bt_ctf_field *field, const char *field_name, | |
795 | struct bt_ctf_field *writer_packet_context, | |
796 | struct bt_ctf_field_type *writer_packet_context_type) | |
797 | { | |
798 | enum bt_component_status ret; | |
799 | struct bt_ctf_field *writer_field; | |
800 | int int_ret; | |
801 | uint64_t value; | |
802 | ||
803 | /* | |
804 | * TODO: handle the special case of the first/last packet that might | |
805 | * be trimmed. In these cases, the timestamp_begin/end need to be | |
806 | * explicitely set to the first/last event timestamps. | |
807 | */ | |
808 | ||
809 | writer_field = bt_ctf_field_structure_get_field(writer_packet_context, | |
810 | field_name); | |
811 | if (!writer_field) { | |
812 | ret = BT_COMPONENT_STATUS_ERROR; | |
813 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
814 | __LINE__); | |
815 | goto end; | |
816 | } | |
817 | ||
818 | int_ret = bt_ctf_field_unsigned_integer_get_value(field, &value); | |
819 | if (int_ret < 0) { | |
820 | fprintf(err, "[error] Wrong packet_context field type\n"); | |
821 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
822 | __LINE__); | |
823 | ret = BT_COMPONENT_STATUS_ERROR; | |
824 | goto end_put_writer_field; | |
825 | } | |
826 | ||
827 | int_ret = bt_ctf_field_unsigned_integer_set_value(writer_field, value); | |
828 | if (int_ret < 0) { | |
829 | ret = BT_COMPONENT_STATUS_ERROR; | |
830 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
831 | __LINE__); | |
832 | goto end_put_writer_field; | |
833 | } | |
834 | ||
835 | ret = BT_COMPONENT_STATUS_OK; | |
836 | ||
837 | end_put_writer_field: | |
838 | bt_put(writer_field); | |
839 | end: | |
840 | return ret; | |
841 | } | |
842 | ||
843 | static | |
844 | enum bt_component_status copy_packet_context(FILE *err, | |
845 | struct bt_ctf_packet *packet, | |
846 | struct bt_ctf_stream *writer_stream) | |
847 | { | |
848 | enum bt_component_status ret; | |
849 | struct bt_ctf_field *packet_context, *writer_packet_context; | |
850 | struct bt_ctf_field_type *struct_type, *writer_packet_context_type; | |
851 | struct bt_ctf_stream_class *writer_stream_class; | |
852 | int nr_fields, i, int_ret; | |
853 | ||
854 | packet_context = bt_ctf_packet_get_context(packet); | |
855 | if (!packet_context) { | |
856 | ret = BT_COMPONENT_STATUS_ERROR; | |
857 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
858 | __LINE__); | |
859 | goto end; | |
860 | } | |
861 | ||
862 | writer_stream_class = bt_ctf_stream_get_class(writer_stream); | |
863 | if (!writer_stream_class) { | |
864 | ret = BT_COMPONENT_STATUS_ERROR; | |
865 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
866 | __LINE__); | |
867 | goto end_put_packet_context; | |
868 | } | |
869 | ||
870 | writer_packet_context_type = bt_ctf_stream_class_get_packet_context_type( | |
871 | writer_stream_class); | |
872 | if (!writer_packet_context_type) { | |
873 | ret = BT_COMPONENT_STATUS_ERROR; | |
874 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
875 | __LINE__); | |
876 | goto end_put_writer_stream_class; | |
877 | } | |
878 | ||
879 | struct_type = bt_ctf_field_get_type(packet_context); | |
880 | if (!struct_type) { | |
881 | ret = BT_COMPONENT_STATUS_ERROR; | |
882 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
883 | __LINE__); | |
884 | goto end_put_writer_packet_context_type; | |
885 | } | |
886 | ||
887 | writer_packet_context = bt_ctf_field_create(writer_packet_context_type); | |
888 | if (!writer_packet_context) { | |
889 | ret = BT_COMPONENT_STATUS_ERROR; | |
890 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, | |
891 | __LINE__); | |
892 | goto end_put_struct_type; | |
893 | } | |
894 | ||
895 | nr_fields = bt_ctf_field_type_structure_get_field_count(struct_type); | |
896 | for (i = 0; i < nr_fields; i++) { | |
897 | struct bt_ctf_field *field; | |
898 | struct bt_ctf_field_type *field_type; | |
899 | const char *field_name; | |
900 | ||
901 | field = bt_ctf_field_structure_get_field_by_index( | |
902 | packet_context, i); | |
903 | if (!field) { | |
904 | ret = BT_COMPONENT_STATUS_ERROR; | |
905 | fprintf(err, "[error] %s in %s:%d\n", __func__, | |
906 | __FILE__, __LINE__); | |
907 | goto end_put_writer_packet_context; | |
908 | } | |
909 | if (bt_ctf_field_type_structure_get_field(struct_type, | |
910 | &field_name, &field_type, i) < 0) { | |
911 | ret = BT_COMPONENT_STATUS_ERROR; | |
912 | bt_put(field); | |
913 | fprintf(err, "[error] %s in %s:%d\n", __func__, | |
914 | __FILE__, __LINE__); | |
915 | goto end_put_writer_packet_context; | |
916 | } | |
917 | ||
918 | if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_TYPE_ID_INTEGER) { | |
919 | fprintf(err, "[error] Unexpected packet context field type\n"); | |
920 | bt_put(field); | |
921 | ret = BT_COMPONENT_STATUS_ERROR; | |
922 | goto end_put_writer_packet_context; | |
923 | } | |
924 | ||
925 | ret = copy_packet_context_field(err, field, field_name, | |
926 | writer_packet_context, writer_packet_context_type); | |
927 | bt_put(field_type); | |
928 | bt_put(field); | |
929 | if (ret != BT_COMPONENT_STATUS_OK) { | |
930 | fprintf(err, "[error] %s in %s:%d\n", __func__, | |
931 | __FILE__, __LINE__); | |
932 | goto end_put_writer_packet_context; | |
933 | } | |
934 | } | |
935 | ||
936 | int_ret = bt_ctf_stream_set_packet_context(writer_stream, | |
937 | writer_packet_context); | |
938 | if (int_ret < 0) { | |
939 | ret = BT_COMPONENT_STATUS_ERROR; | |
940 | goto end_put_writer_packet_context; | |
941 | } | |
942 | ||
943 | end_put_writer_packet_context: | |
944 | bt_put(writer_packet_context); | |
945 | end_put_struct_type: | |
946 | bt_put(struct_type); | |
947 | end_put_writer_packet_context_type: | |
948 | bt_put(writer_packet_context_type); | |
949 | end_put_writer_stream_class: | |
950 | bt_put(writer_stream_class); | |
951 | end_put_packet_context: | |
952 | bt_put(packet_context); | |
953 | end: | |
954 | return ret; | |
955 | } | |
956 | ||
957 | BT_HIDDEN | |
958 | enum bt_component_status writer_close_packet( | |
959 | struct writer_component *writer_component, | |
960 | struct bt_ctf_packet *packet) | |
961 | { | |
962 | struct bt_ctf_stream *stream, *writer_stream; | |
963 | enum bt_component_status ret; | |
964 | ||
965 | stream = bt_ctf_packet_get_stream(packet); | |
966 | if (!stream) { | |
967 | ret = BT_COMPONENT_STATUS_ERROR; | |
968 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
969 | __func__, __FILE__, __LINE__); | |
970 | goto end; | |
971 | } | |
972 | ||
973 | writer_stream = lookup_stream(writer_component, stream); | |
974 | if (!writer_stream) { | |
975 | ret = BT_COMPONENT_STATUS_ERROR; | |
976 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
977 | __func__, __FILE__, __LINE__); | |
978 | goto end_put; | |
979 | } | |
980 | ||
981 | if (!bt_get(writer_stream)) { | |
982 | fprintf(writer_component->err, | |
983 | "[error] Failed to get reference on writer stream\n"); | |
984 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
985 | __func__, __FILE__, __LINE__); | |
986 | ret = BT_COMPONENT_STATUS_ERROR; | |
987 | goto end_put; | |
988 | } | |
989 | ||
990 | ret = copy_packet_context(writer_component->err, packet, writer_stream); | |
991 | if (ret != BT_COMPONENT_STATUS_OK) { | |
992 | ret = BT_COMPONENT_STATUS_ERROR; | |
993 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
994 | __func__, __FILE__, __LINE__); | |
995 | goto end_put; | |
996 | } | |
997 | ||
998 | ret = bt_ctf_stream_flush(writer_stream); | |
999 | if (ret < 0) { | |
1000 | fprintf(writer_component->err, | |
1001 | "[error] Failed to flush packet\n"); | |
1002 | ret = BT_COMPONENT_STATUS_ERROR; | |
1003 | } | |
1004 | ||
1005 | ret = BT_COMPONENT_STATUS_OK; | |
1006 | ||
1007 | bt_put(writer_stream); | |
1008 | ||
1009 | end_put: | |
1010 | bt_put(stream); | |
1011 | end: | |
1012 | return ret; | |
1013 | } | |
1014 | ||
1015 | static | |
1016 | struct bt_ctf_event *copy_event(FILE *err, struct bt_ctf_event *event, | |
1017 | struct bt_ctf_event_class *writer_event_class) | |
1018 | { | |
1019 | struct bt_ctf_event *writer_event; | |
1020 | struct bt_ctf_field *field; | |
1021 | int ret; | |
1022 | ||
1023 | writer_event = bt_ctf_event_create(writer_event_class); | |
1024 | if (!writer_event) { | |
1025 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); | |
1026 | goto end; | |
1027 | } | |
1028 | ||
1029 | field = bt_ctf_event_get_header(event); | |
1030 | ret = bt_ctf_event_set_header(writer_event, | |
1031 | bt_ctf_field_copy(field)); | |
1032 | if (ret < 0) { | |
1033 | BT_PUT(writer_event); | |
1034 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); | |
1035 | goto end; | |
1036 | } | |
1037 | ||
1038 | field = bt_ctf_event_get_stream_event_context(event); | |
1039 | ret = bt_ctf_event_set_stream_event_context(writer_event, | |
1040 | bt_ctf_field_copy(field)); | |
1041 | if (ret < 0) { | |
1042 | BT_PUT(writer_event); | |
1043 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); | |
1044 | goto end; | |
1045 | } | |
1046 | ||
1047 | field = bt_ctf_event_get_event_context(event); | |
1048 | ret = bt_ctf_event_set_event_context(writer_event, | |
1049 | bt_ctf_field_copy(field)); | |
1050 | if (ret < 0) { | |
1051 | BT_PUT(writer_event); | |
1052 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); | |
1053 | goto end; | |
1054 | } | |
1055 | ||
1056 | field = bt_ctf_event_get_payload_field(event); | |
1057 | ret = bt_ctf_event_set_payload_field(writer_event, | |
1058 | bt_ctf_field_copy(field)); | |
1059 | if (ret < 0) { | |
1060 | BT_PUT(writer_event); | |
1061 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__); | |
1062 | goto end; | |
1063 | } | |
1064 | ||
1065 | end: | |
1066 | return writer_event; | |
1067 | } | |
1068 | ||
1069 | BT_HIDDEN | |
1070 | enum bt_component_status writer_output_event( | |
1071 | struct writer_component *writer_component, | |
1072 | struct bt_ctf_event *event) | |
1073 | { | |
1074 | enum bt_component_status ret; | |
1075 | struct bt_ctf_event_class *event_class, *writer_event_class; | |
1076 | struct bt_ctf_stream *stream, *writer_stream; | |
1077 | struct bt_ctf_stream_class *stream_class, *writer_stream_class; | |
1078 | struct bt_ctf_event *writer_event; | |
1079 | const char *event_name; | |
1080 | int int_ret; | |
1081 | ||
1082 | event_class = bt_ctf_event_get_class(event); | |
1083 | if (!event_class) { | |
1084 | ret = BT_COMPONENT_STATUS_ERROR; | |
1085 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, | |
1086 | __FILE__, __LINE__); | |
1087 | goto end; | |
1088 | } | |
1089 | ||
1090 | event_name = bt_ctf_event_class_get_name(event_class); | |
1091 | if (!event_name) { | |
1092 | ret = BT_COMPONENT_STATUS_ERROR; | |
1093 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, | |
1094 | __FILE__, __LINE__); | |
1095 | goto end_put_event_class; | |
1096 | } | |
bc506aa5 JD |
1097 | |
1098 | stream = bt_ctf_event_get_stream(event); | |
1099 | if (!stream) { | |
1100 | ret = BT_COMPONENT_STATUS_ERROR; | |
1101 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, | |
1102 | __FILE__, __LINE__); | |
1103 | goto end_put_event_class; | |
1104 | } | |
1105 | ||
1106 | writer_stream = lookup_stream(writer_component, stream); | |
1107 | if (!writer_stream || !bt_get(writer_stream)) { | |
1108 | ret = BT_COMPONENT_STATUS_ERROR; | |
1109 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, | |
1110 | __FILE__, __LINE__); | |
1111 | goto end_put_stream; | |
1112 | } | |
1113 | ||
1114 | stream_class = bt_ctf_event_class_get_stream_class(event_class); | |
1115 | if (!stream_class) { | |
1116 | ret = BT_COMPONENT_STATUS_ERROR; | |
1117 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, | |
1118 | __FILE__, __LINE__); | |
1119 | goto end_put_writer_stream; | |
1120 | } | |
1121 | ||
1122 | writer_stream_class = g_hash_table_lookup( | |
1123 | writer_component->stream_class_map, | |
1124 | (gpointer) stream_class); | |
1125 | if (!writer_stream_class || !bt_get(writer_stream_class)) { | |
1126 | ret = BT_COMPONENT_STATUS_ERROR; | |
1127 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, | |
1128 | __FILE__, __LINE__); | |
1129 | goto end_put_stream_class; | |
1130 | } | |
1131 | ||
1132 | writer_event_class = get_event_class(writer_component, | |
1133 | writer_stream_class, event_class); | |
1134 | if (!writer_event_class) { | |
1135 | ret = BT_COMPONENT_STATUS_ERROR; | |
1136 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, | |
1137 | __FILE__, __LINE__); | |
1138 | goto end_put_writer_stream_class; | |
1139 | } | |
1140 | ||
1141 | writer_event = copy_event(writer_component->err, event, writer_event_class); | |
1142 | if (!writer_event) { | |
1143 | ret = BT_COMPONENT_STATUS_ERROR; | |
1144 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, | |
1145 | __FILE__, __LINE__); | |
1146 | fprintf(writer_component->err, "[error] Failed to copy event %s\n", | |
1147 | bt_ctf_event_class_get_name(writer_event_class)); | |
1148 | goto end_put_writer_event_class; | |
1149 | } | |
1150 | ||
1151 | int_ret = bt_ctf_stream_append_event(writer_stream, writer_event); | |
1152 | if (int_ret < 0) { | |
1153 | ret = BT_COMPONENT_STATUS_ERROR; | |
1154 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, | |
1155 | __FILE__, __LINE__); | |
1156 | fprintf(writer_component->err, "[error] Failed to append event %s\n", | |
1157 | bt_ctf_event_class_get_name(writer_event_class)); | |
1158 | goto end_put_writer_event; | |
1159 | } | |
1160 | ||
1161 | ret = BT_COMPONENT_STATUS_OK; | |
1162 | ||
1163 | end_put_writer_event: | |
1164 | bt_put(writer_event); | |
1165 | end_put_writer_event_class: | |
1166 | bt_put(writer_event_class); | |
1167 | end_put_writer_stream_class: | |
1168 | bt_put(writer_stream_class); | |
1169 | end_put_stream_class: | |
1170 | bt_put(stream_class); | |
1171 | end_put_writer_stream: | |
1172 | bt_put(writer_stream); | |
1173 | end_put_stream: | |
1174 | bt_put(stream); | |
1175 | end_put_event_class: | |
1176 | bt_put(event_class); | |
1177 | end: | |
1178 | return ret; | |
1179 | } |