2
3
6
7
13#include <restinio/impl/include_fmtlib.hpp>
15#include <restinio/string_view.hpp>
16#include <restinio/exception.hpp>
17#include <restinio/expected.hpp>
19#include <restinio/utils/utf8_checker.hpp>
28
29
30
31
32
33
34
41 (
'0' <= c && c <=
'9' ) ||
42 (
'a' <= c && c <=
'z' ) ||
43 (
'A' <= c && c <=
'Z' ) ||
52
53
54
55
56
57
58
59
66 (
'0' <= c && c <=
'9' ) ||
67 (
'a' <= c && c <=
'z' ) ||
68 (
'A' <= c && c <=
'Z' ) ||
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
101 return nullptr != std::strchr(
103 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
104 "abcdefghijklmnopqrstuvwxyz"
113
114
115
116
117
118
119
120
121
122
123
126 static constexpr bool
130 (
'0' <= c && c <=
'9' ) ||
131 (
'a' <= c && c <=
'z' ) ||
132 (
'A' <= c && c <=
'Z' ) ||
146
147
148
149
150
154
155
156
157
158
166 std::string description )
177
178
179
180
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';
228
229
230
231
234 typename Chars_Collector >
240 const string_view_t data,
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 )
258 "next byte from UTF-8 sequence expected at {}" ),
264 if( chars_to_handle >= 3 &&
273 "invalid UTF-8 sequence detected at {}" ),
278 chars_to_handle -= 3;
282 if( !expect_next_utf8_byte )
290 "invalid escape sequence at pos {}" ),
301 else if( Traits::ordinary_char( c ) )
312 "invalid non-escaped char with code {:#02X} at pos: {}" ),
319 if( expect_next_utf8_byte )
338 const auto escaped_chars_count =
static_cast<std::size_t>(
342 [](
auto c ){
return !Traits::ordinary_char(c); } ));
344 if( 0 == escaped_chars_count )
347 result.assign( data.data(), data.size() );
352 result.reserve( data.size() + 2*escaped_chars_count );
355 if( Traits::ordinary_char( c ) )
373 result.reserve( data.size() );
375 auto r =
impl::do_unescape_percent_encoding<Traits>(
377 [&result](
char ch ) { result += ch; } );
379 throw exception_t{ r.error().giveout_description() };
385
386
387
388
389
390
391
392
393
394
395
402 result.reserve( data.size() );
404 auto r =
impl::do_unescape_percent_encoding<Traits>(
406 [&result](
char ch ) { result += ch; } );
408 return make_unexpected( std::move(r.error()) );
410 return std::move(result);
418 std::size_t result_size = 0u;
421 auto r = impl::do_unescape_percent_encoding<Traits>(
422 string_view_t{ data, size },
423 [&result_size, &dest](
char ch ) {
428 throw exception_t{ r.error().giveout_description() };
434
435
436
437
438
439
440
441
442
443
444
450 std::size_t result_size = 0u;
453 auto r = impl::do_unescape_percent_encoding<Traits>(
454 string_view_t{ data, size },
455 [&result_size, &dest](
char ch ) {
460 return make_unexpected( std::move(r.error()) );
477
478
479
480
481
482
493
494
495
496
497
498
499
500
501
502
503
504
505
507 typename One_Byte_Handler,
508 typename Three_Byte_Handler >
512 One_Byte_Handler && one_byte_handler,
513 Three_Byte_Handler && three_byte_handler )
517 std::size_t chars_to_handle = what.size();
518 const char * d = what.data();
521 bool expect_next_utf8_byte =
false;
523 const auto current_pos = [&d, &what]()
noexcept {
return d - what.data(); };
525 while( 0 < chars_to_handle )
527 if( expect_next_utf8_byte &&
'%' != *d )
531 "next byte from UTF-8 sequence expected at {}" ),
538 one_byte_handler( *d );
542 else if( chars_to_handle >= 3 &&
550 "invalid UTF-8 sequence detected at {}" ),
554 bool keep_three_bytes =
true;
558 expect_next_utf8_byte =
false;
565 const char ascii_char =
static_cast<
char>(symbol);
569 one_byte_handler( ascii_char );
570 keep_three_bytes =
false;
576 expect_next_utf8_byte =
true;
579 if( keep_three_bytes )
582 three_byte_handler( d[ 0 ], d[ 1 ], d[ 2 ] );
585 chars_to_handle -= 3;
598 if( expect_next_utf8_byte )
606
607
608
609
610
611
612
613
614
615
616
622 std::size_t calculated_capacity = 0u;
624 impl::run_normalization_algo( what,
625 [&calculated_capacity](
char )
noexcept {
626 ++calculated_capacity;
628 [&calculated_capacity](
char,
char,
char )
noexcept {
629 calculated_capacity += 3u;
632 return calculated_capacity;
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
658 impl::run_normalization_algo( what,
659 [&dest](
char ch )
noexcept {
662 [&dest](
char ch1,
char ch2,
char ch3 )
noexcept {
Exception class for all exceptions thrown by RESTinio.
Type that indicates a failure of unescaping of percent-encoded symbols.
const std::string & description() const noexcept
Get a reference to the description of the failure.
std::string giveout_description() noexcept
Get out the value of the description of the failure.
std::string m_description
Description of a failure.
unescape_percent_encoding_failure_t(std::string description)
Helper class for checking UTF-8 byte sequence during parsing URI or incoming byte stream.
bool process_byte(std::uint8_t byte) noexcept
bool finalized() const noexcept
std::uint32_t current_symbol() const noexcept
#define RESTINIO_FMT_FORMAT_STRING(s)
char extract_escaped_char(char c1, char c2)
expected_t< unescape_percent_encoding_success_t, unescape_percent_encoding_failure_t > do_unescape_percent_encoding(const string_view_t data, Chars_Collector &&collector)
The actual implementation of unescape-percent-encoding procedure.
constexpr bool is_unreserved_char(const char ch) noexcept
Is this symbol a part of unreserved set?
void run_normalization_algo(string_view_t what, One_Byte_Handler &&one_byte_handler, Three_Byte_Handler &&three_byte_handler)
Internal helper to perform the main logic of enumeration of symbols in URI.
std::size_t estimate_required_capacity(string_view_t what)
Calculate the size of a buffer to hold normalized value of a URI.
void normalize_to(string_view_t what, char *dest)
Perform normalization of URI value.
std::string escape_percent_encoding(const string_view_t data)
Percent encoding.
std::string unescape_percent_encoding(const string_view_t data)
std::size_t inplace_unescape_percent_encoding(char *data, std::size_t size)
expected_t< std::size_t, unescape_percent_encoding_failure_t > try_inplace_unescape_percent_encoding(char *data, std::size_t size)
Helper function for unescaping percent-encoded string inplace.
expected_t< std::string, unescape_percent_encoding_failure_t > try_unescape_percent_encoding(const string_view_t data)
Helper function for unescaping percent-encoded string.
The traits for escaping and unexcaping symbols in JavaScript-compatible mode.
static constexpr bool ordinary_char(char c) noexcept
Traits for escaping and unescaping symbols in a query string in very relaxed mode.
static bool ordinary_char(char c) noexcept
The default traits for escaping and unexcaping symbols in a query string.
static constexpr bool ordinary_char(char c) noexcept
Type that indicates that unescaping of percent-encoded symbols completed successfully.