Crunch
A Message Definition Language for Getting Things Right
Loading...
Searching...
No Matches
crunch_header.hpp
1#pragma once
2
3#include <crunch/core/crunch_endian.hpp>
4#include <crunch/core/crunch_types.hpp>
5#include <cstring>
6#include <expected>
7#include <span>
8
9namespace Crunch {
10
20 CrunchVersionId version;
21 Format format;
22 MessageId message_id;
23};
24
31[[nodiscard]] constexpr std::expected<CrunchHeader, Error> GetHeader(
32 std::span<const std::byte> input) noexcept {
33 if (input.size() < StandardHeaderSize) {
34 return std::unexpected(
35 Error::deserialization("buffer too small for header"));
36 }
37
38 CrunchHeader header{};
39
40 std::memcpy(&header.version, input.data(), sizeof(CrunchVersionId));
41 std::memcpy(&header.format, input.data() + sizeof(CrunchVersionId),
42 sizeof(Format));
43
44 MessageId msg_id;
45 std::memcpy(&msg_id,
46 input.data() + sizeof(CrunchVersionId) + sizeof(Format),
47 sizeof(MessageId));
48 header.message_id = LittleEndian(msg_id);
49
50 return header;
51}
52
61template <typename Message, typename Serdes>
62[[nodiscard]] constexpr std::size_t WriteHeader(
63 std::span<std::byte> output) noexcept {
64 std::size_t offset = 0;
65
66 const CrunchVersionId version = CrunchVersion;
67 std::memcpy(output.data() + offset, &version, sizeof(version));
68 offset += sizeof(version);
69
70 const Format format = Serdes::GetFormat();
71 std::memcpy(output.data() + offset, &format, sizeof(format));
72 offset += sizeof(format);
73
74 const MessageId msg_id = Message::message_id;
75 const MessageId le_msg_id = LittleEndian(msg_id);
76 std::memcpy(output.data() + offset, &le_msg_id, sizeof(le_msg_id));
77 offset += sizeof(le_msg_id);
78
79 return offset;
80}
81
96template <typename Message, typename Serdes>
97[[nodiscard]] constexpr std::expected<std::size_t, Error> ValidateHeader(
98 std::span<const std::byte> input) noexcept {
99 auto header_result = GetHeader(input);
100 if (!header_result) {
101 return std::unexpected(header_result.error());
102 }
103
104 const CrunchHeader& header = *header_result;
105
106 if (header.version != CrunchVersion) {
107 return std::unexpected(
108 Error::deserialization("unsupported crunch version"));
109 }
110
111 if (header.format != Serdes::GetFormat()) {
112 return std::unexpected(Error::invalid_format());
113 }
114
115 if (header.message_id != Message::message_id) {
116 return std::unexpected(Error::invalid_message_id());
117 }
118
119 return StandardHeaderSize;
120}
121
122} // namespace Crunch
The public API for Crunch.
Definition: crunch_endian.hpp:10
uint8_t CrunchVersionId
Version identifier for the Crunch library.
Definition: crunch_types.hpp:40
constexpr std::size_t WriteHeader(std::span< std::byte > output) noexcept
Writes the standard header to the output buffer.
Definition: crunch_header.hpp:62
constexpr T LittleEndian(T value) noexcept
Converts a value to/from Little Endian byte order.
Definition: crunch_endian.hpp:21
int32_t MessageId
Unique identifier for a message type.
Definition: crunch_types.hpp:25
constexpr std::expected< CrunchHeader, Error > GetHeader(std::span< const std::byte > input) noexcept
Parses and returns a copy of the header from the input buffer.
Definition: crunch_header.hpp:31
Format
Serialization format identifier stored in the message header.
Definition: crunch_types.hpp:30
constexpr std::expected< std::size_t, Error > ValidateHeader(std::span< const std::byte > input) noexcept
Validates the header and returns offset after header on success.
Definition: crunch_header.hpp:97
Represents the standard Crunch message header.
Definition: crunch_header.hpp:19
static constexpr Error deserialization(std::string_view msg="deserialization error") noexcept
Creates an error representing a deserialization failure.
Definition: crunch_types.hpp:104
static constexpr Error invalid_message_id() noexcept
Creates an error representing an invalid message ID.
Definition: crunch_types.hpp:112
static constexpr Error invalid_format() noexcept
Creates an error representing an invalid serialization format.
Definition: crunch_types.hpp:119