summaryrefslogtreecommitdiff
path: root/src/network/packet.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/packet.h')
-rw-r--r--src/network/packet.h165
1 files changed, 165 insertions, 0 deletions
diff --git a/src/network/packet.h b/src/network/packet.h
new file mode 100644
index 000000000..e69217488
--- /dev/null
+++ b/src/network/packet.h
@@ -0,0 +1,165 @@
1// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <array>
7#include <vector>
8#include "common/common_types.h"
9
10namespace Network {
11
12/// A class that serializes data for network transfer. It also handles endianess
13class Packet {
14public:
15 Packet() = default;
16 ~Packet() = default;
17
18 /**
19 * Append data to the end of the packet
20 * @param data Pointer to the sequence of bytes to append
21 * @param size_in_bytes Number of bytes to append
22 */
23 void Append(const void* data, std::size_t size_in_bytes);
24
25 /**
26 * Reads data from the current read position of the packet
27 * @param out_data Pointer where the data should get written to
28 * @param size_in_bytes Number of bytes to read
29 */
30 void Read(void* out_data, std::size_t size_in_bytes);
31
32 /**
33 * Clear the packet
34 * After calling Clear, the packet is empty.
35 */
36 void Clear();
37
38 /**
39 * Ignores bytes while reading
40 * @param length THe number of bytes to ignore
41 */
42 void IgnoreBytes(u32 length);
43
44 /**
45 * Get a pointer to the data contained in the packet
46 * @return Pointer to the data
47 */
48 const void* GetData() const;
49
50 /**
51 * This function returns the number of bytes pointed to by
52 * what getData returns.
53 * @return Data size, in bytes
54 */
55 std::size_t GetDataSize() const;
56
57 /**
58 * This function is useful to know if there is some data
59 * left to be read, without actually reading it.
60 * @return True if all data was read, false otherwise
61 */
62 bool EndOfPacket() const;
63
64 explicit operator bool() const;
65
66 /// Overloads of read function to read data from the packet
67 Packet& Read(bool& out_data);
68 Packet& Read(s8& out_data);
69 Packet& Read(u8& out_data);
70 Packet& Read(s16& out_data);
71 Packet& Read(u16& out_data);
72 Packet& Read(s32& out_data);
73 Packet& Read(u32& out_data);
74 Packet& Read(s64& out_data);
75 Packet& Read(u64& out_data);
76 Packet& Read(float& out_data);
77 Packet& Read(double& out_data);
78 Packet& Read(char* out_data);
79 Packet& Read(std::string& out_data);
80 template <typename T>
81 Packet& Read(std::vector<T>& out_data);
82 template <typename T, std::size_t S>
83 Packet& Read(std::array<T, S>& out_data);
84
85 /// Overloads of write function to write data into the packet
86 Packet& Write(bool in_data);
87 Packet& Write(s8 in_data);
88 Packet& Write(u8 in_data);
89 Packet& Write(s16 in_data);
90 Packet& Write(u16 in_data);
91 Packet& Write(s32 in_data);
92 Packet& Write(u32 in_data);
93 Packet& Write(s64 in_data);
94 Packet& Write(u64 in_data);
95 Packet& Write(float in_data);
96 Packet& Write(double in_data);
97 Packet& Write(const char* in_data);
98 Packet& Write(const std::string& in_data);
99 template <typename T>
100 Packet& Write(const std::vector<T>& in_data);
101 template <typename T, std::size_t S>
102 Packet& Write(const std::array<T, S>& data);
103
104private:
105 /**
106 * Check if the packet can extract a given number of bytes
107 * This function updates accordingly the state of the packet.
108 * @param size Size to check
109 * @return True if size bytes can be read from the packet
110 */
111 bool CheckSize(std::size_t size);
112
113 // Member data
114 std::vector<char> data; ///< Data stored in the packet
115 std::size_t read_pos = 0; ///< Current reading position in the packet
116 bool is_valid = true; ///< Reading state of the packet
117};
118
119template <typename T>
120Packet& Packet::Read(std::vector<T>& out_data) {
121 // First extract the size
122 u32 size = 0;
123 Read(size);
124 out_data.resize(size);
125
126 // Then extract the data
127 for (std::size_t i = 0; i < out_data.size(); ++i) {
128 T character;
129 Read(character);
130 out_data[i] = character;
131 }
132 return *this;
133}
134
135template <typename T, std::size_t S>
136Packet& Packet::Read(std::array<T, S>& out_data) {
137 for (std::size_t i = 0; i < out_data.size(); ++i) {
138 T character;
139 Read(character);
140 out_data[i] = character;
141 }
142 return *this;
143}
144
145template <typename T>
146Packet& Packet::Write(const std::vector<T>& in_data) {
147 // First insert the size
148 Write(static_cast<u32>(in_data.size()));
149
150 // Then insert the data
151 for (std::size_t i = 0; i < in_data.size(); ++i) {
152 Write(in_data[i]);
153 }
154 return *this;
155}
156
157template <typename T, std::size_t S>
158Packet& Packet::Write(const std::array<T, S>& in_data) {
159 for (std::size_t i = 0; i < in_data.size(); ++i) {
160 Write(in_data[i]);
161 }
162 return *this;
163}
164
165} // namespace Network