852ca3f70775c13e39aeadbdc37c6c0e71627e16
[babeltrace.git] / doc / api / libbabeltrace2 / examples / epitome.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdint.h>
4 #include <inttypes.h>
5 #include <string.h>
6 #include <babeltrace2/babeltrace.h>
7
8 /* Sink component's private data */
9 struct epitome_out {
10 /* Upstream message iterator (owned by this) */
11 bt_message_iterator *message_iterator;
12
13 /* Current event message index */
14 uint64_t index;
15 };
16
17 /*
18 * Initializes the sink component.
19 */
20 static
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)
25 {
26 /* Allocate a private data structure */
27 struct epitome_out *epitome_out = malloc(sizeof(*epitome_out));
28
29 /* Initialize the first event message's index */
30 epitome_out->index = 1;
31
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),
35 epitome_out);
36
37 /*
38 * Add an input port named `in` to the sink component.
39 *
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.
44 */
45 bt_self_component_sink_add_input_port(self_component_sink,
46 "in", NULL, NULL);
47
48 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
49 }
50
51 /*
52 * Finalizes the sink component.
53 */
54 static
55 void epitome_out_finalize(bt_self_component_sink *self_component_sink)
56 {
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));
60
61 /* Free the allocated structure */
62 free(epitome_out);
63 }
64
65 /*
66 * Called when the trace processing graph containing the sink component
67 * is configured.
68 *
69 * This is where we can create our upstream message iterator.
70 */
71 static
72 bt_component_class_sink_graph_is_configured_method_status
73 epitome_out_graph_is_configured(bt_self_component_sink *self_component_sink)
74 {
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));
78
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);
83
84 /* Create the uptream message iterator */
85 bt_message_iterator_create_from_sink_component(self_component_sink,
86 in_port, &epitome_out->message_iterator);
87
88 return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
89 }
90
91 /*
92 * Prints a line for `message`, if it's an event message, to the
93 * standard output.
94 */
95 static
96 void print_message(struct epitome_out *epitome_out, const bt_message *message)
97 {
98 /* Discard if it's not an event message */
99 if (bt_message_get_type(message) != BT_MESSAGE_TYPE_EVENT) {
100 goto end;
101 }
102
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);
107
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));
113
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");
118
119 /* Increment the current event message's index */
120 epitome_out->index++;
121
122 end:
123 return;
124 }
125
126 /*
127 * Consumes a batch of messages and writes the corresponding lines to
128 * the standard output.
129 */
130 bt_component_class_sink_consume_method_status epitome_out_consume(
131 bt_self_component_sink *self_component_sink)
132 {
133 bt_component_class_sink_consume_method_status status =
134 BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
135
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));
139
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,
145 &message_count);
146
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;
152 goto end;
153 case BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN:
154 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_AGAIN;
155 goto end;
156 case BT_MESSAGE_ITERATOR_NEXT_STATUS_MEMORY_ERROR:
157 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_MEMORY_ERROR;
158 goto end;
159 case BT_MESSAGE_ITERATOR_NEXT_STATUS_ERROR:
160 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
161 goto end;
162 default:
163 break;
164 }
165
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];
170
171 /* Print line for current message if it's an event message */
172 print_message(epitome_out, message);
173
174 /* Put this message's reference */
175 bt_message_put_ref(message);
176 }
177
178 end:
179 return status;
180 }
181
182 /* Mandatory */
183 BT_PLUGIN_MODULE();
184
185 /* Define the `epitome` plugin */
186 BT_PLUGIN(epitome);
187
188 /* Define the `output` sink component class */
189 BT_PLUGIN_SINK_COMPONENT_CLASS(output, epitome_out_consume);
190
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);
This page took 0.0351939999999999 seconds and 4 git commands to generate.