plugin-dev.h: put selector (type) close to union in structures
[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,
102 bt_component_class_source_init_iterator_method init_iterator_method)
103{
104 struct bt_component_class_source *source_class = NULL;
105 int ret;
106
107 if (!name || !init_iterator_method) {
6ba0b073
PP
108 goto end;
109 }
fb2dcc52 110
d3e4dcd8
PP
111 source_class = g_new0(struct bt_component_class_source, 1);
112 if (!source_class) {
fb2dcc52
JG
113 goto end;
114 }
115
d3e4dcd8
PP
116 ret = bt_component_class_init(&source_class->parent,
117 BT_COMPONENT_CLASS_TYPE_SOURCE, name);
118 if (ret) {
119 /*
120 * If bt_component_class_init() fails, the component
121 * class is put, therefore its memory is already
122 * freed.
123 */
124 source_class = NULL;
125 goto end;
126 }
127
128 source_class->methods.init_iterator = init_iterator_method;
129
130end:
131 return &source_class->parent;
132}
133
134struct bt_component_class *bt_component_class_filter_create(const char *name,
135 bt_component_class_filter_init_iterator_method init_iterator_method)
136{
137 struct bt_component_class_filter *filter_class = NULL;
138 int ret;
139
140 if (!name || !init_iterator_method) {
fb2dcc52
JG
141 goto end;
142 }
6ba0b073 143
d3e4dcd8
PP
144 filter_class = g_new0(struct bt_component_class_filter, 1);
145 if (!filter_class) {
146 goto end;
6ba0b073
PP
147 }
148
d3e4dcd8
PP
149 ret = bt_component_class_init(&filter_class->parent,
150 BT_COMPONENT_CLASS_TYPE_FILTER, name);
151 if (ret) {
152 /*
153 * If bt_component_class_init() fails, the component
154 * class is put, therefore its memory is already
155 * freed.
156 */
157 filter_class = NULL;
33b34c43
PP
158 goto end;
159 }
d3e4dcd8
PP
160
161 filter_class->methods.init_iterator = init_iterator_method;
162
fb2dcc52 163end:
d3e4dcd8
PP
164 return &filter_class->parent;
165}
166
167struct bt_component_class *bt_component_class_sink_create(const char *name,
168 bt_component_class_sink_consume_method consume_method)
169{
170 struct bt_component_class_sink *sink_class = NULL;
171 int ret;
172
173 if (!name || !consume_method) {
174 goto end;
175 }
176
177 sink_class = g_new0(struct bt_component_class_sink, 1);
178 if (!sink_class) {
179 goto end;
180 }
181
182 ret = bt_component_class_init(&sink_class->parent,
183 BT_COMPONENT_CLASS_TYPE_SINK, name);
184 if (ret) {
185 /*
186 * If bt_component_class_init() fails, the component
187 * class is put, therefore its memory is already
188 * freed.
189 */
190 sink_class = NULL;
191 goto end;
192 }
193
194 sink_class->methods.consume = consume_method;
195
196end:
197 return &sink_class->parent;
198}
199
200int bt_component_class_set_init_method(
201 struct bt_component_class *component_class,
202 bt_component_class_init_method init_method)
203{
204 int ret = 0;
205
1e4d8103 206 if (!component_class || component_class->frozen || !init_method) {
d3e4dcd8
PP
207 ret = -1;
208 goto end;
209 }
210
211 component_class->methods.init = init_method;
212
213end:
214 return ret;
215}
216
217int bt_component_class_set_destroy_method(
218 struct bt_component_class *component_class,
219 bt_component_class_destroy_method destroy_method)
220{
221 int ret = 0;
222
1e4d8103 223 if (!component_class || component_class->frozen || !destroy_method) {
d3e4dcd8
PP
224 ret = -1;
225 goto end;
226 }
227
228 component_class->methods.destroy = destroy_method;
229
230end:
231 return ret;
232}
233
234extern int bt_component_class_set_description(
235 struct bt_component_class *component_class,
236 const char *description)
237{
238 int ret = 0;
239
1e4d8103 240 if (!component_class || component_class->frozen || !description) {
d3e4dcd8
PP
241 ret = -1;
242 goto end;
243 }
244
245 g_string_assign(component_class->description, description);
246
247end:
248 return ret;
fb2dcc52 249}
38b48196
JG
250
251const char *bt_component_class_get_name(
252 struct bt_component_class *component_class)
253{
254 return component_class ? component_class->name->str : NULL;
255}
256
d3e4dcd8 257enum bt_component_class_type bt_component_class_get_type(
38b48196
JG
258 struct bt_component_class *component_class)
259{
260 return component_class ? component_class->type :
d3e4dcd8 261 BT_COMPONENT_CLASS_TYPE_UNKNOWN;
38b48196
JG
262}
263
33b34c43 264const char *bt_component_class_get_description(
38b48196
JG
265 struct bt_component_class *component_class)
266{
6ba0b073
PP
267 return component_class && component_class->description ?
268 component_class->description->str : NULL;
38b48196 269}
7c7c0433 270
33b34c43
PP
271BT_HIDDEN
272int bt_component_class_add_destroy_listener(struct bt_component_class *class,
273 bt_component_class_destroy_listener_func func, void *data)
7c7c0433 274{
33b34c43 275 int ret = 0;
d3e4dcd8 276 struct bt_component_class_destroy_listener listener;
33b34c43 277
1e4d8103 278 if (!class || class->frozen || !func) {
33b34c43
PP
279 ret = -1;
280 goto end;
281 }
282
283 listener.func = func;
284 listener.data = data;
285 g_array_append_val(class->destroy_listeners, listener);
286
287end:
288 return ret;
7c7c0433 289}
d3e4dcd8
PP
290
291extern int bt_component_class_sink_set_add_iterator_method(
292 struct bt_component_class *component_class,
293 bt_component_class_sink_add_iterator_method add_iterator_method)
294{
295 struct bt_component_class_sink *sink_class;
296 int ret = 0;
297
1e4d8103
PP
298 if (!component_class || component_class->frozen ||
299 !add_iterator_method ||
d3e4dcd8
PP
300 component_class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
301 ret = -1;
302 goto end;
303 }
304
305 sink_class = container_of(component_class,
306 struct bt_component_class_sink, parent);
307 sink_class->methods.add_iterator = add_iterator_method;
308
309end:
310 return ret;
311}
312
313extern int bt_component_class_filter_set_add_iterator_method(
314 struct bt_component_class *component_class,
315 bt_component_class_filter_add_iterator_method add_iterator_method)
316{
317 struct bt_component_class_filter *filter_class;
318 int ret = 0;
319
1e4d8103
PP
320 if (!component_class || component_class->frozen ||
321 !add_iterator_method ||
d3e4dcd8
PP
322 component_class->type !=
323 BT_COMPONENT_CLASS_TYPE_FILTER) {
324 ret = -1;
325 goto end;
326 }
327
328 filter_class = container_of(component_class,
329 struct bt_component_class_filter, parent);
330 filter_class->methods.add_iterator = add_iterator_method;
331
332end:
333 return ret;
334}
1e4d8103
PP
335
336int bt_component_class_freeze(
337 struct bt_component_class *component_class)
338{
339 int ret = 0;
340
341 if (!component_class) {
342 ret = -1;
343 goto end;
344 }
345
346 component_class->frozen = true;
347
348end:
349 return ret;
350}
This page took 0.041289 seconds and 4 git commands to generate.