30#pragma warning(disable: 4100)
33#define ENUM_FLAG_OPERATOR(T,X) \
34inline 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)); } \
35inline 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); } \
36inline 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)); } \
37inline T& operator X= (T& lhs, const T rhs) { return lhs = lhs X rhs; } \
38inline T& operator X= (T& lhs, const std::underlying_type_t<T> rhs) { return lhs = lhs X rhs; }
39#define ENUM_FLAGS(T, type) \
41inline T operator ~ (T t) { return (T) (~static_cast<std::underlying_type_t <T>>(t)); } \
42ENUM_FLAG_OPERATOR(T,|) \
43ENUM_FLAG_OPERATOR(T,^) \
44ENUM_FLAG_OPERATOR(T,&) \
54 constexpr int match_default = 0;
55 constexpr int match_case_insensitive = 0x1;
56 constexpr int match_multiline = 0x2;
65 basic_parser(_In_
const std::locale& locale = std::locale()) : m_locale(locale) {}
69 _In_reads_or_z_(end)
const T* text,
70 _In_
size_t start = 0,
71 _In_
size_t end = (
size_t)-1,
72 _In_
int flags = match_default)
74 for (
size_t i = start; i < end && text[i]; i++)
75 if (match(text, i, end, flags))
81 _In_reads_or_z_(end)
const T* text,
82 _In_
size_t start = 0,
83 _In_
size_t end = (
size_t)-1,
84 _In_
int flags = match_default) = 0;
86 template<
class _Traits,
class _Ax>
88 const std::basic_string<T, _Traits, _Ax>& text,
89 _In_
size_t start = 0,
90 _In_
size_t end = (
size_t)-1,
91 _In_
int flags = match_default)
93 return match(text.c_str(), start, std::min<size_t>(end, text.size()), flags);
96 virtual void invalidate()
104 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])
106 if (text[start] ==
'&') {
108 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
109 for (chr_end = start + 1;; chr_end++) {
110 if (chr_end >= end || text[chr_end] == 0) {
114 if (text[chr_end] ==
';') {
116 size_t n = chr_end - start - 1;
117 if (n >= 2 && text[start + 1] ==
'#') {
120 if (text[start + 2] ==
'x' || text[start + 2] ==
'X')
121 unicode = strtou32(text + start + 3, n - 2,
nullptr, 16);
123 unicode = strtou32(text + start + 2, n - 1,
nullptr, 10);
125 if (unicode < 0x10000) {
126 buf[0] = (wchar_t)unicode;
130 ucs4_to_surrogate_pair(buf, unicode);
134 buf[0] = (wchar_t)unicode;
140 const wchar_t* entity_w = sgml2uni(text + start + 1, n);
148 else if (text[chr_end] ==
'&' || ctype.is(ctype.space, text[chr_end])) {
154 buf[0] = text[start];
165 std::locale m_locale;
185 _In_reads_or_z_(end)
const T* text,
186 _In_
size_t start = 0,
187 _In_
size_t end = (
size_t)-1,
188 _In_
int flags = match_default)
190 assert(text || start >= end);
191 if (start < end && text[start]) {
219 _In_reads_or_z_(end)
const T* text,
220 _In_
size_t start = 0,
221 _In_
size_t end = (
size_t)-1,
222 _In_
int flags = match_default)
224 assert(text || start >= end);
225 if (start < end && text[start]) {
251 _In_reads_or_z_(end)
const char* text,
252 _In_
size_t start = 0,
253 _In_
size_t end = (
size_t)-1,
254 _In_
int flags = match_default)
256 assert(text || start >= end);
257 if (start < end && text[start]) {
258 if (text[start] ==
'&') {
260 const auto& ctype = std::use_facet<std::ctype<char>>(m_locale);
286 basic_cu(T chr,
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
293 _In_reads_or_z_(end)
const T* text,
294 _In_
size_t start = 0,
295 _In_
size_t end = (
size_t)-1,
296 _In_
int flags = match_default)
298 assert(text || start >= end);
299 if (start < end && text[start]) {
301 if (flags & match_case_insensitive) {
302 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
303 r = ctype.tolower(text[start]) == ctype.tolower(m_chr);
306 r = text[start] == m_chr;
307 if (r && !m_invert || !r && m_invert) {
335 sgml_cp(
const char* chr,
size_t count = (
size_t)-1,
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
339 assert(chr || !count);
342 m_chr.assign(count ? next_sgml_cp(chr, 0, count, chr_end, buf) : L
"");
346 _In_reads_or_z_(end)
const char* text,
347 _In_
size_t start = 0,
348 _In_
size_t end = (
size_t)-1,
349 _In_
int flags = match_default)
351 assert(text || start >= end);
352 if (start < end && text[start]) {
354 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
355 bool r = ((flags & match_case_insensitive) ?
356 stdex::strnicmp(chr, (
size_t)-1, m_chr.c_str(), m_chr.size(), m_locale) :
357 stdex::strncmp(chr, (
size_t)-1, m_chr.c_str(), m_chr.size())) == 0;
358 if (r && !m_invert || !r && m_invert) {
379 basic_space_cu(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
385 _In_reads_or_z_(end)
const T* text,
386 _In_
size_t start = 0,
387 _In_
size_t end = (
size_t)-1,
388 _In_
int flags = match_default)
390 assert(text || start >= end);
391 if (start < end && text[start]) {
393 ((flags & match_multiline) || !islbreak(text[start])) &&
394 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::space, text[start]);
395 if (r && !m_invert || !r && m_invert) {
422 sgml_space_cp(_In_
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
427 _In_reads_or_z_(end)
const char* text,
428 _In_
size_t start = 0,
429 _In_
size_t end = (
size_t)-1,
430 _In_
int flags = match_default)
432 assert(text || start >= end);
433 if (start < end && text[start]) {
435 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
436 const wchar_t* chr_end = chr + stdex::strlen(chr);
438 ((flags & match_multiline) || !islbreak(chr, (
size_t)-1)) &&
439 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space, chr, chr_end) == chr_end;
440 if (r && !m_invert || !r && m_invert) {
458 basic_punct_cu(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
464 _In_reads_or_z_(end)
const T* text,
465 _In_
size_t start = 0,
466 _In_
size_t end = (
size_t)-1,
467 _In_
int flags = match_default)
469 assert(text || start >= end);
470 if (start < end && text[start]) {
471 bool r = std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::punct, text[start]);
472 if (r && !m_invert || !r && m_invert) {
499 sgml_punct_cp(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
504 _In_reads_or_z_(end)
const char* text,
505 _In_
size_t start = 0,
506 _In_
size_t end = (
size_t)-1,
507 _In_
int flags = match_default)
509 assert(text || start >= end);
510 if (start < end && text[start]) {
512 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
513 const wchar_t* chr_end = chr + stdex::strlen(chr);
514 bool r = std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::punct, chr, chr_end) == chr_end;
515 if (r && !m_invert || !r && m_invert) {
538 _In_reads_or_z_(end)
const T* text,
539 _In_
size_t start = 0,
540 _In_
size_t end = (
size_t)-1,
541 _In_
int flags = match_default)
543 assert(text || start >= end);
544 if (start < end && text[start]) {
546 ((flags & match_multiline) || !islbreak(text[start])) &&
547 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::space | std::ctype_base::punct, text[start]);
548 if (r && !m_invert || !r && m_invert) {
580 _In_reads_or_z_(end)
const char* text,
581 _In_
size_t start = 0,
582 _In_
size_t end = (
size_t)-1,
583 _In_
int flags = match_default)
585 assert(text || start >= end);
586 if (start < end && text[start]) {
588 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
589 const wchar_t* chr_end = chr + stdex::strlen(chr);
591 ((flags & match_multiline) || !islbreak(chr, (
size_t)-1)) &&
592 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space | std::ctype_base::punct, chr, chr_end) == chr_end;
593 if (r && !m_invert || !r && m_invert) {
610 basic_bol(
bool invert =
false) : m_invert(invert) {}
613 _In_reads_or_z_(end)
const T* text,
614 _In_
size_t start = 0,
615 _In_
size_t end = (
size_t)-1,
616 _In_
int flags = match_default)
618 assert(text || start >= end);
619 bool r = start == 0 || start <= end && islbreak(text[start - 1]);
620 if (r && !m_invert || !r && m_invert) {
648 basic_eol(
bool invert =
false) : m_invert(invert) {}
651 _In_reads_or_z_(end)
const T* text,
652 _In_
size_t start = 0,
653 _In_
size_t end = (
size_t)-1,
654 _In_
int flags = match_default)
656 assert(text || start >= end);
657 bool r = islbreak(text[start]);
658 if (r && !m_invert || !r && m_invert) {
683 basic_set(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
685 hit_offset((
size_t)-1),
690 _In_reads_or_z_(end)
const T* text,
691 _In_
size_t start = 0,
692 _In_
size_t end = (
size_t)-1,
693 _In_
int flags = match_default) = 0;
695 virtual void invalidate()
697 hit_offset = (size_t)-1;
716 _In_reads_or_z_(count)
const T* set,
717 _In_
size_t count = (
size_t)-1,
718 _In_
bool invert =
false,
719 _In_
const std::locale& locale = std::locale()) :
723 m_set.assign(set, set + stdex::strnlen(set, count));
727 _In_reads_or_z_(end)
const T* text,
728 _In_
size_t start = 0,
729 _In_
size_t end = (
size_t)-1,
730 _In_
int flags = match_default)
732 assert(text || start >= end);
733 if (start < end && text[start]) {
734 const T* set = m_set.c_str();
735 size_t r = (flags & match_case_insensitive) ?
736 stdex::strnichr(set, m_set.size(), text[start], m_locale) :
737 stdex::strnchr(set, m_set.size(), text[start]);
738 if (r != stdex::npos && !m_invert || r == stdex::npos && m_invert) {
744 hit_offset = (size_t)-1;
750 std::basic_string<T> m_set;
767 sgml_cp_set(
const char* set,
size_t count = (
size_t)-1,
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
771 m_set = sgml2wstr(set, count);
775 _In_reads_or_z_(end)
const char* text,
776 _In_
size_t start = 0,
777 _In_
size_t end = (
size_t)-1,
778 _In_
int flags = match_default)
780 assert(text || start >= end);
781 if (start < end && text[start]) {
783 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
784 const wchar_t* set = m_set.c_str();
785 size_t r = (flags & match_case_insensitive) ?
786 stdex::strnistr(set, m_set.size(), chr, m_locale) :
787 stdex::strnstr(set, m_set.size(), chr);
788 if (r != stdex::npos && !m_invert || r == stdex::npos && m_invert) {
794 hit_offset = (size_t)-1;
811 _In_reads_or_z_(count)
const T* str,
812 _In_
size_t count = (
size_t)-1,
813 _In_
const std::locale& locale = std::locale()) :
815 m_str(str, str + stdex::strnlen(str, count))
819 _In_reads_or_z_(end)
const T* text,
820 _In_
size_t start = 0,
821 _In_
size_t end = (
size_t)-1,
822 _In_
int flags = match_default)
824 assert(text || start >= end);
827 n = std::min<size_t>(end - start, m);
828 bool r = ((flags & match_case_insensitive) ?
829 stdex::strnicmp(text + start, n, m_str.c_str(), m, m_locale) :
830 stdex::strncmp(text + start, n, m_str.c_str(), m)) == 0;
840 std::basic_string<T> m_str;
857 sgml_string(
const char* str,
size_t count = (
size_t)-1, _In_
const std::locale& locale = std::locale()) :
859 m_str(sgml2wstr(str, count))
863 _In_reads_or_z_(end)
const char* text,
864 _In_
size_t start = 0,
865 _In_
size_t end = (
size_t)-1,
866 _In_
int flags = match_default)
868 assert(text || start >= end);
869 const wchar_t* str = m_str.c_str();
870 const bool case_insensitive = flags & match_case_insensitive ? true :
false;
871 const auto& ctype = std::use_facet<std::ctype<wchar_t>>(m_locale);
883 for (; *chr; ++str, ++chr) {
885 (case_insensitive ? ctype.tolower(*str) != ctype.tolower(*chr) : *str != *chr))
913 _In_reads_or_z_(end)
const T* text,
914 _In_
size_t start = 0,
915 _In_
size_t end = (
size_t)-1,
916 _In_
int flags = match_default)
918 assert(text || start >= end);
920 for (
size_t i = 0; ; i++) {
939 std::shared_ptr<basic_parser<T>>
m_el;
967 _In_
const std::locale& locale = std::locale()) :
970 assert(el || !count);
971 m_collection.reserve(count);
972 for (
size_t i = 0; i < count; i++)
973 m_collection.push_back(el[i]);
978 _In_
const std::locale& locale = std::locale()) :
980 m_collection(std::move(collection))
983 virtual void invalidate()
985 for (
auto& el: m_collection)
991 std::vector<std::shared_ptr<basic_parser<T>>> m_collection;
1002 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1003 _In_
size_t count = 0,
1004 _In_
const std::locale& locale = std::locale()) :
1010 _In_
const std::locale& locale = std::locale()) :
1015 _In_reads_or_z_(end)
const T* text,
1016 _In_
size_t start = 0,
1017 _In_
size_t end = (
size_t)-1,
1018 _In_
int flags = match_default)
1020 assert(text || start >= end);
1022 for (
auto i = m_collection.begin(); i != m_collection.end(); ++i) {
1023 if (!(*i)->match(text,
interval.
end, end, flags)) {
1024 for (++i; i != m_collection.end(); ++i)
1054 hit_offset((
size_t)-1)
1059 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1060 _In_
size_t count = 0,
1061 _In_
const std::locale& locale = std::locale()) :
1063 hit_offset((
size_t)-1)
1068 _In_
const std::locale& locale = std::locale()) :
1070 hit_offset((
size_t)-1)
1074 _In_reads_or_z_(end)
const T* text,
1075 _In_
size_t start = 0,
1076 _In_
size_t end = (
size_t)-1,
1077 _In_
int flags = match_default)
1079 assert(text || start >= end);
1081 for (
auto i = m_collection.begin(); i != m_collection.end(); ++i, ++hit_offset) {
1082 if ((*i)->match(text, start, end, flags)) {
1084 for (++i; i != m_collection.end(); ++i)
1089 hit_offset = (size_t)-1;
1094 virtual void invalidate()
1096 hit_offset = (size_t)-1;
1116 template <
class T,
class T_parser = basic_
string<T>>
1121 _In_reads_(count)
const T* str_z =
nullptr,
1122 _In_
size_t count = 0,
1123 _In_
const std::locale& locale = std::locale()) :
1126 build(str_z, count);
1133 va_start(params, str);
1142 va_start(params, str);
1148 void build(_In_reads_(count)
const T* str_z, _In_
size_t count)
1150 assert(str_z || !count);
1155 offset < count && str_z[offset];
1156 offset += stdex::strnlen(str_z + offset, count - offset) + 1, ++n);
1157 m_collection.reserve(n);
1160 offset < count && str_z[offset];
1161 offset += stdex::strnlen(str_z + offset, count - offset) + 1)
1162 m_collection.push_back(std::move(std::make_shared<T_parser>(str_z + offset, count - offset, m_locale)));
1166 void build(_In_z_
const T* str, _In_ va_list params)
1170 m_collection.push_back(std::move(std::make_shared<T_parser>(str, (
size_t)-1, m_locale)));
1171 (p = va_arg(params,
const T*)) !=
nullptr;
1172 m_collection.push_back(std::move(std::make_shared<T_parser>(p, (
size_t)-1, m_locale))));
1193 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1194 _In_
size_t count = 0,
1195 _In_
const std::locale& locale = std::locale()) :
1201 _In_
const std::locale& locale = std::locale()) :
1206 _In_reads_or_z_(end)
const T* text,
1207 _In_
size_t start = 0,
1208 _In_
size_t end = (
size_t)-1,
1209 _In_
int flags = match_default)
1211 assert(text || start >= end);
1212 for (
auto& el: m_collection)
1214 if (match_recursively(text, start, end, flags)) {
1223 bool match_recursively(
1224 _In_reads_or_z_(end)
const T* text,
1225 _In_
size_t start = 0,
1226 _In_
size_t end = (
size_t)-1,
1227 _In_
int flags = match_default)
1229 bool all_matched =
true;
1230 for (
auto& el: m_collection) {
1231 if (!el->interval) {
1233 all_matched =
false;
1234 if (el->match(text, start, end, flags)) {
1236 if (match_recursively(text, el->interval.end, end, flags)) {
1268 basic_integer(_In_
const std::locale& locale = std::locale()) :
1273 virtual void invalidate()
1301 _In_
const std::locale& locale = std::locale()) :
1316 _In_reads_or_z_(end)
const T* text,
1317 _In_
size_t start = 0,
1318 _In_
size_t end = (
size_t)-1,
1319 _In_
int flags = match_default)
1321 assert(text || start >= end);
1324 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0;
interval.
end = m_digit_0->interval.end; }
1325 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1;
interval.
end = m_digit_1->interval.end; }
1326 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2;
interval.
end = m_digit_2->interval.end; }
1327 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3;
interval.
end = m_digit_3->interval.end; }
1328 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4;
interval.
end = m_digit_4->interval.end; }
1329 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5;
interval.
end = m_digit_5->interval.end; }
1330 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6;
interval.
end = m_digit_6->interval.end; }
1331 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7;
interval.
end = m_digit_7->interval.end; }
1332 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8;
interval.
end = m_digit_8->interval.end; }
1333 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9;
interval.
end = m_digit_9->interval.end; }
1346 std::shared_ptr<basic_parser<T>>
1378 _In_
const std::locale& locale = std::locale()) :
1383 m_separator(separator)
1387 _In_reads_or_z_(end)
const T* text,
1388 _In_
size_t start = 0,
1389 _In_
size_t end = (
size_t)-1,
1390 _In_
int flags = match_default)
1392 assert(text || start >= end);
1393 if (m_digits->match(text, start, end, flags)) {
1395 value = m_digits->value;
1400 if (m_digits->interval.size() <= 3) {
1402 size_t hit_offset = (size_t)-1;
1403 while (m_separator->match(text,
interval.
end, end, flags) &&
1404 (hit_offset == (size_t)-1 || hit_offset == m_separator->hit_offset) &&
1405 m_digits->match(text, m_separator->interval.end, end, flags) &&
1406 m_digits->interval.size() == 3)
1413 hit_offset = m_separator->hit_offset;
1424 virtual void invalidate()
1436 std::shared_ptr<basic_integer10<T>> m_digits;
1437 std::shared_ptr<basic_set<T>> m_separator;
1473 _In_
const std::locale& locale = std::locale()) :
1485 m_digit_10(digit_10),
1486 m_digit_11(digit_11),
1487 m_digit_12(digit_12),
1488 m_digit_13(digit_13),
1489 m_digit_14(digit_14),
1490 m_digit_15(digit_15)
1494 _In_reads_or_z_(end)
const T* text,
1495 _In_
size_t start = 0,
1496 _In_
size_t end = (
size_t)-1,
1497 _In_
int flags = match_default)
1499 assert(text || start >= end);
1502 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0;
interval.
end = m_digit_0->interval.end; }
1503 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1;
interval.
end = m_digit_1->interval.end; }
1504 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2;
interval.
end = m_digit_2->interval.end; }
1505 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3;
interval.
end = m_digit_3->interval.end; }
1506 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4;
interval.
end = m_digit_4->interval.end; }
1507 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5;
interval.
end = m_digit_5->interval.end; }
1508 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6;
interval.
end = m_digit_6->interval.end; }
1509 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7;
interval.
end = m_digit_7->interval.end; }
1510 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8;
interval.
end = m_digit_8->interval.end; }
1511 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9;
interval.
end = m_digit_9->interval.end; }
1512 else if (m_digit_10->match(text,
interval.
end, end, flags)) { dig = 10;
interval.
end = m_digit_10->interval.end; }
1513 else if (m_digit_11->match(text,
interval.
end, end, flags)) { dig = 11;
interval.
end = m_digit_11->interval.end; }
1514 else if (m_digit_12->match(text,
interval.
end, end, flags)) { dig = 12;
interval.
end = m_digit_12->interval.end; }
1515 else if (m_digit_13->match(text,
interval.
end, end, flags)) { dig = 13;
interval.
end = m_digit_13->interval.end; }
1516 else if (m_digit_14->match(text,
interval.
end, end, flags)) { dig = 14;
interval.
end = m_digit_14->interval.end; }
1517 else if (m_digit_15->match(text,
interval.
end, end, flags)) { dig = 15;
interval.
end = m_digit_15->interval.end; }
1530 std::shared_ptr<basic_parser<T>>
1575 _In_
const std::locale& locale = std::locale()) :
1579 m_digit_10(digit_10),
1580 m_digit_50(digit_50),
1581 m_digit_100(digit_100),
1582 m_digit_500(digit_500),
1583 m_digit_1000(digit_1000),
1584 m_digit_5000(digit_5000),
1585 m_digit_10000(digit_10000)
1589 _In_reads_or_z_(end)
const T* text,
1590 _In_
size_t start = 0,
1591 _In_
size_t end = (
size_t)-1,
1592 _In_
int flags = match_default)
1594 assert(text || start >= end);
1596 dig[5] = { (size_t)-1, (
size_t)-1, (size_t)-1, (
size_t)-1, (size_t)-1 },
1600 if (m_digit_1 && m_digit_1->match(text,
interval.
end, end, flags)) { dig[0] = 1; end2 = m_digit_1->interval.end; }
1601 else if (m_digit_5 && m_digit_5->match(text,
interval.
end, end, flags)) { dig[0] = 5; end2 = m_digit_5->interval.end; }
1602 else if (m_digit_10 && m_digit_10->match(text,
interval.
end, end, flags)) { dig[0] = 10; end2 = m_digit_10->interval.end; }
1603 else if (m_digit_50 && m_digit_50->match(text,
interval.
end, end, flags)) { dig[0] = 50; end2 = m_digit_50->interval.end; }
1604 else if (m_digit_100 && m_digit_100->match(text,
interval.
end, end, flags)) { dig[0] = 100; end2 = m_digit_100->interval.end; }
1605 else if (m_digit_500 && m_digit_500->match(text,
interval.
end, end, flags)) { dig[0] = 500; end2 = m_digit_500->interval.end; }
1606 else if (m_digit_1000 && m_digit_1000->match(text,
interval.
end, end, flags)) { dig[0] = 1000; end2 = m_digit_1000->interval.end; }
1607 else if (m_digit_5000 && m_digit_5000->match(text,
interval.
end, end, flags)) { dig[0] = 5000; end2 = m_digit_5000->interval.end; }
1608 else if (m_digit_10000 && m_digit_10000->match(text,
interval.
end, end, flags)) { dig[0] = 10000; end2 = m_digit_10000->interval.end; }
1612 if (dig[4] == (
size_t)-1) dig[4] = dig[0];
1614 if (dig[3] == dig[2] && dig[2] == dig[1] && dig[1] == dig[0] && dig[0] != dig[4]) {
1618 if (dig[0] <= dig[1]) {
1623 dig[1] == 1 && (dig[0] == 5 || dig[0] == 10) ||
1624 dig[1] == 10 && (dig[0] == 50 || dig[0] == 100) ||
1625 dig[1] == 100 && (dig[0] == 500 || dig[0] == 1000) ||
1626 dig[1] == 1000 && (dig[0] == 5000 || dig[0] == 10000))
1629 if (dig[2] < dig[0]) {
1653 std::shared_ptr<basic_parser<T>>
1685 _In_
const std::locale& locale = std::locale()) :
1687 numerator(_numerator),
1688 fraction_line(_fraction_line),
1689 denominator(_denominator)
1693 _In_reads_or_z_(end)
const T* text,
1694 _In_
size_t start = 0,
1695 _In_
size_t end = (
size_t)-1,
1696 _In_
int flags = match_default)
1698 assert(text || start >= end);
1699 if (numerator->match(text, start, end, flags) &&
1700 fraction_line->match(text, numerator->interval.end, end, flags) &&
1701 denominator->match(text, fraction_line->interval.end, end, flags))
1707 numerator->invalidate();
1708 fraction_line->invalidate();
1709 denominator->invalidate();
1714 virtual void invalidate()
1716 numerator->invalidate();
1717 fraction_line->invalidate();
1718 denominator->invalidate();
1723 std::shared_ptr<basic_parser<T>> numerator;
1724 std::shared_ptr<basic_parser<T>> fraction_line;
1725 std::shared_ptr<basic_parser<T>> denominator;
1749 _In_
const std::locale& locale = std::locale()) :
1752 separator(_separator),
1758 _In_reads_or_z_(end)
const T* text,
1759 _In_
size_t start = 0,
1760 _In_
size_t end = (
size_t)-1,
1761 _In_
int flags = match_default)
1763 assert(text || start >= end);
1771 const int space_match_flags = flags & ~match_multiline;
1772 for (; m_space->match(text,
interval.
end, end, space_match_flags);
interval.
end = m_space->interval.end);
1774 if (separator->match(text,
interval.
end, end, flags))
1779 for (; m_space->match(text,
interval.
end, end, space_match_flags);
interval.
end = m_space->interval.end);
1791 separator->invalidate();
1792 guest->invalidate();
1797 virtual void invalidate()
1800 separator->invalidate();
1801 guest->invalidate();
1806 std::shared_ptr<basic_parser<T>> home;
1807 std::shared_ptr<basic_parser<T>> separator;
1808 std::shared_ptr<basic_parser<T>> guest;
1811 std::shared_ptr<basic_parser<T>> m_space;
1835 _In_
const std::locale& locale = std::locale()) :
1844 _In_reads_or_z_(end)
const T* text,
1845 _In_
size_t start = 0,
1846 _In_
size_t end = (
size_t)-1,
1847 _In_
int flags = match_default)
1849 assert(text || start >= end);
1884 virtual void invalidate()
1923 _In_
const std::locale& locale = std::locale()) :
1934 _In_reads_or_z_(end)
const T* text,
1935 _In_
size_t start = 0,
1936 _In_
size_t end = (
size_t)-1,
1937 _In_
int flags = match_default)
1939 assert(text || start >= end);
1964 const int space_match_flags = flags & ~match_multiline;
1966 m_space->match(text,
integer->interval.end, end, space_match_flags))
2005 virtual void invalidate()
2023 std::shared_ptr<basic_parser<T>> m_space;
2053 _In_
const std::locale& locale = std::locale()) :
2065 value(std::numeric_limits<double>::quiet_NaN())
2069 _In_reads_or_z_(end)
const T* text,
2070 _In_
size_t start = 0,
2071 _In_
size_t end = (
size_t)-1,
2072 _In_
int flags = match_default)
2074 assert(text || start >= end);
2109 if (!
integer->interval.empty() &&
2155 double e = (double)
exponent->value;
2158 value *= pow(10.0, e);
2165 virtual void invalidate()
2177 value = std::numeric_limits<double>::quiet_NaN();
2219 _In_
const std::locale& locale = std::locale()) :
2231 _In_reads_or_z_(end)
const T* text,
2232 _In_
size_t start = 0,
2233 _In_
size_t end = (
size_t)-1,
2234 _In_
int flags = match_default)
2236 assert(text || start >= end);
2283 if (
integer->interval.empty() &&
2302 virtual void invalidate()
2352 _In_
const std::locale& locale = std::locale()) :
2364 m_separator(separator)
2370 _In_reads_or_z_(end)
const T* text,
2371 _In_
size_t start = 0,
2372 _In_
size_t end = (
size_t)-1,
2373 _In_
int flags = match_default)
2375 assert(text || start >= end);
2380 for (i = 0; i < 4; i++) {
2382 if (m_separator->match(text,
interval.
end, end, flags))
2389 bool is_empty =
true;
2392 size_t dig, digit_end;
2393 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
2394 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
2395 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
2396 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
2397 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
2398 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
2399 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
2400 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
2401 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
2402 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
2404 size_t x_n = x * 10 + dig;
2416 value.s_addr = (
value.s_addr << 8) | (uint8_t)x;
2438 virtual void invalidate()
2457 std::shared_ptr<basic_parser<T>>
2468 std::shared_ptr<basic_parser<T>> m_separator;
2490 _In_reads_or_z_(end)
const T* text,
2491 _In_
size_t start = 0,
2492 _In_
size_t end = (
size_t)-1,
2493 _In_
int flags = match_default)
2495 assert(text || start >= end);
2496 if (start < end && text[start]) {
2497 if (text[start] ==
'-' ||
2498 text[start] ==
'_' ||
2499 text[start] ==
':' ||
2500 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
2528 _In_reads_or_z_(end)
const char* text,
2529 _In_
size_t start = 0,
2530 _In_
size_t end = (
size_t)-1,
2531 _In_
int flags = match_default)
2533 assert(text || start >= end);
2534 if (start < end && text[start]) {
2536 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
2537 const wchar_t* chr_end = chr + stdex::strlen(chr);
2538 if ((chr[0] == L
'-' ||
2540 chr[0] == L
':') && chr[1] == 0 ||
2541 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
2577 _In_
const std::shared_ptr<
basic_parser<T>>& scope_id_separator =
nullptr,
2579 _In_
const std::locale& locale = std::locale()) :
2591 m_digit_10(digit_10),
2592 m_digit_11(digit_11),
2593 m_digit_12(digit_12),
2594 m_digit_13(digit_13),
2595 m_digit_14(digit_14),
2596 m_digit_15(digit_15),
2597 m_separator(separator),
2598 m_scope_id_separator(scope_id_separator),
2605 _In_reads_or_z_(end)
const T* text,
2606 _In_
size_t start = 0,
2607 _In_
size_t end = (
size_t)-1,
2608 _In_
int flags = match_default)
2610 assert(text || start >= end);
2614 size_t i, compaction_i = (size_t)-1, compaction_start = start;
2615 for (i = 0; i < 8; i++) {
2616 bool is_empty =
true;
2618 if (m_separator->match(text,
interval.
end, end, flags)) {
2619 if (m_separator->match(text, m_separator->interval.end, end, flags)) {
2621 if (compaction_i == (
size_t)-1) {
2624 compaction_start = m_separator->interval.start;
2649 size_t dig, digit_end;
2650 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
2651 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
2652 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
2653 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
2654 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
2655 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
2656 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
2657 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
2658 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
2659 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
2660 else if (m_digit_10->match(text,
interval.
end, end, flags)) { dig = 10; digit_end = m_digit_10->interval.end; }
2661 else if (m_digit_11->match(text,
interval.
end, end, flags)) { dig = 11; digit_end = m_digit_11->interval.end; }
2662 else if (m_digit_12->match(text,
interval.
end, end, flags)) { dig = 12; digit_end = m_digit_12->interval.end; }
2663 else if (m_digit_13->match(text,
interval.
end, end, flags)) { dig = 13; digit_end = m_digit_13->interval.end; }
2664 else if (m_digit_14->match(text,
interval.
end, end, flags)) { dig = 14; digit_end = m_digit_14->interval.end; }
2665 else if (m_digit_15->match(text,
interval.
end, end, flags)) { dig = 15; digit_end = m_digit_15->interval.end; }
2667 size_t x_n = x * 16 + dig;
2668 if (x_n <= 0xffff) {
2677 if (compaction_i != (
size_t)-1) {
2684 value.s6_words[i] = (uint16_t)x;
2687 if (compaction_i != (
size_t)-1) {
2690 for (j = 8, k = i; k > compaction_i;) {
2694 for (; j > compaction_i;) {
2695 value.s6_words[--j] = 0;
2703 if (m_scope_id_separator && m_scope_id_separator->match(text,
interval.
end, end, flags) &&
2704 scope_id &&
scope_id->match(text, m_scope_id_separator->interval.end, end, flags))
2735 virtual void invalidate()
2764 std::shared_ptr<basic_parser<T>>
2781 std::shared_ptr<basic_parser<T>> m_separator, m_scope_id_separator;
2801 _In_
bool allow_idn,
2802 _In_
const std::locale& locale = std::locale()) :
2804 m_allow_idn(allow_idn),
2809 _In_reads_or_z_(end)
const T* text,
2810 _In_
size_t start = 0,
2811 _In_
size_t end = (
size_t)-1,
2812 _In_
int flags = match_default)
2814 assert(text || start >= end);
2815 if (start < end && text[start]) {
2816 if ((
'A' <= text[start] && text[start] <=
'Z') ||
2817 (
'a' <= text[start] && text[start] <=
'z') ||
2818 (
'0' <= text[start] && text[start] <=
'9'))
2820 else if (text[start] ==
'-')
2822 else if (m_allow_idn && std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
2857 _In_
bool allow_idn,
2858 _In_
const std::locale& locale = std::locale()) :
2863 _In_reads_or_z_(end)
const char* text,
2864 _In_
size_t start = 0,
2865 _In_
size_t end = (
size_t)-1,
2866 _In_
int flags = match_default)
2868 assert(text || start >= end);
2869 if (start < end && text[start]) {
2871 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
2872 const wchar_t* chr_end = chr + stdex::strlen(chr);
2873 if (((
'A' <= chr[0] && chr[0] <=
'Z') ||
2874 (
'a' <= chr[0] && chr[0] <=
'z') ||
2875 (
'0' <= chr[0] && chr[0] <=
'9')) && chr[1] == 0)
2877 else if (chr[0] ==
'-' && chr[1] == 0)
2879 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)
2901 _In_
bool allow_absolute,
2904 _In_
const std::locale& locale = std::locale()) :
2907 m_domain_char(domain_char),
2908 m_separator(separator)
2912 _In_reads_or_z_(end)
const T* text,
2913 _In_
size_t start = 0,
2914 _In_
size_t end = (
size_t)-1,
2915 _In_
int flags = match_default)
2917 assert(text || start >= end);
2918 size_t i = start, count;
2919 for (count = 0; i < end && text[i] && count < 127; count++) {
2920 if (m_domain_char->match(text, i, end, flags) &&
2921 m_domain_char->allow_on_edge)
2925 while (i < end && text[i]) {
2926 if (m_domain_char->allow_on_edge &&
2927 m_separator->match(text, i, end, flags))
2934 i = m_separator->interval.end;
2938 if (m_domain_char->match(text, i, end, flags)) {
2939 if (m_domain_char->allow_on_edge)
2942 i = m_domain_char->interval.end;
2963 std::shared_ptr<basic_dns_domain_char<T>> m_domain_char;
2964 std::shared_ptr<basic_parser<T>> m_separator;
2986 _In_reads_or_z_(end)
const T* text,
2987 _In_
size_t start = 0,
2988 _In_
size_t end = (
size_t)-1,
2989 _In_
int flags = match_default)
2991 assert(text || start >= end);
2992 if (start < end && text[start]) {
2993 if (text[start] ==
'-' ||
2994 text[start] ==
'.' ||
2995 text[start] ==
'_' ||
2996 text[start] ==
'~' ||
2997 text[start] ==
'%' ||
2998 text[start] ==
'!' ||
2999 text[start] ==
'$' ||
3000 text[start] ==
'&' ||
3001 text[start] ==
'\'' ||
3004 text[start] ==
'*' ||
3005 text[start] ==
'+' ||
3006 text[start] ==
',' ||
3007 text[start] ==
';' ||
3008 text[start] ==
'=' ||
3009 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
3037 _In_reads_or_z_(end)
const char* text,
3038 _In_
size_t start = 0,
3039 _In_
size_t end = (
size_t)-1,
3040 _In_
int flags = match_default)
3042 assert(text || start >= end);
3043 if (start < end && text[start]) {
3045 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
3046 const wchar_t* chr_end = chr + stdex::strlen(chr);
3047 if ((chr[0] == L
'-' ||
3062 chr[0] == L
'=') && chr[1] == 0 ||
3063 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3085 _In_reads_or_z_(end)
const T* text,
3086 _In_
size_t start = 0,
3087 _In_
size_t end = (
size_t)-1,
3088 _In_
int flags = match_default)
3090 assert(text || start >= end);
3091 if (start < end && text[start]) {
3092 if (text[start] ==
'-' ||
3093 text[start] ==
'.' ||
3094 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 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
3137 _In_reads_or_z_(end)
const char* text,
3138 _In_
size_t start = 0,
3139 _In_
size_t end = (
size_t)-1,
3140 _In_
int flags = match_default)
3142 assert(text || start >= end);
3143 if (start < end && text[start]) {
3145 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
3146 const wchar_t* chr_end = chr + stdex::strlen(chr);
3147 if ((chr[0] == L
'-' ||
3163 chr[0] == L
':') && chr[1] == 0 ||
3164 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3185 _In_reads_or_z_(end)
const T* text,
3186 _In_
size_t start = 0,
3187 _In_
size_t end = (
size_t)-1,
3188 _In_
int flags = match_default)
3190 assert(text || start >= end);
3191 if (start < end && text[start]) {
3192 if (text[start] ==
'/' ||
3193 text[start] ==
'-' ||
3194 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 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
3241 _In_reads_or_z_(end)
const char* text,
3242 _In_
size_t start = 0,
3243 _In_
size_t end = (
size_t)-1,
3244 _In_
int flags = match_default)
3246 assert(text || start >= end);
3247 if (start < end && text[start]) {
3249 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
3250 const wchar_t* chr_end = chr + stdex::strlen(chr);
3251 if ((chr[0] == L
'/' ||
3271 chr[0] == L
'#') && chr[1] == 0 ||
3272 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3294 _In_
const std::locale& locale = std::locale()) :
3296 m_path_char(path_char),
3297 m_query_start(query_start),
3298 m_bookmark_start(bookmark_start)
3302 _In_reads_or_z_(end)
const T* text,
3303 _In_
size_t start = 0,
3304 _In_
size_t end = (
size_t)-1,
3305 _In_
int flags = match_default)
3307 assert(text || start >= end);
3319 if (m_query_start->match(text,
interval.
end, end, flags)) {
3327 if (m_bookmark_start->match(text,
interval.
end, end, flags)) {
3335 if (m_path_char->match(text,
interval.
end, end, flags))
3345 if (m_path_char->match(text,
interval.
end, end, flags))
3355 if (m_bookmark_start->match(text,
interval.
end, end, flags)) {
3363 if (m_path_char->match(text,
interval.
end, end, flags))
3373 if (m_path_char->match(text,
interval.
end, end, flags))
3393 virtual void invalidate()
3410 std::shared_ptr<basic_parser<T>> m_path_char;
3411 std::shared_ptr<basic_parser<T>> m_query_start;
3412 std::shared_ptr<basic_parser<T>> m_bookmark_start;
3448 _In_
const std::locale& locale = std::locale()) :
3450 http_scheme(_http_scheme),
3451 ftp_scheme(_ftp_scheme),
3452 mailto_scheme(_mailto_scheme),
3453 file_scheme(_file_scheme),
3456 username(_username),
3457 password(_password),
3459 m_ip_lbracket(ip_lbracket),
3460 m_ip_rbracket(ip_rbracket),
3461 ipv4_host(_ipv4_host),
3462 ipv6_host(_ipv6_host),
3463 dns_host(_dns_host),
3469 _In_reads_or_z_(end)
const T* text,
3470 _In_
size_t start = 0,
3471 _In_
size_t end = (
size_t)-1,
3472 _In_
int flags = match_default)
3474 assert(text || start >= end);
3478 if (http_scheme->match(text,
interval.
end, end, flags) &&
3479 m_colon->match(text, http_scheme->interval.end, end, flags) &&
3480 m_slash->match(text, m_colon->interval.end, end, flags) &&
3481 m_slash->match(text, m_slash->interval.end, end, flags))
3485 ftp_scheme->invalidate();
3486 mailto_scheme->invalidate();
3487 file_scheme->invalidate();
3489 else if (ftp_scheme->match(text,
interval.
end, end, flags) &&
3490 m_colon->match(text, ftp_scheme->interval.end, end, flags) &&
3491 m_slash->match(text, m_colon->interval.end, end, flags) &&
3492 m_slash->match(text, m_slash->interval.end, end, flags))
3496 http_scheme->invalidate();
3497 mailto_scheme->invalidate();
3498 file_scheme->invalidate();
3500 else if (mailto_scheme->match(text,
interval.
end, end, flags) &&
3501 m_colon->match(text, mailto_scheme->interval.end, end, flags))
3505 http_scheme->invalidate();
3506 ftp_scheme->invalidate();
3507 file_scheme->invalidate();
3509 else if (file_scheme->match(text,
interval.
end, end, flags) &&
3510 m_colon->match(text, file_scheme->interval.end, end, flags) &&
3511 m_slash->match(text, m_colon->interval.end, end, flags) &&
3512 m_slash->match(text, m_slash->interval.end, end, flags))
3516 http_scheme->invalidate();
3517 ftp_scheme->invalidate();
3518 mailto_scheme->invalidate();
3522 http_scheme->invalidate();
3523 ftp_scheme->invalidate();
3524 mailto_scheme->invalidate();
3525 file_scheme->invalidate();
3528 if (ftp_scheme->interval) {
3529 if (username->match(text,
interval.
end, end, flags)) {
3530 if (m_colon->match(text, username->interval.end, end, flags) &&
3531 password->match(text, m_colon->interval.end, end, flags) &&
3532 m_at->match(text, password->interval.end, end, flags))
3537 else if (m_at->match(text,
interval.
end, end, flags)) {
3540 password->invalidate();
3543 username->invalidate();
3544 password->invalidate();
3548 username->invalidate();
3549 password->invalidate();
3552 if (ipv4_host->match(text,
interval.
end, end, flags)) {
3555 ipv6_host->invalidate();
3556 dns_host->invalidate();
3559 m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3560 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3561 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3565 ipv4_host->invalidate();
3566 dns_host->invalidate();
3568 else if (dns_host->match(text,
interval.
end, end, flags)) {
3571 ipv4_host->invalidate();
3572 ipv6_host->invalidate();
3579 if (m_colon->match(text,
interval.
end, end, flags) &&
3580 port->match(text, m_colon->interval.end, end, flags))
3588 if (path->match(text,
interval.
end, end, flags)) {
3597 if (mailto_scheme->interval) {
3598 if (username->match(text,
interval.
end, end, flags) &&
3599 m_at->match(text, username->interval.end, end, flags))
3609 if (m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3610 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3611 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
3615 ipv6_host->invalidate();
3616 dns_host->invalidate();
3619 m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3620 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3621 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3625 ipv4_host->invalidate();
3626 dns_host->invalidate();
3628 else if (dns_host->match(text,
interval.
end, end, flags)) {
3631 ipv4_host->invalidate();
3632 ipv6_host->invalidate();
3639 password->invalidate();
3646 if (file_scheme->interval) {
3647 if (path->match(text,
interval.
end, end, flags)) {
3652 username->invalidate();
3653 password->invalidate();
3654 ipv4_host->invalidate();
3655 ipv6_host->invalidate();
3656 dns_host->invalidate();
3665 if (http_scheme->interval &&
3668 if (m_colon->match(text, username->interval.end, end, flags) &&
3669 password->match(text, m_colon->interval.end, end, flags) &&
3670 m_at->match(text, password->interval.end, end, flags))
3675 else if (m_at->match(text, username->interval.end, end, flags)) {
3678 password->invalidate();
3681 username->invalidate();
3682 password->invalidate();
3686 username->invalidate();
3687 password->invalidate();
3690 if (ipv4_host->match(text,
interval.
end, end, flags)) {
3693 ipv6_host->invalidate();
3694 dns_host->invalidate();
3697 m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3698 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3699 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3703 ipv4_host->invalidate();
3704 dns_host->invalidate();
3706 else if (dns_host->match(text,
interval.
end, end, flags)) {
3709 ipv4_host->invalidate();
3710 ipv6_host->invalidate();
3717 if (m_colon->match(text,
interval.
end, end, flags) &&
3718 port->match(text, m_colon->interval.end, end, flags))
3726 if (path->match(text,
interval.
end, end, flags)) {
3735 virtual void invalidate()
3737 http_scheme->invalidate();
3738 ftp_scheme->invalidate();
3739 mailto_scheme->invalidate();
3740 file_scheme->invalidate();
3741 username->invalidate();
3742 password->invalidate();
3743 ipv4_host->invalidate();
3744 ipv6_host->invalidate();
3745 dns_host->invalidate();
3752 std::shared_ptr<basic_parser<T>> http_scheme;
3753 std::shared_ptr<basic_parser<T>> ftp_scheme;
3754 std::shared_ptr<basic_parser<T>> mailto_scheme;
3755 std::shared_ptr<basic_parser<T>> file_scheme;
3756 std::shared_ptr<basic_parser<T>> username;
3757 std::shared_ptr<basic_parser<T>> password;
3758 std::shared_ptr<basic_parser<T>> ipv4_host;
3759 std::shared_ptr<basic_parser<T>> ipv6_host;
3760 std::shared_ptr<basic_parser<T>> dns_host;
3761 std::shared_ptr<basic_parser<T>> port;
3762 std::shared_ptr<basic_parser<T>> path;
3765 std::shared_ptr<basic_parser<T>> m_colon;
3766 std::shared_ptr<basic_parser<T>> m_slash;
3767 std::shared_ptr<basic_parser<T>> m_at;
3768 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
3769 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
3796 _In_
const std::locale& locale = std::locale()) :
3798 username(_username),
3800 m_ip_lbracket(ip_lbracket),
3801 m_ip_rbracket(ip_rbracket),
3802 ipv4_host(_ipv4_host),
3803 ipv6_host(_ipv6_host),
3808 _In_reads_or_z_(end)
const T* text,
3809 _In_
size_t start = 0,
3810 _In_
size_t end = (
size_t)-1,
3811 _In_
int flags = match_default)
3813 assert(text || start >= end);
3815 if (username->match(text, start, end, flags) &&
3816 m_at->match(text, username->interval.end, end, flags))
3819 if (m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
3820 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3821 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
3825 ipv6_host->invalidate();
3826 dns_host->invalidate();
3829 m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
3830 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3831 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3835 ipv4_host->invalidate();
3836 dns_host->invalidate();
3838 else if (dns_host->match(text, m_at->interval.end, end, flags)) {
3841 ipv4_host->invalidate();
3842 ipv6_host->invalidate();
3851 username->invalidate();
3852 ipv4_host->invalidate();
3853 ipv6_host->invalidate();
3854 dns_host->invalidate();
3859 virtual void invalidate()
3861 username->invalidate();
3862 ipv4_host->invalidate();
3863 ipv6_host->invalidate();
3864 dns_host->invalidate();
3869 std::shared_ptr<basic_parser<T>> username;
3870 std::shared_ptr<basic_parser<T>> ipv4_host;
3871 std::shared_ptr<basic_parser<T>> ipv6_host;
3872 std::shared_ptr<basic_parser<T>> dns_host;
3875 std::shared_ptr<basic_parser<T>> m_at;
3876 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
3877 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
3902 _In_
const std::locale& locale = std::locale()) :
3912 _In_reads_or_z_(end)
const T* text,
3913 _In_
size_t start = 0,
3914 _In_
size_t end = (
size_t)-1,
3915 _In_
int flags = match_default)
3917 assert(text || start >= end);
3923 mouth->invalidate();
3935 if (
nose &&
nose->match(text,
eyes->interval.end, end, flags) &&
3936 mouth->match(text,
nose->interval.end, end, flags))
3939 start_mouth =
mouth->interval.start,
3940 hit_offset =
mouth->hit_offset;
3943 mouth->interval.start = start_mouth;
3948 if (
mouth->match(text,
eyes->interval.end, end, flags)) {
3950 start_mouth =
mouth->interval.start,
3951 hit_offset =
mouth->hit_offset;
3955 mouth->interval.start = start_mouth;
3966 mouth->invalidate();
3971 virtual void invalidate()
3977 mouth->invalidate();
3983 std::shared_ptr<basic_parser<T>>
apex;
3984 std::shared_ptr<basic_parser<T>>
eyes;
3985 std::shared_ptr<basic_parser<T>>
nose;
4001 ENUM_FLAGS(date_format_t,
int) {
4020 _In_
int format_mask,
4026 _In_
const std::locale& locale = std::locale()) :
4028 format(date_format_t::none),
4029 m_format_mask(format_mask),
4033 m_separator(separator),
4038 _In_reads_or_z_(end)
const T* text,
4039 _In_
size_t start = 0,
4040 _In_
size_t end = (
size_t)-1,
4041 _In_
int flags = match_default)
4043 assert(text || start >= end);
4045 const int space_match_flags = flags & ~match_multiline;
4046 if ((m_format_mask & date_format_t::dmy) == date_format_t::dmy) {
4047 if (day->match(text, start, end, flags)) {
4049 if (m_separator->match(text,
interval.
end, end, flags)) {
4050 size_t hit_offset = m_separator->hit_offset;
4052 if (month->match(text,
interval.
end, end, flags)) {
4054 if (m_separator->match(text,
interval.
end, end, flags) &&
4055 m_separator->hit_offset == hit_offset)
4058 if (year->match(text,
interval.
end, end, flags) &&
4059 is_valid(day->value, month->value))
4063 format = date_format_t::dmy;
4072 if ((m_format_mask & date_format_t::mdy) == date_format_t::mdy) {
4073 if (month->match(text, start, end, flags)) {
4075 if (m_separator->match(text,
interval.
end, end, flags)) {
4076 size_t hit_offset = m_separator->hit_offset;
4080 if (m_separator->match(text,
interval.
end, end, flags) &&
4081 m_separator->hit_offset == hit_offset)
4084 if (year->match(text,
interval.
end, end, flags) &&
4085 is_valid(day->value, month->value))
4089 format = date_format_t::mdy;
4098 if ((m_format_mask & date_format_t::ymd) == date_format_t::ymd) {
4099 if (year->match(text, start, end, flags)) {
4101 if (m_separator->match(text,
interval.
end, end, flags)) {
4102 size_t hit_offset = m_separator->hit_offset;
4104 if (month->match(text,
interval.
end, end, flags)) {
4106 if (m_separator->match(text,
interval.
end, end, flags) &&
4107 m_separator->hit_offset == hit_offset)
4111 is_valid(day->value, month->value))
4115 format = date_format_t::ymd;
4124 if ((m_format_mask & date_format_t::ym) == date_format_t::ym) {
4125 if (year->match(text, start, end, flags)) {
4127 if (m_separator->match(text,
interval.
end, end, flags)) {
4129 if (month->match(text,
interval.
end, end, flags) &&
4130 is_valid((
size_t)-1, month->value))
4132 if (day) day->invalidate();
4135 format = date_format_t::ym;
4142 if ((m_format_mask & date_format_t::my) == date_format_t::my) {
4143 if (month->match(text, start, end, flags)) {
4145 if (m_separator->match(text,
interval.
end, end, flags)) {
4147 if (year->match(text,
interval.
end, end, flags) &&
4148 is_valid((
size_t)-1, month->value))
4150 if (day) day->invalidate();
4153 format = date_format_t::my;
4160 if ((m_format_mask & date_format_t::dm) == date_format_t::dm) {
4161 if (day->match(text, start, end, flags)) {
4163 if (m_separator->match(text,
interval.
end, end, flags)) {
4164 size_t hit_offset = m_separator->hit_offset;
4166 if (month->match(text,
interval.
end, end, flags) &&
4167 is_valid(day->value, month->value))
4169 if (year) year->invalidate();
4172 if (m_separator->match(text,
interval.
end, end, flags) &&
4173 m_separator->hit_offset == hit_offset)
4177 format = date_format_t::dm;
4184 if ((m_format_mask & date_format_t::md) == date_format_t::md) {
4185 if (month->match(text, start, end, flags)) {
4187 if (m_separator->match(text,
interval.
end, end, flags)) {
4188 size_t hit_offset = m_separator->hit_offset;
4191 is_valid(day->value, month->value))
4193 if (year) year->invalidate();
4196 if (m_separator->match(text,
interval.
end, end, flags) &&
4197 m_separator->hit_offset == hit_offset)
4201 format = date_format_t::md;
4208 if (day) day->invalidate();
4209 if (month) month->invalidate();
4210 if (year) year->invalidate();
4211 format = date_format_t::none;
4216 virtual void invalidate()
4218 if (day) day->invalidate();
4219 if (month) month->invalidate();
4220 if (year) year->invalidate();
4221 format = date_format_t::none;
4226 static inline bool is_valid(
size_t day,
size_t month)
4228 if (month == (
size_t)-1) {
4232 if (day == (
size_t)-1) {
4245 return 1 <= day && day <= 31;
4247 return 1 <= day && day <= 29;
4252 return 1 <= day && day <= 30;
4259 date_format_t format;
4260 std::shared_ptr<basic_integer<T>> day;
4261 std::shared_ptr<basic_integer<T>> month;
4262 std::shared_ptr<basic_integer<T>> year;
4266 std::shared_ptr<basic_set<T>> m_separator;
4267 std::shared_ptr<basic_parser<T>> m_space;
4293 _In_
const std::locale& locale = std::locale()) :
4298 millisecond(_millisecond),
4299 m_separator(separator),
4300 m_millisecond_separator(millisecond_separator)
4304 _In_reads_or_z_(end)
const T* text,
4305 _In_
size_t start = 0,
4306 _In_
size_t end = (
size_t)-1,
4307 _In_
int flags = match_default)
4309 assert(text || start >= end);
4311 if (hour->match(text, start, end, flags) &&
4312 m_separator->match(text, hour->interval.end, end, flags) &&
4313 minute->match(text, m_separator->interval.end, end, flags) &&
4317 size_t hit_offset = m_separator->hit_offset;
4318 if (m_separator->match(text, minute->interval.end, end, flags) &&
4319 m_separator->hit_offset == hit_offset &&
4320 second && second->match(text, m_separator->interval.end, end, flags) &&
4324 if (m_millisecond_separator && m_millisecond_separator->match(text, second->interval.end, end, flags) &&
4325 millisecond && millisecond->match(text, m_millisecond_separator->interval.end, end, flags) &&
4326 millisecond->value < 1000)
4332 if (millisecond) millisecond->invalidate();
4337 if (second) second->invalidate();
4338 if (millisecond) millisecond->invalidate();
4346 minute->invalidate();
4347 if (second) second->invalidate();
4348 if (millisecond) millisecond->invalidate();
4353 virtual void invalidate()
4356 minute->invalidate();
4357 if (second) second->invalidate();
4358 if (millisecond) millisecond->invalidate();
4363 std::shared_ptr<basic_integer10<T>> hour;
4364 std::shared_ptr<basic_integer10<T>> minute;
4365 std::shared_ptr<basic_integer10<T>> second;
4366 std::shared_ptr<basic_integer10<T>> millisecond;
4369 std::shared_ptr<basic_set<T>> m_separator;
4370 std::shared_ptr<basic_parser<T>> m_millisecond_separator;
4397 _In_
const std::locale& locale = std::locale()) :
4400 degree_separator(_degree_separator),
4402 minute_separator(_minute_separator),
4404 second_separator(_second_separator),
4409 _In_reads_or_z_(end)
const T* text,
4410 _In_
size_t start = 0,
4411 _In_
size_t end = (
size_t)-1,
4412 _In_
int flags = match_default)
4414 assert(text || start >= end);
4418 if (degree->match(text,
interval.
end, end, flags) &&
4419 degree_separator->match(text, degree->interval.end, end, flags))
4425 degree->invalidate();
4426 degree_separator->invalidate();
4429 if (minute->match(text,
interval.
end, end, flags) &&
4430 minute->value < 60 &&
4431 minute_separator->match(text, minute->interval.end, end, flags))
4437 minute->invalidate();
4438 minute_separator->invalidate();
4441 if (second && second->match(text,
interval.
end, end, flags) &&
4446 if (second_separator && second_separator->match(text,
interval.
end, end, flags))
4449 if (second_separator) second_separator->invalidate();
4452 if (second) second->invalidate();
4453 if (second_separator) second_separator->invalidate();
4456 if (degree->interval.start < degree->interval.end ||
4457 minute->interval.start < minute->interval.end ||
4458 second && second->interval.start < second->interval.end)
4460 if (decimal && decimal->match(text,
interval.
end, end, flags)) {
4465 decimal->invalidate();
4469 if (decimal) decimal->invalidate();
4474 virtual void invalidate()
4476 degree->invalidate();
4477 degree_separator->invalidate();
4478 minute->invalidate();
4479 minute_separator->invalidate();
4480 if (second) second->invalidate();
4481 if (second_separator) second_separator->invalidate();
4482 if (decimal) decimal->invalidate();
4487 std::shared_ptr<basic_integer10<T>> degree;
4488 std::shared_ptr<basic_parser<T>> degree_separator;
4489 std::shared_ptr<basic_integer10<T>> minute;
4490 std::shared_ptr<basic_parser<T>> minute_separator;
4491 std::shared_ptr<basic_integer10<T>> second;
4492 std::shared_ptr<basic_parser<T>> second_separator;
4493 std::shared_ptr<basic_parser<T>> decimal;
4515 _In_
const std::shared_ptr<
basic_set<T>>& lparenthesis,
4516 _In_
const std::shared_ptr<
basic_set<T>>& rparenthesis,
4519 _In_
const std::locale& locale = std::locale()) :
4522 m_plus_sign(plus_sign),
4523 m_lparenthesis(lparenthesis),
4524 m_rparenthesis(rparenthesis),
4525 m_separator(separator),
4530 _In_reads_or_z_(end)
const T* text,
4531 _In_
size_t start = 0,
4532 _In_
size_t end = (
size_t)-1,
4533 _In_
int flags = match_default)
4535 assert(text || start >= end);
4537 size_t safe_digit_end = start, safe_value_size = 0;
4538 bool has_digits =
false, after_digit =
false, in_parentheses =
false, after_parentheses =
false;
4539 const int space_match_flags = flags & ~match_multiline;
4543 m_lparenthesis->invalidate();
4544 m_rparenthesis->invalidate();
4546 if (m_plus_sign && m_plus_sign->match(text,
interval.
end, end, flags)) {
4547 value.append(text + m_plus_sign->interval.start, text + m_plus_sign->interval.end);
4548 safe_value_size =
value.size();
4556 if (m_digit->match(text,
interval.
end, end, flags)) {
4558 value.append(text + m_digit->interval.start, text + m_digit->interval.end);
4560 if (!in_parentheses) {
4562 safe_value_size =
value.size();
4566 after_parentheses =
false;
4569 m_lparenthesis && !m_lparenthesis->interval &&
4570 m_rparenthesis && !m_rparenthesis->interval &&
4571 m_lparenthesis->match(text,
interval.
end, end, flags))
4574 value.append(text + m_lparenthesis->interval.start, m_lparenthesis->interval.size());
4576 in_parentheses =
true;
4577 after_digit =
false;
4578 after_parentheses =
false;
4582 m_rparenthesis && !m_rparenthesis->interval &&
4583 m_rparenthesis->match(text,
interval.
end, end, flags) &&
4584 m_lparenthesis->hit_offset == m_rparenthesis->hit_offset)
4587 value.append(text + m_rparenthesis->interval.start, text + m_rparenthesis->interval.end);
4590 safe_value_size =
value.size();
4591 in_parentheses =
false;
4592 after_digit =
false;
4593 after_parentheses =
true;
4598 !after_parentheses &&
4599 m_separator && m_separator->match(text,
interval.
end, end, flags))
4603 after_digit =
false;
4604 after_parentheses =
false;
4607 (after_digit || after_parentheses) &&
4608 m_space && m_space->match(text,
interval.
end, end, space_match_flags))
4612 after_digit =
false;
4613 after_parentheses =
false;
4619 value.erase(safe_value_size);
4629 virtual void invalidate()
4639 std::shared_ptr<basic_parser<T>> m_digit;
4640 std::shared_ptr<basic_parser<T>> m_plus_sign;
4641 std::shared_ptr<basic_set<T>> m_lparenthesis;
4642 std::shared_ptr<basic_set<T>> m_rparenthesis;
4643 std::shared_ptr<basic_parser<T>> m_separator;
4644 std::shared_ptr<basic_parser<T>> m_space;
4667 _In_
const std::locale& locale = std::locale()) :
4677 _In_reads_or_z_(end)
const T* text,
4678 _In_
size_t start = 0,
4679 _In_
size_t end = (
size_t)-1,
4680 _In_
int flags = match_default)
4682 assert(text || start >= end);
4688 const int element_match_flags = flags & ~match_case_insensitive;
4690 if (m_element->match(text,
interval.
end, end, element_match_flags)) {
4692 while (m_digit->match(text,
interval.
end, end, flags)) {
4698 if (m_sign->match(text,
interval.
end, end, flags)) {
4712 virtual void invalidate()
4724 std::shared_ptr<basic_parser<T>> m_element;
4725 std::shared_ptr<basic_parser<T>> m_digit;
4726 std::shared_ptr<basic_parser<T>> m_sign;
4745 _In_reads_or_z_(end)
const char* text,
4746 _In_
size_t start = 0,
4747 _In_
size_t end = (
size_t)-1,
4748 _In_
int flags = match_default)
4750 assert(text || start >= end);
4781 _In_reads_or_z_(end)
const char* text,
4782 _In_
size_t start = 0,
4783 _In_
size_t end = (
size_t)-1,
4784 _In_
int flags = match_default)
4786 assert(text || start >= end);
4788 if (m_line_break.match(text,
interval.
end, end, flags)) {
4818 _In_reads_or_z_(end)
const char* text,
4819 _In_
size_t start = 0,
4820 _In_
size_t end = (
size_t)-1,
4821 _In_
int flags = match_default)
4823 assert(text || start >= end);
4827 if (m_space.match(text,
interval.
end, end, flags)) {
4852 _In_reads_or_z_(end)
const char* text,
4853 _In_
size_t start = 0,
4854 _In_
size_t end = (
size_t)-1,
4855 _In_
int flags = match_default)
4857 assert(text || start >= end);
4906 _In_reads_or_z_(end)
const char* text,
4907 _In_
size_t start = 0,
4908 _In_
size_t end = (
size_t)-1,
4909 _In_
int flags = match_default)
4911 assert(text || start >= end);
4933 else if (m_chr.match(text,
interval.
end, end, flags))
4951 virtual void invalidate()
4955 parser::invalidate();
4972 _In_reads_or_z_(end)
const char* text,
4973 _In_
size_t start = 0,
4974 _In_
size_t end = (
size_t)-1,
4975 _In_
int flags = match_default)
4977 assert(text || start >= end);
4979 if (
string.match(text,
interval.
end, end, flags)) {
4986 string.invalidate();
4997 virtual void invalidate()
4999 string.invalidate();
5001 parser::invalidate();
5016 _In_reads_or_z_(end)
const char* text,
5017 _In_
size_t start = 0,
5018 _In_
size_t end = (
size_t)-1,
5019 _In_
int flags = match_default)
5021 assert(text || start >= end);
5027 while (m_space.match(text,
interval.
end, end, flags))
5033 while (m_space.match(text,
interval.
end, end, flags))
5049 virtual void invalidate()
5053 parser::invalidate();
5071 _In_reads_or_z_(end)
const char* text,
5072 _In_
size_t start = 0,
5073 _In_
size_t end = (
size_t)-1,
5074 _In_
int flags = match_default)
5076 assert(text || start >= end);
5077 if (start + 2 < end &&
5078 text[start] ==
'*' &&
5079 text[start + 1] ==
'/' &&
5080 text[start + 2] ==
'*')
5085 else if (start < end && text[start] ==
'*') {
5103 _In_reads_or_z_(end)
const char* text,
5104 _In_
size_t start = 0,
5105 _In_
size_t end = (
size_t)-1,
5106 _In_
int flags = match_default)
5108 assert(text || start >= end);
5114 while (m_space.match(text,
interval.
end, end, flags))
5120 while (m_space.match(text,
interval.
end, end, flags))
5122 if (subtype.match(text,
interval.
end, end, flags))
5131 subtype.invalidate();
5136 virtual void invalidate()
5139 subtype.invalidate();
5140 parser::invalidate();
5158 _In_reads_or_z_(end)
const char* text,
5159 _In_
size_t start = 0,
5160 _In_
size_t end = (
size_t)-1,
5161 _In_
int flags = match_default)
5163 assert(text || start >= end);
5164 if (!http_media_range::match(text, start, end, flags))
5169 if (m_space.match(text,
interval.
end, end, flags))
5173 while (m_space.match(text,
interval.
end, end, flags))
5176 if (param.match(text,
interval.
end, end, flags)) {
5178 params.push_back(std::move(param));
5193 http_media_range::invalidate();
5199 virtual void invalidate()
5202 http_media_range::invalidate();
5206 std::list<http_parameter> params;
5216 _In_reads_or_z_(end)
const char* text,
5217 _In_
size_t start = 0,
5218 _In_
size_t end = (
size_t)-1,
5219 _In_
int flags = match_default)
5221 assert(text || start >= end);
5252 http_url_port(_In_
const std::locale& locale = std::locale()) :
5258 _In_reads_or_z_(end)
const char* text,
5259 _In_
size_t start = 0,
5260 _In_
size_t end = (
size_t)-1,
5261 _In_
int flags = match_default)
5263 assert(text || start >= end);
5269 size_t _value = (size_t)value * 10 + text[
interval.
end] -
'0';
5270 if (_value > (uint16_t)-1) {
5275 value = (uint16_t)_value;
5292 virtual void invalidate()
5295 parser::invalidate();
5309 _In_reads_or_z_(end)
const char* text,
5310 _In_
size_t start = 0,
5311 _In_
size_t end = (
size_t)-1,
5312 _In_
int flags = match_default)
5314 assert(text || start >= end);
5342 _In_reads_or_z_(end)
const char* text,
5343 _In_
size_t start = 0,
5344 _In_
size_t end = (
size_t)-1,
5345 _In_
int flags = match_default)
5347 assert(text || start >= end);
5381 virtual void invalidate()
5384 parser::invalidate();
5398 _In_reads_or_z_(end)
const char* text,
5399 _In_
size_t start = 0,
5400 _In_
size_t end = (
size_t)-1,
5401 _In_
int flags = match_default)
5403 assert(text || start >= end);
5458 virtual void invalidate()
5464 parser::invalidate();
5478 http_url(_In_
const std::locale& locale = std::locale()) :
5484 _In_reads_or_z_(end)
const char* text,
5485 _In_
size_t start = 0,
5486 _In_
size_t end = (
size_t)-1,
5487 _In_
int flags = match_default)
5489 assert(text || start >= end);
5492 if (
interval.
end + 7 <= end && stdex::strnicmp(text +
interval.
end, 7,
"http://", (
size_t)-1, m_locale) == 0) {
5509 server.invalidate();
5533 if (param.match(text,
interval.
end, end, flags)) {
5535 params.push_back(std::move(param));
5550 server.invalidate();
5558 virtual void invalidate()
5560 server.invalidate();
5564 parser::invalidate();
5571 std::list<http_url_parameter> params;
5581 _In_reads_or_z_(end)
const char* text,
5582 _In_
size_t start = 0,
5583 _In_
size_t end = (
size_t)-1,
5584 _In_
int flags = match_default)
5586 assert(text || start >= end);
5594 if (k.
end < end && text[k.
end]) {
5595 if (isalpha(text[k.
end]))
5606 components.push_back(k);
5618 if (!components.empty()) {
5627 virtual void invalidate()
5630 parser::invalidate();
5634 std::vector<stdex::interval<size_t>> components;
5643 http_weight(_In_
const std::locale& locale = std::locale()) :
5649 _In_reads_or_z_(end)
const char* text,
5650 _In_
size_t start = 0,
5651 _In_
size_t end = (
size_t)-1,
5652 _In_
int flags = match_default)
5654 assert(text || start >= end);
5655 size_t celi_del = 0, decimalni_del = 0, decimalni_del_n = 1;
5660 celi_del = celi_del * 10 + text[
interval.
end] -
'0';
5668 decimalni_del = decimalni_del * 10 + text[
interval.
end] -
'0';
5669 decimalni_del_n *= 10;
5687 value = (float)((
double)celi_del + (double)decimalni_del / decimalni_del_n);
5696 virtual void invalidate()
5699 parser::invalidate();
5713 _In_reads_or_z_(end)
const char* text,
5714 _In_
size_t start = 0,
5715 _In_
size_t end = (
size_t)-1,
5716 _In_
int flags = match_default)
5718 assert(text || end <= start);
5719 if (start < end && text[start] ==
'*') {
5731 template <
class T,
class T_asterisk = http_asterisk>
5741 _In_reads_or_z_(end)
const char* text,
5742 _In_
size_t start = 0,
5743 _In_
size_t end = (
size_t)-1,
5744 _In_
int flags = match_default)
5746 assert(text || start >= end);
5747 size_t konec_vrednosti;
5749 if (asterisk.match(text,
interval.
end, end, flags)) {
5750 interval.
end = konec_vrednosti = asterisk.interval.end;
5753 else if (value.match(text,
interval.
end, end, flags)) {
5754 interval.
end = konec_vrednosti = value.interval.end;
5755 asterisk.invalidate();
5758 asterisk.invalidate();
5780 factor.invalidate();
5787 virtual void invalidate()
5789 asterisk.invalidate();
5791 factor.invalidate();
5792 parser::invalidate();
5796 T_asterisk asterisk;
5808 _In_reads_or_z_(end)
const char* text,
5809 _In_
size_t start = 0,
5810 _In_
size_t end = (
size_t)-1,
5811 _In_
int flags = match_default)
5813 assert(text || start >= end);
5823 while (m_space.match(text,
interval.
end, end, flags))
5829 while (m_space.match(text,
interval.
end, end, flags))
5845 virtual void invalidate()
5849 parser::invalidate();
5867 _In_reads_or_z_(end)
const char* text,
5868 _In_
size_t start = 0,
5869 _In_
size_t end = (
size_t)-1,
5870 _In_
int flags = match_default)
5872 assert(text || start >= end);
5878 while (m_space.match(text,
interval.
end, end, flags))
5884 while (m_space.match(text,
interval.
end, end, flags))
5893 if (m_space.match(text,
interval.
end, end, flags))
5897 while (m_space.match(text,
interval.
end, end, flags))
5900 if (param.match(text,
interval.
end, end, flags)) {
5902 params.push_back(std::move(param));
5925 virtual void invalidate()
5930 parser::invalidate();
5949 _In_reads_or_z_(end)
const char* text,
5950 _In_
size_t start = 0,
5951 _In_
size_t end = (
size_t)-1,
5952 _In_
int flags = match_default)
5954 assert(text || start >= end);
6004 virtual void invalidate()
6010 parser::invalidate();
6024 http_protocol(_In_
const std::locale& locale = std::locale()) :
6030 _In_reads_or_z_(end)
const char* text,
6031 _In_
size_t start = 0,
6032 _In_
size_t end = (
size_t)-1,
6033 _In_
int flags = match_default)
6035 assert(text || start >= end);
6067 (uint16_t)strtoui(text + version_maj.
start, version_maj.
size(),
nullptr, 10) * 0x100 +
6068 (uint16_t)strtoui(text + version_min.
start, version_min.
size(),
nullptr, 10);
6081 version_min.
start = 1;
6082 version_min.
end = 0;
6083 version = (uint16_t)strtoui(text + version_maj.
start, version_maj.
size(),
nullptr, 10) * 0x100;
6098 version_maj.
start = 1;
6099 version_maj.
end = 0;
6100 version_min.
start = 1;
6101 version_min.
end = 0;
6108 virtual void invalidate()
6112 version_maj.
start = 1;
6113 version_maj.
end = 0;
6114 version_min.
start = 1;
6115 version_min.
end = 0;
6117 parser::invalidate();
6133 http_request(_In_
const std::locale& locale = std::locale()) :
6140 _In_reads_or_z_(end)
const char* text,
6141 _In_
size_t start = 0,
6142 _In_
size_t end = (
size_t)-1,
6143 _In_
int flags = match_default)
6145 assert(text || start >= end);
6149 if (m_line_break.match(text,
interval.
end, end, flags))
6162 if (m_line_break.match(text,
interval.
end, end, flags))
6178 if (m_line_break.match(text,
interval.
end, end, flags))
6194 protocol.invalidate();
6196 if (m_line_break.match(text,
interval.
end, end, flags)) {
6210 if (m_line_break.match(text,
interval.
end, end, flags)) {
6214 else if (protocol.match(text,
interval.
end, end, flags)) {
6223 if (m_line_break.match(text,
interval.
end, end, flags)) {
6241 protocol.invalidate();
6247 virtual void invalidate()
6252 protocol.invalidate();
6253 parser::invalidate();
6272 _In_reads_or_z_(end)
const char* text,
6273 _In_
size_t start = 0,
6274 _In_
size_t end = (
size_t)-1,
6275 _In_
int flags = match_default)
6277 assert(text || start >= end);
6280 if (m_line_break.match(text,
interval.
end, end, flags) ||
6285 if (m_line_break.match(text,
interval.
end, end, flags))
6292 if (m_line_break.match(text,
interval.
end, end, flags))
6322 value.
start = (size_t)-1;
6325 if (m_line_break.match(text,
interval.
end, end, flags)) {
6327 if (!m_line_break.match(text,
interval.
end, end, flags) &&
6357 virtual void invalidate()
6363 parser::invalidate();
6382 _In_reads_or_z_(end)
const char* text,
6383 _In_
size_t start = 0,
6384 _In_
size_t end = (
size_t)-1,
6385 _In_
int flags = match_default)
6387 while (start < end) {
6388 while (start < end && text[start] && isspace(text[start])) start++;
6389 if (start < end && text[start] ==
',') {
6391 while (start < end&& text[start] && isspace(text[start])) start++;
6394 if (el.match(text, start, end, flags)) {
6395 start = el.interval.end;
6396 T::insert(std::move(el));
6406 constexpr bool operator()(
const T& a,
const T& b)
const noexcept
6408 return a.factor.value > b.factor.value;
6415 template <
class T,
class _Alloc = std::allocator<T>>
6437 _In_
const std::locale& locale = std::locale()) :
6453 _In_reads_or_z_(end)
const T* text,
6454 _In_
size_t start = 0,
6455 _In_
size_t end = (
size_t)-1,
6456 _In_
int flags = match_default)
6458 assert(text || start >= end);
6460 if (m_quote->match(text,
interval.
end, end, flags)) {
6464 if (m_quote->match(text,
interval.
end, end, flags)) {
6469 if (m_escape->match(text,
interval.
end, end, flags)) {
6470 if (m_quote->match(text, m_escape->interval.end, end, flags)) {
6471 value +=
'"';
interval.
end = m_quote->interval.end;
6474 if (m_sol->match(text, m_escape->interval.end, end, flags)) {
6478 if (m_bs->match(text, m_escape->interval.end, end, flags)) {
6482 if (m_ff->match(text, m_escape->interval.end, end, flags)) {
6486 if (m_lf->match(text, m_escape->interval.end, end, flags)) {
6490 if (m_cr->match(text, m_escape->interval.end, end, flags)) {
6494 if (m_htab->match(text, m_escape->interval.end, end, flags)) {
6495 value +=
'\t';
interval.
end = m_htab->interval.end;
6499 m_uni->match(text, m_escape->interval.end, end, flags) &&
6500 m_hex->match(text, m_uni->interval.end, std::min(m_uni->interval.end + 4, end), flags | match_case_insensitive) &&
6501 m_hex->interval.size() == 4 )
6503 assert(m_hex->value <= 0xffff);
6504 if (
sizeof(T) == 1) {
6505 if (m_hex->value > 0x7ff) {
6506 value += (T)(0xe0 | (m_hex->value >> 12) & 0x0f);
6507 value += (T)(0x80 | (m_hex->value >> 6) & 0x3f);
6508 value += (T)(0x80 | m_hex->value & 0x3f);
6510 else if (m_hex->value > 0x7f) {
6511 value += (T)(0xc0 | (m_hex->value >> 6) & 0x1f);
6512 value += (T)(0x80 | m_hex->value & 0x3f);
6515 value += (T)(m_hex->value & 0x7f);
6518 value += (T)m_hex->value;
6522 if (m_escape->match(text, m_escape->interval.end, end, flags)) {
6523 value +=
'\\';
interval.
end = m_escape->interval.end;
6527 if (m_chr->match(text,
interval.
end, end, flags)) {
6528 value.Prilepi(text + m_chr->interval.start, m_chr->interval.size());
6540 virtual void invalidate()
6547 std::basic_string<T> value;
6550 std::shared_ptr<basic_parser<T>> m_quote;
6551 std::shared_ptr<basic_parser<T>> m_chr;
6552 std::shared_ptr<basic_parser<T>> m_escape;
6553 std::shared_ptr<basic_parser<T>> m_sol;
6554 std::shared_ptr<basic_parser<T>> m_bs;
6555 std::shared_ptr<basic_parser<T>> m_ff;
6556 std::shared_ptr<basic_parser<T>> m_lf;
6557 std::shared_ptr<basic_parser<T>> m_cr;
6558 std::shared_ptr<basic_parser<T>> m_htab;
6559 std::shared_ptr<basic_parser<T>> m_uni;
6560 std::shared_ptr<basic_integer16<T>> m_hex;
6573#undef ENUM_FLAG_OPERATOR
Test for angle in d°mm'ss.dddd form.
Definition parser.hpp:4387
Test for any code unit.
Definition parser.hpp:214
Test for beginning of line.
Definition parser.hpp:608
Test for any.
Definition parser.hpp:1050
Test for any code unit from a given string of code units.
Definition parser.hpp:713
Test for specific code unit.
Definition parser.hpp:284
Test for date.
Definition parser.hpp:4017
Test for valid DNS domain character.
Definition parser.hpp:2798
bool allow_on_edge
Is character allowed at the beginning or an end of a DNS domain?
Definition parser.hpp:2836
Test for DNS domain/hostname.
Definition parser.hpp:2898
bool m_allow_absolute
May DNS names end with a dot (absolute name)?
Definition parser.hpp:2962
Test for e-mail address.
Definition parser.hpp:3786
Test for emoticon.
Definition parser.hpp:3894
std::shared_ptr< basic_parser< T > > apex
apex/eyebrows/halo (e.g. O, 0)
Definition parser.hpp:3983
std::shared_ptr< basic_parser< T > > eyes
eyes (e.g. :, ;, >, |, B)
Definition parser.hpp:3984
std::shared_ptr< basic_set< T > > mouth
mouth (e.g. ), ), (, (, |, P, D, p, d)
Definition parser.hpp:3986
std::shared_ptr< basic_parser< T > > nose
nose (e.g. -, o)
Definition parser.hpp:3985
std::shared_ptr< basic_parser< T > > emoticon
emoticon as a whole (e.g. 😀, 🤔, 😶)
Definition parser.hpp:3982
Test for end of line.
Definition parser.hpp:646
Test for fraction.
Definition parser.hpp:1679
Test for decimal integer.
Definition parser.hpp:1288
Test for decimal integer possibly containing thousand separators.
Definition parser.hpp:1373
bool has_separators
Did integer have any separators?
Definition parser.hpp:1433
size_t digit_count
Total number of digits in integer.
Definition parser.hpp:1432
Test for hexadecimal integer.
Definition parser.hpp:1454
Base class for integer testing.
Definition parser.hpp:1266
size_t value
Calculated value of the numeral.
Definition parser.hpp:1280
Test for IPv4 address.
Definition parser.hpp:2338
stdex::interval< size_t > components[4]
Individual component intervals.
Definition parser.hpp:2453
struct in_addr value
IPv4 address value.
Definition parser.hpp:2454
Test for IPv6 address.
Definition parser.hpp:2557
std::shared_ptr< basic_parser< T > > scope_id
Scope ID (e.g. NIC index with link-local addresses)
Definition parser.hpp:2761
stdex::interval< size_t > components[8]
Individual component intervals.
Definition parser.hpp:2759
struct in6_addr value
IPv6 address value.
Definition parser.hpp:2760
Test for valid IPv6 address scope ID character.
Definition parser.hpp:2485
Test for repeating.
Definition parser.hpp:903
bool m_greedy
try to match as long sequence as possible
Definition parser.hpp:942
std::shared_ptr< basic_parser< T > > m_el
repeating element
Definition parser.hpp:939
size_t m_min_iterations
minimum number of iterations
Definition parser.hpp:940
size_t m_max_iterations
maximum number of iterations
Definition parser.hpp:941
Test for JSON string.
Definition parser.hpp:6423
Test for mixed numeral.
Definition parser.hpp:1914
std::shared_ptr< basic_parser< T > > fraction
fraction
Definition parser.hpp:2020
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2018
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2017
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2016
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2019
Test for monetary numeral.
Definition parser.hpp:2209
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2315
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2320
std::shared_ptr< basic_parser< T > > currency
Currency part.
Definition parser.hpp:2318
std::shared_ptr< basic_parser< T > > decimal
Decimal part.
Definition parser.hpp:2321
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2319
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2316
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2317
"No-op" match
Definition parser.hpp:182
Base template for all parsers.
Definition parser.hpp:63
interval< size_t > interval
Region of the last match.
Definition parser.hpp:162
Test for permutation.
Definition parser.hpp:1190
Test for phone number.
Definition parser.hpp:4510
std::basic_string< T > value
Normalized phone number.
Definition parser.hpp:4636
Test for any punctuation code unit.
Definition parser.hpp:456
Test for Roman numeral.
Definition parser.hpp:1563
Test for scientific numeral.
Definition parser.hpp:2040
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2184
std::shared_ptr< basic_parser< T > > exponent_symbol
Exponent symbol (e.g. 'e')
Definition parser.hpp:2188
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2182
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2183
double value
Calculated value of the numeral.
Definition parser.hpp:2192
std::shared_ptr< basic_parser< T > > negative_exp_sign
Negative exponent sign (e.g. '-')
Definition parser.hpp:2190
std::shared_ptr< basic_integer< T > > decimal
Decimal part.
Definition parser.hpp:2187
std::shared_ptr< basic_parser< T > > positive_exp_sign
Positive exponent sign (e.g. '+')
Definition parser.hpp:2189
std::shared_ptr< basic_integer< T > > exponent
Exponent part.
Definition parser.hpp:2191
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2186
std::shared_ptr< basic_integer< T > > integer
Integer part.
Definition parser.hpp:2185
Test for match score.
Definition parser.hpp:1742
Test for sequence.
Definition parser.hpp:999
Definition parser.hpp:681
Test for signed numeral.
Definition parser.hpp:1828
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:1896
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:1895
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:1894
std::shared_ptr< basic_parser< T > > number
Number.
Definition parser.hpp:1897
Test for any space code unit.
Definition parser.hpp:377
Test for any space or punctuation code unit.
Definition parser.hpp:530
Test for any string.
Definition parser.hpp:1118
Test for given string.
Definition parser.hpp:808
Test for time.
Definition parser.hpp:4284
Test for valid URL password character.
Definition parser.hpp:3080
Test for valid URL path character.
Definition parser.hpp:3180
Test for URL path.
Definition parser.hpp:3288
Test for valid URL username character.
Definition parser.hpp:2981
Test for URL.
Definition parser.hpp:3429
Test for HTTP agent.
Definition parser.hpp:5946
Test for HTTP any type.
Definition parser.hpp:5068
Test for HTTP asterisk.
Definition parser.hpp:5710
Test for HTTP cookie parameter (RFC2109)
Definition parser.hpp:5805
Test for HTTP cookie (RFC2109)
Definition parser.hpp:5864
std::list< http_cookie_parameter > params
List of cookie parameters.
Definition parser.hpp:5936
http_token name
Cookie name.
Definition parser.hpp:5934
http_value value
Cookie value.
Definition parser.hpp:5935
Test for HTTP language (RFC1766)
Definition parser.hpp:5578
Test for HTTP line break (RFC2616: CRLF | LF)
Definition parser.hpp:4742
Test for HTTP parameter (RFC2616: parameter)
Definition parser.hpp:5013
http_token name
Parameter name.
Definition parser.hpp:5057
http_value value
Parameter value.
Definition parser.hpp:5058
Test for HTTP protocol.
Definition parser.hpp:6022
uint16_t version
HTTP protocol version: 0x100 = 1.0, 0x101 = 1.1...
Definition parser.hpp:6124
Test for HTTP quoted string (RFC2616: quoted-string)
Definition parser.hpp:4903
stdex::interval< size_t > content
String content (without quotes)
Definition parser.hpp:4959
Test for HTTP request.
Definition parser.hpp:6131
Test for HTTP space (RFC2616: LWS)
Definition parser.hpp:4778
Test for HTTP text character (RFC2616: TEXT)
Definition parser.hpp:4815
Test for HTTP token (RFC2616: token - tolerates non-ASCII)
Definition parser.hpp:4849
Test for HTTP URL parameter.
Definition parser.hpp:5395
Test for HTTP URL path segment.
Definition parser.hpp:5306
Test for HTTP URL path segment.
Definition parser.hpp:5339
std::vector< http_url_path_segment > segments
Path segments.
Definition parser.hpp:5388
Test for HTTP URL port.
Definition parser.hpp:5250
Test for HTTP URL server.
Definition parser.hpp:5213
Test for HTTP URL.
Definition parser.hpp:5476
Collection of HTTP values.
Definition parser.hpp:6379
Test for HTTP value (RFC2616: value)
Definition parser.hpp:4969
http_quoted_string string
Value when matched as quoted string.
Definition parser.hpp:5005
http_token token
Value when matched as token.
Definition parser.hpp:5006
Test for HTTP weight factor.
Definition parser.hpp:5641
float value
Calculated value of the weight factor.
Definition parser.hpp:5703
Test for HTTP weighted value.
Definition parser.hpp:5733
Base template for collection-holding parsers.
Definition parser.hpp:959
Test for any SGML code point.
Definition parser.hpp:246
Test for any SGML code point from a given string of SGML code points.
Definition parser.hpp:765
Test for specific SGML code point.
Definition parser.hpp:333
Test for valid DNS domain SGML character.
Definition parser.hpp:2854
Test for valid IPv6 address scope ID SGML character.
Definition parser.hpp:2523
Test for any SGML punctuation code point.
Definition parser.hpp:497
Test for any SGML space code point.
Definition parser.hpp:420
Test for any SGML space or punctuation code point.
Definition parser.hpp:573
Test for SGML given string.
Definition parser.hpp:855
Test for valid URL password SGML character.
Definition parser.hpp:3132
Test for valid URL path SGML character.
Definition parser.hpp:3236
Test for valid URL username SGML character.
Definition parser.hpp:3032
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:6405