2
3
6
7
11#include <restinio/impl/include_fmtlib.hpp>
13#include <restinio/exception.hpp>
14#include <restinio/utils/percent_encoding.hpp>
18#include <unordered_map>
29 const char * result =
static_cast<
const char * >(
30 std::memchr( from, chr,
static_cast<std::size_t>(to - from) ) );
32 return result ? result : to;
50 std::unique_ptr<
char[] > data_buffer,
51 parameters_container_t parameters )
59 std::unique_ptr<
char[] > data_buffer,
60 std::optional< string_view_t > tag )
75 return find_parameter_with_check( key ).second;
80 has( string_view_t key )
const noexcept
82 return m_parameters.end() != find_parameter( key );
90 const auto it = find_parameter( key );
92 return m_parameters.end() != it ?
93 std::optional< string_view_t >{ it->second } :
94 std::optional< string_view_t >{ std::nullopt };
98 auto size()
const noexcept {
return m_parameters.size(); }
102 bool empty()
const noexcept {
return m_parameters.empty(); }
109 return m_parameters.begin();
115 return m_parameters.end();
121
122
123
124
125
126
127
128
129
130
131 auto tag()
const noexcept {
return m_tag; }
139 m_parameters.begin(),
142 return key == p.first;
149 auto it = find_parameter( key );
151 if( m_parameters.end() == it )
156 "unable to find parameter \"{}\"" ),
157 std::string{ key.data(), key.size() } ) };
173template <
typename Value_Type >
177 return std::get< Value_Type >( params[ key ] );
187
188
189
190
191
192
193
194
200 string_view_t::size_type start_from )
noexcept
202 return where.find_first_of(
"&;", start_from );
207
208
209
210
211
212
213
214
220 string_view_t::size_type start_from )
noexcept
222 return where.find_first_of(
'&', start_from );
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
251
252
253
254
255
256
257
258
259
260
261
262
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
334
335
336
337
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396template<
typename Parse_Traits >
401 string_view_t original_query_string )
403 std::unique_ptr<
char[] > data_buffer;
404 query_string_params_t::parameters_container_t parameters;
406 if( !original_query_string.empty() )
410 data_buffer.reset(
new char[ original_query_string.size() ] );
413 original_query_string.data(),
414 original_query_string.size() );
417 string_view_t work_query_string{
419 original_query_string.size()
421 string_view_t::size_type pos{ 0 };
422 const string_view_t::size_type end_pos = work_query_string.size();
424 while( pos < end_pos )
426 const auto eq_pos = work_query_string.find_first_of(
'=', pos );
428 if( string_view_t::npos == eq_pos )
438 "invalid format of key-value pairs in query_string, "
439 "no '=' symbol starting from position {}" ),
445 auto tag_unescape_result =
446 utils::try_inplace_unescape_percent_encoding< Parse_Traits >(
449 if( !tag_unescape_result )
451 std::move(tag_unescape_result.error())
454 const string_view_t tag = work_query_string.substr(
455 pos, *tag_unescape_result );
461 const auto eq_pos_next = eq_pos + 1u;
462 auto separator_pos = Parse_Traits::find_next_separator(
463 work_query_string, eq_pos_next );
464 if( string_view_t::npos == separator_pos )
465 separator_pos = work_query_string.size();
468 auto key_unescape_result =
469 utils::try_inplace_unescape_percent_encoding< Parse_Traits >(
472 if( !key_unescape_result )
474 std::move(key_unescape_result.error())
477 auto value_unescape_result =
478 utils::try_inplace_unescape_percent_encoding< Parse_Traits >(
479 &data_buffer[ eq_pos_next ],
480 separator_pos - eq_pos_next );
481 if( !value_unescape_result )
483 std::move(value_unescape_result.error())
486 parameters.emplace_back(
487 string_view_t{ &data_buffer[ pos ], *key_unescape_result },
488 string_view_t{ &data_buffer[ eq_pos_next ], *value_unescape_result } );
490 pos = separator_pos + 1u;
495 std::move( data_buffer ),
496 std::move( parameters )
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
522 string_view_t original_query_string )
524 auto r = try_parse_query< Parse_Traits >( original_query_string );
526 throw exception_t{ std::move(r.error().giveout_description()) };
528 return std::move(*r);
Exception class for all exceptions thrown by RESTinio.
Type that indicates a failure of an attempt of query-string parsing.
std::string giveout_description() noexcept
Get out the value of the description of the failure.
const std::string & description() const noexcept
Get a reference to the description of the failure.
std::string m_description
Description of a failure.
parse_query_failure_t(std::string description)
parse_query_failure_t(utils::unescape_percent_encoding_failure_t &&failure)
std::unique_ptr< char[] > m_data_buffer
Shared buffer for string_view of named parameterts names.
query_string_params_t(query_string_params_t &&)=default
auto tag() const noexcept
Get the tag (web beacon) part.
bool empty() const noexcept
Is there any parameters?
auto size() const noexcept
Get the size of parameters.
parameters_container_t::const_iterator begin() const noexcept
query_string_params_t & operator=(query_string_params_t &&)=default
string_view_t operator[](string_view_t key) const
Get parameter.
parameters_container_t m_parameters
std::vector< std::pair< string_view_t, string_view_t > > parameters_container_t
std::optional< string_view_t > get_param(string_view_t key) const noexcept
Get the value of a parameter if it exists.
query_string_params_t(std::unique_ptr< char[] > data_buffer, parameters_container_t parameters)
Constructor for the case when query string empty of contains a set of key-value pairs.
parameters_container_t::const_iterator find_parameter(string_view_t key) const noexcept
query_string_params_t & operator=(const query_string_params_t &)=delete
parameters_container_t::const_reference find_parameter_with_check(string_view_t key) const
parameters_container_t::const_iterator end() const noexcept
bool has(string_view_t key) const noexcept
Check parameter.
query_string_params_t(const query_string_params_t &)=delete
std::optional< string_view_t > m_tag
Tag (or web beacon) part.
Type that indicates a failure of unescaping of percent-encoded symbols.
std::string giveout_description() noexcept
Get out the value of the description of the failure.
#define RESTINIO_FMT_FORMAT_STRING(s)
const char * modified_memchr(int chr, const char *from, const char *to)
query_string_params_t parse_query(string_view_t original_query_string)
Parse query key-value parts.
expected_t< query_string_params_t, parse_query_failure_t > try_parse_query(string_view_t original_query_string)
Helper function for parsing query string.
Value_Type get(const query_string_params_t ¶ms, string_view_t key)
Cast query string parameter to a given type.
Helper class to be reused in implementation of query-string parsing traits.
static string_view_t::size_type find_next_separator(string_view_t where, string_view_t::size_type start_from) noexcept
Helper class to be reused in implementation of query-string parsing traits.
static string_view_t::size_type find_next_separator(string_view_t where, string_view_t::size_type start_from) noexcept
Traits for parsing a query string in JavaScript-compatible mode.
Traits for parsing a query string in a very relaxed mode.
Traits for the default RESTinio parser for query string.
The traits for escaping and unexcaping symbols in JavaScript-compatible mode.
Traits for escaping and unescaping symbols in a query string in very relaxed mode.
The default traits for escaping and unexcaping symbols in a query string.