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 "../integer-range-set.hpp"
16 #include "../logging.hpp"
17 #include "../private-query-executor.hpp"
18 #include "../self-component-class.hpp"
19 #include "../self-component-port.hpp"
20 #include "../self-message-iterator-configuration.hpp"
21 #include "../self-message-iterator.hpp"
22 #include "../value.hpp"
27 constexpr bt2c::CStringView unhandledExcLogStr() noexcept
29 return "Unhandled exception.";
32 constexpr bt2c::CStringView unhandledExcLogTag() noexcept
34 return "PLUGIN-DEV-HPP";
38 * Base class of any component class bridge.
40 * `UserCompClsT` is the actual C++ user component class and `TypesT`
41 * is a structure offering the following specific types:
44 * Self component class library type.
47 * Self component library type.
50 * Self component configuration library type.
53 * Self component type.
55 template <typename UserCompClsT, typename TypesT>
59 using _LibSelfCompPtr = typename TypesT::LibSelfComp *;
62 static UserCompClsT& userCompFromLibSelfCompPtr(const _LibSelfCompPtr libSelfCompPtr) noexcept
64 return typename TypesT::SelfComp {libSelfCompPtr}.template data<UserCompClsT>();
67 static bt_component_class_initialize_method_status init(const _LibSelfCompPtr libSelfCompPtr,
68 typename TypesT::LibSelfCompCfg *,
69 const bt_value * const libParamsPtr,
70 void * const initData) noexcept
72 const auto selfComp = typename TypesT::SelfComp {libSelfCompPtr};
76 new UserCompClsT {selfComp, ConstMapValue {libParamsPtr},
77 static_cast<typename UserCompClsT::InitData *>(initData)};
80 } catch (const std::bad_alloc&) {
81 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
82 } catch (const Error&) {
83 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
85 BT_LOG_WRITE_CUR_LVL(BT_LOG_WARNING, static_cast<int>(selfComp.loggingLevel()),
86 unhandledExcLogTag(), unhandledExcLogStr());
87 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
90 return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
93 static void finalize(const _LibSelfCompPtr libSelfCompPtr) noexcept
95 delete &userCompFromLibSelfCompPtr(libSelfCompPtr);
98 static bt_component_class_get_supported_mip_versions_method_status
99 getSupportedMipVersions(typename TypesT::LibSelfCompCls * const libSelfCompClsPtr,
100 const bt_value * const libParamsPtr, void *,
101 const bt_logging_level logLevel,
102 bt_integer_range_set_unsigned * const libSupportedVersionsPtr) noexcept
105 UserCompClsT::getSupportedMipVersions(
106 SelfComponentClass {libSelfCompClsPtr}, ConstMapValue {libParamsPtr},
107 static_cast<LoggingLevel>(logLevel),
108 UnsignedIntegerRangeSet {libSupportedVersionsPtr});
109 return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_OK;
110 } catch (const std::bad_alloc&) {
111 return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_MEMORY_ERROR;
112 } catch (const Error&) {
113 return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_ERROR;
115 BT_LOG_WRITE_CUR_LVL(BT_LOG_WARNING, static_cast<int>(logLevel), unhandledExcLogTag(),
116 unhandledExcLogStr());
117 return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_ERROR;
121 static bt_component_class_query_method_status
122 query(typename TypesT::LibSelfCompCls * const libSelfCompClsPtr,
123 bt_private_query_executor * const libPrivQueryExecPtr, const char * const object,
124 const bt_value * const libParamsPtr, void * const data,
125 const bt_value ** const libResultPtr) noexcept
127 const auto privQueryExec = PrivateQueryExecutor {libPrivQueryExecPtr};
130 auto result = UserCompClsT::query(
131 SelfComponentClass {libSelfCompClsPtr}, privQueryExec, object,
132 ConstValue {libParamsPtr}, static_cast<typename UserCompClsT::QueryData *>(data));
134 *libResultPtr = result.release().libObjPtr();
135 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK;
136 } catch (const TryAgain&) {
137 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_AGAIN;
138 } catch (const UnknownObject&) {
139 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_UNKNOWN_OBJECT;
140 } catch (const std::bad_alloc&) {
141 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_MEMORY_ERROR;
142 } catch (const Error&) {
143 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR;
145 BT_LOG_WRITE_CUR_LVL(BT_LOG_WARNING, static_cast<int>(privQueryExec.loggingLevel()),
146 unhandledExcLogTag(), unhandledExcLogStr());
147 return BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR;
152 template <typename SpecCompClsBridgeT, typename TypesT>
153 struct CompClsBridgeWithInputPorts
155 static bt_component_class_port_connected_method_status
156 inputPortConnected(typename TypesT::LibSelfComp * const libSelfCompPtr,
157 bt_self_component_port_input * const libSelfCompPortPtr,
158 const bt_port_output * const libOtherPortPtr) noexcept
161 SpecCompClsBridgeT::userCompFromLibSelfCompPtr(libSelfCompPtr)
162 .inputPortConnected(SelfComponentInputPort {libSelfCompPortPtr},
163 ConstOutputPort {libOtherPortPtr});
164 } catch (const std::bad_alloc&) {
165 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_MEMORY_ERROR;
166 } catch (const Error&) {
167 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_ERROR;
169 BT_LOG_WRITE_CUR_LVL(
171 static_cast<int>(typename TypesT::SelfComp {libSelfCompPtr}.loggingLevel()),
172 unhandledExcLogTag(), unhandledExcLogStr());
173 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_ERROR;
176 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_OK;
180 template <typename SpecCompClsBridgeT, typename TypesT>
181 struct CompClsBridgeWithOutputPorts
183 static bt_component_class_port_connected_method_status
184 outputPortConnected(typename TypesT::LibSelfComp * const libSelfCompPtr,
185 bt_self_component_port_output * const libSelfCompPortPtr,
186 const bt_port_input * const libOtherPortPtr) noexcept
189 SpecCompClsBridgeT::userCompFromLibSelfCompPtr(libSelfCompPtr)
190 .outputPortConnected(SelfComponentOutputPort {libSelfCompPortPtr},
191 ConstInputPort {libOtherPortPtr});
192 } catch (const std::bad_alloc&) {
193 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_MEMORY_ERROR;
194 } catch (const Error&) {
195 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_ERROR;
197 BT_LOG_WRITE_CUR_LVL(
199 static_cast<int>(typename TypesT::SelfComp {libSelfCompPtr}.loggingLevel()),
200 unhandledExcLogTag(), unhandledExcLogStr());
201 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_ERROR;
204 return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_OK;
208 struct SrcCompClsTypes final
210 using LibSelfCompCls = bt_self_component_class_source;
211 using LibSelfComp = bt_self_component_source;
212 using LibSelfCompCfg = bt_self_component_source_configuration;
213 using SelfComp = SelfSourceComponent;
216 template <typename UserCompClsT>
217 class SrcCompClsBridge final :
218 public CompClsBridge<UserCompClsT, SrcCompClsTypes>,
219 public CompClsBridgeWithOutputPorts<SrcCompClsBridge<UserCompClsT>, SrcCompClsTypes>
223 struct FltCompClsTypes final
225 using LibSelfCompCls = bt_self_component_class_filter;
226 using LibSelfComp = bt_self_component_filter;
227 using LibSelfCompCfg = bt_self_component_filter_configuration;
228 using SelfComp = SelfFilterComponent;
231 template <typename UserCompClsT>
232 class FltCompClsBridge final :
233 public CompClsBridge<UserCompClsT, FltCompClsTypes>,
234 public CompClsBridgeWithInputPorts<FltCompClsBridge<UserCompClsT>, FltCompClsTypes>,
235 public CompClsBridgeWithOutputPorts<FltCompClsBridge<UserCompClsT>, FltCompClsTypes>
239 struct SinkCompClsTypes final
241 using LibSelfCompCls = bt_self_component_class_sink;
242 using LibSelfComp = bt_self_component_sink;
243 using LibSelfCompCfg = bt_self_component_sink_configuration;
244 using SelfComp = SelfSinkComponent;
247 template <typename UserCompClsT>
248 class SinkCompClsBridge final :
249 public CompClsBridge<UserCompClsT, SinkCompClsTypes>,
250 public CompClsBridgeWithInputPorts<SinkCompClsBridge<UserCompClsT>, SinkCompClsTypes>
253 using CompClsBridge<UserCompClsT, SinkCompClsTypes>::userCompFromLibSelfCompPtr;
255 static bt_component_class_sink_consume_method_status
256 consume(bt_self_component_sink * const libSelfCompPtr) noexcept
259 if (userCompFromLibSelfCompPtr(libSelfCompPtr).consume()) {
260 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
262 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_END;
264 } catch (const TryAgain&) {
265 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_AGAIN;
266 } catch (const std::bad_alloc&) {
267 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_MEMORY_ERROR;
268 } catch (const Error&) {
269 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
271 BT_LOG_WRITE_CUR_LVL(
272 BT_LOG_WARNING, static_cast<int>(SelfSinkComponent {libSelfCompPtr}.loggingLevel()),
273 unhandledExcLogTag(), unhandledExcLogStr());
274 return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
278 static bt_component_class_sink_graph_is_configured_method_status
279 graphIsConfigured(bt_self_component_sink * const libSelfCompPtr) noexcept
282 userCompFromLibSelfCompPtr(libSelfCompPtr).graphIsConfigured();
283 return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
284 } catch (const std::bad_alloc&) {
285 return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_MEMORY_ERROR;
286 } catch (const Error&) {
287 return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR;
289 BT_LOG_WRITE_CUR_LVL(
290 BT_LOG_WARNING, static_cast<int>(SelfSinkComponent {libSelfCompPtr}.loggingLevel()),
291 unhandledExcLogTag(), unhandledExcLogStr());
292 return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR;
297 template <typename UserMsgIterT>
298 class MsgIterClsBridge final
302 userMsgIterFromLibSelfMsgIterPtr(bt_self_message_iterator * const libSelfMsgIterPtr) noexcept
304 return SelfMessageIterator {libSelfMsgIterPtr}.data<UserMsgIterT>();
307 static bt_message_iterator_class_initialize_method_status
308 init(bt_self_message_iterator * const libSelfMsgIterPtr,
309 bt_self_message_iterator_configuration * const libSelfMsgIterConfigPtr,
310 bt_self_component_port_output * const libSelfCompPortPtr) noexcept
312 const auto selfMsgIter = SelfMessageIterator {libSelfMsgIterPtr};
315 const auto msgIter = new UserMsgIterT {
316 selfMsgIter, SelfMessageIteratorConfiguration {libSelfMsgIterConfigPtr},
317 SelfComponentOutputPort {libSelfCompPortPtr}};
319 selfMsgIter.data(*msgIter);
320 } catch (const std::bad_alloc&) {
321 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
322 } catch (const Error&) {
323 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
325 BT_LOG_WRITE_CUR_LVL(
328 SelfMessageIterator {libSelfMsgIterPtr}.component().loggingLevel()),
329 unhandledExcLogTag(), unhandledExcLogStr());
330 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
333 return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK;
336 static void finalize(bt_self_message_iterator * const libSelfMsgIterPtr) noexcept
338 delete &userMsgIterFromLibSelfMsgIterPtr(libSelfMsgIterPtr);
341 static bt_message_iterator_class_next_method_status
342 next(bt_self_message_iterator * const libSelfMsgIterPtr, bt_message_array_const libMsgsPtr,
343 const uint64_t capacity, uint64_t * const count) noexcept
346 auto msgArray = ConstMessageArray::wrapEmpty(libMsgsPtr, capacity);
347 auto& msgIter = userMsgIterFromLibSelfMsgIterPtr(libSelfMsgIterPtr);
349 msgIter.next(msgArray);
350 *count = msgArray.release();
352 if (G_LIKELY(*count > 0)) {
353 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK;
355 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END;
357 } catch (const TryAgain&) {
358 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN;
359 } catch (const std::bad_alloc&) {
360 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_MEMORY_ERROR;
361 } catch (const Error&) {
362 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
364 BT_LOG_WRITE_CUR_LVL(
367 SelfMessageIterator {libSelfMsgIterPtr}.component().loggingLevel()),
368 unhandledExcLogTag(), unhandledExcLogStr());
369 return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
373 static bt_message_iterator_class_can_seek_beginning_method_status
374 canSeekBeginning(bt_self_message_iterator * const libSelfMsgIterPtr,
375 bt_bool * const canSeek) noexcept
378 *canSeek = static_cast<bt_bool>(
379 userMsgIterFromLibSelfMsgIterPtr(libSelfMsgIterPtr).canSeekBeginning());
380 } catch (const TryAgain&) {
381 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_BEGINNING_METHOD_STATUS_AGAIN;
382 } catch (const std::bad_alloc&) {
383 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_BEGINNING_METHOD_STATUS_MEMORY_ERROR;
384 } catch (const Error&) {
385 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_BEGINNING_METHOD_STATUS_ERROR;
387 BT_LOG_WRITE_CUR_LVL(
390 SelfMessageIterator {libSelfMsgIterPtr}.component().loggingLevel()),
391 unhandledExcLogTag(), unhandledExcLogStr());
392 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_BEGINNING_METHOD_STATUS_ERROR;
395 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_BEGINNING_METHOD_STATUS_OK;
398 static bt_message_iterator_class_seek_beginning_method_status
399 seekBeginning(bt_self_message_iterator * const libSelfMsgIterPtr) noexcept
402 userMsgIterFromLibSelfMsgIterPtr(libSelfMsgIterPtr).seekBeginning();
403 } catch (const TryAgain&) {
404 return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_AGAIN;
405 } catch (const std::bad_alloc&) {
406 return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_MEMORY_ERROR;
407 } catch (const Error&) {
408 return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_ERROR;
410 BT_LOG_WRITE_CUR_LVL(
413 SelfMessageIterator {libSelfMsgIterPtr}.component().loggingLevel()),
414 unhandledExcLogTag(), unhandledExcLogStr());
415 return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_ERROR;
418 return BT_MESSAGE_ITERATOR_CLASS_SEEK_BEGINNING_METHOD_STATUS_OK;
421 static bt_message_iterator_class_can_seek_ns_from_origin_method_status
422 canSeekNsFromOrigin(bt_self_message_iterator * const libSelfMsgIterPtr,
423 const std::int64_t nsFromOrigin, bt_bool * const canSeek) noexcept
426 *canSeek = static_cast<bt_bool>(userMsgIterFromLibSelfMsgIterPtr(libSelfMsgIterPtr)
427 .canSeekNsFromOrigin(nsFromOrigin));
428 } catch (const TryAgain&) {
429 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_AGAIN;
430 } catch (const std::bad_alloc&) {
431 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_MEMORY_ERROR;
432 } catch (const Error&) {
433 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_ERROR;
435 BT_LOG_WRITE_CUR_LVL(
438 SelfMessageIterator {libSelfMsgIterPtr}.component().loggingLevel()),
439 unhandledExcLogTag(), unhandledExcLogStr());
440 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_ERROR;
443 return BT_MESSAGE_ITERATOR_CLASS_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_OK;
446 static bt_message_iterator_class_seek_ns_from_origin_method_status
447 seekNsFromOrigin(bt_self_message_iterator * const libSelfMsgIterPtr,
448 const std::int64_t nsFromOrigin) noexcept
451 userMsgIterFromLibSelfMsgIterPtr(libSelfMsgIterPtr).seekNsFromOrigin(nsFromOrigin);
452 } catch (const TryAgain&) {
453 return BT_MESSAGE_ITERATOR_CLASS_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_AGAIN;
454 } catch (const std::bad_alloc&) {
455 return BT_MESSAGE_ITERATOR_CLASS_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_MEMORY_ERROR;
456 } catch (const Error&) {
457 return BT_MESSAGE_ITERATOR_CLASS_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_ERROR;
459 BT_LOG_WRITE_CUR_LVL(
462 SelfMessageIterator {libSelfMsgIterPtr}.component().loggingLevel()),
463 unhandledExcLogTag(), unhandledExcLogStr());
464 return BT_MESSAGE_ITERATOR_CLASS_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_ERROR;
467 return BT_MESSAGE_ITERATOR_CLASS_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_OK;
471 } /* namespace internal */
472 } /* namespace bt2 */
474 #endif /* BABELTRACE_CPP_COMMON_BT2_INTERNAL_COMP_CLS_BRIDGE_HPP */