BitStream
Loading...
Searching...
No Matches
string_traits.h
Go to the documentation of this file.
1#pragma once
2#include "../utility/assert.h"
3#include "../utility/bits.h"
4#include "../utility/meta.h"
5#include "../utility/parameter.h"
6
7#include "../stream/serialize_traits.h"
8
9#include <cstdint>
10#include <string>
11
12namespace bitstream
13{
17 template<typename T, size_t I>
19
20#pragma region const char*
24 template<>
25 struct serialize_traits<const char*>
26 {
34 template<typename Stream>
36 static serialize(Stream& writer, const char* value, uint32_t max_size) noexcept
37 {
38 uint32_t length = static_cast<uint32_t>(std::char_traits<char>::length(value));
39
40 BS_ASSERT(length < max_size);
41
42 if (length == 0)
43 return true;
44
45 uint32_t num_bits = utility::bits_to_represent(max_size);
46
47 BS_ASSERT(writer.serialize_bits(length, num_bits));
48
49 return writer.serialize_bytes(reinterpret_cast<const uint8_t*>(value), length * 8);
50 }
51
59 template<typename Stream>
61 static serialize(Stream& reader, char* value, uint32_t max_size) noexcept
62 {
63 uint32_t num_bits = utility::bits_to_represent(max_size);
64
65 uint32_t length;
66 BS_ASSERT(reader.serialize_bits(length, num_bits));
67
68 BS_ASSERT(length < max_size);
69
70 if (length == 0)
71 {
72 value[0] = '\0';
73 return true;
74 }
75
76 BS_ASSERT(reader.serialize_bytes(reinterpret_cast<uint8_t*>(value), length * 8));
77
78 value[length] = '\0';
79
80 return true;
81 }
82 };
83
88 template<size_t MaxSize>
89 struct serialize_traits<bounded_string<const char*, MaxSize>>
90 {
97 template<typename Stream>
99 static serialize(Stream& writer, const char* value) noexcept
100 {
101 uint32_t length = static_cast<uint32_t>(std::char_traits<char>::length(value));
102
103 BS_ASSERT(length < MaxSize);
104
105 if (length == 0)
106 return true;
107
108 constexpr uint32_t num_bits = utility::bits_to_represent(MaxSize);
109
110 BS_ASSERT(writer.serialize_bits(length, num_bits));
111
112 return writer.serialize_bytes(reinterpret_cast<const uint8_t*>(value), length * 8);
113 }
114
121 template<typename Stream>
123 static serialize(Stream& reader, char* value) noexcept
124 {
125 constexpr uint32_t num_bits = utility::bits_to_represent(MaxSize);
126
127 uint32_t length;
128 BS_ASSERT(reader.serialize_bits(length, num_bits));
129
130 BS_ASSERT(length < MaxSize);
131
132 if (length == 0)
133 {
134 value[0] = '\0';
135 return true;
136 }
137
138 BS_ASSERT(reader.serialize_bytes(reinterpret_cast<uint8_t*>(value), length * 8));
139
140 value[length] = '\0';
141
142 return true;
143 }
144 };
145#pragma endregion
146
147#ifdef __cpp_char8_t
151 template<>
152 struct serialize_traits<const char8_t*>
153 {
161 template<typename Stream>
162 typename utility::is_writing_t<Stream>
163 static serialize(Stream& writer, const char8_t* value, uint32_t max_size) noexcept
164 {
165 uint32_t length = static_cast<uint32_t>(std::char_traits<char8_t>::length(value));
166
167 BS_ASSERT(length < max_size);
168
169 if (length == 0)
170 return true;
171
172 uint32_t num_bits = utility::bits_to_represent(max_size);
173
174 BS_ASSERT(writer.serialize_bits(length, num_bits));
175
176 return writer.serialize_bytes(reinterpret_cast<const uint8_t*>(value), length * 8);
177 }
178
186 template<typename Stream>
187 typename utility::is_reading_t<Stream>
188 static serialize(Stream& reader, char8_t* value, uint32_t max_size) noexcept
189 {
190 uint32_t num_bits = utility::bits_to_represent(max_size);
191
192 uint32_t length;
193 BS_ASSERT(reader.serialize_bits(length, num_bits));
194
195 BS_ASSERT(length < max_size);
196
197 if (length == 0)
198 {
199 value[0] = '\0';
200 return true;
201 }
202
203 BS_ASSERT(reader.serialize_bytes(reinterpret_cast<uint8_t*>(value), length * 8));
204
205 value[length] = '\0';
206
207 return true;
208 }
209 };
210#endif
211
212#pragma region std::basic_string
219 template<typename T, typename Traits, typename Alloc>
220 struct serialize_traits<std::basic_string<T, Traits, Alloc>>
221 {
229 template<typename Stream>
231 static serialize(Stream& writer, in<std::basic_string<T, Traits, Alloc>> value, uint32_t max_size) noexcept
232 {
233 uint32_t length = static_cast<uint32_t>(value.size());
234
235 BS_ASSERT(length <= max_size);
236
237 uint32_t num_bits = utility::bits_to_represent(max_size);
238
239 BS_ASSERT(writer.serialize_bits(length, num_bits));
240
241 if (length == 0)
242 return true;
243
244 return writer.serialize_bytes(reinterpret_cast<const uint8_t*>(value.c_str()), length * sizeof(T) * 8);
245 }
246
254 template<typename Stream>
256 static serialize(Stream& reader, out<std::basic_string<T, Traits, Alloc>> value, uint32_t max_size)
257 {
258 uint32_t num_bits = utility::bits_to_represent(max_size);
259
260 uint32_t length;
261 BS_ASSERT(reader.serialize_bits(length, num_bits));
262
263 BS_ASSERT(length <= max_size);
264
265 if (length == 0)
266 {
267 value->clear();
268 return true;
269 }
270
271 value->resize(length);
272
273 BS_ASSERT(reader.serialize_bytes(reinterpret_cast<uint8_t*>(value->data()), length * sizeof(T) * 8));
274
275 return true;
276 }
277 };
278
286 template<typename T, typename Traits, typename Alloc, size_t MaxSize>
287 struct serialize_traits<bounded_string<std::basic_string<T, Traits, Alloc>, MaxSize>>
288 {
295 template<typename Stream>
297 static serialize(Stream& writer, in<std::basic_string<T, Traits, Alloc>> value) noexcept
298 {
299 uint32_t length = static_cast<uint32_t>(value.size());
300
301 BS_ASSERT(length <= MaxSize);
302
303 constexpr uint32_t num_bits = utility::bits_to_represent(MaxSize);
304
305 BS_ASSERT(writer.serialize_bits(length, num_bits));
306
307 if (length == 0)
308 return true;
309
310 return writer.serialize_bytes(reinterpret_cast<const uint8_t*>(value.c_str()), length * sizeof(T) * 8);
311 }
312
319 template<typename Stream>
321 static serialize(Stream& reader, out<std::basic_string<T, Traits, Alloc>> value)
322 {
323 constexpr uint32_t num_bits = utility::bits_to_represent(MaxSize);
324
325 uint32_t length;
326 BS_ASSERT(reader.serialize_bits(length, num_bits));
327
328 BS_ASSERT(length <= MaxSize);
329
330 if (length == 0)
331 {
332 value->clear();
333 return true;
334 }
335
336 value->resize(length);
337
338 BS_ASSERT(reader.serialize_bytes(reinterpret_cast<uint8_t*>(value->data()), length * sizeof(T) * 8));
339
340 return true;
341 }
342 };
343#pragma endregion
344}
#define BS_ASSERT(...)
Definition assert.h:15
Definition parameter.h:59
std::enable_if_t< T::writing, R > is_writing_t
Definition meta.h:25
constexpr uint32_t bits_to_represent(uintmax_t n)
Definition bits.h:8
std::enable_if_t< T::reading, R > is_reading_t
Definition meta.h:28
Definition bounded_range.h:28
std::conditional_t<(sizeof(T)<=16 &&std::is_trivially_copy_constructible_v< T >), std::add_const_t< T >, std::add_lvalue_reference_t< std::add_const_t< T > > > in
Passes by const or const reference depending on size.
Definition parameter.h:89
Wrapper type for compiletime known string max_size.
Definition string_traits.h:18
static utility::is_reading_t< Stream > serialize(Stream &reader, char *value) noexcept
Read a c-style string from the reader into value.
Definition string_traits.h:123
static utility::is_writing_t< Stream > serialize(Stream &writer, const char *value) noexcept
Writes a c-style string into the writer.
Definition string_traits.h:99
static utility::is_writing_t< Stream > serialize(Stream &writer, in< std::basic_string< T, Traits, Alloc > > value) noexcept
Writes a string into the writer.
Definition string_traits.h:297
static utility::is_reading_t< Stream > serialize(Stream &reader, out< std::basic_string< T, Traits, Alloc > > value)
Reads a string from the reader into value.
Definition string_traits.h:321
static utility::is_writing_t< Stream > serialize(Stream &writer, const char *value, uint32_t max_size) noexcept
Writes a c-style string into the writer.
Definition string_traits.h:36
static utility::is_reading_t< Stream > serialize(Stream &reader, char *value, uint32_t max_size) noexcept
Read a c-style string from the reader into value.
Definition string_traits.h:61
static utility::is_writing_t< Stream > serialize(Stream &writer, in< std::basic_string< T, Traits, Alloc > > value, uint32_t max_size) noexcept
Writes a string into the writer.
Definition string_traits.h:231
static utility::is_reading_t< Stream > serialize(Stream &reader, out< std::basic_string< T, Traits, Alloc > > value, uint32_t max_size)
Reads a string from the reader into value.
Definition string_traits.h:256
A class for specializing trait serialization functions.
Definition serialize_traits.h:11