RESTinio
Loading...
Searching...
No Matches
from_string_details.ipp
Go to the documentation of this file.
1namespace restinio
2{
3
4namespace utils
5{
6
7namespace details
8{
9
10template< typename C >
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
36{
37 using type_t = std::int8_t;
38
39 static constexpr std::size_t
41 {
42 return 3;
43 }
44
45 static const char *
47 {
48 static constexpr char r[] = "128";
49 return r;
50 }
51
52 static const char *
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
67{
68 using type_t = std::uint8_t;
69
70 static constexpr std::size_t
72 {
73 return 3;
74 }
75
76 static const char *
78 {
79 static constexpr char r[] = "0";
80 return r;
81 }
82
83 static const char *
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
98{
99 using type_t = std::int16_t;
100
101 static constexpr std::size_t
103 {
104 return 5;
105 }
106
107 static const char *
109 {
110 static constexpr char r[] = "32768";
111 return r;
112 }
113
114 static const char *
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
129{
130 using type_t = std::uint16_t;
131
132 static constexpr std::size_t
134 {
135 return 5;
136 }
137
138 static const char *
140 {
141 static constexpr char r[] = "0";
142 return r;
143 }
144
145 static const char *
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
160{
161 using type_t = std::int32_t;
162
163 static constexpr std::size_t
165 {
166 return 10;
167 }
168
169 static const char *
171 {
172 static constexpr char r[] = "2147483648";
173 return r;
174 }
175
176 static const char *
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
191{
192 using type_t = std::uint32_t;
193
194 static constexpr std::size_t
196 {
197 return 10;
198 }
199
200 static const char *
202 {
203 static constexpr char r[] = "0";
204 return r;
205 }
206
207 static const char *
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
222{
223 using type_t = std::int64_t;
224
225 static constexpr std::size_t
227 {
228 return 19;
229 }
230
231 static const char *
233 {
234 static constexpr char r[] = "9223372036854775808";
235 return r;
236 }
237
238 static const char *
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
253{
254 using type_t = std::uint64_t;
255
256 static constexpr std::size_t
258 {
259 return 20;
260 }
261
262 static const char *
264 {
265 static constexpr char r[] = "0";
266 return r;
267 }
268
269 static const char *
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
283template < typename Integer >
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 - static_cast<Integer>(
298 mapping_table[ static_cast< std::size_t >( *data_begin++ ) ] );
299 }
300 else
301 while( data_begin != data_end )
302 {
303 result = result*10 + static_cast<Integer>(
304 mapping_table[ static_cast< std::size_t >( *data_begin++ ) ] );
305 }
306
307 return result;
308}
309
310template < typename Integer >
313 const std::uint8_t * const mapping_table,
314 const char * data_begin,
315 const char * data_end,
316 bool ,
317 std::false_type /* is signed */ )
318{
319 Integer result = 0;
320
321 while( data_begin != data_end )
322 {
323 result = result * 10 + static_cast<Integer>(
324 mapping_table[ static_cast< std::size_t >( *data_begin++ ) ] );
325 }
326
327 return result;
328}
329
330template < typename Traits >
331typename Traits::type_t
332parse_integer( const char * data_begin, const char * data_end )
333{
334 bool apply_minus_sign = false;
335 if( '-' == *data_begin )
336 {
337 if( !std::is_signed< typename Traits::type_t >::value )
338 {
339 throw exception_t{
340 fmt::format(
342 "invalid {} value: unsigned starts with minus" ),
343 Traits::type_name() ) };
344 }
345
346 // else:
347 apply_minus_sign = true;
348 ++data_begin;
349 }
350 else if( '+' == *data_begin )
351 {
352 ++data_begin;
353 }
354
355 const auto representation_size = static_cast< std::size_t >( data_end - data_begin );
356
357 if( 0 == representation_size )
358 throw exception_t{
359 fmt::format(
360 RESTINIO_FMT_FORMAT_STRING( "invalid {} value: empty string" ),
361 Traits::type_name() )
362 };
363
364 if( Traits::digits_representation_max_size() < representation_size )
365 throw exception_t{
366 fmt::format(
368 "invalid {} value: max digits for type is {}" ),
369 Traits::type_name(),
370 Traits::digits_representation_max_size() )
371 };
372
373 const std::uint8_t * const mapping_table = digits_mapping< std::uint8_t >();
374
375 if( std::any_of(
377 data_end,
378 [&]( auto d ){ return 0xFF == mapping_table[ static_cast< std::size_t >( d ) ]; } ) )
379 {
380 throw exception_t{
381 fmt::format(
382 RESTINIO_FMT_FORMAT_STRING( "invalid {} value: invalid digit" ),
383 Traits::type_name() )
384 };
385 }
386
387 if( Traits::digits_representation_max_size() == representation_size )
388 {
389 const char * const posssible_max = apply_minus_sign ?
390 Traits::min_representation() : Traits::max_representation();
391
392 if( 0 < std::memcmp( data_begin, posssible_max, representation_size ) )
393 throw std::out_of_range{
394 fmt::format(
395 RESTINIO_FMT_FORMAT_STRING( "invalid {} value: out of range" ),
396 Traits::type_name() )
397 };
398 }
399
400 using is_signed_t = typename std::is_signed< typename Traits::type_t >::type;
401
402 return
406 data_end,
408 is_signed_t{} );
409}
410
411} /* namespace details */
412
413} /* namespace utils */
414
415} /* namespace restinio */
Exception class for all exceptions thrown by RESTinio.
Definition exception.hpp:26
#define RESTINIO_FMT_FORMAT_STRING(s)
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)
Traits::type_t parse_integer(const char *data_begin, const char *data_end)
run_on_this_thread_settings_t< Traits > on_this_thread()
A special marker for the case when http_server must be run on the context of the current thread.
static constexpr std::size_t digits_representation_max_size()
static constexpr std::size_t digits_representation_max_size()
static constexpr std::size_t digits_representation_max_size()
static constexpr std::size_t digits_representation_max_size()
static constexpr std::size_t digits_representation_max_size()
static constexpr std::size_t digits_representation_max_size()
static constexpr std::size_t digits_representation_max_size()
static constexpr std::size_t digits_representation_max_size()