2 * SPDX-License-Identifier: MIT
4 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 * Copyright 2017-2023 Philippe Proulx <pproulx@efficios.com>
8 #ifndef BABELTRACE_PLUGINS_UTILS_MUXER_UPSTREAM_MSG_ITER_HPP
9 #define BABELTRACE_PLUGINS_UTILS_MUXER_UPSTREAM_MSG_ITER_HPP
13 #include "common/assert.h"
14 #include "cpp-common/bt2/message-array.hpp"
15 #include "cpp-common/bt2/message-iterator.hpp"
16 #include "cpp-common/bt2c/logging.hpp"
17 #include "cpp-common/bt2s/optional.hpp"
22 * An instance of this wraps an upstream libbabeltrace2 message
23 * iterator, keeping an internal array of receives messages, and making
24 * the oldest one available (msg() method).
26 class UpstreamMsgIter final
29 /* Unique pointer to upstream message iterator */
30 using UP = std::unique_ptr<UpstreamMsgIter>;
32 /* Return type of reload() */
33 enum class ReloadStatus
40 * Builds an upstream message iterator wrapper using the
41 * libbabeltrace2 message iterator `msgIter`.
43 * This constructor doesn't immediately gets the next messages from
44 * `*msgIter` (you always need to call reload() before you call
45 * msg()), therefore it won't throw `bt2::Error` or `bt2::TryAgain`.
47 explicit UpstreamMsgIter(bt2::MessageIterator::Shared msgIter, std::string portName,
48 const bt2c::Logger& parentLogger);
51 UpstreamMsgIter(const UpstreamMsgIter&) = delete;
52 UpstreamMsgIter& operator=(const UpstreamMsgIter&) = delete;
57 * Before you call this method:
59 * 1. If needed, you must call discard().
61 * This is not the case immediately after construction and
62 * immediately after seeking.
64 * 2. You must call reload() successfully (not ended).
66 * This is always the case.
68 * This makes it possible to build an `UpstreamMsgIter` instance
69 * without libbabeltrace2 message iterator exceptions.
71 bt2::ConstMessage msg() const noexcept
73 BT_ASSERT_DBG(_mMsgs.msgs && _mMsgs.index < _mMsgs.msgs->length());
74 return (*_mMsgs.msgs)[_mMsgs.index];
78 * Timestamp, if any, of the current message.
80 * It must be valid to call msg() when you call this method.
82 const bt2s::optional<std::int64_t> msgTs() const noexcept
88 * Discards the current message, making this upstream message
89 * iterator ready for a reload (reload()).
91 * You may only call reload() or seekBeginning() after having called
94 void discard() noexcept
96 BT_ASSERT_DBG(_mMsgs.msgs && _mMsgs.index < _mMsgs.msgs->length());
97 BT_ASSERT_DBG(_mDiscardRequired);
98 _mDiscardRequired = false;
101 if (_mMsgs.index == _mMsgs.msgs->length()) {
107 * Retrieves the next message, making it available afterwards
108 * through the msg() method.
110 * You must have called discard() to discard the current message, if
111 * any, before you call this method.
113 * This method may throw anything bt2::MessageIterator::next() may
116 * If this method returns `ReloadStatus::NO_MORE`, then the
117 * underlying libbabeltrace2 message iterator is ended, meaning you
118 * may not call msg(), msgTs(), or reload() again for this message
119 * iterator until you successfully call seekBeginning().
121 ReloadStatus reload();
124 * Forwards to bt2::MessageIterator::canSeekBeginning().
126 bool canSeekBeginning();
129 * Forwards to bt2::MessageIterator::seekBeginning().
131 * On success, you may call reload() afterwards. With any exception,
132 * you must call this method again, successfully, before you may
135 void seekBeginning();
138 * Forwards to bt2::MessageIterator::canSeekForward().
140 bool canSeekForward() const noexcept;
143 * Name of the input port on which the libbabeltrace2 message
144 * iterator was created.
146 const std::string& portName() const noexcept
153 * Tries to get new messages into `_mMsgs.msgs`.
155 void _tryGetNewMsgs();
157 /* Actual upstream message iterator */
158 bt2::MessageIterator::Shared _mMsgIter;
161 * Currently contained messages.
163 * `index` is the index of the current message (msg()/msgTs())
168 bt2s::optional<bt2::ConstMessageArray> msgs;
172 /* Timestamp of the current message, if any */
173 bt2s::optional<std::int64_t> _mMsgTs;
176 * Only relevant in debug mode: true if a call to discard() is
177 * required before calling reload().
179 bool _mDiscardRequired = false;
181 bt2c::Logger _mLogger;
182 std::string _mPortName;
185 } /* namespace bt2mux */
187 #endif /* BABELTRACE_PLUGINS_UTILS_MUXER_UPSTREAM_MSG_ITER_HPP */