summaryrefslogtreecommitdiff
path: root/src/network/packet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/packet.cpp')
-rw-r--r--src/network/packet.cpp229
1 files changed, 229 insertions, 0 deletions
diff --git a/src/network/packet.cpp b/src/network/packet.cpp
new file mode 100644
index 000000000..b3a61d824
--- /dev/null
+++ b/src/network/packet.cpp
@@ -0,0 +1,229 @@
1// Copyright 2017 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#ifdef _WIN32
6#include <winsock2.h>
7#else
8#include <arpa/inet.h>
9#endif
10#include <cstring>
11#include <string>
12#include "network/packet.h"
13
14namespace Network {
15
16Packet::Packet() : read_pos(0), is_valid(true) {}
17
18Packet::~Packet() {}
19
20void Packet::Append(const void* in_data, std::size_t size_in_bytes) {
21 if (in_data && (size_in_bytes > 0)) {
22 std::size_t start = data.size();
23 data.resize(start + size_in_bytes);
24 std::memcpy(&data[start], in_data, size_in_bytes);
25 }
26}
27
28void Packet::Read(void* out_data, std::size_t size_in_bytes) {
29 if (out_data && CheckSize(size_in_bytes)) {
30 std::memcpy(out_data, &data[read_pos], size_in_bytes);
31 read_pos += size_in_bytes;
32 }
33}
34
35void Packet::Clear() {
36 data.clear();
37 read_pos = 0;
38 is_valid = true;
39}
40
41const void* Packet::GetData() const {
42 return !data.empty() ? &data[0] : NULL;
43}
44
45void Packet::IgnoreBytes(u32 length) {
46 read_pos += length;
47}
48
49std::size_t Packet::GetDataSize() const {
50 return data.size();
51}
52
53bool Packet::EndOfPacket() const {
54 return read_pos >= data.size();
55}
56
57Packet::operator BoolType() const {
58 return is_valid ? &Packet::CheckSize : NULL;
59}
60
61Packet& Packet::operator>>(bool& out_data) {
62 u8 value;
63 if (*this >> value) {
64 out_data = (value != 0);
65 }
66 return *this;
67}
68
69Packet& Packet::operator>>(s8& out_data) {
70 Read(&out_data, sizeof(out_data));
71 return *this;
72}
73
74Packet& Packet::operator>>(u8& out_data) {
75 Read(&out_data, sizeof(out_data));
76 return *this;
77}
78
79Packet& Packet::operator>>(s16& out_data) {
80 s16 value;
81 Read(&value, sizeof(value));
82 out_data = ntohs(value);
83 return *this;
84}
85
86Packet& Packet::operator>>(u16& out_data) {
87 u16 value;
88 Read(&value, sizeof(value));
89 out_data = ntohs(value);
90 return *this;
91}
92
93Packet& Packet::operator>>(s32& out_data) {
94 s32 value;
95 Read(&value, sizeof(value));
96 out_data = ntohl(value);
97 return *this;
98}
99
100Packet& Packet::operator>>(u32& out_data) {
101 u32 value;
102 Read(&value, sizeof(value));
103 out_data = ntohl(value);
104 return *this;
105}
106
107Packet& Packet::operator>>(float& out_data) {
108 Read(&out_data, sizeof(out_data));
109 return *this;
110}
111
112Packet& Packet::operator>>(double& out_data) {
113 Read(&out_data, sizeof(out_data));
114 return *this;
115}
116
117Packet& Packet::operator>>(char* out_data) {
118 // First extract string length
119 u32 length = 0;
120 *this >> length;
121
122 if ((length > 0) && CheckSize(length)) {
123 // Then extract characters
124 std::memcpy(out_data, &data[read_pos], length);
125 out_data[length] = '\0';
126
127 // Update reading position
128 read_pos += length;
129 }
130
131 return *this;
132}
133
134Packet& Packet::operator>>(std::string& out_data) {
135 // First extract string length
136 u32 length = 0;
137 *this >> length;
138
139 out_data.clear();
140 if ((length > 0) && CheckSize(length)) {
141 // Then extract characters
142 out_data.assign(&data[read_pos], length);
143
144 // Update reading position
145 read_pos += length;
146 }
147
148 return *this;
149}
150
151Packet& Packet::operator<<(bool in_data) {
152 *this << static_cast<u8>(in_data);
153 return *this;
154}
155
156Packet& Packet::operator<<(s8 in_data) {
157 Append(&in_data, sizeof(in_data));
158 return *this;
159}
160
161Packet& Packet::operator<<(u8 in_data) {
162 Append(&in_data, sizeof(in_data));
163 return *this;
164}
165
166Packet& Packet::operator<<(s16 in_data) {
167 s16 toWrite = htons(in_data);
168 Append(&toWrite, sizeof(toWrite));
169 return *this;
170}
171
172Packet& Packet::operator<<(u16 in_data) {
173 u16 toWrite = htons(in_data);
174 Append(&toWrite, sizeof(toWrite));
175 return *this;
176}
177
178Packet& Packet::operator<<(s32 in_data) {
179 s32 toWrite = htonl(in_data);
180 Append(&toWrite, sizeof(toWrite));
181 return *this;
182}
183
184Packet& Packet::operator<<(u32 in_data) {
185 u32 toWrite = htonl(in_data);
186 Append(&toWrite, sizeof(toWrite));
187 return *this;
188}
189
190Packet& Packet::operator<<(float in_data) {
191 Append(&in_data, sizeof(in_data));
192 return *this;
193}
194
195Packet& Packet::operator<<(double in_data) {
196 Append(&in_data, sizeof(in_data));
197 return *this;
198}
199
200Packet& Packet::operator<<(const char* in_data) {
201 // First insert string length
202 u32 length = std::strlen(in_data);
203 *this << length;
204
205 // Then insert characters
206 Append(in_data, length * sizeof(char));
207
208 return *this;
209}
210
211Packet& Packet::operator<<(const std::string& in_data) {
212 // First insert string length
213 u32 length = static_cast<u32>(in_data.size());
214 *this << length;
215
216 // Then insert characters
217 if (length > 0)
218 Append(in_data.c_str(), length * sizeof(std::string::value_type));
219
220 return *this;
221}
222
223bool Packet::CheckSize(std::size_t size) {
224 is_valid = is_valid && (read_pos + size <= data.size());
225
226 return is_valid;
227}
228
229} // namespace Network