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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#ifndef RAW_PACKET_H
#define RAW_PACKET_H
#include <cassert>
#include <cstdint>
#include <cstring>
#include <utility>
#include <string>
#include <vector>
#include "System/SafeVector.h"
namespace netcode
{
/**
* @brief simple structure to hold some data
*/
class RawPacket
{
public:
RawPacket() = default;
/**
* @brief create a new packet and store data inside
* @param data the data to store
* @param length the length of the data (is safe even if 0)
*/
RawPacket(const uint8_t* const data, const uint32_t length);
/**
* @brief create a new packet without data
* @param length the estimated length of the data
*/
RawPacket(const uint32_t newLength): length(newLength) {
if (length == 0)
return;
data = new uint8_t[length];
}
RawPacket(const uint32_t length, uint8_t msgID): RawPacket(length) {
*this << (id = msgID);
}
RawPacket(const RawPacket& p) = delete;
RawPacket( RawPacket&& p) { *this = std::move(p); }
~RawPacket() { Delete(); }
RawPacket& operator = (const RawPacket& p) = delete;
RawPacket& operator = ( RawPacket&& p) {
// assume no self-assignment
data = p.data;
p.data = nullptr;
id = p.id;
p.id = 0;
pos = p.pos;
p.pos = 0;
length = p.length;
p.length = 0;
return *this;
}
// packing operations
template <typename T>
RawPacket& operator << (const T& t) {
constexpr uint32_t size = sizeof(T);
assert((size + pos) <= length);
memcpy(reinterpret_cast<T*>(GetWritingPos()), reinterpret_cast<const void*>(&t), sizeof(T));
pos += size;
return *this;
}
RawPacket& operator << (const std::string& text);
template <typename element>
RawPacket& operator << (const std::vector<element>& vec) {
const size_t size = vec.size() * sizeof(element);
assert((size + pos) <= length);
if (size > 0) {
std::memcpy(GetWritingPos(), reinterpret_cast<const void*>(vec.data()), size);
pos += size;
}
return *this;
}
#ifdef USE_SAFE_VECTOR
template <typename element>
RawPacket& operator << (const safe_vector<element>& vec) {
const size_t size = vec.size() * sizeof(element);
assert((size + pos) <= length);
if (size > 0) {
std::memcpy(GetWritingPos(), reinterpret_cast<const void*>(vec.data()), size);
pos += size;
}
return *this;
}
#endif
uint8_t* GetWritingPos() { return (data + pos); }
void Delete() {
if (length == 0)
return;
delete[] data;
data = nullptr;
length = 0;
}
public:
uint8_t id = 0;
uint8_t* data = nullptr;
uint32_t pos = 0;
uint32_t length = 0;
};
} // namespace netcode
#endif // RAW_PACKET_H
|