TrinityCore
Loading...
Searching...
No Matches
PacketUtilities.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 PacketUtilities_h__
19#define PacketUtilities_h__
20
21#include "ByteBuffer.h"
22#include "Tuples.h"
23#include <short_alloc/short_alloc.h>
24#include <string_view>
25
26namespace WorldPackets
27{
29 {
30 public:
31 InvalidStringValueException(std::string const& value);
32
33 std::string const& GetInvalidValue() const { return _value; }
34
35 private:
36 std::string _value;
37 };
38
40 {
41 public:
42 InvalidUtf8ValueException(std::string const& value);
43 };
44
46 {
47 public:
48 InvalidHyperlinkException(std::string const& value);
49 };
50
52 {
53 public:
54 IllegalHyperlinkException(std::string const& value);
55 };
56
57 namespace Strings
58 {
59 struct RawBytes { static bool Validate(std::string const& /*value*/) { return true; } };
60 template<std::size_t MaxBytesWithoutNullTerminator>
61 struct ByteSize { static bool Validate(std::string const& value) { return value.size() <= MaxBytesWithoutNullTerminator; } };
62 struct Utf8 { static bool Validate(std::string const& value); };
63 struct Hyperlinks { static bool Validate(std::string const& value); };
64 struct NoHyperlinks { static bool Validate(std::string const& value); };
65 }
66
70 template<std::size_t MaxBytesWithoutNullTerminator, typename... Validators>
71 class String
72 {
73 using ValidatorList = std::conditional_t<!Trinity::has_type<Strings::RawBytes, std::tuple<Validators...>>::value,
74 std::tuple<Strings::ByteSize<MaxBytesWithoutNullTerminator>, Strings::Utf8, Validators...>,
75 std::tuple<Strings::ByteSize<MaxBytesWithoutNullTerminator>, Validators...>>;
76
77 public:
78 bool empty() const { return _storage.empty(); }
79 char const* c_str() const { return _storage.c_str(); }
80
81 operator std::string_view() const { return _storage; }
82 operator std::string&() { return _storage; }
83 operator std::string const&() const { return _storage; }
84
85 std::string&& Move() { return std::move(_storage); }
86
87 friend ByteBuffer& operator>>(ByteBuffer& data, String& value)
88 {
89 value._storage = data.ReadCString(false);
90 value.Validate();
91 return data;
92 }
93
94 private:
95 bool Validate() const
96 {
97 return ValidateNth(std::make_index_sequence<std::tuple_size_v<ValidatorList>>{});
98 }
99
100 template<std::size_t... indexes>
101 bool ValidateNth(std::index_sequence<indexes...>) const
102 {
103 return (std::tuple_element_t<indexes, ValidatorList>::Validate(_storage) && ...);
104 }
105
106 std::string _storage;
107 };
108
110 {
111 public:
113 };
114
118 template<typename T, std::size_t N>
119 class Array
120 {
121 public:
122 using allocator_type = short_alloc::short_alloc<T, (N * sizeof(T) + (alignof(std::max_align_t) - 1)) & ~(alignof(std::max_align_t) - 1)>;
123 using arena_type = typename allocator_type::arena_type;
124
125 using storage_type = std::vector<T, allocator_type>;
126
127 using max_capacity = std::integral_constant<std::size_t, N>;
128
129 using value_type = typename storage_type::value_type;
130 using size_type = typename storage_type::size_type;
131 using pointer = typename storage_type::pointer;
132 using const_pointer = typename storage_type::const_pointer;
133 using reference = typename storage_type::reference;
134 using const_reference = typename storage_type::const_reference;
135 using iterator = typename storage_type::iterator;
136 using const_iterator = typename storage_type::const_iterator;
137
139
140 Array(Array const& other) : Array()
141 {
142 for (T const& element : other)
143 _storage.push_back(element);
144 }
145
146 Array(Array&& other) noexcept = delete;
147
149 {
150 if (this == &other)
151 return *this;
152
153 _storage.clear();
154 for (T const& element : other)
155 _storage.push_back(element);
156
157 return *this;
158 }
159
160 Array& operator=(Array&& other) noexcept = delete;
161
162 iterator begin() { return _storage.begin(); }
163 const_iterator begin() const { return _storage.begin(); }
164
165 iterator end() { return _storage.end(); }
166 const_iterator end() const { return _storage.end(); }
167
168 pointer data() { return _storage.data(); }
169 const_pointer data() const { return _storage.data(); }
170
171 size_type size() const { return _storage.size(); }
172 bool empty() const { return _storage.empty(); }
173
176
178 {
179 if (newSize > max_capacity::value)
180 throw PacketArrayMaxCapacityException(newSize, max_capacity::value);
181
182 _storage.resize(newSize);
183 }
184
185 void push_back(value_type const& value)
186 {
187 if (_storage.size() >= max_capacity::value)
188 throw PacketArrayMaxCapacityException(_storage.size() + 1, max_capacity::value);
189
190 _storage.push_back(value);
191 }
192
193 void push_back(value_type&& value)
194 {
195 if (_storage.size() >= max_capacity::value)
196 throw PacketArrayMaxCapacityException(_storage.size() + 1, max_capacity::value);
197
198 _storage.push_back(std::forward<value_type>(value));
199 }
200
201 template<typename... Args>
202 T& emplace_back(Args&&... args)
203 {
204 _storage.emplace_back(std::forward<Args>(args)...);
205 return _storage.back();
206 }
207
209 {
210 return _storage.erase(first, last);
211 }
212
213 void clear()
214 {
215 _storage.clear();
216 }
217
218 private:
221 };
222}
223
224#endif // PacketUtilities_h__
std::string ReadCString(bool requireValidUtf8=true)
typename storage_type::iterator iterator
short_alloc::short_alloc< T,(N *sizeof(T)+(alignof(std::max_align_t) - 1)) &~(alignof(std::max_align_t) - 1)> allocator_type
const_pointer data() const
iterator erase(const_iterator first, const_iterator last)
T & emplace_back(Args &&... args)
Array & operator=(Array &&other) noexcept=delete
std::vector< T, allocator_type > storage_type
typename storage_type::const_pointer const_pointer
typename storage_type::const_reference const_reference
void push_back(value_type const &value)
const_iterator end() const
typename storage_type::reference reference
typename storage_type::size_type size_type
Array & operator=(Array const &other)
typename storage_type::value_type value_type
const_reference operator[](size_type i) const
void push_back(value_type &&value)
Array(Array &&other) noexcept=delete
typename storage_type::const_iterator const_iterator
size_type size() const
typename storage_type::pointer pointer
std::integral_constant< std::size_t, N > max_capacity
typename allocator_type::arena_type arena_type
reference operator[](size_type i)
const_iterator begin() const
void resize(size_type newSize)
Array(Array const &other)
std::string const & GetInvalidValue() const
char const * c_str() const
std::conditional_t<!Trinity::has_type< Strings::RawBytes, std::tuple< Validators... > >::value, std::tuple< Strings::ByteSize< MaxBytesWithoutNullTerminator >, Strings::Utf8, Validators... >, std::tuple< Strings::ByteSize< MaxBytesWithoutNullTerminator >, Validators... > > ValidatorList
friend ByteBuffer & operator>>(ByteBuffer &data, String &value)
std::string && Move()
bool ValidateNth(std::index_sequence< indexes... >) const
static bool Validate(std::string const &value)
static bool Validate(std::string const &)
static bool Validate(std::string const &value)