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; | |
265 | Port operator[](const char *name) const noexcept; | |
266 | Port operator[](const std::string& name) const noexcept; | |
267 | Iterator begin() const noexcept; | |
268 | Iterator end() const noexcept; | |
269 | }; | |
270 | ||
271 | namespace internal { | |
272 | ||
273 | struct ConstSourceComponentRefFuncs final | |
274 | { | |
275 | static void get(const bt_component_source * const libObjPtr) noexcept | |
276 | { | |
277 | bt_component_source_get_ref(libObjPtr); | |
278 | } | |
279 | ||
280 | static void put(const bt_component_source * const libObjPtr) noexcept | |
281 | { | |
282 | bt_component_source_put_ref(libObjPtr); | |
283 | } | |
284 | }; | |
285 | ||
286 | } /* namespace internal */ | |
287 | ||
288 | class ConstSourceComponent final : public ConstSpecificComponent<const bt_component_source> | |
289 | { | |
290 | public: | |
291 | using Shared = SharedObject<ConstSourceComponent, const bt_component_source, | |
292 | internal::ConstSourceComponentRefFuncs>; | |
293 | ||
294 | using OutputPorts = ConstComponentPorts<const bt_component_source, const bt_port_output>; | |
295 | ||
296 | explicit ConstSourceComponent(const bt_component_source * const libObjPtr) noexcept : | |
297 | ConstSpecificComponent {libObjPtr} | |
298 | { | |
299 | } | |
300 | ||
301 | OutputPorts outputPorts() const noexcept; | |
302 | ||
303 | Shared shared() const noexcept | |
304 | { | |
305 | return Shared::createWithRef(*this); | |
306 | } | |
307 | }; | |
308 | ||
309 | namespace internal { | |
310 | ||
311 | struct ConstFilterComponentRefFuncs final | |
312 | { | |
313 | static void get(const bt_component_filter * const libObjPtr) noexcept | |
314 | { | |
315 | bt_component_filter_get_ref(libObjPtr); | |
316 | } | |
317 | ||
318 | static void put(const bt_component_filter * const libObjPtr) noexcept | |
319 | { | |
320 | bt_component_filter_put_ref(libObjPtr); | |
321 | } | |
322 | }; | |
323 | ||
324 | } /* namespace internal */ | |
325 | ||
326 | class ConstFilterComponent final : public ConstSpecificComponent<const bt_component_filter> | |
327 | { | |
328 | public: | |
329 | using Shared = SharedObject<ConstFilterComponent, const bt_component_filter, | |
330 | internal::ConstFilterComponentRefFuncs>; | |
331 | ||
332 | using InputPorts = ConstComponentPorts<const bt_component_filter, const bt_port_input>; | |
333 | using OutputPorts = ConstComponentPorts<const bt_component_filter, const bt_port_output>; | |
334 | ||
335 | explicit ConstFilterComponent(const bt_component_filter * const libObjPtr) noexcept : | |
336 | ConstSpecificComponent {libObjPtr} | |
337 | { | |
338 | } | |
339 | ||
340 | InputPorts inputPorts() const noexcept; | |
341 | OutputPorts outputPorts() const noexcept; | |
342 | ||
343 | Shared shared() const noexcept | |
344 | { | |
345 | return Shared::createWithRef(*this); | |
346 | } | |
347 | }; | |
348 | ||
349 | namespace internal { | |
350 | ||
351 | struct ConstSinkComponentRefFuncs final | |
352 | { | |
353 | static void get(const bt_component_sink * const libObjPtr) noexcept | |
354 | { | |
355 | bt_component_sink_get_ref(libObjPtr); | |
356 | } | |
357 | ||
358 | static void put(const bt_component_sink * const libObjPtr) noexcept | |
359 | { | |
360 | bt_component_sink_put_ref(libObjPtr); | |
361 | } | |
362 | }; | |
363 | ||
364 | } /* namespace internal */ | |
365 | ||
366 | class ConstSinkComponent final : public ConstSpecificComponent<const bt_component_sink> | |
367 | { | |
368 | public: | |
369 | using Shared = SharedObject<ConstSinkComponent, const bt_component_sink, | |
370 | internal::ConstSinkComponentRefFuncs>; | |
371 | ||
372 | using InputPorts = ConstComponentPorts<const bt_component_sink, const bt_port_input>; | |
373 | ||
374 | explicit ConstSinkComponent(const bt_component_sink * const libObjPtr) noexcept : | |
375 | ConstSpecificComponent {libObjPtr} | |
376 | { | |
377 | } | |
378 | ||
379 | InputPorts inputPorts() const noexcept; | |
380 | ||
381 | Shared shared() const noexcept | |
382 | { | |
383 | return Shared::createWithRef(*this); | |
384 | } | |
385 | }; | |
386 | ||
387 | inline ConstComponent::ConstComponent(const ConstSourceComponent other) noexcept : | |
388 | ConstComponent {other.libObjPtr()} | |
389 | { | |
390 | } | |
391 | ||
392 | inline ConstComponent::ConstComponent(const ConstFilterComponent other) noexcept : | |
393 | ConstComponent {other.libObjPtr()} | |
394 | { | |
395 | } | |
396 | ||
397 | inline ConstComponent::ConstComponent(const ConstSinkComponent other) noexcept : | |
398 | ConstComponent {other.libObjPtr()} | |
399 | { | |
400 | } | |
401 | ||
402 | inline ConstComponent ConstComponent::operator=(const ConstSourceComponent other) noexcept | |
403 | { | |
404 | *this = ConstComponent {other.libObjPtr()}; | |
405 | return *this; | |
406 | } | |
407 | ||
408 | inline ConstComponent ConstComponent::operator=(const ConstFilterComponent other) noexcept | |
409 | { | |
410 | *this = ConstComponent {other.libObjPtr()}; | |
411 | return *this; | |
412 | } | |
413 | ||
414 | inline ConstComponent ConstComponent::operator=(const ConstSinkComponent other) noexcept | |
415 | { | |
416 | *this = ConstComponent {other.libObjPtr()}; | |
417 | return *this; | |
418 | } | |
419 | ||
420 | namespace internal { | |
421 | ||
422 | template <typename LibObjT> | |
423 | struct ConstPortSpec; | |
424 | ||
425 | /* Functions specific to constant input ports */ | |
426 | template <> | |
427 | struct ConstPortSpec<const bt_port_input> final | |
428 | { | |
429 | static const bt_port *asPort(const bt_port_input * const libObjPtr) noexcept | |
430 | { | |
431 | return bt_port_input_as_port_const(libObjPtr); | |
432 | } | |
433 | }; | |
434 | ||
435 | /* Functions specific to constant output ports */ | |
436 | template <> | |
437 | struct ConstPortSpec<const bt_port_output> final | |
438 | { | |
439 | static const bt_port *asPort(const bt_port_output * const libObjPtr) noexcept | |
440 | { | |
441 | return bt_port_output_as_port_const(libObjPtr); | |
442 | } | |
443 | }; | |
444 | ||
445 | template <typename LibObjT> | |
446 | struct ConstPortRefFuncs final | |
447 | { | |
448 | static void get(LibObjT * const libObjPtr) noexcept | |
449 | { | |
450 | bt_port_get_ref(ConstPortSpec<LibObjT>::port(libObjPtr)); | |
451 | } | |
452 | ||
453 | static void put(LibObjT * const libObjPtr) noexcept | |
454 | { | |
455 | bt_port_put_ref(ConstPortSpec<LibObjT>::port(libObjPtr)); | |
456 | } | |
457 | }; | |
458 | ||
459 | } /* namespace internal */ | |
460 | ||
461 | template <typename LibObjT> | |
462 | class ConstPort final : public BorrowedObject<LibObjT> | |
463 | { | |
464 | public: | |
d246c457 | 465 | using typename BorrowedObject<LibObjT>::LibObjPtr; |
7bdf11a1 PP |
466 | using Shared = SharedObject<ConstPort, LibObjT, internal::ConstPortRefFuncs<LibObjT>>; |
467 | ||
d246c457 | 468 | explicit ConstPort(const LibObjPtr libObjPtr) noexcept : BorrowedObject<LibObjT> {libObjPtr} |
7bdf11a1 PP |
469 | { |
470 | } | |
471 | ||
e7f0f07b | 472 | bt2c::CStringView name() const noexcept |
7bdf11a1 PP |
473 | { |
474 | return bt_port_get_name(this->_libConstPortPtr()); | |
475 | } | |
476 | ||
477 | bool isConnected() const noexcept | |
478 | { | |
479 | return static_cast<bool>(bt_port_is_connected(this->_libConstPortPtr())); | |
480 | } | |
481 | ||
482 | ConstComponent component() const noexcept | |
483 | { | |
484 | return ConstComponent {bt_port_borrow_component_const(this->_libConstPortPtr())}; | |
485 | } | |
486 | ||
487 | Shared shared() const noexcept | |
488 | { | |
489 | return Shared::createWithRef(*this); | |
490 | } | |
491 | ||
492 | private: | |
493 | const bt_port *_libConstPortPtr() const noexcept | |
494 | { | |
495 | return internal::ConstPortSpec<LibObjT>::asPort(this->libObjPtr()); | |
496 | } | |
497 | }; | |
498 | ||
499 | template <typename LibCompT, typename LibPortT> | |
500 | typename ConstComponentPorts<LibCompT, LibPortT>::Port | |
501 | ConstComponentPorts<LibCompT, LibPortT>::operator[](const std::uint64_t index) const noexcept | |
502 | { | |
503 | return Port {_Spec::portByIndex(this->libObjPtr(), index)}; | |
504 | } | |
505 | ||
506 | template <typename LibCompT, typename LibPortT> | |
507 | typename ConstComponentPorts<LibCompT, LibPortT>::Port | |
508 | ConstComponentPorts<LibCompT, LibPortT>::operator[](const char * const name) const noexcept | |
509 | { | |
510 | return Port {_Spec::portByName(this->libObjPtr(), name)}; | |
511 | } | |
512 | ||
513 | template <typename LibCompT, typename LibPortT> | |
514 | typename ConstComponentPorts<LibCompT, LibPortT>::Port | |
515 | ConstComponentPorts<LibCompT, LibPortT>::operator[](const std::string& name) const noexcept | |
516 | { | |
517 | return (*this)[name.data()]; | |
518 | } | |
519 | ||
520 | template <typename LibCompT, typename LibPortT> | |
521 | typename ConstComponentPorts<LibCompT, LibPortT>::Iterator | |
522 | ConstComponentPorts<LibCompT, LibPortT>::begin() const noexcept | |
523 | { | |
524 | return Iterator {*this, 0}; | |
525 | } | |
526 | ||
527 | template <typename LibCompT, typename LibPortT> | |
528 | typename ConstComponentPorts<LibCompT, LibPortT>::Iterator | |
529 | ConstComponentPorts<LibCompT, LibPortT>::end() const noexcept | |
530 | { | |
531 | return Iterator {*this, this->length()}; | |
532 | } | |
533 | ||
534 | using ConstInputPort = ConstPort<const bt_port_input>; | |
535 | using ConstOutputPort = ConstPort<const bt_port_output>; | |
536 | ||
537 | inline ConstSourceComponent::OutputPorts ConstSourceComponent::outputPorts() const noexcept | |
538 | { | |
539 | return OutputPorts {this->libObjPtr()}; | |
540 | } | |
541 | ||
542 | inline ConstFilterComponent::OutputPorts ConstFilterComponent::outputPorts() const noexcept | |
543 | { | |
544 | return OutputPorts {this->libObjPtr()}; | |
545 | } | |
546 | ||
547 | inline ConstFilterComponent::InputPorts ConstFilterComponent::inputPorts() const noexcept | |
548 | { | |
549 | return InputPorts {this->libObjPtr()}; | |
550 | } | |
551 | ||
552 | inline ConstSinkComponent::InputPorts ConstSinkComponent::inputPorts() const noexcept | |
553 | { | |
554 | return InputPorts {this->libObjPtr()}; | |
555 | } | |
556 | ||
557 | } /* namespace bt2 */ | |
558 | ||
559 | #endif /* BABELTRACE_CPP_COMMON_BT2_COMPONENT_PORT_HPP */ |