TrinityCore
Loading...
Searching...
No Matches
ByteBuffer.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef _BYTEBUFFER_H
19#define _BYTEBUFFER_H
20
21#include "Define.h"
22#include "ByteConverter.h"
23#include <array>
24#include <string>
25#include <vector>
26#include <cstring>
27
28class MessageBuffer;
29
30// Root of ByteBuffer exception hierarchy
31class TC_SHARED_API ByteBufferException : public std::exception
32{
33public:
34 ~ByteBufferException() noexcept = default;
35
36 char const* what() const noexcept override { return msg_.c_str(); }
37
38protected:
39 std::string & message() noexcept { return msg_; }
40
41private:
42 std::string msg_;
43};
44
46{
47public:
48 ByteBufferPositionException(bool add, size_t pos, size_t size, size_t valueSize);
49
50 ~ByteBufferPositionException() noexcept = default;
51};
52
54{
55public:
56 ByteBufferSourceException(size_t pos, size_t size, size_t valueSize);
57
58 ~ByteBufferSourceException() noexcept = default;
59};
60
62{
63public:
64 ByteBufferInvalidValueException(char const* type, char const* value);
65
67};
68
70{
71 public:
72 constexpr static size_t DEFAULT_SIZE = 0x1000;
73
74 // constructor
75 ByteBuffer() : _rpos(0), _wpos(0)
76 {
77 _storage.reserve(DEFAULT_SIZE);
78 }
79
80 ByteBuffer(size_t reserve) : _rpos(0), _wpos(0)
81 {
82 _storage.reserve(reserve);
83 }
84
85 ByteBuffer(ByteBuffer&& buf) noexcept : _rpos(buf._rpos), _wpos(buf._wpos), _storage(std::move(buf._storage))
86 {
87 buf._rpos = 0;
88 buf._wpos = 0;
89 }
90
91 ByteBuffer(ByteBuffer const& right) = default;
92
93 ByteBuffer(MessageBuffer&& buffer);
94
96 {
97 if (this != &right)
98 {
99 _rpos = right._rpos;
100 _wpos = right._wpos;
101 _storage = right._storage;
102 }
103
104 return *this;
105 }
106
107 ByteBuffer& operator=(ByteBuffer&& right) noexcept
108 {
109 if (this != &right)
110 {
111 _rpos = right._rpos;
112 right._rpos = 0;
113 _wpos = right._wpos;
114 right._wpos = 0;
115 _storage = std::move(right._storage);
116 }
117
118 return *this;
119 }
120
121 virtual ~ByteBuffer() = default;
122
123 void clear()
124 {
125 _storage.clear();
126 _rpos = _wpos = 0;
127 }
128
129 template <typename T> void append(T value)
130 {
131 static_assert(std::is_fundamental<T>::value, "append(compound)");
132 EndianConvert(value);
133 append((uint8 *)&value, sizeof(value));
134 }
135
136 template <typename T>
137 void put(std::size_t pos, T value)
138 {
139 static_assert(std::is_fundamental<T>::value, "append(compound)");
140 EndianConvert(value);
141 put(pos, (uint8 *)&value, sizeof(value));
142 }
143
145 {
146 append<uint8>(value ? 1 : 0);
147 return *this;
148 }
149
151 {
152 append<uint8>(value);
153 return *this;
154 }
155
157 {
158 append<uint16>(value);
159 return *this;
160 }
161
163 {
164 append<uint32>(value);
165 return *this;
166 }
167
169 {
170 append<uint64>(value);
171 return *this;
172 }
173
174 // signed as in 2e complement
176 {
177 append<int8>(value);
178 return *this;
179 }
180
182 {
183 append<int16>(value);
184 return *this;
185 }
186
188 {
189 append<int32>(value);
190 return *this;
191 }
192
194 {
195 append<int64>(value);
196 return *this;
197 }
198
199 // floating points
200 ByteBuffer &operator<<(float value)
201 {
202 append<float>(value);
203 return *this;
204 }
205
206 ByteBuffer &operator<<(double value)
207 {
208 append<double>(value);
209 return *this;
210 }
211
212 ByteBuffer &operator<<(std::string_view value)
213 {
214 if (size_t len = value.length())
215 append(reinterpret_cast<uint8 const*>(value.data()), len);
216 append(static_cast<uint8>(0));
217 return *this;
218 }
219
220 ByteBuffer& operator<<(std::string const& str)
221 {
222 return operator<<(std::string_view(str));
223 }
224
225 ByteBuffer &operator<<(char const* str)
226 {
227 return operator<<(std::string_view(str ? str : ""));
228 }
229
230 ByteBuffer &operator>>(bool &value)
231 {
232 value = read<char>() > 0 ? true : false;
233 return *this;
234 }
235
237 {
238 value = read<uint8>();
239 return *this;
240 }
241
243 {
244 value = read<uint16>();
245 return *this;
246 }
247
249 {
250 value = read<uint32>();
251 return *this;
252 }
253
255 {
256 value = read<uint64>();
257 return *this;
258 }
259
260 //signed as in 2e complement
262 {
263 value = read<int8>();
264 return *this;
265 }
266
268 {
269 value = read<int16>();
270 return *this;
271 }
272
274 {
275 value = read<int32>();
276 return *this;
277 }
278
280 {
281 value = read<int64>();
282 return *this;
283 }
284
285 ByteBuffer &operator>>(float &value);
286 ByteBuffer &operator>>(double &value);
287
288 ByteBuffer& operator>>(std::string& value)
289 {
290 value = ReadCString(true);
291 return *this;
292 }
293
294 uint8& operator[](size_t const pos)
295 {
296 if (pos >= size())
297 throw ByteBufferPositionException(false, pos, 1, size());
298 return _storage[pos];
299 }
300
301 uint8 const& operator[](size_t const pos) const
302 {
303 if (pos >= size())
304 throw ByteBufferPositionException(false, pos, 1, size());
305 return _storage[pos];
306 }
307
308 size_t rpos() const { return _rpos; }
309
310 size_t rpos(size_t rpos_)
311 {
312 _rpos = rpos_;
313 return _rpos;
314 }
315
316 void rfinish()
317 {
318 _rpos = wpos();
319 }
320
321 size_t wpos() const { return _wpos; }
322
323 size_t wpos(size_t wpos_)
324 {
325 _wpos = wpos_;
326 return _wpos;
327 }
328
329 template<typename T>
330 void read_skip() { read_skip(sizeof(T)); }
331
332 void read_skip(size_t skip)
333 {
334 if (_rpos + skip > size())
335 throw ByteBufferPositionException(false, _rpos, skip, size());
336 _rpos += skip;
337 }
338
339 template <typename T> T read()
340 {
341 T r = read<T>(_rpos);
342 _rpos += sizeof(T);
343 return r;
344 }
345
346 template <typename T> T read(size_t pos) const
347 {
348 if (pos + sizeof(T) > size())
349 throw ByteBufferPositionException(false, pos, sizeof(T), size());
350 T val = *((T const*)&_storage[pos]);
351 EndianConvert(val);
352 return val;
353 }
354
355 void read(uint8 *dest, size_t len)
356 {
357 if (_rpos + len > size())
358 throw ByteBufferPositionException(false, _rpos, len, size());
359 std::memcpy(dest, &_storage[_rpos], len);
360 _rpos += len;
361 }
362
363 template <size_t Size>
364 void read(std::array<uint8, Size>& arr)
365 {
366 read(arr.data(), Size);
367 }
368
370 {
371 if (rpos() + 1 > size())
372 throw ByteBufferPositionException(false, _rpos, 1, size());
373
374 guid = 0;
375
376 uint8 guidmark = 0;
377 (*this) >> guidmark;
378
379 for (int i = 0; i < 8; ++i)
380 {
381 if (guidmark & (uint8(1) << i))
382 {
383 if (rpos() + 1 > size())
384 throw ByteBufferPositionException(false, _rpos, 1, size());
385
386 uint8 bit;
387 (*this) >> bit;
388 guid |= (uint64(bit) << (i * 8));
389 }
390 }
391 }
392
393 std::string ReadCString(bool requireValidUtf8 = true);
394
396 {
397 if (_storage.empty())
398 throw ByteBufferException();
399 return _storage.data();
400 }
401
402 uint8 const* contents() const
403 {
404 if (_storage.empty())
405 throw ByteBufferException();
406 return _storage.data();
407 }
408
409 size_t size() const { return _storage.size(); }
410 bool empty() const { return _storage.empty(); }
411
412 void resize(size_t newsize)
413 {
414 _storage.resize(newsize, 0);
415 _rpos = 0;
416 _wpos = size();
417 }
418
419 void reserve(size_t ressize)
420 {
421 if (ressize > size())
422 _storage.reserve(ressize);
423 }
424
426 {
427 _storage.shrink_to_fit();
428 }
429
430 void append(const char *src, size_t cnt)
431 {
432 return append((const uint8 *)src, cnt);
433 }
434
435 template<class T> void append(const T *src, size_t cnt)
436 {
437 return append((const uint8 *)src, cnt * sizeof(T));
438 }
439
440 void append(uint8 const* src, size_t cnt);
441
442 void append(ByteBuffer const& buffer)
443 {
444 if (buffer.wpos())
445 append(buffer.contents(), buffer.wpos());
446 }
447
448 template <size_t Size>
449 void append(std::array<uint8, Size> const& arr)
450 {
451 append(arr.data(), Size);
452 }
453
454 // can be used in SMSG_MONSTER_MOVE opcode
455 void appendPackXYZ(float x, float y, float z)
456 {
457 uint32 packed = 0;
458 packed |= ((int)(x / 0.25f) & 0x7FF);
459 packed |= ((int)(y / 0.25f) & 0x7FF) << 11;
460 packed |= ((int)(z / 0.25f) & 0x3FF) << 22;
461 *this << packed;
462 }
463
465 {
466 uint8 packGUID[8+1];
467 packGUID[0] = 0;
468 size_t size = 1;
469 for (uint8 i = 0;guid != 0;++i)
470 {
471 if (guid & 0xFF)
472 {
473 packGUID[0] |= uint8(1 << i);
474 packGUID[size] = uint8(guid & 0xFF);
475 ++size;
476 }
477
478 guid >>= 8;
479 }
480 append(packGUID, size);
481 }
482
483 void put(size_t pos, const uint8 *src, size_t cnt);
484
485 void print_storage() const;
486
487 void textlike() const;
488
489 void hexlike() const;
490
491 protected:
492 size_t _rpos, _wpos;
493 std::vector<uint8> _storage;
494};
495
497template<> inline std::string ByteBuffer::read<std::string>()
498{
499 std::string tmp;
500 *this >> tmp;
501 return tmp;
502}
503
504template<>
505inline void ByteBuffer::read_skip<char*>()
506{
507 std::string temp;
508 *this >> temp;
509}
510
511template<>
512inline void ByteBuffer::read_skip<char const*>()
513{
514 read_skip<char*>();
515}
516
517template<>
518inline void ByteBuffer::read_skip<std::string>()
519{
520 read_skip<char*>();
521}
522
523#endif
void EndianConvert(T &val)
uint8_t uint8
Definition Define.h:135
#define TC_SHARED_API
Definition Define.h:108
int64_t int64
Definition Define.h:128
int16_t int16
Definition Define.h:130
int8_t int8
Definition Define.h:131
int32_t int32
Definition Define.h:129
uint64_t uint64
Definition Define.h:132
uint16_t uint16
Definition Define.h:134
uint32_t uint32
Definition Define.h:133
ByteBuffer & operator<<(ByteBuffer &buf, ObjectGuid const &guid)
ByteBuffer & operator>>(ByteBuffer &buf, ObjectGuid &guid)
std::string msg_
Definition ByteBuffer.h:42
~ByteBufferException() noexcept=default
std::string & message() noexcept
Definition ByteBuffer.h:39
~ByteBufferInvalidValueException() noexcept=default
~ByteBufferPositionException() noexcept=default
~ByteBufferSourceException() noexcept=default
ByteBuffer & operator<<(bool value)
Definition ByteBuffer.h:144
void append(std::array< uint8, Size > const &arr)
Definition ByteBuffer.h:449
size_t _wpos
Definition ByteBuffer.h:492
void read(std::array< uint8, Size > &arr)
Definition ByteBuffer.h:364
ByteBuffer & operator<<(uint32 value)
Definition ByteBuffer.h:162
ByteBuffer & operator>>(int64 &value)
Definition ByteBuffer.h:279
void read_skip()
Definition ByteBuffer.h:330
ByteBuffer & operator<<(double value)
Definition ByteBuffer.h:206
ByteBuffer & operator<<(std::string const &str)
Definition ByteBuffer.h:220
ByteBuffer(size_t reserve)
Definition ByteBuffer.h:80
void appendPackXYZ(float x, float y, float z)
Definition ByteBuffer.h:455
ByteBuffer & operator>>(uint32 &value)
Definition ByteBuffer.h:248
size_t rpos() const
Definition ByteBuffer.h:308
ByteBuffer & operator<<(uint8 value)
Definition ByteBuffer.h:150
std::vector< uint8 > _storage
Definition ByteBuffer.h:493
ByteBuffer & operator<<(int32 value)
Definition ByteBuffer.h:187
void reserve(size_t ressize)
Definition ByteBuffer.h:419
uint8 const * contents() const
Definition ByteBuffer.h:402
ByteBuffer & operator=(ByteBuffer const &right)
Definition ByteBuffer.h:95
void appendPackGUID(uint64 guid)
Definition ByteBuffer.h:464
ByteBuffer & operator<<(int64 value)
Definition ByteBuffer.h:193
ByteBuffer & operator<<(std::string_view value)
Definition ByteBuffer.h:212
T read(size_t pos) const
Definition ByteBuffer.h:346
void resize(size_t newsize)
Definition ByteBuffer.h:412
ByteBuffer & operator>>(int16 &value)
Definition ByteBuffer.h:267
void read_skip(size_t skip)
Definition ByteBuffer.h:332
void shrink_to_fit()
Definition ByteBuffer.h:425
ByteBuffer & operator>>(uint8 &value)
Definition ByteBuffer.h:236
void append(T value)
Definition ByteBuffer.h:129
ByteBuffer & operator<<(float value)
Definition ByteBuffer.h:200
void append(const T *src, size_t cnt)
Definition ByteBuffer.h:435
ByteBuffer & operator>>(int8 &value)
Definition ByteBuffer.h:261
ByteBuffer & operator>>(uint16 &value)
Definition ByteBuffer.h:242
void rfinish()
Definition ByteBuffer.h:316
uint8 & operator[](size_t const pos)
Definition ByteBuffer.h:294
uint8 const & operator[](size_t const pos) const
Definition ByteBuffer.h:301
ByteBuffer & operator<<(uint16 value)
Definition ByteBuffer.h:156
size_t wpos() const
Definition ByteBuffer.h:321
void append(ByteBuffer const &buffer)
Definition ByteBuffer.h:442
ByteBuffer & operator>>(std::string &value)
Definition ByteBuffer.h:288
ByteBuffer & operator=(ByteBuffer &&right) noexcept
Definition ByteBuffer.h:107
size_t rpos(size_t rpos_)
Definition ByteBuffer.h:310
void put(std::size_t pos, T value)
Definition ByteBuffer.h:137
ByteBuffer(ByteBuffer &&buf) noexcept
Definition ByteBuffer.h:85
ByteBuffer & operator>>(int32 &value)
Definition ByteBuffer.h:273
void clear()
Definition ByteBuffer.h:123
ByteBuffer & operator<<(uint64 value)
Definition ByteBuffer.h:168
ByteBuffer & operator<<(int16 value)
Definition ByteBuffer.h:181
size_t size() const
Definition ByteBuffer.h:409
bool empty() const
Definition ByteBuffer.h:410
ByteBuffer(ByteBuffer const &right)=default
size_t _rpos
Definition ByteBuffer.h:492
void readPackGUID(uint64 &guid)
Definition ByteBuffer.h:369
size_t wpos(size_t wpos_)
Definition ByteBuffer.h:323
ByteBuffer & operator<<(int8 value)
Definition ByteBuffer.h:175
void append(const char *src, size_t cnt)
Definition ByteBuffer.h:430
ByteBuffer & operator>>(bool &value)
Definition ByteBuffer.h:230
uint8 * contents()
Definition ByteBuffer.h:395
ByteBuffer & operator>>(uint64 &value)
Definition ByteBuffer.h:254
ByteBuffer & operator<<(char const *str)
Definition ByteBuffer.h:225
virtual ~ByteBuffer()=default
void read(uint8 *dest, size_t len)
Definition ByteBuffer.h:355