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