Commit | Line | Data |
---|---|---|
7bdf11a1 PP |
1 | /* |
2 | * Copyright (c) 2023 Philippe Proulx <pproulx@efficios.com> | |
3 | * | |
4 | * SPDX-License-Identifier: MIT | |
5 | */ | |
6 | ||
7 | #ifndef BABELTRACE_CPP_COMMON_BT2_COMPONENT_PORT_HPP | |
8 | #define BABELTRACE_CPP_COMMON_BT2_COMPONENT_PORT_HPP | |
9 | ||
10 | #include <cstdint> | |
11 | #include <string> | |
12 | ||
13 | #include <babeltrace2/babeltrace.h> | |
14 | ||
15 | #include "logging.hpp" | |
16 | ||
e7f0f07b SM |
17 | #include "cpp-common/bt2c/c-string-view.hpp" |
18 | ||
7bdf11a1 PP |
19 | #include "borrowed-object-iterator.hpp" |
20 | #include "borrowed-object.hpp" | |
21 | #include "shared-object.hpp" | |
22 | ||
23 | namespace bt2 { | |
24 | namespace internal { | |
25 | ||
26 | struct ConstComponentRefFuncs final | |
27 | { | |
28 | static void get(const bt_component * const libObjPtr) noexcept | |
29 | { | |
30 | bt_component_get_ref(libObjPtr); | |
31 | } | |
32 | ||
33 | static void put(const bt_component * const libObjPtr) noexcept | |
34 | { | |
35 | bt_component_put_ref(libObjPtr); | |
36 | } | |
37 | }; | |
38 | ||
39 | } /* namespace internal */ | |
40 | ||
41 | class ConstSourceComponent; | |
42 | class ConstFilterComponent; | |
43 | class ConstSinkComponent; | |
44 | ||
45 | class ConstComponent final : public BorrowedObject<const bt_component> | |
46 | { | |
47 | private: | |
48 | using typename BorrowedObject<const bt_component>::_ThisBorrowedObject; | |
49 | ||
50 | public: | |
51 | using Shared = | |
52 | SharedObject<ConstComponent, const bt_component, internal::ConstComponentRefFuncs>; | |
53 | ||
54 | explicit ConstComponent(const bt_component * const libObjPtr) noexcept : | |
55 | _ThisBorrowedObject {libObjPtr} | |
56 | { | |
57 | } | |
58 | ||
59 | explicit ConstComponent(const bt_component_source * const libObjPtr) noexcept : | |
60 | _ThisBorrowedObject {bt_component_source_as_component_const(libObjPtr)} | |
61 | { | |
62 | } | |
63 | ||
64 | explicit ConstComponent(const bt_component_filter * const libObjPtr) noexcept : | |
65 | _ThisBorrowedObject {bt_component_filter_as_component_const(libObjPtr)} | |
66 | { | |
67 | } | |
68 | ||
69 | explicit ConstComponent(const bt_component_sink * const libObjPtr) noexcept : | |
70 | _ThisBorrowedObject {bt_component_sink_as_component_const(libObjPtr)} | |
71 | { | |
72 | } | |
73 | ||
74 | /* Not `explicit` to make them behave like copy constructors */ | |
75 | ConstComponent(ConstSourceComponent other) noexcept; | |
76 | ConstComponent(ConstFilterComponent other) noexcept; | |
77 | ConstComponent(ConstSinkComponent other) noexcept; | |
78 | ||
79 | ConstComponent operator=(ConstSourceComponent other) noexcept; | |
80 | ConstComponent operator=(ConstFilterComponent other) noexcept; | |
81 | ConstComponent operator=(ConstSinkComponent other) noexcept; | |
82 | ||
83 | bool isSource() const noexcept | |
84 | { | |
85 | return static_cast<bool>(bt_component_is_source(this->libObjPtr())); | |
86 | } | |
87 | ||
88 | bool isFilter() const noexcept | |
89 | { | |
90 | return static_cast<bool>(bt_component_is_filter(this->libObjPtr())); | |
91 | } | |
92 | ||
93 | bool isSink() const noexcept | |
94 | { | |
95 | return static_cast<bool>(bt_component_is_sink(this->libObjPtr())); | |
96 | } | |
97 | ||
e7f0f07b | 98 | bt2c::CStringView name() const noexcept |
7bdf11a1 PP |
99 | { |
100 | return bt_component_get_name(this->libObjPtr()); | |
101 | } | |
102 | ||
103 | LoggingLevel loggingLevel() const noexcept | |
104 | { | |
105 | return static_cast<LoggingLevel>(bt_component_get_logging_level(this->libObjPtr())); | |
106 | } | |
107 | ||
108 | Shared shared() const noexcept | |
109 | { | |
110 | return Shared::createWithRef(*this); | |
111 | } | |
112 | }; | |
113 | ||
114 | template <typename LibObjT> | |
115 | class ConstSpecificComponent : public BorrowedObject<LibObjT> | |
116 | { | |
117 | public: | |
d246c457 | 118 | using typename BorrowedObject<LibObjT>::LibObjPtr; |
7bdf11a1 PP |
119 | |
120 | protected: | |
d246c457 | 121 | explicit ConstSpecificComponent(const LibObjPtr libObjPtr) noexcept : |
7bdf11a1 PP |
122 | BorrowedObject<LibObjT> {libObjPtr} |
123 | { | |
124 | } | |
125 | ||
126 | public: | |
e7f0f07b | 127 | bt2c::CStringView name() const noexcept |
7bdf11a1 PP |
128 | { |
129 | return this->_constComponent().name(); | |
130 | } | |
131 | ||
132 | LoggingLevel loggingLevel() const noexcept | |
133 | { | |
134 | return this->_constComponent().loggingLevel(); | |
135 | } | |
136 | ||
137 | ConstComponent::Shared sharedComponent() const noexcept | |
138 | { | |
139 | return this->_constComponent().shared(); | |
140 | } | |
141 | ||
142 | private: | |
143 | ConstComponent _constComponent() const noexcept | |
144 | { | |
145 | return ConstComponent {this->libObjPtr()}; | |
146 | } | |
147 | }; | |
148 | ||
149 | namespace internal { | |
150 | ||
151 | template <typename LibCompT, typename LibPortPtrT> | |
152 | struct ConstComponentPortsSpec; | |
153 | ||
154 | template <> | |
155 | struct ConstComponentPortsSpec<const bt_component_source, const bt_port_output> final | |
156 | { | |
157 | static std::uint64_t portCount(const bt_component_source * const libCompPtr) noexcept | |
158 | { | |
159 | return bt_component_source_get_output_port_count(libCompPtr); | |
160 | } | |
161 | ||
162 | static const bt_port_output *portByIndex(const bt_component_source * const libCompPtr, | |
163 | const std::uint64_t index) noexcept | |
164 | { | |
165 | return bt_component_source_borrow_output_port_by_index_const(libCompPtr, index); | |
166 | } | |
167 | ||
168 | static const bt_port_output *portByName(const bt_component_source * const libCompPtr, | |
169 | const char * const name) noexcept | |
170 | { | |
171 | return bt_component_source_borrow_output_port_by_name_const(libCompPtr, name); | |
172 | } | |
173 | }; | |
174 | ||
175 | template <> | |
176 | struct ConstComponentPortsSpec<const bt_component_filter, const bt_port_output> final | |
177 | { | |
178 | static std::uint64_t portCount(const bt_component_filter * const libCompPtr) noexcept | |
179 | { | |
180 | return bt_component_filter_get_output_port_count(libCompPtr); | |
181 | } | |
182 | ||
183 | static const bt_port_output *portByIndex(const bt_component_filter * const libCompPtr, | |
184 | const std::uint64_t index) noexcept | |
185 | { | |
186 | return bt_component_filter_borrow_output_port_by_index_const(libCompPtr, index); | |
187 | } | |
188 | ||
189 | static const bt_port_output *portByName(const bt_component_filter * const libCompPtr, | |
190 | const char * const name) noexcept | |
191 | { | |
192 | return bt_component_filter_borrow_output_port_by_name_const(libCompPtr, name); | |
193 | } | |
194 | }; | |
195 | ||
196 | template <> | |
197 | struct ConstComponentPortsSpec<const bt_component_filter, const bt_port_input> final | |
198 | { | |
199 | static std::uint64_t portCount(const bt_component_filter * const libCompPtr) noexcept | |
200 | { | |
201 | return bt_component_filter_get_input_port_count(libCompPtr); | |
202 | } | |
203 | ||
204 | static const bt_port_input *portByIndex(const bt_component_filter * const libCompPtr, | |
205 | const std::uint64_t index) noexcept | |
206 | { | |
207 | return bt_component_filter_borrow_input_port_by_index_const(libCompPtr, index); | |
208 | } | |
209 | ||
210 | static const bt_port_input *portByName(const bt_component_filter * const libCompPtr, | |
211 | const char * const name) noexcept | |
212 | { | |
213 | return bt_component_filter_borrow_input_port_by_name_const(libCompPtr, name); | |
214 | } | |
215 | }; | |
216 | ||
217 | template <> | |
218 | struct ConstComponentPortsSpec<const bt_component_sink, const bt_port_input> final | |
219 | { | |
220 | static std::uint64_t portCount(const bt_component_sink * const libCompPtr) noexcept | |
221 | { | |
222 | return bt_component_sink_get_input_port_count(libCompPtr); | |
223 | } | |
224 | ||
225 | static const bt_port_input *portByIndex(const bt_component_sink * const libCompPtr, | |
226 | const std::uint64_t index) noexcept | |
227 | { | |
228 | return bt_component_sink_borrow_input_port_by_index_const(libCompPtr, index); | |
229 | } | |
230 | ||
231 | static const bt_port_input *portByName(const bt_component_sink * const libCompPtr, | |
232 | const char * const name) noexcept | |
233 | { | |
234 | return bt_component_sink_borrow_input_port_by_name_const(libCompPtr, name); | |
235 | } | |
236 | }; | |
237 | ||
238 | } /* namespace internal */ | |
239 | ||
240 | template <typename> | |
241 | class ConstPort; | |
242 | ||
243 | template <typename LibCompT, typename LibPortT> | |
244 | class ConstComponentPorts final : public BorrowedObject<LibCompT> | |
245 | { | |
246 | private: | |
247 | using _Spec = internal::ConstComponentPortsSpec<LibCompT, LibPortT>; | |
248 | ||
249 | public: | |
d246c457 | 250 | using typename BorrowedObject<LibCompT>::LibObjPtr; |
7bdf11a1 PP |
251 | using Port = ConstPort<LibPortT>; |
252 | using Iterator = BorrowedObjectIterator<ConstComponentPorts>; | |
253 | ||
d246c457 | 254 | explicit ConstComponentPorts(const LibObjPtr libObjPtr) noexcept : |
7bdf11a1 PP |
255 | BorrowedObject<LibCompT> {libObjPtr} |
256 | { | |
257 | } | |
258 | ||
259 | std::uint64_t length() const noexcept | |
260 | { | |
261 | return _Spec::portCount(this->libObjPtr()); | |
262 | } | |
263 | ||
264 | Port operator[](std::uint64_t index) const noexcept; | |
15030982 | 265 | Port operator[](bt2c::CStringView name) const noexcept; |
7bdf11a1 PP |
266 | Iterator begin() const noexcept; |
267 | Iterator end() const noexcept; | |
268 | }; | |
269 | ||
270 | namespace internal { | |
271 | ||
272 | struct ConstSourceComponentRefFuncs final | |
273 | { | |
274 | static void get(const bt_component_source * const libObjPtr) noexcept | |
275 | { | |
276 | bt_component_source_get_ref(libObjPtr); | |
277 | } | |
278 | ||
279 | static void put(const bt_component_source * const libObjPtr) noexcept | |
280 | { | |
281 | bt_component_source_put_ref(libObjPtr); | |
282 | } | |
283 | }; | |
284 | ||
285 | } /* namespace internal */ | |
286 | ||
287 | class ConstSourceComponent final : public ConstSpecificComponent<const bt_component_source> | |
288 | { | |
289 | public: | |
290 | using Shared = SharedObject<ConstSourceComponent, const bt_component_source, | |
291 | internal::ConstSourceComponentRefFuncs>; | |
292 | ||
293 | using OutputPorts = ConstComponentPorts<const bt_component_source, const bt_port_output>; | |
294 | ||
295 | explicit ConstSourceComponent(const bt_component_source * const libObjPtr) noexcept : | |
296 | ConstSpecificComponent {libObjPtr} | |
297 | { | |
298 | } | |
299 | ||
300 | OutputPorts outputPorts() const noexcept; | |
301 | ||
302 | Shared shared() const noexcept | |
303 | { | |
304 | return Shared::createWithRef(*this); | |
305 | } | |
306 | }; | |
307 | ||
308 | namespace internal { | |
309 | ||
310 | struct ConstFilterComponentRefFuncs final | |
311 | { | |
312 | static void get(const bt_component_filter * const libObjPtr) noexcept | |
313 | { | |
314 | bt_component_filter_get_ref(libObjPtr); | |
315 | } | |
316 | ||
317 | static void put(const bt_component_filter * const libObjPtr) noexcept | |
318 | { | |
319 | bt_component_filter_put_ref(libObjPtr); | |
320 | } | |
321 | }; | |
322 | ||
323 | } /* namespace internal */ | |
324 | ||
325 | class ConstFilterComponent final : public ConstSpecificComponent<const bt_component_filter> | |
326 | { | |
327 | public: | |
328 | using Shared = SharedObject<ConstFilterComponent, const bt_component_filter, | |
329 | internal::ConstFilterComponentRefFuncs>; | |
330 | ||
331 | using InputPorts = ConstComponentPorts<const bt_component_filter, const bt_port_input>; | |
332 | using OutputPorts = ConstComponentPorts<const bt_component_filter, const bt_port_output>; | |
333 | ||
334 | explicit ConstFilterComponent(const bt_component_filter * const libObjPtr) noexcept : | |
335 | ConstSpecificComponent {libObjPtr} | |
336 | { | |
337 | } | |
338 | ||
339 | InputPorts inputPorts() const noexcept; | |
340 | OutputPorts outputPorts() const noexcept; | |
341 | ||
342 | Shared shared() const noexcept | |
343 | { | |
344 | return Shared::createWithRef(*this); | |
345 | } | |
346 | }; | |
347 | ||
348 | namespace internal { | |
349 | ||
350 | struct ConstSinkComponentRefFuncs final | |
351 | { | |
352 | static void get(const bt_component_sink * const libObjPtr) noexcept | |
353 | { | |
354 | bt_component_sink_get_ref(libObjPtr); | |
355 | } | |
356 | ||
357 | static void put(const bt_component_sink * const libObjPtr) noexcept | |
358 | { | |
359 | bt_component_sink_put_ref(libObjPtr); | |
360 | } | |
361 | }; | |
362 | ||
363 | } /* namespace internal */ | |
364 | ||
365 | class ConstSinkComponent final : public ConstSpecificComponent<const bt_component_sink> | |
366 | { | |
367 | public: | |
368 | using Shared = SharedObject<ConstSinkComponent, const bt_component_sink, | |
369 | internal::ConstSinkComponentRefFuncs>; | |
370 | ||
371 | using InputPorts = ConstComponentPorts<const bt_component_sink, const bt_port_input>; | |
372 | ||
373 | explicit ConstSinkComponent(const bt_component_sink * const libObjPtr) noexcept : | |
374 | ConstSpecificComponent {libObjPtr} | |
375 | { | |
376 | } | |
377 | ||
378 | InputPorts inputPorts() const noexcept; | |
379 | ||
380 | Shared shared() const noexcept | |
381 | { | |
382 | return Shared::createWithRef(*this); | |
383 | } | |
384 | }; | |
385 | ||
386 | inline ConstComponent::ConstComponent(const ConstSourceComponent other) noexcept : | |
387 | ConstComponent {other.libObjPtr()} | |
388 | { | |
389 | } | |
390 | ||
391 | inline ConstComponent::ConstComponent(const ConstFilterComponent other) noexcept : | |
392 | ConstComponent {other.libObjPtr()} | |
393 | { | |
394 | } | |
395 | ||
396 | inline ConstComponent::ConstComponent(const ConstSinkComponent other) noexcept : | |
397 | ConstComponent {other.libObjPtr()} | |
398 | { | |
399 | } | |
400 | ||
401 | inline ConstComponent ConstComponent::operator=(const ConstSourceComponent other) noexcept | |
402 | { | |
403 | *this = ConstComponent {other.libObjPtr()}; | |
404 | return *this; | |
405 | } | |
406 | ||
407 | inline ConstComponent ConstComponent::operator=(const ConstFilterComponent other) noexcept | |
408 | { | |
409 | *this = ConstComponent {other.libObjPtr()}; | |
410 | return *this; | |
411 | } | |
412 | ||
413 | inline ConstComponent ConstComponent::operator=(const ConstSinkComponent other) noexcept | |
414 | { | |
415 | *this = ConstComponent {other.libObjPtr()}; | |
416 | return *this; | |
417 | } | |
418 | ||
419 | namespace internal { | |
420 | ||
421 | template <typename LibObjT> | |
422 | struct ConstPortSpec; | |
423 | ||
424 | /* Functions specific to constant input ports */ | |
425 | template <> | |
426 | struct ConstPortSpec<const bt_port_input> final | |
427 | { | |
428 | static const bt_port *asPort(const bt_port_input * const libObjPtr) noexcept | |
429 | { | |
430 | return bt_port_input_as_port_const(libObjPtr); | |
431 | } | |
432 | }; | |
433 | ||
434 | /* Functions specific to constant output ports */ | |
435 | template <> | |
436 | struct ConstPortSpec<const bt_port_output> final | |
437 | { | |
438 | static const bt_port *asPort(const bt_port_output * const libObjPtr) noexcept | |
439 | { | |
440 | return bt_port_output_as_port_const(libObjPtr); | |
441 | } | |
442 | }; | |
443 | ||
444 | template <typename LibObjT> | |
445 | struct ConstPortRefFuncs final | |
446 | { | |
447 | static void get(LibObjT * const libObjPtr) noexcept | |
448 | { | |
449 | bt_port_get_ref(ConstPortSpec<LibObjT>::port(libObjPtr)); | |
450 | } | |
451 | ||
452 | static void put(LibObjT * const libObjPtr) noexcept | |
453 | { | |
454 | bt_port_put_ref(ConstPortSpec<LibObjT>::port(libObjPtr)); | |
455 | } | |
456 | }; | |
457 | ||
458 | } /* namespace internal */ | |
459 | ||
460 | template <typename LibObjT> | |
461 | class ConstPort final : public BorrowedObject<LibObjT> | |
462 | { | |
463 | public: | |
d246c457 | 464 | using typename BorrowedObject<LibObjT>::LibObjPtr; |
7bdf11a1 PP |
465 | using Shared = SharedObject<ConstPort, LibObjT, internal::ConstPortRefFuncs<LibObjT>>; |
466 | ||
d246c457 | 467 | explicit ConstPort(const LibObjPtr libObjPtr) noexcept : BorrowedObject<LibObjT> {libObjPtr} |
7bdf11a1 PP |
468 | { |
469 | } | |
470 | ||
e7f0f07b | 471 | bt2c::CStringView name() const noexcept |
7bdf11a1 PP |
472 | { |
473 | return bt_port_get_name(this->_libConstPortPtr()); | |
474 | } | |
475 | ||
476 | bool isConnected() const noexcept | |
477 | { | |
478 | return static_cast<bool>(bt_port_is_connected(this->_libConstPortPtr())); | |
479 | } | |
480 | ||
481 | ConstComponent component() const noexcept | |
482 | { | |
483 | return ConstComponent {bt_port_borrow_component_const(this->_libConstPortPtr())}; | |
484 | } | |
485 | ||
486 | Shared shared() const noexcept | |
487 | { | |
488 | return Shared::createWithRef(*this); | |
489 | } | |
490 | ||
491 | private: | |
492 | const bt_port *_libConstPortPtr() const noexcept | |
493 | { | |
494 | return internal::ConstPortSpec<LibObjT>::asPort(this->libObjPtr()); | |
495 | } | |
496 | }; | |
497 | ||
498 | template <typename LibCompT, typename LibPortT> | |
499 | typename ConstComponentPorts<LibCompT, LibPortT>::Port | |
500 | ConstComponentPorts<LibCompT, LibPortT>::operator[](const std::uint64_t index) const noexcept | |
501 | { | |
502 | return Port {_Spec::portByIndex(this->libObjPtr(), index)}; | |
503 | } | |
504 | ||
505 | template <typename LibCompT, typename LibPortT> | |
506 | typename ConstComponentPorts<LibCompT, LibPortT>::Port | |
15030982 | 507 | ConstComponentPorts<LibCompT, LibPortT>::operator[](const bt2c::CStringView name) const noexcept |
7bdf11a1 PP |
508 | { |
509 | return Port {_Spec::portByName(this->libObjPtr(), name)}; | |
510 | } | |
511 | ||
7bdf11a1 PP |
512 | template <typename LibCompT, typename LibPortT> |
513 | typename ConstComponentPorts<LibCompT, LibPortT>::Iterator | |
514 | ConstComponentPorts<LibCompT, LibPortT>::begin() const noexcept | |
515 | { | |
516 | return Iterator {*this, 0}; | |
517 | } | |
518 | ||
519 | template <typename LibCompT, typename LibPortT> | |
520 | typename ConstComponentPorts<LibCompT, LibPortT>::Iterator | |
521 | ConstComponentPorts<LibCompT, LibPortT>::end() const noexcept | |
522 | { | |
523 | return Iterator {*this, this->length()}; | |
524 | } | |
525 | ||
526 | using ConstInputPort = ConstPort<const bt_port_input>; | |
527 | using ConstOutputPort = ConstPort<const bt_port_output>; | |
528 | ||
529 | inline ConstSourceComponent::OutputPorts ConstSourceComponent::outputPorts() const noexcept | |
530 | { | |
531 | return OutputPorts {this->libObjPtr()}; | |
532 | } | |
533 | ||
534 | inline ConstFilterComponent::OutputPorts ConstFilterComponent::outputPorts() const noexcept | |
535 | { | |
536 | return OutputPorts {this->libObjPtr()}; | |
537 | } | |
538 | ||
539 | inline ConstFilterComponent::InputPorts ConstFilterComponent::inputPorts() const noexcept | |
540 | { | |
541 | return InputPorts {this->libObjPtr()}; | |
542 | } | |
543 | ||
544 | inline ConstSinkComponent::InputPorts ConstSinkComponent::inputPorts() const noexcept | |
545 | { | |
546 | return InputPorts {this->libObjPtr()}; | |
547 | } | |
548 | ||
549 | } /* namespace bt2 */ | |
550 | ||
551 | #endif /* BABELTRACE_CPP_COMMON_BT2_COMPONENT_PORT_HPP */ |