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_SLICER_H_
#define BOTAN_BUFFER_SLICER_H_
#include <botan/assert.h>
#include <botan/concepts.h>
#include <botan/secmem.h>
#include <botan/strong_type.h>
#include <botan/types.h>
#include <span>
#include <vector>
namespace Botan {
/**
* Helper class to ease unmarshalling of concatenated fixed-length values
*/
class BufferSlicer final {
public:
explicit BufferSlicer(std::span<const uint8_t> buffer) : m_remaining(buffer) {}
template <concepts::contiguous_container ContainerT>
auto copy(const size_t count) {
const auto result = take(count);
return ContainerT(result.begin(), result.end());
}
auto copy_as_vector(const size_t count) { return copy<std::vector<uint8_t>>(count); }
auto copy_as_secure_vector(const size_t count) { return copy<secure_vector<uint8_t>>(count); }
std::span<const uint8_t> take(const size_t count) {
BOTAN_STATE_CHECK(remaining() >= count);
auto result = m_remaining.first(count);
m_remaining = m_remaining.subspan(count);
return result;
}
template <size_t count>
std::span<const uint8_t, count> take() {
BOTAN_STATE_CHECK(remaining() >= count);
auto result = m_remaining.first<count>();
m_remaining = m_remaining.subspan(count);
return result;
}
template <concepts::contiguous_strong_type T>
StrongSpan<const T> take(const size_t count) {
return StrongSpan<const T>(take(count));
}
uint8_t take_byte() { return take(1)[0]; }
void copy_into(std::span<uint8_t> sink) {
const auto data = take(sink.size());
std::copy(data.begin(), data.end(), sink.begin());
}
void skip(const size_t count) { take(count); }
size_t remaining() const { return m_remaining.size(); }
bool empty() const { return m_remaining.empty(); }
private:
std::span<const uint8_t> m_remaining;
};
} // namespace Botan
#endif