File: RawPacket.h

package info (click to toggle)
spring 106.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 55,316 kB
  • sloc: cpp: 543,954; ansic: 44,800; python: 12,575; java: 12,201; awk: 5,889; sh: 1,796; asm: 1,546; xml: 655; perl: 405; php: 211; objc: 194; makefile: 76; sed: 2
file content (135 lines) | stat: -rw-r--r-- 2,663 bytes parent folder | download | duplicates (3)
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