#pragma once #include "Read.hpp" #include #include namespace tw::net { template class BufferReader : public Read { Read* m_readable; std::vector m_buffer; size_t m_head; size_t m_tail; size_t remaining_size() { return m_head - m_tail; } public: BufferReader(Read* readable, size_t buffer_size) : m_readable(readable), m_buffer(buffer_size), m_head(0), m_tail(0) { } size_t read(std::span target) override { size_t read_size = std::min(remaining_size(), target.size()); std::copy(m_buffer.begin() + m_tail, m_buffer.begin() + m_tail + read_size, target.begin()); spdlog::info("Read {} bytes", read_size); m_tail += read_size; // read next chunk if(m_tail == m_head && read_size < target.size()) { spdlog::info("Reading next chunk"); m_head = m_readable->read(std::span(m_buffer.begin(), m_buffer.end())); m_tail = 0; } if(target.size() > read_size && m_head > 0) { read_size += read(std::span(target.begin() + read_size, target.end())); } return read_size; } std::optional peek() { if(remaining_size() > 0) { return m_buffer[m_tail]; } return std::nullopt; } }; }