Go to the documentation of this file.
9 #ifndef EAGINE_SERIALIZE_STRING_BACKEND_HPP
10 #define EAGINE_SERIALIZE_STRING_BACKEND_HPP
18 EAGINE_DIAG_OFF(
format-nonliteral)
28 common_serializer_backend<string_serializer_backend>,
29 EAGINE_ID_V(String)> {
36 using base::remaining_size;
45 for(
auto& val : values) {
114 return sink(
"false");
117 auto _write_one(
char value, type_identity<char>) -> result {
118 result errors =
sink(
'\'');
119 errors |=
sink(value);
120 errors |=
sink(
'\'');
124 template <
typename T, std::
size_t L>
125 auto _sprintf_one(T value,
const char (&fmt)[L]) -> result {
126 std::array<char, 64> temp{};
130 temp.data(), temp.size(),
static_cast<const char*
>(fmt), value);
134 auto _write_one(
byte value, type_identity<byte>) -> result {
135 return _sprintf_one(value,
"%02hhx");
138 auto _write_one(
signed char value, type_identity<signed char>) -> result {
139 return _sprintf_one(value,
"%hhd");
142 auto _write_one(
short value, type_identity<short>) -> result {
143 return _sprintf_one(value,
"%hd");
146 auto _write_one(
unsigned short value, type_identity<unsigned short>)
148 return _sprintf_one(value,
"%hu");
151 auto _write_one(
int value, type_identity<int>) -> result {
152 return _sprintf_one(value,
"%d");
155 auto _write_one(
unsigned value, type_identity<unsigned>) -> result {
156 return _sprintf_one(value,
"%u");
159 auto _write_one(
long value, type_identity<long>) -> result {
160 return _sprintf_one(value,
"%ld");
163 auto _write_one(
unsigned long value, type_identity<unsigned long>)
165 return _sprintf_one(value,
"%lu");
168 auto _write_one(
long long value, type_identity<long long>) -> result {
169 return _sprintf_one(value,
"%lld");
172 auto _write_one(
unsigned long long value, type_identity<unsigned long long>)
174 return _sprintf_one(value,
"%llu");
177 auto _write_one(
float value, type_identity<float>) -> result {
178 return _sprintf_one(value,
"%f");
181 auto _write_one(
double value, type_identity<double>) -> result {
182 return _sprintf_one(value,
"%lf");
185 auto _write_one(
identifier id, type_identity<identifier>) -> result {
189 auto _write_one(decl_name name, type_identity<decl_name>) -> result {
193 auto _write_one(
string_view str, type_identity<string_view>) -> result {
194 result errors =
sink(
'"');
195 errors |= _write_one(str.size(), type_identity<span_size_t>{});
208 common_deserializer_backend<string_deserializer_backend>,
209 EAGINE_ID_V(String)> {
216 using base::consume_until;
221 template <
typename T>
225 for(T& val : values) {
226 errors |= _read_one(val,
';');
240 void skip_whitespaces() {
241 consume_until([](
byte b) {
return !std::isspace(b); });
250 result errors = require(
'{');
252 errors |= _read_one(count,
'|');
258 result errors = require(name);
260 errors |= require(
':');
270 return require(
"};");
274 result errors = require(
'[');
276 errors |= _read_one(count,
'|');
290 return require(
"];");
294 return require(
">\0");
298 auto _read_one(
bool& value,
char delimiter) -> result {
300 if(this->consume(
"true", temp)) {
302 }
else if(this->consume(
"false", temp)) {
307 return require(delimiter);
310 auto _read_one(
char& value,
char delimiter) -> result {
311 result errors = require(
'\'');
313 if(
auto opt_char = this->top_char()) {
317 errors |= error_code::not_enough_data;
320 const char t[3] = {
'\'', delimiter,
'\0'};
327 template <
typename T, std::
size_t L>
328 auto _sscanf_one(T& value,
char delimiter,
const char (&fmt)[L]) -> result {
330 if(
auto src = this->string_before(delimiter, 128)) {
331 auto fmtstr =
static_cast<const char*
>(fmt);
334 if(std::sscanf(src.data(), fmtstr, &value) == 1) {
337 errors |= error_code::invalid_format;
340 errors |= error_code::not_enough_data;
345 auto _read_one(
byte& value,
char delimiter) -> result {
346 const char fmt[6] = {
'%',
'h',
'h',
'x', delimiter,
'\0'};
347 return _sscanf_one(value, delimiter, fmt);
350 auto _read_one(
signed char& value,
char delimiter) -> result {
351 const char fmt[6] = {
'%',
'h',
'h',
'd', delimiter,
'\0'};
352 return _sscanf_one(value, delimiter, fmt);
355 auto _read_one(
short& value,
char delimiter) -> result {
356 const char fmt[5] = {
'%',
'h',
'd', delimiter,
'\0'};
357 return _sscanf_one(value, delimiter, fmt);
360 auto _read_one(
unsigned short& value,
char delimiter) -> result {
361 const char fmt[5] = {
'%',
'h',
'u', delimiter,
'\0'};
362 return _sscanf_one(value, delimiter, fmt);
365 auto _read_one(
int& value,
char delimiter) -> result {
366 const char fmt[4] = {
'%',
'd', delimiter,
'\0'};
367 return _sscanf_one(value, delimiter, fmt);
370 auto _read_one(
unsigned& value,
char delimiter) -> result {
371 const char fmt[4] = {
'%',
'u', delimiter,
'\0'};
372 return _sscanf_one(value, delimiter, fmt);
375 auto _read_one(
long& value,
char delimiter) -> result {
376 const char fmt[5] = {
'%',
'l',
'd', delimiter,
'\0'};
377 return _sscanf_one(value, delimiter, fmt);
380 auto _read_one(
unsigned long& value,
char delimiter) -> result {
381 const char fmt[5] = {
'%',
'l',
'u', delimiter,
'\0'};
382 return _sscanf_one(value, delimiter, fmt);
385 auto _read_one(
long long& value,
char delimiter) -> result {
386 const char fmt[6] = {
'%',
'l',
'l',
'd', delimiter,
'\0'};
387 return _sscanf_one(value, delimiter, fmt);
390 auto _read_one(
unsigned long long& value,
char delimiter) -> result {
391 const char fmt[6] = {
'%',
'l',
'l',
'u', delimiter,
'\0'};
392 return _sscanf_one(value, delimiter, fmt);
395 auto _read_one(
float& value,
char delimiter) -> result {
396 const char fmt[4] = {
'%',
'f', delimiter,
'\0'};
397 return _sscanf_one(value, delimiter, fmt);
400 auto _read_one(
double& value,
char delimiter) -> result {
401 const char fmt[5] = {
'%',
'l',
'f', delimiter,
'\0'};
402 return _sscanf_one(value, delimiter, fmt);
405 auto _read_one(
identifier& value,
char delimiter) -> result {
407 if(
auto src = this->string_before(delimiter, 32)) {
411 errors |= error_code::not_enough_data;
416 auto _read_one(decl_name_storage& value,
char delimiter) -> result {
418 const auto max = decl_name_storage::max_length + 1;
419 if(
auto src = this->string_before(delimiter, max)) {
423 errors |= error_code::not_enough_data;
428 auto _read_one(std::string& value,
char delimiter) -> result {
429 result errors = require(
'"');
432 errors |= _read_one(len,
'|');
434 auto str = this->top_string(len);
435 if(str.size() < len) {
436 errors |= error_code::not_enough_data;
440 errors |= require(
'"');
441 errors |= require(delimiter);
455 #endif // EAGINE_SERIALIZE_STRING_BACKEND_HPP
Base class partially implementing serializer and deserialized backends.
Definition: write_backend.hpp:287
Cross-platform implementation of deserializer backend using ASCII-only strings.
Definition: string_backend.hpp:206
std::ptrdiff_t span_size_t
Signed span size type used by eagine.
Definition: types.hpp:36
basic_string_span< const char > string_view
Alias for const string views.
Definition: string_span.hpp:116
#define EAGINE_ID_V(NAME)
Macro for constructing instances of eagine::identifier_t.
Definition: identifier.hpp:359
auto begin_struct(span_size_t count) -> result final
Begins the serialization of a structure instance.
Definition: string_backend.hpp:65
Common code is placed in this namespace.
Definition: eagine.hpp:21
auto begin_list(span_size_t count) -> result final
Begins the serialization of a container instance.
Definition: string_backend.hpp:86
auto sink() -> serializer_data_sink *final
Definition: write_backend.hpp:143
static constexpr auto extract(api_result_value< Result, api_result_validity::never > &) noexcept -> Result &
Overload of extract for api_result_value.
Definition: c_api_wrap.hpp:270
auto finish() -> result final
Finishes the deserialization of a potentially complex structured value.
Definition: string_backend.hpp:293
auto begin_member(string_view name) -> result final
Begins the serialization of a structure data member.
Definition: string_backend.hpp:72
Class for manipulating and testing a group of enumeration-based bits.
Definition: bitfield.hpp:19
auto begin_element(span_size_t) -> result final
Begins the deserialization of a container element.
Definition: string_backend.hpp:281
static constexpr auto view(T *addr, S size) noexcept -> const_span< T >
Creates a view starting at the specified pointer and specified length.
Definition: span.hpp:458
static constexpr auto assign_to(std::basic_string< C, T, A > &str, memory::basic_span< const C, P, S > spn) -> auto &
Assigns the contents of a span of characters to a standard string.
Definition: string_span.hpp:137
auto begin_list(span_size_t &count) -> result final
Begins the deserialization of a container instance.
Definition: string_backend.hpp:273
auto finish_element(span_size_t) -> result final
Finishes the deserialization of a container element.
Definition: string_backend.hpp:285
auto begin_member(string_view name) -> result final
Begins the deserialization of a structure data member.
Definition: string_backend.hpp:257
deserialization_error_code
Deserialization error code bits enumeration.
Definition: result.hpp:53
auto finish() -> result final
Finishes the serialization of a potentially complex structured value.
Definition: string_backend.hpp:105
serialization_error_code
Serialization error code bits enumeration.
Definition: result.hpp:24
auto finish_list() -> result final
Finishes the serialization of a container instance.
Definition: string_backend.hpp:101
auto begin_struct(span_size_t &count) -> result final
Begins the deserialization of a structure instance.
Definition: string_backend.hpp:249
static auto format(std::string &&fmt_str) noexcept -> format_string_and_list< 0 >
Function taking a format string, returning an object for variable specification.
Definition: str_format.hpp:118
auto finish_member(string_view) -> result final
Finishes the deserialization of a structure data member.
Definition: string_backend.hpp:265
auto finish_element(span_size_t) -> result final
Finishes the serialization of a container element.
Definition: string_backend.hpp:97
auto enum_as_string() -> bool final
@brie Indicates if the backed stores enumerators as strings (or numeric values).
Definition: string_backend.hpp:57
bitfield< deserialization_error_code > deserialization_errors
Alias for deserialization error bitfield.
Definition: result.hpp:106
auto finish_struct() -> result final
Finishes the deserialization of a structure instance.
Definition: string_backend.hpp:269
auto begin() -> result final
Starts the deserialization of a potentially complex structured value.
Definition: string_backend.hpp:244
auto enum_as_string() -> bool final
@brie Indicates if the backed stores enumerators as strings (or numeric values).
Definition: string_backend.hpp:236
auto finish_list() -> result final
Finishes the deserialization of a container instance.
Definition: string_backend.hpp:289
Cross-platform implementation of serializer backend using ASCII-only strings.
Definition: string_backend.hpp:26
auto finish_member(string_view) -> result final
Finishes the serialization of a structure data member.
Definition: string_backend.hpp:78
Template type used mostly for function type-tag dispatching.
Definition: type_identity.hpp:19
auto begin_element(span_size_t) -> result final
Begins the serialization of a container element.
Definition: string_backend.hpp:93
auto finish_struct() -> result final
Finishes the serialization of a structure instance.
Definition: string_backend.hpp:82
auto begin() -> result final
Starts the serialization of a potentially complex structured value.
Definition: string_backend.hpp:61
bitfield< serialization_error_code > serialization_errors
Alias for serialization error bitfield.
Definition: result.hpp:100
basic_identifier< 10, 6, default_identifier_char_set, identifier_t > identifier
Default identifier type used throughout the project.
Definition: identifier.hpp:346