Packet.cpp
1
2//
3// SFML - Simple and Fast Multimedia Library
4// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
5//
6// This software is provided 'as-is', without any express or implied warranty.
7// In no event will the authors be held liable for any damages arising from the use of this software.
8//
9// Permission is granted to anyone to use this software for any purpose,
10// including commercial applications, and to alter it and redistribute it freely,
11// subject to the following restrictions:
12//
13// 1. The origin of this software must not be misrepresented;
14// you must not claim that you wrote the original software.
15// If you use this software in a product, an acknowledgment
16// in the product documentation would be appreciated but is not required.
17//
18// 2. Altered source versions must be plainly marked as such,
19// and must not be misrepresented as being the original software.
20//
21// 3. This notice may not be removed or altered from any source distribution.
22//
24
26// Headers
28#include <SFML/Network/Packet.hpp>
29#include <SFML/Network/SocketHelper.hpp>
30#include <string.h>
31
32
33namespace sf
34{
39myReadPos(0),
40myIsValid(true)
41{
42
43}
44
45
50{
51
52}
53
54
58void Packet::Append(const void* Data, std::size_t SizeInBytes)
59{
60 if (Data && (SizeInBytes > 0))
61 {
62 std::size_t Start = myData.size();
63 myData.resize(Start + SizeInBytes);
64 memcpy(&myData[Start], Data, SizeInBytes);
65 }
66}
67
68
73{
74 myData.clear();
75 myReadPos = 0;
76 myIsValid = true;
77}
78
79
85const char* Packet::GetData() const
86{
87 return !myData.empty() ? &myData[0] : NULL;
88}
89
90
94std::size_t Packet::GetDataSize() const
95{
96 return myData.size();
97}
98
99
104{
105 return myReadPos >= myData.size();
106}
107
108
112Packet::operator bool() const
113{
114 return myIsValid;
115}
116
117
122{
123 Uint8 Value;
124 if (*this >> Value)
125 Data = (Value != 0);
126
127 return *this;
128}
129Packet& Packet::operator >>(Int8& Data)
130{
131 if (CheckSize(sizeof(Data)))
132 {
133 Data = *reinterpret_cast<const Int8*>(GetData() + myReadPos);
134 myReadPos += sizeof(Data);
135 }
136
137 return *this;
138}
139Packet& Packet::operator >>(Uint8& Data)
140{
141 if (CheckSize(sizeof(Data)))
142 {
143 Data = *reinterpret_cast<const Uint8*>(GetData() + myReadPos);
144 myReadPos += sizeof(Data);
145 }
146
147 return *this;
148}
149Packet& Packet::operator >>(Int16& Data)
150{
151 if (CheckSize(sizeof(Data)))
152 {
153 Data = ntohs(*reinterpret_cast<const Int16*>(GetData() + myReadPos));
154 myReadPos += sizeof(Data);
155 }
156
157 return *this;
158}
159Packet& Packet::operator >>(Uint16& Data)
160{
161 if (CheckSize(sizeof(Data)))
162 {
163 Data = ntohs(*reinterpret_cast<const Uint16*>(GetData() + myReadPos));
164 myReadPos += sizeof(Data);
165 }
166
167 return *this;
168}
169Packet& Packet::operator >>(Int32& Data)
170{
171 if (CheckSize(sizeof(Data)))
172 {
173 Data = ntohl(*reinterpret_cast<const Int32*>(GetData() + myReadPos));
174 myReadPos += sizeof(Data);
175 }
176
177 return *this;
178}
179Packet& Packet::operator >>(Uint32& Data)
180{
181 if (CheckSize(sizeof(Data)))
182 {
183 Data = ntohl(*reinterpret_cast<const Uint32*>(GetData() + myReadPos));
184 myReadPos += sizeof(Data);
185 }
186
187 return *this;
188}
189Packet& Packet::operator >>(float& Data)
190{
191 if (CheckSize(sizeof(Data)))
192 {
193 Data = *reinterpret_cast<const float*>(GetData() + myReadPos);
194 myReadPos += sizeof(Data);
195 }
196
197 return *this;
198}
199Packet& Packet::operator >>(double& Data)
200{
201 if (CheckSize(sizeof(Data)))
202 {
203 Data = *reinterpret_cast<const double*>(GetData() + myReadPos);
204 myReadPos += sizeof(Data);
205 }
206
207 return *this;
208}
209Packet& Packet::operator >>(char* Data)
210{
211 // First extract string length
212 Uint32 Length;
213 *this >> Length;
214
215 if ((Length > 0) && CheckSize(Length))
216 {
217 // Then extract characters
218 memcpy(Data, GetData() + myReadPos, Length);
219 Data[Length] = '\0';
220
221 // Update reading position
222 myReadPos += Length;
223 }
224
225 return *this;
226}
227Packet& Packet::operator >>(std::string& Data)
228{
229 // First extract string length
230 Uint32 Length;
231 *this >> Length;
232
233 Data.clear();
234 if ((Length > 0) && CheckSize(Length))
235 {
236 // Then extract characters
237 Data.assign(GetData() + myReadPos, Length);
238
239 // Update reading position
240 myReadPos += Length;
241 }
242
243 return *this;
244}
245Packet& Packet::operator >>(wchar_t* Data)
246{
247 // First extract string length
248 Uint32 Length;
249 *this >> Length;
250
251 if ((Length > 0) && CheckSize(Length * sizeof(Int32)))
252 {
253 // Then extract characters
254 for (Uint32 i = 0; i < Length; ++i)
255 {
256 Uint32 c;
257 *this >> c;
258 Data[i] = static_cast<wchar_t>(c);
259 }
260 Data[Length] = L'\0';
261 }
262
263 return *this;
264}
265Packet& Packet::operator >>(std::wstring& Data)
266{
267 // First extract string length
268 Uint32 Length;
269 *this >> Length;
270
271 Data.clear();
272 if ((Length > 0) && CheckSize(Length * sizeof(Int32)))
273 {
274 // Then extract characters
275 for (Uint32 i = 0; i < Length; ++i)
276 {
277 Uint32 c;
278 *this >> c;
279 Data += static_cast<wchar_t>(c);
280 }
281 }
282
283 return *this;
284}
285
286
291{
292 *this << static_cast<Uint8>(Data);
293 return *this;
294}
295Packet& Packet::operator <<(Int8 Data)
296{
297 Append(&Data, sizeof(Data));
298 return *this;
299}
300Packet& Packet::operator <<(Uint8 Data)
301{
302 Append(&Data, sizeof(Data));
303 return *this;
304}
305Packet& Packet::operator <<(Int16 Data)
306{
307 Int16 ToWrite = htons(Data);
308 Append(&ToWrite, sizeof(ToWrite));
309 return *this;
310}
311Packet& Packet::operator <<(Uint16 Data)
312{
313 Uint16 ToWrite = htons(Data);
314 Append(&ToWrite, sizeof(ToWrite));
315 return *this;
316}
317Packet& Packet::operator <<(Int32 Data)
318{
319 Int32 ToWrite = htonl(Data);
320 Append(&ToWrite, sizeof(ToWrite));
321 return *this;
322}
323Packet& Packet::operator <<(Uint32 Data)
324{
325 Uint32 ToWrite = htonl(Data);
326 Append(&ToWrite, sizeof(ToWrite));
327 return *this;
328}
329Packet& Packet::operator <<(float Data)
330{
331 Append(&Data, sizeof(Data));
332 return *this;
333}
334Packet& Packet::operator <<(double Data)
335{
336 Append(&Data, sizeof(Data));
337 return *this;
338}
339Packet& Packet::operator <<(const char* Data)
340{
341 // First insert string length
342 Uint32 Length = 0;
343 for (const char* c = Data; *c != '\0'; ++c)
344 ++Length;
345 *this << Length;
346
347 // Then insert characters
348 Append(Data, Length * sizeof(char));
349
350 return *this;
351}
352Packet& Packet::operator <<(const std::string& Data)
353{
354 // First insert string length
355 Uint32 Length = static_cast<Uint32>(Data.size());
356 *this << Length;
357
358 // Then insert characters
359 if (Length > 0)
360 {
361 Append(Data.c_str(), Length * sizeof(std::string::value_type));
362 }
363
364 return *this;
365}
366Packet& Packet::operator <<(const wchar_t* Data)
367{
368 // First insert string length
369 Uint32 Length = 0;
370 for (const wchar_t* c = Data; *c != L'\0'; ++c)
371 ++Length;
372 *this << Length;
373
374 // Then insert characters
375 for (const wchar_t* c = Data; *c != L'\0'; ++c)
376 *this << static_cast<Int32>(*c);
377
378 return *this;
379}
380Packet& Packet::operator <<(const std::wstring& Data)
381{
382 // First insert string length
383 Uint32 Length = static_cast<Uint32>(Data.size());
384 *this << Length;
385
386 // Then insert characters
387 if (Length > 0)
388 {
389 for (std::wstring::const_iterator c = Data.begin(); c != Data.end(); ++c)
390 *this << static_cast<Int32>(*c);
391 }
392
393 return *this;
394}
395
396
400bool Packet::CheckSize(std::size_t Size)
401{
402 myIsValid = myIsValid && (myReadPos + Size <= myData.size());
403
404 return myIsValid;
405}
406
407
411const char* Packet::OnSend(std::size_t& DataSize)
412{
413 DataSize = GetDataSize();
414 return GetData();
415}
416
417
421void Packet::OnReceive(const char* Data, std::size_t DataSize)
422{
423 Append(Data, DataSize);
424}
425
426} // namespace sf
Packet wraps data to send / to receive through the network.
Definition Packet.hpp:42
const char * GetData() const
Get a pointer to the data contained in the packet Warning : the returned pointer may be invalid after...
Definition Packet.cpp:85
void Clear()
Clear the packet data.
Definition Packet.cpp:72
Packet & operator<<(bool Data)
Operator << overloads to put data into the packet.
Definition Packet.cpp:290
Packet()
Default constructor.
Definition Packet.cpp:38
Packet & operator>>(bool &Data)
Operator >> overloads to extract data from the packet.
Definition Packet.cpp:121
bool EndOfPacket() const
Tell if the reading position has reached the end of the packet.
Definition Packet.cpp:103
void Append(const void *Data, std::size_t SizeInBytes)
Append data to the end of the packet.
Definition Packet.cpp:58
virtual ~Packet()
Virtual destructor.
Definition Packet.cpp:49
std::size_t GetDataSize() const
Get the size of the data contained in the packet.
Definition Packet.cpp:94