3 * SPDX-License-Identifier: MIT
5 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
6 * Copyright 2017-2023 Philippe Proulx <pproulx@efficios.com>
9 #ifndef BABELTRACE_PLUGINS_UTILS_MUXER_UPSTREAM_MSG_ITER_HPP
10 #define BABELTRACE_PLUGINS_UTILS_MUXER_UPSTREAM_MSG_ITER_HPP
14 #include "common/assert.h"
15 #include "cpp-common/bt2/message-array.hpp"
16 #include "cpp-common/bt2/message-iterator.hpp"
17 #include "cpp-common/bt2c/logging.hpp"
18 #include "cpp-common/bt2s/optional.hpp"
23 * An instance of this wraps an upstream libbabeltrace2 message
24 * iterator, keeping an internal array of receives messages, and making
25 * the oldest one available (msg() method).
27 class UpstreamMsgIter final
30 /* Unique pointer to upstream message iterator */
31 using UP = std::unique_ptr<UpstreamMsgIter>;
33 /* Return type of reload() */
34 enum class ReloadStatus
41 * Builds an upstream message iterator wrapper using the
42 * libbabeltrace2 message iterator `msgIter`.
44 * This constructor doesn't immediately gets the next messages from
45 * `*msgIter` (you always need to call reload() before you call
46 * msg()), therefore it won't throw `bt2::Error` or `bt2::TryAgain`.
48 explicit UpstreamMsgIter(bt2::MessageIterator::Shared msgIter, std::string portName,
49 const bt2c::Logger& parentLogger);
52 UpstreamMsgIter(const UpstreamMsgIter&) = delete;
53 UpstreamMsgIter& operator=(const UpstreamMsgIter&) = delete;
58 * Before you call this method:
60 * 1. If needed, you must call discard().
62 * This is not the case immediately after construction and
63 * immediately after seeking.
65 * 2. You must call reload() successfully (not ended).
67 * This is always the case.
69 * This makes it possible to build an `UpstreamMsgIter` instance
70 * without libbabeltrace2 message iterator exceptions.
72 bt2::ConstMessage msg() const noexcept
74 BT_ASSERT_DBG(_mMsgs.msgs && _mMsgs.index < _mMsgs.msgs->length());
75 return (*_mMsgs.msgs)[_mMsgs.index];
79 * Timestamp, if any, of the current message.
81 * It must be valid to call msg() when you call this method.
83 const bt2s::optional<std::int64_t> msgTs() const noexcept
89 * Discards the current message, making this upstream message
90 * iterator ready for a reload (reload()).
92 * You may only call reload() or seekBeginning() after having called
95 void discard() noexcept
97 BT_ASSERT_DBG(_mMsgs.msgs && _mMsgs.index < _mMsgs.msgs->length());
98 BT_ASSERT_DBG(_mDiscardRequired);
99 _mDiscardRequired = false;
102 if (_mMsgs.index == _mMsgs.msgs->length()) {
108 * Retrieves the next message, making it available afterwards
109 * through the msg() method.
111 * You must have called discard() to discard the current message, if
112 * any, before you call this method.
114 * This method may throw anything bt2::MessageIterator::next() may
117 * If this method returns `ReloadStatus::NO_MORE`, then the
118 * underlying libbabeltrace2 message iterator is ended, meaning you
119 * may not call msg(), msgTs(), or reload() again for this message
120 * iterator until you successfully call seekBeginning().
122 ReloadStatus reload();
125 * Forwards to bt2::MessageIterator::canSeekBeginning().
127 bool canSeekBeginning();
130 * Forwards to bt2::MessageIterator::seekBeginning().
132 * On success, you may call reload() afterwards. With any exception,
133 * you must call this method again, successfully, before you may
136 void seekBeginning();
139 * Forwards to bt2::MessageIterator::canSeekForward().
141 bool canSeekForward() const noexcept;
144 * Name of the input port on which the libbabeltrace2 message
145 * iterator was created.
147 const std::string& portName() const noexcept
154 * Tries to get new messages into `_mMsgs.msgs`.
156 void _tryGetNewMsgs();
158 /* Actual upstream message iterator */
159 bt2::MessageIterator::Shared _mMsgIter;
162 * Currently contained messages.
164 * `index` is the index of the current message (msg()/msgTs())
169 bt2s::optional<bt2::ConstMessageArray> msgs;
173 /* Timestamp of the current message, if any */
174 bt2s::optional<std::int64_t> _mMsgTs;
177 * Only relevant in debug mode: true if a call to discard() is
178 * required before calling reload().
180 bool _mDiscardRequired = false;
182 bt2c::Logger _mLogger;
183 std::string _mPortName;
186 } /* namespace bt2mux */
188 #endif /* BABELTRACE_PLUGINS_UTILS_MUXER_UPSTREAM_MSG_ITER_HPP */