9#ifndef BOTAN_ALIGNMENT_BUFFER_H_
10#define BOTAN_ALIGNMENT_BUFFER_H_
12#include <botan/concepts.h>
13#include <botan/mem_ops.h>
14#include <botan/internal/stl_util.h>
60 requires(BLOCK_SIZE > 0)
73 clear_mem(m_buffer.data(), m_buffer.size());
81 if(!ready_to_consume()) {
82 clear_mem(&m_buffer[m_position], elements_until_alignment());
83 m_position = m_buffer.size();
91 void append(std::span<const T> elements) {
93 std::copy(elements.begin(), elements.end(), m_buffer.begin() + m_position);
94 m_position += elements.size();
105 return std::span(m_buffer).first(elements);
116 return std::span(m_buffer).last(elements);
132 const size_t defer = (defers_final_block()) ? 1 : 0;
133 const size_t full_blocks_to_process = (slicer.
remaining() - defer) / m_buffer.size();
134 return {slicer.
take(full_blocks_to_process * m_buffer.size()), full_blocks_to_process};
149 const size_t defer = (defers_final_block()) ? 1 : 0;
150 if(slicer.
remaining() < m_buffer.size() + defer) {
154 return slicer.
take(m_buffer.size());
171 const size_t defer = (defers_final_block()) ? 1 : 0;
173 if(in_alignment() && slicer.
remaining() >= m_buffer.size() + defer) {
182 const auto elements_to_consume = std::min(m_buffer.size() - m_position, slicer.
remaining());
183 append(slicer.
take(elements_to_consume));
189 if(ready_to_consume() && (!defers_final_block() || !slicer.
empty())) {
213 const auto elements = elements_in_buffer();
215 return std::span(m_buffer).first(elements);
218 constexpr size_t size()
const {
return m_buffer.size(); }
239 std::array<T, BLOCK_SIZE> m_buffer;
#define BOTAN_ASSERT_NOMSG(expr)
AlignmentBuffer & operator=(AlignmentBuffer &&other) noexcept=default
constexpr size_t size() const
AlignmentBuffer(AlignmentBuffer &&other) noexcept=default
std::span< T > directly_modify_first(size_t elements)
constexpr bool defers_final_block() const
AlignmentBuffer & operator=(const AlignmentBuffer &other)=default
size_t elements_in_buffer() const
std::tuple< std::span< const uint8_t >, size_t > aligned_data_to_process(BufferSlicer &slicer) const
std::optional< std::span< const uint8_t > > next_aligned_block_to_process(BufferSlicer &slicer) const
bool ready_to_consume() const
AlignmentBuffer(const AlignmentBuffer &other)=default
void append(std::span< const T > elements)
size_t elements_until_alignment() const
std::optional< std::span< const T > > handle_unaligned_data(BufferSlicer &slicer)
std::span< T > directly_modify_last(size_t elements)
std::span< const T > consume()
void fill_up_with_zeros()
std::span< const T > consume_partial()
bool in_alignment() const
std::span< const uint8_t > take(const size_t count)
void secure_scrub_memory(void *ptr, size_t n)
AlignmentBufferFinalBlock
constexpr void clear_mem(T *ptr, size_t n)