Commit | Line | Data |
---|---|---|
d9a27df8 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_MESSAGE_ITERATOR_HPP | |
8 | #define BABELTRACE_CPP_COMMON_BT2_MESSAGE_ITERATOR_HPP | |
9 | ||
10 | #include <babeltrace2/babeltrace.h> | |
11 | ||
12 | #include "common/common.h" | |
13 | #include "cpp-common/optional.hpp" | |
14 | ||
15 | #include "component-port.hpp" | |
16 | #include "exc.hpp" | |
17 | #include "message-array.hpp" | |
18 | #include "shared-object.hpp" | |
19 | ||
20 | namespace bt2 { | |
21 | namespace internal { | |
22 | ||
23 | struct MessageIteratorRefFuncs final | |
24 | { | |
25 | static void get(const bt_message_iterator * const libObjPtr) noexcept | |
26 | { | |
27 | bt_message_iterator_get_ref(libObjPtr); | |
28 | } | |
29 | ||
30 | static void put(const bt_message_iterator * const libObjPtr) noexcept | |
31 | { | |
32 | bt_message_iterator_put_ref(libObjPtr); | |
33 | } | |
34 | }; | |
35 | ||
36 | } /* namespace internal */ | |
37 | ||
38 | class MessageIterator final : public BorrowedObject<bt_message_iterator> | |
39 | { | |
40 | public: | |
41 | using Shared = | |
42 | SharedObject<MessageIterator, bt_message_iterator, internal::MessageIteratorRefFuncs>; | |
43 | ||
44 | explicit MessageIterator(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr} | |
45 | { | |
46 | } | |
47 | ||
48 | ConstComponent component() const noexcept | |
49 | { | |
50 | return ConstComponent {bt_message_iterator_borrow_component(this->libObjPtr())}; | |
51 | } | |
52 | ||
53 | nonstd::optional<ConstMessageArray> next() const | |
54 | { | |
55 | bt_message_array_const libMsgsPtr; | |
56 | std::uint64_t count; | |
57 | const auto status = bt_message_iterator_next(this->libObjPtr(), &libMsgsPtr, &count); | |
58 | ||
59 | switch (status) { | |
60 | case BT_MESSAGE_ITERATOR_NEXT_STATUS_OK: | |
61 | /* Caller becomes the owner of the contained messages */ | |
62 | return ConstMessageArray::wrapExisting(libMsgsPtr, count); | |
63 | case BT_MESSAGE_ITERATOR_NEXT_STATUS_END: | |
64 | return nonstd::nullopt; | |
65 | case BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN: | |
66 | throw TryAgain {}; | |
67 | case BT_MESSAGE_ITERATOR_NEXT_STATUS_MEMORY_ERROR: | |
68 | throw MemoryError {}; | |
69 | case BT_MESSAGE_ITERATOR_NEXT_STATUS_ERROR: | |
70 | throw Error {}; | |
71 | default: | |
72 | bt_common_abort(); | |
73 | } | |
74 | } | |
75 | ||
76 | bool canSeekBeginning() const | |
77 | { | |
78 | bt_bool canSeek; | |
79 | ||
80 | const auto status = bt_message_iterator_can_seek_beginning(this->libObjPtr(), &canSeek); | |
81 | ||
82 | switch (status) { | |
83 | case BT_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_STATUS_OK: | |
84 | return static_cast<bool>(canSeek); | |
85 | case BT_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_STATUS_AGAIN: | |
86 | throw TryAgain {}; | |
87 | case BT_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_STATUS_MEMORY_ERROR: | |
88 | throw MemoryError {}; | |
89 | case BT_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_STATUS_ERROR: | |
90 | throw Error {}; | |
91 | default: | |
92 | bt_common_abort(); | |
93 | } | |
94 | } | |
95 | ||
96 | void seekBeginning() const | |
97 | { | |
98 | const auto status = bt_message_iterator_seek_beginning(this->libObjPtr()); | |
99 | ||
100 | switch (status) { | |
101 | case BT_MESSAGE_ITERATOR_SEEK_BEGINNING_STATUS_OK: | |
102 | return; | |
103 | case BT_MESSAGE_ITERATOR_SEEK_BEGINNING_STATUS_AGAIN: | |
104 | throw TryAgain {}; | |
105 | case BT_MESSAGE_ITERATOR_SEEK_BEGINNING_STATUS_MEMORY_ERROR: | |
106 | throw MemoryError {}; | |
107 | case BT_MESSAGE_ITERATOR_SEEK_BEGINNING_STATUS_ERROR: | |
108 | throw Error {}; | |
109 | default: | |
110 | bt_common_abort(); | |
111 | } | |
112 | } | |
113 | ||
114 | bool canSeekNsFromOrigin(const std::int64_t nsFromOrigin) const | |
115 | { | |
116 | bt_bool canSeek; | |
117 | ||
118 | const auto status = | |
119 | bt_message_iterator_can_seek_ns_from_origin(this->libObjPtr(), nsFromOrigin, &canSeek); | |
120 | ||
121 | switch (status) { | |
122 | case BT_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_STATUS_OK: | |
123 | return static_cast<bool>(canSeek); | |
124 | case BT_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_STATUS_AGAIN: | |
125 | throw TryAgain {}; | |
126 | case BT_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_STATUS_MEMORY_ERROR: | |
127 | throw MemoryError {}; | |
128 | case BT_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_STATUS_ERROR: | |
129 | throw Error {}; | |
130 | default: | |
131 | bt_common_abort(); | |
132 | } | |
133 | } | |
134 | ||
135 | void seekNsFromOrigin(const std::int64_t nsFromOrigin) const | |
136 | { | |
137 | const auto status = | |
138 | bt_message_iterator_seek_ns_from_origin(this->libObjPtr(), nsFromOrigin); | |
139 | ||
140 | switch (status) { | |
141 | case BT_MESSAGE_ITERATOR_SEEK_NS_FROM_ORIGIN_STATUS_OK: | |
142 | return; | |
143 | case BT_MESSAGE_ITERATOR_SEEK_NS_FROM_ORIGIN_STATUS_AGAIN: | |
144 | throw TryAgain {}; | |
145 | case BT_MESSAGE_ITERATOR_SEEK_NS_FROM_ORIGIN_STATUS_MEMORY_ERROR: | |
146 | throw MemoryError {}; | |
147 | case BT_MESSAGE_ITERATOR_SEEK_NS_FROM_ORIGIN_STATUS_ERROR: | |
148 | throw Error {}; | |
149 | default: | |
150 | bt_common_abort(); | |
151 | } | |
152 | } | |
153 | ||
154 | bool canSeekForward() const noexcept | |
155 | { | |
156 | return static_cast<bool>(bt_message_iterator_can_seek_forward(this->libObjPtr())); | |
157 | } | |
158 | ||
159 | Shared shared() const noexcept | |
160 | { | |
161 | return Shared::createWithRef(*this); | |
162 | } | |
163 | }; | |
164 | ||
165 | } /* namespace bt2 */ | |
166 | ||
167 | #endif /* BABELTRACE_CPP_COMMON_BT2_MESSAGE_ITERATOR_HPP */ |