2 * Copyright (c) 2024 EfficiOS, Inc.
4 * SPDX-License-Identifier: MIT
7 #ifndef BABELTRACE_CPP_COMMON_BT2_INTERNAL_COMP_CLS_BRIDGE_HPP
8 #define BABELTRACE_CPP_COMMON_BT2_INTERNAL_COMP_CLS_BRIDGE_HPP
10 #include <babeltrace2/babeltrace.h>
12 #include "cpp-common/bt2c/c-string-view.hpp"
13 #include "logging/log-api.h"
15 #include "../wrap.hpp"
20 constexpr bt2c::CStringView unhandledExcLogStr() noexcept
22 return "Unhandled exception.";
25 constexpr bt2c::CStringView unhandledExcLogTag() noexcept
27 return "PLUGIN-DEV-HPP";
31 * Base class of any component class bridge.
33 * `UserCompClsT` is the actual C++ user component class and `LibTypesT`
34 * is a structure offering the following specific library types:
37 * Self component class.
43 * Self component configuration.
45 template <typename UserCompClsT, typename LibTypesT>
49 using _LibSelfCompPtr = typename LibTypesT::SelfComp *;
52 static UserCompClsT& userCompFromLibSelfCompPtr(const _LibSelfCompPtr libSelfCompPtr) noexcept
54 return wrap(libSelfCompPtr).template data<UserCompClsT>();
57 static bt_component_class_initialize_method_status init(const _LibSelfCompPtr libSelfCompPtr,
58 typename LibTypesT::SelfCompCfg *,
59 const bt_value * const libParamsPtr,
60 void * const initData) noexcept
62 const auto selfComp = wrap(libSelfCompPtr);
66 new UserCompClsT {selfComp, wrap(libParamsPtr).asMap(),
67 static_cast<typename UserCompClsT::InitData *>(initData)};
70 } catch (const std::bad_alloc&) {
71 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
72 } catch (const Error&) {
73 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
75 BT_LOG_WRITE_CUR_LVL(BT_LOG_WARNING, static_cast<int>(selfComp.loggingLevel()),
76 unhandledExcLogTag(), unhandledExcLogStr());
77 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
80 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
83 static void finalize(const _LibSelfCompPtr libSelfCompPtr) noexcept
85 delete &userCompFromLibSelfCompPtr(libSelfCompPtr);
88 static bt_component_class_get_supported_mip_versions_method_status
89 getSupportedMipVersions(typename LibTypesT::SelfCompCls * const libSelfCompClsPtr,
90 const bt_value * const libParamsPtr, void *,
91 const bt_logging_level logLevel,
92 bt_integer_range_set_unsigned * const libSupportedVersionsPtr) noexcept
95 UserCompClsT::getSupportedMipVersions(wrap(libSelfCompClsPtr), wrap(libParamsPtr),
96 static_cast<LoggingLevel>(logLevel),
97 wrap(libSupportedVersionsPtr));
98 return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_OK;
99 } catch (const std::bad_alloc&) {
100 return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_MEMORY_ERROR;
101 } catch (const Error&) {
102 return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_ERROR;
104 BT_LOG_WRITE_CUR_LVL(BT_LOG_WARNING, static_cast<int>(logLevel), unhandledExcLogTag(),
105 unhandledExcLogStr());
106 return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_ERROR;
110 static bt_component_class_query_method_status
111 query(typename LibTypesT::SelfCompCls * const libSelfCompClsPtr,
112 bt_private_query_executor * const libPrivQueryExecPtr, const char * const object,
113 const bt_value * const libParamsPtr, void * const data,
114 const bt_value ** const libResultPtr) noexcept
116 const auto privQueryExec = wrap(libPrivQueryExecPtr);
119 auto result = UserCompClsT::query(
120 wrap(libSelfCompClsPtr), privQueryExec, object, wrap(libParamsPtr),
121 static_cast<typename UserCompClsT::QueryData *>(data));
123 *libResultPtr = result.release().libObjPtr();
124 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK;
125 } catch (const TryAgain&) {
126 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_AGAIN;
127 } catch (const UnknownObject&) {
128 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_UNKNOWN_OBJECT;
129 } catch (const std::bad_alloc&) {
130 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR;
131 } catch (const Error&) {
132 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR;
134 BT_LOG_WRITE_CUR_LVL(BT_LOG_WARNING, static_cast<int>(privQueryExec.loggingLevel()),
135 unhandledExcLogTag(), unhandledExcLogStr());
136 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR;
141 template <typename SpecCompClsBridgeT, typename LibTypesT>
142 struct CompClsBridgeWithInputPorts
144 static bt_component_class_port_connected_method_status
145 inputPortConnected(typename LibTypesT::SelfComp * const libSelfCompPtr,
146 bt_self_component_port_input * const libSelfCompPortPtr,
147 const bt_port_output * const libOtherPortPtr) noexcept
150 SpecCompClsBridgeT::userCompFromLibSelfCompPtr(libSelfCompPtr)
151 .inputPortConnected(wrap(libSelfCompPortPtr), wrap(libOtherPortPtr));
152 } catch (const std::bad_alloc&) {
153 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_MEMORY_ERROR;
154 } catch (const Error&) {
155 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_ERROR;
157 BT_LOG_WRITE_CUR_LVL(BT_LOG_WARNING,
158 static_cast<int>(wrap(libSelfCompPtr).loggingLevel()),
159 unhandledExcLogTag(), unhandledExcLogStr());
160 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_ERROR;
163 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_OK;
167 template <typename SpecCompClsBridgeT, typename LibTypesT>
168 struct CompClsBridgeWithOutputPorts
170 static bt_component_class_port_connected_method_status
171 outputPortConnected(typename LibTypesT::SelfComp * const libSelfCompPtr,
172 bt_self_component_port_output * const libSelfCompPortPtr,
173 const bt_port_input * const libOtherPortPtr) noexcept
176 SpecCompClsBridgeT::userCompFromLibSelfCompPtr(libSelfCompPtr)
177 .outputPortConnected(wrap(libSelfCompPortPtr), wrap(libOtherPortPtr));
178 } catch (const std::bad_alloc&) {
179 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_MEMORY_ERROR;
180 } catch (const Error&) {
181 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_ERROR;
183 BT_LOG_WRITE_CUR_LVL(BT_LOG_WARNING,
184 static_cast<int>(wrap(libSelfCompPtr).loggingLevel()),
185 unhandledExcLogTag(), unhandledExcLogStr());
186 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_ERROR;
189 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_OK;
193 struct SrcCompClsLibTypes final
195 using SelfCompCls = bt_self_component_class_source;
196 using SelfComp = bt_self_component_source;
197 using SelfCompCfg = bt_self_component_source_configuration;
200 template <typename UserCompClsT>
201 class SrcCompClsBridge final :
202 public CompClsBridge<UserCompClsT, SrcCompClsLibTypes>,
203 public CompClsBridgeWithOutputPorts<SrcCompClsBridge<UserCompClsT>, SrcCompClsLibTypes>
207 struct FltCompClsLibTypes final
209 using SelfCompCls = bt_self_component_class_filter;
210 using SelfComp = bt_self_component_filter;
211 using SelfCompCfg = bt_self_component_filter_configuration;
214 template <typename UserCompClsT>
215 class FltCompClsBridge final :
216 public CompClsBridge<UserCompClsT, FltCompClsLibTypes>,
217 public CompClsBridgeWithInputPorts<FltCompClsBridge<UserCompClsT>, FltCompClsLibTypes>,
218 public CompClsBridgeWithOutputPorts<FltCompClsBridge<UserCompClsT>, FltCompClsLibTypes>
222 struct SinkCompClsLibTypes final
224 using SelfCompCls = bt_self_component_class_sink;
225 using SelfComp = bt_self_component_sink;
226 using SelfCompCfg = bt_self_component_sink_configuration;
229 template <typename UserCompClsT>
230 class SinkCompClsBridge final :
231 public CompClsBridge<UserCompClsT, SinkCompClsLibTypes>,
232 public CompClsBridgeWithInputPorts<SinkCompClsBridge<UserCompClsT>, SinkCompClsLibTypes>
235 using CompClsBridge<UserCompClsT, SinkCompClsLibTypes>::userCompFromLibSelfCompPtr;
238 static bt_component_class_sink_consume_method_status
239 consume(bt_self_component_sink * const libSelfCompPtr) noexcept
242 if (userCompFromLibSelfCompPtr(libSelfCompPtr).consume()) {
243 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
245 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_END;
247 } catch (const TryAgain&) {
248 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_AGAIN;
249 } catch (const std::bad_alloc&) {
250 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_MEMORY_ERROR;
251 } catch (const Error&) {
252 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
254 BT_LOG_WRITE_CUR_LVL(BT_LOG_WARNING,
255 static_cast<int>(wrap(libSelfCompPtr).loggingLevel()),
256 unhandledExcLogTag(), unhandledExcLogStr());
257 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
261 static bt_component_class_sink_graph_is_configured_method_status
262 graphIsConfigured(bt_self_component_sink * const libSelfCompPtr) noexcept
265 userCompFromLibSelfCompPtr(libSelfCompPtr).graphIsConfigured();
266 return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
267 } catch (const std::bad_alloc&) {
268 return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_MEMORY_ERROR;
269 } catch (const Error&) {
270 return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR;
272 BT_LOG_WRITE_CUR_LVL(BT_LOG_WARNING,
273 static_cast<int>(wrap(libSelfCompPtr).loggingLevel()),
274 unhandledExcLogTag(), unhandledExcLogStr());
275 return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR;
280 template <typename UserMsgIterT>
281 class MsgIterClsBridge final
285 userMsgIterFromLibSelfMsgIterPtr(bt_self_message_iterator * const libSelfMsgIterPtr) noexcept
287 return bt2::wrap(libSelfMsgIterPtr).data<UserMsgIterT>();
290 static bt_message_iterator_class_initialize_method_status
291 init(bt_self_message_iterator * const libSelfMsgIterPtr,
292 bt_self_message_iterator_configuration * const libSelfMsgIterConfigPtr,
293 bt_self_component_port_output * const libSelfCompPortPtr) noexcept
295 const auto selfMsgIter = bt2::wrap(libSelfMsgIterPtr);
298 const auto msgIter = new UserMsgIterT {selfMsgIter, bt2::wrap(libSelfMsgIterConfigPtr),
299 bt2::wrap(libSelfCompPortPtr)};
301 selfMsgIter.data(*msgIter);
302 } catch (const std::bad_alloc&) {
303 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
304 } catch (const bt2::Error&) {
305 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
307 BT_LOG_WRITE_CUR_LVL(
309 static_cast<int>(wrap(libSelfMsgIterPtr).component().loggingLevel()),
310 unhandledExcLogTag(), unhandledExcLogStr());
311 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
314 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK;
317 static void finalize(bt_self_message_iterator * const libSelfMsgIterPtr) noexcept
319 delete &userMsgIterFromLibSelfMsgIterPtr(libSelfMsgIterPtr);
322 static bt_message_iterator_class_next_method_status
323 next(bt_self_message_iterator * const libSelfMsgIterPtr, bt_message_array_const libMsgsPtr,
324 const uint64_t capacity, uint64_t * const count) noexcept
327 auto msgArray = bt2::ConstMessageArray::wrapEmpty(libMsgsPtr, capacity);
328 auto& msgIter = userMsgIterFromLibSelfMsgIterPtr(libSelfMsgIterPtr);
330 msgIter.next(msgArray);
331 *count = msgArray.release();
333 if (G_LIKELY(*count > 0)) {
334 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK;
336 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END;
338 } catch (const bt2::TryAgain&) {
339 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN;
340 } catch (const std::bad_alloc&) {
341 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR;
342 } catch (const bt2::Error&) {
343 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
345 BT_LOG_WRITE_CUR_LVL(
347 static_cast<int>(wrap(libSelfMsgIterPtr).component().loggingLevel()),
348 unhandledExcLogTag(), unhandledExcLogStr());
349 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
353 static bt_message_iterator_class_can_seek_beginning_method_status
354 canSeekBeginning(bt_self_message_iterator * const libSelfMsgIterPtr,
355 bt_bool * const canSeek) noexcept
358 *canSeek = static_cast<bt_bool>(
359 userMsgIterFromLibSelfMsgIterPtr(libSelfMsgIterPtr).canSeekBeginning());
360 } catch (const bt2::TryAgain&) {
361 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_BEGINNING_METHOD_STATUS_AGAIN;
362 } catch (const std::bad_alloc&) {
363 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_BEGINNING_METHOD_STATUS_MEMORY_ERROR;
364 } catch (const bt2::Error&) {
365 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_BEGINNING_METHOD_STATUS_ERROR;
367 BT_LOG_WRITE_CUR_LVL(
369 static_cast<int>(wrap(libSelfMsgIterPtr).component().loggingLevel()),
370 unhandledExcLogTag(), unhandledExcLogStr());
371 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_BEGINNING_METHOD_STATUS_ERROR;
374 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_BEGINNING_METHOD_STATUS_OK;
377 static bt_message_iterator_class_seek_beginning_method_status
378 seekBeginning(bt_self_message_iterator * const libSelfMsgIterPtr) noexcept
381 userMsgIterFromLibSelfMsgIterPtr(libSelfMsgIterPtr).seekBeginning();
382 } catch (const bt2::TryAgain&) {
383 return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_AGAIN;
384 } catch (const std::bad_alloc&) {
385 return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_MEMORY_ERROR;
386 } catch (const bt2::Error&) {
387 return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_ERROR;
389 BT_LOG_WRITE_CUR_LVL(
391 static_cast<int>(wrap(libSelfMsgIterPtr).component().loggingLevel()),
392 unhandledExcLogTag(), unhandledExcLogStr());
393 return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_ERROR;
396 return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_OK;
399 static bt_message_iterator_class_can_seek_ns_from_origin_method_status
400 canSeekNsFromOrigin(bt_self_message_iterator * const libSelfMsgIterPtr,
401 const std::int64_t nsFromOrigin, bt_bool * const canSeek) noexcept
404 *canSeek = static_cast<bt_bool>(userMsgIterFromLibSelfMsgIterPtr(libSelfMsgIterPtr)
405 .canSeekNsFromOrigin(nsFromOrigin));
406 } catch (const bt2::TryAgain&) {
407 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_AGAIN;
408 } catch (const std::bad_alloc&) {
409 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_MEMORY_ERROR;
410 } catch (const bt2::Error&) {
411 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_ERROR;
413 BT_LOG_WRITE_CUR_LVL(
415 static_cast<int>(wrap(libSelfMsgIterPtr).component().loggingLevel()),
416 unhandledExcLogTag(), unhandledExcLogStr());
417 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_ERROR;
420 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_OK;
423 static bt_message_iterator_class_seek_ns_from_origin_method_status
424 seekNsFromOrigin(bt_self_message_iterator * const libSelfMsgIterPtr,
425 const std::int64_t nsFromOrigin) noexcept
428 userMsgIterFromLibSelfMsgIterPtr(libSelfMsgIterPtr).seekNsFromOrigin(nsFromOrigin);
429 } catch (const bt2::TryAgain&) {
430 return BT_MESSAGE_ITERATOR_CLASS_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_AGAIN;
431 } catch (const std::bad_alloc&) {
432 return BT_MESSAGE_ITERATOR_CLASS_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_MEMORY_ERROR;
433 } catch (const bt2::Error&) {
434 return BT_MESSAGE_ITERATOR_CLASS_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_ERROR;
436 BT_LOG_WRITE_CUR_LVL(
438 static_cast<int>(wrap(libSelfMsgIterPtr).component().loggingLevel()),
439 unhandledExcLogTag(), unhandledExcLogStr());
440 return BT_MESSAGE_ITERATOR_CLASS_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_ERROR;
443 return BT_MESSAGE_ITERATOR_CLASS_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_OK;
447 } /* namespace internal */
448 } /* namespace bt2 */
450 #endif /* BABELTRACE_CPP_COMMON_BT2_INTERNAL_COMP_CLS_BRIDGE_HPP */