8e4703768f9473a6e6f5da5bde9910f94ec55477
[babeltrace.git] / plugins / writer / writer.c
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>
30 #include <babeltrace/plugin/plugin-dev.h>
31 #include <babeltrace/component/component.h>
32 #include <babeltrace/component/component-sink.h>
33 #include <babeltrace/component/notification/notification.h>
34 #include <babeltrace/component/notification/iterator.h>
35 #include <babeltrace/component/notification/event.h>
36 #include <babeltrace/component/notification/packet.h>
37 #include <plugins-common.h>
38 #include <stdio.h>
39 #include <stdbool.h>
40 #include <glib.h>
41 #include "writer.h"
42
43 static
44 void destroy_writer_component_data(struct writer_component *writer_component)
45 {
46 g_hash_table_destroy(writer_component->stream_map);
47 g_hash_table_destroy(writer_component->stream_class_map);
48 g_hash_table_destroy(writer_component->trace_map);
49 g_string_free(writer_component->base_path, true);
50 g_string_free(writer_component->trace_name_base, true);
51 }
52
53 static
54 void destroy_writer_component(struct bt_component *component)
55 {
56 struct writer_component *writer_component = (struct writer_component *)
57 bt_component_get_private_data(component);
58
59 destroy_writer_component_data(writer_component);
60 g_free(writer_component);
61 }
62
63 static
64 void unref_stream_class(struct bt_ctf_stream_class *writer_stream_class)
65 {
66 BT_PUT(writer_stream_class);
67 g_free(writer_stream_class);
68 }
69
70 static
71 void unref_stream(struct bt_ctf_stream_class *writer_stream)
72 {
73 BT_PUT(writer_stream);
74 g_free(writer_stream);
75 }
76
77 static
78 void unref_trace(struct bt_ctf_writer *writer)
79 {
80 BT_PUT(writer);
81 g_free(writer);
82 }
83
84 static
85 struct writer_component *create_writer_component(void)
86 {
87 struct writer_component *writer_component;
88
89 writer_component = g_new0(struct writer_component, 1);
90 if (!writer_component) {
91 goto end;
92 }
93
94 writer_component->err = stderr;
95 writer_component->trace_id = 0;
96 writer_component->trace_name_base = g_string_new("trace");
97 if (!writer_component->trace_name_base) {
98 g_free(writer_component);
99 writer_component = NULL;
100 goto end;
101 }
102
103 /*
104 * Reader to writer corresponding structures.
105 */
106 writer_component->trace_map = g_hash_table_new_full(g_direct_hash,
107 g_direct_equal, NULL, (GDestroyNotify) unref_trace);
108 writer_component->stream_class_map = g_hash_table_new_full(g_direct_hash,
109 g_direct_equal, NULL, (GDestroyNotify) unref_stream_class);
110 writer_component->stream_map = g_hash_table_new_full(g_direct_hash,
111 g_direct_equal, NULL, (GDestroyNotify) unref_stream);
112
113 end:
114 return writer_component;
115 }
116
117 static
118 enum bt_component_status handle_notification(
119 struct writer_component *writer_component,
120 struct bt_notification *notification)
121 {
122 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
123
124 if (!writer_component) {
125 ret = BT_COMPONENT_STATUS_ERROR;
126 goto end;
127 }
128
129 switch (bt_notification_get_type(notification)) {
130 case BT_NOTIFICATION_TYPE_PACKET_BEGIN:
131 {
132 struct bt_ctf_packet *packet =
133 bt_notification_packet_begin_get_packet(notification);
134
135 if (!packet) {
136 ret = BT_COMPONENT_STATUS_ERROR;
137 goto end;
138 }
139
140 ret = writer_new_packet(writer_component, packet);
141 bt_put(packet);
142 break;
143 }
144 case BT_NOTIFICATION_TYPE_PACKET_END:
145 {
146 struct bt_ctf_packet *packet =
147 bt_notification_packet_end_get_packet(notification);
148
149 if (!packet) {
150 ret = BT_COMPONENT_STATUS_ERROR;
151 goto end;
152 }
153 ret = writer_close_packet(writer_component, packet);
154 bt_put(packet);
155 break;
156 }
157 case BT_NOTIFICATION_TYPE_EVENT:
158 {
159 struct bt_ctf_event *event = bt_notification_event_get_event(
160 notification);
161
162 if (!event) {
163 ret = BT_COMPONENT_STATUS_ERROR;
164 goto end;
165 }
166 ret = BT_COMPONENT_STATUS_OK;
167 ret = writer_output_event(writer_component, event);
168 bt_put(event);
169 if (ret != BT_COMPONENT_STATUS_OK) {
170 goto end;
171 }
172 break;
173 }
174 case BT_NOTIFICATION_TYPE_STREAM_END:
175 break;
176 default:
177 puts("Unhandled notification type");
178 }
179 end:
180 return ret;
181 }
182
183 static
184 enum bt_component_status run(struct bt_component *component)
185 {
186 enum bt_component_status ret;
187 struct bt_notification *notification = NULL;
188 struct bt_notification_iterator *it;
189 struct writer_component *writer_component =
190 bt_component_get_private_data(component);
191
192 ret = bt_component_sink_get_input_iterator(component, 0, &it);
193 if (ret != BT_COMPONENT_STATUS_OK) {
194 goto end;
195 }
196
197 notification = bt_notification_iterator_get_notification(it);
198 if (!notification) {
199 ret = BT_COMPONENT_STATUS_ERROR;
200 goto end;
201 }
202
203 ret = bt_notification_iterator_next(it);
204 if (ret != BT_COMPONENT_STATUS_OK) {
205 goto end;
206 }
207
208 ret = handle_notification(writer_component, notification);
209 end:
210 bt_put(it);
211 bt_put(notification);
212 return ret;
213 }
214
215 static
216 enum bt_component_status writer_component_init(
217 struct bt_component *component, struct bt_value *params,
218 UNUSED_VAR void *init_method_data)
219 {
220 enum bt_component_status ret;
221 enum bt_value_status value_ret;
222 struct writer_component *writer_component = create_writer_component();
223 struct bt_value *value = NULL;
224 const char *path;
225
226 if (!writer_component) {
227 ret = BT_COMPONENT_STATUS_NOMEM;
228 goto end;
229 }
230
231 value = bt_value_map_get(params, "path");
232 if (!value || bt_value_is_null(value) || !bt_value_is_string(value)) {
233 fprintf(writer_component->err,
234 "[error] output path parameter required\n");
235 ret = BT_COMPONENT_STATUS_INVALID;
236 goto error;
237 }
238
239 value_ret = bt_value_string_get(value, &path);
240 if (value_ret != BT_VALUE_STATUS_OK) {
241 ret = BT_COMPONENT_STATUS_INVALID;
242 goto error;
243 }
244
245 writer_component->base_path = g_string_new(path);
246 if (!writer_component) {
247 ret = BT_COMPONENT_STATUS_ERROR;
248 goto error;
249 }
250
251 ret = bt_component_set_private_data(component, writer_component);
252 if (ret != BT_COMPONENT_STATUS_OK) {
253 goto error;
254 }
255
256 end:
257 return ret;
258 error:
259 destroy_writer_component_data(writer_component);
260 g_free(writer_component);
261 return ret;
262 }
263
264 /* Initialize plug-in entry points. */
265 BT_PLUGIN(writer);
266 BT_PLUGIN_DESCRIPTION("Babeltrace CTF-Writer output plug-in.");
267 BT_PLUGIN_AUTHOR("Jérémie Galarneau");
268 BT_PLUGIN_LICENSE("MIT");
269 BT_PLUGIN_SINK_COMPONENT_CLASS(writer, run);
270 BT_PLUGIN_SINK_COMPONENT_CLASS_INIT_METHOD(writer, writer_component_init);
271 BT_PLUGIN_SINK_COMPONENT_CLASS_DESTROY_METHOD(writer, destroy_writer_component);
272 BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(writer, "Formats CTF-IR to CTF.");
This page took 0.041871 seconds and 3 git commands to generate.