RESTinio

from_string_details.ipp
Go to the documentation of this file.
1 namespace restinio
2{
3
4 namespace utils
5{
6
7 namespace details
8{
9
10 template< typename C >
11 const C * digits_mapping()
12{
13 static constexpr C table[] = {
14 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
15 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
16 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
17
18 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
19
20 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
21 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
22 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
23 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
24 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
25 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
26 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
27 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
28 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
29 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
30 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
31 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
32 return table;
33}
34
35 struct int8_parse_traits_t
36{
37 using type_t = std::int8_t;
38
39 static constexpr std::size_t
40 digits_representation_max_size()
41 {
42 return 3;
43 }
44
45 static const char *
46 min_representation()
47 {
48 static constexpr char r[] = "128";
49 return r;
50 }
51
52 static const char *
53 max_representation()
54 {
55 static constexpr char r[] = "127";
56 return r;
57 }
58
59 static const char * type_name()
60 {
61 static constexpr char r[] = "int8_t";
62 return r;
63 }
64};
65
66 struct uint8_parse_traits_t
67{
68 using type_t = std::uint8_t;
69
70 static constexpr std::size_t
71 digits_representation_max_size()
72 {
73 return 3;
74 }
75
76 static const char *
77 min_representation()
78 {
79 static constexpr char r[] = "0";
80 return r;
81 }
82
83 static const char *
84 max_representation()
85 {
86 static constexpr char r[] = "255";
87 return r;
88 }
89
90 static const char * type_name()
91 {
92 static constexpr char r[] = "uint8_t";
93 return r;
94 }
95};
96
97 struct int16_parse_traits_t
98{
99 using type_t = std::int16_t;
100
101 static constexpr std::size_t
102 digits_representation_max_size()
103 {
104 return 5;
105 }
106
107 static const char *
108 min_representation()
109 {
110 static constexpr char r[] = "32768";
111 return r;
112 }
113
114 static const char *
115 max_representation()
116 {
117 static constexpr char r[] = "32767";
118 return r;
119 }
120
121 static const char * type_name()
122 {
123 static constexpr char r[] = "int16_t";
124 return r;
125 }
126};
127
128 struct uint16_parse_traits_t
129{
130 using type_t = std::uint16_t;
131
132 static constexpr std::size_t
133 digits_representation_max_size()
134 {
135 return 5;
136 }
137
138 static const char *
139 min_representation()
140 {
141 static constexpr char r[] = "0";
142 return r;
143 }
144
145 static const char *
146 max_representation()
147 {
148 static constexpr char r[] = "65535";
149 return r;
150 }
151
152 static const char * type_name()
153 {
154 static constexpr char r[] = "uint16_t";
155 return r;
156 }
157};
158
159 struct int32_parse_traits_t
160{
161 using type_t = std::int32_t;
162
163 static constexpr std::size_t
164 digits_representation_max_size()
165 {
166 return 10;
167 }
168
169 static const char *
170 min_representation()
171 {
172 static constexpr char r[] = "2147483648";
173 return r;
174 }
175
176 static const char *
177 max_representation()
178 {
179 static constexpr char r[] = "2147483647";
180 return r;
181 }
182
183 static const char * type_name()
184 {
185 static constexpr char r[] = "int32_t";
186 return r;
187 }
188};
189
190 struct uint32_parse_traits_t
191{
192 using type_t = std::uint32_t;
193
194 static constexpr std::size_t
195 digits_representation_max_size()
196 {
197 return 10;
198 }
199
200 static const char *
201 min_representation()
202 {
203 static constexpr char r[] = "0";
204 return r;
205 }
206
207 static const char *
208 max_representation()
209 {
210 static constexpr char r[] = "4294967295";
211 return r;
212 }
213
214 static const char * type_name()
215 {
216 static constexpr char r[] = "uint32_t";
217 return r;
218 }
219};
220
221 struct int64_parse_traits_t
222{
223 using type_t = std::int64_t;
224
225 static constexpr std::size_t
226 digits_representation_max_size()
227 {
228 return 19;
229 }
230
231 static const char *
232 min_representation()
233 {
234 static constexpr char r[] = "9223372036854775808";
235 return r;
236 }
237
238 static const char *
239 max_representation()
240 {
241 static constexpr char r[] = "9223372036854775807";
242 return r;
243 }
244
245 static const char * type_name()
246 {
247 static constexpr char r[] = "int64_t";
248 return r;
249 }
250};
251
252 struct uint64_parse_traits_t
253{
254 using type_t = std::uint64_t;
255
256 static constexpr std::size_t
257 digits_representation_max_size()
258 {
259 return 20;
260 }
261
262 static const char *
263 min_representation()
264 {
265 static constexpr char r[] = "0";
266 return r;
267 }
268
269 static const char *
270 max_representation()
271 {
272 static constexpr char r[] = "18446744073709551615";
273 return r;
274 }
275
276 static const char * type_name()
277 {
278 static constexpr char r[] = "uint64_t";
279 return r;
280 }
281};
282
283 template < typename Integer >
284Integer
285 parse_integer_no_checks(
286 const std::uint8_t * const mapping_table,
287 const char * data_begin,
288 const char * data_end,
289 bool apply_minus_sign,
290 std::true_type /* is signed */)
291{
292 Integer result = 0;
293
294 if( apply_minus_sign )
295 while( data_begin != data_end )
296 {
297 result = result*10 - mapping_table[ static_cast< std::size_t >( *data_begin++ ) ];
298 }
299 else
300 while( data_begin != data_end )
301 {
302 result = result*10 + mapping_table[ static_cast< std::size_t >( *data_begin++ ) ];
303 }
304
305 return result;
306}
307
308 template < typename Integer >
309Integer
310 parse_integer_no_checks(
311 const std::uint8_t * const mapping_table,
312 const char * data_begin,
313 const char * data_end,
314 bool ,
315 std::false_type /* is signed */ )
316{
317 Integer result = 0;
318
319 while( data_begin != data_end )
320 {
321 result = result * 10 + mapping_table[ static_cast< std::size_t >( *data_begin++ ) ];
322 }
323
324 return result;
325}
326
327 template < typename Traits >
328 typename Traits::type_t
329 parse_integer( const char * data_begin, const char * data_end )
330{
331 bool apply_minus_sign = false;
332 if( '-' == *data_begin )
333 {
334 if( !std::is_signed< typename Traits::type_t >::value )
335 {
336 throw exception_t{
337 fmt::format(
338 "invalid {} value: unsigned starts with minus",
339 Traits::type_name() ) };
340 }
341
342 // else:
343 apply_minus_sign = true;
344 ++data_begin;
345 }
346 else if( '+' == *data_begin )
347 {
348 ++data_begin;
349 }
350
351 const auto representation_size = static_cast< std::size_t >( data_end - data_begin );
352
353 if( 0 == representation_size )
354 throw exception_t{ fmt::format( "invalid {} value: empty string", Traits::type_name() ) };
355
356 if( Traits::digits_representation_max_size() < representation_size )
357 throw exception_t{
358 fmt::format(
359 "invalid {} value: max digits for type is {}",
360 Traits::type_name(),
361 Traits::digits_representation_max_size() ) };
362
363 const std::uint8_t * const mapping_table = digits_mapping< std::uint8_t >();
364
365 if( std::any_of(
366 data_begin,
367 data_end,
368 [&]( auto d ){ return 0xFF == mapping_table[ static_cast< std::size_t >( d ) ]; } ) )
369 {
370 throw exception_t{
371 fmt::format( "invalid {} value: invalid digit", Traits::type_name() ) };
372 }
373
374 if( Traits::digits_representation_max_size() == representation_size )
375 {
376 const char * const posssible_max = apply_minus_sign ?
377 Traits::min_representation() : Traits::max_representation();
378
379 if( 0 < std::memcmp( data_begin, posssible_max, representation_size ) )
380 throw std::out_of_range{
381 fmt::format( "invalid {} value: out of range", Traits::type_name() ) };
382 }
383
384 using is_signed_t = typename std::is_signed< typename Traits::type_t >::type;
385
386 return
387 parse_integer_no_checks< typename Traits::type_t >(
388 mapping_table,
389 data_begin,
390 data_end,
391 apply_minus_sign,
392 is_signed_t{} );
393}
394
395} /* namespace details */
396
397} /* namespace utils */
398
399} /* namespace restinio */
restinio::exception_t
Exception class for all exceptions thrown by RESTinio.
Definition: exception.hpp:26
nonstd::optional_lite::std11::false_type
bool_constant< false > false_type
Definition: optional.hpp:460
nonstd::optional_lite::std11::true_type
bool_constant< true > true_type
Definition: optional.hpp:459
restinio::utils::details::parse_integer_no_checks
Integer parse_integer_no_checks(const std::uint8_t *const mapping_table, const char *data_begin, const char *data_end, bool apply_minus_sign, std::true_type)
Definition: from_string_details.ipp:285
restinio::utils::details::parse_integer
Traits::type_t parse_integer(const char *data_begin, const char *data_end)
Definition: from_string_details.ipp:329
restinio::utils::details::digits_mapping
const C * digits_mapping()
Definition: from_string_details.ipp:11
restinio::utils::tuple_algorithms::any_of
RESTINIO_NODISCARD bool any_of(Tuple &&tuple, Predicate &&predicate)
Definition: tuple_algorithms.hpp:117
restinio
Definition: asio_include.hpp:21
restinio::utils::details::int16_parse_traits_t
Definition: from_string_details.ipp:98
restinio::utils::details::int16_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:108
restinio::utils::details::int16_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:121
restinio::utils::details::int16_parse_traits_t::type_t
std::int16_t type_t
Definition: from_string_details.ipp:99
restinio::utils::details::int16_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:115
restinio::utils::details::int16_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:102
restinio::utils::details::int32_parse_traits_t
Definition: from_string_details.ipp:160
restinio::utils::details::int32_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:177
restinio::utils::details::int32_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:183
restinio::utils::details::int32_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:164
restinio::utils::details::int32_parse_traits_t::type_t
std::int32_t type_t
Definition: from_string_details.ipp:161
restinio::utils::details::int32_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:170
restinio::utils::details::int64_parse_traits_t
Definition: from_string_details.ipp:222
restinio::utils::details::int64_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:245
restinio::utils::details::int64_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:232
restinio::utils::details::int64_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:226
restinio::utils::details::int64_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:239
restinio::utils::details::int64_parse_traits_t::type_t
std::int64_t type_t
Definition: from_string_details.ipp:223
restinio::utils::details::int8_parse_traits_t
Definition: from_string_details.ipp:36
restinio::utils::details::int8_parse_traits_t::type_t
std::int8_t type_t
Definition: from_string_details.ipp:37
restinio::utils::details::int8_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:53
restinio::utils::details::int8_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:59
restinio::utils::details::int8_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:46
restinio::utils::details::int8_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:40
restinio::utils::details::uint16_parse_traits_t
Definition: from_string_details.ipp:129
restinio::utils::details::uint16_parse_traits_t::type_t
std::uint16_t type_t
Definition: from_string_details.ipp:130
restinio::utils::details::uint16_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:133
restinio::utils::details::uint16_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:139
restinio::utils::details::uint16_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:152
restinio::utils::details::uint16_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:146
restinio::utils::details::uint32_parse_traits_t
Definition: from_string_details.ipp:191
restinio::utils::details::uint32_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:201
restinio::utils::details::uint32_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:195
restinio::utils::details::uint32_parse_traits_t::type_t
std::uint32_t type_t
Definition: from_string_details.ipp:192
restinio::utils::details::uint32_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:208
restinio::utils::details::uint32_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:214
restinio::utils::details::uint64_parse_traits_t
Definition: from_string_details.ipp:253
restinio::utils::details::uint64_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:257
restinio::utils::details::uint64_parse_traits_t::type_t
std::uint64_t type_t
Definition: from_string_details.ipp:254
restinio::utils::details::uint64_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:276
restinio::utils::details::uint64_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:263
restinio::utils::details::uint64_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:270
restinio::utils::details::uint8_parse_traits_t
Definition: from_string_details.ipp:67
restinio::utils::details::uint8_parse_traits_t::type_t
std::uint8_t type_t
Definition: from_string_details.ipp:68
restinio::utils::details::uint8_parse_traits_t::digits_representation_max_size
static constexpr std::size_t digits_representation_max_size()
Definition: from_string_details.ipp:71
restinio::utils::details::uint8_parse_traits_t::min_representation
static const char * min_representation()
Definition: from_string_details.ipp:77
restinio::utils::details::uint8_parse_traits_t::type_name
static const char * type_name()
Definition: from_string_details.ipp:90
restinio::utils::details::uint8_parse_traits_t::max_representation
static const char * max_representation()
Definition: from_string_details.ipp:84