22#elif defined(__APPLE__)
23#include <netinet/in.h>
37#pragma warning(disable: 4100)
40#define ENUM_FLAG_OPERATOR(T,X) \
41inline T operator X (const T lhs, const T rhs) { return static_cast<T>(static_cast<std::underlying_type_t<T>>(lhs) X static_cast<std::underlying_type_t<T>>(rhs)); } \
42inline T operator X (const T lhs, const std::underlying_type_t<T> rhs) { return static_cast<T>(static_cast<std::underlying_type_t<T>>(lhs) X rhs); } \
43inline T operator X (const std::underlying_type_t<T> lhs, const T rhs) { return static_cast<T>(lhs X static_cast<std::underlying_type_t<T>>(rhs)); } \
44inline T& operator X= (T& lhs, const T rhs) { return lhs = lhs X rhs; } \
45inline T& operator X= (T& lhs, const std::underlying_type_t<T> rhs) { return lhs = lhs X rhs; }
46#define ENUM_FLAGS(T, type) \
48inline T operator ~ (T t) { return (T) (~static_cast<std::underlying_type_t <T>>(t)); } \
49ENUM_FLAG_OPERATOR(T,|) \
50ENUM_FLAG_OPERATOR(T,^) \
51ENUM_FLAG_OPERATOR(T,&) \
61 constexpr int match_default = 0;
62 constexpr int match_case_insensitive = 0x1;
63 constexpr int match_multiline = 0x2;
72 basic_parser(
_In_ const std::locale& locale = std::locale()) : m_locale(locale) {}
76 _In_reads_or_z_(end)
const T*
text,
77 _In_ size_t start = 0,
78 _In_ size_t end = (
size_t)-1,
81 for (
size_t i = start;
i < end &&
text[
i];
i++)
88 _In_reads_or_z_(end)
const T*
text,
89 _In_ size_t start = 0,
90 _In_ size_t end = (
size_t)-1,
93 template<
class _Traits,
class _Ax>
95 const std::basic_string<T, _Traits, _Ax>&
text,
96 _In_ size_t start = 0,
97 _In_ size_t end = (
size_t)-1,
100 return match(
text.c_str(), start, std::min<size_t>(end,
text.size()),
flags);
103 virtual void invalidate()
113 if (
text[start] ==
'&') {
115 const auto&
ctype = std::use_facet<std::ctype<T>>(m_locale);
124 if (
n >= 2 &&
text[start + 1] ==
'#') {
127 if (
text[start + 2] ==
'x' ||
text[start + 2] ==
'X')
128 unicode = strtou32(
text + start + 3,
n - 2,
nullptr, 16);
130 unicode = strtou32(
text + start + 2,
n - 1,
nullptr, 10);
137 ucs4_to_surrogate_pair(buf,
unicode);
161 buf[0] =
text[start];
172 std::locale m_locale;
192 _In_reads_or_z_(end)
const T*
text,
193 _In_ size_t start = 0,
194 _In_ size_t end = (
size_t)-1,
198 if (start < end &&
text[start]) {
226 _In_reads_or_z_(end)
const T*
text,
227 _In_ size_t start = 0,
228 _In_ size_t end = (
size_t)-1,
232 if (start < end &&
text[start]) {
258 _In_reads_or_z_(end)
const char*
text,
259 _In_ size_t start = 0,
260 _In_ size_t end = (
size_t)-1,
264 if (start < end &&
text[start]) {
265 if (
text[start] ==
'&') {
267 const auto&
ctype = std::use_facet<std::ctype<char>>(m_locale);
300 _In_reads_or_z_(end)
const T*
text,
301 _In_ size_t start = 0,
302 _In_ size_t end = (
size_t)-1,
306 if (start < end &&
text[start]) {
308 if (
flags & match_case_insensitive) {
309 const auto&
ctype = std::use_facet<std::ctype<T>>(this->m_locale);
313 r =
text[start] == m_chr;
314 if ((
r && !m_invert) || (!
r && m_invert)) {
342 sgml_cp(
const char*
chr,
size_t count = (
size_t)-1,
bool invert =
false,
_In_ const std::locale& locale = std::locale()) :
353 _In_reads_or_z_(end)
const char*
text,
354 _In_ size_t start = 0,
355 _In_ size_t end = (
size_t)-1,
359 if (start < end &&
text[start]) {
362 bool r = ((
flags & match_case_insensitive) ?
363 stdex::strnicmp(
chr, (
size_t)-1, m_chr.c_str(), m_chr.size(), m_locale) :
364 stdex::strncmp(
chr, (
size_t)-1, m_chr.c_str(), m_chr.size())) == 0;
365 if ((
r && !m_invert) || (!
r && m_invert)) {
392 _In_reads_or_z_(end)
const T*
text,
393 _In_ size_t start = 0,
394 _In_ size_t end = (
size_t)-1,
398 if (start < end &&
text[start]) {
400 ((
flags & match_multiline) || !islbreak(
text[start])) &&
401 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::space,
text[start]);
402 if ((
r && !m_invert) || (!
r && m_invert)) {
434 _In_reads_or_z_(end)
const char*
text,
435 _In_ size_t start = 0,
436 _In_ size_t end = (
size_t)-1,
440 if (start < end &&
text[start]) {
445 ((
flags & match_multiline) || !islbreak(
chr, (
size_t)-1)) &&
447 if ((
r && !m_invert) || (!
r && m_invert)) {
471 _In_reads_or_z_(end)
const T*
text,
472 _In_ size_t start = 0,
473 _In_ size_t end = (
size_t)-1,
477 if (start < end &&
text[start]) {
478 bool r = std::use_facet<std::ctype<T>>(this->m_locale).
is(std::ctype_base::punct,
text[start]);
479 if ((
r && !m_invert) || (!
r && m_invert)) {
511 _In_reads_or_z_(end)
const char*
text,
512 _In_ size_t start = 0,
513 _In_ size_t end = (
size_t)-1,
517 if (start < end &&
text[start]) {
522 if ((
r && !m_invert) || (!
r && m_invert)) {
545 _In_reads_or_z_(end)
const T*
text,
546 _In_ size_t start = 0,
547 _In_ size_t end = (
size_t)-1,
551 if (start < end &&
text[start]) {
553 ((
flags & match_multiline) || !islbreak(
text[start])) &&
554 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::space | std::ctype_base::punct,
text[start]);
555 if ((
r && !m_invert) || (!
r && m_invert)) {
587 _In_reads_or_z_(end)
const char*
text,
588 _In_ size_t start = 0,
589 _In_ size_t end = (
size_t)-1,
593 if (start < end &&
text[start]) {
598 ((
flags & match_multiline) || !islbreak(
chr, (
size_t)-1)) &&
599 std::use_facet<std::ctype<wchar_t>>(m_locale).
scan_not(std::ctype_base::space | std::ctype_base::punct,
chr,
chr_end) ==
chr_end;
600 if ((
r && !m_invert) || (!
r && m_invert)) {
620 _In_reads_or_z_(end)
const T*
text,
621 _In_ size_t start = 0,
622 _In_ size_t end = (
size_t)-1,
626 bool r = start == 0 || (start <= end && islbreak(
text[start - 1]));
627 if ((
r && !m_invert) || (!
r && m_invert)) {
658 _In_reads_or_z_(end)
const T*
text,
659 _In_ size_t start = 0,
660 _In_ size_t end = (
size_t)-1,
664 bool r = islbreak(
text[start]);
665 if ((
r && !m_invert) || (!
r && m_invert)) {
692 hit_offset((
size_t)-1),
697 _In_reads_or_z_(end)
const T*
text,
698 _In_ size_t start = 0,
699 _In_ size_t end = (
size_t)-1,
702 virtual void invalidate()
723 _In_reads_or_z_(
count)
const T* set,
726 _In_ const std::locale& locale = std::locale()) :
730 m_set.assign(set, set + stdex::strnlen(set,
count));
734 _In_reads_or_z_(end)
const T*
text,
735 _In_ size_t start = 0,
736 _In_ size_t end = (
size_t)-1,
740 if (start < end &&
text[start]) {
741 const T* set = m_set.c_str();
742 size_t r = (
flags & match_case_insensitive) ?
743 stdex::strnichr(set, m_set.size(),
text[start], this->m_locale) :
744 stdex::strnchr(set, m_set.size(),
text[start]);
745 if ((
r != stdex::npos && !this->m_invert) || (
r == stdex::npos && this->m_invert)) {
746 this->hit_offset =
r;
751 this->hit_offset = (
size_t)-1;
757 std::basic_string<T> m_set;
774 sgml_cp_set(
const char* set,
size_t count = (
size_t)-1,
bool invert =
false,
_In_ const std::locale& locale = std::locale()) :
778 m_set = sgml2wstr(set,
count);
782 _In_reads_or_z_(end)
const char*
text,
783 _In_ size_t start = 0,
784 _In_ size_t end = (
size_t)-1,
788 if (start < end &&
text[start]) {
791 const wchar_t* set = m_set.c_str();
792 size_t r = (
flags & match_case_insensitive) ?
793 stdex::strnistr(set, m_set.size(),
chr, m_locale) :
794 stdex::strnstr(set, m_set.size(),
chr);
795 if ((
r != stdex::npos && !m_invert) || (
r == stdex::npos && m_invert)) {
818 _In_reads_or_z_(
count)
const T*
str,
820 _In_ const std::locale& locale = std::locale()) :
826 _In_reads_or_z_(end)
const T*
text,
827 _In_ size_t start = 0,
828 _In_ size_t end = (
size_t)-1,
834 n = std::min<size_t>(end - start,
m);
835 bool r = ((
flags & match_case_insensitive) ?
836 stdex::strnicmp(
text + start,
n, m_str.c_str(),
m, this->m_locale) :
837 stdex::strncmp(
text + start,
n, m_str.c_str(),
m)) == 0;
847 std::basic_string<T> m_str;
870 _In_reads_or_z_(end)
const char*
text,
871 _In_ size_t start = 0,
872 _In_ size_t end = (
size_t)-1,
876 const wchar_t*
str = m_str.c_str();
878 const auto&
ctype = std::use_facet<std::ctype<wchar_t>>(m_locale);
920 _In_reads_or_z_(end)
const T*
text,
921 _In_ size_t start = 0,
922 _In_ size_t end = (
size_t)-1,
927 for (
size_t i = 0; ;
i++) {
946 std::shared_ptr<basic_parser<T>>
m_el;
974 _In_ const std::locale& locale = std::locale()) :
978 m_collection.reserve(
count);
980 m_collection.push_back(
el[
i]);
985 _In_ const std::locale& locale = std::locale()) :
990 virtual void invalidate()
992 for (
auto&
el: m_collection)
998 std::vector<std::shared_ptr<basic_parser<T>>> m_collection;
1011 _In_ const std::locale& locale = std::locale()) :
1017 _In_ const std::locale& locale = std::locale()) :
1022 _In_reads_or_z_(end)
const T*
text,
1023 _In_ size_t start = 0,
1024 _In_ size_t end = (
size_t)-1,
1029 for (
auto i = this->m_collection.begin();
i != this->m_collection.end(); ++
i) {
1031 for (++
i;
i != this->m_collection.end(); ++
i)
1061 hit_offset((
size_t)-1)
1068 _In_ const std::locale& locale = std::locale()) :
1070 hit_offset((
size_t)-1)
1075 _In_ const std::locale& locale = std::locale()) :
1077 hit_offset((
size_t)-1)
1081 _In_reads_or_z_(end)
const T*
text,
1082 _In_ size_t start = 0,
1083 _In_ size_t end = (
size_t)-1,
1088 for (
auto i = this->m_collection.begin();
i != this->m_collection.end(); ++
i, ++hit_offset) {
1089 if ((*i)->match(
text, start, end,
flags)) {
1091 for (++
i;
i != this->m_collection.end(); ++
i)
1101 virtual void invalidate()
1123 template <
class T,
class T_parser = basic_
string<T>>
1130 _In_ const std::locale& locale = std::locale()) :
1163 offset += stdex::strnlen(
str_z + offset,
count - offset) + 1, ++
n);
1164 this->m_collection.reserve(
n);
1168 offset += stdex::strnlen(
str_z + offset,
count - offset) + 1)
1169 this->m_collection.push_back(std::move(std::make_shared<T_parser>(
str_z + offset,
count - offset,
this->m_locale)));
1177 this->m_collection.push_back(std::move(std::make_shared<T_parser>(
str, (
size_t)-1,
this->m_locale)));
1178 (
p =
va_arg(params,
const T*)) !=
nullptr;
1179 this->m_collection.push_back(std::move(std::make_shared<T_parser>(
p, (
size_t)-1, this->m_locale))));
1202 _In_ const std::locale& locale = std::locale()) :
1208 _In_ const std::locale& locale = std::locale()) :
1213 _In_reads_or_z_(end)
const T*
text,
1214 _In_ size_t start = 0,
1215 _In_ size_t end = (
size_t)-1,
1219 for (
auto&
el: this->m_collection)
1221 if (match_recursively(
text, start, end,
flags)) {
1230 bool match_recursively(
1231 _In_reads_or_z_(end)
const T*
text,
1232 _In_ size_t start = 0,
1233 _In_ size_t end = (
size_t)-1,
1237 for (
auto&
el: this->m_collection) {
1280 virtual void invalidate()
1308 _In_ const std::locale& locale = std::locale()) :
1323 _In_reads_or_z_(end)
const T*
text,
1324 _In_ size_t start = 0,
1325 _In_ size_t end = (
size_t)-1,
1353 std::shared_ptr<basic_parser<T>>
1385 _In_ const std::locale& locale = std::locale()) :
1390 m_separator(separator)
1394 _In_reads_or_z_(end)
const T*
text,
1395 _In_ size_t start = 0,
1396 _In_ size_t end = (
size_t)-1,
1400 if (m_digits->match(
text, start, end,
flags)) {
1402 this->
value = m_digits->value;
1407 if (m_digits->interval.size() <= 3) {
1409 size_t hit_offset = (
size_t)-1;
1411 (hit_offset == (
size_t)-1 || hit_offset == m_separator->hit_offset) &&
1412 m_digits->match(
text, m_separator->interval.end, end,
flags) &&
1413 m_digits->interval.size() == 3)
1416 this->
value = this->
value * 1000 + m_digits->value;
1420 hit_offset = m_separator->hit_offset;
1431 virtual void invalidate()
1443 std::shared_ptr<basic_integer10<T>> m_digits;
1444 std::shared_ptr<basic_set<T>> m_separator;
1480 _In_ const std::locale& locale = std::locale()) :
1501 _In_reads_or_z_(end)
const T*
text,
1502 _In_ size_t start = 0,
1503 _In_ size_t end = (
size_t)-1,
1537 std::shared_ptr<basic_parser<T>>
1582 _In_ const std::locale& locale = std::locale()) :
1596 _In_reads_or_z_(end)
const T*
text,
1597 _In_ size_t start = 0,
1598 _In_ size_t end = (
size_t)-1,
1619 if (
dig[4] == (
size_t)-1)
dig[4] =
dig[0];
1627 this->
value += dig[0];
1630 (
dig[1] == 1 && (
dig[0] == 5 ||
dig[0] == 10)) ||
1631 (
dig[1] == 10 && (
dig[0] == 50 ||
dig[0] == 100)) ||
1632 (
dig[1] == 100 && (
dig[0] == 500 ||
dig[0] == 1000)) ||
1633 (
dig[1] == 1000 && (
dig[0] == 5000 ||
dig[0] == 10000)))
1640 this->
value -= dig[1];
1644 this->
value += dig[0];
1660 std::shared_ptr<basic_parser<T>>
1692 _In_ const std::locale& locale = std::locale()) :
1700 _In_reads_or_z_(end)
const T*
text,
1701 _In_ size_t start = 0,
1702 _In_ size_t end = (
size_t)-1,
1706 if (numerator->match(
text, start, end,
flags) &&
1707 fraction_line->match(
text, numerator->interval.end, end,
flags) &&
1708 denominator->match(
text, fraction_line->interval.end, end,
flags))
1714 numerator->invalidate();
1715 fraction_line->invalidate();
1716 denominator->invalidate();
1721 virtual void invalidate()
1723 numerator->invalidate();
1724 fraction_line->invalidate();
1725 denominator->invalidate();
1730 std::shared_ptr<basic_parser<T>> numerator;
1731 std::shared_ptr<basic_parser<T>> fraction_line;
1732 std::shared_ptr<basic_parser<T>> denominator;
1756 _In_ const std::locale& locale = std::locale()) :
1765 _In_reads_or_z_(end)
const T*
text,
1766 _In_ size_t start = 0,
1767 _In_ size_t end = (
size_t)-1,
1799 separator->invalidate();
1800 guest->invalidate();
1805 virtual void invalidate()
1808 separator->invalidate();
1809 guest->invalidate();
1814 std::shared_ptr<basic_parser<T>> home;
1815 std::shared_ptr<basic_parser<T>> separator;
1816 std::shared_ptr<basic_parser<T>> guest;
1819 std::shared_ptr<basic_parser<T>> m_space;
1843 _In_ const std::locale& locale = std::locale()) :
1852 _In_reads_or_z_(end)
const T*
text,
1853 _In_ size_t start = 0,
1854 _In_ size_t end = (
size_t)-1,
1892 virtual void invalidate()
1931 _In_ const std::locale& locale = std::locale()) :
1942 _In_reads_or_z_(end)
const T*
text,
1943 _In_ size_t start = 0,
1944 _In_ size_t end = (
size_t)-1,
2013 virtual void invalidate()
2031 std::shared_ptr<basic_parser<T>> m_space;
2061 _In_ const std::locale& locale = std::locale()) :
2073 value(std::numeric_limits<double>::quiet_NaN())
2077 _In_reads_or_z_(end)
const T*
text,
2078 _In_ size_t start = 0,
2079 _In_ size_t end = (
size_t)-1,
2117 if (
integer->interval.empty() &&
2173 virtual void invalidate()
2185 value = std::numeric_limits<double>::quiet_NaN();
2227 _In_ const std::locale& locale = std::locale()) :
2239 _In_reads_or_z_(end)
const T*
text,
2240 _In_ size_t start = 0,
2241 _In_ size_t end = (
size_t)-1,
2291 if (
integer->interval.empty() &&
2310 virtual void invalidate()
2360 _In_ const std::locale& locale = std::locale()) :
2372 m_separator(separator)
2378 _In_reads_or_z_(end)
const T*
text,
2379 _In_ size_t start = 0,
2380 _In_ size_t end = (
size_t)-1,
2388 for (
i = 0;
i < 4;
i++) {
2446 virtual void invalidate()
2465 std::shared_ptr<basic_parser<T>>
2476 std::shared_ptr<basic_parser<T>> m_separator;
2498 _In_reads_or_z_(end)
const T*
text,
2499 _In_ size_t start = 0,
2500 _In_ size_t end = (
size_t)-1,
2504 if (start < end &&
text[start]) {
2505 if (
text[start] ==
'-' ||
2506 text[start] ==
'_' ||
2507 text[start] ==
':' ||
2508 std::use_facet<std::ctype<T>>(this->m_locale).
is(std::ctype_base::alnum,
text[start]))
2536 _In_reads_or_z_(end)
const char*
text,
2537 _In_ size_t start = 0,
2538 _In_ size_t end = (
size_t)-1,
2542 if (start < end &&
text[start]) {
2546 if (((
chr[0] ==
L'-' ||
2548 chr[0] ==
L':') &&
chr[1] == 0) ||
2587 _In_ const std::locale& locale = std::locale()) :
2605 m_separator(separator),
2613 _In_reads_or_z_(end)
const T*
text,
2614 _In_ size_t start = 0,
2615 _In_ size_t end = (
size_t)-1,
2623 for (
i = 0;
i < 8;
i++) {
2627 if (m_separator->match(
text, m_separator->interval.end, end,
flags)) {
2676 if (
x_n <= 0xffff) {
2699 this->
value.s6_words[--j] = this->
value.s6_words[--k];
2703 this->
value.s6_words[--j] = 0;
2743 virtual void invalidate()
2772 std::shared_ptr<basic_parser<T>>
2789 std::shared_ptr<basic_parser<T>> m_separator, m_scope_id_separator;
2810 _In_ const std::locale& locale = std::locale()) :
2817 _In_reads_or_z_(end)
const T*
text,
2818 _In_ size_t start = 0,
2819 _In_ size_t end = (
size_t)-1,
2823 if (start < end &&
text[start]) {
2824 if ((
'A' <=
text[start] &&
text[start] <=
'Z') ||
2825 (
'a' <=
text[start] &&
text[start] <=
'z') ||
2826 (
'0' <=
text[start] &&
text[start] <=
'9'))
2828 else if (
text[start] ==
'-')
2830 else if (m_allow_idn && std::use_facet<std::ctype<T>>(this->m_locale).
is(std::ctype_base::alnum,
text[start]))
2866 _In_ const std::locale& locale = std::locale()) :
2871 _In_reads_or_z_(end)
const char*
text,
2872 _In_ size_t start = 0,
2873 _In_ size_t end = (
size_t)-1,
2877 if (start < end &&
text[start]) {
2881 if (((
'A' <=
chr[0] &&
chr[0] <=
'Z') ||
2882 (
'a' <=
chr[0] &&
chr[0] <=
'z') ||
2883 (
'0' <=
chr[0] &&
chr[0] <=
'9')) &&
chr[1] == 0)
2885 else if (
chr[0] ==
'-' &&
chr[1] == 0)
2887 else if (m_allow_idn && std::use_facet<std::ctype<wchar_t>>(m_locale).
scan_not(std::ctype_base::alnum,
chr,
chr_end) ==
chr_end)
2912 _In_ const std::locale& locale = std::locale()) :
2916 m_separator(separator)
2920 _In_reads_or_z_(end)
const T*
text,
2921 _In_ size_t start = 0,
2922 _In_ size_t end = (
size_t)-1,
2928 if (m_domain_char->match(
text,
i, end,
flags) &&
2929 m_domain_char->allow_on_edge)
2933 while (
i < end &&
text[
i]) {
2934 if (m_domain_char->allow_on_edge &&
2942 i = m_separator->interval.end;
2946 if (m_domain_char->match(
text,
i, end,
flags)) {
2947 if (m_domain_char->allow_on_edge)
2950 i = m_domain_char->interval.end;
2971 std::shared_ptr<basic_dns_domain_char<T>> m_domain_char;
2972 std::shared_ptr<basic_parser<T>> m_separator;
2994 _In_reads_or_z_(end)
const T*
text,
2995 _In_ size_t start = 0,
2996 _In_ size_t end = (
size_t)-1,
3000 if (start < end &&
text[start]) {
3001 if (
text[start] ==
'-' ||
3002 text[start] ==
'.' ||
3003 text[start] ==
'_' ||
3004 text[start] ==
'~' ||
3005 text[start] ==
'%' ||
3006 text[start] ==
'!' ||
3007 text[start] ==
'$' ||
3008 text[start] ==
'&' ||
3009 text[start] ==
'\'' ||
3012 text[start] ==
'*' ||
3013 text[start] ==
'+' ||
3014 text[start] ==
',' ||
3015 text[start] ==
';' ||
3016 text[start] ==
'=' ||
3017 std::use_facet<std::ctype<T>>(this->m_locale).
is(std::ctype_base::alnum,
text[start]))
3045 _In_reads_or_z_(end)
const char*
text,
3046 _In_ size_t start = 0,
3047 _In_ size_t end = (
size_t)-1,
3051 if (start < end &&
text[start]) {
3055 if (((
chr[0] ==
L'-' ||
3070 chr[0] ==
L'=') &&
chr[1] == 0) ||
3093 _In_reads_or_z_(end)
const T*
text,
3094 _In_ size_t start = 0,
3095 _In_ size_t end = (
size_t)-1,
3099 if (start < end &&
text[start]) {
3100 if (
text[start] ==
'-' ||
3101 text[start] ==
'.' ||
3102 text[start] ==
'_' ||
3103 text[start] ==
'~' ||
3104 text[start] ==
'%' ||
3105 text[start] ==
'!' ||
3106 text[start] ==
'$' ||
3107 text[start] ==
'&' ||
3108 text[start] ==
'\'' ||
3109 text[start] ==
'(' ||
3110 text[start] ==
')' ||
3111 text[start] ==
'*' ||
3112 text[start] ==
'+' ||
3113 text[start] ==
',' ||
3114 text[start] ==
';' ||
3115 text[start] ==
'=' ||
3116 text[start] ==
':' ||
3117 std::use_facet<std::ctype<T>>(this->m_locale).
is(std::ctype_base::alnum,
text[start]))
3145 _In_reads_or_z_(end)
const char*
text,
3146 _In_ size_t start = 0,
3147 _In_ size_t end = (
size_t)-1,
3151 if (start < end &&
text[start]) {
3155 if (((
chr[0] ==
L'-' ||
3171 chr[0] ==
L':') &&
chr[1] == 0) ||
3193 _In_reads_or_z_(end)
const T*
text,
3194 _In_ size_t start = 0,
3195 _In_ size_t end = (
size_t)-1,
3199 if (start < end &&
text[start]) {
3200 if (
text[start] ==
'/' ||
3201 text[start] ==
'-' ||
3202 text[start] ==
'.' ||
3203 text[start] ==
'_' ||
3204 text[start] ==
'~' ||
3205 text[start] ==
'%' ||
3206 text[start] ==
'!' ||
3207 text[start] ==
'$' ||
3208 text[start] ==
'&' ||
3209 text[start] ==
'\'' ||
3210 text[start] ==
'(' ||
3211 text[start] ==
')' ||
3212 text[start] ==
'*' ||
3213 text[start] ==
'+' ||
3214 text[start] ==
',' ||
3215 text[start] ==
';' ||
3216 text[start] ==
'=' ||
3217 text[start] ==
':' ||
3218 text[start] ==
'@' ||
3219 text[start] ==
'?' ||
3220 text[start] ==
'#' ||
3221 std::use_facet<std::ctype<T>>(this->m_locale).
is(std::ctype_base::alnum,
text[start]))
3249 _In_reads_or_z_(end)
const char*
text,
3250 _In_ size_t start = 0,
3251 _In_ size_t end = (
size_t)-1,
3255 if (start < end &&
text[start]) {
3259 if (((
chr[0] ==
L'/' ||
3279 chr[0] ==
L'#') &&
chr[1] == 0) ||
3302 _In_ const std::locale& locale = std::locale()) :
3310 _In_reads_or_z_(end)
const T*
text,
3311 _In_ size_t start = 0,
3312 _In_ size_t end = (
size_t)-1,
3401 virtual void invalidate()
3418 std::shared_ptr<basic_parser<T>> m_path_char;
3419 std::shared_ptr<basic_parser<T>> m_query_start;
3420 std::shared_ptr<basic_parser<T>> m_bookmark_start;
3456 _In_ const std::locale& locale = std::locale()) :
3477 _In_reads_or_z_(end)
const T*
text,
3478 _In_ size_t start = 0,
3479 _In_ size_t end = (
size_t)-1,
3487 m_colon->match(
text, http_scheme->interval.end, end,
flags) &&
3488 m_slash->match(
text, m_colon->interval.end, end,
flags) &&
3489 m_slash->match(
text, m_slash->interval.end, end,
flags))
3493 ftp_scheme->invalidate();
3494 mailto_scheme->invalidate();
3495 file_scheme->invalidate();
3498 m_colon->match(
text, ftp_scheme->interval.end, end,
flags) &&
3499 m_slash->match(
text, m_colon->interval.end, end,
flags) &&
3500 m_slash->match(
text, m_slash->interval.end, end,
flags))
3504 http_scheme->invalidate();
3505 mailto_scheme->invalidate();
3506 file_scheme->invalidate();
3509 m_colon->match(
text, mailto_scheme->interval.end, end,
flags))
3513 http_scheme->invalidate();
3514 ftp_scheme->invalidate();
3515 file_scheme->invalidate();
3518 m_colon->match(
text, file_scheme->interval.end, end,
flags) &&
3519 m_slash->match(
text, m_colon->interval.end, end,
flags) &&
3520 m_slash->match(
text, m_slash->interval.end, end,
flags))
3524 http_scheme->invalidate();
3525 ftp_scheme->invalidate();
3526 mailto_scheme->invalidate();
3530 http_scheme->invalidate();
3531 ftp_scheme->invalidate();
3532 mailto_scheme->invalidate();
3533 file_scheme->invalidate();
3536 if (ftp_scheme->interval) {
3538 if (m_colon->match(
text, username->interval.end, end,
flags) &&
3539 password->match(
text, m_colon->interval.end, end,
flags) &&
3540 m_at->match(
text, password->interval.end, end,
flags))
3548 password->invalidate();
3551 username->invalidate();
3552 password->invalidate();
3556 username->invalidate();
3557 password->invalidate();
3563 ipv6_host->invalidate();
3564 dns_host->invalidate();
3568 ipv6_host->match(
text, m_ip_lbracket->interval.end, end,
flags) &&
3569 m_ip_rbracket->match(
text, ipv6_host->interval.end, end,
flags))
3573 ipv4_host->invalidate();
3574 dns_host->invalidate();
3579 ipv4_host->invalidate();
3580 ipv6_host->invalidate();
3588 port->match(
text, m_colon->interval.end, end,
flags))
3605 if (mailto_scheme->interval) {
3607 m_at->match(
text, username->interval.end, end,
flags))
3618 ipv4_host->match(
text, m_ip_lbracket->interval.end, end,
flags) &&
3619 m_ip_rbracket->match(
text, ipv4_host->interval.end, end,
flags))
3623 ipv6_host->invalidate();
3624 dns_host->invalidate();
3628 ipv6_host->match(
text, m_ip_lbracket->interval.end, end,
flags) &&
3629 m_ip_rbracket->match(
text, ipv6_host->interval.end, end,
flags))
3633 ipv4_host->invalidate();
3634 dns_host->invalidate();
3639 ipv4_host->invalidate();
3640 ipv6_host->invalidate();
3647 password->invalidate();
3654 if (file_scheme->interval) {
3660 username->invalidate();
3661 password->invalidate();
3662 ipv4_host->invalidate();
3663 ipv6_host->invalidate();
3664 dns_host->invalidate();
3673 if (http_scheme->interval &&
3676 if (m_colon->match(
text, username->interval.end, end,
flags) &&
3677 password->match(
text, m_colon->interval.end, end,
flags) &&
3678 m_at->match(
text, password->interval.end, end,
flags))
3683 else if (m_at->match(
text, username->interval.end, end,
flags)) {
3686 password->invalidate();
3689 username->invalidate();
3690 password->invalidate();
3694 username->invalidate();
3695 password->invalidate();
3701 ipv6_host->invalidate();
3702 dns_host->invalidate();
3706 ipv6_host->match(
text, m_ip_lbracket->interval.end, end,
flags) &&
3707 m_ip_rbracket->match(
text, ipv6_host->interval.end, end,
flags))
3711 ipv4_host->invalidate();
3712 dns_host->invalidate();
3717 ipv4_host->invalidate();
3718 ipv6_host->invalidate();
3726 port->match(
text, m_colon->interval.end, end,
flags))
3743 virtual void invalidate()
3745 http_scheme->invalidate();
3746 ftp_scheme->invalidate();
3747 mailto_scheme->invalidate();
3748 file_scheme->invalidate();
3749 username->invalidate();
3750 password->invalidate();
3751 ipv4_host->invalidate();
3752 ipv6_host->invalidate();
3753 dns_host->invalidate();
3760 std::shared_ptr<basic_parser<T>> http_scheme;
3761 std::shared_ptr<basic_parser<T>> ftp_scheme;
3762 std::shared_ptr<basic_parser<T>> mailto_scheme;
3763 std::shared_ptr<basic_parser<T>> file_scheme;
3764 std::shared_ptr<basic_parser<T>> username;
3765 std::shared_ptr<basic_parser<T>> password;
3766 std::shared_ptr<basic_parser<T>> ipv4_host;
3767 std::shared_ptr<basic_parser<T>> ipv6_host;
3768 std::shared_ptr<basic_parser<T>> dns_host;
3769 std::shared_ptr<basic_parser<T>> port;
3770 std::shared_ptr<basic_parser<T>> path;
3773 std::shared_ptr<basic_parser<T>> m_colon;
3774 std::shared_ptr<basic_parser<T>> m_slash;
3775 std::shared_ptr<basic_parser<T>> m_at;
3776 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
3777 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
3804 _In_ const std::locale& locale = std::locale()) :
3816 _In_reads_or_z_(end)
const T*
text,
3817 _In_ size_t start = 0,
3818 _In_ size_t end = (
size_t)-1,
3823 if (username->match(
text, start, end,
flags) &&
3824 m_at->match(
text, username->interval.end, end,
flags))
3827 if (m_ip_lbracket->match(
text, m_at->interval.end, end,
flags) &&
3828 ipv4_host->match(
text, m_ip_lbracket->interval.end, end,
flags) &&
3829 m_ip_rbracket->match(
text, ipv4_host->interval.end, end,
flags))
3833 ipv6_host->invalidate();
3834 dns_host->invalidate();
3837 m_ip_lbracket->match(
text, m_at->interval.end, end,
flags) &&
3838 ipv6_host->match(
text, m_ip_lbracket->interval.end, end,
flags) &&
3839 m_ip_rbracket->match(
text, ipv6_host->interval.end, end,
flags))
3843 ipv4_host->invalidate();
3844 dns_host->invalidate();
3846 else if (dns_host->match(
text, m_at->interval.end, end,
flags)) {
3849 ipv4_host->invalidate();
3850 ipv6_host->invalidate();
3859 username->invalidate();
3860 ipv4_host->invalidate();
3861 ipv6_host->invalidate();
3862 dns_host->invalidate();
3867 virtual void invalidate()
3869 username->invalidate();
3870 ipv4_host->invalidate();
3871 ipv6_host->invalidate();
3872 dns_host->invalidate();
3877 std::shared_ptr<basic_parser<T>> username;
3878 std::shared_ptr<basic_parser<T>> ipv4_host;
3879 std::shared_ptr<basic_parser<T>> ipv6_host;
3880 std::shared_ptr<basic_parser<T>> dns_host;
3883 std::shared_ptr<basic_parser<T>> m_at;
3884 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
3885 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
3910 _In_ const std::locale& locale = std::locale()) :
3920 _In_reads_or_z_(end)
const T*
text,
3921 _In_ size_t start = 0,
3922 _In_ size_t end = (
size_t)-1,
3931 mouth->invalidate();
3948 hit_offset =
mouth->hit_offset;
3959 hit_offset =
mouth->hit_offset;
3974 mouth->invalidate();
3979 virtual void invalidate()
3985 mouth->invalidate();
3991 std::shared_ptr<basic_parser<T>>
apex;
3992 std::shared_ptr<basic_parser<T>>
eyes;
3993 std::shared_ptr<basic_parser<T>>
nose;
4009 enum date_format_t {
4010 date_format_none = 0,
4011 date_format_dmy = 0x1,
4012 date_format_mdy = 0x2,
4013 date_format_ymd = 0x4,
4014 date_format_ym = 0x8,
4015 date_format_my = 0x10,
4016 date_format_dm = 0x20,
4017 date_format_md = 0x40,
4034 _In_ const std::locale& locale = std::locale()) :
4036 format(date_format_none),
4041 m_separator(separator),
4046 _In_reads_or_z_(end)
const T*
text,
4047 _In_ size_t start = 0,
4048 _In_ size_t end = (
size_t)-1,
4054 if ((m_format_mask & date_format_dmy) == date_format_dmy) {
4055 if (day->match(
text, start, end,
flags)) {
4058 size_t hit_offset = m_separator->hit_offset;
4063 m_separator->hit_offset == hit_offset)
4067 is_valid(day->value, month->value))
4071 format = date_format_dmy;
4080 if ((m_format_mask & date_format_mdy) == date_format_mdy) {
4081 if (month->match(
text, start, end,
flags)) {
4084 size_t hit_offset = m_separator->hit_offset;
4089 m_separator->hit_offset == hit_offset)
4093 is_valid(day->value, month->value))
4097 format = date_format_mdy;
4106 if ((m_format_mask & date_format_ymd) == date_format_ymd) {
4107 if (year->match(
text, start, end,
flags)) {
4110 size_t hit_offset = m_separator->hit_offset;
4115 m_separator->hit_offset == hit_offset)
4119 is_valid(day->value, month->value))
4123 format = date_format_ymd;
4132 if ((m_format_mask & date_format_ym) == date_format_ym) {
4133 if (year->match(
text, start, end,
flags)) {
4138 is_valid((
size_t)-1, month->value))
4140 if (day) day->invalidate();
4143 format = date_format_ym;
4150 if ((m_format_mask & date_format_my) == date_format_my) {
4151 if (month->match(
text, start, end,
flags)) {
4156 is_valid((
size_t)-1, month->value))
4158 if (day) day->invalidate();
4161 format = date_format_my;
4168 if ((m_format_mask & date_format_dm) == date_format_dm) {
4169 if (day->match(
text, start, end,
flags)) {
4172 size_t hit_offset = m_separator->hit_offset;
4175 is_valid(day->value, month->value))
4177 if (year) year->invalidate();
4181 m_separator->hit_offset == hit_offset)
4185 format = date_format_dm;
4192 if ((m_format_mask & date_format_md) == date_format_md) {
4193 if (month->match(
text, start, end,
flags)) {
4196 size_t hit_offset = m_separator->hit_offset;
4199 is_valid(day->value, month->value))
4201 if (year) year->invalidate();
4205 m_separator->hit_offset == hit_offset)
4209 format = date_format_md;
4216 if (day) day->invalidate();
4217 if (month) month->invalidate();
4218 if (year) year->invalidate();
4219 format = date_format_none;
4224 virtual void invalidate()
4226 if (day) day->invalidate();
4227 if (month) month->invalidate();
4228 if (year) year->invalidate();
4229 format = date_format_none;
4234 static inline bool is_valid(
size_t day,
size_t month)
4236 if (month == (
size_t)-1) {
4240 if (day == (
size_t)-1) {
4253 return 1 <= day && day <= 31;
4255 return 1 <= day && day <= 29;
4260 return 1 <= day && day <= 30;
4267 date_format_t format;
4268 std::shared_ptr<basic_integer<T>> day;
4269 std::shared_ptr<basic_integer<T>> month;
4270 std::shared_ptr<basic_integer<T>> year;
4274 std::shared_ptr<basic_set<T>> m_separator;
4275 std::shared_ptr<basic_parser<T>> m_space;
4301 _In_ const std::locale& locale = std::locale()) :
4307 m_separator(separator),
4312 _In_reads_or_z_(end)
const T*
text,
4313 _In_ size_t start = 0,
4314 _In_ size_t end = (
size_t)-1,
4319 if (hour->match(
text, start, end,
flags) &&
4320 m_separator->match(
text, hour->interval.end, end,
flags) &&
4321 minute->match(
text, m_separator->interval.end, end,
flags) &&
4325 size_t hit_offset = m_separator->hit_offset;
4326 if (m_separator->match(
text, minute->interval.end, end,
flags) &&
4327 m_separator->hit_offset == hit_offset &&
4328 second && second->match(
text, m_separator->interval.end, end,
flags) &&
4332 if (m_millisecond_separator && m_millisecond_separator->match(
text, second->interval.end, end,
flags) &&
4333 millisecond && millisecond->match(
text, m_millisecond_separator->interval.end, end,
flags) &&
4334 millisecond->value < 1000)
4340 if (millisecond) millisecond->invalidate();
4345 if (second) second->invalidate();
4346 if (millisecond) millisecond->invalidate();
4354 minute->invalidate();
4355 if (second) second->invalidate();
4356 if (millisecond) millisecond->invalidate();
4361 virtual void invalidate()
4364 minute->invalidate();
4365 if (second) second->invalidate();
4366 if (millisecond) millisecond->invalidate();
4371 std::shared_ptr<basic_integer10<T>> hour;
4372 std::shared_ptr<basic_integer10<T>> minute;
4373 std::shared_ptr<basic_integer10<T>> second;
4374 std::shared_ptr<basic_integer10<T>> millisecond;
4377 std::shared_ptr<basic_set<T>> m_separator;
4378 std::shared_ptr<basic_parser<T>> m_millisecond_separator;
4405 _In_ const std::locale& locale = std::locale()) :
4417 _In_reads_or_z_(end)
const T*
text,
4418 _In_ size_t start = 0,
4419 _In_ size_t end = (
size_t)-1,
4427 degree_separator->match(
text, degree->interval.end, end,
flags))
4430 this->
interval.
end = degree_separator->interval.end;
4433 degree->invalidate();
4434 degree_separator->invalidate();
4438 minute->value < 60 &&
4439 minute_separator->match(
text, minute->interval.end, end,
flags))
4442 this->
interval.
end = minute_separator->interval.end;
4445 minute->invalidate();
4446 minute_separator->invalidate();
4455 this->
interval.
end = second_separator->interval.end;
4457 if (second_separator) second_separator->invalidate();
4460 if (second) second->invalidate();
4461 if (second_separator) second_separator->invalidate();
4464 if (degree->interval.start < degree->interval.end ||
4465 minute->interval.start < minute->interval.end ||
4466 (second && second->interval.start < second->interval.end))
4473 decimal->invalidate();
4477 if (decimal) decimal->invalidate();
4482 virtual void invalidate()
4484 degree->invalidate();
4485 degree_separator->invalidate();
4486 minute->invalidate();
4487 minute_separator->invalidate();
4488 if (second) second->invalidate();
4489 if (second_separator) second_separator->invalidate();
4490 if (decimal) decimal->invalidate();
4495 std::shared_ptr<basic_integer10<T>> degree;
4496 std::shared_ptr<basic_parser<T>> degree_separator;
4497 std::shared_ptr<basic_integer10<T>> minute;
4498 std::shared_ptr<basic_parser<T>> minute_separator;
4499 std::shared_ptr<basic_integer10<T>> second;
4500 std::shared_ptr<basic_parser<T>> second_separator;
4501 std::shared_ptr<basic_parser<T>> decimal;
4527 _In_ const std::locale& locale = std::locale()) :
4533 m_separator(separator),
4538 _In_reads_or_z_(end)
const T*
text,
4539 _In_ size_t start = 0,
4540 _In_ size_t end = (
size_t)-1,
4551 m_lparenthesis->invalidate();
4552 m_rparenthesis->invalidate();
4555 value.append(
text + m_plus_sign->interval.start,
text + m_plus_sign->interval.end);
4566 value.append(
text + m_digit->interval.start,
text + m_digit->interval.end);
4577 m_lparenthesis && !m_lparenthesis->interval &&
4578 m_rparenthesis && !m_rparenthesis->interval &&
4582 value.append(
text + m_lparenthesis->interval.start, m_lparenthesis->interval.size());
4583 this->
interval.
end = m_lparenthesis->interval.end;
4590 m_rparenthesis && !m_rparenthesis->interval &&
4592 m_lparenthesis->hit_offset == m_rparenthesis->hit_offset)
4595 value.append(
text + m_rparenthesis->interval.start,
text + m_rparenthesis->interval.end);
4596 this->
interval.
end = m_rparenthesis->interval.end;
4637 virtual void invalidate()
4647 std::shared_ptr<basic_parser<T>> m_digit;
4648 std::shared_ptr<basic_parser<T>> m_plus_sign;
4649 std::shared_ptr<basic_set<T>> m_lparenthesis;
4650 std::shared_ptr<basic_set<T>> m_rparenthesis;
4651 std::shared_ptr<basic_parser<T>> m_separator;
4652 std::shared_ptr<basic_parser<T>> m_space;
4675 _In_ const std::locale& locale = std::locale()) :
4685 _In_reads_or_z_(end)
const T*
text,
4686 _In_ size_t start = 0,
4687 _In_ size_t end = (
size_t)-1,
4720 virtual void invalidate()
4732 std::shared_ptr<basic_parser<T>> m_element;
4733 std::shared_ptr<basic_parser<T>> m_digit;
4734 std::shared_ptr<basic_parser<T>> m_sign;
4753 _In_reads_or_z_(end)
const char*
text,
4754 _In_ size_t start = 0,
4755 _In_ size_t end = (
size_t)-1,
4789 _In_reads_or_z_(end)
const char*
text,
4790 _In_ size_t start = 0,
4791 _In_ size_t end = (
size_t)-1,
4826 _In_reads_or_z_(end)
const char*
text,
4827 _In_ size_t start = 0,
4828 _In_ size_t end = (
size_t)-1,
4860 _In_reads_or_z_(end)
const char*
text,
4861 _In_ size_t start = 0,
4862 _In_ size_t end = (
size_t)-1,
4914 _In_reads_or_z_(end)
const char*
text,
4915 _In_ size_t start = 0,
4916 _In_ size_t end = (
size_t)-1,
4959 virtual void invalidate()
4963 parser::invalidate();
4980 _In_reads_or_z_(end)
const char*
text,
4981 _In_ size_t start = 0,
4982 _In_ size_t end = (
size_t)-1,
4994 string.invalidate();
5005 virtual void invalidate()
5007 string.invalidate();
5009 parser::invalidate();
5024 _In_reads_or_z_(end)
const char*
text,
5025 _In_ size_t start = 0,
5026 _In_ size_t end = (
size_t)-1,
5057 virtual void invalidate()
5061 parser::invalidate();
5079 _In_reads_or_z_(end)
const char*
text,
5080 _In_ size_t start = 0,
5081 _In_ size_t end = (
size_t)-1,
5085 if (start + 2 < end &&
5086 text[start] ==
'*' &&
5087 text[start + 1] ==
'/' &&
5088 text[start + 2] ==
'*')
5093 else if (start < end &&
text[start] ==
'*') {
5111 _In_reads_or_z_(end)
const char*
text,
5112 _In_ size_t start = 0,
5113 _In_ size_t end = (
size_t)-1,
5139 subtype.invalidate();
5144 virtual void invalidate()
5147 subtype.invalidate();
5148 parser::invalidate();
5166 _In_reads_or_z_(end)
const char*
text,
5167 _In_ size_t start = 0,
5168 _In_ size_t end = (
size_t)-1,
5172 if (!http_media_range::match(
text, start, end,
flags))
5186 params.push_back(std::move(
param));
5201 http_media_range::invalidate();
5207 virtual void invalidate()
5210 http_media_range::invalidate();
5214 std::list<http_parameter> params;
5224 _In_reads_or_z_(end)
const char*
text,
5225 _In_ size_t start = 0,
5226 _In_ size_t end = (
size_t)-1,
5266 _In_reads_or_z_(end)
const char*
text,
5267 _In_ size_t start = 0,
5268 _In_ size_t end = (
size_t)-1,
5300 virtual void invalidate()
5303 parser::invalidate();
5317 _In_reads_or_z_(end)
const char*
text,
5318 _In_ size_t start = 0,
5319 _In_ size_t end = (
size_t)-1,
5350 _In_reads_or_z_(end)
const char*
text,
5351 _In_ size_t start = 0,
5352 _In_ size_t end = (
size_t)-1,
5389 virtual void invalidate()
5392 parser::invalidate();
5406 _In_reads_or_z_(end)
const char*
text,
5407 _In_ size_t start = 0,
5408 _In_ size_t end = (
size_t)-1,
5466 virtual void invalidate()
5472 parser::invalidate();
5486 http_url(
_In_ const std::locale& locale = std::locale()) :
5492 _In_reads_or_z_(end)
const char*
text,
5493 _In_ size_t start = 0,
5494 _In_ size_t end = (
size_t)-1,
5517 server.invalidate();
5543 params.push_back(std::move(
param));
5558 server.invalidate();
5566 virtual void invalidate()
5568 server.invalidate();
5572 parser::invalidate();
5579 std::list<http_url_parameter> params;
5589 _In_reads_or_z_(end)
const char*
text,
5590 _In_ size_t start = 0,
5591 _In_ size_t end = (
size_t)-1,
5602 if (
k.end < end &&
text[
k.end]) {
5614 components.push_back(
k);
5626 if (!components.empty()) {
5635 virtual void invalidate()
5638 parser::invalidate();
5642 std::vector<stdex::interval<size_t>> components;
5657 _In_reads_or_z_(end)
const char*
text,
5658 _In_ size_t start = 0,
5659 _In_ size_t end = (
size_t)-1,
5704 virtual void invalidate()
5707 parser::invalidate();
5721 _In_reads_or_z_(end)
const char*
text,
5722 _In_ size_t start = 0,
5723 _In_ size_t end = (
size_t)-1,
5727 if (start < end &&
text[start] ==
'*') {
5739 template <
class T,
class T_asterisk = http_asterisk>
5749 _In_reads_or_z_(end)
const char*
text,
5750 _In_ size_t start = 0,
5751 _In_ size_t end = (
size_t)-1,
5763 asterisk.invalidate();
5766 asterisk.invalidate();
5788 factor.invalidate();
5795 virtual void invalidate()
5797 asterisk.invalidate();
5799 factor.invalidate();
5800 parser::invalidate();
5816 _In_reads_or_z_(end)
const char*
text,
5817 _In_ size_t start = 0,
5818 _In_ size_t end = (
size_t)-1,
5853 virtual void invalidate()
5857 parser::invalidate();
5875 _In_reads_or_z_(end)
const char*
text,
5876 _In_ size_t start = 0,
5877 _In_ size_t end = (
size_t)-1,
5933 virtual void invalidate()
5938 parser::invalidate();
5957 _In_reads_or_z_(end)
const char*
text,
5958 _In_ size_t start = 0,
5959 _In_ size_t end = (
size_t)-1,
6012 virtual void invalidate()
6018 parser::invalidate();
6038 _In_reads_or_z_(end)
const char*
text,
6039 _In_ size_t start = 0,
6040 _In_ size_t end = (
size_t)-1,
6089 version_min.
start = 1;
6090 version_min.
end = 0;
6106 version_maj.
start = 1;
6107 version_maj.
end = 0;
6108 version_min.
start = 1;
6109 version_min.
end = 0;
6116 virtual void invalidate()
6120 version_maj.
start = 1;
6121 version_maj.
end = 0;
6122 version_min.
start = 1;
6123 version_min.
end = 0;
6125 parser::invalidate();
6148 _In_reads_or_z_(end)
const char*
text,
6149 _In_ size_t start = 0,
6150 _In_ size_t end = (
size_t)-1,
6202 protocol.invalidate();
6249 protocol.invalidate();
6255 virtual void invalidate()
6260 protocol.invalidate();
6261 parser::invalidate();
6280 _In_reads_or_z_(end)
const char*
text,
6281 _In_ size_t start = 0,
6282 _In_ size_t end = (
size_t)-1,
6365 virtual void invalidate()
6371 parser::invalidate();
6385 template <
class _Key,
class T>
6390 _In_reads_or_z_(end)
const char*
text,
6391 _In_ size_t start = 0,
6392 _In_ size_t end = (
size_t)-1,
6395 while (start < end) {
6397 if (start < end &&
text[start] ==
',') {
6404 T::insert(std::move(
el));
6414 constexpr bool operator()(
const T&
a,
const T&
b)
const noexcept
6416 return a.factor.value >
b.factor.value;
6423 template <
class T,
class _Alloc = std::allocator<T>>
6445 _In_ const std::locale& locale = std::locale()) :
6461 _In_reads_or_z_(end)
const T*
text,
6462 _In_ size_t start = 0,
6463 _In_ size_t end = (
size_t)-1,
6478 if (m_quote->match(
text, m_escape->interval.end, end,
flags)) {
6479 value +=
'"'; this->
interval.
end = m_quote->interval.end;
6482 if (m_sol->match(
text, m_escape->interval.end, end,
flags)) {
6483 value +=
'/'; this->
interval.
end = m_sol->interval.end;
6486 if (m_bs->match(
text, m_escape->interval.end, end,
flags)) {
6487 value +=
'\b'; this->
interval.
end = m_bs->interval.end;
6490 if (m_ff->match(
text, m_escape->interval.end, end,
flags)) {
6491 value +=
'\f'; this->
interval.
end = m_ff->interval.end;
6494 if (m_lf->match(
text, m_escape->interval.end, end,
flags)) {
6495 value +=
'\n'; this->
interval.
end = m_lf->interval.end;
6498 if (m_cr->match(
text, m_escape->interval.end, end,
flags)) {
6499 value +=
'\r'; this->
interval.
end = m_cr->interval.end;
6502 if (m_htab->match(
text, m_escape->interval.end, end,
flags)) {
6503 value +=
'\t'; this->
interval.
end = m_htab->interval.end;
6507 m_uni->match(
text, m_escape->interval.end, end,
flags) &&
6508 m_hex->match(
text, m_uni->interval.end, std::min(m_uni->interval.end + 4, end),
flags | match_case_insensitive) &&
6509 m_hex->interval.size() == 4 )
6511 assert(m_hex->value <= 0xffff);
6512 if (
sizeof(T) == 1) {
6513 if (m_hex->value > 0x7ff) {
6514 value += (T)(0xe0 | ((m_hex->value >> 12) & 0x0f));
6515 value += (T)(0x80 | ((m_hex->value >> 6) & 0x3f));
6516 value += (T)(0x80 | (m_hex->value & 0x3f));
6518 else if (m_hex->value > 0x7f) {
6519 value += (T)(0xc0 | ((m_hex->value >> 6) & 0x1f));
6520 value += (T)(0x80 | (m_hex->value & 0x3f));
6523 value += (T)(m_hex->value & 0x7f);
6526 value += (T)m_hex->value;
6530 if (m_escape->match(
text, m_escape->interval.end, end,
flags)) {
6531 value +=
'\\'; this->
interval.
end = m_escape->interval.end;
6536 value.Prilepi(
text + m_chr->interval.start, m_chr->interval.size());
6548 virtual void invalidate()
6555 std::basic_string<T> value;
6558 std::shared_ptr<basic_parser<T>> m_quote;
6559 std::shared_ptr<basic_parser<T>> m_chr;
6560 std::shared_ptr<basic_parser<T>> m_escape;
6561 std::shared_ptr<basic_parser<T>> m_sol;
6562 std::shared_ptr<basic_parser<T>> m_bs;
6563 std::shared_ptr<basic_parser<T>> m_ff;
6564 std::shared_ptr<basic_parser<T>> m_lf;
6565 std::shared_ptr<basic_parser<T>> m_cr;
6566 std::shared_ptr<basic_parser<T>> m_htab;
6567 std::shared_ptr<basic_parser<T>> m_uni;
6568 std::shared_ptr<basic_integer16<T>> m_hex;
6581#undef ENUM_FLAG_OPERATOR
Test for angle in d°mm'ss.dddd form.
Definition parser.hpp:4395
Test for any code unit.
Definition parser.hpp:221
Test for beginning of line.
Definition parser.hpp:615
Test for any.
Definition parser.hpp:1057
Test for any code unit from a given string of code units.
Definition parser.hpp:720
Test for specific code unit.
Definition parser.hpp:291
Test for date.
Definition parser.hpp:4025
Test for valid DNS domain character.
Definition parser.hpp:2806
bool allow_on_edge
Is character allowed at the beginning or an end of a DNS domain?
Definition parser.hpp:2844
Test for DNS domain/hostname.
Definition parser.hpp:2906
bool m_allow_absolute
May DNS names end with a dot (absolute name)?
Definition parser.hpp:2970
Test for e-mail address.
Definition parser.hpp:3794
Test for emoticon.
Definition parser.hpp:3902
std::shared_ptr< basic_parser< T > > apex
apex/eyebrows/halo (e.g. O, 0)
Definition parser.hpp:3991
std::shared_ptr< basic_parser< T > > eyes
eyes (e.g. :, ;, >, |, B)
Definition parser.hpp:3992
std::shared_ptr< basic_set< T > > mouth
mouth (e.g. ), ), (, (, |, P, D, p, d)
Definition parser.hpp:3994
std::shared_ptr< basic_parser< T > > nose
nose (e.g. -, o)
Definition parser.hpp:3993
std::shared_ptr< basic_parser< T > > emoticon
emoticon as a whole (e.g. 😀, 🤔, 😶)
Definition parser.hpp:3990
Test for end of line.
Definition parser.hpp:653
Test for fraction.
Definition parser.hpp:1686
Test for decimal integer.
Definition parser.hpp:1295
Test for decimal integer possibly containing thousand separators.
Definition parser.hpp:1380
bool has_separators
Did integer have any separators?
Definition parser.hpp:1440
size_t digit_count
Total number of digits in integer.
Definition parser.hpp:1439
Test for hexadecimal integer.
Definition parser.hpp:1461
Base class for integer testing.
Definition parser.hpp:1273
size_t value
Calculated value of the numeral.
Definition parser.hpp:1287
Test for IPv4 address.
Definition parser.hpp:2346
stdex::interval< size_t > components[4]
Individual component intervals.
Definition parser.hpp:2461
struct in_addr value
IPv4 address value.
Definition parser.hpp:2462
Test for IPv6 address.
Definition parser.hpp:2565
std::shared_ptr< basic_parser< T > > scope_id
Scope ID (e.g. NIC index with link-local addresses)
Definition parser.hpp:2769
stdex::interval< size_t > components[8]
Individual component intervals.
Definition parser.hpp:2767
struct in6_addr value
IPv6 address value.
Definition parser.hpp:2768
Test for valid IPv6 address scope ID character.
Definition parser.hpp:2493
Test for repeating.
Definition parser.hpp:910
bool m_greedy
try to match as long sequence as possible
Definition parser.hpp:949
std::shared_ptr< basic_parser< T > > m_el
repeating element
Definition parser.hpp:946
size_t m_min_iterations
minimum number of iterations
Definition parser.hpp:947
size_t m_max_iterations
maximum number of iterations
Definition parser.hpp:948
Test for JSON string.
Definition parser.hpp:6431
Test for mixed numeral.
Definition parser.hpp:1922
std::shared_ptr< basic_parser< T > > fraction
fraction
Definition parser.hpp:2028
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2026
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2025
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2024
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2027
Test for monetary numeral.
Definition parser.hpp:2217
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2323
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2328
std::shared_ptr< basic_parser< T > > currency
Currency part.
Definition parser.hpp:2326
std::shared_ptr< basic_parser< T > > decimal
Decimal part.
Definition parser.hpp:2329
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2327
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2324
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2325
"No-op" match
Definition parser.hpp:189
Base template for all parsers.
Definition parser.hpp:70
interval< size_t > interval
Region of the last match.
Definition parser.hpp:169
Test for permutation.
Definition parser.hpp:1197
Test for phone number.
Definition parser.hpp:4518
std::basic_string< T > value
Normalized phone number.
Definition parser.hpp:4644
Test for any punctuation code unit.
Definition parser.hpp:463
Test for Roman numeral.
Definition parser.hpp:1570
Test for scientific numeral.
Definition parser.hpp:2048
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2192
std::shared_ptr< basic_parser< T > > exponent_symbol
Exponent symbol (e.g. 'e')
Definition parser.hpp:2196
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2190
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2191
double value
Calculated value of the numeral.
Definition parser.hpp:2200
std::shared_ptr< basic_parser< T > > negative_exp_sign
Negative exponent sign (e.g. '-')
Definition parser.hpp:2198
std::shared_ptr< basic_integer< T > > decimal
Decimal part.
Definition parser.hpp:2195
std::shared_ptr< basic_parser< T > > positive_exp_sign
Positive exponent sign (e.g. '+')
Definition parser.hpp:2197
std::shared_ptr< basic_integer< T > > exponent
Exponent part.
Definition parser.hpp:2199
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2194
std::shared_ptr< basic_integer< T > > integer
Integer part.
Definition parser.hpp:2193
Test for match score.
Definition parser.hpp:1749
Test for sequence.
Definition parser.hpp:1006
Definition parser.hpp:688
Test for signed numeral.
Definition parser.hpp:1836
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:1904
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:1903
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:1902
std::shared_ptr< basic_parser< T > > number
Number.
Definition parser.hpp:1905
Test for any space code unit.
Definition parser.hpp:384
Test for any space or punctuation code unit.
Definition parser.hpp:537
Test for any string.
Definition parser.hpp:1125
Test for given string.
Definition parser.hpp:815
Test for time.
Definition parser.hpp:4292
Test for valid URL password character.
Definition parser.hpp:3088
Test for valid URL path character.
Definition parser.hpp:3188
Test for URL path.
Definition parser.hpp:3296
Test for valid URL username character.
Definition parser.hpp:2989
Test for URL.
Definition parser.hpp:3437
Test for HTTP agent.
Definition parser.hpp:5954
Test for HTTP any type.
Definition parser.hpp:5076
Test for HTTP asterisk.
Definition parser.hpp:5718
Test for HTTP cookie parameter (RFC2109)
Definition parser.hpp:5813
Test for HTTP cookie (RFC2109)
Definition parser.hpp:5872
std::list< http_cookie_parameter > params
List of cookie parameters.
Definition parser.hpp:5944
http_token name
Cookie name.
Definition parser.hpp:5942
http_value value
Cookie value.
Definition parser.hpp:5943
Test for HTTP language (RFC1766)
Definition parser.hpp:5586
Test for HTTP line break (RFC2616: CRLF | LF)
Definition parser.hpp:4750
Test for HTTP parameter (RFC2616: parameter)
Definition parser.hpp:5021
http_token name
Parameter name.
Definition parser.hpp:5065
http_value value
Parameter value.
Definition parser.hpp:5066
Test for HTTP protocol.
Definition parser.hpp:6030
uint16_t version
HTTP protocol version: 0x100 = 1.0, 0x101 = 1.1...
Definition parser.hpp:6132
Test for HTTP quoted string (RFC2616: quoted-string)
Definition parser.hpp:4911
stdex::interval< size_t > content
String content (without quotes)
Definition parser.hpp:4967
Test for HTTP request.
Definition parser.hpp:6139
Test for HTTP space (RFC2616: LWS)
Definition parser.hpp:4786
Test for HTTP text character (RFC2616: TEXT)
Definition parser.hpp:4823
Test for HTTP token (RFC2616: token - tolerates non-ASCII)
Definition parser.hpp:4857
Test for HTTP URL parameter.
Definition parser.hpp:5403
Test for HTTP URL path segment.
Definition parser.hpp:5314
Test for HTTP URL path segment.
Definition parser.hpp:5347
std::vector< http_url_path_segment > segments
Path segments.
Definition parser.hpp:5396
Test for HTTP URL port.
Definition parser.hpp:5258
Test for HTTP URL server.
Definition parser.hpp:5221
Test for HTTP URL.
Definition parser.hpp:5484
Collection of HTTP values.
Definition parser.hpp:6387
Test for HTTP value (RFC2616: value)
Definition parser.hpp:4977
http_quoted_string string
Value when matched as quoted string.
Definition parser.hpp:5013
http_token token
Value when matched as token.
Definition parser.hpp:5014
Test for HTTP weight factor.
Definition parser.hpp:5649
float value
Calculated value of the weight factor.
Definition parser.hpp:5711
Test for HTTP weighted value.
Definition parser.hpp:5741
Base template for collection-holding parsers.
Definition parser.hpp:966
Test for any SGML code point.
Definition parser.hpp:253
Test for any SGML code point from a given string of SGML code points.
Definition parser.hpp:772
Test for specific SGML code point.
Definition parser.hpp:340
Test for valid DNS domain SGML character.
Definition parser.hpp:2862
Test for valid IPv6 address scope ID SGML character.
Definition parser.hpp:2531
Test for any SGML punctuation code point.
Definition parser.hpp:504
Test for any SGML space code point.
Definition parser.hpp:427
Test for any SGML space or punctuation code point.
Definition parser.hpp:580
Test for SGML given string.
Definition parser.hpp:862
Test for valid URL password SGML character.
Definition parser.hpp:3140
Test for valid URL path SGML character.
Definition parser.hpp:3244
Test for valid URL username SGML character.
Definition parser.hpp:3040
Numerical interval.
Definition interval.hpp:18
T size() const
Returns interval size.
Definition interval.hpp:47
T end
interval end
Definition interval.hpp:20
interval() noexcept
Constructs an invalid interval.
Definition interval.hpp:25
T start
interval start
Definition interval.hpp:19
Definition parser.hpp:6413