SuperTuxKart
Loading...
Searching...
No Matches
network_string.hpp
Go to the documentation of this file.
1//
2// SuperTuxKart - a fun racing game with go-kart
3// Copyright (C) 2013-2015 SuperTuxKart-Team
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 3
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
23#ifndef NETWORK_STRING_HPP
24#define NETWORK_STRING_HPP
25
26#include "network/protocol.hpp"
27#include "utils/leak_check.hpp"
28#include "utils/types.hpp"
29#include "utils/vec3.hpp"
30
31#include "LinearMath/btQuaternion.h"
32
33#include "irrString.h"
34
35#include <assert.h>
36#include <stdarg.h>
37#include <stdexcept>
38#include <string>
39#include <string.h>
40#include <vector>
41
42typedef unsigned char uchar;
43
53{
54friend class Crypto;
55private:
56 LEAK_CHECK();
57
58protected:
60 std::vector<uint8_t> m_buffer;
61
68 mutable int m_current_offset;
69
70 // ------------------------------------------------------------------------
76 std::string getString(int len) const
77 {
78 if (m_current_offset > (int)m_buffer.size() ||
79 m_current_offset + len > (int)m_buffer.size())
80 throw std::out_of_range("getString out of range.");
81
82 std::string a(m_buffer.begin() + (m_current_offset ),
83 m_buffer.begin() + (m_current_offset + len));
84 m_current_offset += len;
85 return a;
86 } // getString
87 // ------------------------------------------------------------------------
89 BareNetworkString& addString(const std::string& value)
90 {
91 for (unsigned int i = 0; i < value.size(); i++)
92 m_buffer.push_back((uint8_t)(value[i]));
93 return *this;
94 } // addString
95
96 // ------------------------------------------------------------------------
98 template<typename T, size_t n>
99 T get() const
100 {
101 int a = n;
102 T result = 0;
103 m_current_offset += n;
104 int offset = m_current_offset -1;
105 while (a--)
106 {
107 result <<= 8; // offset one byte
108 // add the data to result
109 result += m_buffer.at(offset - a);
110 }
111 return result;
112 } // get(int pos)
113 // ------------------------------------------------------------------------
115 template<typename T>
116 T get() const
117 {
118 return m_buffer.at(m_current_offset++);
119 } // get
120
121public:
122
124 BareNetworkString(int capacity=16)
125 {
126 m_buffer.reserve(capacity);
128 } // BareNetworkString
129
130 // ------------------------------------------------------------------------
131 BareNetworkString(const std::string &s)
132 {
134 encodeString(s);
135 } // BareNetworkString
136 // ------------------------------------------------------------------------
138 BareNetworkString(const char *data, int len)
139 {
141 m_buffer.resize(len);
142 memcpy(m_buffer.data(), data, len);
143 } // BareNetworkString
144
145 // ------------------------------------------------------------------------
147 void reset() { m_current_offset = 0; }
148 // ------------------------------------------------------------------------
149 BareNetworkString& encodeString16(const irr::core::stringw& value,
150 uint16_t max_len = 65535);
151 // ------------------------------------------------------------------------
152 int decodeString16(irr::core::stringw* out,
153 uint16_t max_len = 65535);
154 // ------------------------------------------------------------------------
155 BareNetworkString& encodeString(const std::string &value);
156 BareNetworkString& encodeString(const irr::core::stringw &value);
157 int decodeString(std::string *out) const;
158 int decodeStringW(irr::core::stringw *out) const;
159 std::string getLogMessage(const std::string &indent="") const;
160 // ------------------------------------------------------------------------
162 std::vector<uint8_t>& getBuffer() { return m_buffer; }
163
164 // ------------------------------------------------------------------------
166 char* getData() { return (char*)(m_buffer.data()); };
167
168 // ------------------------------------------------------------------------
170 const char* getData() const { return (char*)(m_buffer.data()); };
171
172 // ------------------------------------------------------------------------
176 {
177 return (char*)(m_buffer.data()+m_current_offset);
178 } // getCurrentData
179
180 // ------------------------------------------------------------------------
183 const char* getCurrentData() const
184 {
185 return (char*)(m_buffer.data()+m_current_offset);
186 } // getCurrentData
187 // ------------------------------------------------------------------------
188 int getCurrentOffset() const { return m_current_offset; }
189 // ------------------------------------------------------------------------
191 unsigned int size() const { return (int)m_buffer.size()-m_current_offset; }
192
193 // ------------------------------------------------------------------------
195 void skip(int n)
196 {
197 m_current_offset += n;
198 assert(m_current_offset >=0 &&
199 m_current_offset <= (int)m_buffer.size());
200 } // skip
201 // ------------------------------------------------------------------------
206 unsigned int getTotalSize() const { return (unsigned int)m_buffer.size(); }
207 // ------------------------------------------------------------------------
208 // All functions related to adding data to a network string
210 BareNetworkString& addUInt8(const uint8_t value)
211 {
212 m_buffer.push_back(value);
213 return *this;
214 } // addUInt8
215
216 // ------------------------------------------------------------------------
218 BareNetworkString& addChar(const char value)
219 {
220 m_buffer.push_back((uint8_t)(value));
221 return *this;
222 } // addChar
223 // ------------------------------------------------------------------------
225 BareNetworkString& addUInt16(const uint16_t value)
226 {
227 m_buffer.push_back((value >> 8) & 0xff);
228 m_buffer.push_back(value & 0xff);
229 return *this;
230 } // addUInt16
231
232 // ------------------------------------------------------------------------
234 BareNetworkString& addInt24(const int value)
235 {
236 uint32_t combined = (uint32_t)value & 0xffffff;
237 m_buffer.push_back((combined >> 16) & 0xff);
238 m_buffer.push_back((combined >> 8) & 0xff);
239 m_buffer.push_back(combined & 0xff);
240 return *this;
241 } // addInt24
242
243 // ------------------------------------------------------------------------
245 BareNetworkString& addUInt32(const uint32_t& value)
246 {
247 m_buffer.push_back((value >> 24) & 0xff);
248 m_buffer.push_back((value >> 16) & 0xff);
249 m_buffer.push_back((value >> 8) & 0xff);
250 m_buffer.push_back( value & 0xff);
251 return *this;
252 } // addUInt32
253
254 // ------------------------------------------------------------------------
256 BareNetworkString& addUInt64(const uint64_t& value)
257 {
258 m_buffer.push_back((value >> 56) & 0xff);
259 m_buffer.push_back((value >> 48) & 0xff);
260 m_buffer.push_back((value >> 40) & 0xff);
261 m_buffer.push_back((value >> 32) & 0xff);
262 m_buffer.push_back((value >> 24) & 0xff);
263 m_buffer.push_back((value >> 16) & 0xff);
264 m_buffer.push_back((value >> 8) & 0xff);
265 m_buffer.push_back( value & 0xff);
266 return *this;
267 } // addUInt64
268
269 // ------------------------------------------------------------------------
271 BareNetworkString& addFloat(const float value)
272 {
273 uint32_t *p = (uint32_t*)&value;
274 return addUInt32(*p);
275 } // addFloat
276
277 // ------------------------------------------------------------------------
281 {
282 m_buffer.insert(m_buffer.end(),
283 value.m_buffer.begin()+value.m_current_offset,
284 value.m_buffer.end() );
285 return *this;
286 } // operator+=
287
288 // ------------------------------------------------------------------------
291 {
292 return addFloat(f);
293 } // add
294 // ------------------------------------------------------------------------
297 {
298 return addFloat(xyz.getX()).addFloat(xyz.getY()).addFloat(xyz.getZ());
299 } // add
300
301 // ------------------------------------------------------------------------
303 BareNetworkString& add(const btQuaternion &quat)
304 {
305 return addFloat(quat.getX()).addFloat(quat.getY())
306 .addFloat(quat.getZ()).addFloat(quat.getW());
307 } // add
308 // ------------------------------------------------------------------------
314 {
315 return addUInt32(ticks);
316 } // addTime
317
318 // Functions related to getting data from a network string
319 // ------------------------------------------------------------------------
321 inline uint64_t getUInt64() const { return get<uint64_t, 8>(); }
322 // ------------------------------------------------------------------------
324 inline uint32_t getUInt32() const { return get<uint32_t, 4>(); }
325 // ------------------------------------------------------------------------
327 inline int getInt24() const
328 {
329 uint32_t combined = get<uint32_t, 3>();
330 if (combined & 0x800000)
331 return (0x1000000 - (int)combined) * -1;
332 else
333 return (int)combined;
334 }
335 // ------------------------------------------------------------------------
337 inline uint32_t getTime() const { return get<uint32_t, 4>(); }
338 // ------------------------------------------------------------------------
340 inline uint16_t getUInt16() const { return get<uint16_t, 2>(); }
341 // ------------------------------------------------------------------------
343 inline int16_t getInt16() const { return get<int16_t, 2>(); }
344 // ------------------------------------------------------------------------
346 inline uint8_t getUInt8() const
347 {
348 return m_buffer.at(m_current_offset++);
349 } // getUInt8
350 // ------------------------------------------------------------------------
352 inline int8_t getInt8() const
353 {
354 return m_buffer.at(m_current_offset++);
355 } // getInt8
356 // ------------------------------------------------------------------------
358 float getFloat() const
359 {
360 uint32_t u = getUInt32();
361 float f;
362 // Doig a "return *(float*)&u;" appears to be more efficient,
363 // but it can create incorrect code on higher optimisation: c++
364 // makes the assumption that pointer of different types never
365 // overlap. So the compiler can assume that the int pointer (&u)
366 // and float pointer do point to different aras, so there read
367 // (*(float*) can be done before the write to u (and then the
368 // write to u is basically a no-op and can be removed, too).
369 // Using a union of int and float is not valid either, there
370 // is no guarantee that writing to the int part of the union
371 // will affect the float part. So, an explicit memcpy is the
372 // more or less only portable guaranteed to be correct way of
373 // converting the int to a float.
374 memcpy(&f, &u, sizeof(float));
375 return f;
376 } // getFloat
377
378 // ------------------------------------------------------------------------
380 Vec3 getVec3() const
381 {
382 Vec3 r;
383 r.setX(getFloat());
384 r.setY(getFloat());
385 r.setZ(getFloat());
386 return r;
387 } // getVec3
388
389 // ------------------------------------------------------------------------
391 btQuaternion getQuat() const
392 {
393 btQuaternion q;
394 q.setX(getFloat());
395 q.setY(getFloat());
396 q.setZ(getFloat());
397 q.setW(getFloat());
398 return q;
399 } // getQuat
400 // ------------------------------------------------------------------------
401
402}; // class BareNetworkString
403
404
405// ============================================================================
406
422{
423public:
424 static void unitTesting();
425
429 NetworkString(ProtocolType type, int capacity=16)
430 : BareNetworkString(capacity+1)
431 {
432 m_buffer.push_back(type);
433 } // NetworkString
434
435 // ------------------------------------------------------------------------
439 NetworkString(const uint8_t *data, int len)
440 : BareNetworkString((char*)data, len)
441 {
442 m_current_offset = 1; // ignore type
443 } // NetworkString
444
445 // ------------------------------------------------------------------------
447 void clear()
448 {
449 m_buffer.erase(m_buffer.begin() + 1, m_buffer.end());
451 } // clear
452 // ------------------------------------------------------------------------
455 {
456 return (ProtocolType)(m_buffer.at(0) & ~PROTOCOL_SYNCHRONOUS);
457 } // getProtocolType
458
459 // ------------------------------------------------------------------------
461 void setSynchronous(bool b)
462 {
463 if(b)
465 else
466 m_buffer[0] &= ~PROTOCOL_SYNCHRONOUS;
467 } // setSynchronous
468 // ------------------------------------------------------------------------
470 bool isSynchronous() const
471 {
473 } // isSynchronous
474
475}; // class NetworkString
476
477
478#endif // NETWORK_STRING_HPP
Describes a chain of 8-bit unsigned integers.
Definition: network_string.hpp:53
BareNetworkString & add(float f)
Adds a floating point number.
Definition: network_string.hpp:290
uint64_t getUInt64() const
Returns a unsigned 64 bit integer.
Definition: network_string.hpp:321
btQuaternion getQuat() const
Gets a bullet quaternion.
Definition: network_string.hpp:391
uint8_t getUInt8() const
Returns an unsigned 8-bit integer.
Definition: network_string.hpp:346
unsigned int size() const
Returns the remaining length of the network string.
Definition: network_string.hpp:191
BareNetworkString(int capacity=16)
Constructor, sets the protocol type of this message.
Definition: network_string.hpp:124
BareNetworkString & encodeString16(const irr::core::stringw &value, uint16_t max_len=65535)
Encode string with max length of 16bit and utf32, used in motd or chat.
Definition: network_string.cpp:131
int decodeString(std::string *out) const
Returns a string at the given position.
Definition: network_string.cpp:104
int m_current_offset
To avoid copying the buffer when bytes are deleted (which only happens at the front),...
Definition: network_string.hpp:68
const char * getData() const
Returns a byte pointer to the content of the network string.
Definition: network_string.hpp:170
BareNetworkString & addUInt8(const uint8_t value)
Add 8 bit unsigned int.
Definition: network_string.hpp:210
std::vector< uint8_t > & getBuffer()
Returns the internal buffer of the network string.
Definition: network_string.hpp:162
BareNetworkString & encodeString(const std::string &value)
Adds one byte for the length of the string, and then (up to 255 of) the characters of the given strin...
Definition: network_string.cpp:79
BareNetworkString & addInt24(const int value)
Adds signed 24 bit integer.
Definition: network_string.hpp:234
std::string getString(int len) const
Returns a part of the network string as a std::string.
Definition: network_string.hpp:76
char * getCurrentData()
Returns a byte pointer to the unread remaining content of the network string.
Definition: network_string.hpp:175
BareNetworkString & addUInt64(const uint64_t &value)
Adds unsigned 64 bit integer.
Definition: network_string.hpp:256
BareNetworkString & addFloat(const float value)
Adds a 4 byte floating point value.
Definition: network_string.hpp:271
void skip(int n)
Skips the specified number of bytes when reading.
Definition: network_string.hpp:195
std::vector< uint8_t > m_buffer
The actual buffer.
Definition: network_string.hpp:60
int getInt24() const
Returns a signed 24 bit integer.
Definition: network_string.hpp:327
BareNetworkString & add(const btQuaternion &quat)
Adds the four components of a quaternion.
Definition: network_string.hpp:303
BareNetworkString(const char *data, int len)
Initialises the string with a sequence of characters.
Definition: network_string.hpp:138
BareNetworkString & add(const Vec3 &xyz)
Adds the xyz components of a Vec3 to the string.
Definition: network_string.hpp:296
float getFloat() const
Gets a 4 byte floating point value.
Definition: network_string.hpp:358
Vec3 getVec3() const
Gets a Vec3.
Definition: network_string.hpp:380
int decodeStringW(irr::core::stringw *out) const
Returns an irrlicht wide string from the utf8 encoded string at the given position.
Definition: network_string.cpp:120
BareNetworkString & addChar(const char value)
Adds a single character to the string.
Definition: network_string.hpp:218
unsigned int getTotalSize() const
Returns the send size, which is the full length of the buffer.
Definition: network_string.hpp:206
BareNetworkString & addTime(int ticks)
Adds a function to add a time ticks value.
Definition: network_string.hpp:313
void reset()
Allows one to read a buffer from the beginning again.
Definition: network_string.hpp:147
const char * getCurrentData() const
Returns a byte pointer to the unread remaining content of the network string.
Definition: network_string.hpp:183
BareNetworkString & operator+=(BareNetworkString const &value)
Adds the content of another network string.
Definition: network_string.hpp:280
BareNetworkString & addUInt32(const uint32_t &value)
Adds unsigned 32 bit integer.
Definition: network_string.hpp:245
BareNetworkString & addUInt16(const uint16_t value)
Adds 16 bit unsigned int.
Definition: network_string.hpp:225
T get() const
Another function for n == 1 to surpress warnings in clang.
Definition: network_string.hpp:116
uint32_t getUInt32() const
Returns a unsigned 32 bit integer.
Definition: network_string.hpp:324
char * getData()
Returns a byte pointer to the content of the network string.
Definition: network_string.hpp:166
T get() const
Template to get n bytes from a buffer into a single data type.
Definition: network_string.hpp:99
int16_t getInt16() const
Returns an unsigned 16 bit integer.
Definition: network_string.hpp:343
uint16_t getUInt16() const
Returns an unsigned 16 bit integer.
Definition: network_string.hpp:340
uint32_t getTime() const
Returns a unsigned 32 bit integer.
Definition: network_string.hpp:337
std::string getLogMessage(const std::string &indent="") const
Returns a string representing this message suitable to be printed to stdout or via the Log mechanism.
Definition: network_string.cpp:202
BareNetworkString & addString(const std::string &value)
Adds a std::string.
Definition: network_string.hpp:89
int8_t getInt8() const
Returns an unsigned 8-bit integer.
Definition: network_string.hpp:352
A new implementation of NetworkString, which has a fixed format: Byte 0: The type of the message,...
Definition: network_string.hpp:422
static void unitTesting()
Unit testing function.
Definition: network_string.cpp:30
NetworkString(const uint8_t *data, int len)
Constructor for a received message.
Definition: network_string.hpp:439
NetworkString(ProtocolType type, int capacity=16)
Constructor for a message to be sent.
Definition: network_string.hpp:429
void clear()
Empties the string, but does not reset the pre-allocated size.
Definition: network_string.hpp:447
void setSynchronous(bool b)
Sets if this message is to be sent synchronous or asynchronous.
Definition: network_string.hpp:461
ProtocolType getProtocolType() const
Returns the protocol type of this message.
Definition: network_string.hpp:454
bool isSynchronous() const
Returns if this message is synchronous or not.
Definition: network_string.hpp:470
A wrapper around bullets btVector3 to include conventient conversion functions (e....
Definition: vec3.hpp:35
Generic protocols declarations.
ProtocolType
The types that protocols can have.
Definition: protocol.hpp:43
@ PROTOCOL_SYNCHRONOUS
Flag, indicates synchronous delivery.
Definition: protocol.hpp:51
Declares the general types that are used by the network.