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_query_method(
232 struct bt_component_class
*component_class
,
233 bt_component_class_query_method query_method
)
237 if (!component_class
|| component_class
->frozen
|| !query_method
) {
242 component_class
->methods
.query
= query_method
;
248 int bt_component_class_set_new_connection_method(
249 struct bt_component_class
*component_class
,
250 bt_component_class_new_connection_method new_connection_method
)
254 if (!component_class
|| component_class
->frozen
||
255 !new_connection_method
) {
260 component_class
->methods
.new_connection_method
= new_connection_method
;
266 int bt_component_class_set_destroy_method(
267 struct bt_component_class
*component_class
,
268 bt_component_class_destroy_method destroy_method
)
272 if (!component_class
|| component_class
->frozen
|| !destroy_method
) {
277 component_class
->methods
.destroy
= destroy_method
;
283 int bt_component_class_source_set_notification_iterator_init_method(
284 struct bt_component_class
*component_class
,
285 bt_component_class_notification_iterator_init_method notification_iterator_init_method
)
287 struct bt_component_class_source
*source_class
;
290 if (!component_class
|| component_class
->frozen
||
291 !notification_iterator_init_method
||
292 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
297 source_class
= container_of(component_class
,
298 struct bt_component_class_source
, parent
);
299 source_class
->methods
.iterator
.init
= notification_iterator_init_method
;
305 int bt_component_class_source_set_notification_iterator_destroy_method(
306 struct bt_component_class
*component_class
,
307 bt_component_class_notification_iterator_destroy_method notification_iterator_destroy_method
)
309 struct bt_component_class_source
*source_class
;
312 if (!component_class
|| component_class
->frozen
||
313 !notification_iterator_destroy_method
||
314 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
319 source_class
= container_of(component_class
,
320 struct bt_component_class_source
, parent
);
321 source_class
->methods
.iterator
.destroy
=
322 notification_iterator_destroy_method
;
328 int bt_component_class_source_set_notification_iterator_seek_time_method(
329 struct bt_component_class
*component_class
,
330 bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method
)
332 struct bt_component_class_source
*source_class
;
335 if (!component_class
|| component_class
->frozen
||
336 !notification_iterator_seek_time_method
||
337 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
342 source_class
= container_of(component_class
,
343 struct bt_component_class_source
, parent
);
344 source_class
->methods
.iterator
.seek_time
=
345 notification_iterator_seek_time_method
;
351 int bt_component_class_filter_set_notification_iterator_init_method(
352 struct bt_component_class
*component_class
,
353 bt_component_class_notification_iterator_init_method notification_iterator_init_method
)
355 struct bt_component_class_filter
*filter_class
;
358 if (!component_class
|| component_class
->frozen
||
359 !notification_iterator_init_method
||
360 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
365 filter_class
= container_of(component_class
,
366 struct bt_component_class_filter
, parent
);
367 filter_class
->methods
.iterator
.init
= notification_iterator_init_method
;
373 int bt_component_class_filter_set_notification_iterator_destroy_method(
374 struct bt_component_class
*component_class
,
375 bt_component_class_notification_iterator_destroy_method notification_iterator_destroy_method
)
377 struct bt_component_class_filter
*filter_class
;
380 if (!component_class
|| component_class
->frozen
||
381 !notification_iterator_destroy_method
||
382 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
387 filter_class
= container_of(component_class
,
388 struct bt_component_class_filter
, parent
);
389 filter_class
->methods
.iterator
.destroy
=
390 notification_iterator_destroy_method
;
396 int bt_component_class_filter_set_notification_iterator_seek_time_method(
397 struct bt_component_class
*component_class
,
398 bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method
)
400 struct bt_component_class_filter
*filter_class
;
403 if (!component_class
|| component_class
->frozen
||
404 !notification_iterator_seek_time_method
||
405 component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
410 filter_class
= container_of(component_class
,
411 struct bt_component_class_filter
, parent
);
412 filter_class
->methods
.iterator
.seek_time
=
413 notification_iterator_seek_time_method
;
419 int bt_component_class_set_description(
420 struct bt_component_class
*component_class
,
421 const char *description
)
425 if (!component_class
|| component_class
->frozen
|| !description
) {
430 g_string_assign(component_class
->description
, description
);
436 int bt_component_class_set_help(
437 struct bt_component_class
*component_class
,
442 if (!component_class
|| component_class
->frozen
|| !help
) {
447 g_string_assign(component_class
->help
, help
);
453 const char *bt_component_class_get_name(
454 struct bt_component_class
*component_class
)
456 return component_class
? component_class
->name
->str
: NULL
;
459 enum bt_component_class_type
bt_component_class_get_type(
460 struct bt_component_class
*component_class
)
462 return component_class
? component_class
->type
:
463 BT_COMPONENT_CLASS_TYPE_UNKNOWN
;
466 const char *bt_component_class_get_description(
467 struct bt_component_class
*component_class
)
469 return component_class
&& component_class
->description
&&
470 component_class
->description
->str
[0] != '\0' ?
471 component_class
->description
->str
: NULL
;
474 const char *bt_component_class_get_help(
475 struct bt_component_class
*component_class
)
477 return component_class
&& component_class
->help
&&
478 component_class
->help
->str
[0] != '\0' ?
479 component_class
->help
->str
: NULL
;
483 int bt_component_class_add_destroy_listener(struct bt_component_class
*class,
484 bt_component_class_destroy_listener_func func
, void *data
)
487 struct bt_component_class_destroy_listener listener
;
489 if (!class || class->frozen
|| !func
) {
494 listener
.func
= func
;
495 listener
.data
= data
;
496 g_array_append_val(class->destroy_listeners
, listener
);
502 int bt_component_class_freeze(
503 struct bt_component_class
*component_class
)
507 if (!component_class
) {
512 component_class
->frozen
= true;
518 struct bt_value
*bt_component_class_query(
519 struct bt_component_class
*component_class
,
520 const char *object
, struct bt_value
*params
)
522 struct bt_value
*results
= NULL
;
524 if (!component_class
|| !object
|| !params
||
525 !component_class
->methods
.query
) {
529 results
= component_class
->methods
.query(component_class
,