BCNP 3.2.1
Batched Command Network Protocol
Loading...
Searching...
No Matches
message_types.h
Go to the documentation of this file.
1// AUTO-GENERATED by bcnp_codegen.py - DO NOT EDIT
2// Schema version: 3.2
3// Schema hash: 0x5667F881
4#pragma once
5
6#include <array>
7#include <cstddef>
8#include <cstdint>
9#include <cmath>
10#include <cstring>
11#include <functional>
12#include <limits>
13#include <optional>
14#include <variant>
15
16namespace bcnp {
17
18// ============================================================================
19// Protocol Constants
20// ============================================================================
21
22constexpr uint8_t kProtocolMajorV3 = 3;
23constexpr uint8_t kProtocolMinorV3 = 2;
24constexpr uint32_t kSchemaHash = 0x5667F881U;
25
26// Handshake packet structure: "BCNP" (4 bytes) + schema hash (4 bytes)
27constexpr std::size_t kHandshakeSize = 8;
28constexpr std::array<uint8_t, 4> kHandshakeMagic = {{'B', 'C', 'N', 'P'}};
29
30// V3 Header: Major(1) + Minor(1) + Flags(1) + MsgTypeId(2) + MsgCount(2) = 7 bytes
31constexpr std::size_t kHeaderSizeV3 = 7;
32constexpr std::size_t kHeaderMsgTypeIndex = 3;
33constexpr std::size_t kHeaderMsgCountIndex = 5;
34
35// ============================================================================
36// Message Type IDs
37// ============================================================================
38
39enum class MessageTypeId : uint16_t {
40 Unknown = 0,
41};
42
43// Message sizes (wire format, bytes)
44
45// ============================================================================
46// Byte Order Utilities (Big-Endian Wire Format)
47// ============================================================================
48
49namespace detail {
50
51inline uint16_t LoadU16(const uint8_t* p) {
52 return (uint16_t(p[0]) << 8) | uint16_t(p[1]);
53}
54
55inline uint32_t LoadU32(const uint8_t* p) {
56 return (uint32_t(p[0]) << 24) | (uint32_t(p[1]) << 16) |
57 (uint32_t(p[2]) << 8) | uint32_t(p[3]);
58}
59
60inline int16_t LoadS16(const uint8_t* p) {
61 return static_cast<int16_t>(LoadU16(p));
62}
63
64inline int32_t LoadS32(const uint8_t* p) {
65 return static_cast<int32_t>(LoadU32(p));
66}
67
68inline void StoreU16(uint16_t v, uint8_t* p) {
69 p[0] = static_cast<uint8_t>((v >> 8) & 0xFF);
70 p[1] = static_cast<uint8_t>(v & 0xFF);
71}
72
73inline void StoreU32(uint32_t v, uint8_t* p) {
74 p[0] = static_cast<uint8_t>((v >> 24) & 0xFF);
75 p[1] = static_cast<uint8_t>((v >> 16) & 0xFF);
76 p[2] = static_cast<uint8_t>((v >> 8) & 0xFF);
77 p[3] = static_cast<uint8_t>(v & 0xFF);
78}
79
80inline void StoreS16(int16_t v, uint8_t* p) {
81 StoreU16(static_cast<uint16_t>(v), p);
82}
83
84inline void StoreS32(int32_t v, uint8_t* p) {
85 StoreU32(static_cast<uint32_t>(v), p);
86}
87
88inline int32_t QuantizeFloat(float value, float scale) {
89 const double scaled = static_cast<double>(value) * static_cast<double>(scale);
90 const double clamped = std::clamp(scaled,
91 static_cast<double>(std::numeric_limits<int32_t>::min()),
92 static_cast<double>(std::numeric_limits<int32_t>::max()));
93 return static_cast<int32_t>(std::llround(clamped));
94}
95
96inline float DequantizeFloat(int32_t fixed, float scale) {
97 return static_cast<float>(static_cast<double>(fixed) / static_cast<double>(scale));
98}
99
100} // namespace detail
101
102// ============================================================================
103// Message Structs
104// ============================================================================
105
106// ============================================================================
107// Message Registry
108// ============================================================================
109
112 std::size_t wireSize;
113 const char* name;
114};
115
116// No messages defined - add message types to your schema and regenerate
117inline constexpr std::array<MessageInfo, 0> kMessageRegistry = {{}};
118
119inline std::optional<MessageInfo> GetMessageInfo(MessageTypeId typeId) {
120 for (const auto& info : kMessageRegistry) {
121 if (info.typeId == typeId) return info;
122 }
123 return std::nullopt;
124}
125
126inline std::optional<MessageInfo> GetMessageInfo(uint16_t typeId) {
127 return GetMessageInfo(static_cast<MessageTypeId>(typeId));
128}
129
130// ============================================================================
131// Handshake Utilities
132// ============================================================================
133
135inline bool EncodeHandshake(uint8_t* out, std::size_t capacity) {
136 if (capacity < kHandshakeSize) return false;
137 std::memcpy(out, kHandshakeMagic.data(), 4);
139 return true;
140}
141
143inline bool EncodeHandshakeWithHash(uint8_t* out, std::size_t capacity, uint32_t schemaHash) {
144 if (capacity < kHandshakeSize) return false;
145 std::memcpy(out, kHandshakeMagic.data(), 4);
146 detail::StoreU32(schemaHash, &out[4]);
147 return true;
148}
149
150inline bool ValidateHandshake(const uint8_t* data, std::size_t length) {
151 if (length < kHandshakeSize) return false;
152 if (std::memcmp(data, kHandshakeMagic.data(), 4) != 0) return false;
153 const uint32_t remoteHash = detail::LoadU32(&data[4]);
154 return remoteHash == kSchemaHash;
155}
156
158inline bool ValidateHandshakeWithHash(const uint8_t* data, std::size_t length, uint32_t expectedHash) {
159 if (length < kHandshakeSize) return false;
160 if (std::memcmp(data, kHandshakeMagic.data(), 4) != 0) return false;
161 const uint32_t remoteHash = detail::LoadU32(&data[4]);
162 return remoteHash == expectedHash;
163}
164
165inline uint32_t ExtractSchemaHash(const uint8_t* data, std::size_t length) {
166 if (length < kHandshakeSize) return 0;
167 return detail::LoadU32(&data[4]);
168}
169
170} // namespace bcnp
int16_t LoadS16(const uint8_t *p)
void StoreU16(uint16_t v, uint8_t *p)
float DequantizeFloat(int32_t fixed, float scale)
uint32_t LoadU32(const uint8_t *p)
int32_t QuantizeFloat(float value, float scale)
void StoreS16(int16_t v, uint8_t *p)
void StoreU32(uint32_t v, uint8_t *p)
uint16_t LoadU16(const uint8_t *p)
int32_t LoadS32(const uint8_t *p)
void StoreS32(int32_t v, uint8_t *p)
constexpr std::size_t kHeaderMsgCountIndex
std::optional< MessageInfo > GetMessageInfo(MessageTypeId typeId)
bool EncodeHandshake(uint8_t *out, std::size_t capacity)
Encode handshake with default schema hash.
bool EncodeHandshakeWithHash(uint8_t *out, std::size_t capacity, uint32_t schemaHash)
Encode handshake with custom schema hash (for testing)
constexpr std::array< MessageInfo, 0 > kMessageRegistry
constexpr std::size_t kHandshakeSize
constexpr std::array< uint8_t, 4 > kHandshakeMagic
bool ValidateHandshakeWithHash(const uint8_t *data, std::size_t length, uint32_t expectedHash)
Validate handshake against custom expected hash (for testing)
uint32_t ExtractSchemaHash(const uint8_t *data, std::size_t length)
constexpr uint32_t kSchemaHash
constexpr std::size_t kHeaderMsgTypeIndex
constexpr uint8_t kProtocolMinorV3
constexpr std::size_t kHeaderSizeV3
bool ValidateHandshake(const uint8_t *data, std::size_t length)
constexpr uint8_t kProtocolMajorV3
const char * name
MessageTypeId typeId
std::size_t wireSize