4 * Babeltrace Plugin Component Class
6 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
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:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
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
29 #include <babeltrace/compiler.h>
30 #include <babeltrace/graph/component-class-internal.h>
31 #include <babeltrace/ref.h>
36 void bt_component_class_destroy(struct bt_object
*obj
)
38 struct bt_component_class
*class;
42 class = container_of(obj
, struct bt_component_class
, base
);
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
,
51 listener
->func(class, listener
->data
);
55 g_string_free(class->name
, TRUE
);
57 if (class->description
) {
58 g_string_free(class->description
, TRUE
);
61 g_string_free(class->help
, TRUE
);
63 if (class->destroy_listeners
) {
64 g_array_free(class->destroy_listeners
, TRUE
);
71 int bt_component_class_init(struct bt_component_class
*class,
72 enum bt_component_class_type type
, const char *name
)
76 bt_object_init(class, bt_component_class_destroy
);
78 class->name
= g_string_new(name
);
83 class->description
= g_string_new(NULL
);
84 if (!class->description
) {
88 class->help
= g_string_new(NULL
);
93 class->destroy_listeners
= g_array_new(FALSE
, TRUE
,
94 sizeof(struct bt_component_class_destroy_listener
));
95 if (!class->destroy_listeners
) {
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
)
112 struct bt_component_class_source
*source_class
= NULL
;
115 if (!name
|| !notification_iterator_next_method
) {
119 source_class
= g_new0(struct bt_component_class_source
, 1);
124 ret
= bt_component_class_init(&source_class
->parent
,
125 BT_COMPONENT_CLASS_TYPE_SOURCE
, name
);
128 * If bt_component_class_init() fails, the component
129 * class is put, therefore its memory is already
136 source_class
->methods
.iterator
.next
= notification_iterator_next_method
;
139 return &source_class
->parent
;
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
)
145 struct bt_component_class_filter
*filter_class
= NULL
;
148 if (!name
|| !notification_iterator_next_method
) {
152 filter_class
= g_new0(struct bt_component_class_filter
, 1);
157 ret
= bt_component_class_init(&filter_class
->parent
,
158 BT_COMPONENT_CLASS_TYPE_FILTER
, name
);
161 * If bt_component_class_init() fails, the component
162 * class is put, therefore its memory is already
169 filter_class
->methods
.iterator
.next
= notification_iterator_next_method
;
172 return &filter_class
->parent
;
175 struct bt_component_class
*bt_component_class_sink_create(const char *name
,
176 bt_component_class_sink_consume_method consume_method
)
178 struct bt_component_class_sink
*sink_class
= NULL
;
181 if (!name
|| !consume_method
) {
185 sink_class
= g_new0(struct bt_component_class_sink
, 1);
190 ret
= bt_component_class_init(&sink_class
->parent
,
191 BT_COMPONENT_CLASS_TYPE_SINK
, name
);
194 * If bt_component_class_init() fails, the component
195 * class is put, therefore its memory is already
202 sink_class
->methods
.consume
= consume_method
;
205 return &sink_class
->parent
;
208 int bt_component_class_set_init_method(
209 struct bt_component_class
*component_class
,
210 bt_component_class_init_method init_method
)
214 if (!component_class
|| component_class
->frozen
|| !init_method
) {
219 component_class
->methods
.init
= init_method
;
225 int bt_component_class_set_query_method(
226 struct bt_component_class
*component_class
,
227 bt_component_class_query_method query_method
)
231 if (!component_class
|| component_class
->frozen
|| !query_method
) {
236 component_class
->methods
.query
= query_method
;
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
)
248 if (!component_class
|| component_class
->frozen
|| !method
) {
253 component_class
->methods
.accept_port_connection
= method
;
259 int bt_component_class_set_port_disconnected_method(
260 struct bt_component_class
*component_class
,
261 bt_component_class_port_disconnected_method method
)
265 if (!component_class
|| component_class
->frozen
|| !method
) {
270 component_class
->methods
.port_disconnected
= method
;
276 int bt_component_class_set_finalize_method(
277 struct bt_component_class
*component_class
,
278 bt_component_class_finalize_method finalize_method
)
282 if (!component_class
|| component_class
->frozen
|| !finalize_method
) {
287 component_class
->methods
.finalize
= finalize_method
;
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
)
297 struct bt_component_class_source
*source_class
;
300 if (!component_class
|| component_class
->frozen
||
301 !notification_iterator_init_method
||
302 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
307 source_class
= container_of(component_class
,
308 struct bt_component_class_source
, parent
);
309 source_class
->methods
.iterator
.init
= notification_iterator_init_method
;
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
)
319 struct bt_component_class_source
*source_class
;
322 if (!component_class
|| component_class
->frozen
||
323 !notification_iterator_finalize_method
||
324 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
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
;
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
)
342 struct bt_component_class_source
*source_class
;
345 if (!component_class
|| component_class
->frozen
||
346 !notification_iterator_seek_time_method
||
347 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
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
;
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
)
365 struct bt_component_class_filter
*filter_class
;
368 if (!component_class
|| component_class
->frozen
||
369 !notification_iterator_init_method
||
370 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
375 filter_class
= container_of(component_class
,
376 struct bt_component_class_filter
, parent
);
377 filter_class
->methods
.iterator
.init
= notification_iterator_init_method
;
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
)
387 struct bt_component_class_filter
*filter_class
;
390 if (!component_class
|| component_class
->frozen
||
391 !notification_iterator_finalize_method
||
392 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
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
;
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
)
410 struct bt_component_class_filter
*filter_class
;
413 if (!component_class
|| component_class
->frozen
||
414 !notification_iterator_seek_time_method
||
415 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
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
;
429 int bt_component_class_set_description(
430 struct bt_component_class
*component_class
,
431 const char *description
)
435 if (!component_class
|| component_class
->frozen
|| !description
) {
440 g_string_assign(component_class
->description
, description
);
446 int bt_component_class_set_help(
447 struct bt_component_class
*component_class
,
452 if (!component_class
|| component_class
->frozen
|| !help
) {
457 g_string_assign(component_class
->help
, help
);
463 const char *bt_component_class_get_name(
464 struct bt_component_class
*component_class
)
466 return component_class
? component_class
->name
->str
: NULL
;
469 enum bt_component_class_type
bt_component_class_get_type(
470 struct bt_component_class
*component_class
)
472 return component_class
? component_class
->type
:
473 BT_COMPONENT_CLASS_TYPE_UNKNOWN
;
476 const char *bt_component_class_get_description(
477 struct bt_component_class
*component_class
)
479 return component_class
&& component_class
->description
&&
480 component_class
->description
->str
[0] != '\0' ?
481 component_class
->description
->str
: NULL
;
484 const char *bt_component_class_get_help(
485 struct bt_component_class
*component_class
)
487 return component_class
&& component_class
->help
&&
488 component_class
->help
->str
[0] != '\0' ?
489 component_class
->help
->str
: NULL
;
493 int bt_component_class_add_destroy_listener(struct bt_component_class
*class,
494 bt_component_class_destroy_listener_func func
, void *data
)
497 struct bt_component_class_destroy_listener listener
;
499 if (!class || class->frozen
|| !func
) {
504 listener
.func
= func
;
505 listener
.data
= data
;
506 g_array_append_val(class->destroy_listeners
, listener
);
512 int bt_component_class_freeze(
513 struct bt_component_class
*component_class
)
517 if (!component_class
) {
522 component_class
->frozen
= true;
528 struct bt_value
*bt_component_class_query(
529 struct bt_component_class
*component_class
,
530 const char *object
, struct bt_value
*params
)
532 struct bt_value
*results
= NULL
;
534 if (!component_class
|| !object
|| !params
||
535 !component_class
->methods
.query
) {
539 results
= component_class
->methods
.query(component_class
,