From: Philippe Proulx Date: Wed, 1 Nov 2023 20:33:19 +0000 (-0400) Subject: cpp-common/bt2: add `bt2::MessageIterator` X-Git-Url: https://git.efficios.com/?a=commitdiff_plain;h=d9a27df87dad3d1d7727709b7515904b8860514b;p=babeltrace.git cpp-common/bt2: add `bt2::MessageIterator` This patch adds `bt2::MessageIterator` to wrap `bt_message_iterator` objects. `bt2::MessageIterator` offers: component(): Borrows the parent component of the message iterator. next(): Returns the next batch of messages. This method returns an optional message array: set if there are messages (`BT_MESSAGE_ITERATOR_NEXT_STATUS_OK`), or not set on end of iteration (`BT_MESSAGE_ITERATOR_NEXT_STATUS_END`). Throws otherwise. Example: if (const auto msgs = myMsgIter.next()) { for (const auto msg : *msgs) { if (msg.isEvent()) { // ... } } } else { // This is the end, my only friend, the end } canSeekBeginning(): Wraps bt_message_iterator_can_seek_beginning(). seekBeginning(): Wraps bt_message_iterator_seek_beginning(). canSeekNsFromOrigin(): Wraps bt_message_iterator_can_seek_ns_from_origin(). seekNsFromOrigin(): Wraps bt_message_iterator_seek_ns_from_origin(). canSeekForward(): Wraps bt_message_iterator_can_seek_forward(). Signed-off-by: Philippe Proulx Change-Id: Ifd16546ad56b237d62491fd17dd6cb180ca3edba Reviewed-on: https://review.lttng.org/c/babeltrace/+/11194 Reviewed-by: Simon Marchi Tested-by: jenkins CI-Build: Simon Marchi --- diff --git a/src/Makefile.am b/src/Makefile.am index 1a01d427..b572c728 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,6 +27,7 @@ noinst_HEADERS = \ cpp-common/bt2/internal/utils.hpp \ cpp-common/bt2/logging.hpp \ cpp-common/bt2/message-array.hpp \ + cpp-common/bt2/message-iterator.hpp \ cpp-common/bt2/message.hpp \ cpp-common/bt2/shared-object.hpp \ cpp-common/bt2/raw-value-proxy.hpp \ diff --git a/src/cpp-common/bt2/exc.hpp b/src/cpp-common/bt2/exc.hpp index 3b16a22b..71997c3e 100644 --- a/src/cpp-common/bt2/exc.hpp +++ b/src/cpp-common/bt2/exc.hpp @@ -14,6 +14,7 @@ namespace bt2 { using Error = bt2_common::Error; using OverflowError = bt2_common::OverflowError; using MemoryError = bt2_common::MemoryError; +using TryAgain = bt2_common::TryAgain; } /* namespace bt2 */ diff --git a/src/cpp-common/bt2/message-iterator.hpp b/src/cpp-common/bt2/message-iterator.hpp new file mode 100644 index 00000000..9ba7ed96 --- /dev/null +++ b/src/cpp-common/bt2/message-iterator.hpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2023 Philippe Proulx + * + * SPDX-License-Identifier: MIT + */ + +#ifndef BABELTRACE_CPP_COMMON_BT2_MESSAGE_ITERATOR_HPP +#define BABELTRACE_CPP_COMMON_BT2_MESSAGE_ITERATOR_HPP + +#include + +#include "common/common.h" +#include "cpp-common/optional.hpp" + +#include "component-port.hpp" +#include "exc.hpp" +#include "message-array.hpp" +#include "shared-object.hpp" + +namespace bt2 { +namespace internal { + +struct MessageIteratorRefFuncs final +{ + static void get(const bt_message_iterator * const libObjPtr) noexcept + { + bt_message_iterator_get_ref(libObjPtr); + } + + static void put(const bt_message_iterator * const libObjPtr) noexcept + { + bt_message_iterator_put_ref(libObjPtr); + } +}; + +} /* namespace internal */ + +class MessageIterator final : public BorrowedObject +{ +public: + using Shared = + SharedObject; + + explicit MessageIterator(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr} + { + } + + ConstComponent component() const noexcept + { + return ConstComponent {bt_message_iterator_borrow_component(this->libObjPtr())}; + } + + nonstd::optional next() const + { + bt_message_array_const libMsgsPtr; + std::uint64_t count; + const auto status = bt_message_iterator_next(this->libObjPtr(), &libMsgsPtr, &count); + + switch (status) { + case BT_MESSAGE_ITERATOR_NEXT_STATUS_OK: + /* Caller becomes the owner of the contained messages */ + return ConstMessageArray::wrapExisting(libMsgsPtr, count); + case BT_MESSAGE_ITERATOR_NEXT_STATUS_END: + return nonstd::nullopt; + case BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN: + throw TryAgain {}; + case BT_MESSAGE_ITERATOR_NEXT_STATUS_MEMORY_ERROR: + throw MemoryError {}; + case BT_MESSAGE_ITERATOR_NEXT_STATUS_ERROR: + throw Error {}; + default: + bt_common_abort(); + } + } + + bool canSeekBeginning() const + { + bt_bool canSeek; + + const auto status = bt_message_iterator_can_seek_beginning(this->libObjPtr(), &canSeek); + + switch (status) { + case BT_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_STATUS_OK: + return static_cast(canSeek); + case BT_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_STATUS_AGAIN: + throw TryAgain {}; + case BT_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_STATUS_MEMORY_ERROR: + throw MemoryError {}; + case BT_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_STATUS_ERROR: + throw Error {}; + default: + bt_common_abort(); + } + } + + void seekBeginning() const + { + const auto status = bt_message_iterator_seek_beginning(this->libObjPtr()); + + switch (status) { + case BT_MESSAGE_ITERATOR_SEEK_BEGINNING_STATUS_OK: + return; + case BT_MESSAGE_ITERATOR_SEEK_BEGINNING_STATUS_AGAIN: + throw TryAgain {}; + case BT_MESSAGE_ITERATOR_SEEK_BEGINNING_STATUS_MEMORY_ERROR: + throw MemoryError {}; + case BT_MESSAGE_ITERATOR_SEEK_BEGINNING_STATUS_ERROR: + throw Error {}; + default: + bt_common_abort(); + } + } + + bool canSeekNsFromOrigin(const std::int64_t nsFromOrigin) const + { + bt_bool canSeek; + + const auto status = + bt_message_iterator_can_seek_ns_from_origin(this->libObjPtr(), nsFromOrigin, &canSeek); + + switch (status) { + case BT_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_STATUS_OK: + return static_cast(canSeek); + case BT_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_STATUS_AGAIN: + throw TryAgain {}; + case BT_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_STATUS_MEMORY_ERROR: + throw MemoryError {}; + case BT_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_STATUS_ERROR: + throw Error {}; + default: + bt_common_abort(); + } + } + + void seekNsFromOrigin(const std::int64_t nsFromOrigin) const + { + const auto status = + bt_message_iterator_seek_ns_from_origin(this->libObjPtr(), nsFromOrigin); + + switch (status) { + case BT_MESSAGE_ITERATOR_SEEK_NS_FROM_ORIGIN_STATUS_OK: + return; + case BT_MESSAGE_ITERATOR_SEEK_NS_FROM_ORIGIN_STATUS_AGAIN: + throw TryAgain {}; + case BT_MESSAGE_ITERATOR_SEEK_NS_FROM_ORIGIN_STATUS_MEMORY_ERROR: + throw MemoryError {}; + case BT_MESSAGE_ITERATOR_SEEK_NS_FROM_ORIGIN_STATUS_ERROR: + throw Error {}; + default: + bt_common_abort(); + } + } + + bool canSeekForward() const noexcept + { + return static_cast(bt_message_iterator_can_seek_forward(this->libObjPtr())); + } + + Shared shared() const noexcept + { + return Shared::createWithRef(*this); + } +}; + +} /* namespace bt2 */ + +#endif /* BABELTRACE_CPP_COMMON_BT2_MESSAGE_ITERATOR_HPP */