Split CTF IR and CTF writer APIs and implementations
[babeltrace.git] / include / babeltrace / ctf-ir / stream-class-internal.h
1 #ifndef BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H
2 #define BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H
3
4 /*
5 * BabelTrace - CTF IR: Stream class internal
6 *
7 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 *
9 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * SOFTWARE.
28 */
29
30 #include <babeltrace/assert-internal.h>
31 #include <babeltrace/common-internal.h>
32 #include <babeltrace/ctf-ir/validation-internal.h>
33 #include <babeltrace/ctf-ir/field-types-internal.h>
34 #include <babeltrace/ctf-ir/utils-internal.h>
35 #include <babeltrace/ctf-ir/visitor.h>
36 #include <babeltrace/object-internal.h>
37 #include <babeltrace/babeltrace-internal.h>
38 #include <glib.h>
39 #include <inttypes.h>
40
41 struct bt_stream_class_common {
42 struct bt_object base;
43 GString *name;
44
45 /* Array of pointers to event class addresses */
46 GPtrArray *event_classes;
47
48 /* event class id (int64_t) to event class address */
49 GHashTable *event_classes_ht;
50 int id_set;
51 int64_t id;
52 int64_t next_event_id;
53 struct bt_field_type_common *packet_context_field_type;
54 struct bt_field_type_common *event_header_field_type;
55 struct bt_field_type_common *event_context_field_type;
56 int frozen;
57 int byte_order;
58
59 /*
60 * This flag indicates if the stream class is valid. A valid
61 * stream class is _always_ frozen.
62 */
63 int valid;
64
65 /*
66 * Unique clock class mapped to any field type within this
67 * stream class, including all the stream class's event class
68 * field types. This is only set if the stream class is frozen.
69 *
70 * If the stream class is frozen and this is still NULL, it is
71 * still possible that it becomes non-NULL because
72 * bt_stream_class_add_event_class() can add an event class
73 * containing a field type mapped to some clock class. In this
74 * case, this is the mapped clock class, and at this point, both
75 * the new event class and the stream class are frozen, so the
76 * next added event classes are expected to contain field types
77 * which only map to this specific clock class.
78 *
79 * If this is a CTF writer stream class, then this is the
80 * backing clock class of the `clock` member above.
81 */
82 struct bt_clock_class *clock_class;
83 };
84
85 struct bt_stream_class {
86 struct bt_stream_class_common common;
87 };
88
89 struct bt_event_class_common;
90
91 BT_HIDDEN
92 int bt_stream_class_common_initialize(struct bt_stream_class_common *stream_class,
93 const char *name, bt_object_release_func release_func);
94
95 BT_HIDDEN
96 void bt_stream_class_common_finalize(struct bt_stream_class_common *stream_class);
97
98 BT_HIDDEN
99 void bt_stream_class_common_freeze(struct bt_stream_class_common *stream_class);
100
101 BT_HIDDEN
102 void bt_stream_class_freeze(struct bt_stream_class *stream_class);
103
104 static inline
105 const char *bt_stream_class_common_get_name(
106 struct bt_stream_class_common *stream_class)
107 {
108 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
109 return stream_class->name->len > 0 ? stream_class->name->str : NULL;
110 }
111
112 static inline
113 int64_t bt_stream_class_common_get_id(
114 struct bt_stream_class_common *stream_class)
115 {
116 int64_t ret;
117
118 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
119
120 if (!stream_class->id_set) {
121 BT_LOGV("Stream class's ID is not set: addr=%p, name=\"%s\"",
122 stream_class,
123 bt_stream_class_common_get_name(stream_class));
124 ret = (int64_t) -1;
125 goto end;
126 }
127
128 ret = stream_class->id;
129
130 end:
131 return ret;
132 }
133
134 BT_HIDDEN
135 void bt_stream_class_common_set_byte_order(
136 struct bt_stream_class_common *stream_class, int byte_order);
137
138 BT_HIDDEN
139 int bt_stream_class_common_validate_single_clock_class(
140 struct bt_stream_class_common *stream_class,
141 struct bt_clock_class **expected_clock_class);
142
143 BT_HIDDEN
144 int bt_stream_class_common_add_event_class(
145 struct bt_stream_class_common *stream_class,
146 struct bt_event_class_common *event_class,
147 bt_validation_flag_copy_field_type_func copy_field_type_func);
148
149 BT_HIDDEN
150 int bt_stream_class_common_visit(struct bt_stream_class_common *stream_class,
151 bt_visitor visitor, void *data);
152
153 static inline
154 struct bt_trace_common *bt_stream_class_common_borrow_trace(
155 struct bt_stream_class_common *stream_class)
156 {
157 BT_ASSERT(stream_class);
158 return (void *) bt_object_borrow_parent(stream_class);
159 }
160
161 static inline
162 struct bt_trace *bt_stream_class_borrow_trace(
163 struct bt_stream_class *stream_class)
164 {
165 return BT_FROM_COMMON(bt_stream_class_common_borrow_trace(
166 BT_TO_COMMON(stream_class)));
167 }
168
169 static inline
170 struct bt_trace_common *bt_stream_class_common_get_trace(
171 struct bt_stream_class_common *stream_class)
172 {
173 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
174 return bt_get(bt_stream_class_common_borrow_trace(stream_class));
175 }
176
177 static inline
178 int bt_stream_class_common_set_name(struct bt_stream_class_common *stream_class,
179 const char *name)
180 {
181 int ret = 0;
182
183 if (!stream_class) {
184 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
185 ret = -1;
186 goto end;
187 }
188
189 if (stream_class->frozen) {
190 BT_LOGW("Invalid parameter: stream class is frozen: "
191 "addr=%p, name=\"%s\", id=%" PRId64,
192 stream_class,
193 bt_stream_class_common_get_name(stream_class),
194 bt_stream_class_common_get_id(stream_class));
195 ret = -1;
196 goto end;
197 }
198
199 if (!name) {
200 g_string_assign(stream_class->name, "");
201 } else {
202 if (strlen(name) == 0) {
203 BT_LOGW("Invalid parameter: name is empty.");
204 ret = -1;
205 goto end;
206 }
207
208 g_string_assign(stream_class->name, name);
209 }
210
211 BT_LOGV("Set stream class's name: "
212 "addr=%p, name=\"%s\", id=%" PRId64,
213 stream_class, bt_stream_class_common_get_name(stream_class),
214 bt_stream_class_common_get_id(stream_class));
215 end:
216 return ret;
217 }
218
219 static inline
220 void _bt_stream_class_common_set_id(
221 struct bt_stream_class_common *stream_class, int64_t id)
222 {
223 BT_ASSERT(stream_class);
224 stream_class->id = id;
225 stream_class->id_set = 1;
226 BT_LOGV("Set stream class's ID (internal): "
227 "addr=%p, name=\"%s\", id=%" PRId64,
228 stream_class, bt_stream_class_common_get_name(stream_class),
229 bt_stream_class_common_get_id(stream_class));
230 }
231
232 static inline
233 int bt_stream_class_common_set_id_no_check(
234 struct bt_stream_class_common *stream_class, int64_t id)
235 {
236 _bt_stream_class_common_set_id(stream_class, id);
237 return 0;
238 }
239
240 static inline
241 int bt_stream_class_common_set_id(struct bt_stream_class_common *stream_class,
242 uint64_t id_param)
243 {
244 int ret = 0;
245 int64_t id = (int64_t) id_param;
246
247 if (!stream_class) {
248 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
249 ret = -1;
250 goto end;
251 }
252
253 if (stream_class->frozen) {
254 BT_LOGW("Invalid parameter: stream class is frozen: "
255 "addr=%p, name=\"%s\", id=%" PRId64,
256 stream_class,
257 bt_stream_class_common_get_name(stream_class),
258 bt_stream_class_common_get_id(stream_class));
259 ret = -1;
260 goto end;
261 }
262
263 if (id < 0) {
264 BT_LOGW("Invalid parameter: invalid stream class's ID: "
265 "stream-class-addr=%p, stream-class-name=\"%s\", "
266 "stream-class-id=%" PRId64 ", id=%" PRIu64,
267 stream_class,
268 bt_stream_class_common_get_name(stream_class),
269 bt_stream_class_common_get_id(stream_class),
270 id_param);
271 ret = -1;
272 goto end;
273 }
274
275 ret = bt_stream_class_common_set_id_no_check(stream_class, id);
276 if (ret == 0) {
277 BT_LOGV("Set stream class's ID: "
278 "addr=%p, name=\"%s\", id=%" PRId64,
279 stream_class,
280 bt_stream_class_common_get_name(stream_class),
281 bt_stream_class_common_get_id(stream_class));
282 }
283 end:
284 return ret;
285 }
286
287 static inline
288 int64_t bt_stream_class_common_get_event_class_count(
289 struct bt_stream_class_common *stream_class)
290 {
291 int64_t ret;
292
293 if (!stream_class) {
294 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
295 ret = (int64_t) -1;
296 goto end;
297 }
298
299 ret = (int64_t) stream_class->event_classes->len;
300 end:
301 return ret;
302 }
303
304 static inline
305 struct bt_event_class_common *bt_stream_class_common_get_event_class_by_index(
306 struct bt_stream_class_common *stream_class, uint64_t index)
307 {
308 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
309 BT_ASSERT_PRE(index < stream_class->event_classes->len,
310 "Index is out of bounds: index=%" PRIu64 ", "
311 "count=%u",
312 index, stream_class->event_classes->len);
313 return bt_get(g_ptr_array_index(stream_class->event_classes, index));
314 }
315
316 static inline
317 struct bt_event_class_common *bt_stream_class_common_get_event_class_by_id(
318 struct bt_stream_class_common *stream_class, uint64_t id)
319 {
320 int64_t id_key = (int64_t) id;
321
322 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
323 BT_ASSERT_PRE(id_key >= 0,
324 "Invalid event class ID: %" PRIu64, id);
325 return bt_get(g_hash_table_lookup(stream_class->event_classes_ht,
326 &id_key));
327 }
328
329 static inline
330 struct bt_field_type_common *bt_stream_class_common_get_packet_context_field_type(
331 struct bt_stream_class_common *stream_class)
332 {
333 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
334 return bt_get(stream_class->packet_context_field_type);
335 }
336
337 static inline
338 int bt_stream_class_common_set_packet_context_field_type(
339 struct bt_stream_class_common *stream_class,
340 struct bt_field_type_common *packet_context_type)
341 {
342 int ret = 0;
343
344 if (!stream_class) {
345 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
346 ret = -1;
347 goto end;
348 }
349
350 if (stream_class->frozen) {
351 BT_LOGW("Invalid parameter: stream class is frozen: "
352 "addr=%p, name=\"%s\", id=%" PRId64,
353 stream_class, bt_stream_class_common_get_name(stream_class),
354 bt_stream_class_common_get_id(stream_class));
355 ret = -1;
356 goto end;
357 }
358
359 if (packet_context_type &&
360 bt_field_type_common_get_type_id(packet_context_type) !=
361 BT_FIELD_TYPE_ID_STRUCT) {
362 /* A packet context must be a structure. */
363 BT_LOGW("Invalid parameter: stream class's packet context field type must be a structure: "
364 "addr=%p, name=\"%s\", id=%" PRId64 ", "
365 "packet-context-ft-addr=%p, packet-context-ft-id=%s",
366 stream_class, bt_stream_class_common_get_name(stream_class),
367 bt_stream_class_common_get_id(stream_class),
368 packet_context_type,
369 bt_common_field_type_id_string(
370 bt_field_type_common_get_type_id(packet_context_type)));
371 ret = -1;
372 goto end;
373 }
374
375 bt_put(stream_class->packet_context_field_type);
376 bt_get(packet_context_type);
377 stream_class->packet_context_field_type = packet_context_type;
378 BT_LOGV("Set stream class's packet context field type: "
379 "addr=%p, name=\"%s\", id=%" PRId64 ", "
380 "packet-context-ft-addr=%p",
381 stream_class, bt_stream_class_common_get_name(stream_class),
382 bt_stream_class_common_get_id(stream_class),
383 packet_context_type);
384
385 end:
386 return ret;
387 }
388
389 static inline
390 struct bt_field_type_common *bt_stream_class_common_get_event_header_field_type(
391 struct bt_stream_class_common *stream_class)
392 {
393 struct bt_field_type_common *ret = NULL;
394
395 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
396
397 if (!stream_class->event_header_field_type) {
398 BT_LOGV("Stream class has no event header field type: "
399 "addr=%p, name=\"%s\", id=%" PRId64,
400 stream_class,
401 bt_stream_class_common_get_name(stream_class),
402 bt_stream_class_common_get_id(stream_class));
403 goto end;
404 }
405
406 ret = bt_get(stream_class->event_header_field_type);
407
408 end:
409 return ret;
410 }
411
412 static inline
413 int bt_stream_class_common_set_event_header_field_type(
414 struct bt_stream_class_common *stream_class,
415 struct bt_field_type_common *event_header_type)
416 {
417 int ret = 0;
418
419 if (!stream_class) {
420 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
421 ret = -1;
422 goto end;
423 }
424
425 if (stream_class->frozen) {
426 BT_LOGW("Invalid parameter: stream class is frozen: "
427 "addr=%p, name=\"%s\", id=%" PRId64,
428 stream_class,
429 bt_stream_class_common_get_name(stream_class),
430 bt_stream_class_common_get_id(stream_class));
431 ret = -1;
432 goto end;
433 }
434
435 if (event_header_type &&
436 bt_field_type_common_get_type_id(event_header_type) !=
437 BT_FIELD_TYPE_ID_STRUCT) {
438 /* An event header must be a structure. */
439 BT_LOGW("Invalid parameter: stream class's event header field type must be a structure: "
440 "addr=%p, name=\"%s\", id=%" PRId64 ", "
441 "event-header-ft-addr=%p, event-header-ft-id=%s",
442 stream_class, bt_stream_class_common_get_name(stream_class),
443 bt_stream_class_common_get_id(stream_class),
444 event_header_type,
445 bt_common_field_type_id_string(
446 bt_field_type_common_get_type_id(event_header_type)));
447 ret = -1;
448 goto end;
449 }
450
451 bt_put(stream_class->event_header_field_type);
452 stream_class->event_header_field_type = bt_get(event_header_type);
453 BT_LOGV("Set stream class's event header field type: "
454 "addr=%p, name=\"%s\", id=%" PRId64 ", "
455 "event-header-ft-addr=%p",
456 stream_class, bt_stream_class_common_get_name(stream_class),
457 bt_stream_class_common_get_id(stream_class),
458 event_header_type);
459 end:
460 return ret;
461 }
462
463 static inline
464 struct bt_field_type_common *bt_stream_class_common_get_event_context_field_type(
465 struct bt_stream_class_common *stream_class)
466 {
467 struct bt_field_type_common *ret = NULL;
468
469 BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class");
470
471 if (!stream_class->event_context_field_type) {
472 goto end;
473 }
474
475 ret = bt_get(stream_class->event_context_field_type);
476
477 end:
478 return ret;
479 }
480
481 static inline
482 int bt_stream_class_common_set_event_context_field_type(
483 struct bt_stream_class_common *stream_class,
484 struct bt_field_type_common *event_context_type)
485 {
486 int ret = 0;
487
488 if (!stream_class) {
489 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
490 ret = -1;
491 goto end;
492 }
493
494 if (stream_class->frozen) {
495 BT_LOGW("Invalid parameter: stream class is frozen: "
496 "addr=%p, name=\"%s\", id=%" PRId64,
497 stream_class, bt_stream_class_common_get_name(stream_class),
498 bt_stream_class_common_get_id(stream_class));
499 ret = -1;
500 goto end;
501 }
502
503 if (event_context_type &&
504 bt_field_type_common_get_type_id(event_context_type) !=
505 BT_FIELD_TYPE_ID_STRUCT) {
506 /* A packet context must be a structure. */
507 BT_LOGW("Invalid parameter: stream class's event context field type must be a structure: "
508 "addr=%p, name=\"%s\", id=%" PRId64 ", "
509 "event-context-ft-addr=%p, event-context-ft-id=%s",
510 stream_class, bt_stream_class_common_get_name(stream_class),
511 bt_stream_class_common_get_id(stream_class),
512 event_context_type,
513 bt_common_field_type_id_string(
514 bt_field_type_common_get_type_id(event_context_type)));
515 ret = -1;
516 goto end;
517 }
518
519 bt_put(stream_class->event_context_field_type);
520 stream_class->event_context_field_type = bt_get(event_context_type);
521 BT_LOGV("Set stream class's event context field type: "
522 "addr=%p, name=\"%s\", id=%" PRId64 ", "
523 "event-context-ft-addr=%p",
524 stream_class, bt_stream_class_common_get_name(stream_class),
525 bt_stream_class_common_get_id(stream_class),
526 event_context_type);
527 end:
528 return ret;
529 }
530
531 #endif /* BABELTRACE_CTF_IR_STREAM_CLASS_INTERNAL_H */
This page took 0.040091 seconds and 4 git commands to generate.