Clean-up: coding style adjustments
[babeltrace.git] / plugins / ctf / fs-sink / writer.c
CommitLineData
bc506aa5
JD
1/*
2 * writer.c
3 *
4 * Babeltrace CTF Writer Output Plugin
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/packet.h>
33b34c43 30#include <babeltrace/plugin/plugin-dev.h>
73d5c1ad 31#include <babeltrace/graph/connection.h>
b2e0c907
PP
32#include <babeltrace/graph/component.h>
33#include <babeltrace/graph/private-component.h>
34#include <babeltrace/graph/component-sink.h>
35#include <babeltrace/graph/private-component-sink.h>
36#include <babeltrace/graph/private-port.h>
37#include <babeltrace/graph/private-connection.h>
38#include <babeltrace/graph/notification.h>
39#include <babeltrace/graph/notification-iterator.h>
40#include <babeltrace/graph/notification-event.h>
41#include <babeltrace/graph/notification-packet.h>
f3168545 42#include <babeltrace/graph/notification-stream.h>
7d61fa8e 43#include <plugins-common.h>
bc506aa5
JD
44#include <stdio.h>
45#include <stdbool.h>
46#include <glib.h>
47#include "writer.h"
c70ed359 48#include <assert.h>
bc506aa5 49
1c78e839 50static
a619fcb7 51gboolean empty_trace_map(gpointer key, gpointer value, gpointer user_data)
f3168545 52{
a619fcb7
JD
53 struct fs_writer *fs_writer = value;
54 struct writer_component *writer_component = user_data;
55
3b41eaba 56 fs_writer->trace_static = 1;
a619fcb7
JD
57 writer_close(writer_component, fs_writer);
58
f3168545
JD
59 return TRUE;
60}
61
bc506aa5
JD
62static
63void destroy_writer_component_data(struct writer_component *writer_component)
64{
c70ed359 65 bt_put(writer_component->input_iterator);
f3168545 66
f3168545 67 g_hash_table_foreach_remove(writer_component->trace_map,
a619fcb7 68 empty_trace_map, writer_component);
bc506aa5 69 g_hash_table_destroy(writer_component->trace_map);
f3168545 70
9057f037
JD
71 g_string_free(writer_component->base_path, true);
72 g_string_free(writer_component->trace_name_base, true);
bc506aa5
JD
73}
74
d8866baa
PP
75BT_HIDDEN
76void writer_component_finalize(struct bt_private_component *component)
bc506aa5
JD
77{
78 struct writer_component *writer_component = (struct writer_component *)
890882ef 79 bt_private_component_get_user_data(component);
bc506aa5
JD
80
81 destroy_writer_component_data(writer_component);
82 g_free(writer_component);
83}
84
bc506aa5 85static
f3168545 86void free_fs_writer(struct fs_writer *fs_writer)
bc506aa5 87{
f3168545
JD
88 bt_put(fs_writer->writer);
89 g_free(fs_writer);
bc506aa5
JD
90}
91
92static
93struct writer_component *create_writer_component(void)
94{
95 struct writer_component *writer_component;
96
97 writer_component = g_new0(struct writer_component, 1);
98 if (!writer_component) {
99 goto end;
100 }
101
102 writer_component->err = stderr;
103 writer_component->trace_id = 0;
9057f037
JD
104 writer_component->trace_name_base = g_string_new("trace");
105 if (!writer_component->trace_name_base) {
106 g_free(writer_component);
107 writer_component = NULL;
108 goto end;
109 }
bc506aa5
JD
110
111 /*
112 * Reader to writer corresponding structures.
113 */
114 writer_component->trace_map = g_hash_table_new_full(g_direct_hash,
f3168545 115 g_direct_equal, NULL, (GDestroyNotify) free_fs_writer);
bc506aa5
JD
116
117end:
118 return writer_component;
119}
120
121static
122enum bt_component_status handle_notification(
123 struct writer_component *writer_component,
124 struct bt_notification *notification)
125{
126 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
127
128 if (!writer_component) {
129 ret = BT_COMPONENT_STATUS_ERROR;
130 goto end;
131 }
132
133 switch (bt_notification_get_type(notification)) {
ea0e619e 134 case BT_NOTIFICATION_TYPE_PACKET_BEGIN:
bc506aa5
JD
135 {
136 struct bt_ctf_packet *packet =
ea0e619e 137 bt_notification_packet_begin_get_packet(notification);
bc506aa5
JD
138
139 if (!packet) {
140 ret = BT_COMPONENT_STATUS_ERROR;
141 goto end;
142 }
143
144 ret = writer_new_packet(writer_component, packet);
145 bt_put(packet);
146 break;
147 }
148 case BT_NOTIFICATION_TYPE_PACKET_END:
149 {
150 struct bt_ctf_packet *packet =
ea0e619e 151 bt_notification_packet_end_get_packet(notification);
bc506aa5
JD
152
153 if (!packet) {
154 ret = BT_COMPONENT_STATUS_ERROR;
155 goto end;
156 }
157 ret = writer_close_packet(writer_component, packet);
158 bt_put(packet);
159 break;
160 }
161 case BT_NOTIFICATION_TYPE_EVENT:
162 {
163 struct bt_ctf_event *event = bt_notification_event_get_event(
164 notification);
165
166 if (!event) {
167 ret = BT_COMPONENT_STATUS_ERROR;
168 goto end;
169 }
bc506aa5
JD
170 ret = writer_output_event(writer_component, event);
171 bt_put(event);
172 if (ret != BT_COMPONENT_STATUS_OK) {
173 goto end;
174 }
175 break;
176 }
f384901f
JD
177 case BT_NOTIFICATION_TYPE_STREAM_BEGIN:
178 {
179 struct bt_ctf_stream *stream =
180 bt_notification_stream_begin_get_stream(notification);
181
182 if (!stream) {
183 ret = BT_COMPONENT_STATUS_ERROR;
184 goto end;
185 }
186 ret = writer_stream_begin(writer_component, stream);
187 bt_put(stream);
188 break;
189 }
bc506aa5 190 case BT_NOTIFICATION_TYPE_STREAM_END:
f3168545
JD
191 {
192 struct bt_ctf_stream *stream =
193 bt_notification_stream_end_get_stream(notification);
194
195 if (!stream) {
196 ret = BT_COMPONENT_STATUS_ERROR;
197 goto end;
198 }
199 ret = writer_stream_end(writer_component, stream);
200 bt_put(stream);
bc506aa5 201 break;
f3168545 202 }
bc506aa5
JD
203 default:
204 puts("Unhandled notification type");
205 }
206end:
207 return ret;
208}
209
d8866baa 210BT_HIDDEN
0d8b4d8e 211void writer_component_port_connected(
890882ef 212 struct bt_private_component *component,
8f4799f7
PP
213 struct bt_private_port *self_port,
214 struct bt_port *other_port)
c70ed359 215{
890882ef 216 struct bt_private_connection *connection;
c70ed359 217 struct writer_component *writer;
73d5c1ad 218 enum bt_connection_status conn_status;
93fc16a5 219 static const enum bt_notification_type notif_types[] = {
f3168545 220 BT_NOTIFICATION_TYPE_EVENT,
93fc16a5
JD
221 BT_NOTIFICATION_TYPE_PACKET_BEGIN,
222 BT_NOTIFICATION_TYPE_PACKET_END,
f384901f 223 BT_NOTIFICATION_TYPE_STREAM_BEGIN,
f3168545 224 BT_NOTIFICATION_TYPE_STREAM_END,
93fc16a5
JD
225 BT_NOTIFICATION_TYPE_SENTINEL,
226 };
c70ed359 227
890882ef 228 writer = bt_private_component_get_user_data(component);
c70ed359
JG
229 assert(writer);
230 assert(!writer->input_iterator);
890882ef 231 connection = bt_private_port_get_private_connection(self_port);
72b913fb 232 assert(connection);
73d5c1ad
PP
233 conn_status = bt_private_connection_create_notification_iterator(
234 connection, notif_types, &writer->input_iterator);
235 if (conn_status != BT_CONNECTION_STATUS_OK) {
0d8b4d8e 236 writer->error = true;
c70ed359 237 }
0d8b4d8e 238
72b913fb 239 bt_put(connection);
c70ed359
JG
240}
241
d8866baa
PP
242BT_HIDDEN
243enum bt_component_status writer_run(struct bt_private_component *component)
bc506aa5
JD
244{
245 enum bt_component_status ret;
246 struct bt_notification *notification = NULL;
247 struct bt_notification_iterator *it;
248 struct writer_component *writer_component =
890882ef 249 bt_private_component_get_user_data(component);
7cdc2bab 250 enum bt_notification_iterator_status it_ret;
bc506aa5 251
0d8b4d8e
PP
252 if (unlikely(writer_component->error)) {
253 ret = BT_COMPONENT_STATUS_ERROR;
254 goto end;
255 }
256
7cdc2bab
MD
257 it = writer_component->input_iterator;
258 assert(it);
259 it_ret = bt_notification_iterator_next(it);
bc506aa5 260
7cdc2bab
MD
261 switch (it_ret) {
262 case BT_NOTIFICATION_ITERATOR_STATUS_END:
263 ret = BT_COMPONENT_STATUS_END;
264 BT_PUT(writer_component->input_iterator);
265 goto end;
266 case BT_NOTIFICATION_ITERATOR_STATUS_AGAIN:
267 ret = BT_COMPONENT_STATUS_AGAIN;
268 goto end;
269 case BT_NOTIFICATION_ITERATOR_STATUS_OK:
270 break;
271 default:
72b913fb 272 ret = BT_COMPONENT_STATUS_ERROR;
996a07a1
JG
273 goto end;
274 }
275
7cdc2bab
MD
276 notification = bt_notification_iterator_get_notification(it);
277 assert(notification);
bc506aa5
JD
278 ret = handle_notification(writer_component, notification);
279end:
bc506aa5
JD
280 bt_put(notification);
281 return ret;
282}
283
6ca0eb99
JD
284static
285enum bt_component_status apply_one_bool(const char *key,
286 struct bt_value *params,
287 bool *option,
288 bool *found)
289{
290 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
291 struct bt_value *value = NULL;
292 enum bt_value_status status;
293 bt_bool bool_val;
294
295 value = bt_value_map_get(params, key);
296 if (!value) {
297 goto end;
298 }
299 status = bt_value_bool_get(value, &bool_val);
802af08e 300 if (status != BT_VALUE_STATUS_OK) {
6ca0eb99
JD
301 ret = BT_COMPONENT_STATUS_ERROR;
302 goto end;
303 }
802af08e 304
6ca0eb99
JD
305 *option = (bool) bool_val;
306 if (found) {
307 *found = true;
308 }
309end:
310 bt_put(value);
311 return ret;
312}
313
d8866baa 314BT_HIDDEN
bc506aa5 315enum bt_component_status writer_component_init(
890882ef 316 struct bt_private_component *component, struct bt_value *params,
7d61fa8e 317 UNUSED_VAR void *init_method_data)
bc506aa5
JD
318{
319 enum bt_component_status ret;
320 enum bt_value_status value_ret;
321 struct writer_component *writer_component = create_writer_component();
322 struct bt_value *value = NULL;
323 const char *path;
324
325 if (!writer_component) {
326 ret = BT_COMPONENT_STATUS_NOMEM;
327 goto end;
328 }
329
147337a3
PP
330 ret = bt_private_component_sink_add_input_private_port(component,
331 "in", NULL, NULL);
332 if (ret != BT_COMPONENT_STATUS_OK) {
b9d103be
PP
333 goto end;
334 }
335
bc506aa5
JD
336 value = bt_value_map_get(params, "path");
337 if (!value || bt_value_is_null(value) || !bt_value_is_string(value)) {
338 fprintf(writer_component->err,
339 "[error] output path parameter required\n");
340 ret = BT_COMPONENT_STATUS_INVALID;
341 goto error;
342 }
343
344 value_ret = bt_value_string_get(value, &path);
345 if (value_ret != BT_VALUE_STATUS_OK) {
346 ret = BT_COMPONENT_STATUS_INVALID;
347 goto error;
348 }
d00b90bf 349 bt_put(value);
bc506aa5 350
9057f037
JD
351 writer_component->base_path = g_string_new(path);
352 if (!writer_component) {
353 ret = BT_COMPONENT_STATUS_ERROR;
354 goto error;
355 }
bc506aa5 356
6ca0eb99
JD
357 writer_component->single_trace = false;
358 ret = apply_one_bool("single-trace", params,
359 &writer_component->single_trace, NULL);
360 if (ret != BT_COMPONENT_STATUS_OK) {
361 goto end;
362 }
363
890882ef 364 ret = bt_private_component_set_user_data(component, writer_component);
bc506aa5
JD
365 if (ret != BT_COMPONENT_STATUS_OK) {
366 goto error;
367 }
368
bc506aa5
JD
369end:
370 return ret;
371error:
372 destroy_writer_component_data(writer_component);
56fa591a 373 g_free(writer_component);
bc506aa5
JD
374 return ret;
375}
This page took 0.047108 seconds and 4 git commands to generate.