106 lines
2.6 KiB
C++
106 lines
2.6 KiB
C++
/*
|
|
* messaging_packet.hpp
|
|
*
|
|
* Created on: Mar 27, 2021
|
|
* Author: erki
|
|
*/
|
|
|
|
#ifndef MESSAGING_INC_MESSAGING_PACKET_HPP_
|
|
#define MESSAGING_INC_MESSAGING_PACKET_HPP_
|
|
|
|
#include <cstring>
|
|
#include <cstdint>
|
|
#include <array>
|
|
|
|
namespace Messaging
|
|
{
|
|
|
|
template<std::size_t N>
|
|
struct Packet
|
|
{
|
|
using length_type = std::uint32_t;
|
|
|
|
static constexpr std::uint8_t preamble[] = { 'A', 'A' };
|
|
std::array<std::uint8_t, N> data = { 0 };
|
|
std::uint32_t data_length = 0;
|
|
|
|
const std::uint32_t max_data_length = N;
|
|
const std::uint32_t preamble_length = sizeof(preamble);
|
|
const std::uint32_t data_length_length = sizeof(data_length);
|
|
|
|
static constexpr std::size_t totalLength()
|
|
{
|
|
return N + sizeof(preamble) + sizeof(data_length);
|
|
}
|
|
|
|
Packet() = default;
|
|
Packet(const Packet&) = default;
|
|
Packet(Packet&&) noexcept = default;
|
|
|
|
template<std::size_t data_in_length>
|
|
void copy_data_in(const std::uint8_t (&data_in)[data_in_length])
|
|
{
|
|
const std::uint32_t to_copy_length = std::min(std::uint32_t(data_in_length), max_data_length);
|
|
|
|
std::memcpy(data.data(), data_in, to_copy_length);
|
|
data_length = to_copy_length;
|
|
}
|
|
|
|
template<std::size_t data_in_length>
|
|
void copy_data_in(const std::array<std::uint8_t, data_in_length>& data_in)
|
|
{
|
|
const std::uint32_t to_copy_length = std::min(std::uint32_t(data_in_length), max_data_length);
|
|
|
|
std::memcpy(data.data(), data_in.data(), to_copy_length);
|
|
data_length = to_copy_length;
|
|
}
|
|
|
|
bool serialize(std::uint8_t* buffer, const std::uint32_t max_length)
|
|
{
|
|
const std::uint32_t required_size = preamble_length + data_length_length + data_length;
|
|
|
|
if (max_length < required_size)
|
|
return false;
|
|
|
|
std::memcpy(buffer, preamble, preamble_length);
|
|
buffer += preamble_length;
|
|
|
|
std::memcpy(buffer, &data_length, data_length_length);
|
|
buffer += data_length_length;
|
|
|
|
std::memcpy(buffer, data.data(), data_length);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool deserialize(const std::uint8_t* buffer, const std::uint32_t length)
|
|
{
|
|
const std::uint32_t header_length = preamble_length + data_length_length;
|
|
|
|
if (length < header_length)
|
|
return false;
|
|
|
|
if (std::memcmp(buffer, preamble, preamble_length) != 0)
|
|
return false;
|
|
|
|
std::memcpy(&data_length, buffer + preamble_length, preamble_length);
|
|
|
|
const std::uint32_t final_length = header_length + data_length;
|
|
|
|
if (length != final_length)
|
|
return false;
|
|
|
|
std::memcpy(data.data(), buffer + header_length, data_length);
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
template <std::size_t N>
|
|
constexpr std::uint8_t Packet<N>::preamble[2];
|
|
|
|
}
|
|
|
|
|
|
#endif /* MESSAGING_INC_MESSAGING_PACKET_HPP_ */
|