Revision control

Copy as Markdown

Other Tools

/*
* (C) 2023-2024 René Meusel - Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_BUFFER_STUFFER_H_
#define BOTAN_BUFFER_STUFFER_H_
#include <botan/assert.h>
#include <botan/strong_type.h>
#include <botan/types.h>
#include <span>
namespace Botan {
/**
* @brief Helper class to ease in-place marshalling of concatenated fixed-length
* values.
*
* The size of the final buffer must be known from the start, reallocations are
* not performed.
*/
class BufferStuffer final {
public:
constexpr explicit BufferStuffer(std::span<uint8_t> buffer) : m_buffer(buffer) {}
/**
* @returns a span for the next @p bytes bytes in the concatenated buffer.
* Checks that the buffer is not exceeded.
*/
constexpr std::span<uint8_t> next(size_t bytes) {
BOTAN_STATE_CHECK(m_buffer.size() >= bytes);
auto result = m_buffer.first(bytes);
m_buffer = m_buffer.subspan(bytes);
return result;
}
template <size_t bytes>
constexpr std::span<uint8_t, bytes> next() {
BOTAN_STATE_CHECK(m_buffer.size() >= bytes);
auto result = m_buffer.first<bytes>();
m_buffer = m_buffer.subspan(bytes);
return result;
}
template <concepts::contiguous_strong_type StrongT>
StrongSpan<StrongT> next(size_t bytes) {
return StrongSpan<StrongT>(next(bytes));
}
/**
* @returns a reference to the next single byte in the buffer
*/
constexpr uint8_t& next_byte() { return next(1)[0]; }
constexpr void append(std::span<const uint8_t> buffer) {
auto sink = next(buffer.size());
std::copy(buffer.begin(), buffer.end(), sink.begin());
}
constexpr void append(uint8_t b, size_t repeat = 1) {
auto sink = next(repeat);
std::fill(sink.begin(), sink.end(), b);
}
constexpr bool full() const { return m_buffer.empty(); }
constexpr size_t remaining_capacity() const { return m_buffer.size(); }
private:
std::span<uint8_t> m_buffer;
};
} // namespace Botan
#endif