TrinityCore
Loading...
Searching...
No Matches
ByteBuffer.cpp
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#include "ByteBuffer.h"
19#include "Errors.h"
20#include "Log.h"
21#include <utf8.h>
22#include <algorithm>
23#include <sstream>
24#include <cmath>
25
26ByteBufferPositionException::ByteBufferPositionException(size_t pos, size_t size, size_t valueSize)
27 : ByteBufferException(Trinity::StringFormat("Attempted to get value with size: {} in ByteBuffer (pos: {} size: {})", valueSize, pos, size))
28{
29}
30
32 : ByteBufferException(Trinity::StringFormat("Invalid {} value ({}) found in ByteBuffer", type, value))
33{
34}
35
37{
38 read(&value, 1);
39 if (!std::isfinite(value))
40 throw ByteBufferInvalidValueException("float", "infinity");
41 return *this;
42}
43
45{
46 read(&value, 1);
47 if (!std::isfinite(value))
48 throw ByteBufferInvalidValueException("double", "infinity");
49 return *this;
50}
51
52std::string_view ByteBuffer::ReadCString(bool requireValidUtf8 /*= true*/)
53{
54 if (_rpos >= size())
56
58
59 char const* begin = reinterpret_cast<char const*>(_storage.data()) + _rpos;
60 char const* end = reinterpret_cast<char const*>(_storage.data()) + size();
61 char const* stringEnd = std::ranges::find(begin, end, '\0');
62 if (stringEnd == end)
64
65 std::string_view value(begin, stringEnd);
66 _rpos += value.length() + 1;
67 if (requireValidUtf8 && !utf8::is_valid(value.begin(), value.end()))
68 throw ByteBufferInvalidValueException("utf8 string", value);
69 return value;
70}
71
72std::string_view ByteBuffer::ReadString(uint32 length, bool requireValidUtf8 /*= true*/)
73{
74 if (_rpos + length > size())
75 throw ByteBufferPositionException(_rpos, length, size());
76
78 if (!length)
79 return {};
80
81 std::string_view value(reinterpret_cast<char const*>(&_storage[_rpos]), length);
82 _rpos += length;
83 if (requireValidUtf8 && !utf8::is_valid(value.begin(), value.end()))
84 throw ByteBufferInvalidValueException("utf8 string", value);
85 return value;
86}
87
88void ByteBuffer::append(uint8 const* src, size_t cnt)
89{
90 ASSERT(src, "Attempted to put a NULL-pointer in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", _wpos, size());
91 ASSERT(cnt, "Attempted to put a zero-sized value in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", _wpos, size());
92 ASSERT((size() + cnt) < 100000000);
93
94 FlushBits();
95
96 size_t const newSize = _wpos + cnt;
97 if (_storage.capacity() < newSize) // custom memory allocation rules
98 {
99 if (newSize < 100)
100 _storage.reserve(300);
101 else if (newSize < 750)
102 _storage.reserve(2500);
103 else if (newSize < 6000)
104 _storage.reserve(10000);
105 else
106 _storage.reserve(400000);
107 }
108
109 if (_storage.size() < newSize)
110 _storage.resize(newSize);
111 std::memcpy(&_storage[_wpos], src, cnt);
112 _wpos = newSize;
113}
114
115void ByteBuffer::put(size_t pos, uint8 const* src, size_t cnt)
116{
117 ASSERT(pos + cnt <= size(), "Attempted to put value with size: " SZFMTD " in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", cnt, pos, size());
118 ASSERT(src, "Attempted to put a NULL-pointer in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", pos, size());
119 ASSERT(cnt, "Attempted to put a zero-sized value in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", pos, size());
120
121 std::memcpy(&_storage[pos], src, cnt);
122}
123
124void ByteBuffer::PutBits(std::size_t pos, std::size_t value, uint32 bitCount)
125{
126 ASSERT(pos + bitCount <= size() * 8, "Attempted to put %u bits in ByteBuffer (bitpos: " SZFMTD " size: " SZFMTD ")", bitCount, pos, size());
127 ASSERT(bitCount, "Attempted to put a zero bits in ByteBuffer");
128
129 for (uint32 i = 0; i < bitCount; ++i)
130 {
131 std::size_t wp = (pos + i) / 8;
132 std::size_t bit = (pos + i) % 8;
133 if ((value >> (bitCount - i - 1)) & 1)
134 _storage[wp] |= 1 << (7 - bit);
135 else
136 _storage[wp] &= ~(1 << (7 - bit));
137 }
138}
139
141{
142 Logger const* networkLogger = sLog->GetEnabledLogger("network", LOG_LEVEL_TRACE);
143 if (!networkLogger) // optimize disabled trace output
144 return;
145
146 std::ostringstream o;
147 for (uint32 i = 0; i < size(); ++i)
148 o << uint32(_storage[i]) << " - ";
149
150 TC_LOG_TRACE("network", "STORAGE_SIZE: {} {}", size(), o.view());
151}
152
154{
155 Logger const* networkLogger = sLog->GetEnabledLogger("network", LOG_LEVEL_TRACE);
156 if (networkLogger) // optimize disabled trace output
157 return;
158
159 std::ostringstream o;
160 for (uint32 i = 0; i < size(); ++i)
161 o << char(_storage[i]);
162
163 sLog->OutMessageTo(networkLogger, "network", LOG_LEVEL_TRACE, "STORAGE_SIZE: {} {}", size(), o.view());
164}
165
167{
168 Logger const* networkLogger = sLog->GetEnabledLogger("network", LOG_LEVEL_TRACE);
169 if (!networkLogger) // optimize disabled trace output
170 return;
171
172 std::ostringstream o;
173 o.setf(std::ios_base::hex, std::ios_base::basefield);
174 o.fill('0');
175
176 for (uint32 i = 0; i < size(); )
177 {
178 char const* sep = " | ";
179 for (uint32 j = 0; j < 2; ++j)
180 {
181 for (uint32 k = 0; k < 8; ++k)
182 {
183 o.width(2);
184 o << _storage[i];
185 ++i;
186 }
187
188 o << sep;
189 sep = "\n";
190 }
191 }
192
193 sLog->OutMessageTo(networkLogger, "network", LOG_LEVEL_TRACE, "STORAGE_SIZE: {} {}", size(), o.view());
194}
195
196void ByteBuffer::OnInvalidPosition(size_t pos, size_t valueSize) const
197{
198 throw ByteBufferPositionException(pos, _storage.size(), valueSize);
199}
200
201template TC_SHARED_API char ByteBuffer::read<char>();
202template TC_SHARED_API uint8 ByteBuffer::read<uint8>();
203template TC_SHARED_API uint16 ByteBuffer::read<uint16>();
204template TC_SHARED_API uint32 ByteBuffer::read<uint32>();
205template TC_SHARED_API uint64 ByteBuffer::read<uint64>();
206template TC_SHARED_API int8 ByteBuffer::read<int8>();
207template TC_SHARED_API int16 ByteBuffer::read<int16>();
208template TC_SHARED_API int32 ByteBuffer::read<int32>();
209template TC_SHARED_API int64 ByteBuffer::read<int64>();
210template TC_SHARED_API float ByteBuffer::read<float>();
211template TC_SHARED_API double ByteBuffer::read<double>();
uint8_t uint8
Definition Define.h:156
#define TC_SHARED_API
Definition Define.h:123
int64_t int64
Definition Define.h:149
int16_t int16
Definition Define.h:151
int8_t int8
Definition Define.h:152
int32_t int32
Definition Define.h:150
uint64_t uint64
Definition Define.h:153
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
#define SZFMTD
Definition Define.h:144
#define ASSERT
Definition Errors.h:80
@ LOG_LEVEL_TRACE
Definition LogCommon.h:27
#define sLog
Definition Log.h:156
#define TC_LOG_TRACE(filterType__, message__,...)
Definition Log.h:178
ByteBufferInvalidValueException(char const *type, std::string_view value)
ByteBufferPositionException(size_t pos, size_t size, size_t valueSize)
size_t _wpos
Definition ByteBuffer.h:625
std::vector< uint8 > _storage
Definition ByteBuffer.h:628
void PutBits(std::size_t pos, std::size_t value, uint32 bitCount)
void hexlike() const
void print_storage() const
void OnInvalidPosition(size_t pos, size_t valueSize) const
void append(T value)
Definition ByteBuffer.h:130
std::string_view ReadCString(bool requireValidUtf8=true)
void ResetBitPos()
Definition ByteBuffer.h:152
ByteBuffer & operator>>(bool &)=delete
void textlike() const
std::string_view ReadString(uint32 length, bool requireValidUtf8=true)
void put(std::size_t pos, T value)
Definition ByteBuffer.h:260
size_t size() const
Definition ByteBuffer.h:568
void FlushBits()
Definition ByteBuffer.h:141
size_t _rpos
Definition ByteBuffer.h:625