.gitignore: add some more IDE / tools related file
[babeltrace.git] / src / plugins / utils / muxer / upstream-msg-iter.hpp
CommitLineData
fca1d0f5
PP
1/*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 * Copyright 2017-2023 Philippe Proulx <pproulx@efficios.com>
6 */
7
8#ifndef BABELTRACE_PLUGINS_UTILS_MUXER_UPSTREAM_MSG_ITER_HPP
9#define BABELTRACE_PLUGINS_UTILS_MUXER_UPSTREAM_MSG_ITER_HPP
10
11#include <memory>
12
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"
18
19namespace bt2mux {
20
21/*
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).
25 */
26class UpstreamMsgIter final
27{
28public:
29 /* Unique pointer to upstream message iterator */
30 using UP = std::unique_ptr<UpstreamMsgIter>;
31
32 /* Return type of reload() */
33 enum class ReloadStatus
34 {
1c5ea5eb
SM
35 More,
36 NoMore,
fca1d0f5
PP
37 };
38
39 /*
40 * Builds an upstream message iterator wrapper using the
41 * libbabeltrace2 message iterator `msgIter`.
42 *
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`.
46 */
47 explicit UpstreamMsgIter(bt2::MessageIterator::Shared msgIter, std::string portName,
48 const bt2c::Logger& parentLogger);
49
50 /* Some protection */
51 UpstreamMsgIter(const UpstreamMsgIter&) = delete;
52 UpstreamMsgIter& operator=(const UpstreamMsgIter&) = delete;
53
54 /*
55 * Current message.
56 *
57 * Before you call this method:
58 *
59 * 1. If needed, you must call discard().
60 *
61 * This is not the case immediately after construction and
62 * immediately after seeking.
63 *
64 * 2. You must call reload() successfully (not ended).
65 *
66 * This is always the case.
67 *
68 * This makes it possible to build an `UpstreamMsgIter` instance
69 * without libbabeltrace2 message iterator exceptions.
70 */
71 bt2::ConstMessage msg() const noexcept
72 {
73 BT_ASSERT_DBG(_mMsgs.msgs && _mMsgs.index < _mMsgs.msgs->length());
74 return (*_mMsgs.msgs)[_mMsgs.index];
75 }
76
77 /*
78 * Timestamp, if any, of the current message.
79 *
80 * It must be valid to call msg() when you call this method.
81 */
82 const bt2s::optional<std::int64_t> msgTs() const noexcept
83 {
84 return _mMsgTs;
85 }
86
87 /*
88 * Discards the current message, making this upstream message
89 * iterator ready for a reload (reload()).
90 *
91 * You may only call reload() or seekBeginning() after having called
92 * this.
93 */
94 void discard() noexcept
95 {
96 BT_ASSERT_DBG(_mMsgs.msgs && _mMsgs.index < _mMsgs.msgs->length());
97 BT_ASSERT_DBG(_mDiscardRequired);
98 _mDiscardRequired = false;
99 ++_mMsgs.index;
100
101 if (_mMsgs.index == _mMsgs.msgs->length()) {
102 _mMsgs.msgs.reset();
103 }
104 }
105
106 /*
107 * Retrieves the next message, making it available afterwards
108 * through the msg() method.
109 *
110 * You must have called discard() to discard the current message, if
111 * any, before you call this method.
112 *
113 * This method may throw anything bt2::MessageIterator::next() may
114 * throw.
115 *
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().
120 */
121 ReloadStatus reload();
122
123 /*
124 * Forwards to bt2::MessageIterator::canSeekBeginning().
125 */
126 bool canSeekBeginning();
127
128 /*
129 * Forwards to bt2::MessageIterator::seekBeginning().
130 *
131 * On success, you may call reload() afterwards. With any exception,
132 * you must call this method again, successfully, before you may
133 * call reload().
134 */
135 void seekBeginning();
136
137 /*
138 * Forwards to bt2::MessageIterator::canSeekForward().
139 */
140 bool canSeekForward() const noexcept;
141
142 /*
143 * Name of the input port on which the libbabeltrace2 message
144 * iterator was created.
145 */
146 const std::string& portName() const noexcept
147 {
148 return _mPortName;
149 }
150
151private:
152 /*
153 * Tries to get new messages into `_mMsgs.msgs`.
154 */
155 void _tryGetNewMsgs();
156
157 /* Actual upstream message iterator */
158 bt2::MessageIterator::Shared _mMsgIter;
159
160 /*
161 * Currently contained messages.
162 *
163 * `index` is the index of the current message (msg()/msgTs())
164 * within `msgs`.
165 */
166 struct
167 {
168 bt2s::optional<bt2::ConstMessageArray> msgs;
169 std::size_t index;
170 } _mMsgs;
171
172 /* Timestamp of the current message, if any */
173 bt2s::optional<std::int64_t> _mMsgTs;
174
175 /*
176 * Only relevant in debug mode: true if a call to discard() is
177 * required before calling reload().
178 */
179 bool _mDiscardRequired = false;
180
181 bt2c::Logger _mLogger;
182 std::string _mPortName;
183};
184
185} /* namespace bt2mux */
186
187#endif /* BABELTRACE_PLUGINS_UTILS_MUXER_UPSTREAM_MSG_ITER_HPP */
This page took 0.037231 seconds and 4 git commands to generate.