30#pragma warning(disable: 4100)
40 constexpr int match_default = 0;
41 constexpr int match_case_insensitive = 0x1;
42 constexpr int match_multiline = 0x2;
51 basic_parser(_In_
const std::locale& locale = std::locale()) : m_locale(locale) {}
55 _In_reads_or_z_(end)
const T* text,
56 _In_
size_t start = 0,
57 _In_
size_t end = (
size_t)-1,
58 _In_
int flags = match_default)
60 for (
size_t i = start; i < end && text[i]; i++)
61 if (match(text, i, end, flags))
67 _In_reads_or_z_(end)
const T* text,
68 _In_
size_t start = 0,
69 _In_
size_t end = (
size_t)-1,
70 _In_
int flags = match_default) = 0;
72 template<
class _Traits,
class _Ax>
74 const std::basic_string<T, _Traits, _Ax>& text,
75 _In_
size_t start = 0,
76 _In_
size_t end = (
size_t)-1,
77 _In_
int flags = match_default)
79 return match(text.c_str(), start, std::min<size_t>(end, text.size()), flags);
82 virtual void invalidate()
90 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])
92 if (text[start] ==
'&') {
94 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
95 for (chr_end = start + 1;; chr_end++) {
96 if (chr_end >= end || text[chr_end] == 0) {
100 if (text[chr_end] ==
';') {
102 size_t n = chr_end - start - 1;
103 if (n >= 2 && text[start + 1] ==
'#') {
106 if (text[start + 2] ==
'x' || text[start + 2] ==
'X')
107 unicode = strtou32(text + start + 3, n - 2,
nullptr, 16);
109 unicode = strtou32(text + start + 2, n - 1,
nullptr, 10);
111 if (unicode < 0x10000) {
112 buf[0] = (wchar_t)unicode;
116 ucs4_to_surrogate_pair(buf, unicode);
120 buf[0] = (wchar_t)unicode;
126 const wchar_t* entity_w = sgml2uni(text + start + 1, n);
134 else if (text[chr_end] ==
'&' || ctype.is(ctype.space, text[chr_end])) {
140 buf[0] = text[start];
151 std::locale m_locale;
171 _In_reads_or_z_(end)
const T* text,
172 _In_
size_t start = 0,
173 _In_
size_t end = (
size_t)-1,
174 _In_
int flags = match_default)
176 assert(text || start >= end);
177 if (start < end && text[start]) {
205 _In_reads_or_z_(end)
const T* text,
206 _In_
size_t start = 0,
207 _In_
size_t end = (
size_t)-1,
208 _In_
int flags = match_default)
210 assert(text || start >= end);
211 if (start < end && text[start]) {
237 _In_reads_or_z_(end)
const char* text,
238 _In_
size_t start = 0,
239 _In_
size_t end = (
size_t)-1,
240 _In_
int flags = match_default)
242 assert(text || start >= end);
243 if (start < end && text[start]) {
244 if (text[start] ==
'&') {
246 const auto& ctype = std::use_facet<std::ctype<char>>(m_locale);
272 basic_cu(T chr,
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
279 _In_reads_or_z_(end)
const T* text,
280 _In_
size_t start = 0,
281 _In_
size_t end = (
size_t)-1,
282 _In_
int flags = match_default)
284 assert(text || start >= end);
285 if (start < end && text[start]) {
287 if (flags & match_case_insensitive) {
288 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
289 r = ctype.tolower(text[start]) == ctype.tolower(m_chr);
292 r = text[start] == m_chr;
293 if (r && !m_invert || !r && m_invert) {
321 sgml_cp(
const char* chr,
size_t count = (
size_t)-1,
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
325 assert(chr || !count);
328 m_chr.assign(count ? next_sgml_cp(chr, 0, count, chr_end, buf) : L
"");
332 _In_reads_or_z_(end)
const char* text,
333 _In_
size_t start = 0,
334 _In_
size_t end = (
size_t)-1,
335 _In_
int flags = match_default)
337 assert(text || start >= end);
338 if (start < end && text[start]) {
340 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
341 bool r = ((flags & match_case_insensitive) ?
342 stdex::strnicmp(chr, (
size_t)-1, m_chr.c_str(), m_chr.size(), m_locale) :
343 stdex::strncmp(chr, (
size_t)-1, m_chr.c_str(), m_chr.size())) == 0;
344 if (r && !m_invert || !r && m_invert) {
365 basic_space_cu(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
371 _In_reads_or_z_(end)
const T* text,
372 _In_
size_t start = 0,
373 _In_
size_t end = (
size_t)-1,
374 _In_
int flags = match_default)
376 assert(text || start >= end);
377 if (start < end && text[start]) {
379 ((flags & match_multiline) || !islbreak(text[start])) &&
380 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::space, text[start]);
381 if (r && !m_invert || !r && m_invert) {
408 sgml_space_cp(_In_
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
413 _In_reads_or_z_(end)
const char* text,
414 _In_
size_t start = 0,
415 _In_
size_t end = (
size_t)-1,
416 _In_
int flags = match_default)
418 assert(text || start >= end);
419 if (start < end && text[start]) {
421 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
422 const wchar_t* chr_end = chr + stdex::strlen(chr);
424 ((flags & match_multiline) || !islbreak(chr, (
size_t)-1)) &&
425 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space, chr, chr_end) == chr_end;
426 if (r && !m_invert || !r && m_invert) {
444 basic_punct_cu(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
450 _In_reads_or_z_(end)
const T* text,
451 _In_
size_t start = 0,
452 _In_
size_t end = (
size_t)-1,
453 _In_
int flags = match_default)
455 assert(text || start >= end);
456 if (start < end && text[start]) {
457 bool r = std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::punct, text[start]);
458 if (r && !m_invert || !r && m_invert) {
485 sgml_punct_cp(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
490 _In_reads_or_z_(end)
const char* text,
491 _In_
size_t start = 0,
492 _In_
size_t end = (
size_t)-1,
493 _In_
int flags = match_default)
495 assert(text || start >= end);
496 if (start < end && text[start]) {
498 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
499 const wchar_t* chr_end = chr + stdex::strlen(chr);
500 bool r = std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::punct, chr, chr_end) == chr_end;
501 if (r && !m_invert || !r && m_invert) {
524 _In_reads_or_z_(end)
const T* text,
525 _In_
size_t start = 0,
526 _In_
size_t end = (
size_t)-1,
527 _In_
int flags = match_default)
529 assert(text || start >= end);
530 if (start < end && text[start]) {
532 ((flags & match_multiline) || !islbreak(text[start])) &&
533 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::space | std::ctype_base::punct, text[start]);
534 if (r && !m_invert || !r && m_invert) {
566 _In_reads_or_z_(end)
const char* text,
567 _In_
size_t start = 0,
568 _In_
size_t end = (
size_t)-1,
569 _In_
int flags = match_default)
571 assert(text || start >= end);
572 if (start < end && text[start]) {
574 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
575 const wchar_t* chr_end = chr + stdex::strlen(chr);
577 ((flags & match_multiline) || !islbreak(chr, (
size_t)-1)) &&
578 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space | std::ctype_base::punct, chr, chr_end) == chr_end;
579 if (r && !m_invert || !r && m_invert) {
596 basic_bol(
bool invert =
false) : m_invert(invert) {}
599 _In_reads_or_z_(end)
const T* text,
600 _In_
size_t start = 0,
601 _In_
size_t end = (
size_t)-1,
602 _In_
int flags = match_default)
604 assert(text || start >= end);
605 bool r = start == 0 || start <= end && islbreak(text[start - 1]);
606 if (r && !m_invert || !r && m_invert) {
634 basic_eol(
bool invert =
false) : m_invert(invert) {}
637 _In_reads_or_z_(end)
const T* text,
638 _In_
size_t start = 0,
639 _In_
size_t end = (
size_t)-1,
640 _In_
int flags = match_default)
642 assert(text || start >= end);
643 bool r = islbreak(text[start]);
644 if (r && !m_invert || !r && m_invert) {
669 basic_set(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
671 hit_offset((
size_t)-1),
676 _In_reads_or_z_(end)
const T* text,
677 _In_
size_t start = 0,
678 _In_
size_t end = (
size_t)-1,
679 _In_
int flags = match_default) = 0;
681 virtual void invalidate()
683 hit_offset = (size_t)-1;
702 _In_reads_or_z_(count)
const T* set,
703 _In_
size_t count = (
size_t)-1,
704 _In_
bool invert =
false,
705 _In_
const std::locale& locale = std::locale()) :
709 m_set.assign(set, set + stdex::strnlen(set, count));
713 _In_reads_or_z_(end)
const T* text,
714 _In_
size_t start = 0,
715 _In_
size_t end = (
size_t)-1,
716 _In_
int flags = match_default)
718 assert(text || start >= end);
719 if (start < end && text[start]) {
720 const T* set = m_set.c_str();
721 size_t r = (flags & match_case_insensitive) ?
722 stdex::strnichr(set, m_set.size(), text[start], m_locale) :
723 stdex::strnchr(set, m_set.size(), text[start]);
724 if (r != stdex::npos && !m_invert || r == stdex::npos && m_invert) {
730 hit_offset = (size_t)-1;
736 std::basic_string<T> m_set;
753 sgml_cp_set(
const char* set,
size_t count = (
size_t)-1,
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
757 m_set = sgml2wstr(set, count);
761 _In_reads_or_z_(end)
const char* text,
762 _In_
size_t start = 0,
763 _In_
size_t end = (
size_t)-1,
764 _In_
int flags = match_default)
766 assert(text || start >= end);
767 if (start < end && text[start]) {
769 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
770 const wchar_t* set = m_set.c_str();
771 size_t r = (flags & match_case_insensitive) ?
772 stdex::strnistr(set, m_set.size(), chr, m_locale) :
773 stdex::strnstr(set, m_set.size(), chr);
774 if (r != stdex::npos && !m_invert || r == stdex::npos && m_invert) {
780 hit_offset = (size_t)-1;
797 _In_reads_or_z_(count)
const T* str,
798 _In_
size_t count = (
size_t)-1,
799 _In_
const std::locale& locale = std::locale()) :
801 m_str(str, str + stdex::strnlen(str, count))
805 _In_reads_or_z_(end)
const T* text,
806 _In_
size_t start = 0,
807 _In_
size_t end = (
size_t)-1,
808 _In_
int flags = match_default)
810 assert(text || start >= end);
813 n = std::min<size_t>(end - start, m);
814 bool r = ((flags & match_case_insensitive) ?
815 stdex::strnicmp(text + start, n, m_str.c_str(), m, m_locale) :
816 stdex::strncmp(text + start, n, m_str.c_str(), m)) == 0;
826 std::basic_string<T> m_str;
843 sgml_string(
const char* str,
size_t count = (
size_t)-1, _In_
const std::locale& locale = std::locale()) :
845 m_str(sgml2wstr(str, count))
849 _In_reads_or_z_(end)
const char* text,
850 _In_
size_t start = 0,
851 _In_
size_t end = (
size_t)-1,
852 _In_
int flags = match_default)
854 assert(text || start >= end);
855 const wchar_t* str = m_str.c_str();
856 const bool case_insensitive = flags & match_case_insensitive ? true :
false;
857 const auto& ctype = std::use_facet<std::ctype<wchar_t>>(m_locale);
869 for (; *chr; ++str, ++chr) {
871 (case_insensitive ? ctype.tolower(*str) != ctype.tolower(*chr) : *str != *chr))
899 _In_reads_or_z_(end)
const T* text,
900 _In_
size_t start = 0,
901 _In_
size_t end = (
size_t)-1,
902 _In_
int flags = match_default)
904 assert(text || start >= end);
906 for (
size_t i = 0; ; i++) {
925 std::shared_ptr<basic_parser<T>>
m_el;
953 _In_
const std::locale& locale = std::locale()) :
956 assert(el || !count);
957 m_collection.reserve(count);
958 for (
size_t i = 0; i < count; i++)
959 m_collection.push_back(el[i]);
964 _In_
const std::locale& locale = std::locale()) :
966 m_collection(std::move(collection))
969 virtual void invalidate()
971 for (
auto& el: m_collection)
977 std::vector<std::shared_ptr<basic_parser<T>>> m_collection;
988 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
989 _In_
size_t count = 0,
990 _In_
const std::locale& locale = std::locale()) :
996 _In_
const std::locale& locale = std::locale()) :
1001 _In_reads_or_z_(end)
const T* text,
1002 _In_
size_t start = 0,
1003 _In_
size_t end = (
size_t)-1,
1004 _In_
int flags = match_default)
1006 assert(text || start >= end);
1008 for (
auto i = m_collection.begin(); i != m_collection.end(); ++i) {
1009 if (!(*i)->match(text,
interval.
end, end, flags)) {
1010 for (++i; i != m_collection.end(); ++i)
1040 hit_offset((
size_t)-1)
1045 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1046 _In_
size_t count = 0,
1047 _In_
const std::locale& locale = std::locale()) :
1049 hit_offset((
size_t)-1)
1054 _In_
const std::locale& locale = std::locale()) :
1056 hit_offset((
size_t)-1)
1060 _In_reads_or_z_(end)
const T* text,
1061 _In_
size_t start = 0,
1062 _In_
size_t end = (
size_t)-1,
1063 _In_
int flags = match_default)
1065 assert(text || start >= end);
1067 for (
auto i = m_collection.begin(); i != m_collection.end(); ++i, ++hit_offset) {
1068 if ((*i)->match(text, start, end, flags)) {
1070 for (++i; i != m_collection.end(); ++i)
1075 hit_offset = (size_t)-1;
1080 virtual void invalidate()
1082 hit_offset = (size_t)-1;
1102 template <
class T,
class T_parser = basic_
string<T>>
1107 _In_reads_(count)
const T* str_z =
nullptr,
1108 _In_
size_t count = 0,
1109 _In_
const std::locale& locale = std::locale()) :
1112 build(str_z, count);
1119 va_start(params, str);
1128 va_start(params, str);
1134 void build(_In_reads_(count)
const T* str_z, _In_
size_t count)
1136 assert(str_z || !count);
1141 offset < count && str_z[offset];
1142 offset += stdex::strnlen(str_z + offset, count - offset) + 1, ++n);
1143 m_collection.reserve(n);
1146 offset < count && str_z[offset];
1147 offset += stdex::strnlen(str_z + offset, count - offset) + 1)
1148 m_collection.push_back(std::move(std::make_shared<T_parser>(str_z + offset, count - offset, m_locale)));
1152 void build(_In_z_
const T* str, _In_ va_list params)
1156 m_collection.push_back(std::move(std::make_shared<T_parser>(str, (
size_t)-1, m_locale)));
1157 (p = va_arg(params,
const T*)) !=
nullptr;
1158 m_collection.push_back(std::move(std::make_shared<T_parser>(p, (
size_t)-1, m_locale))));
1179 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1180 _In_
size_t count = 0,
1181 _In_
const std::locale& locale = std::locale()) :
1187 _In_
const std::locale& locale = std::locale()) :
1192 _In_reads_or_z_(end)
const T* text,
1193 _In_
size_t start = 0,
1194 _In_
size_t end = (
size_t)-1,
1195 _In_
int flags = match_default)
1197 assert(text || start >= end);
1198 for (
auto& el: m_collection)
1200 if (match_recursively(text, start, end, flags)) {
1209 bool match_recursively(
1210 _In_reads_or_z_(end)
const T* text,
1211 _In_
size_t start = 0,
1212 _In_
size_t end = (
size_t)-1,
1213 _In_
int flags = match_default)
1215 bool all_matched =
true;
1216 for (
auto& el: m_collection) {
1217 if (!el->interval) {
1219 all_matched =
false;
1220 if (el->match(text, start, end, flags)) {
1222 if (match_recursively(text, el->interval.end, end, flags)) {
1254 basic_integer(_In_
const std::locale& locale = std::locale()) :
1259 virtual void invalidate()
1287 _In_
const std::locale& locale = std::locale()) :
1302 _In_reads_or_z_(end)
const T* text,
1303 _In_
size_t start = 0,
1304 _In_
size_t end = (
size_t)-1,
1305 _In_
int flags = match_default)
1307 assert(text || start >= end);
1310 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0;
interval.
end = m_digit_0->interval.end; }
1311 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1;
interval.
end = m_digit_1->interval.end; }
1312 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2;
interval.
end = m_digit_2->interval.end; }
1313 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3;
interval.
end = m_digit_3->interval.end; }
1314 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4;
interval.
end = m_digit_4->interval.end; }
1315 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5;
interval.
end = m_digit_5->interval.end; }
1316 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6;
interval.
end = m_digit_6->interval.end; }
1317 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7;
interval.
end = m_digit_7->interval.end; }
1318 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8;
interval.
end = m_digit_8->interval.end; }
1319 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9;
interval.
end = m_digit_9->interval.end; }
1332 std::shared_ptr<basic_parser<T>>
1364 _In_
const std::locale& locale = std::locale()) :
1369 m_separator(separator)
1373 _In_reads_or_z_(end)
const T* text,
1374 _In_
size_t start = 0,
1375 _In_
size_t end = (
size_t)-1,
1376 _In_
int flags = match_default)
1378 assert(text || start >= end);
1379 if (m_digits->match(text, start, end, flags)) {
1381 value = m_digits->value;
1386 if (m_digits->interval.size() <= 3) {
1388 size_t hit_offset = (size_t)-1;
1389 while (m_separator->match(text,
interval.
end, end, flags) &&
1390 (hit_offset == (size_t)-1 || hit_offset == m_separator->hit_offset) &&
1391 m_digits->match(text, m_separator->interval.end, end, flags) &&
1392 m_digits->interval.size() == 3)
1399 hit_offset = m_separator->hit_offset;
1410 virtual void invalidate()
1422 std::shared_ptr<basic_integer10<T>> m_digits;
1423 std::shared_ptr<basic_set<T>> m_separator;
1459 _In_
const std::locale& locale = std::locale()) :
1471 m_digit_10(digit_10),
1472 m_digit_11(digit_11),
1473 m_digit_12(digit_12),
1474 m_digit_13(digit_13),
1475 m_digit_14(digit_14),
1476 m_digit_15(digit_15)
1480 _In_reads_or_z_(end)
const T* text,
1481 _In_
size_t start = 0,
1482 _In_
size_t end = (
size_t)-1,
1483 _In_
int flags = match_default)
1485 assert(text || start >= end);
1488 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0;
interval.
end = m_digit_0->interval.end; }
1489 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1;
interval.
end = m_digit_1->interval.end; }
1490 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2;
interval.
end = m_digit_2->interval.end; }
1491 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3;
interval.
end = m_digit_3->interval.end; }
1492 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4;
interval.
end = m_digit_4->interval.end; }
1493 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5;
interval.
end = m_digit_5->interval.end; }
1494 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6;
interval.
end = m_digit_6->interval.end; }
1495 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7;
interval.
end = m_digit_7->interval.end; }
1496 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8;
interval.
end = m_digit_8->interval.end; }
1497 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9;
interval.
end = m_digit_9->interval.end; }
1498 else if (m_digit_10->match(text,
interval.
end, end, flags)) { dig = 10;
interval.
end = m_digit_10->interval.end; }
1499 else if (m_digit_11->match(text,
interval.
end, end, flags)) { dig = 11;
interval.
end = m_digit_11->interval.end; }
1500 else if (m_digit_12->match(text,
interval.
end, end, flags)) { dig = 12;
interval.
end = m_digit_12->interval.end; }
1501 else if (m_digit_13->match(text,
interval.
end, end, flags)) { dig = 13;
interval.
end = m_digit_13->interval.end; }
1502 else if (m_digit_14->match(text,
interval.
end, end, flags)) { dig = 14;
interval.
end = m_digit_14->interval.end; }
1503 else if (m_digit_15->match(text,
interval.
end, end, flags)) { dig = 15;
interval.
end = m_digit_15->interval.end; }
1516 std::shared_ptr<basic_parser<T>>
1561 _In_
const std::locale& locale = std::locale()) :
1565 m_digit_10(digit_10),
1566 m_digit_50(digit_50),
1567 m_digit_100(digit_100),
1568 m_digit_500(digit_500),
1569 m_digit_1000(digit_1000),
1570 m_digit_5000(digit_5000),
1571 m_digit_10000(digit_10000)
1575 _In_reads_or_z_(end)
const T* text,
1576 _In_
size_t start = 0,
1577 _In_
size_t end = (
size_t)-1,
1578 _In_
int flags = match_default)
1580 assert(text || start >= end);
1582 dig[5] = { (size_t)-1, (
size_t)-1, (size_t)-1, (
size_t)-1, (size_t)-1 },
1586 if (m_digit_1 && m_digit_1->match(text,
interval.
end, end, flags)) { dig[0] = 1; end2 = m_digit_1->interval.end; }
1587 else if (m_digit_5 && m_digit_5->match(text,
interval.
end, end, flags)) { dig[0] = 5; end2 = m_digit_5->interval.end; }
1588 else if (m_digit_10 && m_digit_10->match(text,
interval.
end, end, flags)) { dig[0] = 10; end2 = m_digit_10->interval.end; }
1589 else if (m_digit_50 && m_digit_50->match(text,
interval.
end, end, flags)) { dig[0] = 50; end2 = m_digit_50->interval.end; }
1590 else if (m_digit_100 && m_digit_100->match(text,
interval.
end, end, flags)) { dig[0] = 100; end2 = m_digit_100->interval.end; }
1591 else if (m_digit_500 && m_digit_500->match(text,
interval.
end, end, flags)) { dig[0] = 500; end2 = m_digit_500->interval.end; }
1592 else if (m_digit_1000 && m_digit_1000->match(text,
interval.
end, end, flags)) { dig[0] = 1000; end2 = m_digit_1000->interval.end; }
1593 else if (m_digit_5000 && m_digit_5000->match(text,
interval.
end, end, flags)) { dig[0] = 5000; end2 = m_digit_5000->interval.end; }
1594 else if (m_digit_10000 && m_digit_10000->match(text,
interval.
end, end, flags)) { dig[0] = 10000; end2 = m_digit_10000->interval.end; }
1598 if (dig[4] == (
size_t)-1) dig[4] = dig[0];
1600 if (dig[3] == dig[2] && dig[2] == dig[1] && dig[1] == dig[0] && dig[0] != dig[4]) {
1604 if (dig[0] <= dig[1]) {
1609 dig[1] == 1 && (dig[0] == 5 || dig[0] == 10) ||
1610 dig[1] == 10 && (dig[0] == 50 || dig[0] == 100) ||
1611 dig[1] == 100 && (dig[0] == 500 || dig[0] == 1000) ||
1612 dig[1] == 1000 && (dig[0] == 5000 || dig[0] == 10000))
1615 if (dig[2] < dig[0]) {
1639 std::shared_ptr<basic_parser<T>>
1671 _In_
const std::locale& locale = std::locale()) :
1673 numerator(_numerator),
1674 fraction_line(_fraction_line),
1675 denominator(_denominator)
1679 _In_reads_or_z_(end)
const T* text,
1680 _In_
size_t start = 0,
1681 _In_
size_t end = (
size_t)-1,
1682 _In_
int flags = match_default)
1684 assert(text || start >= end);
1685 if (numerator->match(text, start, end, flags) &&
1686 fraction_line->match(text, numerator->interval.end, end, flags) &&
1687 denominator->match(text, fraction_line->interval.end, end, flags))
1693 numerator->invalidate();
1694 fraction_line->invalidate();
1695 denominator->invalidate();
1700 virtual void invalidate()
1702 numerator->invalidate();
1703 fraction_line->invalidate();
1704 denominator->invalidate();
1709 std::shared_ptr<basic_parser<T>> numerator;
1710 std::shared_ptr<basic_parser<T>> fraction_line;
1711 std::shared_ptr<basic_parser<T>> denominator;
1735 _In_
const std::locale& locale = std::locale()) :
1738 separator(_separator),
1744 _In_reads_or_z_(end)
const T* text,
1745 _In_
size_t start = 0,
1746 _In_
size_t end = (
size_t)-1,
1747 _In_
int flags = match_default)
1749 assert(text || start >= end);
1757 const int space_match_flags = flags & ~match_multiline;
1758 for (; m_space->match(text,
interval.
end, end, space_match_flags);
interval.
end = m_space->interval.end);
1760 if (separator->match(text,
interval.
end, end, flags))
1765 for (; m_space->match(text,
interval.
end, end, space_match_flags);
interval.
end = m_space->interval.end);
1777 separator->invalidate();
1778 guest->invalidate();
1783 virtual void invalidate()
1786 separator->invalidate();
1787 guest->invalidate();
1792 std::shared_ptr<basic_parser<T>> home;
1793 std::shared_ptr<basic_parser<T>> separator;
1794 std::shared_ptr<basic_parser<T>> guest;
1797 std::shared_ptr<basic_parser<T>> m_space;
1821 _In_
const std::locale& locale = std::locale()) :
1830 _In_reads_or_z_(end)
const T* text,
1831 _In_
size_t start = 0,
1832 _In_
size_t end = (
size_t)-1,
1833 _In_
int flags = match_default)
1835 assert(text || start >= end);
1870 virtual void invalidate()
1909 _In_
const std::locale& locale = std::locale()) :
1920 _In_reads_or_z_(end)
const T* text,
1921 _In_
size_t start = 0,
1922 _In_
size_t end = (
size_t)-1,
1923 _In_
int flags = match_default)
1925 assert(text || start >= end);
1950 const int space_match_flags = flags & ~match_multiline;
1952 m_space->match(text,
integer->interval.end, end, space_match_flags))
1991 virtual void invalidate()
2009 std::shared_ptr<basic_parser<T>> m_space;
2039 _In_
const std::locale& locale = std::locale()) :
2051 value(std::numeric_limits<double>::quiet_NaN())
2055 _In_reads_or_z_(end)
const T* text,
2056 _In_
size_t start = 0,
2057 _In_
size_t end = (
size_t)-1,
2058 _In_
int flags = match_default)
2060 assert(text || start >= end);
2095 if (!
integer->interval.empty() &&
2141 double e = (double)
exponent->value;
2144 value *= pow(10.0, e);
2151 virtual void invalidate()
2163 value = std::numeric_limits<double>::quiet_NaN();
2205 _In_
const std::locale& locale = std::locale()) :
2217 _In_reads_or_z_(end)
const T* text,
2218 _In_
size_t start = 0,
2219 _In_
size_t end = (
size_t)-1,
2220 _In_
int flags = match_default)
2222 assert(text || start >= end);
2269 if (
integer->interval.empty() &&
2288 virtual void invalidate()
2338 _In_
const std::locale& locale = std::locale()) :
2350 m_separator(separator)
2356 _In_reads_or_z_(end)
const T* text,
2357 _In_
size_t start = 0,
2358 _In_
size_t end = (
size_t)-1,
2359 _In_
int flags = match_default)
2361 assert(text || start >= end);
2366 for (i = 0; i < 4; i++) {
2368 if (m_separator->match(text,
interval.
end, end, flags))
2375 bool is_empty =
true;
2378 size_t dig, digit_end;
2379 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
2380 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
2381 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
2382 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
2383 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
2384 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
2385 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
2386 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
2387 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
2388 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
2390 size_t x_n = x * 10 + dig;
2402 value.s_addr = (
value.s_addr << 8) | (uint8_t)x;
2424 virtual void invalidate()
2443 std::shared_ptr<basic_parser<T>>
2454 std::shared_ptr<basic_parser<T>> m_separator;
2476 _In_reads_or_z_(end)
const T* text,
2477 _In_
size_t start = 0,
2478 _In_
size_t end = (
size_t)-1,
2479 _In_
int flags = match_default)
2481 assert(text || start >= end);
2482 if (start < end && text[start]) {
2483 if (text[start] ==
'-' ||
2484 text[start] ==
'_' ||
2485 text[start] ==
':' ||
2486 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
2514 _In_reads_or_z_(end)
const char* text,
2515 _In_
size_t start = 0,
2516 _In_
size_t end = (
size_t)-1,
2517 _In_
int flags = match_default)
2519 assert(text || start >= end);
2520 if (start < end && text[start]) {
2522 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
2523 const wchar_t* chr_end = chr + stdex::strlen(chr);
2524 if ((chr[0] == L
'-' ||
2526 chr[0] == L
':') && chr[1] == 0 ||
2527 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
2563 _In_
const std::shared_ptr<
basic_parser<T>>& scope_id_separator =
nullptr,
2565 _In_
const std::locale& locale = std::locale()) :
2577 m_digit_10(digit_10),
2578 m_digit_11(digit_11),
2579 m_digit_12(digit_12),
2580 m_digit_13(digit_13),
2581 m_digit_14(digit_14),
2582 m_digit_15(digit_15),
2583 m_separator(separator),
2584 m_scope_id_separator(scope_id_separator),
2591 _In_reads_or_z_(end)
const T* text,
2592 _In_
size_t start = 0,
2593 _In_
size_t end = (
size_t)-1,
2594 _In_
int flags = match_default)
2596 assert(text || start >= end);
2600 size_t i, compaction_i = (size_t)-1, compaction_start = start;
2601 for (i = 0; i < 8; i++) {
2602 bool is_empty =
true;
2604 if (m_separator->match(text,
interval.
end, end, flags)) {
2605 if (m_separator->match(text, m_separator->interval.end, end, flags)) {
2607 if (compaction_i == (
size_t)-1) {
2610 compaction_start = m_separator->interval.start;
2635 size_t dig, digit_end;
2636 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
2637 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
2638 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
2639 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
2640 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
2641 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
2642 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
2643 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
2644 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
2645 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
2646 else if (m_digit_10->match(text,
interval.
end, end, flags)) { dig = 10; digit_end = m_digit_10->interval.end; }
2647 else if (m_digit_11->match(text,
interval.
end, end, flags)) { dig = 11; digit_end = m_digit_11->interval.end; }
2648 else if (m_digit_12->match(text,
interval.
end, end, flags)) { dig = 12; digit_end = m_digit_12->interval.end; }
2649 else if (m_digit_13->match(text,
interval.
end, end, flags)) { dig = 13; digit_end = m_digit_13->interval.end; }
2650 else if (m_digit_14->match(text,
interval.
end, end, flags)) { dig = 14; digit_end = m_digit_14->interval.end; }
2651 else if (m_digit_15->match(text,
interval.
end, end, flags)) { dig = 15; digit_end = m_digit_15->interval.end; }
2653 size_t x_n = x * 16 + dig;
2654 if (x_n <= 0xffff) {
2663 if (compaction_i != (
size_t)-1) {
2670 value.s6_words[i] = (uint16_t)x;
2673 if (compaction_i != (
size_t)-1) {
2676 for (j = 8, k = i; k > compaction_i;) {
2680 for (; j > compaction_i;) {
2681 value.s6_words[--j] = 0;
2689 if (m_scope_id_separator && m_scope_id_separator->match(text,
interval.
end, end, flags) &&
2690 scope_id &&
scope_id->match(text, m_scope_id_separator->interval.end, end, flags))
2721 virtual void invalidate()
2750 std::shared_ptr<basic_parser<T>>
2767 std::shared_ptr<basic_parser<T>> m_separator, m_scope_id_separator;
2787 _In_
bool allow_idn,
2788 _In_
const std::locale& locale = std::locale()) :
2790 m_allow_idn(allow_idn),
2795 _In_reads_or_z_(end)
const T* text,
2796 _In_
size_t start = 0,
2797 _In_
size_t end = (
size_t)-1,
2798 _In_
int flags = match_default)
2800 assert(text || start >= end);
2801 if (start < end && text[start]) {
2802 if ((
'A' <= text[start] && text[start] <=
'Z') ||
2803 (
'a' <= text[start] && text[start] <=
'z') ||
2804 (
'0' <= text[start] && text[start] <=
'9'))
2806 else if (text[start] ==
'-')
2808 else if (m_allow_idn && std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
2843 _In_
bool allow_idn,
2844 _In_
const std::locale& locale = std::locale()) :
2849 _In_reads_or_z_(end)
const char* text,
2850 _In_
size_t start = 0,
2851 _In_
size_t end = (
size_t)-1,
2852 _In_
int flags = match_default)
2854 assert(text || start >= end);
2855 if (start < end && text[start]) {
2857 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
2858 const wchar_t* chr_end = chr + stdex::strlen(chr);
2859 if (((
'A' <= chr[0] && chr[0] <=
'Z') ||
2860 (
'a' <= chr[0] && chr[0] <=
'z') ||
2861 (
'0' <= chr[0] && chr[0] <=
'9')) && chr[1] == 0)
2863 else if (chr[0] ==
'-' && chr[1] == 0)
2865 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)
2887 _In_
bool allow_absolute,
2890 _In_
const std::locale& locale = std::locale()) :
2893 m_domain_char(domain_char),
2894 m_separator(separator)
2898 _In_reads_or_z_(end)
const T* text,
2899 _In_
size_t start = 0,
2900 _In_
size_t end = (
size_t)-1,
2901 _In_
int flags = match_default)
2903 assert(text || start >= end);
2904 size_t i = start, count;
2905 for (count = 0; i < end && text[i] && count < 127; count++) {
2906 if (m_domain_char->match(text, i, end, flags) &&
2907 m_domain_char->allow_on_edge)
2911 while (i < end && text[i]) {
2912 if (m_domain_char->allow_on_edge &&
2913 m_separator->match(text, i, end, flags))
2920 i = m_separator->interval.end;
2924 if (m_domain_char->match(text, i, end, flags)) {
2925 if (m_domain_char->allow_on_edge)
2928 i = m_domain_char->interval.end;
2949 std::shared_ptr<basic_dns_domain_char<T>> m_domain_char;
2950 std::shared_ptr<basic_parser<T>> m_separator;
2972 _In_reads_or_z_(end)
const T* text,
2973 _In_
size_t start = 0,
2974 _In_
size_t end = (
size_t)-1,
2975 _In_
int flags = match_default)
2977 assert(text || start >= end);
2978 if (start < end && text[start]) {
2979 if (text[start] ==
'-' ||
2980 text[start] ==
'.' ||
2981 text[start] ==
'_' ||
2982 text[start] ==
'~' ||
2983 text[start] ==
'%' ||
2984 text[start] ==
'!' ||
2985 text[start] ==
'$' ||
2986 text[start] ==
'&' ||
2987 text[start] ==
'\'' ||
2990 text[start] ==
'*' ||
2991 text[start] ==
'+' ||
2992 text[start] ==
',' ||
2993 text[start] ==
';' ||
2994 text[start] ==
'=' ||
2995 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
3023 _In_reads_or_z_(end)
const char* text,
3024 _In_
size_t start = 0,
3025 _In_
size_t end = (
size_t)-1,
3026 _In_
int flags = match_default)
3028 assert(text || start >= end);
3029 if (start < end && text[start]) {
3031 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
3032 const wchar_t* chr_end = chr + stdex::strlen(chr);
3033 if ((chr[0] == L
'-' ||
3048 chr[0] == L
'=') && chr[1] == 0 ||
3049 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3071 _In_reads_or_z_(end)
const T* text,
3072 _In_
size_t start = 0,
3073 _In_
size_t end = (
size_t)-1,
3074 _In_
int flags = match_default)
3076 assert(text || start >= end);
3077 if (start < end && text[start]) {
3078 if (text[start] ==
'-' ||
3079 text[start] ==
'.' ||
3080 text[start] ==
'_' ||
3081 text[start] ==
'~' ||
3082 text[start] ==
'%' ||
3083 text[start] ==
'!' ||
3084 text[start] ==
'$' ||
3085 text[start] ==
'&' ||
3086 text[start] ==
'\'' ||
3087 text[start] ==
'(' ||
3088 text[start] ==
')' ||
3089 text[start] ==
'*' ||
3090 text[start] ==
'+' ||
3091 text[start] ==
',' ||
3092 text[start] ==
';' ||
3093 text[start] ==
'=' ||
3094 text[start] ==
':' ||
3095 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
3123 _In_reads_or_z_(end)
const char* text,
3124 _In_
size_t start = 0,
3125 _In_
size_t end = (
size_t)-1,
3126 _In_
int flags = match_default)
3128 assert(text || start >= end);
3129 if (start < end && text[start]) {
3131 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
3132 const wchar_t* chr_end = chr + stdex::strlen(chr);
3133 if ((chr[0] == L
'-' ||
3149 chr[0] == L
':') && chr[1] == 0 ||
3150 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3171 _In_reads_or_z_(end)
const T* text,
3172 _In_
size_t start = 0,
3173 _In_
size_t end = (
size_t)-1,
3174 _In_
int flags = match_default)
3176 assert(text || start >= end);
3177 if (start < end && text[start]) {
3178 if (text[start] ==
'/' ||
3179 text[start] ==
'-' ||
3180 text[start] ==
'.' ||
3181 text[start] ==
'_' ||
3182 text[start] ==
'~' ||
3183 text[start] ==
'%' ||
3184 text[start] ==
'!' ||
3185 text[start] ==
'$' ||
3186 text[start] ==
'&' ||
3187 text[start] ==
'\'' ||
3188 text[start] ==
'(' ||
3189 text[start] ==
')' ||
3190 text[start] ==
'*' ||
3191 text[start] ==
'+' ||
3192 text[start] ==
',' ||
3193 text[start] ==
';' ||
3194 text[start] ==
'=' ||
3195 text[start] ==
':' ||
3196 text[start] ==
'@' ||
3197 text[start] ==
'?' ||
3198 text[start] ==
'#' ||
3199 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
3227 _In_reads_or_z_(end)
const char* text,
3228 _In_
size_t start = 0,
3229 _In_
size_t end = (
size_t)-1,
3230 _In_
int flags = match_default)
3232 assert(text || start >= end);
3233 if (start < end && text[start]) {
3235 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
3236 const wchar_t* chr_end = chr + stdex::strlen(chr);
3237 if ((chr[0] == L
'/' ||
3257 chr[0] == L
'#') && chr[1] == 0 ||
3258 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3280 _In_
const std::locale& locale = std::locale()) :
3282 m_path_char(path_char),
3283 m_query_start(query_start),
3284 m_bookmark_start(bookmark_start)
3288 _In_reads_or_z_(end)
const T* text,
3289 _In_
size_t start = 0,
3290 _In_
size_t end = (
size_t)-1,
3291 _In_
int flags = match_default)
3293 assert(text || start >= end);
3305 if (m_query_start->match(text,
interval.
end, end, flags)) {
3313 if (m_bookmark_start->match(text,
interval.
end, end, flags)) {
3321 if (m_path_char->match(text,
interval.
end, end, flags))
3331 if (m_path_char->match(text,
interval.
end, end, flags))
3341 if (m_bookmark_start->match(text,
interval.
end, end, flags)) {
3349 if (m_path_char->match(text,
interval.
end, end, flags))
3359 if (m_path_char->match(text,
interval.
end, end, flags))
3379 virtual void invalidate()
3396 std::shared_ptr<basic_parser<T>> m_path_char;
3397 std::shared_ptr<basic_parser<T>> m_query_start;
3398 std::shared_ptr<basic_parser<T>> m_bookmark_start;
3434 _In_
const std::locale& locale = std::locale()) :
3436 http_scheme(_http_scheme),
3437 ftp_scheme(_ftp_scheme),
3438 mailto_scheme(_mailto_scheme),
3439 file_scheme(_file_scheme),
3442 username(_username),
3443 password(_password),
3445 m_ip_lbracket(ip_lbracket),
3446 m_ip_rbracket(ip_rbracket),
3447 ipv4_host(_ipv4_host),
3448 ipv6_host(_ipv6_host),
3449 dns_host(_dns_host),
3455 _In_reads_or_z_(end)
const T* text,
3456 _In_
size_t start = 0,
3457 _In_
size_t end = (
size_t)-1,
3458 _In_
int flags = match_default)
3460 assert(text || start >= end);
3464 if (http_scheme->match(text,
interval.
end, end, flags) &&
3465 m_colon->match(text, http_scheme->interval.end, end, flags) &&
3466 m_slash->match(text, m_colon->interval.end, end, flags) &&
3467 m_slash->match(text, m_slash->interval.end, end, flags))
3471 ftp_scheme->invalidate();
3472 mailto_scheme->invalidate();
3473 file_scheme->invalidate();
3475 else if (ftp_scheme->match(text,
interval.
end, end, flags) &&
3476 m_colon->match(text, ftp_scheme->interval.end, end, flags) &&
3477 m_slash->match(text, m_colon->interval.end, end, flags) &&
3478 m_slash->match(text, m_slash->interval.end, end, flags))
3482 http_scheme->invalidate();
3483 mailto_scheme->invalidate();
3484 file_scheme->invalidate();
3486 else if (mailto_scheme->match(text,
interval.
end, end, flags) &&
3487 m_colon->match(text, mailto_scheme->interval.end, end, flags))
3491 http_scheme->invalidate();
3492 ftp_scheme->invalidate();
3493 file_scheme->invalidate();
3495 else if (file_scheme->match(text,
interval.
end, end, flags) &&
3496 m_colon->match(text, file_scheme->interval.end, end, flags) &&
3497 m_slash->match(text, m_colon->interval.end, end, flags) &&
3498 m_slash->match(text, m_slash->interval.end, end, flags))
3502 http_scheme->invalidate();
3503 ftp_scheme->invalidate();
3504 mailto_scheme->invalidate();
3508 http_scheme->invalidate();
3509 ftp_scheme->invalidate();
3510 mailto_scheme->invalidate();
3511 file_scheme->invalidate();
3514 if (ftp_scheme->interval) {
3515 if (username->match(text,
interval.
end, end, flags)) {
3516 if (m_colon->match(text, username->interval.end, end, flags) &&
3517 password->match(text, m_colon->interval.end, end, flags) &&
3518 m_at->match(text, password->interval.end, end, flags))
3523 else if (m_at->match(text,
interval.
end, end, flags)) {
3526 password->invalidate();
3529 username->invalidate();
3530 password->invalidate();
3534 username->invalidate();
3535 password->invalidate();
3538 if (ipv4_host->match(text,
interval.
end, end, flags)) {
3541 ipv6_host->invalidate();
3542 dns_host->invalidate();
3545 m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3546 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3547 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3551 ipv4_host->invalidate();
3552 dns_host->invalidate();
3554 else if (dns_host->match(text,
interval.
end, end, flags)) {
3557 ipv4_host->invalidate();
3558 ipv6_host->invalidate();
3565 if (m_colon->match(text,
interval.
end, end, flags) &&
3566 port->match(text, m_colon->interval.end, end, flags))
3574 if (path->match(text,
interval.
end, end, flags)) {
3583 if (mailto_scheme->interval) {
3584 if (username->match(text,
interval.
end, end, flags) &&
3585 m_at->match(text, username->interval.end, end, flags))
3595 if (m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3596 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3597 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
3601 ipv6_host->invalidate();
3602 dns_host->invalidate();
3605 m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3606 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3607 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3611 ipv4_host->invalidate();
3612 dns_host->invalidate();
3614 else if (dns_host->match(text,
interval.
end, end, flags)) {
3617 ipv4_host->invalidate();
3618 ipv6_host->invalidate();
3625 password->invalidate();
3632 if (file_scheme->interval) {
3633 if (path->match(text,
interval.
end, end, flags)) {
3638 username->invalidate();
3639 password->invalidate();
3640 ipv4_host->invalidate();
3641 ipv6_host->invalidate();
3642 dns_host->invalidate();
3651 if (http_scheme->interval &&
3654 if (m_colon->match(text, username->interval.end, end, flags) &&
3655 password->match(text, m_colon->interval.end, end, flags) &&
3656 m_at->match(text, password->interval.end, end, flags))
3661 else if (m_at->match(text, username->interval.end, end, flags)) {
3664 password->invalidate();
3667 username->invalidate();
3668 password->invalidate();
3672 username->invalidate();
3673 password->invalidate();
3676 if (ipv4_host->match(text,
interval.
end, end, flags)) {
3679 ipv6_host->invalidate();
3680 dns_host->invalidate();
3683 m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3684 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3685 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3689 ipv4_host->invalidate();
3690 dns_host->invalidate();
3692 else if (dns_host->match(text,
interval.
end, end, flags)) {
3695 ipv4_host->invalidate();
3696 ipv6_host->invalidate();
3703 if (m_colon->match(text,
interval.
end, end, flags) &&
3704 port->match(text, m_colon->interval.end, end, flags))
3712 if (path->match(text,
interval.
end, end, flags)) {
3721 virtual void invalidate()
3723 http_scheme->invalidate();
3724 ftp_scheme->invalidate();
3725 mailto_scheme->invalidate();
3726 file_scheme->invalidate();
3727 username->invalidate();
3728 password->invalidate();
3729 ipv4_host->invalidate();
3730 ipv6_host->invalidate();
3731 dns_host->invalidate();
3738 std::shared_ptr<basic_parser<T>> http_scheme;
3739 std::shared_ptr<basic_parser<T>> ftp_scheme;
3740 std::shared_ptr<basic_parser<T>> mailto_scheme;
3741 std::shared_ptr<basic_parser<T>> file_scheme;
3742 std::shared_ptr<basic_parser<T>> username;
3743 std::shared_ptr<basic_parser<T>> password;
3744 std::shared_ptr<basic_parser<T>> ipv4_host;
3745 std::shared_ptr<basic_parser<T>> ipv6_host;
3746 std::shared_ptr<basic_parser<T>> dns_host;
3747 std::shared_ptr<basic_parser<T>> port;
3748 std::shared_ptr<basic_parser<T>> path;
3751 std::shared_ptr<basic_parser<T>> m_colon;
3752 std::shared_ptr<basic_parser<T>> m_slash;
3753 std::shared_ptr<basic_parser<T>> m_at;
3754 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
3755 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
3782 _In_
const std::locale& locale = std::locale()) :
3784 username(_username),
3786 m_ip_lbracket(ip_lbracket),
3787 m_ip_rbracket(ip_rbracket),
3788 ipv4_host(_ipv4_host),
3789 ipv6_host(_ipv6_host),
3794 _In_reads_or_z_(end)
const T* text,
3795 _In_
size_t start = 0,
3796 _In_
size_t end = (
size_t)-1,
3797 _In_
int flags = match_default)
3799 assert(text || start >= end);
3801 if (username->match(text, start, end, flags) &&
3802 m_at->match(text, username->interval.end, end, flags))
3805 if (m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
3806 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3807 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
3811 ipv6_host->invalidate();
3812 dns_host->invalidate();
3815 m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
3816 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3817 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3821 ipv4_host->invalidate();
3822 dns_host->invalidate();
3824 else if (dns_host->match(text, m_at->interval.end, end, flags)) {
3827 ipv4_host->invalidate();
3828 ipv6_host->invalidate();
3837 username->invalidate();
3838 ipv4_host->invalidate();
3839 ipv6_host->invalidate();
3840 dns_host->invalidate();
3845 virtual void invalidate()
3847 username->invalidate();
3848 ipv4_host->invalidate();
3849 ipv6_host->invalidate();
3850 dns_host->invalidate();
3855 std::shared_ptr<basic_parser<T>> username;
3856 std::shared_ptr<basic_parser<T>> ipv4_host;
3857 std::shared_ptr<basic_parser<T>> ipv6_host;
3858 std::shared_ptr<basic_parser<T>> dns_host;
3861 std::shared_ptr<basic_parser<T>> m_at;
3862 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
3863 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
3888 _In_
const std::locale& locale = std::locale()) :
3898 _In_reads_or_z_(end)
const T* text,
3899 _In_
size_t start = 0,
3900 _In_
size_t end = (
size_t)-1,
3901 _In_
int flags = match_default)
3903 assert(text || start >= end);
3909 mouth->invalidate();
3921 if (
nose &&
nose->match(text,
eyes->interval.end, end, flags) &&
3922 mouth->match(text,
nose->interval.end, end, flags))
3925 start_mouth =
mouth->interval.start,
3926 hit_offset =
mouth->hit_offset;
3929 mouth->interval.start = start_mouth;
3934 if (
mouth->match(text,
eyes->interval.end, end, flags)) {
3936 start_mouth =
mouth->interval.start,
3937 hit_offset =
mouth->hit_offset;
3941 mouth->interval.start = start_mouth;
3952 mouth->invalidate();
3957 virtual void invalidate()
3963 mouth->invalidate();
3969 std::shared_ptr<basic_parser<T>>
apex;
3970 std::shared_ptr<basic_parser<T>>
eyes;
3971 std::shared_ptr<basic_parser<T>>
nose;
4002 _In_
int format_mask,
4008 _In_
const std::locale& locale = std::locale()) :
4011 m_format_mask(format_mask),
4015 m_separator(separator),
4020 _In_reads_or_z_(end)
const T* text,
4021 _In_
size_t start = 0,
4022 _In_
size_t end = (
size_t)-1,
4023 _In_
int flags = match_default)
4025 assert(text || start >= end);
4027 const int space_match_flags = flags & ~match_multiline;
4028 if ((m_format_mask & format::dmy) != 0) {
4029 if (day->match(text, start, end, flags)) {
4031 if (m_separator->match(text,
interval.
end, end, flags)) {
4032 size_t hit_offset = m_separator->hit_offset;
4034 if (month->match(text,
interval.
end, end, flags)) {
4036 if (m_separator->match(text,
interval.
end, end, flags) &&
4037 m_separator->hit_offset == hit_offset)
4040 if (year->match(text,
interval.
end, end, flags) &&
4041 is_valid(day->value, month->value))
4045 format = format::dmy;
4054 if ((m_format_mask & format::mdy) != 0) {
4055 if (month->match(text, start, end, flags)) {
4057 if (m_separator->match(text,
interval.
end, end, flags)) {
4058 size_t hit_offset = m_separator->hit_offset;
4062 if (m_separator->match(text,
interval.
end, end, flags) &&
4063 m_separator->hit_offset == hit_offset)
4066 if (year->match(text,
interval.
end, end, flags) &&
4067 is_valid(day->value, month->value))
4071 format = format::mdy;
4080 if ((m_format_mask & format::ymd) != 0) {
4081 if (year->match(text, start, end, flags)) {
4083 if (m_separator->match(text,
interval.
end, end, flags)) {
4084 size_t hit_offset = m_separator->hit_offset;
4086 if (month->match(text,
interval.
end, end, flags)) {
4088 if (m_separator->match(text,
interval.
end, end, flags) &&
4089 m_separator->hit_offset == hit_offset)
4093 is_valid(day->value, month->value))
4097 format = format::ymd;
4106 if ((m_format_mask & format::ym) != 0) {
4107 if (year->match(text, start, end, flags)) {
4109 if (m_separator->match(text,
interval.
end, end, flags)) {
4111 if (month->match(text,
interval.
end, end, flags) &&
4112 is_valid((
size_t)-1, month->value))
4114 if (day) day->invalidate();
4117 format = format::ym;
4124 if ((m_format_mask & format::my) != 0) {
4125 if (month->match(text, start, end, flags)) {
4127 if (m_separator->match(text,
interval.
end, end, flags)) {
4129 if (year->match(text,
interval.
end, end, flags) &&
4130 is_valid((
size_t)-1, month->value))
4132 if (day) day->invalidate();
4135 format = format::my;
4142 if ((m_format_mask & format::dm) != 0) {
4143 if (day->match(text, start, end, flags)) {
4145 if (m_separator->match(text,
interval.
end, end, flags)) {
4146 size_t hit_offset = m_separator->hit_offset;
4148 if (month->match(text,
interval.
end, end, flags) &&
4149 is_valid(day->value, month->value))
4151 if (year) year->invalidate();
4154 if (m_separator->match(text,
interval.
end, end, flags) &&
4155 m_separator->hit_offset == hit_offset)
4159 format = format::dm;
4166 if ((m_format_mask & format::md) != 0) {
4167 if (month->match(text, start, end, flags)) {
4169 if (m_separator->match(text,
interval.
end, end, flags)) {
4170 size_t hit_offset = m_separator->hit_offset;
4173 is_valid(day->value, month->value))
4175 if (year) year->invalidate();
4178 if (m_separator->match(text,
interval.
end, end, flags) &&
4179 m_separator->hit_offset == hit_offset)
4183 format = format::md;
4190 if (day) day->invalidate();
4191 if (month) month->invalidate();
4192 if (year) year->invalidate();
4198 virtual void invalidate()
4200 if (day) day->invalidate();
4201 if (month) month->invalidate();
4202 if (year) year->invalidate();
4208 static inline bool is_valid(
size_t day,
size_t month)
4210 if (month == (
size_t)-1) {
4214 if (day == (
size_t)-1) {
4227 return 1 <= day && day <= 31;
4229 return 1 <= day && day <= 29;
4234 return 1 <= day && day <= 30;
4242 std::shared_ptr<basic_integer<T>> day;
4243 std::shared_ptr<basic_integer<T>> month;
4244 std::shared_ptr<basic_integer<T>> year;
4248 std::shared_ptr<basic_set<T>> m_separator;
4249 std::shared_ptr<basic_parser<T>> m_space;
4275 _In_
const std::locale& locale = std::locale()) :
4280 millisecond(_millisecond),
4281 m_separator(separator),
4282 m_millisecond_separator(millisecond_separator)
4286 _In_reads_or_z_(end)
const T* text,
4287 _In_
size_t start = 0,
4288 _In_
size_t end = (
size_t)-1,
4289 _In_
int flags = match_default)
4291 assert(text || start >= end);
4293 if (hour->match(text, start, end, flags) &&
4294 m_separator->match(text, hour->interval.end, end, flags) &&
4295 minute->match(text, m_separator->interval.end, end, flags) &&
4299 size_t hit_offset = m_separator->hit_offset;
4300 if (m_separator->match(text, minute->interval.end, end, flags) &&
4301 m_separator->hit_offset == hit_offset &&
4302 second && second->match(text, m_separator->interval.end, end, flags) &&
4306 if (m_millisecond_separator && m_millisecond_separator->match(text, second->interval.end, end, flags) &&
4307 millisecond && millisecond->match(text, m_millisecond_separator->interval.end, end, flags) &&
4308 millisecond->value < 1000)
4314 if (millisecond) millisecond->invalidate();
4319 if (second) second->invalidate();
4320 if (millisecond) millisecond->invalidate();
4328 minute->invalidate();
4329 if (second) second->invalidate();
4330 if (millisecond) millisecond->invalidate();
4335 virtual void invalidate()
4338 minute->invalidate();
4339 if (second) second->invalidate();
4340 if (millisecond) millisecond->invalidate();
4345 std::shared_ptr<basic_integer10<T>> hour;
4346 std::shared_ptr<basic_integer10<T>> minute;
4347 std::shared_ptr<basic_integer10<T>> second;
4348 std::shared_ptr<basic_integer10<T>> millisecond;
4351 std::shared_ptr<basic_set<T>> m_separator;
4352 std::shared_ptr<basic_parser<T>> m_millisecond_separator;
4379 _In_
const std::locale& locale = std::locale()) :
4382 degree_separator(_degree_separator),
4384 minute_separator(_minute_separator),
4386 second_separator(_second_separator),
4391 _In_reads_or_z_(end)
const T* text,
4392 _In_
size_t start = 0,
4393 _In_
size_t end = (
size_t)-1,
4394 _In_
int flags = match_default)
4396 assert(text || start >= end);
4400 if (degree->match(text,
interval.
end, end, flags) &&
4401 degree_separator->match(text, degree->interval.end, end, flags))
4407 degree->invalidate();
4408 degree_separator->invalidate();
4411 if (minute->match(text,
interval.
end, end, flags) &&
4412 minute->value < 60 &&
4413 minute_separator->match(text, minute->interval.end, end, flags))
4419 minute->invalidate();
4420 minute_separator->invalidate();
4423 if (second && second->match(text,
interval.
end, end, flags) &&
4428 if (second_separator && second_separator->match(text,
interval.
end, end, flags))
4431 if (second_separator) second_separator->invalidate();
4434 if (second) second->invalidate();
4435 if (second_separator) second_separator->invalidate();
4438 if (degree->interval.start < degree->interval.end ||
4439 minute->interval.start < minute->interval.end ||
4440 second && second->interval.start < second->interval.end)
4442 if (decimal && decimal->match(text,
interval.
end, end, flags)) {
4447 decimal->invalidate();
4451 if (decimal) decimal->invalidate();
4456 virtual void invalidate()
4458 degree->invalidate();
4459 degree_separator->invalidate();
4460 minute->invalidate();
4461 minute_separator->invalidate();
4462 if (second) second->invalidate();
4463 if (second_separator) second_separator->invalidate();
4464 if (decimal) decimal->invalidate();
4469 std::shared_ptr<basic_integer10<T>> degree;
4470 std::shared_ptr<basic_parser<T>> degree_separator;
4471 std::shared_ptr<basic_integer10<T>> minute;
4472 std::shared_ptr<basic_parser<T>> minute_separator;
4473 std::shared_ptr<basic_integer10<T>> second;
4474 std::shared_ptr<basic_parser<T>> second_separator;
4475 std::shared_ptr<basic_parser<T>> decimal;
4497 _In_
const std::shared_ptr<
basic_set<T>>& lparenthesis,
4498 _In_
const std::shared_ptr<
basic_set<T>>& rparenthesis,
4501 _In_
const std::locale& locale = std::locale()) :
4504 m_plus_sign(plus_sign),
4505 m_lparenthesis(lparenthesis),
4506 m_rparenthesis(rparenthesis),
4507 m_separator(separator),
4512 _In_reads_or_z_(end)
const T* text,
4513 _In_
size_t start = 0,
4514 _In_
size_t end = (
size_t)-1,
4515 _In_
int flags = match_default)
4517 assert(text || start >= end);
4519 size_t safe_digit_end = start, safe_value_size = 0;
4520 bool has_digits =
false, after_digit =
false, in_parentheses =
false, after_parentheses =
false;
4521 const int space_match_flags = flags & ~match_multiline;
4525 m_lparenthesis->invalidate();
4526 m_rparenthesis->invalidate();
4528 if (m_plus_sign && m_plus_sign->match(text,
interval.
end, end, flags)) {
4529 value.append(text + m_plus_sign->interval.start, text + m_plus_sign->interval.end);
4530 safe_value_size =
value.size();
4538 if (m_digit->match(text,
interval.
end, end, flags)) {
4540 value.append(text + m_digit->interval.start, text + m_digit->interval.end);
4542 if (!in_parentheses) {
4544 safe_value_size =
value.size();
4548 after_parentheses =
false;
4551 m_lparenthesis && !m_lparenthesis->interval &&
4552 m_rparenthesis && !m_rparenthesis->interval &&
4553 m_lparenthesis->match(text,
interval.
end, end, flags))
4556 value.Prilepi(text + m_lparenthesis->interval.start, m_lparenthesis->interval.size());
4558 in_parentheses =
true;
4559 after_digit =
false;
4560 after_parentheses =
false;
4564 m_rparenthesis && !m_rparenthesis->interval &&
4565 m_rparenthesis->match(text,
interval.
end, end, flags) &&
4566 m_lparenthesis->hit_offset == m_rparenthesis->hit_offset)
4569 value.append(text + m_rparenthesis->interval.start, text + m_rparenthesis->interval.end);
4572 safe_value_size =
value.size();
4573 in_parentheses =
false;
4574 after_digit =
false;
4575 after_parentheses =
true;
4580 !after_parentheses &&
4581 m_separator && m_separator->match(text,
interval.
end, end, flags))
4585 after_digit =
false;
4586 after_parentheses =
false;
4589 (after_digit || after_parentheses) &&
4590 m_space && m_space->match(text,
interval.
end, end, space_match_flags))
4594 after_digit =
false;
4595 after_parentheses =
false;
4601 value.erase(safe_value_size);
4611 virtual void invalidate()
4621 std::shared_ptr<basic_parser<T>> m_digit;
4622 std::shared_ptr<basic_parser<T>> m_plus_sign;
4623 std::shared_ptr<basic_set<T>> m_lparenthesis;
4624 std::shared_ptr<basic_set<T>> m_rparenthesis;
4625 std::shared_ptr<basic_parser<T>> m_separator;
4626 std::shared_ptr<basic_parser<T>> m_space;
4649 _In_
const std::locale& locale = std::locale()) :
4659 _In_reads_or_z_(end)
const T* text,
4660 _In_
size_t start = 0,
4661 _In_
size_t end = (
size_t)-1,
4662 _In_
int flags = match_default)
4664 assert(text || start >= end);
4670 const int element_match_flags = flags & ~match_case_insensitive;
4672 if (m_element->match(text,
interval.
end, end, element_match_flags)) {
4674 while (m_digit->match(text,
interval.
end, end, flags)) {
4680 if (m_sign->match(text,
interval.
end, end, flags)) {
4694 virtual void invalidate()
4706 std::shared_ptr<basic_parser<T>> m_element;
4707 std::shared_ptr<basic_parser<T>> m_digit;
4708 std::shared_ptr<basic_parser<T>> m_sign;
4727 _In_reads_or_z_(end)
const char* text,
4728 _In_
size_t start = 0,
4729 _In_
size_t end = (
size_t)-1,
4730 _In_
int flags = match_default)
4732 assert(text || start >= end);
4763 _In_reads_or_z_(end)
const char* text,
4764 _In_
size_t start = 0,
4765 _In_
size_t end = (
size_t)-1,
4766 _In_
int flags = match_default)
4768 assert(text || start >= end);
4770 if (m_line_break.match(text,
interval.
end, end, flags)) {
4800 _In_reads_or_z_(end)
const char* text,
4801 _In_
size_t start = 0,
4802 _In_
size_t end = (
size_t)-1,
4803 _In_
int flags = match_default)
4805 assert(text || start >= end);
4809 if (m_space.match(text,
interval.
end, end, flags)) {
4834 _In_reads_or_z_(end)
const char* text,
4835 _In_
size_t start = 0,
4836 _In_
size_t end = (
size_t)-1,
4837 _In_
int flags = match_default)
4839 assert(text || start >= end);
4888 _In_reads_or_z_(end)
const char* text,
4889 _In_
size_t start = 0,
4890 _In_
size_t end = (
size_t)-1,
4891 _In_
int flags = match_default)
4893 assert(text || start >= end);
4915 else if (m_chr.match(text,
interval.
end, end, flags))
4933 virtual void invalidate()
4937 parser::invalidate();
4954 _In_reads_or_z_(end)
const char* text,
4955 _In_
size_t start = 0,
4956 _In_
size_t end = (
size_t)-1,
4957 _In_
int flags = match_default)
4959 assert(text || start >= end);
4961 if (
string.match(text,
interval.
end, end, flags)) {
4968 string.invalidate();
4979 virtual void invalidate()
4981 string.invalidate();
4983 parser::invalidate();
4998 _In_reads_or_z_(end)
const char* text,
4999 _In_
size_t start = 0,
5000 _In_
size_t end = (
size_t)-1,
5001 _In_
int flags = match_default)
5003 assert(text || start >= end);
5009 while (m_space.match(text,
interval.
end, end, flags))
5015 while (m_space.match(text,
interval.
end, end, flags))
5031 virtual void invalidate()
5035 parser::invalidate();
5053 _In_reads_or_z_(end)
const char* text,
5054 _In_
size_t start = 0,
5055 _In_
size_t end = (
size_t)-1,
5056 _In_
int flags = match_default)
5058 assert(text || start >= end);
5059 if (start + 2 < end &&
5060 text[start] ==
'*' &&
5061 text[start + 1] ==
'/' &&
5062 text[start + 2] ==
'*')
5067 else if (start < end && text[start] ==
'*') {
5085 _In_reads_or_z_(end)
const char* text,
5086 _In_
size_t start = 0,
5087 _In_
size_t end = (
size_t)-1,
5088 _In_
int flags = match_default)
5090 assert(text || start >= end);
5096 while (m_space.match(text,
interval.
end, end, flags))
5102 while (m_space.match(text,
interval.
end, end, flags))
5104 if (subtype.match(text,
interval.
end, end, flags))
5113 subtype.invalidate();
5118 virtual void invalidate()
5121 subtype.invalidate();
5122 parser::invalidate();
5140 _In_reads_or_z_(end)
const char* text,
5141 _In_
size_t start = 0,
5142 _In_
size_t end = (
size_t)-1,
5143 _In_
int flags = match_default)
5145 assert(text || start >= end);
5146 if (!http_media_range::match(text, start, end, flags))
5151 if (m_space.match(text,
interval.
end, end, flags))
5155 while (m_space.match(text,
interval.
end, end, flags))
5158 if (param.match(text,
interval.
end, end, flags)) {
5160 params.push_back(std::move(param));
5175 http_media_range::invalidate();
5181 virtual void invalidate()
5184 http_media_range::invalidate();
5188 std::list<http_parameter> params;
5198 _In_reads_or_z_(end)
const char* text,
5199 _In_
size_t start = 0,
5200 _In_
size_t end = (
size_t)-1,
5201 _In_
int flags = match_default)
5203 assert(text || start >= end);
5234 http_url_port(_In_
const std::locale& locale = std::locale()) :
5240 _In_reads_or_z_(end)
const char* text,
5241 _In_
size_t start = 0,
5242 _In_
size_t end = (
size_t)-1,
5243 _In_
int flags = match_default)
5245 assert(text || start >= end);
5251 size_t _value = (size_t)value * 10 + text[
interval.
end] -
'0';
5252 if (_value > (uint16_t)-1) {
5257 value = (uint16_t)_value;
5274 virtual void invalidate()
5277 parser::invalidate();
5291 _In_reads_or_z_(end)
const char* text,
5292 _In_
size_t start = 0,
5293 _In_
size_t end = (
size_t)-1,
5294 _In_
int flags = match_default)
5296 assert(text || start >= end);
5324 _In_reads_or_z_(end)
const char* text,
5325 _In_
size_t start = 0,
5326 _In_
size_t end = (
size_t)-1,
5327 _In_
int flags = match_default)
5329 assert(text || start >= end);
5363 virtual void invalidate()
5366 parser::invalidate();
5380 _In_reads_or_z_(end)
const char* text,
5381 _In_
size_t start = 0,
5382 _In_
size_t end = (
size_t)-1,
5383 _In_
int flags = match_default)
5385 assert(text || start >= end);
5440 virtual void invalidate()
5446 parser::invalidate();
5460 http_url(_In_
const std::locale& locale = std::locale()) :
5466 _In_reads_or_z_(end)
const char* text,
5467 _In_
size_t start = 0,
5468 _In_
size_t end = (
size_t)-1,
5469 _In_
int flags = match_default)
5471 assert(text || start >= end);
5474 if (
interval.
end + 7 <= end && stdex::strnicmp(text +
interval.
end, 7,
"http://", (
size_t)-1, m_locale) == 0) {
5491 server.invalidate();
5515 if (param.match(text,
interval.
end, end, flags)) {
5517 params.push_back(std::move(param));
5532 server.invalidate();
5540 virtual void invalidate()
5542 server.invalidate();
5546 parser::invalidate();
5553 std::list<http_url_parameter> params;
5563 _In_reads_or_z_(end)
const char* text,
5564 _In_
size_t start = 0,
5565 _In_
size_t end = (
size_t)-1,
5566 _In_
int flags = match_default)
5568 assert(text || start >= end);
5576 if (k.
end < end && text[k.
end]) {
5577 if (isalpha(text[k.
end]))
5588 components.push_back(k);
5600 if (!components.empty()) {
5609 virtual void invalidate()
5612 parser::invalidate();
5616 std::vector<stdex::interval<size_t>> components;
5625 http_weight(_In_
const std::locale& locale = std::locale()) :
5631 _In_reads_or_z_(end)
const char* text,
5632 _In_
size_t start = 0,
5633 _In_
size_t end = (
size_t)-1,
5634 _In_
int flags = match_default)
5636 assert(text || start >= end);
5637 size_t celi_del = 0, decimalni_del = 0, decimalni_del_n = 1;
5642 celi_del = celi_del * 10 + text[
interval.
end] -
'0';
5650 decimalni_del = decimalni_del * 10 + text[
interval.
end] -
'0';
5651 decimalni_del_n *= 10;
5669 value = (float)((
double)celi_del + (double)decimalni_del / decimalni_del_n);
5678 virtual void invalidate()
5681 parser::invalidate();
5695 _In_reads_or_z_(end)
const char* text,
5696 _In_
size_t start = 0,
5697 _In_
size_t end = (
size_t)-1,
5698 _In_
int flags = match_default)
5700 assert(text || end <= start);
5701 if (start < end && text[start] ==
'*') {
5713 template <
class T,
class T_asterisk = http_asterisk>
5723 _In_reads_or_z_(end)
const char* text,
5724 _In_
size_t start = 0,
5725 _In_
size_t end = (
size_t)-1,
5726 _In_
int flags = match_default)
5728 assert(text || start >= end);
5729 size_t konec_vrednosti;
5731 if (asterisk.match(text,
interval.
end, end, flags)) {
5732 interval.
end = konec_vrednosti = asterisk.interval.end;
5735 else if (value.match(text,
interval.
end, end, flags)) {
5736 interval.
end = konec_vrednosti = value.interval.end;
5737 asterisk.invalidate();
5740 asterisk.invalidate();
5762 factor.invalidate();
5769 virtual void invalidate()
5771 asterisk.invalidate();
5773 factor.invalidate();
5774 parser::invalidate();
5778 T_asterisk asterisk;
5790 _In_reads_or_z_(end)
const char* text,
5791 _In_
size_t start = 0,
5792 _In_
size_t end = (
size_t)-1,
5793 _In_
int flags = match_default)
5795 assert(text || start >= end);
5805 while (m_space.match(text,
interval.
end, end, flags))
5811 while (m_space.match(text,
interval.
end, end, flags))
5827 virtual void invalidate()
5831 parser::invalidate();
5849 _In_reads_or_z_(end)
const char* text,
5850 _In_
size_t start = 0,
5851 _In_
size_t end = (
size_t)-1,
5852 _In_
int flags = match_default)
5854 assert(text || start >= end);
5860 while (m_space.match(text,
interval.
end, end, flags))
5866 while (m_space.match(text,
interval.
end, end, flags))
5875 if (m_space.match(text,
interval.
end, end, flags))
5879 while (m_space.match(text,
interval.
end, end, flags))
5882 if (param.match(text,
interval.
end, end, flags)) {
5884 params.push_back(std::move(param));
5907 virtual void invalidate()
5912 parser::invalidate();
5931 _In_reads_or_z_(end)
const char* text,
5932 _In_
size_t start = 0,
5933 _In_
size_t end = (
size_t)-1,
5934 _In_
int flags = match_default)
5936 assert(text || start >= end);
5986 virtual void invalidate()
5992 parser::invalidate();
6006 http_protocol(_In_
const std::locale& locale = std::locale()) :
6012 _In_reads_or_z_(end)
const char* text,
6013 _In_
size_t start = 0,
6014 _In_
size_t end = (
size_t)-1,
6015 _In_
int flags = match_default)
6017 assert(text || start >= end);
6049 (uint16_t)strtoui(text + version_maj.
start, version_maj.
size(),
nullptr, 10) * 0x100 +
6050 (uint16_t)strtoui(text + version_min.
start, version_min.
size(),
nullptr, 10);
6063 version_min.
start = 1;
6064 version_min.
end = 0;
6065 version = (uint16_t)strtoui(text + version_maj.
start, version_maj.
size(),
nullptr, 10) * 0x100;
6080 version_maj.
start = 1;
6081 version_maj.
end = 0;
6082 version_min.
start = 1;
6083 version_min.
end = 0;
6090 virtual void invalidate()
6094 version_maj.
start = 1;
6095 version_maj.
end = 0;
6096 version_min.
start = 1;
6097 version_min.
end = 0;
6099 parser::invalidate();
6115 http_request(_In_
const std::locale& locale = std::locale()) :
6122 _In_reads_or_z_(end)
const char* text,
6123 _In_
size_t start = 0,
6124 _In_
size_t end = (
size_t)-1,
6125 _In_
int flags = match_default)
6127 assert(text || start >= end);
6131 if (m_line_break.match(text,
interval.
end, end, flags))
6144 if (m_line_break.match(text,
interval.
end, end, flags))
6160 if (m_line_break.match(text,
interval.
end, end, flags))
6176 protocol.invalidate();
6178 if (m_line_break.match(text,
interval.
end, end, flags)) {
6192 if (m_line_break.match(text,
interval.
end, end, flags)) {
6196 else if (protocol.match(text,
interval.
end, end, flags)) {
6205 if (m_line_break.match(text,
interval.
end, end, flags)) {
6223 protocol.invalidate();
6229 virtual void invalidate()
6234 protocol.invalidate();
6235 parser::invalidate();
6254 _In_reads_or_z_(end)
const char* text,
6255 _In_
size_t start = 0,
6256 _In_
size_t end = (
size_t)-1,
6257 _In_
int flags = match_default)
6259 assert(text || start >= end);
6262 if (m_line_break.match(text,
interval.
end, end, flags) ||
6267 if (m_line_break.match(text,
interval.
end, end, flags))
6274 if (m_line_break.match(text,
interval.
end, end, flags))
6304 value.
start = (size_t)-1;
6307 if (m_line_break.match(text,
interval.
end, end, flags)) {
6309 if (!m_line_break.match(text,
interval.
end, end, flags) &&
6339 virtual void invalidate()
6345 parser::invalidate();
6364 _In_reads_or_z_(end)
const char* text,
6365 _In_
size_t start = 0,
6366 _In_
size_t end = (
size_t)-1,
6367 _In_
int flags = match_default)
6369 while (start < end) {
6370 while (start < end && text[start] && isspace(text[start])) start++;
6371 if (start < end && text[start] ==
',') {
6373 while (start < end&& text[start] && isspace(text[start])) start++;
6376 if (el.match(text, start, end, flags)) {
6377 start = el.interval.end;
6378 T::insert(std::move(el));
6388 constexpr bool operator()(
const T& a,
const T& b)
const noexcept
6390 return a.factor.value > b.factor.value;
6397 template <
class T,
class _Alloc = std::allocator<T>>
6419 _In_
const std::locale& locale = std::locale()) :
6435 _In_reads_or_z_(end)
const T* text,
6436 _In_
size_t start = 0,
6437 _In_
size_t end = (
size_t)-1,
6438 _In_
int flags = match_default)
6440 assert(text || start >= end);
6442 if (m_quote->match(text,
interval.
end, end, flags)) {
6446 if (m_quote->match(text,
interval.
end, end, flags)) {
6451 if (m_escape->match(text,
interval.
end, end, flags)) {
6452 if (m_quote->match(text, m_escape->interval.end, end, flags)) {
6453 value +=
'"';
interval.
end = m_quote->interval.end;
6456 if (m_sol->match(text, m_escape->interval.end, end, flags)) {
6460 if (m_bs->match(text, m_escape->interval.end, end, flags)) {
6464 if (m_ff->match(text, m_escape->interval.end, end, flags)) {
6468 if (m_lf->match(text, m_escape->interval.end, end, flags)) {
6472 if (m_cr->match(text, m_escape->interval.end, end, flags)) {
6476 if (m_htab->match(text, m_escape->interval.end, end, flags)) {
6477 value +=
'\t';
interval.
end = m_htab->interval.end;
6481 m_uni->match(text, m_escape->interval.end, end, flags) &&
6482 m_hex->match(text, m_uni->interval.end, std::min(m_uni->interval.end + 4, end), flags | match_case_insensitive) &&
6483 m_hex->interval.size() == 4 )
6485 assert(m_hex->value <= 0xffff);
6486 if (
sizeof(T) == 1) {
6487 if (m_hex->value > 0x7ff) {
6488 value += (T)(0xe0 | (m_hex->value >> 12) & 0x0f);
6489 value += (T)(0x80 | (m_hex->value >> 6) & 0x3f);
6490 value += (T)(0x80 | m_hex->value & 0x3f);
6492 else if (m_hex->value > 0x7f) {
6493 value += (T)(0xc0 | (m_hex->value >> 6) & 0x1f);
6494 value += (T)(0x80 | m_hex->value & 0x3f);
6497 value += (T)(m_hex->value & 0x7f);
6500 value += (T)m_hex->value;
6504 if (m_escape->match(text, m_escape->interval.end, end, flags)) {
6505 value +=
'\\';
interval.
end = m_escape->interval.end;
6509 if (m_chr->match(text,
interval.
end, end, flags)) {
6510 value.Prilepi(text + m_chr->interval.start, m_chr->interval.size());
6522 virtual void invalidate()
6529 std::basic_string<T> value;
6532 std::shared_ptr<basic_parser<T>> m_quote;
6533 std::shared_ptr<basic_parser<T>> m_chr;
6534 std::shared_ptr<basic_parser<T>> m_escape;
6535 std::shared_ptr<basic_parser<T>> m_sol;
6536 std::shared_ptr<basic_parser<T>> m_bs;
6537 std::shared_ptr<basic_parser<T>> m_ff;
6538 std::shared_ptr<basic_parser<T>> m_lf;
6539 std::shared_ptr<basic_parser<T>> m_cr;
6540 std::shared_ptr<basic_parser<T>> m_htab;
6541 std::shared_ptr<basic_parser<T>> m_uni;
6542 std::shared_ptr<basic_integer16<T>> m_hex;
Test for angle in d°mm'ss.dddd form.
Definition parser.hpp:4369
Test for any code unit.
Definition parser.hpp:200
Test for beginning of line.
Definition parser.hpp:594
Test for any.
Definition parser.hpp:1036
Test for any code unit from a given string of code units.
Definition parser.hpp:699
Test for specific code unit.
Definition parser.hpp:270
Test for date.
Definition parser.hpp:3989
Test for valid DNS domain character.
Definition parser.hpp:2784
bool allow_on_edge
Is character allowed at the beginning or an end of a DNS domain?
Definition parser.hpp:2822
Test for DNS domain/hostname.
Definition parser.hpp:2884
bool m_allow_absolute
May DNS names end with a dot (absolute name)?
Definition parser.hpp:2948
Test for e-mail address.
Definition parser.hpp:3772
Test for emoticon.
Definition parser.hpp:3880
std::shared_ptr< basic_parser< T > > apex
apex/eyebrows/halo (e.g. O, 0)
Definition parser.hpp:3969
std::shared_ptr< basic_parser< T > > eyes
eyes (e.g. :, ;, >, |, B)
Definition parser.hpp:3970
std::shared_ptr< basic_set< T > > mouth
mouth (e.g. ), ), (, (, |, P, D, p, d)
Definition parser.hpp:3972
std::shared_ptr< basic_parser< T > > nose
nose (e.g. -, o)
Definition parser.hpp:3971
std::shared_ptr< basic_parser< T > > emoticon
emoticon as a whole (e.g. 😀, 🤔, 😶)
Definition parser.hpp:3968
Test for end of line.
Definition parser.hpp:632
Test for fraction.
Definition parser.hpp:1665
Test for decimal integer.
Definition parser.hpp:1274
Test for decimal integer possibly containing thousand separators.
Definition parser.hpp:1359
bool has_separators
Did integer have any separators?
Definition parser.hpp:1419
size_t digit_count
Total number of digits in integer.
Definition parser.hpp:1418
Test for hexadecimal integer.
Definition parser.hpp:1440
Base class for integer testing.
Definition parser.hpp:1252
size_t value
Calculated value of the numeral.
Definition parser.hpp:1266
Test for IPv4 address.
Definition parser.hpp:2324
stdex::interval< size_t > components[4]
Individual component intervals.
Definition parser.hpp:2439
struct in_addr value
IPv4 address value.
Definition parser.hpp:2440
Test for IPv6 address.
Definition parser.hpp:2543
std::shared_ptr< basic_parser< T > > scope_id
Scope ID (e.g. NIC index with link-local addresses)
Definition parser.hpp:2747
stdex::interval< size_t > components[8]
Individual component intervals.
Definition parser.hpp:2745
struct in6_addr value
IPv6 address value.
Definition parser.hpp:2746
Test for valid IPv6 address scope ID character.
Definition parser.hpp:2471
Test for repeating.
Definition parser.hpp:889
bool m_greedy
try to match as long sequence as possible
Definition parser.hpp:928
std::shared_ptr< basic_parser< T > > m_el
repeating element
Definition parser.hpp:925
size_t m_min_iterations
minimum number of iterations
Definition parser.hpp:926
size_t m_max_iterations
maximum number of iterations
Definition parser.hpp:927
Test for JSON string.
Definition parser.hpp:6405
Test for mixed numeral.
Definition parser.hpp:1900
std::shared_ptr< basic_parser< T > > fraction
fraction
Definition parser.hpp:2006
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2004
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2003
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2002
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2005
Test for monetary numeral.
Definition parser.hpp:2195
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2301
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2306
std::shared_ptr< basic_parser< T > > currency
Currency part.
Definition parser.hpp:2304
std::shared_ptr< basic_parser< T > > decimal
Decimal part.
Definition parser.hpp:2307
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2305
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2302
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2303
"No-op" match
Definition parser.hpp:168
Base template for all parsers.
Definition parser.hpp:49
interval< size_t > interval
Region of the last match.
Definition parser.hpp:148
Test for permutation.
Definition parser.hpp:1176
Test for phone number.
Definition parser.hpp:4492
std::basic_string< T > value
Normalized phone number.
Definition parser.hpp:4618
Test for any punctuation code unit.
Definition parser.hpp:442
Test for Roman numeral.
Definition parser.hpp:1549
Test for scientific numeral.
Definition parser.hpp:2026
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2170
std::shared_ptr< basic_parser< T > > exponent_symbol
Exponent symbol (e.g. 'e')
Definition parser.hpp:2174
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2168
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2169
double value
Calculated value of the numeral.
Definition parser.hpp:2178
std::shared_ptr< basic_parser< T > > negative_exp_sign
Negative exponent sign (e.g. '-')
Definition parser.hpp:2176
std::shared_ptr< basic_integer< T > > decimal
Decimal part.
Definition parser.hpp:2173
std::shared_ptr< basic_parser< T > > positive_exp_sign
Positive exponent sign (e.g. '+')
Definition parser.hpp:2175
std::shared_ptr< basic_integer< T > > exponent
Exponent part.
Definition parser.hpp:2177
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2172
std::shared_ptr< basic_integer< T > > integer
Integer part.
Definition parser.hpp:2171
Test for match score.
Definition parser.hpp:1728
Test for sequence.
Definition parser.hpp:985
Definition parser.hpp:667
Test for signed numeral.
Definition parser.hpp:1814
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:1882
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:1881
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:1880
std::shared_ptr< basic_parser< T > > number
Number.
Definition parser.hpp:1883
Test for any space code unit.
Definition parser.hpp:363
Test for any space or punctuation code unit.
Definition parser.hpp:516
Test for any string.
Definition parser.hpp:1104
Test for given string.
Definition parser.hpp:794
Test for time.
Definition parser.hpp:4266
Test for valid URL password character.
Definition parser.hpp:3066
Test for valid URL path character.
Definition parser.hpp:3166
Test for URL path.
Definition parser.hpp:3274
Test for valid URL username character.
Definition parser.hpp:2967
Test for URL.
Definition parser.hpp:3415
Test for HTTP agent.
Definition parser.hpp:5928
Test for HTTP any type.
Definition parser.hpp:5050
Test for HTTP asterisk.
Definition parser.hpp:5692
Test for HTTP cookie parameter (RFC2109)
Definition parser.hpp:5787
Test for HTTP cookie (RFC2109)
Definition parser.hpp:5846
std::list< http_cookie_parameter > params
List of cookie parameters.
Definition parser.hpp:5918
http_token name
Cookie name.
Definition parser.hpp:5916
http_value value
Cookie value.
Definition parser.hpp:5917
Test for HTTP language (RFC1766)
Definition parser.hpp:5560
Test for HTTP line break (RFC2616: CRLF | LF)
Definition parser.hpp:4724
Test for HTTP parameter (RFC2616: parameter)
Definition parser.hpp:4995
http_token name
Parameter name.
Definition parser.hpp:5039
http_value value
Parameter value.
Definition parser.hpp:5040
Test for HTTP protocol.
Definition parser.hpp:6004
uint16_t version
HTTP protocol version: 0x100 = 1.0, 0x101 = 1.1...
Definition parser.hpp:6106
Test for HTTP quoted string (RFC2616: quoted-string)
Definition parser.hpp:4885
stdex::interval< size_t > content
String content (without quotes)
Definition parser.hpp:4941
Test for HTTP request.
Definition parser.hpp:6113
Test for HTTP space (RFC2616: LWS)
Definition parser.hpp:4760
Test for HTTP text character (RFC2616: TEXT)
Definition parser.hpp:4797
Test for HTTP token (RFC2616: token - tolerates non-ASCII)
Definition parser.hpp:4831
Test for HTTP URL parameter.
Definition parser.hpp:5377
Test for HTTP URL path segment.
Definition parser.hpp:5288
Test for HTTP URL path segment.
Definition parser.hpp:5321
std::vector< http_url_path_segment > segments
Path segments.
Definition parser.hpp:5370
Test for HTTP URL port.
Definition parser.hpp:5232
Test for HTTP URL server.
Definition parser.hpp:5195
Test for HTTP URL.
Definition parser.hpp:5458
Collection of HTTP values.
Definition parser.hpp:6361
Test for HTTP value (RFC2616: value)
Definition parser.hpp:4951
http_quoted_string string
Value when matched as quoted string.
Definition parser.hpp:4987
http_token token
Value when matched as token.
Definition parser.hpp:4988
Test for HTTP weight factor.
Definition parser.hpp:5623
float value
Calculated value of the weight factor.
Definition parser.hpp:5685
Test for HTTP weighted value.
Definition parser.hpp:5715
Base template for collection-holding parsers.
Definition parser.hpp:945
Test for any SGML code point.
Definition parser.hpp:232
Test for any SGML code point from a given string of SGML code points.
Definition parser.hpp:751
Test for specific SGML code point.
Definition parser.hpp:319
Test for valid DNS domain SGML character.
Definition parser.hpp:2840
Test for valid IPv6 address scope ID SGML character.
Definition parser.hpp:2509
Test for any SGML punctuation code point.
Definition parser.hpp:483
Test for any SGML space code point.
Definition parser.hpp:406
Test for any SGML space or punctuation code point.
Definition parser.hpp:559
Test for SGML given string.
Definition parser.hpp:841
Test for valid URL password SGML character.
Definition parser.hpp:3118
Test for valid URL path SGML character.
Definition parser.hpp:3222
Test for valid URL username SGML character.
Definition parser.hpp:3018
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:6387