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/component/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_get_method notification_iterator_get_method
,
111 bt_component_class_notification_iterator_next_method notification_iterator_next_method
)
113 struct bt_component_class_source
*source_class
= NULL
;
116 if (!name
|| !notification_iterator_get_method
||
117 !notification_iterator_next_method
) {
121 source_class
= g_new0(struct bt_component_class_source
, 1);
126 ret
= bt_component_class_init(&source_class
->parent
,
127 BT_COMPONENT_CLASS_TYPE_SOURCE
, name
);
130 * If bt_component_class_init() fails, the component
131 * class is put, therefore its memory is already
138 source_class
->methods
.iterator
.get
= notification_iterator_get_method
;
139 source_class
->methods
.iterator
.next
= notification_iterator_next_method
;
142 return &source_class
->parent
;
145 struct bt_component_class
*bt_component_class_filter_create(const char *name
,
146 bt_component_class_notification_iterator_get_method notification_iterator_get_method
,
147 bt_component_class_notification_iterator_next_method notification_iterator_next_method
)
149 struct bt_component_class_filter
*filter_class
= NULL
;
152 if (!name
|| !notification_iterator_get_method
||
153 !notification_iterator_next_method
) {
157 filter_class
= g_new0(struct bt_component_class_filter
, 1);
162 ret
= bt_component_class_init(&filter_class
->parent
,
163 BT_COMPONENT_CLASS_TYPE_FILTER
, name
);
166 * If bt_component_class_init() fails, the component
167 * class is put, therefore its memory is already
174 filter_class
->methods
.iterator
.get
= notification_iterator_get_method
;
175 filter_class
->methods
.iterator
.next
= notification_iterator_next_method
;
178 return &filter_class
->parent
;
181 struct bt_component_class
*bt_component_class_sink_create(const char *name
,
182 bt_component_class_sink_consume_method consume_method
)
184 struct bt_component_class_sink
*sink_class
= NULL
;
187 if (!name
|| !consume_method
) {
191 sink_class
= g_new0(struct bt_component_class_sink
, 1);
196 ret
= bt_component_class_init(&sink_class
->parent
,
197 BT_COMPONENT_CLASS_TYPE_SINK
, name
);
200 * If bt_component_class_init() fails, the component
201 * class is put, therefore its memory is already
208 sink_class
->methods
.consume
= consume_method
;
211 return &sink_class
->parent
;
214 int bt_component_class_set_init_method(
215 struct bt_component_class
*component_class
,
216 bt_component_class_init_method init_method
)
220 if (!component_class
|| component_class
->frozen
|| !init_method
) {
225 component_class
->methods
.init
= init_method
;
231 int bt_component_class_set_destroy_method(
232 struct bt_component_class
*component_class
,
233 bt_component_class_destroy_method destroy_method
)
237 if (!component_class
|| component_class
->frozen
|| !destroy_method
) {
242 component_class
->methods
.destroy
= destroy_method
;
248 int bt_component_class_source_set_notification_iterator_init_method(
249 struct bt_component_class
*component_class
,
250 bt_component_class_notification_iterator_init_method notification_iterator_init_method
)
252 struct bt_component_class_source
*source_class
;
255 if (!component_class
|| component_class
->frozen
||
256 !notification_iterator_init_method
||
257 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
262 source_class
= container_of(component_class
,
263 struct bt_component_class_source
, parent
);
264 source_class
->methods
.iterator
.init
= notification_iterator_init_method
;
270 int bt_component_class_source_set_notification_iterator_destroy_method(
271 struct bt_component_class
*component_class
,
272 bt_component_class_notification_iterator_destroy_method notification_iterator_destroy_method
)
274 struct bt_component_class_source
*source_class
;
277 if (!component_class
|| component_class
->frozen
||
278 !notification_iterator_destroy_method
||
279 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
284 source_class
= container_of(component_class
,
285 struct bt_component_class_source
, parent
);
286 source_class
->methods
.iterator
.destroy
=
287 notification_iterator_destroy_method
;
293 int bt_component_class_source_set_notification_iterator_seek_time_method(
294 struct bt_component_class
*component_class
,
295 bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method
)
297 struct bt_component_class_source
*source_class
;
300 if (!component_class
|| component_class
->frozen
||
301 !notification_iterator_seek_time_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
.seek_time
=
310 notification_iterator_seek_time_method
;
316 int bt_component_class_filter_set_notification_iterator_init_method(
317 struct bt_component_class
*component_class
,
318 bt_component_class_notification_iterator_init_method notification_iterator_init_method
)
320 struct bt_component_class_filter
*filter_class
;
323 if (!component_class
|| component_class
->frozen
||
324 !notification_iterator_init_method
||
325 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
330 filter_class
= container_of(component_class
,
331 struct bt_component_class_filter
, parent
);
332 filter_class
->methods
.iterator
.init
= notification_iterator_init_method
;
338 int bt_component_class_filter_set_notification_iterator_destroy_method(
339 struct bt_component_class
*component_class
,
340 bt_component_class_notification_iterator_destroy_method notification_iterator_destroy_method
)
342 struct bt_component_class_filter
*filter_class
;
345 if (!component_class
|| component_class
->frozen
||
346 !notification_iterator_destroy_method
||
347 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
352 filter_class
= container_of(component_class
,
353 struct bt_component_class_filter
, parent
);
354 filter_class
->methods
.iterator
.destroy
=
355 notification_iterator_destroy_method
;
361 int bt_component_class_filter_set_notification_iterator_seek_time_method(
362 struct bt_component_class
*component_class
,
363 bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method
)
365 struct bt_component_class_filter
*filter_class
;
368 if (!component_class
|| component_class
->frozen
||
369 !notification_iterator_seek_time_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
.seek_time
=
378 notification_iterator_seek_time_method
;
384 int bt_component_class_set_description(
385 struct bt_component_class
*component_class
,
386 const char *description
)
390 if (!component_class
|| component_class
->frozen
|| !description
) {
395 g_string_assign(component_class
->description
, description
);
401 int bt_component_class_set_help(
402 struct bt_component_class
*component_class
,
407 if (!component_class
|| component_class
->frozen
|| !help
) {
412 g_string_assign(component_class
->help
, help
);
418 const char *bt_component_class_get_name(
419 struct bt_component_class
*component_class
)
421 return component_class
? component_class
->name
->str
: NULL
;
424 enum bt_component_class_type
bt_component_class_get_type(
425 struct bt_component_class
*component_class
)
427 return component_class
? component_class
->type
:
428 BT_COMPONENT_CLASS_TYPE_UNKNOWN
;
431 const char *bt_component_class_get_description(
432 struct bt_component_class
*component_class
)
434 return component_class
&& component_class
->description
?
435 component_class
->description
->str
: NULL
;
438 const char *bt_component_class_get_help(
439 struct bt_component_class
*component_class
)
441 return component_class
&& component_class
->help
?
442 component_class
->help
->str
: NULL
;
446 int bt_component_class_add_destroy_listener(struct bt_component_class
*class,
447 bt_component_class_destroy_listener_func func
, void *data
)
450 struct bt_component_class_destroy_listener listener
;
452 if (!class || class->frozen
|| !func
) {
457 listener
.func
= func
;
458 listener
.data
= data
;
459 g_array_append_val(class->destroy_listeners
, listener
);
465 extern int bt_component_class_sink_set_add_iterator_method(
466 struct bt_component_class
*component_class
,
467 bt_component_class_sink_add_iterator_method add_iterator_method
)
469 struct bt_component_class_sink
*sink_class
;
472 if (!component_class
|| component_class
->frozen
||
473 !add_iterator_method
||
474 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SINK
) {
479 sink_class
= container_of(component_class
,
480 struct bt_component_class_sink
, parent
);
481 sink_class
->methods
.add_iterator
= add_iterator_method
;
487 extern int bt_component_class_filter_set_add_iterator_method(
488 struct bt_component_class
*component_class
,
489 bt_component_class_filter_add_iterator_method add_iterator_method
)
491 struct bt_component_class_filter
*filter_class
;
494 if (!component_class
|| component_class
->frozen
||
495 !add_iterator_method
||
496 component_class
->type
!=
497 BT_COMPONENT_CLASS_TYPE_FILTER
) {
502 filter_class
= container_of(component_class
,
503 struct bt_component_class_filter
, parent
);
504 filter_class
->methods
.add_iterator
= add_iterator_method
;
510 int bt_component_class_freeze(
511 struct bt_component_class
*component_class
)
515 if (!component_class
) {
520 component_class
->frozen
= true;