32#pragma warning(disable: 4100)
35#define ENUM_FLAG_OPERATOR(T,X) \
36inline 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)); } \
37inline 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); } \
38inline 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)); } \
39inline T& operator X= (T& lhs, const T rhs) { return lhs = lhs X rhs; } \
40inline T& operator X= (T& lhs, const std::underlying_type_t<T> rhs) { return lhs = lhs X rhs; }
41#define ENUM_FLAGS(T, type) \
43inline T operator ~ (T t) { return (T) (~static_cast<std::underlying_type_t <T>>(t)); } \
44ENUM_FLAG_OPERATOR(T,|) \
45ENUM_FLAG_OPERATOR(T,^) \
46ENUM_FLAG_OPERATOR(T,&) \
56 constexpr int match_default = 0;
57 constexpr int match_case_insensitive = 0x1;
58 constexpr int match_multiline = 0x2;
67 basic_parser(_In_
const std::locale& locale = std::locale()) : m_locale(locale) {}
71 _In_reads_or_z_(end)
const T* text,
72 _In_
size_t start = 0,
73 _In_
size_t end = (
size_t)-1,
74 _In_
int flags = match_default)
76 for (
size_t i = start; i < end && text[i]; i++)
77 if (match(text, i, end, flags))
83 _In_reads_or_z_(end)
const T* text,
84 _In_
size_t start = 0,
85 _In_
size_t end = (
size_t)-1,
86 _In_
int flags = match_default) = 0;
88 template<
class _Traits,
class _Ax>
90 const std::basic_string<T, _Traits, _Ax>& text,
91 _In_
size_t start = 0,
92 _In_
size_t end = (
size_t)-1,
93 _In_
int flags = match_default)
95 return match(text.c_str(), start, std::min<size_t>(end, text.size()), flags);
98 virtual void invalidate()
106 const wchar_t* next_sgml_cp(_In_
const char* text, _In_
size_t start, _In_
size_t end, _Out_
size_t& chr_end, _Out_
wchar_t(&buf)[3])
108 if (text[start] ==
'&') {
110 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
111 for (chr_end = start + 1;; chr_end++) {
112 if (chr_end >= end || text[chr_end] == 0) {
116 if (text[chr_end] ==
';') {
118 size_t n = chr_end - start - 1;
119 if (n >= 2 && text[start + 1] ==
'#') {
122 if (text[start + 2] ==
'x' || text[start + 2] ==
'X')
123 unicode = strtou32(text + start + 3, n - 2,
nullptr, 16);
125 unicode = strtou32(text + start + 2, n - 1,
nullptr, 10);
127 if (unicode < 0x10000) {
128 buf[0] = (wchar_t)unicode;
132 ucs4_to_surrogate_pair(buf, unicode);
136 buf[0] = (wchar_t)unicode;
142 const wchar_t* entity_w = sgml2uni(text + start + 1, n);
150 else if (text[chr_end] ==
'&' || ctype.is(ctype.space, text[chr_end])) {
156 buf[0] = text[start];
167 std::locale m_locale;
187 _In_reads_or_z_(end)
const T* text,
188 _In_
size_t start = 0,
189 _In_
size_t end = (
size_t)-1,
190 _In_
int flags = match_default)
192 assert(text || start >= end);
193 if (start < end && text[start]) {
221 _In_reads_or_z_(end)
const T* text,
222 _In_
size_t start = 0,
223 _In_
size_t end = (
size_t)-1,
224 _In_
int flags = match_default)
226 assert(text || start >= end);
227 if (start < end && text[start]) {
253 _In_reads_or_z_(end)
const char* text,
254 _In_
size_t start = 0,
255 _In_
size_t end = (
size_t)-1,
256 _In_
int flags = match_default)
258 assert(text || start >= end);
259 if (start < end && text[start]) {
260 if (text[start] ==
'&') {
262 const auto& ctype = std::use_facet<std::ctype<char>>(m_locale);
288 basic_cu(T chr,
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
295 _In_reads_or_z_(end)
const T* text,
296 _In_
size_t start = 0,
297 _In_
size_t end = (
size_t)-1,
298 _In_
int flags = match_default)
300 assert(text || start >= end);
301 if (start < end && text[start]) {
303 if (flags & match_case_insensitive) {
304 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
305 r = ctype.tolower(text[start]) == ctype.tolower(m_chr);
308 r = text[start] == m_chr;
309 if (r && !m_invert || !r && m_invert) {
337 sgml_cp(
const char* chr,
size_t count = (
size_t)-1,
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
341 assert(chr || !count);
344 m_chr.assign(count ? next_sgml_cp(chr, 0, count, chr_end, buf) : L
"");
348 _In_reads_or_z_(end)
const char* text,
349 _In_
size_t start = 0,
350 _In_
size_t end = (
size_t)-1,
351 _In_
int flags = match_default)
353 assert(text || start >= end);
354 if (start < end && text[start]) {
356 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
357 bool r = ((flags & match_case_insensitive) ?
358 stdex::strnicmp(chr, (
size_t)-1, m_chr.c_str(), m_chr.size(), m_locale) :
359 stdex::strncmp(chr, (
size_t)-1, m_chr.c_str(), m_chr.size())) == 0;
360 if (r && !m_invert || !r && m_invert) {
381 basic_space_cu(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
387 _In_reads_or_z_(end)
const T* text,
388 _In_
size_t start = 0,
389 _In_
size_t end = (
size_t)-1,
390 _In_
int flags = match_default)
392 assert(text || start >= end);
393 if (start < end && text[start]) {
395 ((flags & match_multiline) || !islbreak(text[start])) &&
396 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::space, text[start]);
397 if (r && !m_invert || !r && m_invert) {
424 sgml_space_cp(_In_
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
429 _In_reads_or_z_(end)
const char* text,
430 _In_
size_t start = 0,
431 _In_
size_t end = (
size_t)-1,
432 _In_
int flags = match_default)
434 assert(text || start >= end);
435 if (start < end && text[start]) {
437 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
438 const wchar_t* chr_end = chr + stdex::strlen(chr);
440 ((flags & match_multiline) || !islbreak(chr, (
size_t)-1)) &&
441 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space, chr, chr_end) == chr_end;
442 if (r && !m_invert || !r && m_invert) {
460 basic_punct_cu(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
466 _In_reads_or_z_(end)
const T* text,
467 _In_
size_t start = 0,
468 _In_
size_t end = (
size_t)-1,
469 _In_
int flags = match_default)
471 assert(text || start >= end);
472 if (start < end && text[start]) {
473 bool r = std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::punct, text[start]);
474 if (r && !m_invert || !r && m_invert) {
501 sgml_punct_cp(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
506 _In_reads_or_z_(end)
const char* text,
507 _In_
size_t start = 0,
508 _In_
size_t end = (
size_t)-1,
509 _In_
int flags = match_default)
511 assert(text || start >= end);
512 if (start < end && text[start]) {
514 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
515 const wchar_t* chr_end = chr + stdex::strlen(chr);
516 bool r = std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::punct, chr, chr_end) == chr_end;
517 if (r && !m_invert || !r && m_invert) {
540 _In_reads_or_z_(end)
const T* text,
541 _In_
size_t start = 0,
542 _In_
size_t end = (
size_t)-1,
543 _In_
int flags = match_default)
545 assert(text || start >= end);
546 if (start < end && text[start]) {
548 ((flags & match_multiline) || !islbreak(text[start])) &&
549 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::space | std::ctype_base::punct, text[start]);
550 if (r && !m_invert || !r && m_invert) {
582 _In_reads_or_z_(end)
const char* text,
583 _In_
size_t start = 0,
584 _In_
size_t end = (
size_t)-1,
585 _In_
int flags = match_default)
587 assert(text || start >= end);
588 if (start < end && text[start]) {
590 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
591 const wchar_t* chr_end = chr + stdex::strlen(chr);
593 ((flags & match_multiline) || !islbreak(chr, (
size_t)-1)) &&
594 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space | std::ctype_base::punct, chr, chr_end) == chr_end;
595 if (r && !m_invert || !r && m_invert) {
612 basic_bol(
bool invert =
false) : m_invert(invert) {}
615 _In_reads_or_z_(end)
const T* text,
616 _In_
size_t start = 0,
617 _In_
size_t end = (
size_t)-1,
618 _In_
int flags = match_default)
620 assert(text || start >= end);
621 bool r = start == 0 || start <= end && islbreak(text[start - 1]);
622 if (r && !m_invert || !r && m_invert) {
650 basic_eol(
bool invert =
false) : m_invert(invert) {}
653 _In_reads_or_z_(end)
const T* text,
654 _In_
size_t start = 0,
655 _In_
size_t end = (
size_t)-1,
656 _In_
int flags = match_default)
658 assert(text || start >= end);
659 bool r = islbreak(text[start]);
660 if (r && !m_invert || !r && m_invert) {
685 basic_set(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
687 hit_offset((
size_t)-1),
692 _In_reads_or_z_(end)
const T* text,
693 _In_
size_t start = 0,
694 _In_
size_t end = (
size_t)-1,
695 _In_
int flags = match_default) = 0;
697 virtual void invalidate()
699 hit_offset = (size_t)-1;
718 _In_reads_or_z_(count)
const T* set,
719 _In_
size_t count = (
size_t)-1,
720 _In_
bool invert =
false,
721 _In_
const std::locale& locale = std::locale()) :
725 m_set.assign(set, set + stdex::strnlen(set, count));
729 _In_reads_or_z_(end)
const T* text,
730 _In_
size_t start = 0,
731 _In_
size_t end = (
size_t)-1,
732 _In_
int flags = match_default)
734 assert(text || start >= end);
735 if (start < end && text[start]) {
736 const T* set = m_set.c_str();
737 size_t r = (flags & match_case_insensitive) ?
738 stdex::strnichr(set, m_set.size(), text[start], m_locale) :
739 stdex::strnchr(set, m_set.size(), text[start]);
740 if (r != stdex::npos && !m_invert || r == stdex::npos && m_invert) {
746 hit_offset = (size_t)-1;
752 std::basic_string<T> m_set;
769 sgml_cp_set(
const char* set,
size_t count = (
size_t)-1,
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
773 m_set = sgml2wstr(set, count);
777 _In_reads_or_z_(end)
const char* text,
778 _In_
size_t start = 0,
779 _In_
size_t end = (
size_t)-1,
780 _In_
int flags = match_default)
782 assert(text || start >= end);
783 if (start < end && text[start]) {
785 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
786 const wchar_t* set = m_set.c_str();
787 size_t r = (flags & match_case_insensitive) ?
788 stdex::strnistr(set, m_set.size(), chr, m_locale) :
789 stdex::strnstr(set, m_set.size(), chr);
790 if (r != stdex::npos && !m_invert || r == stdex::npos && m_invert) {
796 hit_offset = (size_t)-1;
813 _In_reads_or_z_(count)
const T* str,
814 _In_
size_t count = (
size_t)-1,
815 _In_
const std::locale& locale = std::locale()) :
817 m_str(str, str + stdex::strnlen(str, count))
821 _In_reads_or_z_(end)
const T* text,
822 _In_
size_t start = 0,
823 _In_
size_t end = (
size_t)-1,
824 _In_
int flags = match_default)
826 assert(text || start >= end);
829 n = std::min<size_t>(end - start, m);
830 bool r = ((flags & match_case_insensitive) ?
831 stdex::strnicmp(text + start, n, m_str.c_str(), m, m_locale) :
832 stdex::strncmp(text + start, n, m_str.c_str(), m)) == 0;
842 std::basic_string<T> m_str;
859 sgml_string(
const char* str,
size_t count = (
size_t)-1, _In_
const std::locale& locale = std::locale()) :
861 m_str(sgml2wstr(str, count))
865 _In_reads_or_z_(end)
const char* text,
866 _In_
size_t start = 0,
867 _In_
size_t end = (
size_t)-1,
868 _In_
int flags = match_default)
870 assert(text || start >= end);
871 const wchar_t* str = m_str.c_str();
872 const bool case_insensitive = flags & match_case_insensitive ? true :
false;
873 const auto& ctype = std::use_facet<std::ctype<wchar_t>>(m_locale);
885 for (; *chr; ++str, ++chr) {
887 (case_insensitive ? ctype.tolower(*str) != ctype.tolower(*chr) : *str != *chr))
915 _In_reads_or_z_(end)
const T* text,
916 _In_
size_t start = 0,
917 _In_
size_t end = (
size_t)-1,
918 _In_
int flags = match_default)
920 assert(text || start >= end);
922 for (
size_t i = 0; ; i++) {
941 std::shared_ptr<basic_parser<T>>
m_el;
969 _In_
const std::locale& locale = std::locale()) :
972 assert(el || !count);
973 m_collection.reserve(count);
974 for (
size_t i = 0; i < count; i++)
975 m_collection.push_back(el[i]);
980 _In_
const std::locale& locale = std::locale()) :
982 m_collection(std::move(collection))
985 virtual void invalidate()
987 for (
auto& el: m_collection)
993 std::vector<std::shared_ptr<basic_parser<T>>> m_collection;
1004 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1005 _In_
size_t count = 0,
1006 _In_
const std::locale& locale = std::locale()) :
1012 _In_
const std::locale& locale = std::locale()) :
1017 _In_reads_or_z_(end)
const T* text,
1018 _In_
size_t start = 0,
1019 _In_
size_t end = (
size_t)-1,
1020 _In_
int flags = match_default)
1022 assert(text || start >= end);
1024 for (
auto i = m_collection.begin(); i != m_collection.end(); ++i) {
1025 if (!(*i)->match(text,
interval.
end, end, flags)) {
1026 for (++i; i != m_collection.end(); ++i)
1056 hit_offset((
size_t)-1)
1061 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1062 _In_
size_t count = 0,
1063 _In_
const std::locale& locale = std::locale()) :
1065 hit_offset((
size_t)-1)
1070 _In_
const std::locale& locale = std::locale()) :
1072 hit_offset((
size_t)-1)
1076 _In_reads_or_z_(end)
const T* text,
1077 _In_
size_t start = 0,
1078 _In_
size_t end = (
size_t)-1,
1079 _In_
int flags = match_default)
1081 assert(text || start >= end);
1083 for (
auto i = m_collection.begin(); i != m_collection.end(); ++i, ++hit_offset) {
1084 if ((*i)->match(text, start, end, flags)) {
1086 for (++i; i != m_collection.end(); ++i)
1091 hit_offset = (size_t)-1;
1096 virtual void invalidate()
1098 hit_offset = (size_t)-1;
1118 template <
class T,
class T_parser = basic_
string<T>>
1123 _In_reads_(count)
const T* str_z =
nullptr,
1124 _In_
size_t count = 0,
1125 _In_
const std::locale& locale = std::locale()) :
1128 build(str_z, count);
1135 va_start(params, str);
1144 va_start(params, str);
1150 void build(_In_reads_(count)
const T* str_z, _In_
size_t count)
1152 assert(str_z || !count);
1157 offset < count && str_z[offset];
1158 offset += stdex::strnlen(str_z + offset, count - offset) + 1, ++n);
1159 m_collection.reserve(n);
1162 offset < count && str_z[offset];
1163 offset += stdex::strnlen(str_z + offset, count - offset) + 1)
1164 m_collection.push_back(std::move(std::make_shared<T_parser>(str_z + offset, count - offset, m_locale)));
1168 void build(_In_z_
const T* str, _In_ va_list params)
1172 m_collection.push_back(std::move(std::make_shared<T_parser>(str, (
size_t)-1, m_locale)));
1173 (p = va_arg(params,
const T*)) !=
nullptr;
1174 m_collection.push_back(std::move(std::make_shared<T_parser>(p, (
size_t)-1, m_locale))));
1195 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1196 _In_
size_t count = 0,
1197 _In_
const std::locale& locale = std::locale()) :
1203 _In_
const std::locale& locale = std::locale()) :
1208 _In_reads_or_z_(end)
const T* text,
1209 _In_
size_t start = 0,
1210 _In_
size_t end = (
size_t)-1,
1211 _In_
int flags = match_default)
1213 assert(text || start >= end);
1214 for (
auto& el: m_collection)
1216 if (match_recursively(text, start, end, flags)) {
1225 bool match_recursively(
1226 _In_reads_or_z_(end)
const T* text,
1227 _In_
size_t start = 0,
1228 _In_
size_t end = (
size_t)-1,
1229 _In_
int flags = match_default)
1231 bool all_matched =
true;
1232 for (
auto& el: m_collection) {
1233 if (!el->interval) {
1235 all_matched =
false;
1236 if (el->match(text, start, end, flags)) {
1238 if (match_recursively(text, el->interval.end, end, flags)) {
1270 basic_integer(_In_
const std::locale& locale = std::locale()) :
1275 virtual void invalidate()
1303 _In_
const std::locale& locale = std::locale()) :
1318 _In_reads_or_z_(end)
const T* text,
1319 _In_
size_t start = 0,
1320 _In_
size_t end = (
size_t)-1,
1321 _In_
int flags = match_default)
1323 assert(text || start >= end);
1326 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0;
interval.
end = m_digit_0->interval.end; }
1327 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1;
interval.
end = m_digit_1->interval.end; }
1328 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2;
interval.
end = m_digit_2->interval.end; }
1329 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3;
interval.
end = m_digit_3->interval.end; }
1330 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4;
interval.
end = m_digit_4->interval.end; }
1331 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5;
interval.
end = m_digit_5->interval.end; }
1332 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6;
interval.
end = m_digit_6->interval.end; }
1333 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7;
interval.
end = m_digit_7->interval.end; }
1334 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8;
interval.
end = m_digit_8->interval.end; }
1335 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9;
interval.
end = m_digit_9->interval.end; }
1348 std::shared_ptr<basic_parser<T>>
1380 _In_
const std::locale& locale = std::locale()) :
1385 m_separator(separator)
1389 _In_reads_or_z_(end)
const T* text,
1390 _In_
size_t start = 0,
1391 _In_
size_t end = (
size_t)-1,
1392 _In_
int flags = match_default)
1394 assert(text || start >= end);
1395 if (m_digits->match(text, start, end, flags)) {
1397 value = m_digits->value;
1402 if (m_digits->interval.size() <= 3) {
1404 size_t hit_offset = (size_t)-1;
1405 while (m_separator->match(text,
interval.
end, end, flags) &&
1406 (hit_offset == (size_t)-1 || hit_offset == m_separator->hit_offset) &&
1407 m_digits->match(text, m_separator->interval.end, end, flags) &&
1408 m_digits->interval.size() == 3)
1415 hit_offset = m_separator->hit_offset;
1426 virtual void invalidate()
1438 std::shared_ptr<basic_integer10<T>> m_digits;
1439 std::shared_ptr<basic_set<T>> m_separator;
1475 _In_
const std::locale& locale = std::locale()) :
1487 m_digit_10(digit_10),
1488 m_digit_11(digit_11),
1489 m_digit_12(digit_12),
1490 m_digit_13(digit_13),
1491 m_digit_14(digit_14),
1492 m_digit_15(digit_15)
1496 _In_reads_or_z_(end)
const T* text,
1497 _In_
size_t start = 0,
1498 _In_
size_t end = (
size_t)-1,
1499 _In_
int flags = match_default)
1501 assert(text || start >= end);
1504 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0;
interval.
end = m_digit_0->interval.end; }
1505 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1;
interval.
end = m_digit_1->interval.end; }
1506 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2;
interval.
end = m_digit_2->interval.end; }
1507 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3;
interval.
end = m_digit_3->interval.end; }
1508 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4;
interval.
end = m_digit_4->interval.end; }
1509 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5;
interval.
end = m_digit_5->interval.end; }
1510 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6;
interval.
end = m_digit_6->interval.end; }
1511 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7;
interval.
end = m_digit_7->interval.end; }
1512 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8;
interval.
end = m_digit_8->interval.end; }
1513 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9;
interval.
end = m_digit_9->interval.end; }
1514 else if (m_digit_10->match(text,
interval.
end, end, flags)) { dig = 10;
interval.
end = m_digit_10->interval.end; }
1515 else if (m_digit_11->match(text,
interval.
end, end, flags)) { dig = 11;
interval.
end = m_digit_11->interval.end; }
1516 else if (m_digit_12->match(text,
interval.
end, end, flags)) { dig = 12;
interval.
end = m_digit_12->interval.end; }
1517 else if (m_digit_13->match(text,
interval.
end, end, flags)) { dig = 13;
interval.
end = m_digit_13->interval.end; }
1518 else if (m_digit_14->match(text,
interval.
end, end, flags)) { dig = 14;
interval.
end = m_digit_14->interval.end; }
1519 else if (m_digit_15->match(text,
interval.
end, end, flags)) { dig = 15;
interval.
end = m_digit_15->interval.end; }
1532 std::shared_ptr<basic_parser<T>>
1577 _In_
const std::locale& locale = std::locale()) :
1581 m_digit_10(digit_10),
1582 m_digit_50(digit_50),
1583 m_digit_100(digit_100),
1584 m_digit_500(digit_500),
1585 m_digit_1000(digit_1000),
1586 m_digit_5000(digit_5000),
1587 m_digit_10000(digit_10000)
1591 _In_reads_or_z_(end)
const T* text,
1592 _In_
size_t start = 0,
1593 _In_
size_t end = (
size_t)-1,
1594 _In_
int flags = match_default)
1596 assert(text || start >= end);
1598 dig[5] = { (size_t)-1, (
size_t)-1, (size_t)-1, (
size_t)-1, (size_t)-1 },
1602 if (m_digit_1 && m_digit_1->match(text,
interval.
end, end, flags)) { dig[0] = 1; end2 = m_digit_1->interval.end; }
1603 else if (m_digit_5 && m_digit_5->match(text,
interval.
end, end, flags)) { dig[0] = 5; end2 = m_digit_5->interval.end; }
1604 else if (m_digit_10 && m_digit_10->match(text,
interval.
end, end, flags)) { dig[0] = 10; end2 = m_digit_10->interval.end; }
1605 else if (m_digit_50 && m_digit_50->match(text,
interval.
end, end, flags)) { dig[0] = 50; end2 = m_digit_50->interval.end; }
1606 else if (m_digit_100 && m_digit_100->match(text,
interval.
end, end, flags)) { dig[0] = 100; end2 = m_digit_100->interval.end; }
1607 else if (m_digit_500 && m_digit_500->match(text,
interval.
end, end, flags)) { dig[0] = 500; end2 = m_digit_500->interval.end; }
1608 else if (m_digit_1000 && m_digit_1000->match(text,
interval.
end, end, flags)) { dig[0] = 1000; end2 = m_digit_1000->interval.end; }
1609 else if (m_digit_5000 && m_digit_5000->match(text,
interval.
end, end, flags)) { dig[0] = 5000; end2 = m_digit_5000->interval.end; }
1610 else if (m_digit_10000 && m_digit_10000->match(text,
interval.
end, end, flags)) { dig[0] = 10000; end2 = m_digit_10000->interval.end; }
1614 if (dig[4] == (
size_t)-1) dig[4] = dig[0];
1616 if (dig[3] == dig[2] && dig[2] == dig[1] && dig[1] == dig[0] && dig[0] != dig[4]) {
1620 if (dig[0] <= dig[1]) {
1625 dig[1] == 1 && (dig[0] == 5 || dig[0] == 10) ||
1626 dig[1] == 10 && (dig[0] == 50 || dig[0] == 100) ||
1627 dig[1] == 100 && (dig[0] == 500 || dig[0] == 1000) ||
1628 dig[1] == 1000 && (dig[0] == 5000 || dig[0] == 10000))
1631 if (dig[2] < dig[0]) {
1655 std::shared_ptr<basic_parser<T>>
1687 _In_
const std::locale& locale = std::locale()) :
1689 numerator(_numerator),
1690 fraction_line(_fraction_line),
1691 denominator(_denominator)
1695 _In_reads_or_z_(end)
const T* text,
1696 _In_
size_t start = 0,
1697 _In_
size_t end = (
size_t)-1,
1698 _In_
int flags = match_default)
1700 assert(text || start >= end);
1701 if (numerator->match(text, start, end, flags) &&
1702 fraction_line->match(text, numerator->interval.end, end, flags) &&
1703 denominator->match(text, fraction_line->interval.end, end, flags))
1709 numerator->invalidate();
1710 fraction_line->invalidate();
1711 denominator->invalidate();
1716 virtual void invalidate()
1718 numerator->invalidate();
1719 fraction_line->invalidate();
1720 denominator->invalidate();
1725 std::shared_ptr<basic_parser<T>> numerator;
1726 std::shared_ptr<basic_parser<T>> fraction_line;
1727 std::shared_ptr<basic_parser<T>> denominator;
1751 _In_
const std::locale& locale = std::locale()) :
1754 separator(_separator),
1760 _In_reads_or_z_(end)
const T* text,
1761 _In_
size_t start = 0,
1762 _In_
size_t end = (
size_t)-1,
1763 _In_
int flags = match_default)
1765 assert(text || start >= end);
1773 const int space_match_flags = flags & ~match_multiline;
1774 for (; m_space->match(text,
interval.
end, end, space_match_flags);
interval.
end = m_space->interval.end);
1776 if (separator->match(text,
interval.
end, end, flags))
1781 for (; m_space->match(text,
interval.
end, end, space_match_flags);
interval.
end = m_space->interval.end);
1793 separator->invalidate();
1794 guest->invalidate();
1799 virtual void invalidate()
1802 separator->invalidate();
1803 guest->invalidate();
1808 std::shared_ptr<basic_parser<T>> home;
1809 std::shared_ptr<basic_parser<T>> separator;
1810 std::shared_ptr<basic_parser<T>> guest;
1813 std::shared_ptr<basic_parser<T>> m_space;
1837 _In_
const std::locale& locale = std::locale()) :
1846 _In_reads_or_z_(end)
const T* text,
1847 _In_
size_t start = 0,
1848 _In_
size_t end = (
size_t)-1,
1849 _In_
int flags = match_default)
1851 assert(text || start >= end);
1886 virtual void invalidate()
1925 _In_
const std::locale& locale = std::locale()) :
1936 _In_reads_or_z_(end)
const T* text,
1937 _In_
size_t start = 0,
1938 _In_
size_t end = (
size_t)-1,
1939 _In_
int flags = match_default)
1941 assert(text || start >= end);
1966 const int space_match_flags = flags & ~match_multiline;
1968 m_space->match(text,
integer->interval.end, end, space_match_flags))
2007 virtual void invalidate()
2025 std::shared_ptr<basic_parser<T>> m_space;
2055 _In_
const std::locale& locale = std::locale()) :
2067 value(std::numeric_limits<double>::quiet_NaN())
2071 _In_reads_or_z_(end)
const T* text,
2072 _In_
size_t start = 0,
2073 _In_
size_t end = (
size_t)-1,
2074 _In_
int flags = match_default)
2076 assert(text || start >= end);
2111 if (
integer->interval.empty() &&
2157 double e = (double)
exponent->value;
2160 value *= pow(10.0, e);
2167 virtual void invalidate()
2179 value = std::numeric_limits<double>::quiet_NaN();
2221 _In_
const std::locale& locale = std::locale()) :
2233 _In_reads_or_z_(end)
const T* text,
2234 _In_
size_t start = 0,
2235 _In_
size_t end = (
size_t)-1,
2236 _In_
int flags = match_default)
2238 assert(text || start >= end);
2285 if (
integer->interval.empty() &&
2304 virtual void invalidate()
2354 _In_
const std::locale& locale = std::locale()) :
2366 m_separator(separator)
2372 _In_reads_or_z_(end)
const T* text,
2373 _In_
size_t start = 0,
2374 _In_
size_t end = (
size_t)-1,
2375 _In_
int flags = match_default)
2377 assert(text || start >= end);
2382 for (i = 0; i < 4; i++) {
2384 if (m_separator->match(text,
interval.
end, end, flags))
2391 bool is_empty =
true;
2394 size_t dig, digit_end;
2395 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
2396 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
2397 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
2398 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
2399 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
2400 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
2401 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
2402 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
2403 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
2404 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
2406 size_t x_n = x * 10 + dig;
2418 value.s_addr = (
value.s_addr << 8) | (uint8_t)x;
2440 virtual void invalidate()
2459 std::shared_ptr<basic_parser<T>>
2470 std::shared_ptr<basic_parser<T>> m_separator;
2492 _In_reads_or_z_(end)
const T* text,
2493 _In_
size_t start = 0,
2494 _In_
size_t end = (
size_t)-1,
2495 _In_
int flags = match_default)
2497 assert(text || start >= end);
2498 if (start < end && text[start]) {
2499 if (text[start] ==
'-' ||
2500 text[start] ==
'_' ||
2501 text[start] ==
':' ||
2502 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
2530 _In_reads_or_z_(end)
const char* text,
2531 _In_
size_t start = 0,
2532 _In_
size_t end = (
size_t)-1,
2533 _In_
int flags = match_default)
2535 assert(text || start >= end);
2536 if (start < end && text[start]) {
2538 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
2539 const wchar_t* chr_end = chr + stdex::strlen(chr);
2540 if ((chr[0] == L
'-' ||
2542 chr[0] == L
':') && chr[1] == 0 ||
2543 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
2579 _In_
const std::shared_ptr<
basic_parser<T>>& scope_id_separator =
nullptr,
2581 _In_
const std::locale& locale = std::locale()) :
2593 m_digit_10(digit_10),
2594 m_digit_11(digit_11),
2595 m_digit_12(digit_12),
2596 m_digit_13(digit_13),
2597 m_digit_14(digit_14),
2598 m_digit_15(digit_15),
2599 m_separator(separator),
2600 m_scope_id_separator(scope_id_separator),
2607 _In_reads_or_z_(end)
const T* text,
2608 _In_
size_t start = 0,
2609 _In_
size_t end = (
size_t)-1,
2610 _In_
int flags = match_default)
2612 assert(text || start >= end);
2616 size_t i, compaction_i = (size_t)-1, compaction_start = start;
2617 for (i = 0; i < 8; i++) {
2618 bool is_empty =
true;
2620 if (m_separator->match(text,
interval.
end, end, flags)) {
2621 if (m_separator->match(text, m_separator->interval.end, end, flags)) {
2623 if (compaction_i == (
size_t)-1) {
2626 compaction_start = m_separator->interval.start;
2651 size_t dig, digit_end;
2652 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
2653 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
2654 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
2655 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
2656 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
2657 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
2658 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
2659 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
2660 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
2661 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
2662 else if (m_digit_10->match(text,
interval.
end, end, flags)) { dig = 10; digit_end = m_digit_10->interval.end; }
2663 else if (m_digit_11->match(text,
interval.
end, end, flags)) { dig = 11; digit_end = m_digit_11->interval.end; }
2664 else if (m_digit_12->match(text,
interval.
end, end, flags)) { dig = 12; digit_end = m_digit_12->interval.end; }
2665 else if (m_digit_13->match(text,
interval.
end, end, flags)) { dig = 13; digit_end = m_digit_13->interval.end; }
2666 else if (m_digit_14->match(text,
interval.
end, end, flags)) { dig = 14; digit_end = m_digit_14->interval.end; }
2667 else if (m_digit_15->match(text,
interval.
end, end, flags)) { dig = 15; digit_end = m_digit_15->interval.end; }
2669 size_t x_n = x * 16 + dig;
2670 if (x_n <= 0xffff) {
2679 if (compaction_i != (
size_t)-1) {
2686 value.s6_words[i] = (uint16_t)x;
2689 if (compaction_i != (
size_t)-1) {
2692 for (j = 8, k = i; k > compaction_i;) {
2696 for (; j > compaction_i;) {
2697 value.s6_words[--j] = 0;
2705 if (m_scope_id_separator && m_scope_id_separator->match(text,
interval.
end, end, flags) &&
2706 scope_id &&
scope_id->match(text, m_scope_id_separator->interval.end, end, flags))
2737 virtual void invalidate()
2766 std::shared_ptr<basic_parser<T>>
2783 std::shared_ptr<basic_parser<T>> m_separator, m_scope_id_separator;
2803 _In_
bool allow_idn,
2804 _In_
const std::locale& locale = std::locale()) :
2806 m_allow_idn(allow_idn),
2811 _In_reads_or_z_(end)
const T* text,
2812 _In_
size_t start = 0,
2813 _In_
size_t end = (
size_t)-1,
2814 _In_
int flags = match_default)
2816 assert(text || start >= end);
2817 if (start < end && text[start]) {
2818 if ((
'A' <= text[start] && text[start] <=
'Z') ||
2819 (
'a' <= text[start] && text[start] <=
'z') ||
2820 (
'0' <= text[start] && text[start] <=
'9'))
2822 else if (text[start] ==
'-')
2824 else if (m_allow_idn && std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
2859 _In_
bool allow_idn,
2860 _In_
const std::locale& locale = std::locale()) :
2865 _In_reads_or_z_(end)
const char* text,
2866 _In_
size_t start = 0,
2867 _In_
size_t end = (
size_t)-1,
2868 _In_
int flags = match_default)
2870 assert(text || start >= end);
2871 if (start < end && text[start]) {
2873 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
2874 const wchar_t* chr_end = chr + stdex::strlen(chr);
2875 if (((
'A' <= chr[0] && chr[0] <=
'Z') ||
2876 (
'a' <= chr[0] && chr[0] <=
'z') ||
2877 (
'0' <= chr[0] && chr[0] <=
'9')) && chr[1] == 0)
2879 else if (chr[0] ==
'-' && chr[1] == 0)
2881 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)
2903 _In_
bool allow_absolute,
2906 _In_
const std::locale& locale = std::locale()) :
2909 m_domain_char(domain_char),
2910 m_separator(separator)
2914 _In_reads_or_z_(end)
const T* text,
2915 _In_
size_t start = 0,
2916 _In_
size_t end = (
size_t)-1,
2917 _In_
int flags = match_default)
2919 assert(text || start >= end);
2920 size_t i = start, count;
2921 for (count = 0; i < end && text[i] && count < 127; count++) {
2922 if (m_domain_char->match(text, i, end, flags) &&
2923 m_domain_char->allow_on_edge)
2927 while (i < end && text[i]) {
2928 if (m_domain_char->allow_on_edge &&
2929 m_separator->match(text, i, end, flags))
2936 i = m_separator->interval.end;
2940 if (m_domain_char->match(text, i, end, flags)) {
2941 if (m_domain_char->allow_on_edge)
2944 i = m_domain_char->interval.end;
2965 std::shared_ptr<basic_dns_domain_char<T>> m_domain_char;
2966 std::shared_ptr<basic_parser<T>> m_separator;
2988 _In_reads_or_z_(end)
const T* text,
2989 _In_
size_t start = 0,
2990 _In_
size_t end = (
size_t)-1,
2991 _In_
int flags = match_default)
2993 assert(text || start >= end);
2994 if (start < end && text[start]) {
2995 if (text[start] ==
'-' ||
2996 text[start] ==
'.' ||
2997 text[start] ==
'_' ||
2998 text[start] ==
'~' ||
2999 text[start] ==
'%' ||
3000 text[start] ==
'!' ||
3001 text[start] ==
'$' ||
3002 text[start] ==
'&' ||
3003 text[start] ==
'\'' ||
3006 text[start] ==
'*' ||
3007 text[start] ==
'+' ||
3008 text[start] ==
',' ||
3009 text[start] ==
';' ||
3010 text[start] ==
'=' ||
3011 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
3039 _In_reads_or_z_(end)
const char* text,
3040 _In_
size_t start = 0,
3041 _In_
size_t end = (
size_t)-1,
3042 _In_
int flags = match_default)
3044 assert(text || start >= end);
3045 if (start < end && text[start]) {
3047 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
3048 const wchar_t* chr_end = chr + stdex::strlen(chr);
3049 if ((chr[0] == L
'-' ||
3064 chr[0] == L
'=') && chr[1] == 0 ||
3065 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3087 _In_reads_or_z_(end)
const T* text,
3088 _In_
size_t start = 0,
3089 _In_
size_t end = (
size_t)-1,
3090 _In_
int flags = match_default)
3092 assert(text || start >= end);
3093 if (start < end && text[start]) {
3094 if (text[start] ==
'-' ||
3095 text[start] ==
'.' ||
3096 text[start] ==
'_' ||
3097 text[start] ==
'~' ||
3098 text[start] ==
'%' ||
3099 text[start] ==
'!' ||
3100 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 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
3139 _In_reads_or_z_(end)
const char* text,
3140 _In_
size_t start = 0,
3141 _In_
size_t end = (
size_t)-1,
3142 _In_
int flags = match_default)
3144 assert(text || start >= end);
3145 if (start < end && text[start]) {
3147 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
3148 const wchar_t* chr_end = chr + stdex::strlen(chr);
3149 if ((chr[0] == L
'-' ||
3165 chr[0] == L
':') && chr[1] == 0 ||
3166 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3187 _In_reads_or_z_(end)
const T* text,
3188 _In_
size_t start = 0,
3189 _In_
size_t end = (
size_t)-1,
3190 _In_
int flags = match_default)
3192 assert(text || start >= end);
3193 if (start < end && text[start]) {
3194 if (text[start] ==
'/' ||
3195 text[start] ==
'-' ||
3196 text[start] ==
'.' ||
3197 text[start] ==
'_' ||
3198 text[start] ==
'~' ||
3199 text[start] ==
'%' ||
3200 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 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
3243 _In_reads_or_z_(end)
const char* text,
3244 _In_
size_t start = 0,
3245 _In_
size_t end = (
size_t)-1,
3246 _In_
int flags = match_default)
3248 assert(text || start >= end);
3249 if (start < end && text[start]) {
3251 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
3252 const wchar_t* chr_end = chr + stdex::strlen(chr);
3253 if ((chr[0] == L
'/' ||
3273 chr[0] == L
'#') && chr[1] == 0 ||
3274 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3296 _In_
const std::locale& locale = std::locale()) :
3298 m_path_char(path_char),
3299 m_query_start(query_start),
3300 m_bookmark_start(bookmark_start)
3304 _In_reads_or_z_(end)
const T* text,
3305 _In_
size_t start = 0,
3306 _In_
size_t end = (
size_t)-1,
3307 _In_
int flags = match_default)
3309 assert(text || start >= end);
3321 if (m_query_start->match(text,
interval.
end, end, flags)) {
3329 if (m_bookmark_start->match(text,
interval.
end, end, flags)) {
3337 if (m_path_char->match(text,
interval.
end, end, flags))
3347 if (m_path_char->match(text,
interval.
end, end, flags))
3357 if (m_bookmark_start->match(text,
interval.
end, end, flags)) {
3365 if (m_path_char->match(text,
interval.
end, end, flags))
3375 if (m_path_char->match(text,
interval.
end, end, flags))
3395 virtual void invalidate()
3412 std::shared_ptr<basic_parser<T>> m_path_char;
3413 std::shared_ptr<basic_parser<T>> m_query_start;
3414 std::shared_ptr<basic_parser<T>> m_bookmark_start;
3450 _In_
const std::locale& locale = std::locale()) :
3452 http_scheme(_http_scheme),
3453 ftp_scheme(_ftp_scheme),
3454 mailto_scheme(_mailto_scheme),
3455 file_scheme(_file_scheme),
3458 username(_username),
3459 password(_password),
3461 m_ip_lbracket(ip_lbracket),
3462 m_ip_rbracket(ip_rbracket),
3463 ipv4_host(_ipv4_host),
3464 ipv6_host(_ipv6_host),
3465 dns_host(_dns_host),
3471 _In_reads_or_z_(end)
const T* text,
3472 _In_
size_t start = 0,
3473 _In_
size_t end = (
size_t)-1,
3474 _In_
int flags = match_default)
3476 assert(text || start >= end);
3480 if (http_scheme->match(text,
interval.
end, end, flags) &&
3481 m_colon->match(text, http_scheme->interval.end, end, flags) &&
3482 m_slash->match(text, m_colon->interval.end, end, flags) &&
3483 m_slash->match(text, m_slash->interval.end, end, flags))
3487 ftp_scheme->invalidate();
3488 mailto_scheme->invalidate();
3489 file_scheme->invalidate();
3491 else if (ftp_scheme->match(text,
interval.
end, end, flags) &&
3492 m_colon->match(text, ftp_scheme->interval.end, end, flags) &&
3493 m_slash->match(text, m_colon->interval.end, end, flags) &&
3494 m_slash->match(text, m_slash->interval.end, end, flags))
3498 http_scheme->invalidate();
3499 mailto_scheme->invalidate();
3500 file_scheme->invalidate();
3502 else if (mailto_scheme->match(text,
interval.
end, end, flags) &&
3503 m_colon->match(text, mailto_scheme->interval.end, end, flags))
3507 http_scheme->invalidate();
3508 ftp_scheme->invalidate();
3509 file_scheme->invalidate();
3511 else if (file_scheme->match(text,
interval.
end, end, flags) &&
3512 m_colon->match(text, file_scheme->interval.end, end, flags) &&
3513 m_slash->match(text, m_colon->interval.end, end, flags) &&
3514 m_slash->match(text, m_slash->interval.end, end, flags))
3518 http_scheme->invalidate();
3519 ftp_scheme->invalidate();
3520 mailto_scheme->invalidate();
3524 http_scheme->invalidate();
3525 ftp_scheme->invalidate();
3526 mailto_scheme->invalidate();
3527 file_scheme->invalidate();
3530 if (ftp_scheme->interval) {
3531 if (username->match(text,
interval.
end, end, flags)) {
3532 if (m_colon->match(text, username->interval.end, end, flags) &&
3533 password->match(text, m_colon->interval.end, end, flags) &&
3534 m_at->match(text, password->interval.end, end, flags))
3539 else if (m_at->match(text,
interval.
end, end, flags)) {
3542 password->invalidate();
3545 username->invalidate();
3546 password->invalidate();
3550 username->invalidate();
3551 password->invalidate();
3554 if (ipv4_host->match(text,
interval.
end, end, flags)) {
3557 ipv6_host->invalidate();
3558 dns_host->invalidate();
3561 m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3562 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3563 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3567 ipv4_host->invalidate();
3568 dns_host->invalidate();
3570 else if (dns_host->match(text,
interval.
end, end, flags)) {
3573 ipv4_host->invalidate();
3574 ipv6_host->invalidate();
3581 if (m_colon->match(text,
interval.
end, end, flags) &&
3582 port->match(text, m_colon->interval.end, end, flags))
3590 if (path->match(text,
interval.
end, end, flags)) {
3599 if (mailto_scheme->interval) {
3600 if (username->match(text,
interval.
end, end, flags) &&
3601 m_at->match(text, username->interval.end, end, flags))
3611 if (m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3612 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3613 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
3617 ipv6_host->invalidate();
3618 dns_host->invalidate();
3621 m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3622 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3623 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3627 ipv4_host->invalidate();
3628 dns_host->invalidate();
3630 else if (dns_host->match(text,
interval.
end, end, flags)) {
3633 ipv4_host->invalidate();
3634 ipv6_host->invalidate();
3641 password->invalidate();
3648 if (file_scheme->interval) {
3649 if (path->match(text,
interval.
end, end, flags)) {
3654 username->invalidate();
3655 password->invalidate();
3656 ipv4_host->invalidate();
3657 ipv6_host->invalidate();
3658 dns_host->invalidate();
3667 if (http_scheme->interval &&
3670 if (m_colon->match(text, username->interval.end, end, flags) &&
3671 password->match(text, m_colon->interval.end, end, flags) &&
3672 m_at->match(text, password->interval.end, end, flags))
3677 else if (m_at->match(text, username->interval.end, end, flags)) {
3680 password->invalidate();
3683 username->invalidate();
3684 password->invalidate();
3688 username->invalidate();
3689 password->invalidate();
3692 if (ipv4_host->match(text,
interval.
end, end, flags)) {
3695 ipv6_host->invalidate();
3696 dns_host->invalidate();
3699 m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3700 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3701 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3705 ipv4_host->invalidate();
3706 dns_host->invalidate();
3708 else if (dns_host->match(text,
interval.
end, end, flags)) {
3711 ipv4_host->invalidate();
3712 ipv6_host->invalidate();
3719 if (m_colon->match(text,
interval.
end, end, flags) &&
3720 port->match(text, m_colon->interval.end, end, flags))
3728 if (path->match(text,
interval.
end, end, flags)) {
3737 virtual void invalidate()
3739 http_scheme->invalidate();
3740 ftp_scheme->invalidate();
3741 mailto_scheme->invalidate();
3742 file_scheme->invalidate();
3743 username->invalidate();
3744 password->invalidate();
3745 ipv4_host->invalidate();
3746 ipv6_host->invalidate();
3747 dns_host->invalidate();
3754 std::shared_ptr<basic_parser<T>> http_scheme;
3755 std::shared_ptr<basic_parser<T>> ftp_scheme;
3756 std::shared_ptr<basic_parser<T>> mailto_scheme;
3757 std::shared_ptr<basic_parser<T>> file_scheme;
3758 std::shared_ptr<basic_parser<T>> username;
3759 std::shared_ptr<basic_parser<T>> password;
3760 std::shared_ptr<basic_parser<T>> ipv4_host;
3761 std::shared_ptr<basic_parser<T>> ipv6_host;
3762 std::shared_ptr<basic_parser<T>> dns_host;
3763 std::shared_ptr<basic_parser<T>> port;
3764 std::shared_ptr<basic_parser<T>> path;
3767 std::shared_ptr<basic_parser<T>> m_colon;
3768 std::shared_ptr<basic_parser<T>> m_slash;
3769 std::shared_ptr<basic_parser<T>> m_at;
3770 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
3771 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
3798 _In_
const std::locale& locale = std::locale()) :
3800 username(_username),
3802 m_ip_lbracket(ip_lbracket),
3803 m_ip_rbracket(ip_rbracket),
3804 ipv4_host(_ipv4_host),
3805 ipv6_host(_ipv6_host),
3810 _In_reads_or_z_(end)
const T* text,
3811 _In_
size_t start = 0,
3812 _In_
size_t end = (
size_t)-1,
3813 _In_
int flags = match_default)
3815 assert(text || start >= end);
3817 if (username->match(text, start, end, flags) &&
3818 m_at->match(text, username->interval.end, end, flags))
3821 if (m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
3822 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3823 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
3827 ipv6_host->invalidate();
3828 dns_host->invalidate();
3831 m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
3832 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3833 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3837 ipv4_host->invalidate();
3838 dns_host->invalidate();
3840 else if (dns_host->match(text, m_at->interval.end, end, flags)) {
3843 ipv4_host->invalidate();
3844 ipv6_host->invalidate();
3853 username->invalidate();
3854 ipv4_host->invalidate();
3855 ipv6_host->invalidate();
3856 dns_host->invalidate();
3861 virtual void invalidate()
3863 username->invalidate();
3864 ipv4_host->invalidate();
3865 ipv6_host->invalidate();
3866 dns_host->invalidate();
3871 std::shared_ptr<basic_parser<T>> username;
3872 std::shared_ptr<basic_parser<T>> ipv4_host;
3873 std::shared_ptr<basic_parser<T>> ipv6_host;
3874 std::shared_ptr<basic_parser<T>> dns_host;
3877 std::shared_ptr<basic_parser<T>> m_at;
3878 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
3879 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
3904 _In_
const std::locale& locale = std::locale()) :
3914 _In_reads_or_z_(end)
const T* text,
3915 _In_
size_t start = 0,
3916 _In_
size_t end = (
size_t)-1,
3917 _In_
int flags = match_default)
3919 assert(text || start >= end);
3925 mouth->invalidate();
3937 if (
nose &&
nose->match(text,
eyes->interval.end, end, flags) &&
3938 mouth->match(text,
nose->interval.end, end, flags))
3941 start_mouth =
mouth->interval.start,
3942 hit_offset =
mouth->hit_offset;
3945 mouth->interval.start = start_mouth;
3950 if (
mouth->match(text,
eyes->interval.end, end, flags)) {
3952 start_mouth =
mouth->interval.start,
3953 hit_offset =
mouth->hit_offset;
3957 mouth->interval.start = start_mouth;
3968 mouth->invalidate();
3973 virtual void invalidate()
3979 mouth->invalidate();
3985 std::shared_ptr<basic_parser<T>>
apex;
3986 std::shared_ptr<basic_parser<T>>
eyes;
3987 std::shared_ptr<basic_parser<T>>
nose;
4003 ENUM_FLAGS(date_format_t,
int) {
4022 _In_
int format_mask,
4028 _In_
const std::locale& locale = std::locale()) :
4030 format(date_format_t::none),
4031 m_format_mask(format_mask),
4035 m_separator(separator),
4040 _In_reads_or_z_(end)
const T* text,
4041 _In_
size_t start = 0,
4042 _In_
size_t end = (
size_t)-1,
4043 _In_
int flags = match_default)
4045 assert(text || start >= end);
4047 const int space_match_flags = flags & ~match_multiline;
4048 if ((m_format_mask & date_format_t::dmy) == date_format_t::dmy) {
4049 if (day->match(text, start, end, flags)) {
4051 if (m_separator->match(text,
interval.
end, end, flags)) {
4052 size_t hit_offset = m_separator->hit_offset;
4054 if (month->match(text,
interval.
end, end, flags)) {
4056 if (m_separator->match(text,
interval.
end, end, flags) &&
4057 m_separator->hit_offset == hit_offset)
4060 if (year->match(text,
interval.
end, end, flags) &&
4061 is_valid(day->value, month->value))
4065 format = date_format_t::dmy;
4074 if ((m_format_mask & date_format_t::mdy) == date_format_t::mdy) {
4075 if (month->match(text, start, end, flags)) {
4077 if (m_separator->match(text,
interval.
end, end, flags)) {
4078 size_t hit_offset = m_separator->hit_offset;
4082 if (m_separator->match(text,
interval.
end, end, flags) &&
4083 m_separator->hit_offset == hit_offset)
4086 if (year->match(text,
interval.
end, end, flags) &&
4087 is_valid(day->value, month->value))
4091 format = date_format_t::mdy;
4100 if ((m_format_mask & date_format_t::ymd) == date_format_t::ymd) {
4101 if (year->match(text, start, end, flags)) {
4103 if (m_separator->match(text,
interval.
end, end, flags)) {
4104 size_t hit_offset = m_separator->hit_offset;
4106 if (month->match(text,
interval.
end, end, flags)) {
4108 if (m_separator->match(text,
interval.
end, end, flags) &&
4109 m_separator->hit_offset == hit_offset)
4113 is_valid(day->value, month->value))
4117 format = date_format_t::ymd;
4126 if ((m_format_mask & date_format_t::ym) == date_format_t::ym) {
4127 if (year->match(text, start, end, flags)) {
4129 if (m_separator->match(text,
interval.
end, end, flags)) {
4131 if (month->match(text,
interval.
end, end, flags) &&
4132 is_valid((
size_t)-1, month->value))
4134 if (day) day->invalidate();
4137 format = date_format_t::ym;
4144 if ((m_format_mask & date_format_t::my) == date_format_t::my) {
4145 if (month->match(text, start, end, flags)) {
4147 if (m_separator->match(text,
interval.
end, end, flags)) {
4149 if (year->match(text,
interval.
end, end, flags) &&
4150 is_valid((
size_t)-1, month->value))
4152 if (day) day->invalidate();
4155 format = date_format_t::my;
4162 if ((m_format_mask & date_format_t::dm) == date_format_t::dm) {
4163 if (day->match(text, start, end, flags)) {
4165 if (m_separator->match(text,
interval.
end, end, flags)) {
4166 size_t hit_offset = m_separator->hit_offset;
4168 if (month->match(text,
interval.
end, end, flags) &&
4169 is_valid(day->value, month->value))
4171 if (year) year->invalidate();
4174 if (m_separator->match(text,
interval.
end, end, flags) &&
4175 m_separator->hit_offset == hit_offset)
4179 format = date_format_t::dm;
4186 if ((m_format_mask & date_format_t::md) == date_format_t::md) {
4187 if (month->match(text, start, end, flags)) {
4189 if (m_separator->match(text,
interval.
end, end, flags)) {
4190 size_t hit_offset = m_separator->hit_offset;
4193 is_valid(day->value, month->value))
4195 if (year) year->invalidate();
4198 if (m_separator->match(text,
interval.
end, end, flags) &&
4199 m_separator->hit_offset == hit_offset)
4203 format = date_format_t::md;
4210 if (day) day->invalidate();
4211 if (month) month->invalidate();
4212 if (year) year->invalidate();
4213 format = date_format_t::none;
4218 virtual void invalidate()
4220 if (day) day->invalidate();
4221 if (month) month->invalidate();
4222 if (year) year->invalidate();
4223 format = date_format_t::none;
4228 static inline bool is_valid(
size_t day,
size_t month)
4230 if (month == (
size_t)-1) {
4234 if (day == (
size_t)-1) {
4247 return 1 <= day && day <= 31;
4249 return 1 <= day && day <= 29;
4254 return 1 <= day && day <= 30;
4261 date_format_t format;
4262 std::shared_ptr<basic_integer<T>> day;
4263 std::shared_ptr<basic_integer<T>> month;
4264 std::shared_ptr<basic_integer<T>> year;
4268 std::shared_ptr<basic_set<T>> m_separator;
4269 std::shared_ptr<basic_parser<T>> m_space;
4295 _In_
const std::locale& locale = std::locale()) :
4300 millisecond(_millisecond),
4301 m_separator(separator),
4302 m_millisecond_separator(millisecond_separator)
4306 _In_reads_or_z_(end)
const T* text,
4307 _In_
size_t start = 0,
4308 _In_
size_t end = (
size_t)-1,
4309 _In_
int flags = match_default)
4311 assert(text || start >= end);
4313 if (hour->match(text, start, end, flags) &&
4314 m_separator->match(text, hour->interval.end, end, flags) &&
4315 minute->match(text, m_separator->interval.end, end, flags) &&
4319 size_t hit_offset = m_separator->hit_offset;
4320 if (m_separator->match(text, minute->interval.end, end, flags) &&
4321 m_separator->hit_offset == hit_offset &&
4322 second && second->match(text, m_separator->interval.end, end, flags) &&
4326 if (m_millisecond_separator && m_millisecond_separator->match(text, second->interval.end, end, flags) &&
4327 millisecond && millisecond->match(text, m_millisecond_separator->interval.end, end, flags) &&
4328 millisecond->value < 1000)
4334 if (millisecond) millisecond->invalidate();
4339 if (second) second->invalidate();
4340 if (millisecond) millisecond->invalidate();
4348 minute->invalidate();
4349 if (second) second->invalidate();
4350 if (millisecond) millisecond->invalidate();
4355 virtual void invalidate()
4358 minute->invalidate();
4359 if (second) second->invalidate();
4360 if (millisecond) millisecond->invalidate();
4365 std::shared_ptr<basic_integer10<T>> hour;
4366 std::shared_ptr<basic_integer10<T>> minute;
4367 std::shared_ptr<basic_integer10<T>> second;
4368 std::shared_ptr<basic_integer10<T>> millisecond;
4371 std::shared_ptr<basic_set<T>> m_separator;
4372 std::shared_ptr<basic_parser<T>> m_millisecond_separator;
4399 _In_
const std::locale& locale = std::locale()) :
4402 degree_separator(_degree_separator),
4404 minute_separator(_minute_separator),
4406 second_separator(_second_separator),
4411 _In_reads_or_z_(end)
const T* text,
4412 _In_
size_t start = 0,
4413 _In_
size_t end = (
size_t)-1,
4414 _In_
int flags = match_default)
4416 assert(text || start >= end);
4420 if (degree->match(text,
interval.
end, end, flags) &&
4421 degree_separator->match(text, degree->interval.end, end, flags))
4427 degree->invalidate();
4428 degree_separator->invalidate();
4431 if (minute->match(text,
interval.
end, end, flags) &&
4432 minute->value < 60 &&
4433 minute_separator->match(text, minute->interval.end, end, flags))
4439 minute->invalidate();
4440 minute_separator->invalidate();
4443 if (second && second->match(text,
interval.
end, end, flags) &&
4448 if (second_separator && second_separator->match(text,
interval.
end, end, flags))
4451 if (second_separator) second_separator->invalidate();
4454 if (second) second->invalidate();
4455 if (second_separator) second_separator->invalidate();
4458 if (degree->interval.start < degree->interval.end ||
4459 minute->interval.start < minute->interval.end ||
4460 second && second->interval.start < second->interval.end)
4462 if (decimal && decimal->match(text,
interval.
end, end, flags)) {
4467 decimal->invalidate();
4471 if (decimal) decimal->invalidate();
4476 virtual void invalidate()
4478 degree->invalidate();
4479 degree_separator->invalidate();
4480 minute->invalidate();
4481 minute_separator->invalidate();
4482 if (second) second->invalidate();
4483 if (second_separator) second_separator->invalidate();
4484 if (decimal) decimal->invalidate();
4489 std::shared_ptr<basic_integer10<T>> degree;
4490 std::shared_ptr<basic_parser<T>> degree_separator;
4491 std::shared_ptr<basic_integer10<T>> minute;
4492 std::shared_ptr<basic_parser<T>> minute_separator;
4493 std::shared_ptr<basic_integer10<T>> second;
4494 std::shared_ptr<basic_parser<T>> second_separator;
4495 std::shared_ptr<basic_parser<T>> decimal;
4517 _In_
const std::shared_ptr<
basic_set<T>>& lparenthesis,
4518 _In_
const std::shared_ptr<
basic_set<T>>& rparenthesis,
4521 _In_
const std::locale& locale = std::locale()) :
4524 m_plus_sign(plus_sign),
4525 m_lparenthesis(lparenthesis),
4526 m_rparenthesis(rparenthesis),
4527 m_separator(separator),
4532 _In_reads_or_z_(end)
const T* text,
4533 _In_
size_t start = 0,
4534 _In_
size_t end = (
size_t)-1,
4535 _In_
int flags = match_default)
4537 assert(text || start >= end);
4539 size_t safe_digit_end = start, safe_value_size = 0;
4540 bool has_digits =
false, after_digit =
false, in_parentheses =
false, after_parentheses =
false;
4541 const int space_match_flags = flags & ~match_multiline;
4545 m_lparenthesis->invalidate();
4546 m_rparenthesis->invalidate();
4548 if (m_plus_sign && m_plus_sign->match(text,
interval.
end, end, flags)) {
4549 value.append(text + m_plus_sign->interval.start, text + m_plus_sign->interval.end);
4550 safe_value_size =
value.size();
4558 if (m_digit->match(text,
interval.
end, end, flags)) {
4560 value.append(text + m_digit->interval.start, text + m_digit->interval.end);
4562 if (!in_parentheses) {
4564 safe_value_size =
value.size();
4568 after_parentheses =
false;
4571 m_lparenthesis && !m_lparenthesis->interval &&
4572 m_rparenthesis && !m_rparenthesis->interval &&
4573 m_lparenthesis->match(text,
interval.
end, end, flags))
4576 value.append(text + m_lparenthesis->interval.start, m_lparenthesis->interval.size());
4578 in_parentheses =
true;
4579 after_digit =
false;
4580 after_parentheses =
false;
4584 m_rparenthesis && !m_rparenthesis->interval &&
4585 m_rparenthesis->match(text,
interval.
end, end, flags) &&
4586 m_lparenthesis->hit_offset == m_rparenthesis->hit_offset)
4589 value.append(text + m_rparenthesis->interval.start, text + m_rparenthesis->interval.end);
4592 safe_value_size =
value.size();
4593 in_parentheses =
false;
4594 after_digit =
false;
4595 after_parentheses =
true;
4600 !after_parentheses &&
4601 m_separator && m_separator->match(text,
interval.
end, end, flags))
4605 after_digit =
false;
4606 after_parentheses =
false;
4609 (after_digit || after_parentheses) &&
4610 m_space && m_space->match(text,
interval.
end, end, space_match_flags))
4614 after_digit =
false;
4615 after_parentheses =
false;
4621 value.erase(safe_value_size);
4631 virtual void invalidate()
4641 std::shared_ptr<basic_parser<T>> m_digit;
4642 std::shared_ptr<basic_parser<T>> m_plus_sign;
4643 std::shared_ptr<basic_set<T>> m_lparenthesis;
4644 std::shared_ptr<basic_set<T>> m_rparenthesis;
4645 std::shared_ptr<basic_parser<T>> m_separator;
4646 std::shared_ptr<basic_parser<T>> m_space;
4669 _In_
const std::locale& locale = std::locale()) :
4679 _In_reads_or_z_(end)
const T* text,
4680 _In_
size_t start = 0,
4681 _In_
size_t end = (
size_t)-1,
4682 _In_
int flags = match_default)
4684 assert(text || start >= end);
4690 const int element_match_flags = flags & ~match_case_insensitive;
4692 if (m_element->match(text,
interval.
end, end, element_match_flags)) {
4694 while (m_digit->match(text,
interval.
end, end, flags)) {
4700 if (m_sign->match(text,
interval.
end, end, flags)) {
4714 virtual void invalidate()
4726 std::shared_ptr<basic_parser<T>> m_element;
4727 std::shared_ptr<basic_parser<T>> m_digit;
4728 std::shared_ptr<basic_parser<T>> m_sign;
4747 _In_reads_or_z_(end)
const char* text,
4748 _In_
size_t start = 0,
4749 _In_
size_t end = (
size_t)-1,
4750 _In_
int flags = match_default)
4752 assert(text || start >= end);
4783 _In_reads_or_z_(end)
const char* text,
4784 _In_
size_t start = 0,
4785 _In_
size_t end = (
size_t)-1,
4786 _In_
int flags = match_default)
4788 assert(text || start >= end);
4790 if (m_line_break.match(text,
interval.
end, end, flags)) {
4820 _In_reads_or_z_(end)
const char* text,
4821 _In_
size_t start = 0,
4822 _In_
size_t end = (
size_t)-1,
4823 _In_
int flags = match_default)
4825 assert(text || start >= end);
4829 if (m_space.match(text,
interval.
end, end, flags)) {
4854 _In_reads_or_z_(end)
const char* text,
4855 _In_
size_t start = 0,
4856 _In_
size_t end = (
size_t)-1,
4857 _In_
int flags = match_default)
4859 assert(text || start >= end);
4908 _In_reads_or_z_(end)
const char* text,
4909 _In_
size_t start = 0,
4910 _In_
size_t end = (
size_t)-1,
4911 _In_
int flags = match_default)
4913 assert(text || start >= end);
4935 else if (m_chr.match(text,
interval.
end, end, flags))
4953 virtual void invalidate()
4957 parser::invalidate();
4974 _In_reads_or_z_(end)
const char* text,
4975 _In_
size_t start = 0,
4976 _In_
size_t end = (
size_t)-1,
4977 _In_
int flags = match_default)
4979 assert(text || start >= end);
4981 if (
string.match(text,
interval.
end, end, flags)) {
4988 string.invalidate();
4999 virtual void invalidate()
5001 string.invalidate();
5003 parser::invalidate();
5018 _In_reads_or_z_(end)
const char* text,
5019 _In_
size_t start = 0,
5020 _In_
size_t end = (
size_t)-1,
5021 _In_
int flags = match_default)
5023 assert(text || start >= end);
5029 while (m_space.match(text,
interval.
end, end, flags))
5035 while (m_space.match(text,
interval.
end, end, flags))
5051 virtual void invalidate()
5055 parser::invalidate();
5073 _In_reads_or_z_(end)
const char* text,
5074 _In_
size_t start = 0,
5075 _In_
size_t end = (
size_t)-1,
5076 _In_
int flags = match_default)
5078 assert(text || start >= end);
5079 if (start + 2 < end &&
5080 text[start] ==
'*' &&
5081 text[start + 1] ==
'/' &&
5082 text[start + 2] ==
'*')
5087 else if (start < end && text[start] ==
'*') {
5105 _In_reads_or_z_(end)
const char* text,
5106 _In_
size_t start = 0,
5107 _In_
size_t end = (
size_t)-1,
5108 _In_
int flags = match_default)
5110 assert(text || start >= end);
5116 while (m_space.match(text,
interval.
end, end, flags))
5122 while (m_space.match(text,
interval.
end, end, flags))
5124 if (subtype.match(text,
interval.
end, end, flags))
5133 subtype.invalidate();
5138 virtual void invalidate()
5141 subtype.invalidate();
5142 parser::invalidate();
5160 _In_reads_or_z_(end)
const char* text,
5161 _In_
size_t start = 0,
5162 _In_
size_t end = (
size_t)-1,
5163 _In_
int flags = match_default)
5165 assert(text || start >= end);
5166 if (!http_media_range::match(text, start, end, flags))
5171 if (m_space.match(text,
interval.
end, end, flags))
5175 while (m_space.match(text,
interval.
end, end, flags))
5178 if (param.match(text,
interval.
end, end, flags)) {
5180 params.push_back(std::move(param));
5195 http_media_range::invalidate();
5201 virtual void invalidate()
5204 http_media_range::invalidate();
5208 std::list<http_parameter> params;
5218 _In_reads_or_z_(end)
const char* text,
5219 _In_
size_t start = 0,
5220 _In_
size_t end = (
size_t)-1,
5221 _In_
int flags = match_default)
5223 assert(text || start >= end);
5254 http_url_port(_In_
const std::locale& locale = std::locale()) :
5260 _In_reads_or_z_(end)
const char* text,
5261 _In_
size_t start = 0,
5262 _In_
size_t end = (
size_t)-1,
5263 _In_
int flags = match_default)
5265 assert(text || start >= end);
5271 size_t _value = (size_t)value * 10 + text[
interval.
end] -
'0';
5272 if (_value > (uint16_t)-1) {
5277 value = (uint16_t)_value;
5294 virtual void invalidate()
5297 parser::invalidate();
5311 _In_reads_or_z_(end)
const char* text,
5312 _In_
size_t start = 0,
5313 _In_
size_t end = (
size_t)-1,
5314 _In_
int flags = match_default)
5316 assert(text || start >= end);
5344 _In_reads_or_z_(end)
const char* text,
5345 _In_
size_t start = 0,
5346 _In_
size_t end = (
size_t)-1,
5347 _In_
int flags = match_default)
5349 assert(text || start >= end);
5383 virtual void invalidate()
5386 parser::invalidate();
5400 _In_reads_or_z_(end)
const char* text,
5401 _In_
size_t start = 0,
5402 _In_
size_t end = (
size_t)-1,
5403 _In_
int flags = match_default)
5405 assert(text || start >= end);
5460 virtual void invalidate()
5466 parser::invalidate();
5480 http_url(_In_
const std::locale& locale = std::locale()) :
5486 _In_reads_or_z_(end)
const char* text,
5487 _In_
size_t start = 0,
5488 _In_
size_t end = (
size_t)-1,
5489 _In_
int flags = match_default)
5491 assert(text || start >= end);
5494 if (
interval.
end + 7 <= end && stdex::strnicmp(text +
interval.
end, 7,
"http://", (
size_t)-1, m_locale) == 0) {
5511 server.invalidate();
5535 if (param.match(text,
interval.
end, end, flags)) {
5537 params.push_back(std::move(param));
5552 server.invalidate();
5560 virtual void invalidate()
5562 server.invalidate();
5566 parser::invalidate();
5573 std::list<http_url_parameter> params;
5583 _In_reads_or_z_(end)
const char* text,
5584 _In_
size_t start = 0,
5585 _In_
size_t end = (
size_t)-1,
5586 _In_
int flags = match_default)
5588 assert(text || start >= end);
5596 if (k.
end < end && text[k.
end]) {
5597 if (isalpha(text[k.
end]))
5608 components.push_back(k);
5620 if (!components.empty()) {
5629 virtual void invalidate()
5632 parser::invalidate();
5636 std::vector<stdex::interval<size_t>> components;
5645 http_weight(_In_
const std::locale& locale = std::locale()) :
5651 _In_reads_or_z_(end)
const char* text,
5652 _In_
size_t start = 0,
5653 _In_
size_t end = (
size_t)-1,
5654 _In_
int flags = match_default)
5656 assert(text || start >= end);
5657 size_t celi_del = 0, decimalni_del = 0, decimalni_del_n = 1;
5662 celi_del = celi_del * 10 + text[
interval.
end] -
'0';
5670 decimalni_del = decimalni_del * 10 + text[
interval.
end] -
'0';
5671 decimalni_del_n *= 10;
5689 value = (float)((
double)celi_del + (double)decimalni_del / decimalni_del_n);
5698 virtual void invalidate()
5701 parser::invalidate();
5715 _In_reads_or_z_(end)
const char* text,
5716 _In_
size_t start = 0,
5717 _In_
size_t end = (
size_t)-1,
5718 _In_
int flags = match_default)
5720 assert(text || end <= start);
5721 if (start < end && text[start] ==
'*') {
5733 template <
class T,
class T_asterisk = http_asterisk>
5743 _In_reads_or_z_(end)
const char* text,
5744 _In_
size_t start = 0,
5745 _In_
size_t end = (
size_t)-1,
5746 _In_
int flags = match_default)
5748 assert(text || start >= end);
5749 size_t konec_vrednosti;
5751 if (asterisk.match(text,
interval.
end, end, flags)) {
5752 interval.
end = konec_vrednosti = asterisk.interval.end;
5755 else if (value.match(text,
interval.
end, end, flags)) {
5756 interval.
end = konec_vrednosti = value.interval.end;
5757 asterisk.invalidate();
5760 asterisk.invalidate();
5782 factor.invalidate();
5789 virtual void invalidate()
5791 asterisk.invalidate();
5793 factor.invalidate();
5794 parser::invalidate();
5798 T_asterisk asterisk;
5810 _In_reads_or_z_(end)
const char* text,
5811 _In_
size_t start = 0,
5812 _In_
size_t end = (
size_t)-1,
5813 _In_
int flags = match_default)
5815 assert(text || start >= end);
5825 while (m_space.match(text,
interval.
end, end, flags))
5831 while (m_space.match(text,
interval.
end, end, flags))
5847 virtual void invalidate()
5851 parser::invalidate();
5869 _In_reads_or_z_(end)
const char* text,
5870 _In_
size_t start = 0,
5871 _In_
size_t end = (
size_t)-1,
5872 _In_
int flags = match_default)
5874 assert(text || start >= end);
5880 while (m_space.match(text,
interval.
end, end, flags))
5886 while (m_space.match(text,
interval.
end, end, flags))
5895 if (m_space.match(text,
interval.
end, end, flags))
5899 while (m_space.match(text,
interval.
end, end, flags))
5902 if (param.match(text,
interval.
end, end, flags)) {
5904 params.push_back(std::move(param));
5927 virtual void invalidate()
5932 parser::invalidate();
5951 _In_reads_or_z_(end)
const char* text,
5952 _In_
size_t start = 0,
5953 _In_
size_t end = (
size_t)-1,
5954 _In_
int flags = match_default)
5956 assert(text || start >= end);
6006 virtual void invalidate()
6012 parser::invalidate();
6026 http_protocol(_In_
const std::locale& locale = std::locale()) :
6032 _In_reads_or_z_(end)
const char* text,
6033 _In_
size_t start = 0,
6034 _In_
size_t end = (
size_t)-1,
6035 _In_
int flags = match_default)
6037 assert(text || start >= end);
6069 (uint16_t)strtoui(text + version_maj.
start, version_maj.
size(),
nullptr, 10) * 0x100 +
6070 (uint16_t)strtoui(text + version_min.
start, version_min.
size(),
nullptr, 10);
6083 version_min.
start = 1;
6084 version_min.
end = 0;
6085 version = (uint16_t)strtoui(text + version_maj.
start, version_maj.
size(),
nullptr, 10) * 0x100;
6100 version_maj.
start = 1;
6101 version_maj.
end = 0;
6102 version_min.
start = 1;
6103 version_min.
end = 0;
6110 virtual void invalidate()
6114 version_maj.
start = 1;
6115 version_maj.
end = 0;
6116 version_min.
start = 1;
6117 version_min.
end = 0;
6119 parser::invalidate();
6135 http_request(_In_
const std::locale& locale = std::locale()) :
6142 _In_reads_or_z_(end)
const char* text,
6143 _In_
size_t start = 0,
6144 _In_
size_t end = (
size_t)-1,
6145 _In_
int flags = match_default)
6147 assert(text || start >= end);
6151 if (m_line_break.match(text,
interval.
end, end, flags))
6164 if (m_line_break.match(text,
interval.
end, end, flags))
6180 if (m_line_break.match(text,
interval.
end, end, flags))
6196 protocol.invalidate();
6198 if (m_line_break.match(text,
interval.
end, end, flags)) {
6212 if (m_line_break.match(text,
interval.
end, end, flags)) {
6216 else if (protocol.match(text,
interval.
end, end, flags)) {
6225 if (m_line_break.match(text,
interval.
end, end, flags)) {
6243 protocol.invalidate();
6249 virtual void invalidate()
6254 protocol.invalidate();
6255 parser::invalidate();
6274 _In_reads_or_z_(end)
const char* text,
6275 _In_
size_t start = 0,
6276 _In_
size_t end = (
size_t)-1,
6277 _In_
int flags = match_default)
6279 assert(text || start >= end);
6282 if (m_line_break.match(text,
interval.
end, end, flags) ||
6287 if (m_line_break.match(text,
interval.
end, end, flags))
6294 if (m_line_break.match(text,
interval.
end, end, flags))
6324 value.
start = (size_t)-1;
6327 if (m_line_break.match(text,
interval.
end, end, flags)) {
6329 if (!m_line_break.match(text,
interval.
end, end, flags) &&
6359 virtual void invalidate()
6365 parser::invalidate();
6384 _In_reads_or_z_(end)
const char* text,
6385 _In_
size_t start = 0,
6386 _In_
size_t end = (
size_t)-1,
6387 _In_
int flags = match_default)
6389 while (start < end) {
6390 while (start < end && text[start] && isspace(text[start])) start++;
6391 if (start < end && text[start] ==
',') {
6393 while (start < end&& text[start] && isspace(text[start])) start++;
6396 if (el.match(text, start, end, flags)) {
6397 start = el.interval.end;
6398 T::insert(std::move(el));
6408 constexpr bool operator()(
const T& a,
const T& b)
const noexcept
6410 return a.factor.value > b.factor.value;
6417 template <
class T,
class _Alloc = std::allocator<T>>
6439 _In_
const std::locale& locale = std::locale()) :
6455 _In_reads_or_z_(end)
const T* text,
6456 _In_
size_t start = 0,
6457 _In_
size_t end = (
size_t)-1,
6458 _In_
int flags = match_default)
6460 assert(text || start >= end);
6462 if (m_quote->match(text,
interval.
end, end, flags)) {
6466 if (m_quote->match(text,
interval.
end, end, flags)) {
6471 if (m_escape->match(text,
interval.
end, end, flags)) {
6472 if (m_quote->match(text, m_escape->interval.end, end, flags)) {
6473 value +=
'"';
interval.
end = m_quote->interval.end;
6476 if (m_sol->match(text, m_escape->interval.end, end, flags)) {
6480 if (m_bs->match(text, m_escape->interval.end, end, flags)) {
6484 if (m_ff->match(text, m_escape->interval.end, end, flags)) {
6488 if (m_lf->match(text, m_escape->interval.end, end, flags)) {
6492 if (m_cr->match(text, m_escape->interval.end, end, flags)) {
6496 if (m_htab->match(text, m_escape->interval.end, end, flags)) {
6497 value +=
'\t';
interval.
end = m_htab->interval.end;
6501 m_uni->match(text, m_escape->interval.end, end, flags) &&
6502 m_hex->match(text, m_uni->interval.end, std::min(m_uni->interval.end + 4, end), flags | match_case_insensitive) &&
6503 m_hex->interval.size() == 4 )
6505 assert(m_hex->value <= 0xffff);
6506 if (
sizeof(T) == 1) {
6507 if (m_hex->value > 0x7ff) {
6508 value += (T)(0xe0 | (m_hex->value >> 12) & 0x0f);
6509 value += (T)(0x80 | (m_hex->value >> 6) & 0x3f);
6510 value += (T)(0x80 | m_hex->value & 0x3f);
6512 else if (m_hex->value > 0x7f) {
6513 value += (T)(0xc0 | (m_hex->value >> 6) & 0x1f);
6514 value += (T)(0x80 | m_hex->value & 0x3f);
6517 value += (T)(m_hex->value & 0x7f);
6520 value += (T)m_hex->value;
6524 if (m_escape->match(text, m_escape->interval.end, end, flags)) {
6525 value +=
'\\';
interval.
end = m_escape->interval.end;
6529 if (m_chr->match(text,
interval.
end, end, flags)) {
6530 value.Prilepi(text + m_chr->interval.start, m_chr->interval.size());
6542 virtual void invalidate()
6549 std::basic_string<T> value;
6552 std::shared_ptr<basic_parser<T>> m_quote;
6553 std::shared_ptr<basic_parser<T>> m_chr;
6554 std::shared_ptr<basic_parser<T>> m_escape;
6555 std::shared_ptr<basic_parser<T>> m_sol;
6556 std::shared_ptr<basic_parser<T>> m_bs;
6557 std::shared_ptr<basic_parser<T>> m_ff;
6558 std::shared_ptr<basic_parser<T>> m_lf;
6559 std::shared_ptr<basic_parser<T>> m_cr;
6560 std::shared_ptr<basic_parser<T>> m_htab;
6561 std::shared_ptr<basic_parser<T>> m_uni;
6562 std::shared_ptr<basic_integer16<T>> m_hex;
6575#undef ENUM_FLAG_OPERATOR
Test for angle in d°mm'ss.dddd form.
Definition parser.hpp:4389
Test for any code unit.
Definition parser.hpp:216
Test for beginning of line.
Definition parser.hpp:610
Test for any.
Definition parser.hpp:1052
Test for any code unit from a given string of code units.
Definition parser.hpp:715
Test for specific code unit.
Definition parser.hpp:286
Test for date.
Definition parser.hpp:4019
Test for valid DNS domain character.
Definition parser.hpp:2800
bool allow_on_edge
Is character allowed at the beginning or an end of a DNS domain?
Definition parser.hpp:2838
Test for DNS domain/hostname.
Definition parser.hpp:2900
bool m_allow_absolute
May DNS names end with a dot (absolute name)?
Definition parser.hpp:2964
Test for e-mail address.
Definition parser.hpp:3788
Test for emoticon.
Definition parser.hpp:3896
std::shared_ptr< basic_parser< T > > apex
apex/eyebrows/halo (e.g. O, 0)
Definition parser.hpp:3985
std::shared_ptr< basic_parser< T > > eyes
eyes (e.g. :, ;, >, |, B)
Definition parser.hpp:3986
std::shared_ptr< basic_set< T > > mouth
mouth (e.g. ), ), (, (, |, P, D, p, d)
Definition parser.hpp:3988
std::shared_ptr< basic_parser< T > > nose
nose (e.g. -, o)
Definition parser.hpp:3987
std::shared_ptr< basic_parser< T > > emoticon
emoticon as a whole (e.g. 😀, 🤔, 😶)
Definition parser.hpp:3984
Test for end of line.
Definition parser.hpp:648
Test for fraction.
Definition parser.hpp:1681
Test for decimal integer.
Definition parser.hpp:1290
Test for decimal integer possibly containing thousand separators.
Definition parser.hpp:1375
bool has_separators
Did integer have any separators?
Definition parser.hpp:1435
size_t digit_count
Total number of digits in integer.
Definition parser.hpp:1434
Test for hexadecimal integer.
Definition parser.hpp:1456
Base class for integer testing.
Definition parser.hpp:1268
size_t value
Calculated value of the numeral.
Definition parser.hpp:1282
Test for IPv4 address.
Definition parser.hpp:2340
stdex::interval< size_t > components[4]
Individual component intervals.
Definition parser.hpp:2455
struct in_addr value
IPv4 address value.
Definition parser.hpp:2456
Test for IPv6 address.
Definition parser.hpp:2559
std::shared_ptr< basic_parser< T > > scope_id
Scope ID (e.g. NIC index with link-local addresses)
Definition parser.hpp:2763
stdex::interval< size_t > components[8]
Individual component intervals.
Definition parser.hpp:2761
struct in6_addr value
IPv6 address value.
Definition parser.hpp:2762
Test for valid IPv6 address scope ID character.
Definition parser.hpp:2487
Test for repeating.
Definition parser.hpp:905
bool m_greedy
try to match as long sequence as possible
Definition parser.hpp:944
std::shared_ptr< basic_parser< T > > m_el
repeating element
Definition parser.hpp:941
size_t m_min_iterations
minimum number of iterations
Definition parser.hpp:942
size_t m_max_iterations
maximum number of iterations
Definition parser.hpp:943
Test for JSON string.
Definition parser.hpp:6425
Test for mixed numeral.
Definition parser.hpp:1916
std::shared_ptr< basic_parser< T > > fraction
fraction
Definition parser.hpp:2022
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2020
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2019
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2018
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2021
Test for monetary numeral.
Definition parser.hpp:2211
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2317
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2322
std::shared_ptr< basic_parser< T > > currency
Currency part.
Definition parser.hpp:2320
std::shared_ptr< basic_parser< T > > decimal
Decimal part.
Definition parser.hpp:2323
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2321
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2318
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2319
"No-op" match
Definition parser.hpp:184
Base template for all parsers.
Definition parser.hpp:65
interval< size_t > interval
Region of the last match.
Definition parser.hpp:164
Test for permutation.
Definition parser.hpp:1192
Test for phone number.
Definition parser.hpp:4512
std::basic_string< T > value
Normalized phone number.
Definition parser.hpp:4638
Test for any punctuation code unit.
Definition parser.hpp:458
Test for Roman numeral.
Definition parser.hpp:1565
Test for scientific numeral.
Definition parser.hpp:2042
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2186
std::shared_ptr< basic_parser< T > > exponent_symbol
Exponent symbol (e.g. 'e')
Definition parser.hpp:2190
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2184
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2185
double value
Calculated value of the numeral.
Definition parser.hpp:2194
std::shared_ptr< basic_parser< T > > negative_exp_sign
Negative exponent sign (e.g. '-')
Definition parser.hpp:2192
std::shared_ptr< basic_integer< T > > decimal
Decimal part.
Definition parser.hpp:2189
std::shared_ptr< basic_parser< T > > positive_exp_sign
Positive exponent sign (e.g. '+')
Definition parser.hpp:2191
std::shared_ptr< basic_integer< T > > exponent
Exponent part.
Definition parser.hpp:2193
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2188
std::shared_ptr< basic_integer< T > > integer
Integer part.
Definition parser.hpp:2187
Test for match score.
Definition parser.hpp:1744
Test for sequence.
Definition parser.hpp:1001
Definition parser.hpp:683
Test for signed numeral.
Definition parser.hpp:1830
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:1898
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:1897
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:1896
std::shared_ptr< basic_parser< T > > number
Number.
Definition parser.hpp:1899
Test for any space code unit.
Definition parser.hpp:379
Test for any space or punctuation code unit.
Definition parser.hpp:532
Test for any string.
Definition parser.hpp:1120
Test for given string.
Definition parser.hpp:810
Test for time.
Definition parser.hpp:4286
Test for valid URL password character.
Definition parser.hpp:3082
Test for valid URL path character.
Definition parser.hpp:3182
Test for URL path.
Definition parser.hpp:3290
Test for valid URL username character.
Definition parser.hpp:2983
Test for URL.
Definition parser.hpp:3431
Test for HTTP agent.
Definition parser.hpp:5948
Test for HTTP any type.
Definition parser.hpp:5070
Test for HTTP asterisk.
Definition parser.hpp:5712
Test for HTTP cookie parameter (RFC2109)
Definition parser.hpp:5807
Test for HTTP cookie (RFC2109)
Definition parser.hpp:5866
std::list< http_cookie_parameter > params
List of cookie parameters.
Definition parser.hpp:5938
http_token name
Cookie name.
Definition parser.hpp:5936
http_value value
Cookie value.
Definition parser.hpp:5937
Test for HTTP language (RFC1766)
Definition parser.hpp:5580
Test for HTTP line break (RFC2616: CRLF | LF)
Definition parser.hpp:4744
Test for HTTP parameter (RFC2616: parameter)
Definition parser.hpp:5015
http_token name
Parameter name.
Definition parser.hpp:5059
http_value value
Parameter value.
Definition parser.hpp:5060
Test for HTTP protocol.
Definition parser.hpp:6024
uint16_t version
HTTP protocol version: 0x100 = 1.0, 0x101 = 1.1...
Definition parser.hpp:6126
Test for HTTP quoted string (RFC2616: quoted-string)
Definition parser.hpp:4905
stdex::interval< size_t > content
String content (without quotes)
Definition parser.hpp:4961
Test for HTTP request.
Definition parser.hpp:6133
Test for HTTP space (RFC2616: LWS)
Definition parser.hpp:4780
Test for HTTP text character (RFC2616: TEXT)
Definition parser.hpp:4817
Test for HTTP token (RFC2616: token - tolerates non-ASCII)
Definition parser.hpp:4851
Test for HTTP URL parameter.
Definition parser.hpp:5397
Test for HTTP URL path segment.
Definition parser.hpp:5308
Test for HTTP URL path segment.
Definition parser.hpp:5341
std::vector< http_url_path_segment > segments
Path segments.
Definition parser.hpp:5390
Test for HTTP URL port.
Definition parser.hpp:5252
Test for HTTP URL server.
Definition parser.hpp:5215
Test for HTTP URL.
Definition parser.hpp:5478
Collection of HTTP values.
Definition parser.hpp:6381
Test for HTTP value (RFC2616: value)
Definition parser.hpp:4971
http_quoted_string string
Value when matched as quoted string.
Definition parser.hpp:5007
http_token token
Value when matched as token.
Definition parser.hpp:5008
Test for HTTP weight factor.
Definition parser.hpp:5643
float value
Calculated value of the weight factor.
Definition parser.hpp:5705
Test for HTTP weighted value.
Definition parser.hpp:5735
Base template for collection-holding parsers.
Definition parser.hpp:961
Test for any SGML code point.
Definition parser.hpp:248
Test for any SGML code point from a given string of SGML code points.
Definition parser.hpp:767
Test for specific SGML code point.
Definition parser.hpp:335
Test for valid DNS domain SGML character.
Definition parser.hpp:2856
Test for valid IPv6 address scope ID SGML character.
Definition parser.hpp:2525
Test for any SGML punctuation code point.
Definition parser.hpp:499
Test for any SGML space code point.
Definition parser.hpp:422
Test for any SGML space or punctuation code point.
Definition parser.hpp:575
Test for SGML given string.
Definition parser.hpp:857
Test for valid URL password SGML character.
Definition parser.hpp:3134
Test for valid URL path SGML character.
Definition parser.hpp:3238
Test for valid URL username SGML character.
Definition parser.hpp:3034
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:6407