30 Message(std::shared_ptr<std::vector<std::uint8_t>> buffer = std::make_shared<std::vector<std::uint8_t>>())
31 : _bytes(std::move(buffer))
33 if (_bytes ==
nullptr) {
34 throw std::invalid_argument(
"messages::Message buffer cannot be nullptr");
55 requires std::is_enum_v<T> || std::is_integral_v<T>
58 UintVar type_bytes(
static_cast<std::uint64_t
>(type));
59 _bytes->insert(_bytes->begin(), type_bytes.
begin(), type_bytes.
end());
61 if (_length_bytes_offset.has_value()) {
62 _length_bytes_offset = type_bytes.
size();
74 if (_length_bytes_offset.has_value()) {
78 if (_bytes->empty()) {
79 _length_bytes_offset = 0;
84 _bytes->insert(std::next(_bytes->begin(), _length_bytes_offset.value()), { 0, 0 });
96 _bytes->push_back(
byte);
107 _bytes->insert(_bytes->end(), bytes.begin(), bytes.end());
133 inline const std::shared_ptr<std::vector<uint8_t>>&
ToBytes() const noexcept
135 if (_length_bytes_offset.has_value()) {
136 const std::uint16_t payload_size =
SwapBytes(
137 static_cast<std::uint16_t
>(_bytes->size() - _length_bytes_offset.value() -
sizeof(std::uint16_t)));
138 std::memcpy(_bytes->data() + _length_bytes_offset.value(), &payload_size,
sizeof(std::uint16_t));
154 _length_bytes_offset = std::nullopt;
164 template<
typename Field>
165 [[nodiscard]]
static inline Field
ParseField(std::span<const std::uint8_t>& buffer)
168 buffer = buffer >> field;
172 template<
typename Field>
173 [[nodiscard]]
static inline std::optional<Field>
ParseOptionalField(std::span<const std::uint8_t>& buffer)
175 if (buffer.empty()) {
180 buffer = buffer >> field;
185 std::optional<std::size_t> _length_bytes_offset;
186 mutable std::shared_ptr<std::vector<std::uint8_t>> _bytes;
constexpr auto end() const noexcept
Definition: uintvar.h:166
constexpr std::size_t Size() const noexcept
Definition: uintvar.h:153
constexpr std::size_t size() const noexcept
Definition: uintvar.h:160
constexpr auto begin() const noexcept
Definition: uintvar.h:163
Generic message buffer formatting class.
Definition: message.h:23
void Clear() noexcept
Removes all bytes and any reserved-length state; shared storage remains owned.
Definition: message.h:151
requires std::is_enum_v< T > std::is_integral_v< T > Message & PrependType(T type)
Prepends a message type at the front of the byte buffer.
Definition: message.h:56
static std::optional< Field > ParseOptionalField(std::span< const std::uint8_t > &buffer)
Definition: message.h:173
Message & Append(std::uint8_t byte) noexcept
Definition: message.h:94
static Field ParseField(std::span< const std::uint8_t > &buffer)
Definition: message.h:165
const std::shared_ptr< std::vector< uint8_t > > & ToBytes() const noexcept
Definition: message.h:133
Message & ReserveLength()
Inserts a std::uint16_t near the front of the byte buffer for the payload length.
Definition: message.h:72
Message(std::shared_ptr< std::vector< std::uint8_t >> buffer=std::make_shared< std::vector< std::uint8_t >>())
Definition: message.h:30
requires requires(std::vector< std::uint8_t > &buffer, const T &value)
Definition: message.h:118
Message & Append(const T &value) noexcept(noexcept(*_bytes<< value))
Definition: message.h:119
Message & Append(std::span< const std::uint8_t > bytes) noexcept
Definition: message.h:105
constexpr bool HasPrependedLength() const noexcept
Checks if the message was built with the payload length written near the front.
Definition: message.h:42
std::span< const std::uint8_t > ToByteSpan() const noexcept
Definition: message.h:148
Definition: ctrl_message_types.h:38
constexpr std::uint16_t SwapBytes(const std::uint16_t value)
Converts a 16-bit value between native and big-endian byte order.
Definition: bytes.h:106