cpp-common/bt2: add `bt2::MessageIterator`
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 1 Nov 2023 20:33:19 +0000 (16:33 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Thu, 14 Dec 2023 15:57:04 +0000 (10:57 -0500)
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 <eeppeliteloop@gmail.com>
Change-Id: Ifd16546ad56b237d62491fd17dd6cb180ca3edba
Reviewed-on: https://review.lttng.org/c/babeltrace/+/11194
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
CI-Build: Simon Marchi <simon.marchi@efficios.com>

src/Makefile.am
src/cpp-common/bt2/exc.hpp
src/cpp-common/bt2/message-iterator.hpp [new file with mode: 0644]

index 1a01d4278b6a05d347249975cbb2f2f32a3b99e1..b572c728ffdc45c74dbf9b6db08398b00ddd51d4 100644 (file)
@@ -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 \
index 3b16a22b9082aa8fdec449cbdf208f2244d45b5e..71997c3eb85487e01239079333ed35e38b9c8b67 100644 (file)
@@ -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 (file)
index 0000000..9ba7ed9
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2023 Philippe Proulx <pproulx@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef BABELTRACE_CPP_COMMON_BT2_MESSAGE_ITERATOR_HPP
+#define BABELTRACE_CPP_COMMON_BT2_MESSAGE_ITERATOR_HPP
+
+#include <babeltrace2/babeltrace.h>
+
+#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<bt_message_iterator>
+{
+public:
+    using Shared =
+        SharedObject<MessageIterator, bt_message_iterator, internal::MessageIteratorRefFuncs>;
+
+    explicit MessageIterator(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
+    {
+    }
+
+    ConstComponent component() const noexcept
+    {
+        return ConstComponent {bt_message_iterator_borrow_component(this->libObjPtr())};
+    }
+
+    nonstd::optional<ConstMessageArray> 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<bool>(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<bool>(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<bool>(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 */
This page took 0.028517 seconds and 4 git commands to generate.