This commit is contained in:
Martin Slachta
2026-07-18 14:31:15 +02:00
commit a04f0dc262
3343 changed files with 1140208 additions and 0 deletions
@@ -0,0 +1,65 @@
#pragma once
#include "Read.hpp"
#include <spdlog/spdlog.h>
#include <vector>
namespace tw::net {
template<typename T>
class BufferReader : public Read<T> {
Read<T>* m_readable;
std::vector<T> m_buffer;
size_t m_head;
size_t m_tail;
size_t remaining_size() {
return m_head - m_tail;
}
public:
BufferReader(Read<T>* readable, size_t buffer_size) :
m_readable(readable),
m_buffer(buffer_size),
m_head(0),
m_tail(0) {
}
size_t read(std::span<T> 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<T>(m_buffer.begin(), m_buffer.end()));
m_tail = 0;
}
if(target.size() > read_size && m_head > 0) {
read_size += read(std::span<T>(target.begin() + read_size, target.end()));
}
return read_size;
}
std::optional<T> peek() {
if(remaining_size() > 0) {
return m_buffer[m_tail];
}
return std::nullopt;
}
};
}
@@ -0,0 +1,55 @@
#pragma once
#include <cstdint>
#include <cstddef>
#include <vector>
#include "Write.hpp"
namespace tw::net {
template<typename T>
class BufferWriter : public Write<T> {
private:
Write<T>* m_writeable;
std::vector<T> m_buffer;
uint32_t m_head;
public:
size_t remaining_size() {
return m_buffer.size() - m_head;
}
BufferWriter(Write<T>* writeable, size_t buffer_size) :
m_writeable(writeable),
m_buffer(buffer_size),
m_head(0)
{ }
virtual size_t write(std::span<T> data) override {
if(remaining_size() < data.size()) {
size_t write_size = flush();
write_size += m_writeable->write_into(data);
m_head = 0;
return write_size;
}
std::copy(data.begin(), data.end(), m_buffer.begin() + m_head);
size_t write_size = data.size();
m_head += data.size();
return write_size;
}
virtual size_t flush() override {
m_writeable->write_into(std::span<T>(m_buffer.begin(), m_buffer.begin() + m_head));
size_t write_size = m_head;
m_head = 0;
return write_size;
}
};
}
+45
View File
@@ -0,0 +1,45 @@
#pragma once
#include "NetworkError.hpp"
#include "tl/expected.hpp"
#include <span>
namespace tw::net {
template<typename T>
class Read {
public:
virtual ~Read() = default;
virtual tl::expected<size_t, NetworkError> read_into(std::span<T> target) = 0;
tl::expected<size_t, NetworkError> read_exact_into(std::span<std::byte> data) {
size_t total_read = 0;
while (total_read < data.size()) {
auto read = this->read_into(data.subspan(total_read));
if(!read.has_value()) {
if(read.error().m_type == NetworkErrorType::WOULD_BLOCK) {
continue;
} else {
return read;
}
}
total_read += read.value();
}
return total_read;
}
tl::expected<std::vector<std::byte>, NetworkError> read_exact(size_t size) {
std::vector<std::byte> buffer(size);
auto result = this->read_exact_into(std::span{buffer});
if(result.has_value()) {
return buffer;
}
return tl::make_unexpected(result.error());
}
};
}
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include "NetworkError.hpp"
#include <tl/expected.hpp>
#include <limits>
#include <span>
#include <string>
#include <type_traits>
namespace tw::net {
template<typename T>
class Write {
public:
virtual ~Write() = default;
virtual tl::expected<size_t, NetworkError> write(std::span<T> data) = 0;
tl::expected<size_t, NetworkError> write(const std::string& data) {
return write(std::span<std::byte>((std::byte*)(data.c_str()), data.size()));
}
template<typename TNum,
typename std::enable_if_t<std::is_integral<TNum>::value || std::is_enum<TNum>::value, bool> = true>
tl::expected<size_t, NetworkError> write(TNum data) {
return write(std::as_writable_bytes(std::span{&data, 1}));
}
virtual size_t flush() = 0;
};
}