35#pragma warning(disable: 4100)
38#define ENUM_FLAG_OPERATOR(T,X) \
39inline 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)); } \
40inline 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); } \
41inline 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)); } \
42inline T& operator X= (T& lhs, const T rhs) { return lhs = lhs X rhs; } \
43inline T& operator X= (T& lhs, const std::underlying_type_t<T> rhs) { return lhs = lhs X rhs; }
44#define ENUM_FLAGS(T, type) \
46inline T operator ~ (T t) { return (T) (~static_cast<std::underlying_type_t <T>>(t)); } \
47ENUM_FLAG_OPERATOR(T,|) \
48ENUM_FLAG_OPERATOR(T,^) \
49ENUM_FLAG_OPERATOR(T,&) \
59 constexpr int match_default = 0;
60 constexpr int match_case_insensitive = 0x1;
61 constexpr int match_multiline = 0x2;
70 basic_parser(_In_
const std::locale& locale = std::locale()) : m_locale(locale) {}
74 _In_reads_or_z_(end)
const T* text,
75 _In_
size_t start = 0,
76 _In_
size_t end = (
size_t)-1,
77 _In_
int flags = match_default)
79 for (
size_t i = start; i < end && text[i]; i++)
80 if (match(text, i, end, flags))
86 _In_reads_or_z_(end)
const T* text,
87 _In_
size_t start = 0,
88 _In_
size_t end = (
size_t)-1,
89 _In_
int flags = match_default) = 0;
91 template<
class _Traits,
class _Ax>
93 const std::basic_string<T, _Traits, _Ax>& text,
94 _In_
size_t start = 0,
95 _In_
size_t end = (
size_t)-1,
96 _In_
int flags = match_default)
98 return match(text.c_str(), start, std::min<size_t>(end, text.size()), flags);
101 virtual void invalidate()
109 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])
111 if (text[start] ==
'&') {
113 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
114 for (chr_end = start + 1;; chr_end++) {
115 if (chr_end >= end || text[chr_end] == 0) {
119 if (text[chr_end] ==
';') {
121 size_t n = chr_end - start - 1;
122 if (n >= 2 && text[start + 1] ==
'#') {
125 if (text[start + 2] ==
'x' || text[start + 2] ==
'X')
126 unicode = strtou32(text + start + 3, n - 2,
nullptr, 16);
128 unicode = strtou32(text + start + 2, n - 1,
nullptr, 10);
130 if (unicode < 0x10000) {
131 buf[0] = (wchar_t)unicode;
135 ucs4_to_surrogate_pair(buf, unicode);
139 buf[0] = (wchar_t)unicode;
145 const wchar_t* entity_w = sgml2uni(text + start + 1, n);
153 else if (text[chr_end] ==
'&' || ctype.is(ctype.space, text[chr_end])) {
159 buf[0] = text[start];
170 std::locale m_locale;
190 _In_reads_or_z_(end)
const T* text,
191 _In_
size_t start = 0,
192 _In_
size_t end = (
size_t)-1,
193 _In_
int flags = match_default)
195 assert(text || start >= end);
196 if (start < end && text[start]) {
224 _In_reads_or_z_(end)
const T* text,
225 _In_
size_t start = 0,
226 _In_
size_t end = (
size_t)-1,
227 _In_
int flags = match_default)
229 assert(text || start >= end);
230 if (start < end && text[start]) {
256 _In_reads_or_z_(end)
const char* text,
257 _In_
size_t start = 0,
258 _In_
size_t end = (
size_t)-1,
259 _In_
int flags = match_default)
261 assert(text || start >= end);
262 if (start < end && text[start]) {
263 if (text[start] ==
'&') {
265 const auto& ctype = std::use_facet<std::ctype<char>>(m_locale);
291 basic_cu(T chr,
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
298 _In_reads_or_z_(end)
const T* text,
299 _In_
size_t start = 0,
300 _In_
size_t end = (
size_t)-1,
301 _In_
int flags = match_default)
303 assert(text || start >= end);
304 if (start < end && text[start]) {
306 if (flags & match_case_insensitive) {
307 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
308 r = ctype.tolower(text[start]) == ctype.tolower(m_chr);
311 r = text[start] == m_chr;
312 if (r && !m_invert || !r && m_invert) {
340 sgml_cp(
const char* chr,
size_t count = (
size_t)-1,
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
344 assert(chr || !count);
347 m_chr.assign(count ? next_sgml_cp(chr, 0, count, chr_end, buf) : L
"");
351 _In_reads_or_z_(end)
const char* text,
352 _In_
size_t start = 0,
353 _In_
size_t end = (
size_t)-1,
354 _In_
int flags = match_default)
356 assert(text || start >= end);
357 if (start < end && text[start]) {
359 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
360 bool r = ((flags & match_case_insensitive) ?
361 stdex::strnicmp(chr, (
size_t)-1, m_chr.c_str(), m_chr.size(), m_locale) :
362 stdex::strncmp(chr, (
size_t)-1, m_chr.c_str(), m_chr.size())) == 0;
363 if (r && !m_invert || !r && m_invert) {
384 basic_space_cu(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
390 _In_reads_or_z_(end)
const T* text,
391 _In_
size_t start = 0,
392 _In_
size_t end = (
size_t)-1,
393 _In_
int flags = match_default)
395 assert(text || start >= end);
396 if (start < end && text[start]) {
398 ((flags & match_multiline) || !islbreak(text[start])) &&
399 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::space, text[start]);
400 if (r && !m_invert || !r && m_invert) {
427 sgml_space_cp(_In_
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
432 _In_reads_or_z_(end)
const char* text,
433 _In_
size_t start = 0,
434 _In_
size_t end = (
size_t)-1,
435 _In_
int flags = match_default)
437 assert(text || start >= end);
438 if (start < end && text[start]) {
440 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
441 const wchar_t* chr_end = chr + stdex::strlen(chr);
443 ((flags & match_multiline) || !islbreak(chr, (
size_t)-1)) &&
444 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space, chr, chr_end) == chr_end;
445 if (r && !m_invert || !r && m_invert) {
463 basic_punct_cu(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
469 _In_reads_or_z_(end)
const T* text,
470 _In_
size_t start = 0,
471 _In_
size_t end = (
size_t)-1,
472 _In_
int flags = match_default)
474 assert(text || start >= end);
475 if (start < end && text[start]) {
476 bool r = std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::punct, text[start]);
477 if (r && !m_invert || !r && m_invert) {
504 sgml_punct_cp(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
509 _In_reads_or_z_(end)
const char* text,
510 _In_
size_t start = 0,
511 _In_
size_t end = (
size_t)-1,
512 _In_
int flags = match_default)
514 assert(text || start >= end);
515 if (start < end && text[start]) {
517 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
518 const wchar_t* chr_end = chr + stdex::strlen(chr);
519 bool r = std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::punct, chr, chr_end) == chr_end;
520 if (r && !m_invert || !r && m_invert) {
543 _In_reads_or_z_(end)
const T* text,
544 _In_
size_t start = 0,
545 _In_
size_t end = (
size_t)-1,
546 _In_
int flags = match_default)
548 assert(text || start >= end);
549 if (start < end && text[start]) {
551 ((flags & match_multiline) || !islbreak(text[start])) &&
552 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::space | std::ctype_base::punct, text[start]);
553 if (r && !m_invert || !r && m_invert) {
585 _In_reads_or_z_(end)
const char* text,
586 _In_
size_t start = 0,
587 _In_
size_t end = (
size_t)-1,
588 _In_
int flags = match_default)
590 assert(text || start >= end);
591 if (start < end && text[start]) {
593 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
594 const wchar_t* chr_end = chr + stdex::strlen(chr);
596 ((flags & match_multiline) || !islbreak(chr, (
size_t)-1)) &&
597 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space | std::ctype_base::punct, chr, chr_end) == chr_end;
598 if (r && !m_invert || !r && m_invert) {
615 basic_bol(
bool invert =
false) : m_invert(invert) {}
618 _In_reads_or_z_(end)
const T* text,
619 _In_
size_t start = 0,
620 _In_
size_t end = (
size_t)-1,
621 _In_
int flags = match_default)
623 assert(text || start >= end);
624 bool r = start == 0 || start <= end && islbreak(text[start - 1]);
625 if (r && !m_invert || !r && m_invert) {
653 basic_eol(
bool invert =
false) : m_invert(invert) {}
656 _In_reads_or_z_(end)
const T* text,
657 _In_
size_t start = 0,
658 _In_
size_t end = (
size_t)-1,
659 _In_
int flags = match_default)
661 assert(text || start >= end);
662 bool r = islbreak(text[start]);
663 if (r && !m_invert || !r && m_invert) {
688 basic_set(
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
690 hit_offset((
size_t)-1),
695 _In_reads_or_z_(end)
const T* text,
696 _In_
size_t start = 0,
697 _In_
size_t end = (
size_t)-1,
698 _In_
int flags = match_default) = 0;
700 virtual void invalidate()
702 hit_offset = (size_t)-1;
721 _In_reads_or_z_(count)
const T* set,
722 _In_
size_t count = (
size_t)-1,
723 _In_
bool invert =
false,
724 _In_
const std::locale& locale = std::locale()) :
728 m_set.assign(set, set + stdex::strnlen(set, count));
732 _In_reads_or_z_(end)
const T* text,
733 _In_
size_t start = 0,
734 _In_
size_t end = (
size_t)-1,
735 _In_
int flags = match_default)
737 assert(text || start >= end);
738 if (start < end && text[start]) {
739 const T* set = m_set.c_str();
740 size_t r = (flags & match_case_insensitive) ?
741 stdex::strnichr(set, m_set.size(), text[start], m_locale) :
742 stdex::strnchr(set, m_set.size(), text[start]);
743 if (r != stdex::npos && !m_invert || r == stdex::npos && m_invert) {
749 hit_offset = (size_t)-1;
755 std::basic_string<T> m_set;
772 sgml_cp_set(
const char* set,
size_t count = (
size_t)-1,
bool invert =
false, _In_
const std::locale& locale = std::locale()) :
776 m_set = sgml2wstr(set, count);
780 _In_reads_or_z_(end)
const char* text,
781 _In_
size_t start = 0,
782 _In_
size_t end = (
size_t)-1,
783 _In_
int flags = match_default)
785 assert(text || start >= end);
786 if (start < end && text[start]) {
788 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
789 const wchar_t* set = m_set.c_str();
790 size_t r = (flags & match_case_insensitive) ?
791 stdex::strnistr(set, m_set.size(), chr, m_locale) :
792 stdex::strnstr(set, m_set.size(), chr);
793 if (r != stdex::npos && !m_invert || r == stdex::npos && m_invert) {
799 hit_offset = (size_t)-1;
816 _In_reads_or_z_(count)
const T* str,
817 _In_
size_t count = (
size_t)-1,
818 _In_
const std::locale& locale = std::locale()) :
820 m_str(str, str + stdex::strnlen(str, count))
824 _In_reads_or_z_(end)
const T* text,
825 _In_
size_t start = 0,
826 _In_
size_t end = (
size_t)-1,
827 _In_
int flags = match_default)
829 assert(text || start >= end);
832 n = std::min<size_t>(end - start, m);
833 bool r = ((flags & match_case_insensitive) ?
834 stdex::strnicmp(text + start, n, m_str.c_str(), m, m_locale) :
835 stdex::strncmp(text + start, n, m_str.c_str(), m)) == 0;
845 std::basic_string<T> m_str;
862 sgml_string(
const char* str,
size_t count = (
size_t)-1, _In_
const std::locale& locale = std::locale()) :
864 m_str(sgml2wstr(str, count))
868 _In_reads_or_z_(end)
const char* text,
869 _In_
size_t start = 0,
870 _In_
size_t end = (
size_t)-1,
871 _In_
int flags = match_default)
873 assert(text || start >= end);
874 const wchar_t* str = m_str.c_str();
875 const bool case_insensitive = flags & match_case_insensitive ? true :
false;
876 const auto& ctype = std::use_facet<std::ctype<wchar_t>>(m_locale);
888 for (; *chr; ++str, ++chr) {
890 (case_insensitive ? ctype.tolower(*str) != ctype.tolower(*chr) : *str != *chr))
918 _In_reads_or_z_(end)
const T* text,
919 _In_
size_t start = 0,
920 _In_
size_t end = (
size_t)-1,
921 _In_
int flags = match_default)
923 assert(text || start >= end);
925 for (
size_t i = 0; ; i++) {
944 std::shared_ptr<basic_parser<T>>
m_el;
972 _In_
const std::locale& locale = std::locale()) :
975 assert(el || !count);
976 m_collection.reserve(count);
977 for (
size_t i = 0; i < count; i++)
978 m_collection.push_back(el[i]);
983 _In_
const std::locale& locale = std::locale()) :
985 m_collection(std::move(collection))
988 virtual void invalidate()
990 for (
auto& el: m_collection)
996 std::vector<std::shared_ptr<basic_parser<T>>> m_collection;
1007 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1008 _In_
size_t count = 0,
1009 _In_
const std::locale& locale = std::locale()) :
1015 _In_
const std::locale& locale = std::locale()) :
1020 _In_reads_or_z_(end)
const T* text,
1021 _In_
size_t start = 0,
1022 _In_
size_t end = (
size_t)-1,
1023 _In_
int flags = match_default)
1025 assert(text || start >= end);
1027 for (
auto i = m_collection.begin(); i != m_collection.end(); ++i) {
1028 if (!(*i)->match(text,
interval.
end, end, flags)) {
1029 for (++i; i != m_collection.end(); ++i)
1059 hit_offset((
size_t)-1)
1064 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1065 _In_
size_t count = 0,
1066 _In_
const std::locale& locale = std::locale()) :
1068 hit_offset((
size_t)-1)
1073 _In_
const std::locale& locale = std::locale()) :
1075 hit_offset((
size_t)-1)
1079 _In_reads_or_z_(end)
const T* text,
1080 _In_
size_t start = 0,
1081 _In_
size_t end = (
size_t)-1,
1082 _In_
int flags = match_default)
1084 assert(text || start >= end);
1086 for (
auto i = m_collection.begin(); i != m_collection.end(); ++i, ++hit_offset) {
1087 if ((*i)->match(text, start, end, flags)) {
1089 for (++i; i != m_collection.end(); ++i)
1094 hit_offset = (size_t)-1;
1099 virtual void invalidate()
1101 hit_offset = (size_t)-1;
1121 template <
class T,
class T_parser = basic_
string<T>>
1126 _In_reads_(count)
const T* str_z =
nullptr,
1127 _In_
size_t count = 0,
1128 _In_
const std::locale& locale = std::locale()) :
1131 build(str_z, count);
1138 va_start(params, str);
1147 va_start(params, str);
1153 void build(_In_reads_(count)
const T* str_z, _In_
size_t count)
1155 assert(str_z || !count);
1160 offset < count && str_z[offset];
1161 offset += stdex::strnlen(str_z + offset, count - offset) + 1, ++n);
1162 m_collection.reserve(n);
1165 offset < count && str_z[offset];
1166 offset += stdex::strnlen(str_z + offset, count - offset) + 1)
1167 m_collection.push_back(std::move(std::make_shared<T_parser>(str_z + offset, count - offset, m_locale)));
1171 void build(_In_z_
const T* str, _In_ va_list params)
1175 m_collection.push_back(std::move(std::make_shared<T_parser>(str, (
size_t)-1, m_locale)));
1176 (p = va_arg(params,
const T*)) !=
nullptr;
1177 m_collection.push_back(std::move(std::make_shared<T_parser>(p, (
size_t)-1, m_locale))));
1198 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1199 _In_
size_t count = 0,
1200 _In_
const std::locale& locale = std::locale()) :
1206 _In_
const std::locale& locale = std::locale()) :
1211 _In_reads_or_z_(end)
const T* text,
1212 _In_
size_t start = 0,
1213 _In_
size_t end = (
size_t)-1,
1214 _In_
int flags = match_default)
1216 assert(text || start >= end);
1217 for (
auto& el: m_collection)
1219 if (match_recursively(text, start, end, flags)) {
1228 bool match_recursively(
1229 _In_reads_or_z_(end)
const T* text,
1230 _In_
size_t start = 0,
1231 _In_
size_t end = (
size_t)-1,
1232 _In_
int flags = match_default)
1234 bool all_matched =
true;
1235 for (
auto& el: m_collection) {
1236 if (!el->interval) {
1238 all_matched =
false;
1239 if (el->match(text, start, end, flags)) {
1241 if (match_recursively(text, el->interval.end, end, flags)) {
1273 basic_integer(_In_
const std::locale& locale = std::locale()) :
1278 virtual void invalidate()
1306 _In_
const std::locale& locale = std::locale()) :
1321 _In_reads_or_z_(end)
const T* text,
1322 _In_
size_t start = 0,
1323 _In_
size_t end = (
size_t)-1,
1324 _In_
int flags = match_default)
1326 assert(text || start >= end);
1329 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0;
interval.
end = m_digit_0->interval.end; }
1330 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1;
interval.
end = m_digit_1->interval.end; }
1331 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2;
interval.
end = m_digit_2->interval.end; }
1332 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3;
interval.
end = m_digit_3->interval.end; }
1333 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4;
interval.
end = m_digit_4->interval.end; }
1334 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5;
interval.
end = m_digit_5->interval.end; }
1335 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6;
interval.
end = m_digit_6->interval.end; }
1336 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7;
interval.
end = m_digit_7->interval.end; }
1337 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8;
interval.
end = m_digit_8->interval.end; }
1338 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9;
interval.
end = m_digit_9->interval.end; }
1351 std::shared_ptr<basic_parser<T>>
1383 _In_
const std::locale& locale = std::locale()) :
1388 m_separator(separator)
1392 _In_reads_or_z_(end)
const T* text,
1393 _In_
size_t start = 0,
1394 _In_
size_t end = (
size_t)-1,
1395 _In_
int flags = match_default)
1397 assert(text || start >= end);
1398 if (m_digits->match(text, start, end, flags)) {
1400 value = m_digits->value;
1405 if (m_digits->interval.size() <= 3) {
1407 size_t hit_offset = (size_t)-1;
1408 while (m_separator->match(text,
interval.
end, end, flags) &&
1409 (hit_offset == (size_t)-1 || hit_offset == m_separator->hit_offset) &&
1410 m_digits->match(text, m_separator->interval.end, end, flags) &&
1411 m_digits->interval.size() == 3)
1418 hit_offset = m_separator->hit_offset;
1429 virtual void invalidate()
1441 std::shared_ptr<basic_integer10<T>> m_digits;
1442 std::shared_ptr<basic_set<T>> m_separator;
1478 _In_
const std::locale& locale = std::locale()) :
1490 m_digit_10(digit_10),
1491 m_digit_11(digit_11),
1492 m_digit_12(digit_12),
1493 m_digit_13(digit_13),
1494 m_digit_14(digit_14),
1495 m_digit_15(digit_15)
1499 _In_reads_or_z_(end)
const T* text,
1500 _In_
size_t start = 0,
1501 _In_
size_t end = (
size_t)-1,
1502 _In_
int flags = match_default)
1504 assert(text || start >= end);
1507 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0;
interval.
end = m_digit_0->interval.end; }
1508 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1;
interval.
end = m_digit_1->interval.end; }
1509 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2;
interval.
end = m_digit_2->interval.end; }
1510 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3;
interval.
end = m_digit_3->interval.end; }
1511 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4;
interval.
end = m_digit_4->interval.end; }
1512 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5;
interval.
end = m_digit_5->interval.end; }
1513 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6;
interval.
end = m_digit_6->interval.end; }
1514 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7;
interval.
end = m_digit_7->interval.end; }
1515 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8;
interval.
end = m_digit_8->interval.end; }
1516 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9;
interval.
end = m_digit_9->interval.end; }
1517 else if (m_digit_10->match(text,
interval.
end, end, flags)) { dig = 10;
interval.
end = m_digit_10->interval.end; }
1518 else if (m_digit_11->match(text,
interval.
end, end, flags)) { dig = 11;
interval.
end = m_digit_11->interval.end; }
1519 else if (m_digit_12->match(text,
interval.
end, end, flags)) { dig = 12;
interval.
end = m_digit_12->interval.end; }
1520 else if (m_digit_13->match(text,
interval.
end, end, flags)) { dig = 13;
interval.
end = m_digit_13->interval.end; }
1521 else if (m_digit_14->match(text,
interval.
end, end, flags)) { dig = 14;
interval.
end = m_digit_14->interval.end; }
1522 else if (m_digit_15->match(text,
interval.
end, end, flags)) { dig = 15;
interval.
end = m_digit_15->interval.end; }
1535 std::shared_ptr<basic_parser<T>>
1580 _In_
const std::locale& locale = std::locale()) :
1584 m_digit_10(digit_10),
1585 m_digit_50(digit_50),
1586 m_digit_100(digit_100),
1587 m_digit_500(digit_500),
1588 m_digit_1000(digit_1000),
1589 m_digit_5000(digit_5000),
1590 m_digit_10000(digit_10000)
1594 _In_reads_or_z_(end)
const T* text,
1595 _In_
size_t start = 0,
1596 _In_
size_t end = (
size_t)-1,
1597 _In_
int flags = match_default)
1599 assert(text || start >= end);
1601 dig[5] = { (size_t)-1, (
size_t)-1, (size_t)-1, (
size_t)-1, (size_t)-1 },
1605 if (m_digit_1 && m_digit_1->match(text,
interval.
end, end, flags)) { dig[0] = 1; end2 = m_digit_1->interval.end; }
1606 else if (m_digit_5 && m_digit_5->match(text,
interval.
end, end, flags)) { dig[0] = 5; end2 = m_digit_5->interval.end; }
1607 else if (m_digit_10 && m_digit_10->match(text,
interval.
end, end, flags)) { dig[0] = 10; end2 = m_digit_10->interval.end; }
1608 else if (m_digit_50 && m_digit_50->match(text,
interval.
end, end, flags)) { dig[0] = 50; end2 = m_digit_50->interval.end; }
1609 else if (m_digit_100 && m_digit_100->match(text,
interval.
end, end, flags)) { dig[0] = 100; end2 = m_digit_100->interval.end; }
1610 else if (m_digit_500 && m_digit_500->match(text,
interval.
end, end, flags)) { dig[0] = 500; end2 = m_digit_500->interval.end; }
1611 else if (m_digit_1000 && m_digit_1000->match(text,
interval.
end, end, flags)) { dig[0] = 1000; end2 = m_digit_1000->interval.end; }
1612 else if (m_digit_5000 && m_digit_5000->match(text,
interval.
end, end, flags)) { dig[0] = 5000; end2 = m_digit_5000->interval.end; }
1613 else if (m_digit_10000 && m_digit_10000->match(text,
interval.
end, end, flags)) { dig[0] = 10000; end2 = m_digit_10000->interval.end; }
1617 if (dig[4] == (
size_t)-1) dig[4] = dig[0];
1619 if (dig[3] == dig[2] && dig[2] == dig[1] && dig[1] == dig[0] && dig[0] != dig[4]) {
1623 if (dig[0] <= dig[1]) {
1628 dig[1] == 1 && (dig[0] == 5 || dig[0] == 10) ||
1629 dig[1] == 10 && (dig[0] == 50 || dig[0] == 100) ||
1630 dig[1] == 100 && (dig[0] == 500 || dig[0] == 1000) ||
1631 dig[1] == 1000 && (dig[0] == 5000 || dig[0] == 10000))
1634 if (dig[2] < dig[0]) {
1658 std::shared_ptr<basic_parser<T>>
1690 _In_
const std::locale& locale = std::locale()) :
1692 numerator(_numerator),
1693 fraction_line(_fraction_line),
1694 denominator(_denominator)
1698 _In_reads_or_z_(end)
const T* text,
1699 _In_
size_t start = 0,
1700 _In_
size_t end = (
size_t)-1,
1701 _In_
int flags = match_default)
1703 assert(text || start >= end);
1704 if (numerator->match(text, start, end, flags) &&
1705 fraction_line->match(text, numerator->interval.end, end, flags) &&
1706 denominator->match(text, fraction_line->interval.end, end, flags))
1712 numerator->invalidate();
1713 fraction_line->invalidate();
1714 denominator->invalidate();
1719 virtual void invalidate()
1721 numerator->invalidate();
1722 fraction_line->invalidate();
1723 denominator->invalidate();
1728 std::shared_ptr<basic_parser<T>> numerator;
1729 std::shared_ptr<basic_parser<T>> fraction_line;
1730 std::shared_ptr<basic_parser<T>> denominator;
1754 _In_
const std::locale& locale = std::locale()) :
1757 separator(_separator),
1763 _In_reads_or_z_(end)
const T* text,
1764 _In_
size_t start = 0,
1765 _In_
size_t end = (
size_t)-1,
1766 _In_
int flags = match_default)
1768 assert(text || start >= end);
1776 const int space_match_flags = flags & ~match_multiline;
1777 for (; m_space->match(text,
interval.
end, end, space_match_flags);
interval.
end = m_space->interval.end);
1779 if (separator->match(text,
interval.
end, end, flags))
1784 for (; m_space->match(text,
interval.
end, end, space_match_flags);
interval.
end = m_space->interval.end);
1796 separator->invalidate();
1797 guest->invalidate();
1802 virtual void invalidate()
1805 separator->invalidate();
1806 guest->invalidate();
1811 std::shared_ptr<basic_parser<T>> home;
1812 std::shared_ptr<basic_parser<T>> separator;
1813 std::shared_ptr<basic_parser<T>> guest;
1816 std::shared_ptr<basic_parser<T>> m_space;
1840 _In_
const std::locale& locale = std::locale()) :
1849 _In_reads_or_z_(end)
const T* text,
1850 _In_
size_t start = 0,
1851 _In_
size_t end = (
size_t)-1,
1852 _In_
int flags = match_default)
1854 assert(text || start >= end);
1889 virtual void invalidate()
1928 _In_
const std::locale& locale = std::locale()) :
1939 _In_reads_or_z_(end)
const T* text,
1940 _In_
size_t start = 0,
1941 _In_
size_t end = (
size_t)-1,
1942 _In_
int flags = match_default)
1944 assert(text || start >= end);
1969 const int space_match_flags = flags & ~match_multiline;
1971 m_space->match(text,
integer->interval.end, end, space_match_flags))
2010 virtual void invalidate()
2028 std::shared_ptr<basic_parser<T>> m_space;
2058 _In_
const std::locale& locale = std::locale()) :
2070 value(std::numeric_limits<double>::quiet_NaN())
2074 _In_reads_or_z_(end)
const T* text,
2075 _In_
size_t start = 0,
2076 _In_
size_t end = (
size_t)-1,
2077 _In_
int flags = match_default)
2079 assert(text || start >= end);
2114 if (
integer->interval.empty() &&
2160 double e = (double)
exponent->value;
2163 value *= pow(10.0, e);
2170 virtual void invalidate()
2182 value = std::numeric_limits<double>::quiet_NaN();
2224 _In_
const std::locale& locale = std::locale()) :
2236 _In_reads_or_z_(end)
const T* text,
2237 _In_
size_t start = 0,
2238 _In_
size_t end = (
size_t)-1,
2239 _In_
int flags = match_default)
2241 assert(text || start >= end);
2288 if (
integer->interval.empty() &&
2307 virtual void invalidate()
2357 _In_
const std::locale& locale = std::locale()) :
2369 m_separator(separator)
2375 _In_reads_or_z_(end)
const T* text,
2376 _In_
size_t start = 0,
2377 _In_
size_t end = (
size_t)-1,
2378 _In_
int flags = match_default)
2380 assert(text || start >= end);
2385 for (i = 0; i < 4; i++) {
2387 if (m_separator->match(text,
interval.
end, end, flags))
2394 bool is_empty =
true;
2397 size_t dig, digit_end;
2398 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
2399 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
2400 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
2401 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
2402 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
2403 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
2404 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
2405 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
2406 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
2407 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
2409 size_t x_n = x * 10 + dig;
2421 value.s_addr = (
value.s_addr << 8) | (uint8_t)x;
2443 virtual void invalidate()
2462 std::shared_ptr<basic_parser<T>>
2473 std::shared_ptr<basic_parser<T>> m_separator;
2495 _In_reads_or_z_(end)
const T* text,
2496 _In_
size_t start = 0,
2497 _In_
size_t end = (
size_t)-1,
2498 _In_
int flags = match_default)
2500 assert(text || start >= end);
2501 if (start < end && text[start]) {
2502 if (text[start] ==
'-' ||
2503 text[start] ==
'_' ||
2504 text[start] ==
':' ||
2505 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
2533 _In_reads_or_z_(end)
const char* text,
2534 _In_
size_t start = 0,
2535 _In_
size_t end = (
size_t)-1,
2536 _In_
int flags = match_default)
2538 assert(text || start >= end);
2539 if (start < end && text[start]) {
2541 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
2542 const wchar_t* chr_end = chr + stdex::strlen(chr);
2543 if ((chr[0] == L
'-' ||
2545 chr[0] == L
':') && chr[1] == 0 ||
2546 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
2582 _In_
const std::shared_ptr<
basic_parser<T>>& scope_id_separator =
nullptr,
2584 _In_
const std::locale& locale = std::locale()) :
2596 m_digit_10(digit_10),
2597 m_digit_11(digit_11),
2598 m_digit_12(digit_12),
2599 m_digit_13(digit_13),
2600 m_digit_14(digit_14),
2601 m_digit_15(digit_15),
2602 m_separator(separator),
2603 m_scope_id_separator(scope_id_separator),
2610 _In_reads_or_z_(end)
const T* text,
2611 _In_
size_t start = 0,
2612 _In_
size_t end = (
size_t)-1,
2613 _In_
int flags = match_default)
2615 assert(text || start >= end);
2619 size_t i, compaction_i = (size_t)-1, compaction_start = start;
2620 for (i = 0; i < 8; i++) {
2621 bool is_empty =
true;
2623 if (m_separator->match(text,
interval.
end, end, flags)) {
2624 if (m_separator->match(text, m_separator->interval.end, end, flags)) {
2626 if (compaction_i == (
size_t)-1) {
2629 compaction_start = m_separator->interval.start;
2654 size_t dig, digit_end;
2655 if (m_digit_0->match(text,
interval.
end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
2656 else if (m_digit_1->match(text,
interval.
end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
2657 else if (m_digit_2->match(text,
interval.
end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
2658 else if (m_digit_3->match(text,
interval.
end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
2659 else if (m_digit_4->match(text,
interval.
end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
2660 else if (m_digit_5->match(text,
interval.
end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
2661 else if (m_digit_6->match(text,
interval.
end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
2662 else if (m_digit_7->match(text,
interval.
end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
2663 else if (m_digit_8->match(text,
interval.
end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
2664 else if (m_digit_9->match(text,
interval.
end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
2665 else if (m_digit_10->match(text,
interval.
end, end, flags)) { dig = 10; digit_end = m_digit_10->interval.end; }
2666 else if (m_digit_11->match(text,
interval.
end, end, flags)) { dig = 11; digit_end = m_digit_11->interval.end; }
2667 else if (m_digit_12->match(text,
interval.
end, end, flags)) { dig = 12; digit_end = m_digit_12->interval.end; }
2668 else if (m_digit_13->match(text,
interval.
end, end, flags)) { dig = 13; digit_end = m_digit_13->interval.end; }
2669 else if (m_digit_14->match(text,
interval.
end, end, flags)) { dig = 14; digit_end = m_digit_14->interval.end; }
2670 else if (m_digit_15->match(text,
interval.
end, end, flags)) { dig = 15; digit_end = m_digit_15->interval.end; }
2672 size_t x_n = x * 16 + dig;
2673 if (x_n <= 0xffff) {
2682 if (compaction_i != (
size_t)-1) {
2689 value.s6_words[i] = (uint16_t)x;
2692 if (compaction_i != (
size_t)-1) {
2695 for (j = 8, k = i; k > compaction_i;) {
2699 for (; j > compaction_i;) {
2700 value.s6_words[--j] = 0;
2708 if (m_scope_id_separator && m_scope_id_separator->match(text,
interval.
end, end, flags) &&
2709 scope_id &&
scope_id->match(text, m_scope_id_separator->interval.end, end, flags))
2740 virtual void invalidate()
2769 std::shared_ptr<basic_parser<T>>
2786 std::shared_ptr<basic_parser<T>> m_separator, m_scope_id_separator;
2806 _In_
bool allow_idn,
2807 _In_
const std::locale& locale = std::locale()) :
2809 m_allow_idn(allow_idn),
2814 _In_reads_or_z_(end)
const T* text,
2815 _In_
size_t start = 0,
2816 _In_
size_t end = (
size_t)-1,
2817 _In_
int flags = match_default)
2819 assert(text || start >= end);
2820 if (start < end && text[start]) {
2821 if ((
'A' <= text[start] && text[start] <=
'Z') ||
2822 (
'a' <= text[start] && text[start] <=
'z') ||
2823 (
'0' <= text[start] && text[start] <=
'9'))
2825 else if (text[start] ==
'-')
2827 else if (m_allow_idn && std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
2862 _In_
bool allow_idn,
2863 _In_
const std::locale& locale = std::locale()) :
2868 _In_reads_or_z_(end)
const char* text,
2869 _In_
size_t start = 0,
2870 _In_
size_t end = (
size_t)-1,
2871 _In_
int flags = match_default)
2873 assert(text || start >= end);
2874 if (start < end && text[start]) {
2876 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
2877 const wchar_t* chr_end = chr + stdex::strlen(chr);
2878 if (((
'A' <= chr[0] && chr[0] <=
'Z') ||
2879 (
'a' <= chr[0] && chr[0] <=
'z') ||
2880 (
'0' <= chr[0] && chr[0] <=
'9')) && chr[1] == 0)
2882 else if (chr[0] ==
'-' && chr[1] == 0)
2884 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)
2906 _In_
bool allow_absolute,
2909 _In_
const std::locale& locale = std::locale()) :
2912 m_domain_char(domain_char),
2913 m_separator(separator)
2917 _In_reads_or_z_(end)
const T* text,
2918 _In_
size_t start = 0,
2919 _In_
size_t end = (
size_t)-1,
2920 _In_
int flags = match_default)
2922 assert(text || start >= end);
2923 size_t i = start, count;
2924 for (count = 0; i < end && text[i] && count < 127; count++) {
2925 if (m_domain_char->match(text, i, end, flags) &&
2926 m_domain_char->allow_on_edge)
2930 while (i < end && text[i]) {
2931 if (m_domain_char->allow_on_edge &&
2932 m_separator->match(text, i, end, flags))
2939 i = m_separator->interval.end;
2943 if (m_domain_char->match(text, i, end, flags)) {
2944 if (m_domain_char->allow_on_edge)
2947 i = m_domain_char->interval.end;
2968 std::shared_ptr<basic_dns_domain_char<T>> m_domain_char;
2969 std::shared_ptr<basic_parser<T>> m_separator;
2991 _In_reads_or_z_(end)
const T* text,
2992 _In_
size_t start = 0,
2993 _In_
size_t end = (
size_t)-1,
2994 _In_
int flags = match_default)
2996 assert(text || start >= end);
2997 if (start < end && text[start]) {
2998 if (text[start] ==
'-' ||
2999 text[start] ==
'.' ||
3000 text[start] ==
'_' ||
3001 text[start] ==
'~' ||
3002 text[start] ==
'%' ||
3003 text[start] ==
'!' ||
3004 text[start] ==
'$' ||
3005 text[start] ==
'&' ||
3006 text[start] ==
'\'' ||
3009 text[start] ==
'*' ||
3010 text[start] ==
'+' ||
3011 text[start] ==
',' ||
3012 text[start] ==
';' ||
3013 text[start] ==
'=' ||
3014 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
3042 _In_reads_or_z_(end)
const char* text,
3043 _In_
size_t start = 0,
3044 _In_
size_t end = (
size_t)-1,
3045 _In_
int flags = match_default)
3047 assert(text || start >= end);
3048 if (start < end && text[start]) {
3050 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
3051 const wchar_t* chr_end = chr + stdex::strlen(chr);
3052 if ((chr[0] == L
'-' ||
3067 chr[0] == L
'=') && chr[1] == 0 ||
3068 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3090 _In_reads_or_z_(end)
const T* text,
3091 _In_
size_t start = 0,
3092 _In_
size_t end = (
size_t)-1,
3093 _In_
int flags = match_default)
3095 assert(text || start >= end);
3096 if (start < end && text[start]) {
3097 if (text[start] ==
'-' ||
3098 text[start] ==
'.' ||
3099 text[start] ==
'_' ||
3100 text[start] ==
'~' ||
3101 text[start] ==
'%' ||
3102 text[start] ==
'!' ||
3103 text[start] ==
'$' ||
3104 text[start] ==
'&' ||
3105 text[start] ==
'\'' ||
3106 text[start] ==
'(' ||
3107 text[start] ==
')' ||
3108 text[start] ==
'*' ||
3109 text[start] ==
'+' ||
3110 text[start] ==
',' ||
3111 text[start] ==
';' ||
3112 text[start] ==
'=' ||
3113 text[start] ==
':' ||
3114 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
3142 _In_reads_or_z_(end)
const char* text,
3143 _In_
size_t start = 0,
3144 _In_
size_t end = (
size_t)-1,
3145 _In_
int flags = match_default)
3147 assert(text || start >= end);
3148 if (start < end && text[start]) {
3150 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
3151 const wchar_t* chr_end = chr + stdex::strlen(chr);
3152 if ((chr[0] == L
'-' ||
3168 chr[0] == L
':') && chr[1] == 0 ||
3169 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3190 _In_reads_or_z_(end)
const T* text,
3191 _In_
size_t start = 0,
3192 _In_
size_t end = (
size_t)-1,
3193 _In_
int flags = match_default)
3195 assert(text || start >= end);
3196 if (start < end && text[start]) {
3197 if (text[start] ==
'/' ||
3198 text[start] ==
'-' ||
3199 text[start] ==
'.' ||
3200 text[start] ==
'_' ||
3201 text[start] ==
'~' ||
3202 text[start] ==
'%' ||
3203 text[start] ==
'!' ||
3204 text[start] ==
'$' ||
3205 text[start] ==
'&' ||
3206 text[start] ==
'\'' ||
3207 text[start] ==
'(' ||
3208 text[start] ==
')' ||
3209 text[start] ==
'*' ||
3210 text[start] ==
'+' ||
3211 text[start] ==
',' ||
3212 text[start] ==
';' ||
3213 text[start] ==
'=' ||
3214 text[start] ==
':' ||
3215 text[start] ==
'@' ||
3216 text[start] ==
'?' ||
3217 text[start] ==
'#' ||
3218 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
3246 _In_reads_or_z_(end)
const char* text,
3247 _In_
size_t start = 0,
3248 _In_
size_t end = (
size_t)-1,
3249 _In_
int flags = match_default)
3251 assert(text || start >= end);
3252 if (start < end && text[start]) {
3254 const wchar_t* chr = next_sgml_cp(text, start, end,
interval.
end, buf);
3255 const wchar_t* chr_end = chr + stdex::strlen(chr);
3256 if ((chr[0] == L
'/' ||
3276 chr[0] == L
'#') && chr[1] == 0 ||
3277 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3299 _In_
const std::locale& locale = std::locale()) :
3301 m_path_char(path_char),
3302 m_query_start(query_start),
3303 m_bookmark_start(bookmark_start)
3307 _In_reads_or_z_(end)
const T* text,
3308 _In_
size_t start = 0,
3309 _In_
size_t end = (
size_t)-1,
3310 _In_
int flags = match_default)
3312 assert(text || start >= end);
3324 if (m_query_start->match(text,
interval.
end, end, flags)) {
3332 if (m_bookmark_start->match(text,
interval.
end, end, flags)) {
3340 if (m_path_char->match(text,
interval.
end, end, flags))
3350 if (m_path_char->match(text,
interval.
end, end, flags))
3360 if (m_bookmark_start->match(text,
interval.
end, end, flags)) {
3368 if (m_path_char->match(text,
interval.
end, end, flags))
3378 if (m_path_char->match(text,
interval.
end, end, flags))
3398 virtual void invalidate()
3415 std::shared_ptr<basic_parser<T>> m_path_char;
3416 std::shared_ptr<basic_parser<T>> m_query_start;
3417 std::shared_ptr<basic_parser<T>> m_bookmark_start;
3453 _In_
const std::locale& locale = std::locale()) :
3455 http_scheme(_http_scheme),
3456 ftp_scheme(_ftp_scheme),
3457 mailto_scheme(_mailto_scheme),
3458 file_scheme(_file_scheme),
3461 username(_username),
3462 password(_password),
3464 m_ip_lbracket(ip_lbracket),
3465 m_ip_rbracket(ip_rbracket),
3466 ipv4_host(_ipv4_host),
3467 ipv6_host(_ipv6_host),
3468 dns_host(_dns_host),
3474 _In_reads_or_z_(end)
const T* text,
3475 _In_
size_t start = 0,
3476 _In_
size_t end = (
size_t)-1,
3477 _In_
int flags = match_default)
3479 assert(text || start >= end);
3483 if (http_scheme->match(text,
interval.
end, end, flags) &&
3484 m_colon->match(text, http_scheme->interval.end, end, flags) &&
3485 m_slash->match(text, m_colon->interval.end, end, flags) &&
3486 m_slash->match(text, m_slash->interval.end, end, flags))
3490 ftp_scheme->invalidate();
3491 mailto_scheme->invalidate();
3492 file_scheme->invalidate();
3494 else if (ftp_scheme->match(text,
interval.
end, end, flags) &&
3495 m_colon->match(text, ftp_scheme->interval.end, end, flags) &&
3496 m_slash->match(text, m_colon->interval.end, end, flags) &&
3497 m_slash->match(text, m_slash->interval.end, end, flags))
3501 http_scheme->invalidate();
3502 mailto_scheme->invalidate();
3503 file_scheme->invalidate();
3505 else if (mailto_scheme->match(text,
interval.
end, end, flags) &&
3506 m_colon->match(text, mailto_scheme->interval.end, end, flags))
3510 http_scheme->invalidate();
3511 ftp_scheme->invalidate();
3512 file_scheme->invalidate();
3514 else if (file_scheme->match(text,
interval.
end, end, flags) &&
3515 m_colon->match(text, file_scheme->interval.end, end, flags) &&
3516 m_slash->match(text, m_colon->interval.end, end, flags) &&
3517 m_slash->match(text, m_slash->interval.end, end, flags))
3521 http_scheme->invalidate();
3522 ftp_scheme->invalidate();
3523 mailto_scheme->invalidate();
3527 http_scheme->invalidate();
3528 ftp_scheme->invalidate();
3529 mailto_scheme->invalidate();
3530 file_scheme->invalidate();
3533 if (ftp_scheme->interval) {
3534 if (username->match(text,
interval.
end, end, flags)) {
3535 if (m_colon->match(text, username->interval.end, end, flags) &&
3536 password->match(text, m_colon->interval.end, end, flags) &&
3537 m_at->match(text, password->interval.end, end, flags))
3542 else if (m_at->match(text,
interval.
end, end, flags)) {
3545 password->invalidate();
3548 username->invalidate();
3549 password->invalidate();
3553 username->invalidate();
3554 password->invalidate();
3557 if (ipv4_host->match(text,
interval.
end, end, flags)) {
3560 ipv6_host->invalidate();
3561 dns_host->invalidate();
3564 m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3565 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3566 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3570 ipv4_host->invalidate();
3571 dns_host->invalidate();
3573 else if (dns_host->match(text,
interval.
end, end, flags)) {
3576 ipv4_host->invalidate();
3577 ipv6_host->invalidate();
3584 if (m_colon->match(text,
interval.
end, end, flags) &&
3585 port->match(text, m_colon->interval.end, end, flags))
3593 if (path->match(text,
interval.
end, end, flags)) {
3602 if (mailto_scheme->interval) {
3603 if (username->match(text,
interval.
end, end, flags) &&
3604 m_at->match(text, username->interval.end, end, flags))
3614 if (m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3615 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3616 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
3620 ipv6_host->invalidate();
3621 dns_host->invalidate();
3624 m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3625 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3626 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3630 ipv4_host->invalidate();
3631 dns_host->invalidate();
3633 else if (dns_host->match(text,
interval.
end, end, flags)) {
3636 ipv4_host->invalidate();
3637 ipv6_host->invalidate();
3644 password->invalidate();
3651 if (file_scheme->interval) {
3652 if (path->match(text,
interval.
end, end, flags)) {
3657 username->invalidate();
3658 password->invalidate();
3659 ipv4_host->invalidate();
3660 ipv6_host->invalidate();
3661 dns_host->invalidate();
3670 if (http_scheme->interval &&
3673 if (m_colon->match(text, username->interval.end, end, flags) &&
3674 password->match(text, m_colon->interval.end, end, flags) &&
3675 m_at->match(text, password->interval.end, end, flags))
3680 else if (m_at->match(text, username->interval.end, end, flags)) {
3683 password->invalidate();
3686 username->invalidate();
3687 password->invalidate();
3691 username->invalidate();
3692 password->invalidate();
3695 if (ipv4_host->match(text,
interval.
end, end, flags)) {
3698 ipv6_host->invalidate();
3699 dns_host->invalidate();
3702 m_ip_lbracket->match(text,
interval.
end, end, flags) &&
3703 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3704 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3708 ipv4_host->invalidate();
3709 dns_host->invalidate();
3711 else if (dns_host->match(text,
interval.
end, end, flags)) {
3714 ipv4_host->invalidate();
3715 ipv6_host->invalidate();
3722 if (m_colon->match(text,
interval.
end, end, flags) &&
3723 port->match(text, m_colon->interval.end, end, flags))
3731 if (path->match(text,
interval.
end, end, flags)) {
3740 virtual void invalidate()
3742 http_scheme->invalidate();
3743 ftp_scheme->invalidate();
3744 mailto_scheme->invalidate();
3745 file_scheme->invalidate();
3746 username->invalidate();
3747 password->invalidate();
3748 ipv4_host->invalidate();
3749 ipv6_host->invalidate();
3750 dns_host->invalidate();
3757 std::shared_ptr<basic_parser<T>> http_scheme;
3758 std::shared_ptr<basic_parser<T>> ftp_scheme;
3759 std::shared_ptr<basic_parser<T>> mailto_scheme;
3760 std::shared_ptr<basic_parser<T>> file_scheme;
3761 std::shared_ptr<basic_parser<T>> username;
3762 std::shared_ptr<basic_parser<T>> password;
3763 std::shared_ptr<basic_parser<T>> ipv4_host;
3764 std::shared_ptr<basic_parser<T>> ipv6_host;
3765 std::shared_ptr<basic_parser<T>> dns_host;
3766 std::shared_ptr<basic_parser<T>> port;
3767 std::shared_ptr<basic_parser<T>> path;
3770 std::shared_ptr<basic_parser<T>> m_colon;
3771 std::shared_ptr<basic_parser<T>> m_slash;
3772 std::shared_ptr<basic_parser<T>> m_at;
3773 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
3774 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
3801 _In_
const std::locale& locale = std::locale()) :
3803 username(_username),
3805 m_ip_lbracket(ip_lbracket),
3806 m_ip_rbracket(ip_rbracket),
3807 ipv4_host(_ipv4_host),
3808 ipv6_host(_ipv6_host),
3813 _In_reads_or_z_(end)
const T* text,
3814 _In_
size_t start = 0,
3815 _In_
size_t end = (
size_t)-1,
3816 _In_
int flags = match_default)
3818 assert(text || start >= end);
3820 if (username->match(text, start, end, flags) &&
3821 m_at->match(text, username->interval.end, end, flags))
3824 if (m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
3825 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3826 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
3830 ipv6_host->invalidate();
3831 dns_host->invalidate();
3834 m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
3835 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3836 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3840 ipv4_host->invalidate();
3841 dns_host->invalidate();
3843 else if (dns_host->match(text, m_at->interval.end, end, flags)) {
3846 ipv4_host->invalidate();
3847 ipv6_host->invalidate();
3856 username->invalidate();
3857 ipv4_host->invalidate();
3858 ipv6_host->invalidate();
3859 dns_host->invalidate();
3864 virtual void invalidate()
3866 username->invalidate();
3867 ipv4_host->invalidate();
3868 ipv6_host->invalidate();
3869 dns_host->invalidate();
3874 std::shared_ptr<basic_parser<T>> username;
3875 std::shared_ptr<basic_parser<T>> ipv4_host;
3876 std::shared_ptr<basic_parser<T>> ipv6_host;
3877 std::shared_ptr<basic_parser<T>> dns_host;
3880 std::shared_ptr<basic_parser<T>> m_at;
3881 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
3882 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
3907 _In_
const std::locale& locale = std::locale()) :
3917 _In_reads_or_z_(end)
const T* text,
3918 _In_
size_t start = 0,
3919 _In_
size_t end = (
size_t)-1,
3920 _In_
int flags = match_default)
3922 assert(text || start >= end);
3928 mouth->invalidate();
3940 if (
nose &&
nose->match(text,
eyes->interval.end, end, flags) &&
3941 mouth->match(text,
nose->interval.end, end, flags))
3944 start_mouth =
mouth->interval.start,
3945 hit_offset =
mouth->hit_offset;
3948 mouth->interval.start = start_mouth;
3953 if (
mouth->match(text,
eyes->interval.end, end, flags)) {
3955 start_mouth =
mouth->interval.start,
3956 hit_offset =
mouth->hit_offset;
3960 mouth->interval.start = start_mouth;
3971 mouth->invalidate();
3976 virtual void invalidate()
3982 mouth->invalidate();
3988 std::shared_ptr<basic_parser<T>>
apex;
3989 std::shared_ptr<basic_parser<T>>
eyes;
3990 std::shared_ptr<basic_parser<T>>
nose;
4006 enum date_format_t {
4007 date_format_none = 0,
4008 date_format_dmy = 0x1,
4009 date_format_mdy = 0x2,
4010 date_format_ymd = 0x4,
4011 date_format_ym = 0x8,
4012 date_format_my = 0x10,
4013 date_format_dm = 0x20,
4014 date_format_md = 0x40,
4025 _In_
int format_mask,
4031 _In_
const std::locale& locale = std::locale()) :
4033 format(date_format_none),
4034 m_format_mask(format_mask),
4038 m_separator(separator),
4043 _In_reads_or_z_(end)
const T* text,
4044 _In_
size_t start = 0,
4045 _In_
size_t end = (
size_t)-1,
4046 _In_
int flags = match_default)
4048 assert(text || start >= end);
4050 const int space_match_flags = flags & ~match_multiline;
4051 if ((m_format_mask & date_format_dmy) == date_format_dmy) {
4052 if (day->match(text, start, end, flags)) {
4054 if (m_separator->match(text,
interval.
end, end, flags)) {
4055 size_t hit_offset = m_separator->hit_offset;
4057 if (month->match(text,
interval.
end, end, flags)) {
4059 if (m_separator->match(text,
interval.
end, end, flags) &&
4060 m_separator->hit_offset == hit_offset)
4063 if (year->match(text,
interval.
end, end, flags) &&
4064 is_valid(day->value, month->value))
4068 format = date_format_dmy;
4077 if ((m_format_mask & date_format_mdy) == date_format_mdy) {
4078 if (month->match(text, start, end, flags)) {
4080 if (m_separator->match(text,
interval.
end, end, flags)) {
4081 size_t hit_offset = m_separator->hit_offset;
4085 if (m_separator->match(text,
interval.
end, end, flags) &&
4086 m_separator->hit_offset == hit_offset)
4089 if (year->match(text,
interval.
end, end, flags) &&
4090 is_valid(day->value, month->value))
4094 format = date_format_mdy;
4103 if ((m_format_mask & date_format_ymd) == date_format_ymd) {
4104 if (year->match(text, start, end, flags)) {
4106 if (m_separator->match(text,
interval.
end, end, flags)) {
4107 size_t hit_offset = m_separator->hit_offset;
4109 if (month->match(text,
interval.
end, end, flags)) {
4111 if (m_separator->match(text,
interval.
end, end, flags) &&
4112 m_separator->hit_offset == hit_offset)
4116 is_valid(day->value, month->value))
4120 format = date_format_ymd;
4129 if ((m_format_mask & date_format_ym) == date_format_ym) {
4130 if (year->match(text, start, end, flags)) {
4132 if (m_separator->match(text,
interval.
end, end, flags)) {
4134 if (month->match(text,
interval.
end, end, flags) &&
4135 is_valid((
size_t)-1, month->value))
4137 if (day) day->invalidate();
4140 format = date_format_ym;
4147 if ((m_format_mask & date_format_my) == date_format_my) {
4148 if (month->match(text, start, end, flags)) {
4150 if (m_separator->match(text,
interval.
end, end, flags)) {
4152 if (year->match(text,
interval.
end, end, flags) &&
4153 is_valid((
size_t)-1, month->value))
4155 if (day) day->invalidate();
4158 format = date_format_my;
4165 if ((m_format_mask & date_format_dm) == date_format_dm) {
4166 if (day->match(text, start, end, flags)) {
4168 if (m_separator->match(text,
interval.
end, end, flags)) {
4169 size_t hit_offset = m_separator->hit_offset;
4171 if (month->match(text,
interval.
end, end, flags) &&
4172 is_valid(day->value, month->value))
4174 if (year) year->invalidate();
4177 if (m_separator->match(text,
interval.
end, end, flags) &&
4178 m_separator->hit_offset == hit_offset)
4182 format = date_format_dm;
4189 if ((m_format_mask & date_format_md) == date_format_md) {
4190 if (month->match(text, start, end, flags)) {
4192 if (m_separator->match(text,
interval.
end, end, flags)) {
4193 size_t hit_offset = m_separator->hit_offset;
4196 is_valid(day->value, month->value))
4198 if (year) year->invalidate();
4201 if (m_separator->match(text,
interval.
end, end, flags) &&
4202 m_separator->hit_offset == hit_offset)
4206 format = date_format_md;
4213 if (day) day->invalidate();
4214 if (month) month->invalidate();
4215 if (year) year->invalidate();
4216 format = date_format_none;
4221 virtual void invalidate()
4223 if (day) day->invalidate();
4224 if (month) month->invalidate();
4225 if (year) year->invalidate();
4226 format = date_format_none;
4231 static inline bool is_valid(
size_t day,
size_t month)
4233 if (month == (
size_t)-1) {
4237 if (day == (
size_t)-1) {
4250 return 1 <= day && day <= 31;
4252 return 1 <= day && day <= 29;
4257 return 1 <= day && day <= 30;
4264 date_format_t format;
4265 std::shared_ptr<basic_integer<T>> day;
4266 std::shared_ptr<basic_integer<T>> month;
4267 std::shared_ptr<basic_integer<T>> year;
4271 std::shared_ptr<basic_set<T>> m_separator;
4272 std::shared_ptr<basic_parser<T>> m_space;
4298 _In_
const std::locale& locale = std::locale()) :
4303 millisecond(_millisecond),
4304 m_separator(separator),
4305 m_millisecond_separator(millisecond_separator)
4309 _In_reads_or_z_(end)
const T* text,
4310 _In_
size_t start = 0,
4311 _In_
size_t end = (
size_t)-1,
4312 _In_
int flags = match_default)
4314 assert(text || start >= end);
4316 if (hour->match(text, start, end, flags) &&
4317 m_separator->match(text, hour->interval.end, end, flags) &&
4318 minute->match(text, m_separator->interval.end, end, flags) &&
4322 size_t hit_offset = m_separator->hit_offset;
4323 if (m_separator->match(text, minute->interval.end, end, flags) &&
4324 m_separator->hit_offset == hit_offset &&
4325 second && second->match(text, m_separator->interval.end, end, flags) &&
4329 if (m_millisecond_separator && m_millisecond_separator->match(text, second->interval.end, end, flags) &&
4330 millisecond && millisecond->match(text, m_millisecond_separator->interval.end, end, flags) &&
4331 millisecond->value < 1000)
4337 if (millisecond) millisecond->invalidate();
4342 if (second) second->invalidate();
4343 if (millisecond) millisecond->invalidate();
4351 minute->invalidate();
4352 if (second) second->invalidate();
4353 if (millisecond) millisecond->invalidate();
4358 virtual void invalidate()
4361 minute->invalidate();
4362 if (second) second->invalidate();
4363 if (millisecond) millisecond->invalidate();
4368 std::shared_ptr<basic_integer10<T>> hour;
4369 std::shared_ptr<basic_integer10<T>> minute;
4370 std::shared_ptr<basic_integer10<T>> second;
4371 std::shared_ptr<basic_integer10<T>> millisecond;
4374 std::shared_ptr<basic_set<T>> m_separator;
4375 std::shared_ptr<basic_parser<T>> m_millisecond_separator;
4402 _In_
const std::locale& locale = std::locale()) :
4405 degree_separator(_degree_separator),
4407 minute_separator(_minute_separator),
4409 second_separator(_second_separator),
4414 _In_reads_or_z_(end)
const T* text,
4415 _In_
size_t start = 0,
4416 _In_
size_t end = (
size_t)-1,
4417 _In_
int flags = match_default)
4419 assert(text || start >= end);
4423 if (degree->match(text,
interval.
end, end, flags) &&
4424 degree_separator->match(text, degree->interval.end, end, flags))
4430 degree->invalidate();
4431 degree_separator->invalidate();
4434 if (minute->match(text,
interval.
end, end, flags) &&
4435 minute->value < 60 &&
4436 minute_separator->match(text, minute->interval.end, end, flags))
4442 minute->invalidate();
4443 minute_separator->invalidate();
4446 if (second && second->match(text,
interval.
end, end, flags) &&
4451 if (second_separator && second_separator->match(text,
interval.
end, end, flags))
4454 if (second_separator) second_separator->invalidate();
4457 if (second) second->invalidate();
4458 if (second_separator) second_separator->invalidate();
4461 if (degree->interval.start < degree->interval.end ||
4462 minute->interval.start < minute->interval.end ||
4463 second && second->interval.start < second->interval.end)
4465 if (decimal && decimal->match(text,
interval.
end, end, flags)) {
4470 decimal->invalidate();
4474 if (decimal) decimal->invalidate();
4479 virtual void invalidate()
4481 degree->invalidate();
4482 degree_separator->invalidate();
4483 minute->invalidate();
4484 minute_separator->invalidate();
4485 if (second) second->invalidate();
4486 if (second_separator) second_separator->invalidate();
4487 if (decimal) decimal->invalidate();
4492 std::shared_ptr<basic_integer10<T>> degree;
4493 std::shared_ptr<basic_parser<T>> degree_separator;
4494 std::shared_ptr<basic_integer10<T>> minute;
4495 std::shared_ptr<basic_parser<T>> minute_separator;
4496 std::shared_ptr<basic_integer10<T>> second;
4497 std::shared_ptr<basic_parser<T>> second_separator;
4498 std::shared_ptr<basic_parser<T>> decimal;
4520 _In_
const std::shared_ptr<
basic_set<T>>& lparenthesis,
4521 _In_
const std::shared_ptr<
basic_set<T>>& rparenthesis,
4524 _In_
const std::locale& locale = std::locale()) :
4527 m_plus_sign(plus_sign),
4528 m_lparenthesis(lparenthesis),
4529 m_rparenthesis(rparenthesis),
4530 m_separator(separator),
4535 _In_reads_or_z_(end)
const T* text,
4536 _In_
size_t start = 0,
4537 _In_
size_t end = (
size_t)-1,
4538 _In_
int flags = match_default)
4540 assert(text || start >= end);
4542 size_t safe_digit_end = start, safe_value_size = 0;
4543 bool has_digits =
false, after_digit =
false, in_parentheses =
false, after_parentheses =
false;
4544 const int space_match_flags = flags & ~match_multiline;
4548 m_lparenthesis->invalidate();
4549 m_rparenthesis->invalidate();
4551 if (m_plus_sign && m_plus_sign->match(text,
interval.
end, end, flags)) {
4552 value.append(text + m_plus_sign->interval.start, text + m_plus_sign->interval.end);
4553 safe_value_size =
value.size();
4561 if (m_digit->match(text,
interval.
end, end, flags)) {
4563 value.append(text + m_digit->interval.start, text + m_digit->interval.end);
4565 if (!in_parentheses) {
4567 safe_value_size =
value.size();
4571 after_parentheses =
false;
4574 m_lparenthesis && !m_lparenthesis->interval &&
4575 m_rparenthesis && !m_rparenthesis->interval &&
4576 m_lparenthesis->match(text,
interval.
end, end, flags))
4579 value.append(text + m_lparenthesis->interval.start, m_lparenthesis->interval.size());
4581 in_parentheses =
true;
4582 after_digit =
false;
4583 after_parentheses =
false;
4587 m_rparenthesis && !m_rparenthesis->interval &&
4588 m_rparenthesis->match(text,
interval.
end, end, flags) &&
4589 m_lparenthesis->hit_offset == m_rparenthesis->hit_offset)
4592 value.append(text + m_rparenthesis->interval.start, text + m_rparenthesis->interval.end);
4595 safe_value_size =
value.size();
4596 in_parentheses =
false;
4597 after_digit =
false;
4598 after_parentheses =
true;
4603 !after_parentheses &&
4604 m_separator && m_separator->match(text,
interval.
end, end, flags))
4608 after_digit =
false;
4609 after_parentheses =
false;
4612 (after_digit || after_parentheses) &&
4613 m_space && m_space->match(text,
interval.
end, end, space_match_flags))
4617 after_digit =
false;
4618 after_parentheses =
false;
4624 value.erase(safe_value_size);
4634 virtual void invalidate()
4644 std::shared_ptr<basic_parser<T>> m_digit;
4645 std::shared_ptr<basic_parser<T>> m_plus_sign;
4646 std::shared_ptr<basic_set<T>> m_lparenthesis;
4647 std::shared_ptr<basic_set<T>> m_rparenthesis;
4648 std::shared_ptr<basic_parser<T>> m_separator;
4649 std::shared_ptr<basic_parser<T>> m_space;
4672 _In_
const std::locale& locale = std::locale()) :
4682 _In_reads_or_z_(end)
const T* text,
4683 _In_
size_t start = 0,
4684 _In_
size_t end = (
size_t)-1,
4685 _In_
int flags = match_default)
4687 assert(text || start >= end);
4693 const int element_match_flags = flags & ~match_case_insensitive;
4695 if (m_element->match(text,
interval.
end, end, element_match_flags)) {
4697 while (m_digit->match(text,
interval.
end, end, flags)) {
4703 if (m_sign->match(text,
interval.
end, end, flags)) {
4717 virtual void invalidate()
4729 std::shared_ptr<basic_parser<T>> m_element;
4730 std::shared_ptr<basic_parser<T>> m_digit;
4731 std::shared_ptr<basic_parser<T>> m_sign;
4750 _In_reads_or_z_(end)
const char* text,
4751 _In_
size_t start = 0,
4752 _In_
size_t end = (
size_t)-1,
4753 _In_
int flags = match_default)
4755 assert(text || start >= end);
4786 _In_reads_or_z_(end)
const char* text,
4787 _In_
size_t start = 0,
4788 _In_
size_t end = (
size_t)-1,
4789 _In_
int flags = match_default)
4791 assert(text || start >= end);
4793 if (m_line_break.match(text,
interval.
end, end, flags)) {
4823 _In_reads_or_z_(end)
const char* text,
4824 _In_
size_t start = 0,
4825 _In_
size_t end = (
size_t)-1,
4826 _In_
int flags = match_default)
4828 assert(text || start >= end);
4832 if (m_space.match(text,
interval.
end, end, flags)) {
4857 _In_reads_or_z_(end)
const char* text,
4858 _In_
size_t start = 0,
4859 _In_
size_t end = (
size_t)-1,
4860 _In_
int flags = match_default)
4862 assert(text || start >= end);
4911 _In_reads_or_z_(end)
const char* text,
4912 _In_
size_t start = 0,
4913 _In_
size_t end = (
size_t)-1,
4914 _In_
int flags = match_default)
4916 assert(text || start >= end);
4938 else if (m_chr.match(text,
interval.
end, end, flags))
4956 virtual void invalidate()
4960 parser::invalidate();
4977 _In_reads_or_z_(end)
const char* text,
4978 _In_
size_t start = 0,
4979 _In_
size_t end = (
size_t)-1,
4980 _In_
int flags = match_default)
4982 assert(text || start >= end);
4984 if (
string.match(text,
interval.
end, end, flags)) {
4991 string.invalidate();
5002 virtual void invalidate()
5004 string.invalidate();
5006 parser::invalidate();
5021 _In_reads_or_z_(end)
const char* text,
5022 _In_
size_t start = 0,
5023 _In_
size_t end = (
size_t)-1,
5024 _In_
int flags = match_default)
5026 assert(text || start >= end);
5032 while (m_space.match(text,
interval.
end, end, flags))
5038 while (m_space.match(text,
interval.
end, end, flags))
5054 virtual void invalidate()
5058 parser::invalidate();
5076 _In_reads_or_z_(end)
const char* text,
5077 _In_
size_t start = 0,
5078 _In_
size_t end = (
size_t)-1,
5079 _In_
int flags = match_default)
5081 assert(text || start >= end);
5082 if (start + 2 < end &&
5083 text[start] ==
'*' &&
5084 text[start + 1] ==
'/' &&
5085 text[start + 2] ==
'*')
5090 else if (start < end && text[start] ==
'*') {
5108 _In_reads_or_z_(end)
const char* text,
5109 _In_
size_t start = 0,
5110 _In_
size_t end = (
size_t)-1,
5111 _In_
int flags = match_default)
5113 assert(text || start >= end);
5119 while (m_space.match(text,
interval.
end, end, flags))
5125 while (m_space.match(text,
interval.
end, end, flags))
5127 if (subtype.match(text,
interval.
end, end, flags))
5136 subtype.invalidate();
5141 virtual void invalidate()
5144 subtype.invalidate();
5145 parser::invalidate();
5163 _In_reads_or_z_(end)
const char* text,
5164 _In_
size_t start = 0,
5165 _In_
size_t end = (
size_t)-1,
5166 _In_
int flags = match_default)
5168 assert(text || start >= end);
5169 if (!http_media_range::match(text, start, end, flags))
5174 if (m_space.match(text,
interval.
end, end, flags))
5178 while (m_space.match(text,
interval.
end, end, flags))
5181 if (param.match(text,
interval.
end, end, flags)) {
5183 params.push_back(std::move(param));
5198 http_media_range::invalidate();
5204 virtual void invalidate()
5207 http_media_range::invalidate();
5211 std::list<http_parameter> params;
5221 _In_reads_or_z_(end)
const char* text,
5222 _In_
size_t start = 0,
5223 _In_
size_t end = (
size_t)-1,
5224 _In_
int flags = match_default)
5226 assert(text || start >= end);
5257 http_url_port(_In_
const std::locale& locale = std::locale()) :
5263 _In_reads_or_z_(end)
const char* text,
5264 _In_
size_t start = 0,
5265 _In_
size_t end = (
size_t)-1,
5266 _In_
int flags = match_default)
5268 assert(text || start >= end);
5274 size_t _value = (size_t)value * 10 + text[
interval.
end] -
'0';
5275 if (_value > (uint16_t)-1) {
5280 value = (uint16_t)_value;
5297 virtual void invalidate()
5300 parser::invalidate();
5314 _In_reads_or_z_(end)
const char* text,
5315 _In_
size_t start = 0,
5316 _In_
size_t end = (
size_t)-1,
5317 _In_
int flags = match_default)
5319 assert(text || start >= end);
5347 _In_reads_or_z_(end)
const char* text,
5348 _In_
size_t start = 0,
5349 _In_
size_t end = (
size_t)-1,
5350 _In_
int flags = match_default)
5352 assert(text || start >= end);
5386 virtual void invalidate()
5389 parser::invalidate();
5403 _In_reads_or_z_(end)
const char* text,
5404 _In_
size_t start = 0,
5405 _In_
size_t end = (
size_t)-1,
5406 _In_
int flags = match_default)
5408 assert(text || start >= end);
5463 virtual void invalidate()
5469 parser::invalidate();
5483 http_url(_In_
const std::locale& locale = std::locale()) :
5489 _In_reads_or_z_(end)
const char* text,
5490 _In_
size_t start = 0,
5491 _In_
size_t end = (
size_t)-1,
5492 _In_
int flags = match_default)
5494 assert(text || start >= end);
5497 if (
interval.
end + 7 <= end && stdex::strnicmp(text +
interval.
end, 7,
"http://", (
size_t)-1, m_locale) == 0) {
5514 server.invalidate();
5538 if (param.match(text,
interval.
end, end, flags)) {
5540 params.push_back(std::move(param));
5555 server.invalidate();
5563 virtual void invalidate()
5565 server.invalidate();
5569 parser::invalidate();
5576 std::list<http_url_parameter> params;
5586 _In_reads_or_z_(end)
const char* text,
5587 _In_
size_t start = 0,
5588 _In_
size_t end = (
size_t)-1,
5589 _In_
int flags = match_default)
5591 assert(text || start >= end);
5599 if (k.
end < end && text[k.
end]) {
5600 if (isalpha(text[k.
end]))
5611 components.push_back(k);
5623 if (!components.empty()) {
5632 virtual void invalidate()
5635 parser::invalidate();
5639 std::vector<stdex::interval<size_t>> components;
5648 http_weight(_In_
const std::locale& locale = std::locale()) :
5654 _In_reads_or_z_(end)
const char* text,
5655 _In_
size_t start = 0,
5656 _In_
size_t end = (
size_t)-1,
5657 _In_
int flags = match_default)
5659 assert(text || start >= end);
5660 size_t celi_del = 0, decimalni_del = 0, decimalni_del_n = 1;
5665 celi_del = celi_del * 10 + text[
interval.
end] -
'0';
5673 decimalni_del = decimalni_del * 10 + text[
interval.
end] -
'0';
5674 decimalni_del_n *= 10;
5692 value = (float)((
double)celi_del + (double)decimalni_del / decimalni_del_n);
5701 virtual void invalidate()
5704 parser::invalidate();
5718 _In_reads_or_z_(end)
const char* text,
5719 _In_
size_t start = 0,
5720 _In_
size_t end = (
size_t)-1,
5721 _In_
int flags = match_default)
5723 assert(text || end <= start);
5724 if (start < end && text[start] ==
'*') {
5736 template <
class T,
class T_asterisk = http_asterisk>
5746 _In_reads_or_z_(end)
const char* text,
5747 _In_
size_t start = 0,
5748 _In_
size_t end = (
size_t)-1,
5749 _In_
int flags = match_default)
5751 assert(text || start >= end);
5752 size_t konec_vrednosti;
5754 if (asterisk.match(text,
interval.
end, end, flags)) {
5755 interval.
end = konec_vrednosti = asterisk.interval.end;
5758 else if (value.match(text,
interval.
end, end, flags)) {
5759 interval.
end = konec_vrednosti = value.interval.end;
5760 asterisk.invalidate();
5763 asterisk.invalidate();
5785 factor.invalidate();
5792 virtual void invalidate()
5794 asterisk.invalidate();
5796 factor.invalidate();
5797 parser::invalidate();
5801 T_asterisk asterisk;
5813 _In_reads_or_z_(end)
const char* text,
5814 _In_
size_t start = 0,
5815 _In_
size_t end = (
size_t)-1,
5816 _In_
int flags = match_default)
5818 assert(text || start >= end);
5828 while (m_space.match(text,
interval.
end, end, flags))
5834 while (m_space.match(text,
interval.
end, end, flags))
5850 virtual void invalidate()
5854 parser::invalidate();
5872 _In_reads_or_z_(end)
const char* text,
5873 _In_
size_t start = 0,
5874 _In_
size_t end = (
size_t)-1,
5875 _In_
int flags = match_default)
5877 assert(text || start >= end);
5883 while (m_space.match(text,
interval.
end, end, flags))
5889 while (m_space.match(text,
interval.
end, end, flags))
5898 if (m_space.match(text,
interval.
end, end, flags))
5902 while (m_space.match(text,
interval.
end, end, flags))
5905 if (param.match(text,
interval.
end, end, flags)) {
5907 params.push_back(std::move(param));
5930 virtual void invalidate()
5935 parser::invalidate();
5954 _In_reads_or_z_(end)
const char* text,
5955 _In_
size_t start = 0,
5956 _In_
size_t end = (
size_t)-1,
5957 _In_
int flags = match_default)
5959 assert(text || start >= end);
6009 virtual void invalidate()
6015 parser::invalidate();
6029 http_protocol(_In_
const std::locale& locale = std::locale()) :
6035 _In_reads_or_z_(end)
const char* text,
6036 _In_
size_t start = 0,
6037 _In_
size_t end = (
size_t)-1,
6038 _In_
int flags = match_default)
6040 assert(text || start >= end);
6072 (uint16_t)strtoui(text + version_maj.
start, version_maj.
size(),
nullptr, 10) * 0x100 +
6073 (uint16_t)strtoui(text + version_min.
start, version_min.
size(),
nullptr, 10);
6086 version_min.
start = 1;
6087 version_min.
end = 0;
6088 version = (uint16_t)strtoui(text + version_maj.
start, version_maj.
size(),
nullptr, 10) * 0x100;
6103 version_maj.
start = 1;
6104 version_maj.
end = 0;
6105 version_min.
start = 1;
6106 version_min.
end = 0;
6113 virtual void invalidate()
6117 version_maj.
start = 1;
6118 version_maj.
end = 0;
6119 version_min.
start = 1;
6120 version_min.
end = 0;
6122 parser::invalidate();
6138 http_request(_In_
const std::locale& locale = std::locale()) :
6145 _In_reads_or_z_(end)
const char* text,
6146 _In_
size_t start = 0,
6147 _In_
size_t end = (
size_t)-1,
6148 _In_
int flags = match_default)
6150 assert(text || start >= end);
6154 if (m_line_break.match(text,
interval.
end, end, flags))
6167 if (m_line_break.match(text,
interval.
end, end, flags))
6183 if (m_line_break.match(text,
interval.
end, end, flags))
6199 protocol.invalidate();
6201 if (m_line_break.match(text,
interval.
end, end, flags)) {
6215 if (m_line_break.match(text,
interval.
end, end, flags)) {
6219 else if (protocol.match(text,
interval.
end, end, flags)) {
6228 if (m_line_break.match(text,
interval.
end, end, flags)) {
6246 protocol.invalidate();
6252 virtual void invalidate()
6257 protocol.invalidate();
6258 parser::invalidate();
6277 _In_reads_or_z_(end)
const char* text,
6278 _In_
size_t start = 0,
6279 _In_
size_t end = (
size_t)-1,
6280 _In_
int flags = match_default)
6282 assert(text || start >= end);
6285 if (m_line_break.match(text,
interval.
end, end, flags) ||
6290 if (m_line_break.match(text,
interval.
end, end, flags))
6297 if (m_line_break.match(text,
interval.
end, end, flags))
6327 value.
start = (size_t)-1;
6330 if (m_line_break.match(text,
interval.
end, end, flags)) {
6332 if (!m_line_break.match(text,
interval.
end, end, flags) &&
6362 virtual void invalidate()
6368 parser::invalidate();
6387 _In_reads_or_z_(end)
const char* text,
6388 _In_
size_t start = 0,
6389 _In_
size_t end = (
size_t)-1,
6390 _In_
int flags = match_default)
6392 while (start < end) {
6393 while (start < end && text[start] && isspace(text[start])) start++;
6394 if (start < end && text[start] ==
',') {
6396 while (start < end&& text[start] && isspace(text[start])) start++;
6399 if (el.match(text, start, end, flags)) {
6400 start = el.interval.end;
6401 T::insert(std::move(el));
6411 constexpr bool operator()(
const T& a,
const T& b)
const noexcept
6413 return a.factor.value > b.factor.value;
6420 template <
class T,
class _Alloc = std::allocator<T>>
6442 _In_
const std::locale& locale = std::locale()) :
6458 _In_reads_or_z_(end)
const T* text,
6459 _In_
size_t start = 0,
6460 _In_
size_t end = (
size_t)-1,
6461 _In_
int flags = match_default)
6463 assert(text || start >= end);
6465 if (m_quote->match(text,
interval.
end, end, flags)) {
6469 if (m_quote->match(text,
interval.
end, end, flags)) {
6474 if (m_escape->match(text,
interval.
end, end, flags)) {
6475 if (m_quote->match(text, m_escape->interval.end, end, flags)) {
6476 value +=
'"';
interval.
end = m_quote->interval.end;
6479 if (m_sol->match(text, m_escape->interval.end, end, flags)) {
6483 if (m_bs->match(text, m_escape->interval.end, end, flags)) {
6487 if (m_ff->match(text, m_escape->interval.end, end, flags)) {
6491 if (m_lf->match(text, m_escape->interval.end, end, flags)) {
6495 if (m_cr->match(text, m_escape->interval.end, end, flags)) {
6499 if (m_htab->match(text, m_escape->interval.end, end, flags)) {
6500 value +=
'\t';
interval.
end = m_htab->interval.end;
6504 m_uni->match(text, m_escape->interval.end, end, flags) &&
6505 m_hex->match(text, m_uni->interval.end, std::min(m_uni->interval.end + 4, end), flags | match_case_insensitive) &&
6506 m_hex->interval.size() == 4 )
6508 assert(m_hex->value <= 0xffff);
6509 if (
sizeof(T) == 1) {
6510 if (m_hex->value > 0x7ff) {
6511 value += (T)(0xe0 | (m_hex->value >> 12) & 0x0f);
6512 value += (T)(0x80 | (m_hex->value >> 6) & 0x3f);
6513 value += (T)(0x80 | m_hex->value & 0x3f);
6515 else if (m_hex->value > 0x7f) {
6516 value += (T)(0xc0 | (m_hex->value >> 6) & 0x1f);
6517 value += (T)(0x80 | m_hex->value & 0x3f);
6520 value += (T)(m_hex->value & 0x7f);
6523 value += (T)m_hex->value;
6527 if (m_escape->match(text, m_escape->interval.end, end, flags)) {
6528 value +=
'\\';
interval.
end = m_escape->interval.end;
6532 if (m_chr->match(text,
interval.
end, end, flags)) {
6533 value.Prilepi(text + m_chr->interval.start, m_chr->interval.size());
6545 virtual void invalidate()
6552 std::basic_string<T> value;
6555 std::shared_ptr<basic_parser<T>> m_quote;
6556 std::shared_ptr<basic_parser<T>> m_chr;
6557 std::shared_ptr<basic_parser<T>> m_escape;
6558 std::shared_ptr<basic_parser<T>> m_sol;
6559 std::shared_ptr<basic_parser<T>> m_bs;
6560 std::shared_ptr<basic_parser<T>> m_ff;
6561 std::shared_ptr<basic_parser<T>> m_lf;
6562 std::shared_ptr<basic_parser<T>> m_cr;
6563 std::shared_ptr<basic_parser<T>> m_htab;
6564 std::shared_ptr<basic_parser<T>> m_uni;
6565 std::shared_ptr<basic_integer16<T>> m_hex;
6578#undef ENUM_FLAG_OPERATOR
Test for angle in d°mm'ss.dddd form.
Definition parser.hpp:4392
Test for any code unit.
Definition parser.hpp:219
Test for beginning of line.
Definition parser.hpp:613
Test for any.
Definition parser.hpp:1055
Test for any code unit from a given string of code units.
Definition parser.hpp:718
Test for specific code unit.
Definition parser.hpp:289
Test for date.
Definition parser.hpp:4022
Test for valid DNS domain character.
Definition parser.hpp:2803
bool allow_on_edge
Is character allowed at the beginning or an end of a DNS domain?
Definition parser.hpp:2841
Test for DNS domain/hostname.
Definition parser.hpp:2903
bool m_allow_absolute
May DNS names end with a dot (absolute name)?
Definition parser.hpp:2967
Test for e-mail address.
Definition parser.hpp:3791
Test for emoticon.
Definition parser.hpp:3899
std::shared_ptr< basic_parser< T > > apex
apex/eyebrows/halo (e.g. O, 0)
Definition parser.hpp:3988
std::shared_ptr< basic_parser< T > > eyes
eyes (e.g. :, ;, >, |, B)
Definition parser.hpp:3989
std::shared_ptr< basic_set< T > > mouth
mouth (e.g. ), ), (, (, |, P, D, p, d)
Definition parser.hpp:3991
std::shared_ptr< basic_parser< T > > nose
nose (e.g. -, o)
Definition parser.hpp:3990
std::shared_ptr< basic_parser< T > > emoticon
emoticon as a whole (e.g. 😀, 🤔, 😶)
Definition parser.hpp:3987
Test for end of line.
Definition parser.hpp:651
Test for fraction.
Definition parser.hpp:1684
Test for decimal integer.
Definition parser.hpp:1293
Test for decimal integer possibly containing thousand separators.
Definition parser.hpp:1378
bool has_separators
Did integer have any separators?
Definition parser.hpp:1438
size_t digit_count
Total number of digits in integer.
Definition parser.hpp:1437
Test for hexadecimal integer.
Definition parser.hpp:1459
Base class for integer testing.
Definition parser.hpp:1271
size_t value
Calculated value of the numeral.
Definition parser.hpp:1285
Test for IPv4 address.
Definition parser.hpp:2343
stdex::interval< size_t > components[4]
Individual component intervals.
Definition parser.hpp:2458
struct in_addr value
IPv4 address value.
Definition parser.hpp:2459
Test for IPv6 address.
Definition parser.hpp:2562
std::shared_ptr< basic_parser< T > > scope_id
Scope ID (e.g. NIC index with link-local addresses)
Definition parser.hpp:2766
stdex::interval< size_t > components[8]
Individual component intervals.
Definition parser.hpp:2764
struct in6_addr value
IPv6 address value.
Definition parser.hpp:2765
Test for valid IPv6 address scope ID character.
Definition parser.hpp:2490
Test for repeating.
Definition parser.hpp:908
bool m_greedy
try to match as long sequence as possible
Definition parser.hpp:947
std::shared_ptr< basic_parser< T > > m_el
repeating element
Definition parser.hpp:944
size_t m_min_iterations
minimum number of iterations
Definition parser.hpp:945
size_t m_max_iterations
maximum number of iterations
Definition parser.hpp:946
Test for JSON string.
Definition parser.hpp:6428
Test for mixed numeral.
Definition parser.hpp:1919
std::shared_ptr< basic_parser< T > > fraction
fraction
Definition parser.hpp:2025
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2023
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2022
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2021
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2024
Test for monetary numeral.
Definition parser.hpp:2214
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2320
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2325
std::shared_ptr< basic_parser< T > > currency
Currency part.
Definition parser.hpp:2323
std::shared_ptr< basic_parser< T > > decimal
Decimal part.
Definition parser.hpp:2326
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2324
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2321
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2322
"No-op" match
Definition parser.hpp:187
Base template for all parsers.
Definition parser.hpp:68
interval< size_t > interval
Region of the last match.
Definition parser.hpp:167
Test for permutation.
Definition parser.hpp:1195
Test for phone number.
Definition parser.hpp:4515
std::basic_string< T > value
Normalized phone number.
Definition parser.hpp:4641
Test for any punctuation code unit.
Definition parser.hpp:461
Test for Roman numeral.
Definition parser.hpp:1568
Test for scientific numeral.
Definition parser.hpp:2045
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2189
std::shared_ptr< basic_parser< T > > exponent_symbol
Exponent symbol (e.g. 'e')
Definition parser.hpp:2193
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2187
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2188
double value
Calculated value of the numeral.
Definition parser.hpp:2197
std::shared_ptr< basic_parser< T > > negative_exp_sign
Negative exponent sign (e.g. '-')
Definition parser.hpp:2195
std::shared_ptr< basic_integer< T > > decimal
Decimal part.
Definition parser.hpp:2192
std::shared_ptr< basic_parser< T > > positive_exp_sign
Positive exponent sign (e.g. '+')
Definition parser.hpp:2194
std::shared_ptr< basic_integer< T > > exponent
Exponent part.
Definition parser.hpp:2196
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2191
std::shared_ptr< basic_integer< T > > integer
Integer part.
Definition parser.hpp:2190
Test for match score.
Definition parser.hpp:1747
Test for sequence.
Definition parser.hpp:1004
Definition parser.hpp:686
Test for signed numeral.
Definition parser.hpp:1833
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:1901
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:1900
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:1899
std::shared_ptr< basic_parser< T > > number
Number.
Definition parser.hpp:1902
Test for any space code unit.
Definition parser.hpp:382
Test for any space or punctuation code unit.
Definition parser.hpp:535
Test for any string.
Definition parser.hpp:1123
Test for given string.
Definition parser.hpp:813
Test for time.
Definition parser.hpp:4289
Test for valid URL password character.
Definition parser.hpp:3085
Test for valid URL path character.
Definition parser.hpp:3185
Test for URL path.
Definition parser.hpp:3293
Test for valid URL username character.
Definition parser.hpp:2986
Test for URL.
Definition parser.hpp:3434
Test for HTTP agent.
Definition parser.hpp:5951
Test for HTTP any type.
Definition parser.hpp:5073
Test for HTTP asterisk.
Definition parser.hpp:5715
Test for HTTP cookie parameter (RFC2109)
Definition parser.hpp:5810
Test for HTTP cookie (RFC2109)
Definition parser.hpp:5869
std::list< http_cookie_parameter > params
List of cookie parameters.
Definition parser.hpp:5941
http_token name
Cookie name.
Definition parser.hpp:5939
http_value value
Cookie value.
Definition parser.hpp:5940
Test for HTTP language (RFC1766)
Definition parser.hpp:5583
Test for HTTP line break (RFC2616: CRLF | LF)
Definition parser.hpp:4747
Test for HTTP parameter (RFC2616: parameter)
Definition parser.hpp:5018
http_token name
Parameter name.
Definition parser.hpp:5062
http_value value
Parameter value.
Definition parser.hpp:5063
Test for HTTP protocol.
Definition parser.hpp:6027
uint16_t version
HTTP protocol version: 0x100 = 1.0, 0x101 = 1.1...
Definition parser.hpp:6129
Test for HTTP quoted string (RFC2616: quoted-string)
Definition parser.hpp:4908
stdex::interval< size_t > content
String content (without quotes)
Definition parser.hpp:4964
Test for HTTP request.
Definition parser.hpp:6136
Test for HTTP space (RFC2616: LWS)
Definition parser.hpp:4783
Test for HTTP text character (RFC2616: TEXT)
Definition parser.hpp:4820
Test for HTTP token (RFC2616: token - tolerates non-ASCII)
Definition parser.hpp:4854
Test for HTTP URL parameter.
Definition parser.hpp:5400
Test for HTTP URL path segment.
Definition parser.hpp:5311
Test for HTTP URL path segment.
Definition parser.hpp:5344
std::vector< http_url_path_segment > segments
Path segments.
Definition parser.hpp:5393
Test for HTTP URL port.
Definition parser.hpp:5255
Test for HTTP URL server.
Definition parser.hpp:5218
Test for HTTP URL.
Definition parser.hpp:5481
Collection of HTTP values.
Definition parser.hpp:6384
Test for HTTP value (RFC2616: value)
Definition parser.hpp:4974
http_quoted_string string
Value when matched as quoted string.
Definition parser.hpp:5010
http_token token
Value when matched as token.
Definition parser.hpp:5011
Test for HTTP weight factor.
Definition parser.hpp:5646
float value
Calculated value of the weight factor.
Definition parser.hpp:5708
Test for HTTP weighted value.
Definition parser.hpp:5738
Base template for collection-holding parsers.
Definition parser.hpp:964
Test for any SGML code point.
Definition parser.hpp:251
Test for any SGML code point from a given string of SGML code points.
Definition parser.hpp:770
Test for specific SGML code point.
Definition parser.hpp:338
Test for valid DNS domain SGML character.
Definition parser.hpp:2859
Test for valid IPv6 address scope ID SGML character.
Definition parser.hpp:2528
Test for any SGML punctuation code point.
Definition parser.hpp:502
Test for any SGML space code point.
Definition parser.hpp:425
Test for any SGML space or punctuation code point.
Definition parser.hpp:578
Test for SGML given string.
Definition parser.hpp:860
Test for valid URL password SGML character.
Definition parser.hpp:3137
Test for valid URL path SGML character.
Definition parser.hpp:3241
Test for valid URL username SGML character.
Definition parser.hpp:3037
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:6410