6 #include <babeltrace2/babeltrace.h>
8 /* Sink component's private data */
10 /* Upstream message iterator (owned by this) */
11 bt_message_iterator
*message_iterator
;
13 /* Current event message index */
18 * Initializes the sink component.
21 bt_component_class_initialize_method_status
epitome_out_initialize(
22 bt_self_component_sink
*self_component_sink
,
23 bt_self_component_sink_configuration
*configuration
,
24 const bt_value
*params
, void *initialize_method_data
)
26 /* Allocate a private data structure */
27 struct epitome_out
*epitome_out
= malloc(sizeof(*epitome_out
));
29 /* Initialize the first event message's index */
30 epitome_out
->index
= 1;
32 /* Set the component's user data to our private data structure */
33 bt_self_component_set_data(
34 bt_self_component_sink_as_self_component(self_component_sink
),
38 * Add an input port named `in` to the sink component.
40 * This is needed so that this sink component can be connected to a
41 * filter or a source component. With a connected upstream
42 * component, this sink component can create a message iterator
43 * to consume messages.
45 bt_self_component_sink_add_input_port(self_component_sink
,
48 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK
;
52 * Finalizes the sink component.
55 void epitome_out_finalize(bt_self_component_sink
*self_component_sink
)
57 /* Retrieve our private data from the component's user data */
58 struct epitome_out
*epitome_out
= bt_self_component_get_data(
59 bt_self_component_sink_as_self_component(self_component_sink
));
61 /* Free the allocated structure */
66 * Called when the trace processing graph containing the sink component
69 * This is where we can create our upstream message iterator.
72 bt_component_class_sink_graph_is_configured_method_status
73 epitome_out_graph_is_configured(bt_self_component_sink
*self_component_sink
)
75 /* Retrieve our private data from the component's user data */
76 struct epitome_out
*epitome_out
= bt_self_component_get_data(
77 bt_self_component_sink_as_self_component(self_component_sink
));
79 /* Borrow our unique port */
80 bt_self_component_port_input
*in_port
=
81 bt_self_component_sink_borrow_input_port_by_index(
82 self_component_sink
, 0);
84 /* Create the uptream message iterator */
85 bt_message_iterator_create_from_sink_component(self_component_sink
,
86 in_port
, &epitome_out
->message_iterator
);
88 return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK
;
92 * Prints a line for `message`, if it's an event message, to the
96 void print_message(struct epitome_out
*epitome_out
, const bt_message
*message
)
98 /* Discard if it's not an event message */
99 if (bt_message_get_type(message
) != BT_MESSAGE_TYPE_EVENT
) {
103 /* Borrow the event message's event and its class */
104 const bt_event
*event
=
105 bt_message_event_borrow_event_const(message
);
106 const bt_event_class
*event_class
= bt_event_borrow_class_const(event
);
108 /* Get the number of payload field members */
109 const bt_field
*payload_field
=
110 bt_event_borrow_payload_field_const(event
);
111 uint64_t member_count
= bt_field_class_structure_get_member_count(
112 bt_field_borrow_class_const(payload_field
));
114 /* Write a corresponding line to the standard output */
115 printf("#%" PRIu64
": %s (%" PRIu64
" payload member%s)\n",
116 epitome_out
->index
, bt_event_class_get_name(event_class
),
117 member_count
, member_count
== 1 ? "" : "s");
119 /* Increment the current event message's index */
120 epitome_out
->index
++;
127 * Consumes a batch of messages and writes the corresponding lines to
128 * the standard output.
130 bt_component_class_sink_consume_method_status
epitome_out_consume(
131 bt_self_component_sink
*self_component_sink
)
133 bt_component_class_sink_consume_method_status status
=
134 BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK
;
136 /* Retrieve our private data from the component's user data */
137 struct epitome_out
*epitome_out
= bt_self_component_get_data(
138 bt_self_component_sink_as_self_component(self_component_sink
));
140 /* Consume a batch of messages from the upstream message iterator */
141 bt_message_array_const messages
;
142 uint64_t message_count
;
143 bt_message_iterator_next_status next_status
=
144 bt_message_iterator_next(epitome_out
->message_iterator
, &messages
,
147 switch (next_status
) {
148 case BT_MESSAGE_ITERATOR_NEXT_STATUS_END
:
149 /* End of iteration: put the message iterator's reference */
150 bt_message_iterator_put_ref(epitome_out
->message_iterator
);
151 status
= BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_END
;
153 case BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN
:
154 status
= BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_AGAIN
;
156 case BT_MESSAGE_ITERATOR_NEXT_STATUS_MEMORY_ERROR
:
157 status
= BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_MEMORY_ERROR
;
159 case BT_MESSAGE_ITERATOR_NEXT_STATUS_ERROR
:
160 status
= BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR
;
166 /* For each consumed message */
167 for (uint64_t i
= 0; i
< message_count
; i
++) {
168 /* Current message */
169 const bt_message
*message
= messages
[i
];
171 /* Print line for current message if it's an event message */
172 print_message(epitome_out
, message
);
174 /* Put this message's reference */
175 bt_message_put_ref(message
);
185 /* Define the `epitome` plugin */
188 /* Define the `output` sink component class */
189 BT_PLUGIN_SINK_COMPONENT_CLASS(output
, epitome_out_consume
);
191 /* Set some of the `output` sink component class's optional methods */
192 BT_PLUGIN_SINK_COMPONENT_CLASS_INITIALIZE_METHOD(output
,
193 epitome_out_initialize
);
194 BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(output
, epitome_out_finalize
);
195 BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD(output
,
196 epitome_out_graph_is_configured
);