1 #ifndef BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H
2 #define BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H
5 * Copyright 2014 EfficiOS Inc.
7 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * The Common Trace Format (CTF) Specification is available at
28 * http://www.efficios.com/ctf
31 #include "common/assert.h"
32 #include "common/macros.h"
33 #include "common/common.h"
34 #include <babeltrace2/ctf-writer/field-types.h>
35 #include <babeltrace2/ctf-writer/visitor.h>
39 #include "field-types.h"
41 #include "stream-class.h"
43 #include "validation.h"
45 struct bt_ctf_stream_class_common
{
46 struct bt_ctf_object base
;
49 /* Array of pointers to event class addresses */
50 GPtrArray
*event_classes
;
52 /* event class id (int64_t) to event class address */
53 GHashTable
*event_classes_ht
;
56 int64_t next_event_id
;
57 struct bt_ctf_field_type_common
*packet_context_field_type
;
58 struct bt_ctf_field_type_common
*event_header_field_type
;
59 struct bt_ctf_field_type_common
*event_context_field_type
;
64 * This flag indicates if the stream class is valid. A valid
65 * stream class is _always_ frozen.
70 * Unique clock class mapped to any field type within this
71 * stream class, including all the stream class's event class
72 * field types. This is only set if the stream class is frozen.
74 * If the stream class is frozen and this is still NULL, it is
75 * still possible that it becomes non-NULL because
76 * bt_ctf_stream_class_add_event_class() can add an event class
77 * containing a field type mapped to some clock class. In this
78 * case, this is the mapped clock class, and at this point, both
79 * the new event class and the stream class are frozen, so the
80 * next added event classes are expected to contain field types
81 * which only map to this specific clock class.
83 * If this is a CTF writer stream class, then this is the
84 * backing clock class of the `clock` member above.
86 struct bt_ctf_clock_class
*clock_class
;
89 struct bt_ctf_event_class_common
;
92 int bt_ctf_stream_class_common_initialize(struct bt_ctf_stream_class_common
*stream_class
,
93 const char *name
, bt_ctf_object_release_func release_func
);
96 void bt_ctf_stream_class_common_finalize(struct bt_ctf_stream_class_common
*stream_class
);
99 void bt_ctf_stream_class_common_freeze(struct bt_ctf_stream_class_common
*stream_class
);
102 const char *bt_ctf_stream_class_common_get_name(
103 struct bt_ctf_stream_class_common
*stream_class
)
105 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
106 return stream_class
->name
->len
> 0 ? stream_class
->name
->str
: NULL
;
110 int64_t bt_ctf_stream_class_common_get_id(
111 struct bt_ctf_stream_class_common
*stream_class
)
115 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
117 if (!stream_class
->id_set
) {
118 BT_LOGV("Stream class's ID is not set: addr=%p, name=\"%s\"",
120 bt_ctf_stream_class_common_get_name(stream_class
));
125 ret
= stream_class
->id
;
132 void bt_ctf_stream_class_common_set_byte_order(
133 struct bt_ctf_stream_class_common
*stream_class
, int byte_order
);
136 int bt_ctf_stream_class_common_validate_single_clock_class(
137 struct bt_ctf_stream_class_common
*stream_class
,
138 struct bt_ctf_clock_class
**expected_clock_class
);
141 int bt_ctf_stream_class_common_add_event_class(
142 struct bt_ctf_stream_class_common
*stream_class
,
143 struct bt_ctf_event_class_common
*event_class
,
144 bt_ctf_validation_flag_copy_field_type_func copy_field_type_func
);
147 int bt_ctf_stream_class_common_visit(struct bt_ctf_stream_class_common
*stream_class
,
148 bt_ctf_visitor visitor
, void *data
);
151 int bt_ctf_stream_class_visit(struct bt_ctf_stream_class
*stream_class
,
152 bt_ctf_visitor visitor
, void *data
);
155 struct bt_ctf_trace_common
*bt_ctf_stream_class_common_borrow_trace(
156 struct bt_ctf_stream_class_common
*stream_class
)
158 BT_ASSERT(stream_class
);
159 return (void *) bt_ctf_object_borrow_parent(&stream_class
->base
);
163 int bt_ctf_stream_class_common_set_name(struct bt_ctf_stream_class_common
*stream_class
,
169 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
174 if (stream_class
->frozen
) {
175 BT_LOGW("Invalid parameter: stream class is frozen: "
176 "addr=%p, name=\"%s\", id=%" PRId64
,
178 bt_ctf_stream_class_common_get_name(stream_class
),
179 bt_ctf_stream_class_common_get_id(stream_class
));
185 g_string_assign(stream_class
->name
, "");
187 if (strlen(name
) == 0) {
188 BT_LOGW("Invalid parameter: name is empty.");
193 g_string_assign(stream_class
->name
, name
);
196 BT_LOGV("Set stream class's name: "
197 "addr=%p, name=\"%s\", id=%" PRId64
,
198 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
199 bt_ctf_stream_class_common_get_id(stream_class
));
205 void _bt_ctf_stream_class_common_set_id(
206 struct bt_ctf_stream_class_common
*stream_class
, int64_t id
)
208 BT_ASSERT(stream_class
);
209 stream_class
->id
= id
;
210 stream_class
->id_set
= 1;
211 BT_LOGV("Set stream class's ID (internal): "
212 "addr=%p, name=\"%s\", id=%" PRId64
,
213 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
214 bt_ctf_stream_class_common_get_id(stream_class
));
218 int bt_ctf_stream_class_common_set_id_no_check(
219 struct bt_ctf_stream_class_common
*stream_class
, int64_t id
)
221 _bt_ctf_stream_class_common_set_id(stream_class
, id
);
226 int bt_ctf_stream_class_common_set_id(struct bt_ctf_stream_class_common
*stream_class
,
230 int64_t id
= (int64_t) id_param
;
233 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
238 if (stream_class
->frozen
) {
239 BT_LOGW("Invalid parameter: stream class is frozen: "
240 "addr=%p, name=\"%s\", id=%" PRId64
,
242 bt_ctf_stream_class_common_get_name(stream_class
),
243 bt_ctf_stream_class_common_get_id(stream_class
));
249 BT_LOGW("Invalid parameter: invalid stream class's ID: "
250 "stream-class-addr=%p, stream-class-name=\"%s\", "
251 "stream-class-id=%" PRId64
", id=%" PRIu64
,
253 bt_ctf_stream_class_common_get_name(stream_class
),
254 bt_ctf_stream_class_common_get_id(stream_class
),
260 ret
= bt_ctf_stream_class_common_set_id_no_check(stream_class
, id
);
262 BT_LOGV("Set stream class's ID: "
263 "addr=%p, name=\"%s\", id=%" PRId64
,
265 bt_ctf_stream_class_common_get_name(stream_class
),
266 bt_ctf_stream_class_common_get_id(stream_class
));
273 int64_t bt_ctf_stream_class_common_get_event_class_count(
274 struct bt_ctf_stream_class_common
*stream_class
)
279 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
284 ret
= (int64_t) stream_class
->event_classes
->len
;
290 struct bt_ctf_event_class_common
*bt_ctf_stream_class_common_borrow_event_class_by_index(
291 struct bt_ctf_stream_class_common
*stream_class
, uint64_t index
)
293 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
294 BT_CTF_ASSERT_PRE(index
< stream_class
->event_classes
->len
,
295 "Index is out of bounds: index=%" PRIu64
", "
297 index
, stream_class
->event_classes
->len
);
298 return g_ptr_array_index(stream_class
->event_classes
, index
);
302 struct bt_ctf_event_class_common
*bt_ctf_stream_class_common_borrow_event_class_by_id(
303 struct bt_ctf_stream_class_common
*stream_class
, uint64_t id
)
305 int64_t id_key
= (int64_t) id
;
307 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
308 BT_CTF_ASSERT_PRE(id_key
>= 0,
309 "Invalid event class ID: %" PRIu64
, id
);
310 return g_hash_table_lookup(stream_class
->event_classes_ht
,
315 struct bt_ctf_field_type_common
*
316 bt_ctf_stream_class_common_borrow_packet_context_field_type(
317 struct bt_ctf_stream_class_common
*stream_class
)
319 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
320 return stream_class
->packet_context_field_type
;
324 int bt_ctf_stream_class_common_set_packet_context_field_type(
325 struct bt_ctf_stream_class_common
*stream_class
,
326 struct bt_ctf_field_type_common
*packet_context_type
)
331 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
336 if (stream_class
->frozen
) {
337 BT_LOGW("Invalid parameter: stream class is frozen: "
338 "addr=%p, name=\"%s\", id=%" PRId64
,
339 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
340 bt_ctf_stream_class_common_get_id(stream_class
));
345 if (packet_context_type
&&
346 bt_ctf_field_type_common_get_type_id(packet_context_type
) !=
347 BT_CTF_FIELD_TYPE_ID_STRUCT
) {
348 /* A packet context must be a structure. */
349 BT_LOGW("Invalid parameter: stream class's packet context field type must be a structure: "
350 "addr=%p, name=\"%s\", id=%" PRId64
", "
351 "packet-context-ft-addr=%p, packet-context-ft-id=%s",
352 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
353 bt_ctf_stream_class_common_get_id(stream_class
),
355 bt_ctf_field_type_id_string(
356 bt_ctf_field_type_common_get_type_id(packet_context_type
)));
361 bt_ctf_object_put_ref(stream_class
->packet_context_field_type
);
362 stream_class
->packet_context_field_type
= packet_context_type
;
363 bt_ctf_object_get_ref(stream_class
->packet_context_field_type
);
364 BT_LOGV("Set stream class's packet context field type: "
365 "addr=%p, name=\"%s\", id=%" PRId64
", "
366 "packet-context-ft-addr=%p",
367 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
368 bt_ctf_stream_class_common_get_id(stream_class
),
369 packet_context_type
);
376 struct bt_ctf_field_type_common
*
377 bt_ctf_stream_class_common_borrow_event_header_field_type(
378 struct bt_ctf_stream_class_common
*stream_class
)
380 struct bt_ctf_field_type_common
*ret
= NULL
;
382 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
384 if (!stream_class
->event_header_field_type
) {
385 BT_LOGV("Stream class has no event header field type: "
386 "addr=%p, name=\"%s\", id=%" PRId64
,
388 bt_ctf_stream_class_common_get_name(stream_class
),
389 bt_ctf_stream_class_common_get_id(stream_class
));
393 ret
= stream_class
->event_header_field_type
;
400 int bt_ctf_stream_class_common_set_event_header_field_type(
401 struct bt_ctf_stream_class_common
*stream_class
,
402 struct bt_ctf_field_type_common
*event_header_type
)
407 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
412 if (stream_class
->frozen
) {
413 BT_LOGW("Invalid parameter: stream class is frozen: "
414 "addr=%p, name=\"%s\", id=%" PRId64
,
416 bt_ctf_stream_class_common_get_name(stream_class
),
417 bt_ctf_stream_class_common_get_id(stream_class
));
422 if (event_header_type
&&
423 bt_ctf_field_type_common_get_type_id(event_header_type
) !=
424 BT_CTF_FIELD_TYPE_ID_STRUCT
) {
425 /* An event header must be a structure. */
426 BT_LOGW("Invalid parameter: stream class's event header field type must be a structure: "
427 "addr=%p, name=\"%s\", id=%" PRId64
", "
428 "event-header-ft-addr=%p, event-header-ft-id=%s",
429 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
430 bt_ctf_stream_class_common_get_id(stream_class
),
432 bt_ctf_field_type_id_string(
433 bt_ctf_field_type_common_get_type_id(event_header_type
)));
438 bt_ctf_object_put_ref(stream_class
->event_header_field_type
);
439 stream_class
->event_header_field_type
= event_header_type
;
440 bt_ctf_object_get_ref(stream_class
->event_header_field_type
);
441 BT_LOGV("Set stream class's event header field type: "
442 "addr=%p, name=\"%s\", id=%" PRId64
", "
443 "event-header-ft-addr=%p",
444 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
445 bt_ctf_stream_class_common_get_id(stream_class
),
452 struct bt_ctf_field_type_common
*
453 bt_ctf_stream_class_common_borrow_event_context_field_type(
454 struct bt_ctf_stream_class_common
*stream_class
)
456 struct bt_ctf_field_type_common
*ret
= NULL
;
458 BT_CTF_ASSERT_PRE_NON_NULL(stream_class
, "Stream class");
460 if (!stream_class
->event_context_field_type
) {
464 ret
= stream_class
->event_context_field_type
;
471 int bt_ctf_stream_class_common_set_event_context_field_type(
472 struct bt_ctf_stream_class_common
*stream_class
,
473 struct bt_ctf_field_type_common
*event_context_type
)
478 BT_LOGW_STR("Invalid parameter: stream class is NULL.");
483 if (stream_class
->frozen
) {
484 BT_LOGW("Invalid parameter: stream class is frozen: "
485 "addr=%p, name=\"%s\", id=%" PRId64
,
486 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
487 bt_ctf_stream_class_common_get_id(stream_class
));
492 if (event_context_type
&&
493 bt_ctf_field_type_common_get_type_id(event_context_type
) !=
494 BT_CTF_FIELD_TYPE_ID_STRUCT
) {
495 /* A packet context must be a structure. */
496 BT_LOGW("Invalid parameter: stream class's event context field type must be a structure: "
497 "addr=%p, name=\"%s\", id=%" PRId64
", "
498 "event-context-ft-addr=%p, event-context-ft-id=%s",
499 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
500 bt_ctf_stream_class_common_get_id(stream_class
),
502 bt_ctf_field_type_id_string(
503 bt_ctf_field_type_common_get_type_id(event_context_type
)));
508 bt_ctf_object_put_ref(stream_class
->event_context_field_type
);
509 stream_class
->event_context_field_type
= event_context_type
;
510 bt_ctf_object_get_ref(stream_class
->event_context_field_type
);
511 BT_LOGV("Set stream class's event context field type: "
512 "addr=%p, name=\"%s\", id=%" PRId64
", "
513 "event-context-ft-addr=%p",
514 stream_class
, bt_ctf_stream_class_common_get_name(stream_class
),
515 bt_ctf_stream_class_common_get_id(stream_class
),
521 struct bt_ctf_stream_class
{
522 struct bt_ctf_stream_class_common common
;
523 struct bt_ctf_clock
*clock
;
524 int64_t next_stream_id
;
527 struct metadata_context
;
530 int bt_ctf_stream_class_serialize(struct bt_ctf_stream_class
*stream_class
,
531 struct metadata_context
*context
);
534 int bt_ctf_stream_class_map_clock_class(
535 struct bt_ctf_stream_class
*stream_class
,
536 struct bt_ctf_field_type
*packet_context_type
,
537 struct bt_ctf_field_type
*event_header_type
);
539 #endif /* BABELTRACE_CTF_WRITER_STREAM_CLASS_INTERNAL_H */