clang-tidy: apply suggested fixes
[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
d73aeddd 8#include "../utils.hpp"
9f263671
KS
9#include "event_name.hpp"
10
d73aeddd
JG
11#include <common/container-wrapper.hpp>
12#include <common/macros.hpp>
13#include <common/make-unique.hpp>
14
9f263671
KS
15#include <assert.h>
16#include <babeltrace2/babeltrace.h>
d73aeddd
JG
17#include <cstdint>
18#include <exception>
9f263671
KS
19#include <stdlib.h>
20#include <string.h>
21#include <string>
22#include <unordered_set>
23
d73aeddd
JG
24class event_name_set_operations {
25public:
26 static const char *get(const bt_value *array, std::size_t index)
27 {
28 const auto *names_entry =
29 bt_value_array_borrow_element_by_index_const(array, index);
30
31 if (bt_value_get_type(names_entry) != BT_VALUE_TYPE_STRING) {
32 throw std::runtime_error(
33 "All members of the 'names' parameter array must be strings");
34 }
35
36 return bt_value_string_get(names_entry);
37 }
38
39 static std::size_t size(const bt_value *array)
40 {
41 return bt_value_array_get_length(array);
42 }
43};
44
45class event_name_set
46 : public lttng::utils::random_access_container_wrapper<const bt_value *,
47 const char *,
48 event_name_set_operations> {
49public:
50 friend event_name_set_operations;
51
52 event_name_set() :
53 lttng::utils::random_access_container_wrapper<const bt_value *,
54 const char *,
55 event_name_set_operations>(nullptr)
56 {
57 }
58
07c4863f 59 event_name_set(event_name_set&& original) noexcept :
d73aeddd
JG
60 lttng::utils::random_access_container_wrapper<const bt_value *,
61 const char *,
62 event_name_set_operations>(
07c4863f 63 original._container)
d73aeddd
JG
64 {
65 }
66
07c4863f 67 explicit event_name_set(const bt_value *names) :
d73aeddd
JG
68 lttng::utils::random_access_container_wrapper<const bt_value *,
69 const char *,
70 event_name_set_operations>(names)
71 {
72 if (bt_value_get_type(names) != BT_VALUE_TYPE_ARRAY) {
73 throw std::invalid_argument("'names' parameter must be an array");
74 }
75 }
76};
77
78class event_name_filter {
79public:
80 event_name_filter(bt_self_component_port_input *input_port_,
81 const event_name_set& name_set) :
82 input_port{ input_port_ }, _names{ name_set.begin(), name_set.end() }
83 {
84 }
85
86 bool event_name_is_allowed(const char *event_name) const noexcept
87 {
88 return _names.find(event_name) != _names.end();
89 }
90
9f263671 91 /* weak reference */
d73aeddd
JG
92 bt_self_component_port_input *const input_port;
93
94private:
95 const std::unordered_set<std::string> _names;
9f263671
KS
96};
97
98struct event_name_iterator_data {
d73aeddd
JG
99 event_name_iterator_data(lttng::bt2::message_iterator_ref iterator_,
100 const class event_name_filter& event_name_filter_) :
101 upstream_iterator{ std::move(iterator_) }, event_name_filter{ event_name_filter_ }
102 {
103 }
104
07c4863f 105 ~event_name_iterator_data() = default;
d73aeddd
JG
106
107 const lttng::bt2::message_iterator_ref upstream_iterator;
108 const class event_name_filter& event_name_filter;
9f263671
KS
109};
110
d73aeddd
JG
111namespace {
112bool message_passes(const bt_message *message, const event_name_filter& event_name_filter)
113{
114 if (bt_message_get_type(message) != BT_MESSAGE_TYPE_EVENT) {
115 return true;
116 }
117
118 const bt_event *event = bt_message_event_borrow_event_const(message);
119 const bt_event_class *event_class = bt_event_borrow_class_const(event);
120 const char *event_name = bt_event_class_get_name(event_class);
121
122 if (event_name == nullptr) {
123 return false;
124 }
125
126 return event_name_filter.event_name_is_allowed(event_name);
127}
128} /* namespace */
129
9f263671
KS
130bt_component_class_initialize_method_status
131event_name_initialize(bt_self_component_filter *self_comp,
132 bt_self_component_filter_configuration *,
133 const bt_value *params,
134 void *)
135{
9f263671 136 bt_self_component_port_input *input_port;
d73aeddd
JG
137 std::unique_ptr<class event_name_filter> event_name_filter;
138
9f263671
KS
139 auto self = bt_self_component_filter_as_self_component(self_comp);
140 if (bt_self_component_filter_add_input_port(self_comp, "in", nullptr, &input_port) !=
141 BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) {
142 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(self,
143 "Failed to add input port");
d73aeddd 144 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
9f263671
KS
145 }
146
147 if (bt_self_component_filter_add_output_port(self_comp, "out", nullptr, nullptr) !=
148 BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) {
149 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(self,
150 "Failed to add output port");
d73aeddd 151 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
9f263671
KS
152 }
153
d73aeddd
JG
154 const auto names_param = bt_value_map_borrow_entry_value_const(params, "names");
155 if (names_param == nullptr) {
9f263671
KS
156 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
157 self, "'names' parameter is required");
d73aeddd 158 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
9f263671 159 }
d73aeddd
JG
160
161 try {
07c4863f 162 const event_name_set event_names{ names_param };
d73aeddd 163 if (event_names.empty()) {
9f263671 164 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
d73aeddd
JG
165 bt_self_component_filter_as_self_component(self_comp),
166 "'names' parameter must not be empty");
167 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
9f263671 168 }
d73aeddd
JG
169
170 event_name_filter =
171 lttng::make_unique<class event_name_filter>(input_port, event_names);
172 } catch (const std::bad_alloc&) {
173 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
174 self, "Failed to allocate memory for private component data");
175 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
176 } catch (const std::exception& ex) {
177 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(self, "%s", ex.what());
178 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
9f263671 179 }
9f263671 180
d73aeddd
JG
181 /* Ownership of event_name is transferred to the component. */
182 bt_self_component_set_data(self, event_name_filter.release());
183 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
9f263671
KS
184}
185
186void event_name_finalize(bt_self_component_filter *self_comp)
187{
d73aeddd
JG
188 class event_name_filter *event_name_filter =
189 (class event_name_filter *) bt_self_component_get_data(
190 bt_self_component_filter_as_self_component(self_comp));
191
192 delete event_name_filter;
9f263671
KS
193}
194
195bt_message_iterator_class_initialize_method_status
196event_name_message_iterator_initialize(bt_self_message_iterator *self_message_iterator,
197 bt_self_message_iterator_configuration *,
198 bt_self_component_port_output *)
199{
d73aeddd
JG
200 const auto& event_name_filter =
201 *static_cast<class event_name_filter *>(bt_self_component_get_data(
202 bt_self_message_iterator_borrow_component(self_message_iterator)));
9f263671 203
d73aeddd 204 bt_message_iterator *raw_iterator;
9f263671 205 if (bt_message_iterator_create_from_message_iterator(
d73aeddd 206 self_message_iterator, event_name_filter.input_port, &raw_iterator) !=
9f263671 207 BT_MESSAGE_ITERATOR_CREATE_FROM_MESSAGE_ITERATOR_STATUS_OK) {
9f263671
KS
208 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
209 }
210
d73aeddd
JG
211 lttng::bt2::message_iterator_ref iterator(raw_iterator);
212 raw_iterator = nullptr;
213
214 std::unique_ptr<event_name_iterator_data> iter_data;
215 try {
216 iter_data = lttng::make_unique<event_name_iterator_data>(std::move(iterator),
217 event_name_filter);
218 } catch (const std::bad_alloc&) {
219 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_MESSAGE_ITERATOR(
220 self_message_iterator, "Failed to allocate event_name iterator data");
221 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
222 }
9f263671 223
d73aeddd
JG
224 /* Transfer the ownership of iter_data to the iterator. */
225 bt_self_message_iterator_set_data(self_message_iterator, iter_data.release());
9f263671
KS
226 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK;
227}
228
229void event_name_message_iterator_finalize(bt_self_message_iterator *self_message)
230{
d73aeddd
JG
231 event_name_iterator_data *iter_data = static_cast<event_name_iterator_data *>(
232 bt_self_message_iterator_get_data(self_message));
9f263671 233
d73aeddd
JG
234 LTTNG_ASSERT(iter_data);
235 delete iter_data;
9f263671
KS
236}
237
238bt_message_iterator_class_next_method_status
239event_name_message_iterator_next(bt_self_message_iterator *self_message_iterator,
d73aeddd 240 bt_message_array_const messages_to_deliver_downstream,
9f263671 241 uint64_t,
d73aeddd 242 uint64_t *_messages_to_deliver_count)
9f263671 243{
d73aeddd
JG
244 std::uint64_t messages_to_deliver_count = 0;
245 auto *iter_data = static_cast<event_name_iterator_data *>(
246 bt_self_message_iterator_get_data(self_message_iterator));
247 const auto& event_name_filter =
248 *static_cast<class event_name_filter *>(bt_self_component_get_data(
249 bt_self_message_iterator_borrow_component(self_message_iterator)));
250
251 LTTNG_ASSERT(iter_data);
252
253 /* Retry until we have at least one message to deliver downstream. */
254 while (messages_to_deliver_count == 0) {
255 bt_message_array_const upstream_messages;
256 bt_message_iterator_next_status next_status;
257 uint64_t upstream_message_count;
258
259 next_status = bt_message_iterator_next(iter_data->upstream_iterator.get(),
260 &upstream_messages,
261 &upstream_message_count);
9f263671 262 if (next_status != BT_MESSAGE_ITERATOR_NEXT_STATUS_OK) {
d73aeddd 263 return static_cast<bt_message_iterator_class_next_method_status>(
9f263671 264 next_status);
9f263671
KS
265 }
266
d73aeddd 267 for (std::uint64_t upstream_index = 0; upstream_index < upstream_message_count;
9f263671 268 upstream_index++) {
d73aeddd
JG
269 lttng::bt2::message_const_ref upstream_message(
270 upstream_messages[upstream_index]);
271
272 if (message_passes(upstream_message.get(), event_name_filter)) {
273 /* Reference transferred to downstream message batch. */
274 messages_to_deliver_downstream[messages_to_deliver_count] =
275 upstream_message.release();
276 messages_to_deliver_count++;
9f263671
KS
277 }
278 }
279 }
280
d73aeddd
JG
281 *_messages_to_deliver_count = messages_to_deliver_count;
282 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK;
9f263671 283}
This page took 0.040292 seconds and 4 git commands to generate.