Commit | Line | Data |
---|---|---|
a65c7bf4 SM |
1 | /* |
2 | * Copyright (c) 2024 EfficiOS Inc. | |
3 | * | |
4 | * SPDX-License-Identifier: MIT | |
5 | */ | |
6 | ||
7 | #ifndef BABELTRACE_CPP_COMMON_BT2_ERROR_HPP | |
8 | #define BABELTRACE_CPP_COMMON_BT2_ERROR_HPP | |
9 | ||
10 | #include <cstdint> | |
11 | #include <memory> | |
12 | ||
13 | #include <babeltrace2/babeltrace.h> | |
14 | ||
15 | #include "common/assert.h" | |
16 | #include "cpp-common/bt2c/c-string-view.hpp" | |
17 | #include "cpp-common/vendor/fmt/format.h" /* IWYU pragma: keep */ | |
18 | ||
19 | #include "borrowed-object.hpp" | |
20 | #include "component-class.hpp" | |
21 | ||
22 | namespace bt2 { | |
23 | ||
24 | class ConstComponentClassErrorCause; | |
25 | class ConstComponentErrorCause; | |
26 | class ConstMessageIteratorErrorCause; | |
27 | ||
33f20928 SM |
28 | enum class ErrorCauseActorType |
29 | { | |
30 | Unknown = BT_ERROR_CAUSE_ACTOR_TYPE_UNKNOWN, | |
31 | Component = BT_ERROR_CAUSE_ACTOR_TYPE_COMPONENT, | |
32 | ComponentClass = BT_ERROR_CAUSE_ACTOR_TYPE_COMPONENT_CLASS, | |
33 | MessageIterator = BT_ERROR_CAUSE_ACTOR_TYPE_MESSAGE_ITERATOR, | |
34 | }; | |
35 | ||
a65c7bf4 SM |
36 | class ConstErrorCause : public BorrowedObject<const bt_error_cause> |
37 | { | |
38 | public: | |
a65c7bf4 SM |
39 | explicit ConstErrorCause(const LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr} |
40 | { | |
41 | } | |
42 | ||
33f20928 | 43 | ErrorCauseActorType actorType() const noexcept |
a65c7bf4 | 44 | { |
33f20928 | 45 | return static_cast<ErrorCauseActorType>(bt_error_cause_get_actor_type(this->libObjPtr())); |
a65c7bf4 SM |
46 | } |
47 | ||
48 | bool actorTypeIsComponentClass() const noexcept | |
49 | { | |
33f20928 | 50 | return this->actorType() == ErrorCauseActorType::ComponentClass; |
a65c7bf4 SM |
51 | } |
52 | ||
53 | bool actorTypeIsComponent() const noexcept | |
54 | { | |
33f20928 | 55 | return this->actorType() == ErrorCauseActorType::Component; |
a65c7bf4 SM |
56 | } |
57 | ||
58 | bool actorTypeIsMessageIterator() const noexcept | |
59 | { | |
33f20928 | 60 | return this->actorType() == ErrorCauseActorType::MessageIterator; |
a65c7bf4 SM |
61 | } |
62 | ||
63 | ConstComponentClassErrorCause asComponentClass() const noexcept; | |
64 | ConstComponentErrorCause asComponent() const noexcept; | |
65 | ConstMessageIteratorErrorCause asMessageIterator() const noexcept; | |
66 | ||
67 | bt2c::CStringView message() const noexcept | |
68 | { | |
69 | return bt_error_cause_get_message(this->libObjPtr()); | |
70 | } | |
71 | ||
72 | bt2c::CStringView moduleName() const noexcept | |
73 | { | |
74 | return bt_error_cause_get_module_name(this->libObjPtr()); | |
75 | } | |
76 | ||
77 | bt2c::CStringView fileName() const noexcept | |
78 | { | |
79 | return bt_error_cause_get_file_name(this->libObjPtr()); | |
80 | } | |
81 | ||
82 | std::uint64_t lineNumber() const noexcept | |
83 | { | |
84 | return bt_error_cause_get_line_number(this->libObjPtr()); | |
85 | } | |
86 | }; | |
87 | ||
88 | class ConstComponentClassErrorCause final : public ConstErrorCause | |
89 | { | |
90 | public: | |
91 | explicit ConstComponentClassErrorCause(const LibObjPtr libObjPtr) : ConstErrorCause {libObjPtr} | |
92 | { | |
93 | BT_ASSERT(this->actorTypeIsComponentClass()); | |
94 | } | |
95 | ||
33f20928 | 96 | bt2::ComponentClassType componentClassType() const noexcept |
a65c7bf4 | 97 | { |
33f20928 | 98 | return static_cast<bt2::ComponentClassType>( |
a65c7bf4 SM |
99 | bt_error_cause_component_class_actor_get_component_class_type(this->libObjPtr())); |
100 | } | |
101 | ||
102 | bt2c::CStringView componentClassName() const noexcept | |
103 | { | |
104 | return bt_error_cause_component_class_actor_get_component_class_name(this->libObjPtr()); | |
105 | } | |
106 | ||
107 | bt2c::CStringView pluginName() const noexcept | |
108 | { | |
109 | return bt_error_cause_component_class_actor_get_plugin_name(this->libObjPtr()); | |
110 | } | |
111 | }; | |
112 | ||
113 | inline ConstComponentClassErrorCause ConstErrorCause::asComponentClass() const noexcept | |
114 | { | |
115 | return ConstComponentClassErrorCause {this->libObjPtr()}; | |
116 | } | |
117 | ||
118 | class ConstComponentErrorCause final : public ConstErrorCause | |
119 | { | |
120 | public: | |
121 | explicit ConstComponentErrorCause(const LibObjPtr libObjPtr) : ConstErrorCause {libObjPtr} | |
122 | { | |
123 | BT_ASSERT(this->actorTypeIsComponent()); | |
124 | } | |
125 | ||
126 | bt2c::CStringView componentName() const noexcept | |
127 | { | |
128 | return bt_error_cause_component_actor_get_component_name(this->libObjPtr()); | |
129 | } | |
130 | ||
33f20928 | 131 | bt2::ComponentClassType componentClassType() const noexcept |
a65c7bf4 | 132 | { |
33f20928 | 133 | return static_cast<bt2::ComponentClassType>( |
a65c7bf4 SM |
134 | bt_error_cause_component_actor_get_component_class_type(this->libObjPtr())); |
135 | } | |
136 | ||
137 | bt2c::CStringView componentClassName() const noexcept | |
138 | { | |
139 | return bt_error_cause_component_actor_get_component_class_name(this->libObjPtr()); | |
140 | } | |
141 | ||
142 | bt2c::CStringView pluginName() const noexcept | |
143 | { | |
144 | return bt_error_cause_component_actor_get_plugin_name(this->libObjPtr()); | |
145 | } | |
146 | }; | |
147 | ||
148 | inline ConstComponentErrorCause ConstErrorCause::asComponent() const noexcept | |
149 | { | |
150 | return ConstComponentErrorCause {this->libObjPtr()}; | |
151 | } | |
152 | ||
153 | class ConstMessageIteratorErrorCause final : public ConstErrorCause | |
154 | { | |
155 | public: | |
156 | explicit ConstMessageIteratorErrorCause(const LibObjPtr libObjPtr) : ConstErrorCause {libObjPtr} | |
157 | { | |
158 | BT_ASSERT(this->actorTypeIsMessageIterator()); | |
159 | } | |
160 | ||
161 | bt2c::CStringView componentOutputPortName() const noexcept | |
162 | { | |
163 | return bt_error_cause_message_iterator_actor_get_component_name(this->libObjPtr()); | |
164 | } | |
165 | ||
166 | bt2c::CStringView componentName() const noexcept | |
167 | { | |
168 | return bt_error_cause_message_iterator_actor_get_component_name(this->libObjPtr()); | |
169 | } | |
170 | ||
33f20928 | 171 | bt2::ComponentClassType componentClassType() const noexcept |
a65c7bf4 | 172 | { |
33f20928 | 173 | return static_cast<bt2::ComponentClassType>( |
a65c7bf4 SM |
174 | bt_error_cause_message_iterator_actor_get_component_class_type(this->libObjPtr())); |
175 | } | |
176 | ||
177 | bt2c::CStringView componentClassName() const noexcept | |
178 | { | |
179 | return bt_error_cause_message_iterator_actor_get_component_class_name(this->libObjPtr()); | |
180 | } | |
181 | ||
182 | bt2c::CStringView pluginName() const noexcept | |
183 | { | |
184 | return bt_error_cause_message_iterator_actor_get_plugin_name(this->libObjPtr()); | |
185 | } | |
186 | }; | |
187 | ||
188 | inline ConstMessageIteratorErrorCause ConstErrorCause::asMessageIterator() const noexcept | |
189 | { | |
190 | return ConstMessageIteratorErrorCause {this->libObjPtr()}; | |
191 | } | |
192 | ||
193 | class ConstErrorIterator; | |
194 | ||
195 | class ConstErrorCauseProxy final | |
196 | { | |
197 | friend ConstErrorIterator; | |
198 | ||
199 | private: | |
200 | explicit ConstErrorCauseProxy(const ConstErrorCause cause) noexcept : _mCause {cause} | |
201 | { | |
202 | } | |
203 | ||
204 | public: | |
205 | const ConstErrorCause *operator->() const noexcept | |
206 | { | |
207 | return &_mCause; | |
208 | } | |
209 | ||
210 | private: | |
211 | ConstErrorCause _mCause; | |
212 | }; | |
213 | ||
214 | class UniqueConstError; | |
215 | ||
216 | class ConstErrorIterator final | |
217 | { | |
218 | friend UniqueConstError; | |
219 | ||
220 | private: | |
221 | explicit ConstErrorIterator(const UniqueConstError& error, const std::uint64_t index) noexcept : | |
222 | _mError {error}, _mIndex {index} | |
223 | { | |
224 | } | |
225 | ||
226 | public: | |
227 | bool operator==(const ConstErrorIterator& other) const noexcept | |
228 | { | |
229 | BT_ASSERT(&other._mError == &_mError); | |
230 | return other._mIndex == _mIndex; | |
231 | } | |
232 | ||
233 | bool operator!=(const ConstErrorIterator& other) const noexcept | |
234 | { | |
235 | return !(*this == other); | |
236 | } | |
237 | ||
238 | ConstErrorIterator& operator++() noexcept | |
239 | { | |
240 | ++_mIndex; | |
241 | return *this; | |
242 | } | |
243 | ||
244 | ConstErrorIterator operator++(int) noexcept | |
245 | { | |
246 | const auto ret = *this; | |
247 | ||
248 | ++_mIndex; | |
249 | return ret; | |
250 | } | |
251 | ||
252 | ConstErrorCause operator*() const noexcept; | |
253 | ||
254 | ConstErrorCauseProxy operator->() const noexcept | |
255 | { | |
256 | return ConstErrorCauseProxy {**this}; | |
257 | } | |
258 | ||
259 | private: | |
260 | const UniqueConstError& _mError; | |
261 | std::uint64_t _mIndex; | |
262 | }; | |
263 | ||
264 | class UniqueConstError final | |
265 | { | |
266 | public: | |
267 | using LibObjPtr = const bt_error *; | |
268 | ||
269 | explicit UniqueConstError(const LibObjPtr libError) noexcept : _mLibError {libError} | |
270 | { | |
271 | } | |
272 | ||
273 | explicit operator bool() const noexcept | |
274 | { | |
275 | return this->libObjPtr(); | |
276 | } | |
277 | ||
278 | LibObjPtr libObjPtr() const noexcept | |
279 | { | |
280 | return _mLibError.get(); | |
281 | } | |
282 | ||
283 | LibObjPtr release() noexcept | |
284 | { | |
285 | return _mLibError.release(); | |
286 | } | |
287 | ||
288 | std::uint64_t length() const noexcept | |
289 | { | |
290 | return bt_error_get_cause_count(this->libObjPtr()); | |
291 | } | |
292 | ||
293 | ConstErrorCause operator[](const std::uint64_t index) const noexcept | |
294 | { | |
295 | return ConstErrorCause {bt_error_borrow_cause_by_index(this->libObjPtr(), index)}; | |
296 | } | |
297 | ||
298 | ConstErrorIterator begin() const noexcept | |
299 | { | |
300 | BT_ASSERT(_mLibError); | |
301 | return ConstErrorIterator {*this, 0}; | |
302 | } | |
303 | ||
304 | ConstErrorIterator end() const noexcept | |
305 | { | |
306 | BT_ASSERT(_mLibError); | |
307 | return ConstErrorIterator {*this, this->length()}; | |
308 | } | |
309 | ||
310 | private: | |
311 | struct _LibErrorDeleter final | |
312 | { | |
313 | void operator()(const LibObjPtr libError) const noexcept | |
314 | { | |
315 | bt_error_release(libError); | |
316 | } | |
317 | }; | |
318 | ||
319 | std::unique_ptr<std::remove_pointer<LibObjPtr>::type, _LibErrorDeleter> _mLibError; | |
320 | }; | |
321 | ||
322 | inline ConstErrorCause ConstErrorIterator::operator*() const noexcept | |
323 | { | |
324 | return _mError[_mIndex]; | |
325 | } | |
326 | ||
327 | inline UniqueConstError takeCurrentThreadError() noexcept | |
328 | { | |
329 | return UniqueConstError {bt_current_thread_take_error()}; | |
330 | } | |
331 | ||
332 | inline void moveErrorToCurrentThread(UniqueConstError error) noexcept | |
333 | { | |
334 | bt_current_thread_move_error(error.release()); | |
335 | } | |
336 | ||
337 | } /* namespace bt2 */ | |
338 | ||
339 | #endif /* BABELTRACE_CPP_COMMON_BT2_ERROR_HPP */ |