bt2: add create_plugin_from_name()
[babeltrace.git] / lib / component / component-class.c
CommitLineData
fb2dcc52
JG
1/*
2 * component-class.c
3 *
4 * Babeltrace Plugin Component Class
33b34c43 5 *
3310b217 6 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
fb2dcc52
JG
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/compiler.h>
33b34c43 30#include <babeltrace/component/component-class-internal.h>
b8a06801 31#include <babeltrace/ref.h>
1e4d8103 32#include <stdbool.h>
fb2dcc52
JG
33#include <glib.h>
34
35static
b8a06801 36void bt_component_class_destroy(struct bt_object *obj)
fb2dcc52
JG
37{
38 struct bt_component_class *class;
33b34c43 39 int i;
fb2dcc52 40
b8a06801
JG
41 assert(obj);
42 class = container_of(obj, struct bt_component_class, base);
33b34c43
PP
43
44 /* Call destroy listeners in reverse registration order */
45 for (i = class->destroy_listeners->len - 1; i >= 0; i--) {
d3e4dcd8 46 struct bt_component_class_destroy_listener *listener =
33b34c43 47 &g_array_index(class->destroy_listeners,
d3e4dcd8 48 struct bt_component_class_destroy_listener,
33b34c43
PP
49 i);
50
51 listener->func(class, listener->data);
52 }
53
fb2dcc52
JG
54 if (class->name) {
55 g_string_free(class->name, TRUE);
56 }
7c7c0433
JG
57 if (class->description) {
58 g_string_free(class->description, TRUE);
59 }
33b34c43
PP
60 if (class->destroy_listeners) {
61 g_array_free(class->destroy_listeners, TRUE);
62 }
b8a06801 63
fb2dcc52
JG
64 g_free(class);
65}
66
d3e4dcd8
PP
67static
68int bt_component_class_init(struct bt_component_class *class,
69 enum bt_component_class_type type, const char *name)
fb2dcc52 70{
d3e4dcd8
PP
71 int ret = 0;
72
73 bt_object_init(class, bt_component_class_destroy);
74 class->type = type;
75 class->name = g_string_new(name);
76 if (!class->name) {
77 goto error;
78 }
79
80 class->description = g_string_new(NULL);
81 if (!class->description) {
82 goto error;
83 }
84
85 class->destroy_listeners = g_array_new(FALSE, TRUE,
86 sizeof(struct bt_component_class_destroy_listener));
87 if (!class->destroy_listeners) {
88 goto error;
89 }
90
91 goto end;
6ba0b073 92
d3e4dcd8
PP
93error:
94 BT_PUT(class);
95 ret = -1;
96
97end:
98 return ret;
99}
100
101struct bt_component_class *bt_component_class_source_create(const char *name,
d3eb6e8f
PP
102 bt_component_class_notification_iterator_get_method notification_iterator_get_method,
103 bt_component_class_notification_iterator_next_method notification_iterator_next_method)
d3e4dcd8
PP
104{
105 struct bt_component_class_source *source_class = NULL;
106 int ret;
107
d3eb6e8f
PP
108 if (!name || !notification_iterator_get_method ||
109 !notification_iterator_next_method) {
6ba0b073
PP
110 goto end;
111 }
fb2dcc52 112
d3e4dcd8
PP
113 source_class = g_new0(struct bt_component_class_source, 1);
114 if (!source_class) {
fb2dcc52
JG
115 goto end;
116 }
117
d3e4dcd8
PP
118 ret = bt_component_class_init(&source_class->parent,
119 BT_COMPONENT_CLASS_TYPE_SOURCE, name);
120 if (ret) {
121 /*
122 * If bt_component_class_init() fails, the component
123 * class is put, therefore its memory is already
124 * freed.
125 */
126 source_class = NULL;
127 goto end;
128 }
129
d3eb6e8f
PP
130 source_class->methods.iterator.get = notification_iterator_get_method;
131 source_class->methods.iterator.next = notification_iterator_next_method;
d3e4dcd8
PP
132
133end:
134 return &source_class->parent;
135}
136
137struct bt_component_class *bt_component_class_filter_create(const char *name,
d3eb6e8f
PP
138 bt_component_class_notification_iterator_get_method notification_iterator_get_method,
139 bt_component_class_notification_iterator_next_method notification_iterator_next_method)
d3e4dcd8
PP
140{
141 struct bt_component_class_filter *filter_class = NULL;
142 int ret;
143
d3eb6e8f
PP
144 if (!name || !notification_iterator_get_method ||
145 !notification_iterator_next_method) {
fb2dcc52
JG
146 goto end;
147 }
6ba0b073 148
d3e4dcd8
PP
149 filter_class = g_new0(struct bt_component_class_filter, 1);
150 if (!filter_class) {
151 goto end;
6ba0b073
PP
152 }
153
d3e4dcd8
PP
154 ret = bt_component_class_init(&filter_class->parent,
155 BT_COMPONENT_CLASS_TYPE_FILTER, name);
156 if (ret) {
157 /*
158 * If bt_component_class_init() fails, the component
159 * class is put, therefore its memory is already
160 * freed.
161 */
162 filter_class = NULL;
33b34c43
PP
163 goto end;
164 }
d3e4dcd8 165
d3eb6e8f
PP
166 filter_class->methods.iterator.get = notification_iterator_get_method;
167 filter_class->methods.iterator.next = notification_iterator_next_method;
d3e4dcd8 168
fb2dcc52 169end:
d3e4dcd8
PP
170 return &filter_class->parent;
171}
172
173struct bt_component_class *bt_component_class_sink_create(const char *name,
174 bt_component_class_sink_consume_method consume_method)
175{
176 struct bt_component_class_sink *sink_class = NULL;
177 int ret;
178
179 if (!name || !consume_method) {
180 goto end;
181 }
182
183 sink_class = g_new0(struct bt_component_class_sink, 1);
184 if (!sink_class) {
185 goto end;
186 }
187
188 ret = bt_component_class_init(&sink_class->parent,
189 BT_COMPONENT_CLASS_TYPE_SINK, name);
190 if (ret) {
191 /*
192 * If bt_component_class_init() fails, the component
193 * class is put, therefore its memory is already
194 * freed.
195 */
196 sink_class = NULL;
197 goto end;
198 }
199
200 sink_class->methods.consume = consume_method;
201
202end:
203 return &sink_class->parent;
204}
205
206int bt_component_class_set_init_method(
207 struct bt_component_class *component_class,
208 bt_component_class_init_method init_method)
209{
210 int ret = 0;
211
1e4d8103 212 if (!component_class || component_class->frozen || !init_method) {
d3e4dcd8
PP
213 ret = -1;
214 goto end;
215 }
216
217 component_class->methods.init = init_method;
218
219end:
220 return ret;
221}
222
223int bt_component_class_set_destroy_method(
224 struct bt_component_class *component_class,
225 bt_component_class_destroy_method destroy_method)
226{
227 int ret = 0;
228
1e4d8103 229 if (!component_class || component_class->frozen || !destroy_method) {
d3e4dcd8
PP
230 ret = -1;
231 goto end;
232 }
233
234 component_class->methods.destroy = destroy_method;
235
236end:
237 return ret;
238}
239
d3eb6e8f
PP
240int bt_component_class_source_set_notification_iterator_init_method(
241 struct bt_component_class *component_class,
242 bt_component_class_notification_iterator_init_method notification_iterator_init_method)
243{
244 struct bt_component_class_source *source_class;
245 int ret = 0;
246
247 if (!component_class || component_class->frozen ||
248 !notification_iterator_init_method ||
249 component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
250 ret = -1;
251 goto end;
252 }
253
254 source_class = container_of(component_class,
255 struct bt_component_class_source, parent);
256 source_class->methods.iterator.init = notification_iterator_init_method;
257
258end:
259 return ret;
260}
261
262int bt_component_class_source_set_notification_iterator_destroy_method(
263 struct bt_component_class *component_class,
264 bt_component_class_notification_iterator_destroy_method notification_iterator_destroy_method)
265{
266 struct bt_component_class_source *source_class;
267 int ret = 0;
268
269 if (!component_class || component_class->frozen ||
270 !notification_iterator_destroy_method ||
271 component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
272 ret = -1;
273 goto end;
274 }
275
276 source_class = container_of(component_class,
277 struct bt_component_class_source, parent);
278 source_class->methods.iterator.destroy =
279 notification_iterator_destroy_method;
280
281end:
282 return ret;
283}
284
285int bt_component_class_source_set_notification_iterator_seek_time_method(
286 struct bt_component_class *component_class,
287 bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method)
288{
289 struct bt_component_class_source *source_class;
290 int ret = 0;
291
292 if (!component_class || component_class->frozen ||
293 !notification_iterator_seek_time_method ||
294 component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
295 ret = -1;
296 goto end;
297 }
298
299 source_class = container_of(component_class,
300 struct bt_component_class_source, parent);
301 source_class->methods.iterator.seek_time =
302 notification_iterator_seek_time_method;
303
304end:
305 return ret;
306}
307
308int bt_component_class_filter_set_notification_iterator_init_method(
309 struct bt_component_class *component_class,
310 bt_component_class_notification_iterator_init_method notification_iterator_init_method)
311{
312 struct bt_component_class_filter *filter_class;
313 int ret = 0;
314
315 if (!component_class || component_class->frozen ||
316 !notification_iterator_init_method ||
317 component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
318 ret = -1;
319 goto end;
320 }
321
322 filter_class = container_of(component_class,
323 struct bt_component_class_filter, parent);
324 filter_class->methods.iterator.init = notification_iterator_init_method;
325
326end:
327 return ret;
328}
329
330int bt_component_class_filter_set_notification_iterator_destroy_method(
331 struct bt_component_class *component_class,
332 bt_component_class_notification_iterator_destroy_method notification_iterator_destroy_method)
333{
334 struct bt_component_class_filter *filter_class;
335 int ret = 0;
336
337 if (!component_class || component_class->frozen ||
338 !notification_iterator_destroy_method ||
339 component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
340 ret = -1;
341 goto end;
342 }
343
344 filter_class = container_of(component_class,
345 struct bt_component_class_filter, parent);
346 filter_class->methods.iterator.destroy =
347 notification_iterator_destroy_method;
348
349end:
350 return ret;
351}
352
353int bt_component_class_filter_set_notification_iterator_seek_time_method(
354 struct bt_component_class *component_class,
355 bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method)
356{
357 struct bt_component_class_filter *filter_class;
358 int ret = 0;
359
360 if (!component_class || component_class->frozen ||
361 !notification_iterator_seek_time_method ||
362 component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
363 ret = -1;
364 goto end;
365 }
366
367 filter_class = container_of(component_class,
368 struct bt_component_class_filter, parent);
369 filter_class->methods.iterator.seek_time =
370 notification_iterator_seek_time_method;
371
372end:
373 return ret;
374}
375
376int bt_component_class_set_description(
d3e4dcd8
PP
377 struct bt_component_class *component_class,
378 const char *description)
379{
380 int ret = 0;
381
1e4d8103 382 if (!component_class || component_class->frozen || !description) {
d3e4dcd8
PP
383 ret = -1;
384 goto end;
385 }
386
387 g_string_assign(component_class->description, description);
388
389end:
390 return ret;
fb2dcc52 391}
38b48196
JG
392
393const char *bt_component_class_get_name(
394 struct bt_component_class *component_class)
395{
396 return component_class ? component_class->name->str : NULL;
397}
398
d3e4dcd8 399enum bt_component_class_type bt_component_class_get_type(
38b48196
JG
400 struct bt_component_class *component_class)
401{
402 return component_class ? component_class->type :
d3e4dcd8 403 BT_COMPONENT_CLASS_TYPE_UNKNOWN;
38b48196
JG
404}
405
33b34c43 406const char *bt_component_class_get_description(
38b48196
JG
407 struct bt_component_class *component_class)
408{
6ba0b073
PP
409 return component_class && component_class->description ?
410 component_class->description->str : NULL;
38b48196 411}
7c7c0433 412
33b34c43
PP
413BT_HIDDEN
414int bt_component_class_add_destroy_listener(struct bt_component_class *class,
415 bt_component_class_destroy_listener_func func, void *data)
7c7c0433 416{
33b34c43 417 int ret = 0;
d3e4dcd8 418 struct bt_component_class_destroy_listener listener;
33b34c43 419
1e4d8103 420 if (!class || class->frozen || !func) {
33b34c43
PP
421 ret = -1;
422 goto end;
423 }
424
425 listener.func = func;
426 listener.data = data;
427 g_array_append_val(class->destroy_listeners, listener);
428
429end:
430 return ret;
7c7c0433 431}
d3e4dcd8
PP
432
433extern int bt_component_class_sink_set_add_iterator_method(
434 struct bt_component_class *component_class,
435 bt_component_class_sink_add_iterator_method add_iterator_method)
436{
437 struct bt_component_class_sink *sink_class;
438 int ret = 0;
439
1e4d8103
PP
440 if (!component_class || component_class->frozen ||
441 !add_iterator_method ||
d3e4dcd8
PP
442 component_class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
443 ret = -1;
444 goto end;
445 }
446
447 sink_class = container_of(component_class,
448 struct bt_component_class_sink, parent);
449 sink_class->methods.add_iterator = add_iterator_method;
450
451end:
452 return ret;
453}
454
455extern int bt_component_class_filter_set_add_iterator_method(
456 struct bt_component_class *component_class,
457 bt_component_class_filter_add_iterator_method add_iterator_method)
458{
459 struct bt_component_class_filter *filter_class;
460 int ret = 0;
461
1e4d8103
PP
462 if (!component_class || component_class->frozen ||
463 !add_iterator_method ||
d3e4dcd8
PP
464 component_class->type !=
465 BT_COMPONENT_CLASS_TYPE_FILTER) {
466 ret = -1;
467 goto end;
468 }
469
470 filter_class = container_of(component_class,
471 struct bt_component_class_filter, parent);
472 filter_class->methods.add_iterator = add_iterator_method;
473
474end:
475 return ret;
476}
1e4d8103
PP
477
478int bt_component_class_freeze(
479 struct bt_component_class *component_class)
480{
481 int ret = 0;
482
483 if (!component_class) {
484 ret = -1;
485 goto end;
486 }
487
488 component_class->frozen = true;
489
490end:
491 return ret;
492}
This page took 0.046816 seconds and 4 git commands to generate.