tests: Replace babelstats.pl with bt2 plugins
[lttng-tools.git] / tests / utils / bt2_plugins / event_name / event_name.cpp
CommitLineData
9f263671
KS
1/*
2 * Copyright (C) 2023 Kienan Stewart <kstewart@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8#include "event_name.hpp"
9
10#include <assert.h>
11#include <babeltrace2/babeltrace.h>
12#include <stdlib.h>
13#include <string.h>
14#include <string>
15#include <unordered_set>
16
17struct event_name {
18 std::unordered_set<std::string> names;
19 const bt_value *names_value;
20 /* weak reference */
21 bt_self_component_port_input *input_port;
22};
23
24struct event_name_iterator_data {
25 struct event_name *event_name;
26 bt_message_iterator *iterator;
27};
28
29bt_component_class_initialize_method_status
30event_name_initialize(bt_self_component_filter *self_comp,
31 bt_self_component_filter_configuration *,
32 const bt_value *params,
33 void *)
34{
35 bt_component_class_initialize_method_status status;
36 bt_self_component_port_input *input_port;
37 struct event_name *event_name;
38 auto self = bt_self_component_filter_as_self_component(self_comp);
39 if (bt_self_component_filter_add_input_port(self_comp, "in", nullptr, &input_port) !=
40 BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) {
41 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(self,
42 "Failed to add input port");
43 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
44 goto end;
45 }
46
47 if (bt_self_component_filter_add_output_port(self_comp, "out", nullptr, nullptr) !=
48 BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) {
49 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(self,
50 "Failed to add output port");
51 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
52 goto end;
53 }
54
55 event_name = new (std::nothrow) struct event_name;
56 if (event_name == nullptr) {
57 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
58 self, "Failed to allocate memory for private component data");
59 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
60 goto end;
61 }
62
63 event_name->input_port = input_port;
64 event_name->names_value = bt_value_map_borrow_entry_value_const(params, "names");
65 if (event_name->names_value == nullptr) {
66 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
67 self, "'names' parameter is required");
68 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
69 goto err_free;
70 }
71 if (bt_value_get_type(event_name->names_value) != BT_VALUE_TYPE_ARRAY) {
72 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
73 self, "'names' parameter must be an array");
74 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
75 goto err_free;
76 }
77 if (bt_value_array_is_empty(event_name->names_value)) {
78 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
79 bt_self_component_filter_as_self_component(self_comp),
80 "'names' parameter must not be empty");
81 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
82 goto err_free;
83 }
84 for (uint64_t index = 0; index < bt_value_array_get_length(event_name->names_value);
85 index++) {
86 const bt_value *names_entry = bt_value_array_borrow_element_by_index_const(
87 event_name->names_value, index);
88 if (bt_value_get_type(names_entry) != BT_VALUE_TYPE_STRING) {
89 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
90 self, "All members of the 'names' parameter array must be strings");
91 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
92 goto err_free;
93 }
94 event_name->names.emplace(bt_value_string_get(names_entry));
95 }
96 bt_value_get_ref(event_name->names_value);
97 bt_self_component_set_data(self, event_name);
98 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
99 goto end;
100
101err_free:
102 delete event_name;
103end:
104 return status;
105}
106
107void event_name_finalize(bt_self_component_filter *self_comp)
108{
109 struct event_name *event_name = (struct event_name *) bt_self_component_get_data(
110 bt_self_component_filter_as_self_component(self_comp));
111 bt_value_put_ref(event_name->names_value);
112 delete event_name;
113}
114
115bt_message_iterator_class_initialize_method_status
116event_name_message_iterator_initialize(bt_self_message_iterator *self_message_iterator,
117 bt_self_message_iterator_configuration *,
118 bt_self_component_port_output *)
119{
120 struct event_name *event_name = (struct event_name *) bt_self_component_get_data(
121 bt_self_message_iterator_borrow_component(self_message_iterator));
122 assert(event_name);
123
124 struct event_name_iterator_data *iter_data =
125 (struct event_name_iterator_data *) malloc(sizeof(struct event_name_iterator_data));
126
127 if (iter_data == nullptr) {
128 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
129 }
130 iter_data->event_name = event_name;
131
132 if (bt_message_iterator_create_from_message_iterator(
133 self_message_iterator, event_name->input_port, &iter_data->iterator) !=
134 BT_MESSAGE_ITERATOR_CREATE_FROM_MESSAGE_ITERATOR_STATUS_OK) {
135 free(iter_data);
136 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
137 }
138
139 bt_self_message_iterator_set_data(self_message_iterator, iter_data);
140
141 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK;
142}
143
144void event_name_message_iterator_finalize(bt_self_message_iterator *self_message)
145{
146 struct event_name_iterator_data *iter_data =
147 (struct event_name_iterator_data *) bt_self_message_iterator_get_data(self_message);
148
149 assert(iter_data);
150 bt_message_iterator_put_ref(iter_data->iterator);
151 free(iter_data);
152}
153
154static bool message_passes(const bt_message *message, const std::unordered_set<std::string>& names)
155{
156 if (bt_message_get_type(message) != BT_MESSAGE_TYPE_EVENT) {
157 return true;
158 }
159
160 const bt_event *event = bt_message_event_borrow_event_const(message);
161 const bt_event_class *event_class = bt_event_borrow_class_const(event);
162 const char *event_name = bt_event_class_get_name(event_class);
163
164 if (event_name == nullptr) {
165 return false;
166 }
167
168 if (names.find(event_name) != names.end()) {
169 return true;
170 }
171
172 return false;
173}
174
175bt_message_iterator_class_next_method_status
176event_name_message_iterator_next(bt_self_message_iterator *self_message_iterator,
177 bt_message_array_const messages,
178 uint64_t,
179 uint64_t *count)
180{
181 bt_message_array_const upstream_messages;
182 uint64_t upstream_message_count;
183 uint64_t index = 0;
184 bt_message_iterator_next_status next_status;
185 bt_message_iterator_class_next_method_status status =
186 BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK;
187 struct event_name_iterator_data *iter_data =
188 (struct event_name_iterator_data *) bt_self_message_iterator_get_data(
189 self_message_iterator);
190 struct event_name *event_name = (struct event_name *) bt_self_component_get_data(
191 bt_self_message_iterator_borrow_component(self_message_iterator));
192
193 assert(event_name);
194 assert(iter_data);
195
196 while (index == 0) {
197 next_status = bt_message_iterator_next(
198 iter_data->iterator, &upstream_messages, &upstream_message_count);
199 if (next_status != BT_MESSAGE_ITERATOR_NEXT_STATUS_OK) {
200 status = static_cast<bt_message_iterator_class_next_method_status>(
201 next_status);
202 goto end;
203 }
204
205 for (uint64_t upstream_index = 0; upstream_index < upstream_message_count;
206 upstream_index++) {
207 const bt_message *upstream_message = upstream_messages[upstream_index];
208 if (message_passes(upstream_message, event_name->names)) {
209 messages[index] = upstream_message;
210 index++;
211 } else {
212 bt_message_put_ref(upstream_message);
213 }
214 }
215 }
216
217 *count = index;
218end:
219 return status;
220}
This page took 0.031705 seconds and 4 git commands to generate.