Overflow detection, span-based signatures, flatten control flow
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
#include <span>
|
||||
#include "wire.h"
|
||||
|
||||
using handler_fn = size_t (*)(uint32_t message_id, std::span<const uint8_t> payload, span_writer &out);
|
||||
using handler_fn = msgpack::result<size_t> (*)(uint32_t message_id, std::span<const uint8_t> payload, span_writer &out);
|
||||
|
||||
struct handler_entry {
|
||||
int8_t type_id;
|
||||
@@ -12,7 +12,7 @@ struct handler_entry {
|
||||
};
|
||||
|
||||
template <typename Req, auto Fn>
|
||||
size_t typed_handler(uint32_t message_id, std::span<const uint8_t> payload, span_writer &out) {
|
||||
msgpack::result<size_t> typed_handler(uint32_t message_id, std::span<const uint8_t> payload, span_writer &out) {
|
||||
msgpack::parser p(payload.data(), static_cast<int>(payload.size()));
|
||||
Req req;
|
||||
auto tup = req.as_tuple();
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
#include <functional>
|
||||
#include <span>
|
||||
#include "span_writer.h"
|
||||
#include "msgpack.h"
|
||||
|
||||
struct net_state {
|
||||
std::array<uint8_t, 6> mac;
|
||||
std::array<uint8_t, 4> ip;
|
||||
};
|
||||
|
||||
using net_handler = std::function<size_t(std::span<const uint8_t> payload, span_writer &out)>;
|
||||
using net_handler = std::function<msgpack::result<size_t>(std::span<const uint8_t> payload, span_writer &out)>;
|
||||
|
||||
bool net_init();
|
||||
const net_state& net_get_state();
|
||||
|
||||
@@ -8,6 +8,7 @@ class span_writer {
|
||||
uint8_t *m_data;
|
||||
size_t m_capacity;
|
||||
size_t m_size = 0;
|
||||
bool m_overflow = false;
|
||||
|
||||
public:
|
||||
span_writer(uint8_t *data, size_t capacity) : m_data(data), m_capacity(capacity) {}
|
||||
@@ -15,17 +16,21 @@ public:
|
||||
|
||||
void push_back(uint8_t v) {
|
||||
if (m_size < m_capacity) m_data[m_size++] = v;
|
||||
else m_overflow = true;
|
||||
}
|
||||
|
||||
template <class It>
|
||||
void insert(uint8_t *, It first, It last) {
|
||||
while (first != last && m_size < m_capacity)
|
||||
m_data[m_size++] = *first++;
|
||||
while (first != last) {
|
||||
if (m_size < m_capacity) m_data[m_size++] = *first++;
|
||||
else { m_overflow = true; return; }
|
||||
}
|
||||
}
|
||||
|
||||
size_t size() const { return m_size; }
|
||||
size_t capacity() const { return m_capacity; }
|
||||
bool full() const { return m_size >= m_capacity; }
|
||||
bool overflow() const { return m_overflow; }
|
||||
|
||||
uint8_t *data() { return m_data; }
|
||||
const uint8_t *data() const { return m_data; }
|
||||
|
||||
@@ -109,7 +109,7 @@ static constexpr size_t envelope_hdr_len =
|
||||
static constexpr size_t response_prefix_len = envelope_hdr_len + ext16_header_len;
|
||||
|
||||
template <typename T>
|
||||
inline size_t encode_response_into(span_writer &out, uint32_t message_id, const T &msg) {
|
||||
inline msgpack::result<size_t> encode_response_into(span_writer &out, uint32_t message_id, const T &msg) {
|
||||
auto body = out.subspan(response_prefix_len);
|
||||
msgpack::packer body_p(body);
|
||||
body_p.pack(msg.as_tuple());
|
||||
@@ -129,6 +129,8 @@ inline size_t encode_response_into(span_writer &out, uint32_t message_id, const
|
||||
hdr.pack_uint32_fixed(checksum);
|
||||
hdr.pack_bin16_header(static_cast<uint16_t>(bin_len));
|
||||
|
||||
if (body.overflow() || inner_ext.overflow() || env_hdr.overflow())
|
||||
return std::unexpected(msgpack::error_code::overflow);
|
||||
return response_prefix_len + body.size();
|
||||
}
|
||||
|
||||
@@ -176,6 +178,3 @@ inline msgpack::result<T> decode_response(const uint8_t *data, size_t len) {
|
||||
return out;
|
||||
}
|
||||
|
||||
inline size_t encode_request_into(span_writer &out, uint32_t message_id, const auto &msg) {
|
||||
return encode_response_into(out, message_id, msg);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user