Ember
Loading...
Searching...
No Matches
MessageFrame.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <cstring>
5#include <vector>
6
8
9namespace Ember {
10namespace Network {
11
12constexpr size_t FRAME_HEADER_SIZE = 5;
13
15 uint32_t payloadLength = 0;
17 std::vector<uint8_t> payload;
18
19 MessageFrame() = default;
20
21 MessageFrame(Protocol::MessageType type, const uint8_t *data, size_t size)
22 : payloadLength(static_cast<uint32_t>(size)), messageType(type), payload(data, data + size) {}
23
24 MessageFrame(Protocol::MessageType type, std::vector<uint8_t> &&data)
25 : payloadLength(static_cast<uint32_t>(data.size())), messageType(type), payload(std::move(data)) {}
26
27 std::vector<uint8_t> ToBytes() const {
28 std::vector<uint8_t> result;
29 result.reserve(FRAME_HEADER_SIZE + payload.size());
30
31 result.push_back(static_cast<uint8_t>(payloadLength & 0xFF));
32 result.push_back(static_cast<uint8_t>((payloadLength >> 8) & 0xFF));
33 result.push_back(static_cast<uint8_t>((payloadLength >> 16) & 0xFF));
34 result.push_back(static_cast<uint8_t>((payloadLength >> 24) & 0xFF));
35
36 result.push_back(static_cast<uint8_t>(messageType));
37
38 result.insert(result.end(), payload.begin(), payload.end());
39
40 return result;
41 }
42
43 static bool ParseHeader(const uint8_t *data, size_t dataSize, uint32_t &outLength, Protocol::MessageType &outType) {
44 if (dataSize < FRAME_HEADER_SIZE) {
45 return false;
46 }
47
48 outLength = static_cast<uint32_t>(data[0]) | (static_cast<uint32_t>(data[1]) << 8) |
49 (static_cast<uint32_t>(data[2]) << 16) | (static_cast<uint32_t>(data[3]) << 24);
50
51 outType = static_cast<Protocol::MessageType>(data[4]);
52
53 return true;
54 }
55
56 static MessageFrame FromBytes(const uint8_t *data, size_t dataSize) {
57 MessageFrame frame;
58
59 if (!ParseHeader(data, dataSize, frame.payloadLength, frame.messageType)) {
60 return frame;
61 }
62
63 if (dataSize >= FRAME_HEADER_SIZE + frame.payloadLength) {
64 frame.payload.assign(data + FRAME_HEADER_SIZE, data + FRAME_HEADER_SIZE + frame.payloadLength);
65 }
66
67 return frame;
68 }
69
70 bool IsValid() const { return payloadLength > 0 && payloadLength == payload.size(); }
71
72 size_t TotalSize() const { return FRAME_HEADER_SIZE + payloadLength; }
73};
74
75} // namespace Network
76} // namespace Ember
constexpr size_t FRAME_HEADER_SIZE
static MessageFrame FromBytes(const uint8_t *data, size_t dataSize)
Protocol::MessageType messageType
MessageFrame(Protocol::MessageType type, std::vector< uint8_t > &&data)
MessageFrame(Protocol::MessageType type, const uint8_t *data, size_t size)
std::vector< uint8_t > payload
static bool ParseHeader(const uint8_t *data, size_t dataSize, uint32_t &outLength, Protocol::MessageType &outType)
std::vector< uint8_t > ToBytes() const