2
3
6
7
8
9
10
14#include <restinio/impl/string_caseless_compare.hpp>
16#include <restinio/helpers/easy_parser.hpp>
18#include <restinio/expected.hpp>
58 constexpr auto get()
const noexcept {
return m_value; }
71 if( m_value > maximum )
73 "http_field_parser::rfc::qvalue_t" );
76 auto get()
const noexcept {
return m_value; }
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
164 if( qvalue_details::maximum == m_value )
166 static constexpr char fixed_value[]{
"1.000" };
167 std::copy( std::begin(fixed_value), std::end(fixed_value),
168 std::begin(result) );
175 result[2] =
'0' +
static_cast<
char>(m_value / 100u);
176 const auto d2 = m_value % 100u;
177 result[3] =
'0' +
static_cast<
char>(d2 / 10u);
178 const auto d3 = d2 % 10u;
179 result[4] =
'0' +
static_cast<
char>(d3);
206 constexpr auto as_uint()
const noexcept {
return m_value; }
210 return std::string{ &make_char_array().front() };
213 friend std::ostream &
214 operator<<( std::ostream & to,
const qvalue_t & what )
216 return (to << &what.make_char_array().front());
257
258
259
260
261
262
267 return (ch >=
'\x41' && ch <=
'\x5A') ||
268 (ch >=
'\x61' && ch <=
'\x7A');
275
276
277
278
279
294
295
296
297
298
313
314
315
316
317
318
323 return (ch >=
'\x21' && ch <=
'\x7E');
330
331
332
333
334
349
350
351
352
353
354
359 constexpr unsigned short left = 0x80u;
360 constexpr unsigned short right = 0xFFu;
362 const unsigned short t =
static_cast<
unsigned short>(
363 static_cast<
unsigned char>(ch));
365 return (t >= left && t <= right);
372
373
374
375
376
377
385 (ch >=
'\x23' && ch <=
'\x5B') ||
386 (ch >=
'\x5D' && ch <=
'\x7E') ||
394
395
396
397
398
399
406 (ch >=
'\x21' && ch <=
'\x27') ||
407 (ch >=
'\x2A' && ch <=
'\x5B') ||
408 (ch >=
'\x5D' && ch <=
'\x7E') ||
416
417
418
419
420
435
436
437
441 static constexpr bool
474
475
476
477
478
479
480
481
482
491 std::size_t extracted_spaces{};
504 if( extracted_spaces > 0u )
505 return result_type{
' ' };
507 return result_type{ std::nullopt };
515
516
517
518
519
520
521
522
523
548 accumulator += ch
.m_ch;
552 if( accumulator.empty() )
561 static constexpr bool
573 const auto try_result = try_parse_value( from, value );
575 return { std::move(value) };
577 return make_unexpected( *try_result );
585
586
587
588
589
590
591
592
593
602 bool second_quote_extracted{
false };
613 second_quote_extracted =
true;
614 else if(
'\\' == ch
.m_ch )
626 accumulator += next
.m_ch;
636 accumulator += ch
.m_ch;
644 while( !second_quote_extracted );
646 if( !second_quote_extracted )
665 const auto try_result = try_parse_value( from, value );
669 return { std::move(value) };
672 return make_unexpected( *try_result );
677 consumer.started_at(),
684 consumer.started_at(),
694
695
696
697
698
699
700
701
702
717 if(
'\\' == ch
.m_ch )
738 from.current_position(),
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
778
779
780
781
782
783
784
785
786
787
792 return restinio::easy_parser::impl::symbol_producer_template_t<
793 impl::is_alpha_predicate_t >{};
800
801
802
803
804
805
806
807
808
809
814 return restinio::easy_parser::impl::symbol_producer_template_t<
815 impl::is_alphanum_predicate_t >{};
822
823
824
825
826
827
828
829
830
831
836 return restinio::easy_parser::impl::symbol_producer_template_t<
837 impl::is_vchar_predicate_t >{};
844
845
846
847
848
849
850
851
852
853
858 return restinio::easy_parser::impl::symbol_producer_template_t<
859 impl::is_ctext_predicate_t >{};
866
867
868
869
870
871
872
873
874
875
876
877
878
879
884 return impl::comment_producer_t{};
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
911ows_p()
noexcept {
return impl::ows_producer_t{}; }
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
941ows()
noexcept {
return ows_p() >> skip(); }
947
948
949
950
951
952
953
954
955
956
961 return restinio::easy_parser::impl::symbol_producer_template_t<
962 impl::is_token_char_predicate_t >{};
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
987token_p()
noexcept {
return impl::token_producer_t{}; }
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1016 return impl::quoted_string_producer_t{};
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1042 return impl::quoted_pair_producer_t{};
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1077 return produce<
bool >(
1078 exact_p( token ) >> as_result(),
1079 not_clause( token_symbol_p() >> skip() ) );
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1116 return produce<
bool >(
1117 caseless_exact_p( token ) >> as_result(),
1118 not_clause( token_symbol_p() >> skip() ) );
1131 return produce< std::string >(
1136 ctext_symbol_p() >> to_container(),
1137 quoted_pair_p() >> to_container(),
1138 comment_p() >> custom_consumer(
1139 []( std::string & dest, std::string && what ) {
1144 ).try_parse( from );
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1187 dest.m_value += m_multiplier *
1188 static_cast< qvalue_t::underlying_uint_t >(digit -
'0');
1197 const auto parse_result = produce< zero_initialized_unit_t >(
1203 maybe( digit_p() >> digit_consumer_t{100},
1204 maybe( digit_p() >> digit_consumer_t{10},
1205 maybe( digit_p() >> digit_consumer_t{1} )
1211 symbol_p(
'1') >> digit_consumer_t{1000},
1216 maybe( symbol(
'0') )
1222 ).try_parse( from );
1227 return make_unexpected( parse_result.error() );
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1254 return impl::qvalue_producer_t{};
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1281 return produce< qvalue_t >(
1285 caseless_symbol(
'q'),
1287 qvalue_p() >> as_result()
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1317 typename Element_Producer >
1321 static_assert(
impl::is_producer_v<Element_Producer>,
1322 "Element_Producer should be a value producer type" );
1330 Element_Producer && element )
1338 Container tmp_value;
1342 const auto process_result = sequence(
1343 repeat( 0, N, symbol(
','), ows() ),
1344 m_element >> appender,
1347 maybe( ows(), m_element >> appender )
1349 ).try_process( from, tmp_value );
1351 if( !process_result )
1352 return { std::move(tmp_value) };
1354 return make_unexpected( *process_result );
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1381 typename Element_Producer >
1385 static_assert(
impl::is_producer_v<Element_Producer>,
1386 "Element_Producer should be a value producer type" );
1394 Element_Producer && element )
1402 Container tmp_value;
1406 const auto process_result = maybe(
1407 alternatives( symbol(
','), m_element >> appender ),
1410 maybe( ows(), m_element >> appender )
1412 ).try_process( from, tmp_value );
1414 if( !process_result )
1415 return { std::move(tmp_value) };
1417 return make_unexpected( *process_result );
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1456 typename Element_Producer >
1461 static_assert(
impl::is_producer_v<Element_Producer>,
1462 "Element_Producer should be a value producer type" );
1466 Element_Producer >{ std::move(element) };
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1502 typename Element_Producer >
1507 static_assert(
impl::is_producer_v<Element_Producer>,
1508 "Element_Producer should be a value producer type" );
1512 Element_Producer >{ std::move(element) };
1519
1520
1521
1522
1529
1530
1531
1532
1540
1541
1542
1543
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1571 const parameter_with_mandatory_value_container_t & where,
1572 string_view_t what )
1574 const auto it = std::find_if( where.begin(), where.end(),
1575 [&what](
const auto & pair ) {
1576 return restinio::
impl::is_equal_caseless( pair.first, what );
1578 if( it != where.end() )
1579 return string_view_t{ it->second };
1594
1595
1596
1597
1598
1603 return produce< parameter_with_mandatory_value_container_t >(
1605 produce< parameter_with_mandatory_value_t >(
1609 token_p() >> to_lower()
1610 >> ¶meter_with_mandatory_value_t::first,
1614 >> ¶meter_with_mandatory_value_t::second,
1616 >> ¶meter_with_mandatory_value_t::second
1629
1630
1631
1632
1633
1650 return m_producer.try_parse( from );
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1693
1694
1695
1696
1698 std::pair< std::string, std::optional<std::string> >;
1704
1705
1706
1707
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1741 const parameter_with_optional_value_container_t & where,
1742 string_view_t what )
1744 const auto it = std::find_if( where.begin(), where.end(),
1745 [&what](
const auto & pair ) {
1746 return restinio::
impl::is_equal_caseless( pair.first, what );
1748 if( it != where.end() )
1750 const auto opt = it->second;
1752 return string_view_t{ *opt };
1754 return std::optional< string_view_t >{ std::nullopt };
1770
1771
1772
1773
1774
1779 return produce< parameter_with_optional_value_container_t >(
1781 produce< parameter_with_optional_value_t >(
1785 token_p() >> to_lower()
1786 >> ¶meter_with_optional_value_t::first,
1791 >> ¶meter_with_optional_value_t::second,
1793 >> ¶meter_with_optional_value_t::second
1807
1808
1809
1810
1811
1828 return m_producer.try_parse( from );
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
A helper class to automatically return acquired content back to the input stream.
void commit() noexcept
Consume all acquired content.
content_consumer_t(source_t &from) noexcept
The class that implements "input stream".
void putback() noexcept
Return one character back to the input stream.
character_t getch() noexcept
Get the next character from the input stream.
Information about parsing error.
Exception class for all exceptions thrown by RESTinio.
exception_t(const char *err)
A template for a producer that handles possibly empty list of comma-separated values.
Element_Producer m_element
maybe_empty_comma_separated_list_producer_t(Element_Producer &&element)
expected_t< result_type, parse_error_t > try_parse(source_t &from)
A template for a producer that handles non-empty list of comma-separated values.
Element_Producer m_element
expected_t< result_type, parse_error_t > try_parse(source_t &from)
non_empty_comma_separated_list_producer_t(Element_Producer &&element)
expected_t< result_type, parse_error_t > try_parse(source_t &from) const noexcept
A type of producer that produces instances of parameter_with_optional_value_container.
params_with_opt_value_producer_t()=default
auto try_parse(source_t &from)
actual_producer_t m_producer
A type of producer that produces instances of parameter_with_mandatory_value_container.
auto try_parse(source_t &from)
actual_producer_t m_producer
params_with_value_producer_t()=default
A producer for quoted_pair.
expected_t< result_type, parse_error_t > try_parse(source_t &from) const
A producer for quoted_string.
expected_t< result_type, parse_error_t > try_parse(source_t &from) const
static std::optional< parse_error_t > try_parse_value(source_t &from, std::string &accumulator)
A helper class to be used to accumulate actual integer while when the next digit is extracted from th...
void consume(zero_initialized_unit_t &dest, char &&digit)
const qvalue_t::underlying_uint_t m_multiplier
constexpr digit_consumer_t(qvalue_t::underlying_uint_t m)
An implementation of producer of qvalue.
expected_t< result_type, parse_error_t > try_parse(source_t &from) const noexcept
expected_t< result_type, parse_error_t > try_parse(source_t &from) const
static std::optional< parse_error_t > try_parse_value(source_t &from, std::string &accumulator)
static constexpr bool is_token_char(const char ch) noexcept
A helper wrapper to indicate that value is already checked and shouldn't be checked again.
const underlying_uint_t m_value
constexpr trusted(underlying_uint_t value) noexcept
constexpr auto get() const noexcept
A helper wrapper to indicate that value hasn't been checked yet and should be checked in the construc...
auto get() const noexcept
untrusted(underlying_uint_t value)
underlying_uint_t m_value
A class for holding the parsed value of qvalue from RFC7231.
qvalue_details::untrusted untrusted
The type that checks a value to be used for qvalue.
constexpr qvalue_t(qvalue_details::extremum_min_t) noexcept
constexpr auto as_uint() const noexcept
std::array< char, 6 > underlying_char_array_t
qvalue_details::trusted trusted
The type that doesn't check a value to be used for qvalue.
underlying_char_array_t make_char_array() const noexcept
static constexpr qvalue_details::extremum_min_t zero
The indicator that tells that new qvalue object should have the minimal allowed value.
constexpr qvalue_t()=default
constexpr qvalue_t(trusted val) noexcept
underlying_uint_t m_value
constexpr qvalue_t(qvalue_details::extremum_max_t) noexcept
qvalue_t(untrusted val) noexcept
static constexpr qvalue_details::extremum_max_t maximum
The indicator that tells that new qvalue object should have the maximal allowed value.
constexpr char HTAB
A constant for Horizontal Tab value.
constexpr char SP
A constant for SPACE value.
constexpr bool is_space(const char ch) noexcept
If a character a space character?
constexpr bool is_digit(const char ch) noexcept
Is a character a decimal digit?
auto to_container()
A factory function to create a to_container_consumer.
error_reason_t
Reason of parsing error.
@ unexpected_eof
Unexpected end of input is encontered when some character expected.
@ unexpected_character
Unexpected character is found in the input.
@ pattern_not_found
Required pattern is not found in the input.
auto make_parser()
Helper function that creates an instance of producer of parameter_with_optional_value_container.
auto make_parser()
Helper function that creates an instance of producer of parameter_with_mandatory_value_container.
constexpr bool is_qdtext(const char ch) noexcept
Is a character a qdtext?
constexpr bool is_ctext(const char ch) noexcept
Is a character a ctext?
constexpr bool is_obs_text(const char ch) noexcept
Is a character an obs_text?
constexpr bool is_vchar(const char ch) noexcept
Is a character a VCHAR?
constexpr bool is_alpha(const char ch) noexcept
Is a character an ALPHA?
constexpr underlying_uint_t zero
The minimal allowed value for a qvalue.
constexpr underlying_uint_t maximum
The maximal allowed value for a qvalue.
impl::params_with_value_producer_t params_with_value_p()
A factory of producer of parameter_with_mandatory_value_container.
auto maybe_empty_comma_separated_list_p(Element_Producer element)
A factory for a producer that handles possibly empty list of comma-separated values.
expected_t< string_view_t, not_found_t > find_first(const parameter_with_mandatory_value_container_t &where, string_view_t what)
A helper function to find the first occurence of a parameter with the specified value.
auto vchar_symbol_p()
A factory for producer of VCHAR symbols.
auto qvalue_p() noexcept
A factory function to create a qvalue_producer.
auto ows_p() noexcept
A factory function to create an ows_producer.
auto token_p() noexcept
A factory function to create a token_producer.
auto ctext_symbol_p()
A factory for producer of ctext symbols.
bool operator==(const qvalue_t &a, const qvalue_t &b) noexcept
auto expected_token_p(string_view_t token)
A factory function to create a producer that expect a token with specific value.
auto non_empty_comma_separated_list_p(Element_Producer element)
A factory for a producer that handles non-empty list of comma-separated values.
auto alpha_symbol_p()
A factory for producer of ALPHA symbols.
auto token_symbol_p() noexcept
A factory for producer of symbols than can be used in tokens.
bool operator!=(const qvalue_t &a, const qvalue_t &b) noexcept
std::pair< std::string, std::optional< std::string > > parameter_with_optional_value_t
A type that describes a parameter with optional value.
auto alphanum_symbol_p()
A factory for producer of symbol that an ALPHA or DIGIT.
bool operator<=(const qvalue_t &a, const qvalue_t &b) noexcept
auto weight_p() noexcept
A factory function to create a producer for weight parameter.
auto ows() noexcept
A factory function to create an OWS clause.
std::pair< std::string, std::string > parameter_with_mandatory_value_t
A type that describes a parameter with mandatory value.
auto quoted_pair_p() noexcept
A factory function to create a quoted_pair_producer.
impl::params_with_opt_value_producer_t params_with_opt_value_p()
A factory of producer of parameter_with_optional_value_container.
bool operator<(const qvalue_t &a, const qvalue_t &b) noexcept
auto quoted_string_p() noexcept
A factory function to create a quoted_string_producer.
auto comment_p()
A factory for producer of comment token.
auto expected_caseless_token_p(string_view_t token)
A factory function to create a producer that expect a token with specific value.
One character extracted from the input stream.
A special base class to be used with consumers.
A special base class to be used with producers.
A preducate for symbol_producer_template that checks that a symbol is an alpha.
bool operator()(const char actual) const noexcept
A preducate for symbol_producer_template that checks that a symbol is an alpha or numeric.
bool operator()(const char actual) const noexcept
A preducate for symbol_producer_template that checks that a symbol is a ctext.
bool operator()(const char actual) const noexcept
A predicate for symbol_producer_template that checks that a symbol can be used inside a token.
static constexpr bool is_token_char(const char ch) noexcept
bool operator()(const char actual) const noexcept
A preducate for symbol_producer_template that checks that a symbol is a VCHAR.
bool operator()(const char actual) const noexcept
qvalue_t::underlying_uint_t m_value
An empty type to be used as indicator of negative search result.