-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcodec.h
96 lines (73 loc) · 2.8 KB
/
codec.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#pragma once
#include <one/arcus/error.h>
#include <one/arcus/opcode.h>
#include <stdint.h>
#include <array>
namespace i3d {
namespace one {
class Message;
class Payload;
// The codec provides conversion to and from byte data for Arcus types.
namespace codec {
//-----------------
// Handshake Hello.
// The first packet, used for handshaking, is a hello packet.
struct Hello {
char id[4];
char version;
char dummy;
};
static_assert(sizeof(Hello) == 6, "hello struct alignment");
constexpr size_t hello_size() {
return sizeof(Hello);
}
// Returns true if the given Hello version is compatible with this version of the SDK.
bool validate_hello(const Hello &hello);
// Returns the valid, expected Hello values.
const Hello &valid_hello();
//---------------
// Arcus Message.
// Header for regular Arcus messages.
struct Header {
char flags;
char opcode;
char reserved[2];
uint32_t packet_id;
uint32_t length;
};
static_assert(sizeof(Header) == 12, "header struct alignment");
constexpr size_t header_size() {
return sizeof(Header);
}
constexpr size_t payload_max_size() {
return (1024 * 128) - header_size();
}
// Ensuring that max size is smaller or equal to Stream buffers sizes of the connection's
// socket.
static_assert(sizeof(header_size() + payload_max_size()) <= 1024 * 128,
"max header and payload size");
// Returns true if the given Header matches what is expected by
// this version of the SDK.
bool validate_header(const Header &header);
// Convert the first message from data from at most data_size bytes. The read_data_size
// will contain the number of byte read and be equal to: codec::header_size() +
// header.length. The read_data_size is at least codec::header_size() and at most
// codec::header_size() + codec::payload_max_size().
OneError data_to_message(const void *data, const size_t data_size, size_t &read_data_size,
Header &header, Message &message);
// Convert a Message to byte data.
OneError message_to_data(const uint32_t packet_id, const Message &message,
size_t &data_length,
std::array<char, header_size() + payload_max_size()> &data);
// Convert byte data to a Header. Length must be header_size().
OneError data_to_header(const void *data, size_t length, Header &header);
// Convert a Header to byte data.
OneError header_to_data(const Header &header, std::array<char, header_size()> &data);
// Convert byte data to a Payload. Length must be at most payload_max_size().
OneError data_to_payload(const void *data, size_t length, Payload &payload);
// Convert a Payload to byte data.
OneError payload_to_data(const Payload &payload, size_t &payload_length,
std::array<char, payload_max_size()> &data);
} // namespace codec
} // namespace one
} // namespace i3d