Packet.cpp
1 //
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 
33 namespace sf
34 {
39 myReadPos(0),
40 myIsValid(true)
41 {
42 
43 }
44 
45 
50 {
51 
52 }
53 
54 
58 void 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 
85 const char* Packet::GetData() const
86 {
87  return !myData.empty() ? &myData[0] : NULL;
88 }
89 
90 
94 std::size_t Packet::GetDataSize() const
95 {
96  return myData.size();
97 }
98 
99 
104 {
105  return myReadPos >= myData.size();
106 }
107 
108 
112 Packet::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 }
129 Packet& 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 }
139 Packet& 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 }
149 Packet& 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 }
159 Packet& 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 }
169 Packet& 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 }
179 Packet& 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 }
189 Packet& 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 }
199 Packet& 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 }
209 Packet& 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 }
227 Packet& 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 }
245 Packet& 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 }
265 Packet& 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 }
295 Packet& Packet::operator <<(Int8 Data)
296 {
297  Append(&Data, sizeof(Data));
298  return *this;
299 }
300 Packet& Packet::operator <<(Uint8 Data)
301 {
302  Append(&Data, sizeof(Data));
303  return *this;
304 }
305 Packet& Packet::operator <<(Int16 Data)
306 {
307  Int16 ToWrite = htons(Data);
308  Append(&ToWrite, sizeof(ToWrite));
309  return *this;
310 }
311 Packet& Packet::operator <<(Uint16 Data)
312 {
313  Uint16 ToWrite = htons(Data);
314  Append(&ToWrite, sizeof(ToWrite));
315  return *this;
316 }
317 Packet& Packet::operator <<(Int32 Data)
318 {
319  Int32 ToWrite = htonl(Data);
320  Append(&ToWrite, sizeof(ToWrite));
321  return *this;
322 }
323 Packet& Packet::operator <<(Uint32 Data)
324 {
325  Uint32 ToWrite = htonl(Data);
326  Append(&ToWrite, sizeof(ToWrite));
327  return *this;
328 }
329 Packet& Packet::operator <<(float Data)
330 {
331  Append(&Data, sizeof(Data));
332  return *this;
333 }
334 Packet& Packet::operator <<(double Data)
335 {
336  Append(&Data, sizeof(Data));
337  return *this;
338 }
339 Packet& 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 }
352 Packet& 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 }
366 Packet& 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 }
380 Packet& 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 
400 bool Packet::CheckSize(std::size_t Size)
401 {
402  myIsValid = myIsValid && (myReadPos + Size <= myData.size());
403 
404  return myIsValid;
405 }
406 
407 
411 const char* Packet::OnSend(std::size_t& DataSize)
412 {
413  DataSize = GetDataSize();
414  return GetData();
415 }
416 
417 
421 void Packet::OnReceive(const char* Data, std::size_t DataSize)
422 {
423  Append(Data, DataSize);
424 }
425 
426 } // namespace sf
void Append(const void *Data, std::size_t SizeInBytes)
Append data to the end of the packet.
Definition: Packet.cpp:58
Packet wraps data to send / to receive through the network.
Definition: Packet.hpp:41
bool EndOfPacket() const
Tell if the reading position has reached the end of the packet.
Definition: Packet.cpp:103
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
Packet & operator>>(bool &Data)
Operator >> overloads to extract data from the packet.
Definition: Packet.cpp:121
Packet & operator<<(bool Data)
Operator << overloads to put data into the packet.
Definition: Packet.cpp:290
void Clear()
Clear the packet data.
Definition: Packet.cpp:72
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
Packet()
Default constructor.
Definition: Packet.cpp:38