41 (
'0' <= c && c <=
'9' ) ||
42 (
'a' <= c && c <=
'z' ) ||
43 (
'A' <= c && c <=
'Z' ) ||
66 (
'0' <= c && c <=
'9' ) ||
67 (
'a' <= c && c <=
'z' ) ||
68 (
'A' <= c && c <=
'Z' ) ||
101 return nullptr != std::strchr(
103 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
104 "abcdefghijklmnopqrstuvwxyz"
126 static constexpr
bool
130 (
'0' <= c && c <=
'9' ) ||
131 (
'a' <= c && c <=
'z' ) ||
132 (
'A' <= c && c <=
'Z' ) ||
193 (
'0' <= c && c <=
'9' ) ||
194 (
'a' <= c && c <=
'f' ) ||
195 (
'A' <= c && c <=
'F' );
203 if(
'0' <= c1 && c1 <=
'9' )
208 result = 10 + c1 -
'a';
213 if(
'0' <= c2 && c2 <=
'9' )
218 result += 10 + c2 -
'a';
234 typename Chars_Collector >
241 Chars_Collector && collector )
243 std::size_t chars_to_handle = data.size();
244 const char * d = data.data();
247 bool expect_next_utf8_byte =
false;
249 const auto current_pos = [&d, &data]() noexcept {
return d - data.data(); };
251 while( 0 < chars_to_handle )
254 if( expect_next_utf8_byte &&
'%' != c )
257 "next byte from UTF-8 sequence expected at {}",
263 if( chars_to_handle >= 3 &&
268 if( !utf8_checker.
process_byte(
static_cast<std::uint8_t
>(ch) ) )
270 fmt::format(
"invalid UTF-8 sequence detected at {}",
275 chars_to_handle -= 3;
278 expect_next_utf8_byte = !utf8_checker.
finalized();
279 if( !expect_next_utf8_byte )
280 utf8_checker.
reset();
286 "invalid escape sequence at pos {}", current_pos() )
296 else if( Traits::ordinary_char( c ) )
306 "invalid non-escaped char with code {:#02X} at pos: {}",
313 if( expect_next_utf8_byte )
315 fmt::format(
"unfinished UTF-8 sequence" )
325 template<
typename Traits = restinio_default_unescape_traits >
331 const auto escaped_chars_count =
static_cast<std::size_t
>(
335 [](
auto c ){ return !Traits::ordinary_char(c); } ));
337 if( 0 == escaped_chars_count )
340 result.assign( data.data(), data.size() );
345 result.reserve( data.size() + 2*escaped_chars_count );
348 if( Traits::ordinary_char( c ) )
352 result += fmt::format(
"%{:02X}", c );
360 template<
typename Traits = restinio_default_unescape_traits >
366 result.reserve( data.size() );
368 auto r = impl::do_unescape_percent_encoding<Traits>(
370 [&result](
char ch ) { result += ch; } );
372 throw exception_t{ r.error().giveout_description() };
389 template<
typename Traits = restinio_default_unescape_traits >
395 result.reserve( data.size() );
397 auto r = impl::do_unescape_percent_encoding<Traits>(
399 [&result](
char ch ) { result += ch; } );
401 return make_unexpected(
std::move(r.error()) );
406 template<
typename Traits = restinio_default_unescape_traits >
411 std::size_t result_size = 0u;
414 auto r = impl::do_unescape_percent_encoding<Traits>(
416 [&result_size, &dest](
char ch ) {
421 throw exception_t{ r.error().giveout_description() };
438 template<
typename Traits = restinio_default_unescape_traits >
443 std::size_t result_size = 0u;
446 auto r = impl::do_unescape_percent_encoding<Traits>(
448 [&result_size, &dest](
char ch ) {
453 return make_unexpected(
std::move(r.error()) );
460 namespace uri_normalization
463 namespace unreserved_chars
477 constexpr
inline bool
500 typename One_Byte_Handler,
501 typename Three_Byte_Handler >
505 One_Byte_Handler && one_byte_handler,
506 Three_Byte_Handler && three_byte_handler )
510 std::size_t chars_to_handle = what.size();
511 const char * d = what.data();
514 bool expect_next_utf8_byte =
false;
516 const auto current_pos = [&d, &what]() noexcept {
return d - what.data(); };
518 while( 0 < chars_to_handle )
520 if( expect_next_utf8_byte &&
'%' != *d )
522 fmt::format(
"next byte from UTF-8 sequence expected at {}",
529 one_byte_handler( *d );
533 else if( chars_to_handle >= 3 &&
537 if( !utf8_checker.
process_byte(
static_cast<std::uint8_t
>(ch) ) )
539 fmt::format(
"invalid UTF-8 sequence detected at {}",
543 bool keep_three_bytes =
true;
547 expect_next_utf8_byte =
false;
550 utf8_checker.
reset();
554 const char ascii_char =
static_cast<char>(
symbol);
558 one_byte_handler( ascii_char );
559 keep_three_bytes =
false;
565 expect_next_utf8_byte =
true;
568 if( keep_three_bytes )
571 three_byte_handler( d[ 0 ], d[ 1 ], d[ 2 ] );
574 chars_to_handle -= 3;
580 fmt::format(
"invalid escape sequence at pos {}", current_pos() )
585 if( expect_next_utf8_byte )
586 throw exception_t{ fmt::format(
"unfinished UTF-8 sequence" ) };
608 std::size_t calculated_capacity = 0u;
611 [&calculated_capacity](
char ) noexcept {
612 ++calculated_capacity;
614 [&calculated_capacity]( char, char, char ) noexcept {
615 calculated_capacity += 3u;
618 return calculated_capacity;
645 [&dest](
char ch ) noexcept {
648 [&dest](
char ch1,
char ch2,
char ch3 ) noexcept {