10#include "interval.hpp"
24#include <netinet/in.h>
36#pragma warning(disable: 4100)
37#elif defined(__GNUC__)
38#pragma GCC diagnostic push
39#pragma GCC diagnostic ignored "-Wunknown-pragmas"
40#pragma GCC diagnostic ignored "-Wunused-parameter"
43#define ENUM_FLAG_OPERATOR(T,X) \
44inline 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)); } \
45inline 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); } \
46inline 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)); } \
47inline T& operator X= (T& lhs, const T rhs) { return lhs = lhs X rhs; } \
48inline T& operator X= (T& lhs, const std::underlying_type_t<T> rhs) { return lhs = lhs X rhs; }
49#define ENUM_FLAGS(T, type) \
51inline T operator ~ (T t) { return (T) (~static_cast<std::underlying_type_t <T>>(t)); } \
52ENUM_FLAG_OPERATOR(T,|) \
53ENUM_FLAG_OPERATOR(T,^) \
54ENUM_FLAG_OPERATOR(T,&) \
58#elif defined(__APPLE__)
59#define s6_words __u6_addr.__u6_addr16
61#define s6_words s6_addr16
71 constexpr int match_default = 0;
72 constexpr int match_case_insensitive = 0x1;
73 constexpr int match_multiline = 0x2;
86 _In_reads_or_z_opt_(end)
const T* text,
87 _In_
size_t start = 0,
88 _In_
size_t end = SIZE_MAX,
89 _In_
int flags = match_default)
91 for (
size_t i = start; i < end && text[i]; i++)
92 if (match(text, i, end, flags))
98 _In_reads_or_z_opt_(end)
const T* text,
99 _In_
size_t start = 0,
100 _In_
size_t end = SIZE_MAX,
101 _In_
int flags = match_default)
103 return do_match(text, start, end, flags);
107 _In_
const std::basic_string_view<T, std::char_traits<T>> text,
108 _In_
size_t start = 0,
109 _In_
size_t end = SIZE_MAX,
110 _In_
int flags = match_default)
112 return match(text.data(), start, std::min<size_t>(end, text.size()), flags);
115 virtual void invalidate()
123 virtual bool do_match(
124 _In_reads_or_z_opt_(end)
const T* text,
125 _In_
size_t start = 0,
126 _In_
size_t end = SIZE_MAX,
127 _In_
int flags = match_default) = 0;
130 template <
class T_out =
wchar_t>
131 const T_out* next_sgml_cp(_In_
const char* text, _In_
size_t start, _In_
size_t end, _Out_
size_t& chr_end, _Out_ T_out(&buf)[5])
133 if (text[start] ==
'&') {
135 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
136 for (chr_end = start + 1;; chr_end++) {
137 if (chr_end >= end || text[chr_end] == 0) {
141 if (text[chr_end] ==
';') {
144 size_t n = chr_end - start - 1;
145 auto entity_w = utf32_to_wstr(sgml2uni(text + start + 1, n, buf32), buf);
153 else if (text[chr_end] ==
'&' || ctype.is(ctype.space, text[chr_end])) {
159 buf[0] = text[start];
166 std::locale m_locale;
169 using parser = basic_parser<char>;
170 using wparser = basic_parser<wchar_t>;
172 using tparser = wparser;
174 using tparser = parser;
176 using sgml_parser = basic_parser<char>;
185 virtual bool do_match(
186 _In_reads_or_z_opt_(end)
const T* text,
187 _In_
size_t start = 0,
188 _In_
size_t end = SIZE_MAX,
189 _In_
int flags = match_default)
191 _Assume_(text || start >= end);
192 if (start < end && text[start]) {
193 this->interval.
start = this->interval.
end = start;
220 virtual bool do_match(
221 _In_reads_or_z_opt_(end)
const T* text,
222 _In_
size_t start = 0,
223 _In_
size_t end = SIZE_MAX,
224 _In_
int flags = match_default)
226 _Assume_(text || start >= end);
227 if (start < end && text[start]) {
228 this->interval.
end = (this->interval.
start = start) + 1;
253 virtual bool do_match(
254 _In_reads_or_z_(end)
const char* text,
255 _In_
size_t start = 0,
256 _In_
size_t end = SIZE_MAX,
257 _In_
int flags = match_default)
259 _Assume_(text || start >= end);
260 if (start < end && text[start]) {
261 if (text[start] ==
'&') {
263 const auto& ctype = std::use_facet<std::ctype<char>>(m_locale);
264 for (this->interval.
end = start + 1; this->interval.
end < end && text[this->interval.
end]; this->interval.
end++)
265 if (text[this->interval.
end] ==
';') {
266 this->interval.
end++;
267 this->interval.
start = start;
270 else if (text[this->interval.
end] ==
'&' || ctype.is(ctype.space, text[this->interval.end]))
274 this->interval.
end = (this->interval.
start = start) + 1;
289 basic_cu(T chr,
bool invert =
false, _In_
const std::locale&
locale = std::locale()) :
296 virtual bool do_match(
297 _In_reads_or_z_opt_(end)
const T* text,
298 _In_
size_t start = 0,
299 _In_
size_t end = SIZE_MAX,
300 _In_
int flags = match_default)
302 _Assume_(text || start >= end);
303 if (start < end && text[start]) {
305 if (flags & match_case_insensitive) {
306 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
307 r = ctype.tolower(text[start]) == ctype.tolower(m_chr);
310 r = text[start] == m_chr;
311 if ((r && !m_invert) || (!r && m_invert)) {
312 this->interval.
end = (this->interval.
start = start) + 1;
338 sgml_cp(
const char* chr,
size_t count = SIZE_MAX,
bool invert =
false, _In_
const std::locale&
locale = std::locale()) :
342 _Assume_(chr || !count);
345 m_chr.assign(count ? next_sgml_cp(chr, 0, count, chr_end, buf) : L
"");
349 virtual bool do_match(
350 _In_reads_or_z_(end)
const char* text,
351 _In_
size_t start = 0,
352 _In_
size_t end = SIZE_MAX,
353 _In_
int flags = match_default)
355 _Assume_(text || start >= end);
356 if (start < end && text[start]) {
358 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.
end, buf);
359 bool r = ((flags & match_case_insensitive) ?
360 stdex::strnicmp(chr, stdex::strlen(chr), m_chr.data(), m_chr.size(), m_locale) :
361 stdex::strncmp(chr, stdex::strlen(chr), m_chr.data(), m_chr.size())) == 0;
362 if ((r && !m_invert) || (!r && m_invert)) {
363 this->interval.
start = start;
388 virtual bool do_match(
389 _In_reads_or_z_opt_(end)
const T* text,
390 _In_
size_t start = 0,
391 _In_
size_t end = SIZE_MAX,
392 _In_
int flags = match_default)
394 _Assume_(text || start >= end);
395 if (start < end && text[start]) {
397 ((flags & match_multiline) || !stdex::islbreak(text[start])) &&
398 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::space, text[start]);
399 if ((r && !m_invert) || (!r && m_invert)) {
400 this->interval.
end = (this->interval.
start = start) + 1;
430 virtual bool do_match(
431 _In_reads_or_z_(end)
const char* text,
432 _In_
size_t start = 0,
433 _In_
size_t end = SIZE_MAX,
434 _In_
int flags = match_default)
436 _Assume_(text || start >= end);
437 if (start < end && text[start]) {
439 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.
end, buf);
440 const wchar_t* chr_end = chr + stdex::strlen(chr);
442 ((flags & match_multiline) || !stdex::islbreak(chr, SIZE_MAX)) &&
443 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space, chr, chr_end) == chr_end;
444 if ((r && !m_invert) || (!r && m_invert)) {
445 this->interval.
start = start;
468 virtual bool do_match(
469 _In_reads_or_z_opt_(end)
const T* text,
470 _In_
size_t start = 0,
471 _In_
size_t end = SIZE_MAX,
472 _In_
int flags = match_default)
474 _Assume_(text || start >= end);
475 if (start < end && text[start]) {
476 bool r = std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::punct, text[start]);
477 if ((r && !m_invert) || (!r && m_invert)) {
478 this->interval.
end = (this->interval.
start = start) + 1;
508 virtual bool do_match(
509 _In_reads_or_z_(end)
const char* text,
510 _In_
size_t start = 0,
511 _In_
size_t end = SIZE_MAX,
512 _In_
int flags = match_default)
514 _Assume_(text || start >= end);
515 if (start < end && text[start]) {
517 const wchar_t* chr = next_sgml_cp(text, start, end, this->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)) {
521 this->interval.
start = start;
543 virtual bool do_match(
544 _In_reads_or_z_opt_(end)
const T* text,
545 _In_
size_t start = 0,
546 _In_
size_t end = SIZE_MAX,
547 _In_
int flags = match_default)
549 _Assume_(text || start >= end);
550 if (start < end && text[start]) {
552 ((flags & match_multiline) || !stdex::islbreak(text[start])) &&
553 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::space | std::ctype_base::punct, text[start]);
554 if ((r && !m_invert) || (!r && m_invert)) {
555 this->interval.
end = (this->interval.
start = start) + 1;
585 virtual bool do_match(
586 _In_reads_or_z_(end)
const char* text,
587 _In_
size_t start = 0,
588 _In_
size_t end = SIZE_MAX,
589 _In_
int flags = match_default)
591 _Assume_(text || start >= end);
592 if (start < end && text[start]) {
594 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.
end, buf);
595 const wchar_t* chr_end = chr + stdex::strlen(chr);
597 ((flags & match_multiline) || !stdex::islbreak(chr, SIZE_MAX)) &&
598 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space | std::ctype_base::punct, chr, chr_end) == chr_end;
599 if ((r && !m_invert) || (!r && m_invert)) {
600 this->interval.
start = start;
616 basic_bol(
bool invert =
false) : m_invert(invert) {}
619 virtual bool do_match(
620 _In_reads_or_z_opt_(end)
const T* text,
621 _In_
size_t start = 0,
622 _In_
size_t end = SIZE_MAX,
623 _In_
int flags = match_default)
625 _Assume_(text || !end);
626 _Assume_(text || start >= end);
627 bool r = start == 0 || (start <= end && stdex::islbreak(text[start - 1]));
628 if ((r && !m_invert) || (!r && m_invert)) {
629 this->interval.
end = this->interval.
start = start;
655 basic_eol(
bool invert =
false) : m_invert(invert) {}
658 virtual bool do_match(
659 _In_reads_or_z_opt_(end)
const T* text,
660 _In_
size_t start = 0,
661 _In_
size_t end = SIZE_MAX,
662 _In_
int flags = match_default)
664 _Assume_(text || start >= end);
665 bool r = start >= end || !text[start] || stdex::islbreak(text[start]);
666 if ((r && !m_invert) || (!r && m_invert)) {
667 this->interval.
end = this->interval.
start = start;
690 basic_set(
bool invert =
false, _In_
const std::locale&
locale = std::locale()) :
692 hit_offset(SIZE_MAX),
696 virtual void invalidate()
698 hit_offset = SIZE_MAX;
705 virtual bool do_match(
706 _In_reads_or_z_opt_(end)
const T* text,
707 _In_
size_t start = 0,
708 _In_
size_t end = SIZE_MAX,
709 _In_
int flags = match_default) = 0;
722 _In_reads_or_z_(count)
const T* set,
723 _In_
size_t count = SIZE_MAX,
724 _In_
bool invert =
false,
725 _In_
const std::locale&
locale = std::locale()) :
729 m_set.assign(set, set + stdex::strnlen(set, count));
733 virtual bool do_match(
734 _In_reads_or_z_opt_(end)
const T* text,
735 _In_
size_t start = 0,
736 _In_
size_t end = SIZE_MAX,
737 _In_
int flags = match_default)
739 _Assume_(text || start >= end);
740 if (start < end && text[start]) {
741 const T* set = m_set.data();
742 size_t r = (flags & match_case_insensitive) ?
743 stdex::strnichr(set, m_set.size(), text[start], this->m_locale) :
744 stdex::strnchr(set, m_set.size(), text[start]);
745 if ((r != stdex::npos && !this->m_invert) || (r == stdex::npos && this->m_invert)) {
746 this->hit_offset = r;
747 this->interval.
end = (this->interval.
start = start) + 1;
751 this->hit_offset = SIZE_MAX;
756 std::basic_string<T> m_set;
773 sgml_cp_set(
const char* set,
size_t count = SIZE_MAX,
bool invert =
false, _In_
const std::locale&
locale = std::locale()) :
777 m_set = sgml2str(set, count);
781 virtual bool do_match(
782 _In_reads_or_z_(end)
const char* text,
783 _In_
size_t start = 0,
784 _In_
size_t end = SIZE_MAX,
785 _In_
int flags = match_default)
787 _Assume_(text || start >= end);
788 if (start < end && text[start]) {
790 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.
end, buf);
791 const wchar_t* set = m_set.data();
792 size_t r = (flags & match_case_insensitive) ?
793 stdex::strnistr(set, m_set.size(), chr, m_locale) :
794 stdex::strnstr(set, m_set.size(), chr);
795 if ((r != stdex::npos && !m_invert) || (r == stdex::npos && m_invert)) {
797 this->interval.
start = start;
801 hit_offset = SIZE_MAX;
817 _In_reads_or_z_(count)
const T* str,
818 _In_
size_t count = SIZE_MAX,
819 _In_
const std::locale&
locale = std::locale()) :
821 m_str(str, str + stdex::strnlen(str, count))
825 virtual bool do_match(
826 _In_reads_or_z_opt_(end)
const T* text,
827 _In_
size_t start = 0,
828 _In_
size_t end = SIZE_MAX,
829 _In_
int flags = match_default)
831 _Assume_(text || start >= end);
834 n = std::min<size_t>(end - start, m);
835 bool r = ((flags & match_case_insensitive) ?
836 stdex::strnicmp(text + start, n, m_str.data(), m, this->m_locale) :
837 stdex::strncmp(text + start, n, m_str.data(), m)) == 0;
839 this->interval.
end = (this->interval.
start = start) + n;
846 std::basic_string<T> m_str;
863 sgml_string(
const char* str,
size_t count = SIZE_MAX, _In_
const std::locale&
locale = std::locale()) :
865 m_str(sgml2str(str, count))
869 virtual bool do_match(
870 _In_reads_or_z_(end)
const char* text,
871 _In_
size_t start = 0,
872 _In_
size_t end = SIZE_MAX,
873 _In_
int flags = match_default)
875 _Assume_(text || start >= end);
876 const wchar_t* str = m_str.data();
877 const bool case_insensitive = flags & match_case_insensitive ? true :
false;
878 const auto& ctype = std::use_facet<std::ctype<wchar_t>>(m_locale);
879 for (this->interval.
end = start;;) {
881 this->interval.
start = start;
884 if (this->interval.
end >= end || !text[this->interval.end]) {
889 const wchar_t* chr = next_sgml_cp(text, this->interval.
end, end, this->interval.end, buf);
890 for (; *chr; ++str, ++chr) {
892 (case_insensitive ? ctype.tolower(*str) != ctype.tolower(*chr) : *str != *chr))
919 virtual bool do_match(
920 _In_reads_or_z_opt_(end)
const T* text,
921 _In_
size_t start = 0,
922 _In_
size_t end = SIZE_MAX,
923 _In_
int flags = match_default)
925 _Assume_(text || start >= end);
926 this->interval.
start = this->interval.
end = start;
927 for (
size_t i = 0; ; i++) {
930 if (!
m_el->match(text, this->interval.end, end, flags)) {
935 if (
m_el->interval.end == this->interval.end) {
939 this->interval.
end =
m_el->interval.end;
945 std::shared_ptr<basic_parser<T>>
m_el;
973 _In_
const std::locale&
locale = std::locale()) :
976 _Assume_(el || !count);
977 m_collection.reserve(count);
978 for (
size_t i = 0; i < count; i++)
979 m_collection.push_back(el[i]);
984 _In_
const std::locale&
locale = std::locale()) :
986 m_collection(std::move(collection))
989 virtual void invalidate()
991 for (
auto& el : m_collection)
997 std::vector<std::shared_ptr<basic_parser<T>>> m_collection;
1008 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1009 _In_
size_t count = 0,
1010 _In_
const std::locale&
locale = std::locale()) :
1016 _In_
const std::locale&
locale = std::locale()) :
1021 virtual bool do_match(
1022 _In_reads_or_z_opt_(end)
const T* text,
1023 _In_
size_t start = 0,
1024 _In_
size_t end = SIZE_MAX,
1025 _In_
int flags = match_default)
1027 _Assume_(text || start >= end);
1028 this->interval.
end = start;
1029 for (
auto i = this->m_collection.begin(); i != this->m_collection.end(); ++i) {
1030 if (!(*i)->match(text, this->interval.end, end, flags)) {
1031 for (++i; i != this->m_collection.end(); ++i)
1036 this->interval.
end = (*i)->interval.end;
1038 this->interval.
start = start;
1061 hit_offset(SIZE_MAX)
1066 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1067 _In_
size_t count = 0,
1068 _In_
const std::locale&
locale = std::locale()) :
1070 hit_offset(SIZE_MAX)
1075 _In_
const std::locale&
locale = std::locale()) :
1077 hit_offset(SIZE_MAX)
1080 virtual void invalidate()
1082 hit_offset = SIZE_MAX;
1089 virtual bool do_match(
1090 _In_reads_or_z_opt_(end)
const T* text,
1091 _In_
size_t start = 0,
1092 _In_
size_t end = SIZE_MAX,
1093 _In_
int flags = match_default)
1095 _Assume_(text || start >= end);
1097 for (
auto i = this->m_collection.begin(); i != this->m_collection.end(); ++i, ++hit_offset) {
1098 if ((*i)->match(text, start, end, flags)) {
1100 for (++i; i != this->m_collection.end(); ++i)
1105 hit_offset = SIZE_MAX;
1123 template <
class T,
class T_parser = basic_
string<T>>
1128 _In_reads_(count)
const T* str_z =
nullptr,
1129 _In_
size_t count = 0,
1130 _In_
const std::locale&
locale = std::locale()) :
1133 build(str_z, count);
1140 va_start(params, str);
1149 va_start(params, str);
1155 void build(_In_reads_(count)
const T* str_z, _In_
size_t count)
1157 _Assume_(str_z || !count);
1162 offset < count && str_z[offset];
1163 offset += stdex::strnlen(str_z + offset, count - offset) + 1, ++n);
1164 this->m_collection.reserve(n);
1167 offset < count && str_z[offset];
1168 offset += stdex::strnlen(str_z + offset, count - offset) + 1)
1169 this->m_collection.push_back(std::move(std::make_shared<T_parser>(str_z + offset, count - offset, this->m_locale)));
1173 void build(_In_z_
const T* str, _In_ va_list params)
1177 this->m_collection.push_back(std::move(std::make_shared<T_parser>(str, SIZE_MAX, this->m_locale)));
1178 (p = va_arg(params,
const T*)) !=
nullptr;
1179 this->m_collection.push_back(std::move(std::make_shared<T_parser>(p, SIZE_MAX, this->m_locale))));
1200 _In_count_(count)
const std::shared_ptr<
basic_parser<T>>* el =
nullptr,
1201 _In_
size_t count = 0,
1202 _In_
const std::locale&
locale = std::locale()) :
1208 _In_
const std::locale&
locale = std::locale()) :
1213 virtual bool do_match(
1214 _In_reads_or_z_opt_(end)
const T* text,
1215 _In_
size_t start = 0,
1216 _In_
size_t end = SIZE_MAX,
1217 _In_
int flags = match_default)
1219 _Assume_(text || start >= end);
1220 for (
auto& el : this->m_collection)
1222 if (match_recursively(text, start, end, flags)) {
1223 this->interval.
start = start;
1230 bool match_recursively(
1231 _In_reads_or_z_opt_(end)
const T* text,
1232 _In_
size_t start = 0,
1233 _In_
size_t end = SIZE_MAX,
1234 _In_
int flags = match_default)
1236 bool all_matched =
true;
1237 for (
auto& el : this->m_collection) {
1238 if (!el->interval) {
1240 all_matched =
false;
1241 if (el->match(text, start, end, flags)) {
1243 if (match_recursively(text, el->interval.end, end, flags)) {
1252 this->interval.
end = start;
1280 virtual void invalidate()
1308 _In_
const std::locale&
locale = std::locale()) :
1323 virtual bool do_match(
1324 _In_reads_or_z_opt_(end)
const T* text,
1325 _In_
size_t start = 0,
1326 _In_
size_t end = SIZE_MAX,
1327 _In_
int flags = match_default)
1329 _Assume_(text || start >= end);
1330 for (this->interval.
end = start, this->value = 0; this->interval.
end < end && text[this->interval.
end];) {
1332 if (m_digit_0->match(text, this->interval.end, end, flags)) { dig = 0; this->interval.
end = m_digit_0->interval.end; }
1333 else if (m_digit_1->match(text, this->interval.end, end, flags)) { dig = 1; this->interval.
end = m_digit_1->interval.end; }
1334 else if (m_digit_2->match(text, this->interval.end, end, flags)) { dig = 2; this->interval.
end = m_digit_2->interval.end; }
1335 else if (m_digit_3->match(text, this->interval.end, end, flags)) { dig = 3; this->interval.
end = m_digit_3->interval.end; }
1336 else if (m_digit_4->match(text, this->interval.end, end, flags)) { dig = 4; this->interval.
end = m_digit_4->interval.end; }
1337 else if (m_digit_5->match(text, this->interval.end, end, flags)) { dig = 5; this->interval.
end = m_digit_5->interval.end; }
1338 else if (m_digit_6->match(text, this->interval.end, end, flags)) { dig = 6; this->interval.
end = m_digit_6->interval.end; }
1339 else if (m_digit_7->match(text, this->interval.end, end, flags)) { dig = 7; this->interval.
end = m_digit_7->interval.end; }
1340 else if (m_digit_8->match(text, this->interval.end, end, flags)) { dig = 8; this->interval.
end = m_digit_8->interval.end; }
1341 else if (m_digit_9->match(text, this->interval.end, end, flags)) { dig = 9; this->interval.
end = m_digit_9->interval.end; }
1346 this->interval.
start = start;
1353 std::shared_ptr<basic_parser<T>>
1385 _In_
const std::locale&
locale = std::locale()) :
1390 m_separator(separator)
1393 virtual void invalidate()
1404 virtual bool do_match(
1405 _In_reads_or_z_opt_(end)
const T* text,
1406 _In_
size_t start = 0,
1407 _In_
size_t end = SIZE_MAX,
1408 _In_
int flags = match_default)
1410 _Assume_(text || start >= end);
1411 if (m_digits->match(text, start, end, flags)) {
1413 this->
value = m_digits->value;
1416 this->interval.
start = start;
1417 this->interval.
end = m_digits->interval.end;
1418 if (m_digits->interval.size() <= 3) {
1420 size_t hit_offset = SIZE_MAX;
1421 while (m_separator->match(text, this->interval.end, end, flags) &&
1422 (hit_offset == SIZE_MAX || hit_offset == m_separator->hit_offset) &&
1423 m_digits->match(text, m_separator->interval.end, end, flags) &&
1424 m_digits->interval.size() == 3)
1427 this->
value = this->
value * 1000 + m_digits->value;
1430 this->interval.
end = m_digits->interval.end;
1431 hit_offset = m_separator->hit_offset;
1442 std::shared_ptr<basic_integer10<T>> m_digits;
1443 std::shared_ptr<basic_set<T>> m_separator;
1446 using integer10ts = basic_integer10ts<char>;
1447 using winteger10ts = basic_integer10ts<wchar_t>;
1449 using tinteger10ts = winteger10ts;
1451 using tinteger10ts = integer10ts;
1453 using sgml_integer10ts = basic_integer10ts<char>;
1479 _In_
const std::locale&
locale = std::locale()) :
1491 m_digit_10(digit_10),
1492 m_digit_11(digit_11),
1493 m_digit_12(digit_12),
1494 m_digit_13(digit_13),
1495 m_digit_14(digit_14),
1496 m_digit_15(digit_15)
1500 virtual bool do_match(
1501 _In_reads_or_z_opt_(end)
const T* text,
1502 _In_
size_t start = 0,
1503 _In_
size_t end = SIZE_MAX,
1504 _In_
int flags = match_default)
1506 _Assume_(text || start >= end);
1507 for (this->interval.
end = start, this->value = 0; this->interval.
end < end && text[this->interval.
end];) {
1509 if (m_digit_0->match(text, this->interval.end, end, flags)) { dig = 0; this->interval.
end = m_digit_0->interval.end; }
1510 else if (m_digit_1->match(text, this->interval.end, end, flags)) { dig = 1; this->interval.
end = m_digit_1->interval.end; }
1511 else if (m_digit_2->match(text, this->interval.end, end, flags)) { dig = 2; this->interval.
end = m_digit_2->interval.end; }
1512 else if (m_digit_3->match(text, this->interval.end, end, flags)) { dig = 3; this->interval.
end = m_digit_3->interval.end; }
1513 else if (m_digit_4->match(text, this->interval.end, end, flags)) { dig = 4; this->interval.
end = m_digit_4->interval.end; }
1514 else if (m_digit_5->match(text, this->interval.end, end, flags)) { dig = 5; this->interval.
end = m_digit_5->interval.end; }
1515 else if (m_digit_6->match(text, this->interval.end, end, flags)) { dig = 6; this->interval.
end = m_digit_6->interval.end; }
1516 else if (m_digit_7->match(text, this->interval.end, end, flags)) { dig = 7; this->interval.
end = m_digit_7->interval.end; }
1517 else if (m_digit_8->match(text, this->interval.end, end, flags)) { dig = 8; this->interval.
end = m_digit_8->interval.end; }
1518 else if (m_digit_9->match(text, this->interval.end, end, flags)) { dig = 9; this->interval.
end = m_digit_9->interval.end; }
1519 else if (m_digit_10->match(text, this->interval.end, end, flags)) { dig = 10; this->interval.
end = m_digit_10->interval.end; }
1520 else if (m_digit_11->match(text, this->interval.end, end, flags)) { dig = 11; this->interval.
end = m_digit_11->interval.end; }
1521 else if (m_digit_12->match(text, this->interval.end, end, flags)) { dig = 12; this->interval.
end = m_digit_12->interval.end; }
1522 else if (m_digit_13->match(text, this->interval.end, end, flags)) { dig = 13; this->interval.
end = m_digit_13->interval.end; }
1523 else if (m_digit_14->match(text, this->interval.end, end, flags)) { dig = 14; this->interval.
end = m_digit_14->interval.end; }
1524 else if (m_digit_15->match(text, this->interval.end, end, flags)) { dig = 15; this->interval.
end = m_digit_15->interval.end; }
1529 this->interval.
start = start;
1536 std::shared_ptr<basic_parser<T>>
1581 _In_
const std::locale&
locale = std::locale()) :
1585 m_digit_10(digit_10),
1586 m_digit_50(digit_50),
1587 m_digit_100(digit_100),
1588 m_digit_500(digit_500),
1589 m_digit_1000(digit_1000),
1590 m_digit_5000(digit_5000),
1591 m_digit_10000(digit_10000)
1595 virtual bool do_match(
1596 _In_reads_or_z_opt_(end)
const T* text,
1597 _In_
size_t start = 0,
1598 _In_
size_t end = SIZE_MAX,
1599 _In_
int flags = match_default)
1601 _Assume_(text || start >= end);
1603 dig[5] = { SIZE_MAX, SIZE_MAX, SIZE_MAX, SIZE_MAX, SIZE_MAX },
1606 for (this->interval.
end = start, this->value = 0; this->interval.
end < end && text[this->interval.
end]; dig[3] = dig[2], dig[2] = dig[1], dig[1] = dig[0], this->interval.
end = end2) {
1607 if (m_digit_1 && m_digit_1->match(text, this->interval.end, end, flags)) { dig[0] = 1; end2 = m_digit_1->interval.end; }
1608 else if (m_digit_5 && m_digit_5->match(text, this->interval.end, end, flags)) { dig[0] = 5; end2 = m_digit_5->interval.end; }
1609 else if (m_digit_10 && m_digit_10->match(text, this->interval.end, end, flags)) { dig[0] = 10; end2 = m_digit_10->interval.end; }
1610 else if (m_digit_50 && m_digit_50->match(text, this->interval.end, end, flags)) { dig[0] = 50; end2 = m_digit_50->interval.end; }
1611 else if (m_digit_100 && m_digit_100->match(text, this->interval.end, end, flags)) { dig[0] = 100; end2 = m_digit_100->interval.end; }
1612 else if (m_digit_500 && m_digit_500->match(text, this->interval.end, end, flags)) { dig[0] = 500; end2 = m_digit_500->interval.end; }
1613 else if (m_digit_1000 && m_digit_1000->match(text, this->interval.end, end, flags)) { dig[0] = 1000; end2 = m_digit_1000->interval.end; }
1614 else if (m_digit_5000 && m_digit_5000->match(text, this->interval.end, end, flags)) { dig[0] = 5000; end2 = m_digit_5000->interval.end; }
1615 else if (m_digit_10000 && m_digit_10000->match(text, this->interval.end, end, flags)) { dig[0] = 10000; end2 = m_digit_10000->interval.end; }
1619 if (dig[4] == SIZE_MAX) dig[4] = dig[0];
1621 if (dig[3] == dig[2] && dig[2] == dig[1] && dig[1] == dig[0] && dig[0] != dig[4]) {
1625 if (dig[0] <= dig[1]) {
1627 this->
value += dig[0];
1630 (dig[1] == 1 && (dig[0] == 5 || dig[0] == 10)) ||
1631 (dig[1] == 10 && (dig[0] == 50 || dig[0] == 100)) ||
1632 (dig[1] == 100 && (dig[0] == 500 || dig[0] == 1000)) ||
1633 (dig[1] == 1000 && (dig[0] == 5000 || dig[0] == 10000)))
1636 if (dig[2] < dig[0]) {
1640 this->
value -= dig[1];
1644 this->
value += dig[0];
1652 this->interval.
start = start;
1659 std::shared_ptr<basic_parser<T>>
1691 _In_
const std::locale&
locale = std::locale()) :
1693 numerator(_numerator),
1694 fraction_line(_fraction_line),
1695 denominator(_denominator)
1698 virtual void invalidate()
1700 numerator->invalidate();
1701 fraction_line->invalidate();
1702 denominator->invalidate();
1706 std::shared_ptr<basic_parser<T>> numerator;
1707 std::shared_ptr<basic_parser<T>> fraction_line;
1708 std::shared_ptr<basic_parser<T>> denominator;
1711 virtual bool do_match(
1712 _In_reads_or_z_opt_(end)
const T* text,
1713 _In_
size_t start = 0,
1714 _In_
size_t end = SIZE_MAX,
1715 _In_
int flags = match_default)
1717 _Assume_(text || start >= end);
1718 if (numerator->match(text, start, end, flags) &&
1719 fraction_line->match(text, numerator->interval.end, end, flags) &&
1720 denominator->match(text, fraction_line->interval.end, end, flags))
1722 this->interval.
start = start;
1723 this->interval.
end = denominator->interval.end;
1726 numerator->invalidate();
1727 fraction_line->invalidate();
1728 denominator->invalidate();
1755 _In_
const std::locale&
locale = std::locale()) :
1758 separator(_separator),
1763 virtual void invalidate()
1766 separator->invalidate();
1767 guest->invalidate();
1771 std::shared_ptr<basic_parser<T>> home;
1772 std::shared_ptr<basic_parser<T>> separator;
1773 std::shared_ptr<basic_parser<T>> guest;
1776 virtual bool do_match(
1777 _In_reads_or_z_opt_(end)
const T* text,
1778 _In_
size_t start = 0,
1779 _In_
size_t end = SIZE_MAX,
1780 _In_
int flags = match_default)
1782 _Assume_(text || start >= end);
1783 this->interval.
end = start;
1785 const int space_match_flags = flags & ~match_multiline;
1787 if (home->match(text, this->interval.end, end, flags))
1788 this->interval.
end = home->interval.end;
1792 for (; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
1794 if (separator->match(text, this->interval.end, end, flags))
1795 this->interval.
end = separator->interval.end;
1799 for (; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
1801 if (guest->match(text, this->interval.end, end, flags))
1802 this->interval.
end = guest->interval.end;
1806 this->interval.
start = start;
1811 separator->invalidate();
1812 guest->invalidate();
1817 std::shared_ptr<basic_parser<T>> m_space;
1841 _In_
const std::locale&
locale = std::locale()) :
1849 virtual void invalidate()
1864 virtual bool do_match(
1865 _In_reads_or_z_opt_(end)
const T* text,
1866 _In_
size_t start = 0,
1867 _In_
size_t end = SIZE_MAX,
1868 _In_
int flags = match_default)
1870 _Assume_(text || start >= end);
1871 this->interval.
end = start;
1892 if (
number->match(text, this->interval.end, end, flags)) {
1893 this->interval.
start = start;
1894 this->interval.
end =
number->interval.end;
1906 using signed_numeral = basic_signed_numeral<char>;
1907 using wsigned_numeral = basic_signed_numeral<wchar_t>;
1909 using tsigned_numeral = wsigned_numeral;
1911 using tsigned_numeral = signed_numeral;
1913 using sgml_signed_numeral = basic_signed_numeral<char>;
1929 _In_
const std::locale&
locale = std::locale()) :
1939 virtual void invalidate()
1956 virtual bool do_match(
1957 _In_reads_or_z_opt_(end)
const T* text,
1958 _In_
size_t start = 0,
1959 _In_
size_t end = SIZE_MAX,
1960 _In_
int flags = match_default)
1962 _Assume_(text || start >= end);
1963 this->interval.
end = start;
1987 const int space_match_flags = flags & ~match_multiline;
1988 if (
integer->match(text, this->interval.end, end, flags) &&
1989 m_space->match(text,
integer->interval.end, end, space_match_flags))
1991 for (this->interval.
end = m_space->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
1992 if (
fraction->match(text, this->interval.end, end, flags)) {
1993 this->interval.
start = start;
1998 this->interval.
start = start;
2004 if (
fraction->match(text, this->interval.end, end, flags)) {
2006 this->interval.
start = start;
2012 if (
integer->match(text, this->interval.end, end, flags)) {
2014 this->interval.
start = start;
2028 std::shared_ptr<basic_parser<T>> m_space;
2031 using mixed_numeral = basic_mixed_numeral<char>;
2032 using wmixed_numeral = basic_mixed_numeral<wchar_t>;
2034 using tmixed_numeral = wmixed_numeral;
2036 using tmixed_numeral = mixed_numeral;
2038 using sgml_mixed_numeral = basic_mixed_numeral<char>;
2058 _In_
const std::locale&
locale = std::locale()) :
2070 value(std::numeric_limits<double>::quiet_NaN())
2073 virtual void invalidate()
2085 value = std::numeric_limits<double>::quiet_NaN();
2102 virtual bool do_match(
2103 _In_reads_or_z_opt_(end)
const T* text,
2104 _In_
size_t start = 0,
2105 _In_
size_t end = SIZE_MAX,
2106 _In_
int flags = match_default)
2108 _Assume_(text || start >= end);
2109 this->interval.
end = start;
2132 if (
integer->match(text, this->interval.end, end, flags))
2143 if (
integer->interval.empty() &&
2189 double e = (double)
exponent->value;
2192 value *= pow(10.0, e);
2195 this->interval.
start = start;
2200 using scientific_numeral = basic_scientific_numeral<char>;
2201 using wscientific_numeral = basic_scientific_numeral<wchar_t>;
2203 using tscientific_numeral = wscientific_numeral;
2205 using tscientific_numeral = scientific_numeral;
2207 using sgml_scientific_numeral = basic_scientific_numeral<char>;
2224 _In_
const std::locale&
locale = std::locale()) :
2235 virtual void invalidate()
2256 virtual bool do_match(
2257 _In_reads_or_z_opt_(end)
const T* text,
2258 _In_
size_t start = 0,
2259 _In_
size_t end = SIZE_MAX,
2260 _In_
int flags = match_default)
2262 _Assume_(text || start >= end);
2263 this->interval.
end = start;
2265 if (
positive_sign->match(text, this->interval.end, end, flags)) {
2270 else if (
negative_sign->match(text, this->interval.end, end, flags)) {
2275 else if (
special_sign->match(text, this->interval.end, end, flags)) {
2286 if (
currency->match(text, this->interval.end, end, flags))
2299 if (
integer->match(text, this->interval.end, end, flags))
2309 if (
integer->interval.empty() &&
2324 this->interval.
start = start;
2329 using monetary_numeral = basic_monetary_numeral<char>;
2330 using wmonetary_numeral = basic_monetary_numeral<wchar_t>;
2332 using tmonetary_numeral = wmonetary_numeral;
2334 using tmonetary_numeral = monetary_numeral;
2336 using sgml_monetary_numeral = basic_monetary_numeral<char>;
2357 _In_
const std::locale&
locale = std::locale()) :
2369 m_separator(separator)
2374 virtual void invalidate()
2392 virtual bool do_match(
2393 _In_reads_or_z_opt_(end)
const T* text,
2394 _In_
size_t start = 0,
2395 _In_
size_t end = SIZE_MAX,
2396 _In_
int flags = match_default)
2398 _Assume_(text || start >= end);
2399 this->interval.
end = start;
2403 for (i = 0; i < 4; i++) {
2405 if (m_separator->match(text, this->interval.end, end, flags))
2406 this->interval.
end = m_separator->interval.end;
2412 bool is_empty =
true;
2414 for (x = 0; this->interval.
end < end && text[this->interval.
end];) {
2415 size_t dig, digit_end;
2416 if (m_digit_0->match(text, this->interval.end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
2417 else if (m_digit_1->match(text, this->interval.end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
2418 else if (m_digit_2->match(text, this->interval.end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
2419 else if (m_digit_3->match(text, this->interval.end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
2420 else if (m_digit_4->match(text, this->interval.end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
2421 else if (m_digit_5->match(text, this->interval.end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
2422 else if (m_digit_6->match(text, this->interval.end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
2423 else if (m_digit_7->match(text, this->interval.end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
2424 else if (m_digit_8->match(text, this->interval.end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
2425 else if (m_digit_9->match(text, this->interval.end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
2427 size_t x_n = x * 10 + dig;
2430 this->interval.
end = digit_end;
2439 value.s_addr = (
value.s_addr << 8) | (uint8_t)x;
2444 HE2BE(
reinterpret_cast<uint32_t&
>(
value.s_addr));
2445 this->interval.
start = start;
2453 std::shared_ptr<basic_parser<T>>
2464 std::shared_ptr<basic_parser<T>> m_separator;
2467 using ipv4_address = basic_ipv4_address<char>;
2468 using wipv4_address = basic_ipv4_address<wchar_t>;
2470 using tipv4_address = wipv4_address;
2472 using tipv4_address = ipv4_address;
2474 using sgml_ipv4_address = basic_ipv4_address<char>;
2486 virtual bool do_match(
2487 _In_reads_or_z_opt_(end)
const T* text,
2488 _In_
size_t start = 0,
2489 _In_
size_t end = SIZE_MAX,
2490 _In_
int flags = match_default)
2492 _Assume_(text || start >= end);
2493 if (start < end && text[start]) {
2494 if (text[start] ==
'-' ||
2495 text[start] ==
'_' ||
2496 text[start] ==
':' ||
2497 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
2499 this->interval.
end = (this->interval.
start = start) + 1;
2525 virtual bool do_match(
2526 _In_reads_or_z_(end)
const char* text,
2527 _In_
size_t start = 0,
2528 _In_
size_t end = SIZE_MAX,
2529 _In_
int flags = match_default)
2531 _Assume_(text || start >= end);
2532 if (start < end && text[start]) {
2534 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.
end, buf);
2535 const wchar_t* chr_end = chr + stdex::strlen(chr);
2536 if (((chr[0] == L
'-' ||
2538 chr[0] == L
':') && chr[1] == 0) ||
2539 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
2541 this->interval.
start = start;
2575 _In_
const std::shared_ptr<
basic_parser<T>>& scope_id_separator =
nullptr,
2577 _In_
const std::locale&
locale = std::locale()) :
2589 m_digit_10(digit_10),
2590 m_digit_11(digit_11),
2591 m_digit_12(digit_12),
2592 m_digit_13(digit_13),
2593 m_digit_14(digit_14),
2594 m_digit_15(digit_15),
2595 m_separator(separator),
2596 m_scope_id_separator(scope_id_separator),
2602 virtual void invalidate()
2630 virtual bool do_match(
2631 _In_reads_or_z_opt_(end)
const T* text,
2632 _In_
size_t start = 0,
2633 _In_
size_t end = SIZE_MAX,
2634 _In_
int flags = match_default)
2636 _Assume_(text || start >= end);
2637 this->interval.
end = start;
2640 size_t i, compaction_i = SIZE_MAX, compaction_start = start;
2641 for (i = 0; i < 8; i++) {
2642 bool is_empty =
true;
2644 if (m_separator->match(text, this->interval.end, end, flags)) {
2646 this->interval.
end = m_separator->interval.end;
2647 if (m_separator->match(text, this->interval.end, end, flags)) {
2649 if (compaction_i == SIZE_MAX) {
2652 compaction_start = m_separator->interval.start;
2653 this->interval.
end = m_separator->interval.end;
2672 for (x = 0; this->interval.
end < end && text[this->interval.
end];) {
2673 size_t dig, digit_end;
2674 if (m_digit_0->match(text, this->interval.end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
2675 else if (m_digit_1->match(text, this->interval.end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
2676 else if (m_digit_2->match(text, this->interval.end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
2677 else if (m_digit_3->match(text, this->interval.end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
2678 else if (m_digit_4->match(text, this->interval.end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
2679 else if (m_digit_5->match(text, this->interval.end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
2680 else if (m_digit_6->match(text, this->interval.end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
2681 else if (m_digit_7->match(text, this->interval.end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
2682 else if (m_digit_8->match(text, this->interval.end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
2683 else if (m_digit_9->match(text, this->interval.end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
2684 else if (m_digit_10->match(text, this->interval.end, end, flags)) { dig = 10; digit_end = m_digit_10->interval.end; }
2685 else if (m_digit_11->match(text, this->interval.end, end, flags)) { dig = 11; digit_end = m_digit_11->interval.end; }
2686 else if (m_digit_12->match(text, this->interval.end, end, flags)) { dig = 12; digit_end = m_digit_12->interval.end; }
2687 else if (m_digit_13->match(text, this->interval.end, end, flags)) { dig = 13; digit_end = m_digit_13->interval.end; }
2688 else if (m_digit_14->match(text, this->interval.end, end, flags)) { dig = 14; digit_end = m_digit_14->interval.end; }
2689 else if (m_digit_15->match(text, this->interval.end, end, flags)) { dig = 15; digit_end = m_digit_15->interval.end; }
2691 size_t x_n = x * 16 + dig;
2692 if (x_n <= 0xffff) {
2694 this->interval.
end = digit_end;
2701 if (compaction_i != SIZE_MAX) {
2708 HE2BE(
reinterpret_cast<uint16_t&
>(this->value.s6_words[i]));
2711 if (compaction_i != SIZE_MAX) {
2714 for (j = 8, k = i; k > compaction_i;) {
2715 this->value.s6_words[--j] = this->value.s6_words[--k];
2718 for (; j > compaction_i;) {
2719 this->value.s6_words[--j] = 0;
2727 if (m_scope_id_separator && m_scope_id_separator->match(text, this->interval.end, end, flags) &&
2728 scope_id &&
scope_id->match(text, m_scope_id_separator->interval.end, end, flags))
2733 this->interval.
start = start;
2741 std::shared_ptr<basic_parser<T>>
2758 std::shared_ptr<basic_parser<T>> m_separator, m_scope_id_separator;
2761 using ipv6_address = basic_ipv6_address<char>;
2762 using wipv6_address = basic_ipv6_address<wchar_t>;
2764 using tipv6_address = wipv6_address;
2766 using tipv6_address = ipv6_address;
2768 using sgml_ipv6_address = basic_ipv6_address<char>;
2778 _In_
bool allow_idn,
2779 _In_
const std::locale&
locale = std::locale()) :
2781 m_allow_idn(allow_idn),
2788 virtual bool do_match(
2789 _In_reads_or_z_opt_(end)
const T* text,
2790 _In_
size_t start = 0,
2791 _In_
size_t end = SIZE_MAX,
2792 _In_
int flags = match_default)
2794 _Assume_(text || start >= end);
2795 if (start < end && text[start]) {
2796 if ((
'A' <= text[start] && text[start] <=
'Z') ||
2797 (
'a' <= text[start] && text[start] <=
'z') ||
2798 (
'0' <= text[start] && text[start] <=
'9'))
2800 else if (text[start] ==
'-')
2802 else if (m_allow_idn && std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
2808 this->interval.
end = (this->interval.
start = start) + 1;
2818 using dns_domain_char = basic_dns_domain_char<char>;
2819 using wdns_domain_char = basic_dns_domain_char<wchar_t>;
2821 using tdns_domain_char = wdns_domain_char;
2823 using tdns_domain_char = dns_domain_char;
2833 _In_
bool allow_idn,
2834 _In_
const std::locale&
locale = std::locale()) :
2839 virtual bool do_match(
2840 _In_reads_or_z_(end)
const char* text,
2841 _In_
size_t start = 0,
2842 _In_
size_t end = SIZE_MAX,
2843 _In_
int flags = match_default)
2845 _Assume_(text || start >= end);
2846 if (start < end && text[start]) {
2848 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.
end, buf);
2849 const wchar_t* chr_end = chr + stdex::strlen(chr);
2850 if (((
'A' <= chr[0] && chr[0] <=
'Z') ||
2851 (
'a' <= chr[0] && chr[0] <=
'z') ||
2852 (
'0' <= chr[0] && chr[0] <=
'9')) && chr[1] == 0)
2854 else if (chr[0] ==
'-' && chr[1] == 0)
2856 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)
2862 this->interval.
start = start;
2878 _In_
bool allow_absolute,
2881 _In_
const std::locale&
locale = std::locale()) :
2884 m_domain_char(domain_char),
2885 m_separator(separator)
2889 virtual bool do_match(
2890 _In_reads_or_z_opt_(end)
const T* text,
2891 _In_
size_t start = 0,
2892 _In_
size_t end = SIZE_MAX,
2893 _In_
int flags = match_default)
2895 _Assume_(text || start >= end);
2896 size_t i = start, count;
2897 for (count = 0; i < end && text[i] && count < 127; count++) {
2898 if (m_domain_char->match(text, i, end, flags) &&
2899 m_domain_char->allow_on_edge)
2902 this->interval.
end = i = m_domain_char->interval.end;
2903 while (i < end && text[i]) {
2904 if (m_domain_char->allow_on_edge &&
2905 m_separator->match(text, i, end, flags))
2909 this->interval.
end = i = m_separator->interval.end;
2911 this->interval.
end = i;
2912 i = m_separator->interval.end;
2916 if (m_domain_char->match(text, i, end, flags)) {
2917 if (m_domain_char->allow_on_edge)
2918 this->interval.
end = i = m_domain_char->interval.end;
2920 i = m_domain_char->interval.end;
2923 this->interval.
start = start;
2932 this->interval.
start = start;
2940 std::shared_ptr<basic_dns_domain_char<T>> m_domain_char;
2941 std::shared_ptr<basic_parser<T>> m_separator;
2963 virtual bool do_match(
2964 _In_reads_or_z_opt_(end)
const T* text,
2965 _In_
size_t start = 0,
2966 _In_
size_t end = SIZE_MAX,
2967 _In_
int flags = match_default)
2969 _Assume_(text || start >= end);
2970 if (start < end && text[start]) {
2971 if (text[start] ==
'-' ||
2972 text[start] ==
'.' ||
2973 text[start] ==
'_' ||
2974 text[start] ==
'~' ||
2975 text[start] ==
'%' ||
2976 text[start] ==
'!' ||
2977 text[start] ==
'$' ||
2978 text[start] ==
'&' ||
2979 text[start] ==
'\'' ||
2982 text[start] ==
'*' ||
2983 text[start] ==
'+' ||
2984 text[start] ==
',' ||
2985 text[start] ==
';' ||
2986 text[start] ==
'=' ||
2987 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
2989 this->interval.
end = (this->interval.
start = start) + 1;
3015 virtual bool do_match(
3016 _In_reads_or_z_(end)
const char* text,
3017 _In_
size_t start = 0,
3018 _In_
size_t end = SIZE_MAX,
3019 _In_
int flags = match_default)
3021 _Assume_(text || start >= end);
3022 if (start < end && text[start]) {
3024 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.
end, buf);
3025 const wchar_t* chr_end = chr + stdex::strlen(chr);
3026 if (((chr[0] == L
'-' ||
3041 chr[0] == L
'=') && chr[1] == 0) ||
3042 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3044 this->interval.
start = start;
3064 virtual bool do_match(
3065 _In_reads_or_z_opt_(end)
const T* text,
3066 _In_
size_t start = 0,
3067 _In_
size_t end = SIZE_MAX,
3068 _In_
int flags = match_default)
3070 _Assume_(text || start >= end);
3071 if (start < end && text[start]) {
3072 if (text[start] ==
'-' ||
3073 text[start] ==
'.' ||
3074 text[start] ==
'_' ||
3075 text[start] ==
'~' ||
3076 text[start] ==
'%' ||
3077 text[start] ==
'!' ||
3078 text[start] ==
'$' ||
3079 text[start] ==
'&' ||
3080 text[start] ==
'\'' ||
3081 text[start] ==
'(' ||
3082 text[start] ==
')' ||
3083 text[start] ==
'*' ||
3084 text[start] ==
'+' ||
3085 text[start] ==
',' ||
3086 text[start] ==
';' ||
3087 text[start] ==
'=' ||
3088 text[start] ==
':' ||
3089 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
3091 this->interval.
end = (this->interval.
start = start) + 1;
3117 virtual bool do_match(
3118 _In_reads_or_z_(end)
const char* text,
3119 _In_
size_t start = 0,
3120 _In_
size_t end = SIZE_MAX,
3121 _In_
int flags = match_default)
3123 _Assume_(text || start >= end);
3124 if (start < end && text[start]) {
3126 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.
end, buf);
3127 const wchar_t* chr_end = chr + stdex::strlen(chr);
3128 if (((chr[0] == L
'-' ||
3144 chr[0] == L
':') && chr[1] == 0) ||
3145 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3147 this->interval.
start = start;
3166 virtual bool do_match(
3167 _In_reads_or_z_opt_(end)
const T* text,
3168 _In_
size_t start = 0,
3169 _In_
size_t end = SIZE_MAX,
3170 _In_
int flags = match_default)
3172 _Assume_(text || start >= end);
3173 if (start < end && text[start]) {
3174 if (text[start] ==
'/' ||
3175 text[start] ==
'-' ||
3176 text[start] ==
'.' ||
3177 text[start] ==
'_' ||
3178 text[start] ==
'~' ||
3179 text[start] ==
'%' ||
3180 text[start] ==
'!' ||
3181 text[start] ==
'$' ||
3182 text[start] ==
'&' ||
3183 text[start] ==
'\'' ||
3184 text[start] ==
'(' ||
3185 text[start] ==
')' ||
3186 text[start] ==
'*' ||
3187 text[start] ==
'+' ||
3188 text[start] ==
',' ||
3189 text[start] ==
';' ||
3190 text[start] ==
'=' ||
3191 text[start] ==
':' ||
3192 text[start] ==
'@' ||
3193 text[start] ==
'?' ||
3194 text[start] ==
'#' ||
3195 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
3197 this->interval.
end = (this->interval.
start = start) + 1;
3223 virtual bool do_match(
3224 _In_reads_or_z_(end)
const char* text,
3225 _In_
size_t start = 0,
3226 _In_
size_t end = SIZE_MAX,
3227 _In_
int flags = match_default)
3229 _Assume_(text || start >= end);
3230 if (start < end && text[start]) {
3232 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.
end, buf);
3233 const wchar_t* chr_end = chr + stdex::strlen(chr);
3234 if (((chr[0] == L
'/' ||
3254 chr[0] == L
'#') && chr[1] == 0) ||
3255 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
3257 this->interval.
start = start;
3277 _In_
const std::locale&
locale = std::locale()) :
3279 m_path_char(path_char),
3280 m_query_start(query_start),
3281 m_bookmark_start(bookmark_start)
3284 virtual void invalidate()
3300 virtual bool do_match(
3301 _In_reads_or_z_opt_(end)
const T* text,
3302 _In_
size_t start = 0,
3303 _In_
size_t end = SIZE_MAX,
3304 _In_
int flags = match_default)
3306 _Assume_(text || start >= end);
3308 this->interval.
end = start;
3316 if (this->interval.
end >= end || !text[this->interval.end])
3318 if (m_query_start->match(text, this->interval.end, end, flags)) {
3319 path.
end = this->interval.
end;
3320 query.
start = this->interval.
end = m_query_start->interval.end;
3322 if (this->interval.
end >= end || !text[this->interval.end]) {
3323 query.
end = this->interval.
end;
3326 if (m_bookmark_start->match(text, this->interval.end, end, flags)) {
3327 query.
end = this->interval.
end;
3328 bookmark.
start = this->interval.
end = m_bookmark_start->interval.end;
3330 if (this->interval.
end >= end || !text[this->interval.end]) {
3331 bookmark.
end = this->interval.
end;
3334 if (m_path_char->match(text, this->interval.end, end, flags))
3335 this->interval.
end = m_path_char->interval.end;
3337 bookmark.
end = this->interval.
end;
3341 this->interval.
start = start;
3344 if (m_path_char->match(text, this->interval.end, end, flags))
3345 this->interval.
end = m_path_char->interval.end;
3347 query.
end = this->interval.
end;
3351 this->interval.
start = start;
3354 if (m_bookmark_start->match(text, this->interval.end, end, flags)) {
3355 path.
end = this->interval.
end;
3356 bookmark.
start = this->interval.
end = m_bookmark_start->interval.end;
3358 if (this->interval.
end >= end || !text[this->interval.end]) {
3359 bookmark.
end = this->interval.
end;
3362 if (m_path_char->match(text, this->interval.end, end, flags))
3363 this->interval.
end = m_path_char->interval.end;
3365 bookmark.
end = this->interval.
end;
3369 this->interval.
start = start;
3372 if (m_path_char->match(text, this->interval.end, end, flags))
3373 this->interval.
end = m_path_char->interval.end;
3379 path.
end = this->interval.
end;
3380 this->interval.
start = start;
3392 std::shared_ptr<basic_parser<T>> m_path_char;
3393 std::shared_ptr<basic_parser<T>> m_query_start;
3394 std::shared_ptr<basic_parser<T>> m_bookmark_start;
3430 _In_
const std::locale&
locale = std::locale()) :
3432 http_scheme(_http_scheme),
3433 ftp_scheme(_ftp_scheme),
3434 mailto_scheme(_mailto_scheme),
3435 file_scheme(_file_scheme),
3438 username(_username),
3439 password(_password),
3441 m_ip_lbracket(ip_lbracket),
3442 m_ip_rbracket(ip_rbracket),
3443 ipv4_host(_ipv4_host),
3444 ipv6_host(_ipv6_host),
3445 dns_host(_dns_host),
3450 virtual void invalidate()
3452 http_scheme->invalidate();
3453 ftp_scheme->invalidate();
3454 mailto_scheme->invalidate();
3455 file_scheme->invalidate();
3456 username->invalidate();
3457 password->invalidate();
3458 ipv4_host->invalidate();
3459 ipv6_host->invalidate();
3460 dns_host->invalidate();
3466 std::shared_ptr<basic_parser<T>> http_scheme;
3467 std::shared_ptr<basic_parser<T>> ftp_scheme;
3468 std::shared_ptr<basic_parser<T>> mailto_scheme;
3469 std::shared_ptr<basic_parser<T>> file_scheme;
3470 std::shared_ptr<basic_parser<T>> username;
3471 std::shared_ptr<basic_parser<T>> password;
3472 std::shared_ptr<basic_parser<T>> ipv4_host;
3473 std::shared_ptr<basic_parser<T>> ipv6_host;
3474 std::shared_ptr<basic_parser<T>> dns_host;
3475 std::shared_ptr<basic_parser<T>> port;
3476 std::shared_ptr<basic_parser<T>> path;
3479 virtual bool do_match(
3480 _In_reads_or_z_opt_(end)
const T* text,
3481 _In_
size_t start = 0,
3482 _In_
size_t end = SIZE_MAX,
3483 _In_
int flags = match_default)
3485 _Assume_(text || start >= end);
3487 this->interval.
end = start;
3489 if (http_scheme->match(text, this->interval.end, end, flags) &&
3490 m_colon->match(text, http_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))
3495 this->interval.
end = m_slash->interval.end;
3496 ftp_scheme->invalidate();
3497 mailto_scheme->invalidate();
3498 file_scheme->invalidate();
3500 else if (ftp_scheme->match(text, this->interval.end, end, flags) &&
3501 m_colon->match(text, ftp_scheme->interval.end, end, flags) &&
3502 m_slash->match(text, m_colon->interval.end, end, flags) &&
3503 m_slash->match(text, m_slash->interval.end, end, flags))
3506 this->interval.
end = m_slash->interval.end;
3507 http_scheme->invalidate();
3508 mailto_scheme->invalidate();
3509 file_scheme->invalidate();
3511 else if (mailto_scheme->match(text, this->interval.end, end, flags) &&
3512 m_colon->match(text, mailto_scheme->interval.end, end, flags))
3515 this->interval.
end = m_colon->interval.end;
3516 http_scheme->invalidate();
3517 ftp_scheme->invalidate();
3518 file_scheme->invalidate();
3520 else if (file_scheme->match(text, this->interval.end, end, flags) &&
3521 m_colon->match(text, file_scheme->interval.end, end, flags) &&
3522 m_slash->match(text, m_colon->interval.end, end, flags) &&
3523 m_slash->match(text, m_slash->interval.end, end, flags))
3526 this->interval.
end = m_slash->interval.end;
3527 http_scheme->invalidate();
3528 ftp_scheme->invalidate();
3529 mailto_scheme->invalidate();
3533 http_scheme->invalidate();
3534 ftp_scheme->invalidate();
3535 mailto_scheme->invalidate();
3536 file_scheme->invalidate();
3539 if (ftp_scheme->interval) {
3540 if (username->match(text, this->interval.end, end, flags)) {
3541 if (m_colon->match(text, username->interval.end, end, flags) &&
3542 password->match(text, m_colon->interval.end, end, flags) &&
3543 m_at->match(text, password->interval.end, end, flags))
3546 this->interval.
end = m_at->interval.end;
3548 else if (m_at->match(text, this->interval.end, end, flags)) {
3550 this->interval.
end = m_at->interval.end;
3551 password->invalidate();
3554 username->invalidate();
3555 password->invalidate();
3559 username->invalidate();
3560 password->invalidate();
3563 if (ipv4_host->match(text, this->interval.end, end, flags)) {
3565 this->interval.
end = ipv4_host->interval.end;
3566 ipv6_host->invalidate();
3567 dns_host->invalidate();
3570 m_ip_lbracket->match(text, this->interval.end, end, flags) &&
3571 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3572 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3575 this->interval.
end = m_ip_rbracket->interval.end;
3576 ipv4_host->invalidate();
3577 dns_host->invalidate();
3579 else if (dns_host->match(text, this->interval.end, end, flags)) {
3581 this->interval.
end = dns_host->interval.end;
3582 ipv4_host->invalidate();
3583 ipv6_host->invalidate();
3590 if (m_colon->match(text, this->interval.end, end, flags) &&
3591 port->match(text, m_colon->interval.end, end, flags))
3594 this->interval.
end = port->interval.end;
3599 if (path->match(text, this->interval.end, end, flags)) {
3601 this->interval.
end = path->interval.end;
3604 this->interval.
start = start;
3608 if (mailto_scheme->interval) {
3609 if (username->match(text, this->interval.end, end, flags) &&
3610 m_at->match(text, username->interval.end, end, flags))
3613 this->interval.
end = m_at->interval.end;
3620 if (m_ip_lbracket->match(text, this->interval.end, end, flags) &&
3621 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3622 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
3625 this->interval.
end = m_ip_rbracket->interval.end;
3626 ipv6_host->invalidate();
3627 dns_host->invalidate();
3630 m_ip_lbracket->match(text, this->interval.end, end, flags) &&
3631 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3632 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3635 this->interval.
end = m_ip_rbracket->interval.end;
3636 ipv4_host->invalidate();
3637 dns_host->invalidate();
3639 else if (dns_host->match(text, this->interval.end, end, flags)) {
3641 this->interval.
end = dns_host->interval.end;
3642 ipv4_host->invalidate();
3643 ipv6_host->invalidate();
3650 password->invalidate();
3653 this->interval.
start = start;
3657 if (file_scheme->interval) {
3658 if (path->match(text, this->interval.end, end, flags)) {
3660 this->interval.
end = path->interval.end;
3663 username->invalidate();
3664 password->invalidate();
3665 ipv4_host->invalidate();
3666 ipv6_host->invalidate();
3667 dns_host->invalidate();
3669 this->interval.
start = start;
3676 if (http_scheme->interval &&
3677 username->match(text, this->interval.end, end, flags))
3679 if (m_colon->match(text, username->interval.end, end, flags) &&
3680 password->match(text, m_colon->interval.end, end, flags) &&
3681 m_at->match(text, password->interval.end, end, flags))
3684 this->interval.
end = m_at->interval.end;
3686 else if (m_at->match(text, username->interval.end, end, flags)) {
3688 this->interval.
end = m_at->interval.end;
3689 password->invalidate();
3692 username->invalidate();
3693 password->invalidate();
3697 username->invalidate();
3698 password->invalidate();
3701 if (ipv4_host->match(text, this->interval.end, end, flags)) {
3703 this->interval.
end = ipv4_host->interval.end;
3704 ipv6_host->invalidate();
3705 dns_host->invalidate();
3708 m_ip_lbracket->match(text, this->interval.end, end, flags) &&
3709 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3710 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3713 this->interval.
end = m_ip_rbracket->interval.end;
3714 ipv4_host->invalidate();
3715 dns_host->invalidate();
3717 else if (dns_host->match(text, this->interval.end, end, flags)) {
3719 this->interval.
end = dns_host->interval.end;
3720 ipv4_host->invalidate();
3721 ipv6_host->invalidate();
3728 if (m_colon->match(text, this->interval.end, end, flags) &&
3729 port->match(text, m_colon->interval.end, end, flags))
3732 this->interval.
end = port->interval.end;
3737 if (path->match(text, this->interval.end, end, flags)) {
3739 this->interval.
end = path->interval.end;
3742 this->interval.
start = start;
3746 std::shared_ptr<basic_parser<T>> m_colon;
3747 std::shared_ptr<basic_parser<T>> m_slash;
3748 std::shared_ptr<basic_parser<T>> m_at;
3749 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
3750 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
3777 _In_
const std::locale&
locale = std::locale()) :
3779 username(_username),
3781 m_ip_lbracket(ip_lbracket),
3782 m_ip_rbracket(ip_rbracket),
3783 ipv4_host(_ipv4_host),
3784 ipv6_host(_ipv6_host),
3788 virtual void invalidate()
3790 username->invalidate();
3791 ipv4_host->invalidate();
3792 ipv6_host->invalidate();
3793 dns_host->invalidate();
3797 std::shared_ptr<basic_parser<T>> username;
3798 std::shared_ptr<basic_parser<T>> ipv4_host;
3799 std::shared_ptr<basic_parser<T>> ipv6_host;
3800 std::shared_ptr<basic_parser<T>> dns_host;
3803 virtual bool do_match(
3804 _In_reads_or_z_opt_(end)
const T* text,
3805 _In_
size_t start = 0,
3806 _In_
size_t end = SIZE_MAX,
3807 _In_
int flags = match_default)
3809 _Assume_(text || start >= end);
3811 if (username->match(text, start, end, flags) &&
3812 m_at->match(text, username->interval.end, end, flags))
3815 if (m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
3816 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3817 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
3820 this->interval.
end = m_ip_rbracket->interval.end;
3821 ipv6_host->invalidate();
3822 dns_host->invalidate();
3825 m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
3826 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
3827 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
3830 this->interval.
end = m_ip_rbracket->interval.end;
3831 ipv4_host->invalidate();
3832 dns_host->invalidate();
3834 else if (dns_host->match(text, m_at->interval.end, end, flags)) {
3836 this->interval.
end = dns_host->interval.end;
3837 ipv4_host->invalidate();
3838 ipv6_host->invalidate();
3842 this->interval.
start = start;
3851 std::shared_ptr<basic_parser<T>> m_at;
3852 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
3853 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
3878 _In_
const std::locale&
locale = std::locale()) :
3887 virtual void invalidate()
3893 mouth->invalidate();
3898 std::shared_ptr<basic_parser<T>>
apex;
3899 std::shared_ptr<basic_parser<T>>
eyes;
3900 std::shared_ptr<basic_parser<T>>
nose;
3904 virtual bool do_match(
3905 _In_reads_or_z_opt_(end)
const T* text,
3906 _In_
size_t start = 0,
3907 _In_
size_t end = SIZE_MAX,
3908 _In_
int flags = match_default)
3910 _Assume_(text || start >= end);
3916 mouth->invalidate();
3917 this->interval.
start = start;
3922 this->interval.
end = start;
3924 if (
apex &&
apex->match(text, this->interval.end, end, flags))
3925 this->interval.
end =
apex->interval.end;
3927 if (
eyes->match(text, this->interval.end, end, flags)) {
3928 if (
nose &&
nose->match(text,
eyes->interval.end, end, flags) &&
3929 mouth->match(text,
nose->interval.end, end, flags))
3932 start_mouth =
mouth->interval.start,
3933 hit_offset =
mouth->hit_offset;
3935 for (this->interval.
end =
mouth->interval.end;
mouth->match(text, this->interval.
end, end, flags) &&
mouth->hit_offset == hit_offset; this->interval.
end =
mouth->interval.end);
3936 mouth->interval.start = start_mouth;
3937 mouth->interval.end = this->interval.
end;
3938 this->interval.
start = start;
3941 if (
mouth->match(text,
eyes->interval.end, end, flags)) {
3943 start_mouth =
mouth->interval.start,
3944 hit_offset =
mouth->hit_offset;
3946 for (this->interval.
end =
mouth->interval.end;
mouth->match(text, this->interval.
end, end, flags) &&
mouth->hit_offset == hit_offset; this->interval.
end =
mouth->interval.end);
3948 mouth->interval.start = start_mouth;
3949 mouth->interval.end = this->interval.
end;
3950 this->interval.
start = start;
3959 mouth->invalidate();
3965 using emoticon = basic_emoticon<char>;
3966 using wemoticon = basic_emoticon<wchar_t>;
3968 using temoticon = wemoticon;
3970 using temoticon = emoticon;
3972 using sgml_emoticon = basic_emoticon<char>;
3977 enum date_format_t {
3978 date_format_none = 0,
3979 date_format_dmy = 0x1,
3980 date_format_mdy = 0x2,
3981 date_format_ymd = 0x4,
3982 date_format_ym = 0x8,
3983 date_format_my = 0x10,
3984 date_format_dm = 0x20,
3985 date_format_md = 0x40,
3996 _In_
int format_mask,
4002 _In_
const std::locale&
locale = std::locale()) :
4004 format(date_format_none),
4005 m_format_mask(format_mask),
4009 m_separator(separator),
4013 virtual void invalidate()
4015 if (day) day->invalidate();
4016 if (month) month->invalidate();
4017 if (year) year->invalidate();
4018 format = date_format_none;
4022 date_format_t format;
4023 std::shared_ptr<basic_integer<T>> day;
4024 std::shared_ptr<basic_integer<T>> month;
4025 std::shared_ptr<basic_integer<T>> year;
4028 virtual bool do_match(
4029 _In_reads_or_z_opt_(end)
const T* text,
4030 _In_
size_t start = 0,
4031 _In_
size_t end = SIZE_MAX,
4032 _In_
int flags = match_default)
4034 _Assume_(text || start >= end);
4036 const int space_match_flags = flags & ~match_multiline;
4037 if ((m_format_mask & date_format_dmy) == date_format_dmy) {
4038 if (day->match(text, start, end, flags)) {
4039 for (this->interval.
end = day->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4040 if (m_separator->match(text, this->interval.end, end, flags)) {
4041 size_t hit_offset = m_separator->hit_offset;
4042 for (this->interval.
end = m_separator->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4043 if (month->match(text, this->interval.end, end, flags)) {
4044 for (this->interval.
end = month->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4045 if (m_separator->match(text, this->interval.end, end, flags) &&
4046 m_separator->hit_offset == hit_offset)
4048 for (this->interval.
end = m_separator->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4049 if (year->match(text, this->interval.end, end, flags) &&
4050 is_valid(day->value, month->value))
4052 this->interval.
start = start;
4053 this->interval.
end = year->interval.end;
4054 format = date_format_dmy;
4063 if ((m_format_mask & date_format_mdy) == date_format_mdy) {
4064 if (month->match(text, start, end, flags)) {
4065 for (this->interval.
end = month->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4066 if (m_separator->match(text, this->interval.end, end, flags)) {
4067 size_t hit_offset = m_separator->hit_offset;
4068 for (this->interval.
end = m_separator->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4069 if (day->match(text, this->interval.end, end, flags)) {
4070 for (this->interval.
end = day->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4071 if (m_separator->match(text, this->interval.end, end, flags) &&
4072 m_separator->hit_offset == hit_offset)
4074 for (this->interval.
end = m_separator->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4075 if (year->match(text, this->interval.end, end, flags) &&
4076 is_valid(day->value, month->value))
4078 this->interval.
start = start;
4079 this->interval.
end = year->interval.end;
4080 format = date_format_mdy;
4089 if ((m_format_mask & date_format_ymd) == date_format_ymd) {
4090 if (year->match(text, start, end, flags)) {
4091 for (this->interval.
end = year->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4092 if (m_separator->match(text, this->interval.end, end, flags)) {
4093 size_t hit_offset = m_separator->hit_offset;
4094 for (this->interval.
end = m_separator->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4095 if (month->match(text, this->interval.end, end, flags)) {
4096 for (this->interval.
end = month->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4097 if (m_separator->match(text, this->interval.end, end, flags) &&
4098 m_separator->hit_offset == hit_offset)
4100 for (this->interval.
end = m_separator->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4101 if (day->match(text, this->interval.end, end, flags) &&
4102 is_valid(day->value, month->value))
4104 this->interval.
start = start;
4105 this->interval.
end = day->interval.end;
4106 format = date_format_ymd;
4115 if ((m_format_mask & date_format_ym) == date_format_ym) {
4116 if (year->match(text, start, end, flags)) {
4117 for (this->interval.
end = year->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4118 if (m_separator->match(text, this->interval.end, end, flags)) {
4119 for (this->interval.
end = m_separator->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4120 if (month->match(text, this->interval.end, end, flags) &&
4121 is_valid(SIZE_MAX, month->value))
4123 if (day) day->invalidate();
4124 this->interval.
start = start;
4125 this->interval.
end = month->interval.end;
4126 format = date_format_ym;
4133 if ((m_format_mask & date_format_my) == date_format_my) {
4134 if (month->match(text, start, end, flags)) {
4135 for (this->interval.
end = month->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4136 if (m_separator->match(text, this->interval.end, end, flags)) {
4137 for (this->interval.
end = m_separator->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4138 if (year->match(text, this->interval.end, end, flags) &&
4139 is_valid(SIZE_MAX, month->value))
4141 if (day) day->invalidate();
4142 this->interval.
start = start;
4143 this->interval.
end = year->interval.end;
4144 format = date_format_my;
4151 if ((m_format_mask & date_format_dm) == date_format_dm) {
4152 if (day->match(text, start, end, flags)) {
4153 for (this->interval.
end = day->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4154 if (m_separator->match(text, this->interval.end, end, flags)) {
4155 size_t hit_offset = m_separator->hit_offset;
4156 for (this->interval.
end = m_separator->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4157 if (month->match(text, this->interval.end, end, flags) &&
4158 is_valid(day->value, month->value))
4160 if (year) year->invalidate();
4161 this->interval.
start = start;
4162 for (this->interval.
end = month->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4163 if (m_separator->match(text, this->interval.end, end, flags) &&
4164 m_separator->hit_offset == hit_offset)
4165 this->interval.
end = m_separator->interval.end;
4167 this->interval.
end = month->interval.end;
4168 format = date_format_dm;
4175 if ((m_format_mask & date_format_md) == date_format_md) {
4176 if (month->match(text, start, end, flags)) {
4177 for (this->interval.
end = month->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4178 if (m_separator->match(text, this->interval.end, end, flags)) {
4179 size_t hit_offset = m_separator->hit_offset;
4180 for (this->interval.
end = m_separator->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4181 if (day->match(text, this->interval.end, end, flags) &&
4182 is_valid(day->value, month->value))
4184 if (year) year->invalidate();
4185 this->interval.
start = start;
4186 for (this->interval.
end = day->interval.end; m_space->match(text, this->interval.
end, end, space_match_flags); this->interval.
end = m_space->interval.end);
4187 if (m_separator->match(text, this->interval.end, end, flags) &&
4188 m_separator->hit_offset == hit_offset)
4189 this->interval.
end = m_separator->interval.end;
4191 this->interval.
end = day->interval.end;
4192 format = date_format_md;
4199 if (day) day->invalidate();
4200 if (month) month->invalidate();
4201 if (year) year->invalidate();
4202 format = date_format_none;
4207 static bool is_valid(
size_t day,
size_t month)
4209 if (month == SIZE_MAX) {
4213 if (day == SIZE_MAX) {
4226 return 1 <= day && day <= 31;
4228 return 1 <= day && day <= 29;
4233 return 1 <= day && day <= 30;
4240 std::shared_ptr<basic_set<T>> m_separator;
4241 std::shared_ptr<basic_parser<T>> m_space;
4267 _In_
const std::locale&
locale = std::locale()) :
4272 millisecond(_millisecond),
4273 m_separator(separator),
4274 m_millisecond_separator(millisecond_separator)
4277 virtual void invalidate()
4280 minute->invalidate();
4281 if (second) second->invalidate();
4282 if (millisecond) millisecond->invalidate();
4286 std::shared_ptr<basic_integer10<T>> hour;
4287 std::shared_ptr<basic_integer10<T>> minute;
4288 std::shared_ptr<basic_integer10<T>> second;
4289 std::shared_ptr<basic_integer10<T>> millisecond;
4292 virtual bool do_match(
4293 _In_reads_or_z_opt_(end)
const T* text,
4294 _In_
size_t start = 0,
4295 _In_
size_t end = SIZE_MAX,
4296 _In_
int flags = match_default)
4298 _Assume_(text || start >= end);
4300 if (hour->match(text, start, end, flags) &&
4301 m_separator->match(text, hour->interval.end, end, flags) &&
4302 minute->match(text, m_separator->interval.end, end, flags) &&
4306 size_t hit_offset = m_separator->hit_offset;
4307 if (m_separator->match(text, minute->interval.end, end, flags) &&
4308 m_separator->hit_offset == hit_offset &&
4309 second && second->match(text, m_separator->interval.end, end, flags) &&
4313 if (m_millisecond_separator && m_millisecond_separator->match(text, second->interval.end, end, flags) &&
4314 millisecond && millisecond->match(text, m_millisecond_separator->interval.end, end, flags) &&
4315 millisecond->value < 1000)
4318 this->interval.
end = millisecond->interval.end;
4321 if (millisecond) millisecond->invalidate();
4322 this->interval.
end = second->interval.end;
4326 if (second) second->invalidate();
4327 if (millisecond) millisecond->invalidate();
4328 this->interval.
end = minute->interval.end;
4330 this->interval.
start = start;
4335 minute->invalidate();
4336 if (second) second->invalidate();
4337 if (millisecond) millisecond->invalidate();
4342 std::shared_ptr<basic_set<T>> m_separator;
4343 std::shared_ptr<basic_parser<T>> m_millisecond_separator;
4370 _In_
const std::locale&
locale = std::locale()) :
4373 degree_separator(_degree_separator),
4375 minute_separator(_minute_separator),
4377 second_separator(_second_separator),
4381 virtual void invalidate()
4383 degree->invalidate();
4384 degree_separator->invalidate();
4385 minute->invalidate();
4386 minute_separator->invalidate();
4387 if (second) second->invalidate();
4388 if (second_separator) second_separator->invalidate();
4389 if (decimal) decimal->invalidate();
4393 std::shared_ptr<basic_integer10<T>> degree;
4394 std::shared_ptr<basic_parser<T>> degree_separator;
4395 std::shared_ptr<basic_integer10<T>> minute;
4396 std::shared_ptr<basic_parser<T>> minute_separator;
4397 std::shared_ptr<basic_integer10<T>> second;
4398 std::shared_ptr<basic_parser<T>> second_separator;
4399 std::shared_ptr<basic_parser<T>> decimal;
4402 virtual bool do_match(
4403 _In_reads_or_z_opt_(end)
const T* text,
4404 _In_
size_t start = 0,
4405 _In_
size_t end = SIZE_MAX,
4406 _In_
int flags = match_default)
4408 _Assume_(text || start >= end);
4410 this->interval.
end = start;
4412 if (degree->match(text, this->interval.end, end, flags) &&
4413 degree_separator->match(text, degree->interval.end, end, flags))
4416 this->interval.
end = degree_separator->interval.end;
4419 degree->invalidate();
4420 degree_separator->invalidate();
4423 if (minute->match(text, this->interval.end, end, flags) &&
4424 minute->value < 60 &&
4425 minute_separator->match(text, minute->interval.end, end, flags))
4428 this->interval.
end = minute_separator->interval.end;
4431 minute->invalidate();
4432 minute_separator->invalidate();
4435 if (second && second->match(text, this->interval.end, end, flags) &&
4439 this->interval.
end = second->interval.end;
4440 if (second_separator && second_separator->match(text, this->interval.end, end, flags))
4441 this->interval.
end = second_separator->interval.end;
4443 if (second_separator) second_separator->invalidate();
4446 if (second) second->invalidate();
4447 if (second_separator) second_separator->invalidate();
4450 if (degree->interval.start < degree->interval.end ||
4451 minute->interval.start < minute->interval.end ||
4452 (second && second->interval.start < second->interval.end))
4454 if (decimal && decimal->match(text, this->interval.end, end, flags)) {
4456 this->interval.
end = decimal->interval.end;
4459 decimal->invalidate();
4460 this->interval.
start = start;
4463 if (decimal) decimal->invalidate();
4488 _In_
const std::shared_ptr<
basic_set<T>>& lparenthesis,
4489 _In_
const std::shared_ptr<
basic_set<T>>& rparenthesis,
4492 _In_
const std::locale&
locale = std::locale()) :
4495 m_plus_sign(plus_sign),
4496 m_lparenthesis(lparenthesis),
4497 m_rparenthesis(rparenthesis),
4498 m_separator(separator),
4502 virtual void invalidate()
4511 virtual bool do_match(
4512 _In_reads_or_z_opt_(end)
const T* text,
4513 _In_
size_t start = 0,
4514 _In_
size_t end = SIZE_MAX,
4515 _In_
int flags = match_default)
4517 _Assume_(text || start >= end);
4519 size_t safe_digit_end = start, safe_value_size = 0;
4520 bool has_digits =
false, after_digit =
false, in_parentheses =
false, after_parentheses =
false;
4521 const int space_match_flags = flags & ~match_multiline;
4523 this->interval.
end = start;
4525 m_lparenthesis->invalidate();
4526 m_rparenthesis->invalidate();
4528 if (m_plus_sign && m_plus_sign->match(text, this->interval.end, end, flags)) {
4529 value.append(text + m_plus_sign->interval.start, text + m_plus_sign->interval.end);
4530 safe_value_size =
value.size();
4531 this->interval.
end = m_plus_sign->interval.end;
4535 _Assume_(text || this->interval.
end >= end);
4536 if (this->interval.
end >= end || !text[this->interval.end])
4538 if (m_digit->match(text, this->interval.end, end, flags)) {
4540 value.append(text + m_digit->interval.start, text + m_digit->interval.end);
4541 this->interval.
end = m_digit->interval.end;
4542 if (!in_parentheses) {
4543 safe_digit_end = this->interval.
end;
4544 safe_value_size =
value.size();
4548 after_parentheses =
false;
4551 m_lparenthesis && !m_lparenthesis->interval &&
4552 m_rparenthesis && !m_rparenthesis->interval &&
4553 m_lparenthesis->match(text, this->interval.end, end, flags))
4556 value.append(text + m_lparenthesis->interval.start, m_lparenthesis->interval.size());
4557 this->interval.
end = m_lparenthesis->interval.end;
4558 in_parentheses =
true;
4559 after_digit =
false;
4560 after_parentheses =
false;
4564 m_rparenthesis && !m_rparenthesis->interval &&
4565 m_rparenthesis->match(text, this->interval.end, end, flags) &&
4566 m_lparenthesis->hit_offset == m_rparenthesis->hit_offset)
4569 value.append(text + m_rparenthesis->interval.start, text + m_rparenthesis->interval.end);
4570 this->interval.
end = m_rparenthesis->interval.end;
4571 safe_digit_end = this->interval.
end;
4572 safe_value_size =
value.size();
4573 in_parentheses =
false;
4574 after_digit =
false;
4575 after_parentheses =
true;
4580 !after_parentheses &&
4581 m_separator && m_separator->match(text, this->interval.end, end, flags))
4584 this->interval.
end = m_separator->interval.end;
4585 after_digit =
false;
4586 after_parentheses =
false;
4589 (after_digit || after_parentheses) &&
4590 m_space && m_space->match(text, this->interval.end, end, space_match_flags))
4593 this->interval.
end = m_space->interval.end;
4594 after_digit =
false;
4595 after_parentheses =
false;
4601 value.erase(safe_value_size);
4602 this->interval.
start = start;
4603 this->interval.
end = safe_digit_end;
4611 std::shared_ptr<basic_parser<T>> m_digit;
4612 std::shared_ptr<basic_parser<T>> m_plus_sign;
4613 std::shared_ptr<basic_set<T>> m_lparenthesis;
4614 std::shared_ptr<basic_set<T>> m_rparenthesis;
4615 std::shared_ptr<basic_parser<T>> m_separator;
4616 std::shared_ptr<basic_parser<T>> m_space;
4619 using phone_number = basic_phone_number<char>;
4620 using wphone_number = basic_phone_number<wchar_t>;
4622 using tphone_number = wphone_number;
4624 using tphone_number = phone_number;
4626 using sgml_phone_number = basic_phone_number<char>;
4639 _In_
const std::locale&
locale = std::locale()) :
4649 virtual void invalidate()
4664 virtual bool do_match(
4665 _In_reads_or_z_opt_(end)
const T* text,
4666 _In_
size_t start = 0,
4667 _In_
size_t end = SIZE_MAX,
4668 _In_
int flags = match_default)
4670 _Assume_(text || start >= end);
4671 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
4672 const bool case_insensitive = flags & match_case_insensitive ? true :
false;
4678 static const country_t s_countries[] = {
4679 { {
'A',
'D' }, {}, 24 },
4680 { {
'A',
'E' }, {}, 23 },
4681 { {
'A',
'L' }, {}, 28 },
4682 { {
'A',
'O' }, {}, 25 },
4683 { {
'A',
'T' }, {}, 20 },
4684 { {
'A',
'Z' }, {}, 28 },
4685 { {
'B',
'A' }, {
'3',
'9' }, 20},
4686 { {
'B',
'E' }, {}, 16 },
4687 { {
'B',
'F' }, {}, 28 },
4688 { {
'B',
'G' }, {}, 22 },
4689 { {
'B',
'H' }, {}, 22 },
4690 { {
'B',
'I' }, {}, 27 },
4691 { {
'B',
'J' }, {}, 28 },
4692 { {
'B',
'R' }, {}, 29 },
4693 { {
'B',
'Y' }, {}, 28 },
4694 { {
'C',
'F' }, {}, 27 },
4695 { {
'C',
'G' }, {}, 27 },
4696 { {
'C',
'H' }, {}, 21 },
4697 { {
'C',
'I' }, {}, 28 },
4698 { {
'C',
'M' }, {}, 27 },
4699 { {
'C',
'R' }, {}, 22 },
4700 { {
'C',
'V' }, {}, 25 },
4701 { {
'C',
'Y' }, {}, 28 },
4702 { {
'C',
'Z' }, {}, 24 },
4703 { {
'D',
'E' }, {}, 22 },
4704 { {
'D',
'J' }, {}, 27 },
4705 { {
'D',
'K' }, {}, 18 },
4706 { {
'D',
'O' }, {}, 28 },
4707 { {
'D',
'Z' }, {}, 26 },
4708 { {
'E',
'E' }, {}, 20 },
4709 { {
'E',
'G' }, {}, 29 },
4710 { {
'E',
'S' }, {}, 24 },
4711 { {
'F',
'I' }, {}, 18 },
4712 { {
'F',
'O' }, {}, 18 },
4713 { {
'F',
'R' }, {}, 27 },
4714 { {
'G',
'A' }, {}, 27 },
4715 { {
'G',
'B' }, {}, 22 },
4716 { {
'G',
'E' }, {}, 22 },
4717 { {
'G',
'I' }, {}, 23 },
4718 { {
'G',
'L' }, {}, 18 },
4719 { {
'G',
'Q' }, {}, 27 },
4720 { {
'G',
'R' }, {}, 27 },
4721 { {
'G',
'T' }, {}, 28 },
4722 { {
'G',
'W' }, {}, 25 },
4723 { {
'H',
'N' }, {}, 28 },
4724 { {
'H',
'R' }, {}, 21 },
4725 { {
'H',
'U' }, {}, 28 },
4726 { {
'I',
'E' }, {}, 22 },
4727 { {
'I',
'L' }, {}, 23 },
4728 { {
'I',
'Q' }, {}, 23 },
4729 { {
'I',
'R' }, {}, 26 },
4730 { {
'I',
'S' }, {}, 26 },
4731 { {
'I',
'T' }, {}, 27 },
4732 { {
'J',
'O' }, {}, 30 },
4733 { {
'K',
'M' }, {}, 27 },
4734 { {
'K',
'W' }, {}, 30 },
4735 { {
'K',
'Z' }, {}, 20 },
4736 { {
'L',
'B' }, {}, 28 },
4737 { {
'L',
'C' }, {}, 32 },
4738 { {
'L',
'I' }, {}, 21 },
4739 { {
'L',
'T' }, {}, 20 },
4740 { {
'L',
'U' }, {}, 20 },
4741 { {
'L',
'V' }, {}, 21 },
4742 { {
'L',
'Y' }, {}, 25 },
4743 { {
'M',
'A' }, {}, 28 },
4744 { {
'M',
'C' }, {}, 27 },
4745 { {
'M',
'D' }, {}, 24 },
4746 { {
'M',
'E' }, {
'2',
'5' }, 22 },
4747 { {
'M',
'G' }, {}, 27 },
4748 { {
'M',
'K' }, {
'0',
'7' }, 19 },
4749 { {
'M',
'L' }, {}, 28 },
4750 { {
'M',
'R' }, {
'1',
'3' }, 27},
4751 { {
'M',
'T' }, {}, 31 },
4752 { {
'M',
'U' }, {}, 30 },
4753 { {
'M',
'Z' }, {}, 25 },
4754 { {
'N',
'E' }, {}, 28 },
4755 { {
'N',
'I' }, {}, 32 },
4756 { {
'N',
'L' }, {}, 18 },
4757 { {
'N',
'O' }, {}, 15 },
4758 { {
'P',
'K' }, {}, 24 },
4759 { {
'P',
'L' }, {}, 28 },
4760 { {
'P',
'S' }, {}, 29 },
4761 { {
'P',
'T' }, {
'5',
'0' }, 25 },
4762 { {
'Q',
'A' }, {}, 29 },
4763 { {
'R',
'O' }, {}, 24 },
4764 { {
'R',
'S' }, {
'3',
'5' }, 22 },
4765 { {
'R',
'U' }, {}, 33 },
4766 { {
'S',
'A' }, {}, 24 },
4767 { {
'S',
'C' }, {}, 31 },
4768 { {
'S',
'D' }, {}, 18 },
4769 { {
'S',
'E' }, {}, 24 },
4770 { {
'S',
'I' }, {
'5',
'6' }, 19 },
4771 { {
'S',
'K' }, {}, 24 },
4772 { {
'S',
'M' }, {}, 27 },
4773 { {
'S',
'N' }, {}, 28 },
4774 { {
'S',
'T' }, {}, 25 },
4775 { {
'S',
'V' }, {}, 28 },
4776 { {
'T',
'D' }, {}, 27 },
4777 { {
'T',
'G' }, {}, 28 },
4778 { {
'T',
'L' }, {
'3',
'8' }, 23},
4779 { {
'T',
'N' }, {
'5',
'9' }, 24 },
4780 { {
'T',
'R' }, {}, 26 },
4781 { {
'U',
'A' }, {}, 29 },
4782 { {
'V',
'A' }, {}, 22 },
4783 { {
'V',
'G' }, {}, 24 },
4784 { {
'X',
'K' }, {}, 20 },
4786 const country_t* country_desc =
nullptr;
4787 size_t n, available, next, bban_length;
4790 this->interval.
end = start;
4791 for (
size_t i = 0; i < 2; ++i, ++this->interval.
end) {
4792 if (this->interval.
end >= end || !text[this->interval.end])
4794 T chr = case_insensitive ? ctype.toupper(text[this->interval.
end]) : text[this->interval.
end];
4795 if (chr <
'A' ||
'Z' < chr)
4797 this->country[i] = chr;
4799 for (
size_t l = 0, r = _countof(s_countries);;) {
4802 size_t m = (l + r) / 2;
4803 const country_t& c = s_countries[m];
4804 if (c.country[0] < this->country[0] || (c.country[0] == this->country[0] && c.country[1] < this->country[1]))
4806 else if (this->country[0] < c.country[0] || (this->country[0] == c.country[0] && this->country[1] < c.country[1]))
4813 this->country[2] = 0;
4815 for (
size_t i = 0; i < 2; ++i, ++this->interval.
end) {
4816 if (this->interval.
end >= end || text[this->interval.end] <
'0' ||
'9' < text[this->interval.end])
4818 this->check_digits[i] = text[this->interval.
end];
4820 this->check_digits[2] = 0;
4822 if ((country_desc->check_digits[0] && this->check_digits[0] != country_desc->check_digits[0]) ||
4823 (country_desc->check_digits[1] && this->check_digits[1] != country_desc->check_digits[1]))
4826 bban_length = country_desc->length - 4;
4827 for (n = 0; n < bban_length;) {
4828 if (this->interval.
end >= end || !text[this->interval.end])
4830 if (m_space && m_space->match(text, this->interval.end, end, flags)) {
4831 this->interval.
end = m_space->interval.end;
4834 T chr = case_insensitive ? ctype.toupper(text[this->interval.
end]) : text[this->interval.
end];
4835 if ((
'0' <= chr && chr <=
'9') || (
'A' <= chr && chr <=
'Z')) {
4836 this->bban[n++] = chr;
4837 this->interval.
end++;
4847 for (
size_t i = 0; ; ++i) {
4848 if (!this->bban[i]) {
4849 for (i = 0; i < 2; ++i) {
4850 if (
'A' <= this->country[i] && this->country[i] <=
'J') {
4851 normalized[available++] =
'1';
4852 normalized[available++] =
'0' + this->country[i] -
'A';
4854 else if (
'K' <= this->country[i] && this->country[i] <=
'T') {
4855 normalized[available++] =
'2';
4856 normalized[available++] =
'0' + this->country[i] -
'K';
4858 else if (
'U' <= this->country[i] && this->country[i] <=
'Z') {
4859 normalized[available++] =
'3';
4860 normalized[available++] =
'0' + this->country[i] -
'U';
4863 normalized[available++] = this->check_digits[0];
4864 normalized[available++] = this->check_digits[1];
4865 normalized[available] = 0;
4868 if (
'0' <= this->bban[i] && this->bban[i] <=
'9')
4869 normalized[available++] = this->bban[i];
4870 else if (
'A' <= this->bban[i] && this->bban[i] <=
'J') {
4871 normalized[available++] =
'1';
4872 normalized[available++] =
'0' + this->bban[i] -
'A';
4874 else if (
'K' <= this->bban[i] && this->bban[i] <=
'T') {
4875 normalized[available++] =
'2';
4876 normalized[available++] =
'0' + this->bban[i] -
'K';
4878 else if (
'U' <= this->bban[i] && this->bban[i] <=
'Z') {
4879 normalized[available++] =
'3';
4880 normalized[available++] =
'0' + this->bban[i] -
'U';
4885 nominator = stdex::strtou32(normalized, 9, &next, 10);
4888 if (!normalized[next]) {
4889 this->is_valid = nominator == 1;
4892 size_t digit_count = nominator == 0 ? 0 : nominator < 10 ? 1 : 2;
4893 for (; digit_count < 9 && normalized[next]; ++next, ++digit_count)
4894 nominator = nominator * 10 +
static_cast<uint32_t
>(normalized[next] -
'0');
4897 this->interval.
start = start;
4905 std::shared_ptr<basic_parser<T>> m_space;
4908 using iban = basic_iban<char>;
4909 using wiban = basic_iban<wchar_t>;
4911 using tiban = wiban;
4915 using sgml_iban = basic_iban<char>;
4928 _In_
const std::locale&
locale = std::locale()) :
4932 this->check_digits[0] = 0;
4934 this->is_valid =
false;
4937 virtual void invalidate()
4939 this->check_digits[0] = 0;
4941 this->is_valid =
false;
4950 virtual bool do_match(
4951 _In_reads_or_z_opt_(end)
const T* text,
4952 _In_
size_t start = 0,
4953 _In_
size_t end = SIZE_MAX,
4954 _In_
int flags = match_default)
4956 _Assume_(text || start >= end);
4957 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
4958 const bool case_insensitive = flags & match_case_insensitive ? true :
false;
4959 size_t n, available, next;
4962 this->interval.
end = start;
4963 if (this->interval.
end + 1 >= end ||
4964 (case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.
end]) !=
'R' ||
4965 (case_insensitive ? ctype.toupper(text[this->interval.end + 1]) : text[this->interval.
end + 1]) !=
'F')
4967 this->interval.
end += 2;
4969 for (
size_t i = 0; i < 2; ++i, ++this->interval.
end) {
4970 if (this->interval.
end >= end || text[this->interval.end] <
'0' ||
'9' < text[this->interval.end])
4972 this->check_digits[i] = text[this->interval.
end];
4974 this->check_digits[2] = 0;
4977 if (m_space && m_space->match(text, this->interval.end, end, flags))
4978 this->interval.
end = m_space->interval.end;
4979 for (
size_t j = 0; j < 4; ++j) {
4980 if (this->interval.
end >= end || !text[this->interval.end])
4982 T chr = case_insensitive ? ctype.toupper(text[this->interval.
end]) : text[this->interval.
end];
4983 if ((
'0' <= chr && chr <=
'9') || (
'A' <= chr && chr <=
'Z')) {
4986 this->reference[n++] = chr;
4987 this->interval.
end++;
4996 this->reference[_countof(this->reference) - 1] = 0;
4997 for (
size_t i = n, j = _countof(this->reference) - 1; i;)
4998 this->reference[--j] = this->reference[--i];
4999 for (
size_t j = _countof(this->reference) - 1 - n; j;)
5000 this->reference[--j] =
'0';
5005 for (
size_t i = 0; ; ++i) {
5006 if (!this->reference[i]) {
5007 normalized[available++] =
'2';
5008 normalized[available++] =
'7';
5009 normalized[available++] =
'1';
5010 normalized[available++] =
'5';
5011 normalized[available++] = this->check_digits[0];
5012 normalized[available++] = this->check_digits[1];
5013 normalized[available] = 0;
5016 if (
'0' <= this->reference[i] && this->reference[i] <=
'9')
5017 normalized[available++] = this->reference[i];
5018 else if (
'A' <= this->reference[i] && this->reference[i] <=
'J') {
5019 normalized[available++] =
'1';
5020 normalized[available++] =
'0' + this->reference[i] -
'A';
5022 else if (
'K' <= this->reference[i] && this->reference[i] <=
'T') {
5023 normalized[available++] =
'2';
5024 normalized[available++] =
'0' + this->reference[i] -
'K';
5026 else if (
'U' <= this->reference[i] && this->reference[i] <=
'Z') {
5027 normalized[available++] =
'3';
5028 normalized[available++] =
'0' + this->reference[i] -
'U';
5033 nominator = stdex::strtou32(normalized, 9, &next, 10);
5036 if (!normalized[next]) {
5037 this->is_valid = nominator == 1;
5040 size_t digit_count = nominator == 0 ? 0 : nominator < 10 ? 1 : 2;
5041 for (; digit_count < 9 && normalized[next]; ++next, ++digit_count)
5042 nominator = nominator * 10 +
static_cast<uint32_t
>(normalized[next] -
'0');
5045 this->interval.
start = start;
5053 std::shared_ptr<basic_parser<T>> m_space;
5056 using creditor_reference = basic_creditor_reference<char>;
5057 using wcreditor_reference = basic_creditor_reference<wchar_t>;
5059 using tcreditor_reference = wcreditor_reference;
5061 using tcreditor_reference = creditor_reference;
5063 using sgml_creditor_reference = basic_creditor_reference<char>;
5077 virtual bool do_match(
5078 _In_reads_or_z_opt_(end)
const T* text,
5079 _In_
size_t start = 0,
5080 _In_
size_t end = SIZE_MAX,
5081 _In_
int flags = match_default)
5083 _Assume_(text || start >= end);
5084 this->interval.
end = start;
5086 if (this->interval.
end >= end || !text[this->interval.end])
5088 if (
'0' <= text[this->interval.
end] && text[this->interval.end] <=
'9')
5089 this->interval.
end++;
5094 this->interval.
start = start;
5123 virtual bool do_match(
5124 _In_reads_or_z_opt_(end)
const T* text,
5125 _In_
size_t start = 0,
5126 _In_
size_t end = SIZE_MAX,
5127 _In_
int flags = match_default)
5129 _Assume_(text || start >= end);
5130 if (start < end && text[start] ==
'-') {
5131 this->interval.
end = (this->interval.
start = start) + 1;
5161 _In_
const std::locale&
locale = std::locale()) :
5173 virtual void invalidate()
5176 this->
part1.invalidate();
5177 this->
part2.invalidate();
5178 this->
part3.invalidate();
5179 this->is_valid =
false;
5190 virtual bool do_match(
5191 _In_reads_or_z_opt_(end)
const T* text,
5192 _In_
size_t start = 0,
5193 _In_
size_t end = SIZE_MAX,
5194 _In_
int flags = match_default)
5196 _Assume_(text || start >= end);
5197 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
5198 const bool case_insensitive = flags & match_case_insensitive ? true :
false;
5200 this->interval.
end = start;
5201 if (this->interval.
end + 1 >= end ||
5202 (case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.
end]) !=
'S' ||
5203 (case_insensitive ? ctype.toupper(text[this->interval.end + 1]) : text[this->interval.
end + 1]) !=
'I')
5205 this->interval.
end += 2;
5207 for (
size_t i = 0; i < 2; ++i, ++this->interval.
end) {
5208 if (this->interval.
end >= end || text[this->interval.end] <
'0' ||
'9' < text[this->interval.end])
5210 this->model[i] = text[this->interval.
end];
5214 this->part1.invalidate();
5215 this->part2.invalidate();
5216 this->part3.invalidate();
5217 if (this->model[0] ==
'9' && this->model[1] ==
'9') {
5219 this->interval.
start = start;
5223 if (m_space && m_space->match(text, this->interval.end, end, flags))
5224 this->interval.
end = m_space->interval.end;
5226 this->part1.match(text, this->interval.
end, end, flags) &&
5227 this->m_delimiter.match(text, this->part1.
interval.
end, end, flags) &&
5228 this->part2.match(text, this->m_delimiter.interval.end, end, flags) &&
5229 this->m_delimiter.match(text, this->part2.
interval.
end, end, flags) &&
5230 this->part3.match(text, this->m_delimiter.interval.end, end, flags);
5232 this->interval.
start = start;
5240 this->interval.
end = start + 4;
5242 if (this->model[0] ==
'0' && this->model[1] ==
'0')
5253 else if (this->model[0] ==
'0' && this->model[1] ==
'1')
5259 text + this->part1.
interval.
start, this->part1.interval.size(),
5260 text + this->part2.interval.start, this->part2.interval.size(),
5261 text + this->part3.interval.start, this->part3.interval.size()) :
5266 text + this->part1.
interval.
start, this->part1.interval.size(),
5267 text + this->part2.interval.start, this->part2.interval.size()) :
5270 check11(text + this->part1.
interval.
start, this->part1.interval.size()) :
5272 else if (this->model[0] ==
'0' && this->model[1] ==
'2')
5277 check11(text + this->part2.
interval.
start, this->part2.interval.size()) &&
5278 check11(text + this->part3.
interval.
start, this->part3.interval.size()) :
5280 else if (this->model[0] ==
'0' && this->model[1] ==
'3')
5285 check11(text + this->part1.
interval.
start, this->part1.interval.size()) &&
5286 check11(text + this->part2.
interval.
start, this->part2.interval.size()) &&
5287 check11(text + this->part3.
interval.
start, this->part3.interval.size()) :
5289 else if (this->model[0] ==
'0' && this->model[1] ==
'4')
5294 check11(text + this->part1.
interval.
start, this->part1.interval.size()) &&
5295 check11(text + this->part3.
interval.
start, this->part3.interval.size()) :
5297 else if ((this->model[0] ==
'0' || this->model[0] ==
'5') && this->model[1] ==
'5')
5302 check11(text + this->part1.
interval.
start, this->part1.interval.size()) :
5306 check11(text + this->part1.
interval.
start, this->part1.interval.size()) :
5309 check11(text + this->part1.
interval.
start, this->part1.interval.size()) :
5311 else if (this->model[0] ==
'0' && this->model[1] ==
'6')
5317 text + this->part2.
interval.
start, this->part2.interval.size(),
5318 text + this->part3.interval.start, this->part3.interval.size()) :
5322 check11(text + this->part2.
interval.
start, this->part2.interval.size()) :
5324 else if (this->model[0] ==
'0' && this->model[1] ==
'7')
5329 check11(text + this->part2.
interval.
start, this->part2.interval.size()) :
5333 check11(text + this->part2.
interval.
start, this->part2.interval.size()) :
5335 else if (this->model[0] ==
'0' && this->model[1] ==
'8')
5341 text + this->part1.
interval.
start, this->part1.interval.size(),
5342 text + this->part2.interval.start, this->part2.interval.size()) &&
5343 check11(text + this->part3.
interval.
start, this->part3.interval.size()) :
5345 else if (this->model[0] ==
'0' && this->model[1] ==
'9')
5351 text + this->part1.
interval.
start, this->part1.interval.size(),
5352 text + this->part2.interval.start, this->part2.interval.size()) :
5357 text + this->part1.
interval.
start, this->part1.interval.size(),
5358 text + this->part2.interval.start, this->part2.interval.size()) :
5361 check11(text + this->part1.
interval.
start, this->part1.interval.size()) :
5363 else if (this->model[0] ==
'1' && this->model[1] ==
'0')
5368 check11(text + this->part1.
interval.
start, this->part1.interval.size()) &&
5370 text + this->part2.
interval.
start, this->part2.interval.size(),
5371 text + this->part3.interval.start, this->part3.interval.size()) :
5375 check11(text + this->part1.
interval.
start, this->part1.interval.size()) &&
5376 check11(text + this->part2.
interval.
start, this->part2.interval.size()) :
5379 (this->model[0] ==
'1' && (this->model[1] ==
'1' || this->model[1] ==
'8' || this->model[1] ==
'9')) ||
5380 ((this->model[0] ==
'2' || this->model[0] ==
'3') && this->model[1] ==
'8') ||
5381 (this->model[0] ==
'4' && (this->model[1] ==
'0' || this->model[1] ==
'1' || this->model[1] ==
'8' || this->model[1] ==
'9')) ||
5382 (this->model[0] ==
'5' && (this->model[1] ==
'1' || this->model[1] ==
'8')))
5387 check11(text + this->part1.
interval.
start, this->part1.interval.size()) &&
5388 check11(text + this->part2.
interval.
start, this->part2.interval.size()) :
5392 check11(text + this->part1.
interval.
start, this->part1.interval.size()) &&
5393 check11(text + this->part2.
interval.
start, this->part2.interval.size()) :
5395 else if (this->model[0] ==
'1' && this->model[1] ==
'2')
5401 check11(text + this->part1.
interval.
start, this->part1.interval.size()) :
5403 else if ((this->model[0] ==
'2' || this->model[0] ==
'3') && this->model[1] ==
'1')
5409 check11(text + this->part1.
interval.
start, this->part1.interval.size()) :
5420 static bool check11(
5421 _In_count_(num_part1)
const T*
part1, _In_
size_t num_part1)
5423 _Assume_(
part1 && num_part1 >= 1);
5424 uint32_t nominator = 0, ponder = 2;
5425 for (
size_t i = num_part1 - 1; i--; ++ponder)
5426 nominator +=
static_cast<uint32_t
>(
part1[i] -
'0') * ponder;
5427 uint8_t control = 11 -
static_cast<uint8_t
>(nominator % 11);
5430 return control ==
part1[num_part1 - 1] -
'0';
5433 static bool check11(
5434 _In_count_(num_part1)
const T*
part1, _In_
size_t num_part1,
5435 _In_count_(num_part2)
const T*
part2, _In_
size_t num_part2)
5437 _Assume_(
part1 || !num_part1);
5438 _Assume_(
part2 && num_part2 >= 1);
5439 uint32_t nominator = 0, ponder = 2;
5440 for (
size_t i = num_part2 - 1; i--; ++ponder)
5441 nominator +=
static_cast<uint32_t
>(
part2[i] -
'0') * ponder;
5442 for (
size_t i = num_part1; i--; ++ponder)
5443 nominator +=
static_cast<uint32_t
>(
part1[i] -
'0') * ponder;
5444 uint8_t control = 11 -
static_cast<uint8_t
>(nominator % 11);
5447 return control ==
part2[num_part2 - 1] -
'0';
5450 static bool check11(
5451 _In_count_(num_part1)
const T*
part1, _In_
size_t num_part1,
5452 _In_count_(num_part2)
const T*
part2, _In_
size_t num_part2,
5453 _In_count_(num_part3)
const T*
part3, _In_
size_t num_part3)
5455 _Assume_(
part1 || !num_part1);
5456 _Assume_(
part2 || !num_part2);
5457 _Assume_(
part3 && num_part3 >= 1);
5458 uint32_t nominator = 0, ponder = 2;
5459 for (
size_t i = num_part3 - 1; i--; ++ponder)
5460 nominator +=
static_cast<uint32_t
>(
part3[i] -
'0') * ponder;
5461 for (
size_t i = num_part2; i--; ++ponder)
5462 nominator +=
static_cast<uint32_t
>(
part2[i] -
'0') * ponder;
5463 for (
size_t i = num_part1; i--; ++ponder)
5464 nominator +=
static_cast<uint32_t
>(
part1[i] -
'0') * ponder;
5465 uint8_t control = 11 -
static_cast<uint8_t
>(nominator % 11);
5468 return control ==
part2[num_part3 - 1] -
'0';
5471 std::shared_ptr<basic_parser<T>> m_space;
5472 basic_si_reference_delimiter<T> m_delimiter;
5475 using si_reference = basic_si_reference<char>;
5476 using wsi_reference = basic_si_reference<wchar_t>;
5478 using tsi_reference = wsi_reference;
5480 using tsi_reference = si_reference;
5482 using sgml_si_reference = basic_si_reference<char>;
5495 _In_
const std::locale&
locale = std::locale()) :
5504 virtual void invalidate()
5515 virtual bool do_match(
5516 _In_reads_or_z_opt_(end)
const T* text,
5517 _In_
size_t start = 0,
5518 _In_
size_t end = SIZE_MAX,
5519 _In_
int flags = match_default)
5521 _Assume_(text || start >= end);
5525 this->interval.
end = start;
5527 const int element_match_flags = flags & ~match_case_insensitive;
5529 if (m_element->match(text, this->interval.end, end, element_match_flags)) {
5530 this->interval.
end = m_element->interval.end;
5531 while (m_digit->match(text, this->interval.end, end, flags)) {
5532 this->interval.
end = m_digit->interval.end;
5537 if (m_sign->match(text, this->interval.end, end, flags)) {
5538 this->interval.
end = m_sign->interval.end;
5541 this->interval.
start = start;
5551 std::shared_ptr<basic_parser<T>> m_element;
5552 std::shared_ptr<basic_parser<T>> m_digit;
5553 std::shared_ptr<basic_parser<T>> m_sign;
5571 virtual bool do_match(
5572 _In_reads_or_z_(end)
const char* text,
5573 _In_
size_t start = 0,
5574 _In_
size_t end = SIZE_MAX,
5575 _In_
int flags = match_default)
5577 _Assume_(text || start >= end);
5578 this->interval.
end = start;
5580 _Assume_(text || this->interval.
end >= end);
5581 if (this->interval.
end < end && text[this->interval.end]) {
5582 if (text[this->interval.
end] ==
'\r') {
5583 this->interval.
end++;
5584 if (this->interval.
end < end && text[this->interval.end] ==
'\n') {
5585 this->interval.
start = start;
5586 this->interval.
end++;
5590 else if (text[this->interval.
end] ==
'\n') {
5591 this->interval.
start = start;
5592 this->interval.
end++;
5607 virtual bool do_match(
5608 _In_reads_or_z_(end)
const char* text,
5609 _In_
size_t start = 0,
5610 _In_
size_t end = SIZE_MAX,
5611 _In_
int flags = match_default)
5613 _Assume_(text || start >= end);
5614 this->interval.
end = start;
5615 if (m_line_break.match(text, this->interval.end, end, flags)) {
5617 if (this->interval.
end < end && text[this->interval.end] && stdex::isspace(text[this->interval.end])) {
5618 this->interval.
start = start;
5619 this->interval.
end++;
5620 while (this->interval.
end < end && text[this->interval.end] && stdex::isspace(text[this->interval.end])) this->interval.
end++;
5624 else if (this->interval.
end < end && text[this->interval.end] && stdex::isspace(text[this->interval.end])) {
5625 this->interval.
start = start;
5626 this->interval.
end++;
5627 while (this->interval.
end < end && text[this->interval.end] && stdex::isspace(text[this->interval.end])) this->interval.
end++;
5643 virtual bool do_match(
5644 _In_reads_or_z_(end)
const char* text,
5645 _In_
size_t start = 0,
5646 _In_
size_t end = SIZE_MAX,
5647 _In_
int flags = match_default)
5649 _Assume_(text || start >= end);
5650 this->interval.
end = start;
5652 _Assume_(text || this->interval.
end >= end);
5653 if (m_space.match(text, this->interval.end, end, flags)) {
5654 this->interval.
start = start;
5658 else if (this->interval.
end < end && text[this->interval.end] && text[this->interval.end] >= 0x20) {
5659 this->interval.
start = start;
5660 this->interval.
end++;
5676 virtual bool do_match(
5677 _In_reads_or_z_(end)
const char* text,
5678 _In_
size_t start = 0,
5679 _In_
size_t end = SIZE_MAX,
5680 _In_
int flags = match_default)
5682 _Assume_(text || start >= end);
5683 this->interval.
end = start;
5685 if (this->interval.
end < end && text[this->interval.end]) {
5686 if ((
unsigned int)text[this->interval.
end] < 0x20 ||
5687 (
unsigned int)text[this->interval.end] == 0x7f ||
5688 text[this->interval.end] ==
'(' ||
5689 text[this->interval.end] ==
')' ||
5690 text[this->interval.end] ==
'<' ||
5691 text[this->interval.end] ==
'>' ||
5692 text[this->interval.end] ==
'@' ||
5693 text[this->interval.end] ==
',' ||
5694 text[this->interval.end] ==
';' ||
5695 text[this->interval.end] ==
':' ||
5696 text[this->interval.end] ==
'\\' ||
5697 text[this->interval.end] ==
'\"' ||
5698 text[this->interval.end] ==
'/' ||
5699 text[this->interval.end] ==
'[' ||
5700 text[this->interval.end] ==
']' ||
5701 text[this->interval.end] ==
'?' ||
5702 text[this->interval.end] ==
'=' ||
5703 text[this->interval.end] ==
'{' ||
5704 text[this->interval.end] ==
'}' ||
5705 stdex::isspace(text[this->interval.end]))
5708 this->interval.
end++;
5714 this->interval.
start = start;
5730 virtual void invalidate()
5734 parser::invalidate();
5740 virtual bool do_match(
5741 _In_reads_or_z_(end)
const char* text,
5742 _In_
size_t start = 0,
5743 _In_
size_t end = SIZE_MAX,
5744 _In_
int flags = match_default)
5746 _Assume_(text || start >= end);
5747 this->interval.
end = start;
5748 if (this->interval.
end < end && text[this->interval.end] !=
'"')
5750 this->interval.
end++;
5753 _Assume_(text || this->interval.
end >= end);
5754 if (this->interval.
end < end && text[this->interval.end]) {
5755 if (text[this->interval.
end] ==
'"') {
5757 this->interval.
end++;
5760 else if (text[this->interval.
end] ==
'\\') {
5761 this->interval.
end++;
5762 if (this->interval.
end < end && text[this->interval.end]) {
5763 this->interval.
end++;
5768 else if (m_chr.match(text, this->interval.end, end, flags))
5769 this->interval.
end++;
5776 this->interval.
start = start;
5793 virtual void invalidate()
5795 string.invalidate();
5797 parser::invalidate();
5804 virtual bool do_match(
5805 _In_reads_or_z_(end)
const char* text,
5806 _In_
size_t start = 0,
5807 _In_
size_t end = SIZE_MAX,
5808 _In_
int flags = match_default)
5810 _Assume_(text || start >= end);
5811 this->interval.
end = start;
5812 if (
string.match(text, this->interval.
end, end, flags)) {
5814 this->interval.
end =
string.interval.end;
5815 this->interval.
start = start;
5818 else if (
token.match(text, this->interval.end, end, flags)) {
5819 string.invalidate();
5821 this->interval.
start = start;
5837 virtual void invalidate()
5841 parser::invalidate();
5848 virtual bool do_match(
5849 _In_reads_or_z_(end)
const char* text,
5850 _In_
size_t start = 0,
5851 _In_
size_t end = SIZE_MAX,
5852 _In_
int flags = match_default)
5854 _Assume_(text || start >= end);
5855 this->interval.
end = start;
5856 if (
name.match(text, this->interval.end, end, flags))
5860 while (m_space.match(text, this->interval.end, end, flags))
5862 _Assume_(text || this->interval.
end >= end);
5863 if (this->interval.
end < end && text[this->interval.end] ==
'=')
5864 this->interval.
end++;
5866 while (m_space.match(text, this->interval.end, end, flags))
5868 if (
value.match(text, this->interval.end, end, flags))
5872 this->interval.
start = start;
5889 virtual bool do_match(
5890 _In_reads_or_z_(end)
const char* text,
5891 _In_
size_t start = 0,
5892 _In_
size_t end = SIZE_MAX,
5893 _In_
int flags = match_default)
5895 _Assume_(text || start >= end);
5896 if (start + 2 < end &&
5897 text[start] ==
'*' &&
5898 text[start + 1] ==
'/' &&
5899 text[start + 2] ==
'*')
5901 this->interval.
end = (this->interval.
start = start) + 3;
5904 else if (start < end && text[start] ==
'*') {
5905 this->interval.
end = (this->interval.
start = start) + 1;
5921 virtual void invalidate()
5924 subtype.invalidate();
5925 parser::invalidate();
5932 virtual bool do_match(
5933 _In_reads_or_z_(end)
const char* text,
5934 _In_
size_t start = 0,
5935 _In_
size_t end = SIZE_MAX,
5936 _In_
int flags = match_default)
5938 _Assume_(text || start >= end);
5939 this->interval.
end = start;
5940 if (type.match(text, this->interval.end, end, flags))
5944 while (m_space.match(text, this->interval.end, end, flags))
5946 if (this->interval.
end < end && text[this->interval.end] ==
'/')
5947 this->interval.
end++;
5950 while (m_space.match(text, this->interval.end, end, flags))
5952 if (subtype.match(text, this->interval.end, end, flags))
5956 this->interval.
start = start;
5973 virtual void invalidate()
5976 http_media_range::invalidate();
5979 std::list<http_parameter> params;
5982 virtual bool do_match(
5983 _In_reads_or_z_(end)
const char* text,
5984 _In_
size_t start = 0,
5985 _In_
size_t end = SIZE_MAX,
5986 _In_
int flags = match_default)
5988 _Assume_(text || start >= end);
5989 if (!http_media_range::do_match(text, start, end, flags))
5993 if (this->interval.
end < end && text[this->interval.end]) {
5994 if (m_space.match(text, this->interval.end, end, flags))
5996 else if (text[this->interval.
end] ==
';') {
5997 this->interval.
end++;
5998 while (m_space.match(text, this->interval.end, end, flags))
6001 if (param.match(text, this->interval.end, end, flags)) {
6002 this->interval.
end = param.interval.end;
6003 params.push_back(std::move(param));
6014 this->interval.
end = params.empty() ? subtype.
interval.
end : params.back().interval.end;
6029 virtual bool do_match(
6030 _In_reads_or_z_(end)
const char* text,
6031 _In_
size_t start = 0,
6032 _In_
size_t end = SIZE_MAX,
6033 _In_
int flags = match_default)
6035 _Assume_(text || start >= end);
6036 this->interval.
end = start;
6038 if (this->interval.
end < end && text[this->interval.end]) {
6039 if ((
unsigned int)text[this->interval.
end] < 0x20 ||
6040 (
unsigned int)text[this->interval.end] == 0x7f ||
6041 text[this->interval.end] ==
':' ||
6042 text[this->interval.end] ==
'/' ||
6043 stdex::isspace(text[this->interval.end]))
6046 this->interval.
end++;
6052 this->interval.
start = start;
6071 virtual void invalidate()
6074 parser::invalidate();
6080 virtual bool do_match(
6081 _In_reads_or_z_(end)
const char* text,
6082 _In_
size_t start = 0,
6083 _In_
size_t end = SIZE_MAX,
6084 _In_
int flags = match_default)
6086 _Assume_(text || start >= end);
6088 this->interval.
end = start;
6090 if (this->interval.
end < end && text[this->interval.end]) {
6091 if (
'0' <= text[this->interval.
end] && text[this->interval.end] <=
'9') {
6092 size_t _value =
static_cast<size_t>(value) * 10 +
static_cast<size_t>(text[this->interval.
end] -
'0');
6093 if (_value > UINT16_MAX) {
6098 value = (uint16_t)_value;
6099 this->interval.
end++;
6108 this->interval.
start = start;
6122 virtual bool do_match(
6123 _In_reads_or_z_(end)
const char* text,
6124 _In_
size_t start = 0,
6125 _In_
size_t end = SIZE_MAX,
6126 _In_
int flags = match_default)
6128 _Assume_(text || start >= end);
6129 this->interval.
end = start;
6131 if (this->interval.
end < end && text[this->interval.end]) {
6132 if ((
unsigned int)text[this->interval.
end] < 0x20 ||
6133 (
unsigned int)text[this->interval.end] == 0x7f ||
6134 text[this->interval.end] ==
'?' ||
6135 text[this->interval.end] ==
'/' ||
6136 stdex::isspace(text[this->interval.end]))
6139 this->interval.
end++;
6144 this->interval.
start = start;
6155 virtual void invalidate()
6158 parser::invalidate();
6164 virtual bool do_match(
6165 _In_reads_or_z_(end)
const char* text,
6166 _In_
size_t start = 0,
6167 _In_
size_t end = SIZE_MAX,
6168 _In_
int flags = match_default)
6170 _Assume_(text || start >= end);
6172 this->interval.
end = start;
6174 _Assume_(text || this->interval.
end >= end);
6175 if (this->interval.
end < end && text[this->interval.end] !=
'/')
6177 this->interval.
end++;
6178 s.match(text, this->interval.
end, end, flags);
6180 this->interval.
end = s.interval.end;
6182 if (this->interval.
end < end && text[this->interval.end]) {
6183 if (text[this->interval.
end] ==
'/') {
6184 this->interval.
end++;
6185 s.match(text, this->interval.
end, end, flags);
6187 this->interval.
end = s.interval.end;
6195 this->interval.
start = start;
6210 virtual void invalidate()
6216 parser::invalidate();
6223 virtual bool do_match(
6224 _In_reads_or_z_(end)
const char* text,
6225 _In_
size_t start = 0,
6226 _In_
size_t end = SIZE_MAX,
6227 _In_
int flags = match_default)
6229 _Assume_(text || start >= end);
6230 this->interval.
end = start;
6233 if (this->interval.
end < end && text[this->interval.end]) {
6234 if ((
unsigned int)text[this->interval.
end] < 0x20 ||
6235 (
unsigned int)text[this->interval.end] == 0x7f ||
6236 text[this->interval.end] ==
'&' ||
6237 text[this->interval.end] ==
'=' ||
6238 stdex::isspace(text[this->interval.end]))
6241 this->interval.
end++;
6247 name.
end = this->interval.
end;
6250 if (text[this->interval.
end] ==
'=') {
6251 this->interval.
end++;
6254 if (this->interval.
end < end && text[this->interval.end]) {
6255 if ((
unsigned int)text[this->interval.
end] < 0x20 ||
6256 (
unsigned int)text[this->interval.end] == 0x7f ||
6257 text[this->interval.end] ==
'&' ||
6258 stdex::isspace(text[this->interval.end]))
6261 this->interval.
end++;
6266 value.
end = this->interval.
end;
6272 this->interval.
start = start;
6292 virtual void invalidate()
6294 server.invalidate();
6298 parser::invalidate();
6304 std::list<http_url_parameter> params;
6307 virtual bool do_match(
6308 _In_reads_or_z_(end)
const char* text,
6309 _In_
size_t start = 0,
6310 _In_
size_t end = SIZE_MAX,
6311 _In_
int flags = match_default)
6313 _Assume_(text || start >= end);
6314 this->interval.
end = start;
6316 if (this->interval.
end + 7 <= end && stdex::strnicmp(text + this->interval.end, 7,
"http://", SIZE_MAX, m_locale) == 0) {
6317 this->interval.
end += 7;
6318 if (server.match(text, this->interval.end, end, flags))
6322 if (this->interval.
end < end && text[this->interval.end] ==
':') {
6323 this->interval.
end++;
6324 if (port.match(text, this->interval.end, end, flags))
6333 server.invalidate();
6338 if (path.match(text, this->interval.end, end, flags))
6345 if (this->interval.
end < end && text[this->interval.end] ==
'?') {
6346 this->interval.
end++;
6348 if (this->interval.
end < end && text[this->interval.end]) {
6349 if ((
unsigned int)text[this->interval.
end] < 0x20 ||
6350 (
unsigned int)text[this->interval.end] == 0x7f ||
6351 stdex::isspace(text[this->interval.end]))
6353 else if (text[this->interval.
end] ==
'&')
6354 this->interval.
end++;
6357 if (param.match(text, this->interval.end, end, flags)) {
6358 this->interval.
end = param.interval.end;
6359 params.push_back(std::move(param));
6370 this->interval.
start = start;
6385 virtual void invalidate()
6388 parser::invalidate();
6391 std::vector<stdex::interval<size_t>> components;
6394 virtual bool do_match(
6395 _In_reads_or_z_(end)
const char* text,
6396 _In_
size_t start = 0,
6397 _In_
size_t end = SIZE_MAX,
6398 _In_
int flags = match_default)
6400 _Assume_(text || start >= end);
6401 this->interval.
end = start;
6404 if (this->interval.
end < end && text[this->interval.end]) {
6406 k.
end = this->interval.
end;
6408 if (k.
end < end && text[k.
end]) {
6409 if (stdex::isalpha(text[k.
end]))
6417 if (this->interval.
end < k.
end) {
6419 this->interval.
end = k.
end;
6420 components.push_back(k);
6424 if (this->interval.
end < end && text[this->interval.end] ==
'-')
6425 this->interval.
end++;
6432 if (!components.empty()) {
6433 this->interval.
start = start;
6434 this->interval.
end = components.back().end;
6453 virtual void invalidate()
6456 parser::invalidate();
6462 virtual bool do_match(
6463 _In_reads_or_z_(end)
const char* text,
6464 _In_
size_t start = 0,
6465 _In_
size_t end = SIZE_MAX,
6466 _In_
int flags = match_default)
6468 _Assume_(text || start >= end);
6469 size_t celi_del = 0, decimalni_del = 0, decimalni_del_n = 1;
6470 this->interval.
end = start;
6472 if (this->interval.
end < end && text[this->interval.end]) {
6473 if (
'0' <= text[this->interval.
end] && text[this->interval.end] <=
'9') {
6474 celi_del = celi_del * 10 +
static_cast<size_t>(text[this->interval.
end] -
'0');
6475 this->interval.
end++;
6477 else if (text[this->interval.
end] ==
'.') {
6478 this->interval.
end++;
6480 if (this->interval.
end < end && text[this->interval.end]) {
6481 if (
'0' <= text[this->interval.
end] && text[this->interval.end] <=
'9') {
6482 decimalni_del = decimalni_del * 10 +
static_cast<size_t>(text[this->interval.
end] -
'0');
6483 decimalni_del_n *= 10;
6484 this->interval.
end++;
6501 value = (float)((
double)celi_del + (double)decimalni_del / decimalni_del_n);
6502 this->interval.
start = start;
6517 virtual bool do_match(
6518 _In_reads_or_z_(end)
const char* text,
6519 _In_
size_t start = 0,
6520 _In_
size_t end = SIZE_MAX,
6521 _In_
int flags = match_default)
6523 _Assume_(text || end <= start);
6524 if (start < end && text[start] ==
'*') {
6525 this->interval.
end = (this->interval.
start = start) + 1;
6536 template <
class T,
class T_asterisk = http_asterisk>
6545 virtual void invalidate()
6547 asterisk.invalidate();
6549 factor.invalidate();
6550 parser::invalidate();
6553 T_asterisk asterisk;
6558 virtual bool do_match(
6559 _In_reads_or_z_(end)
const char* text,
6560 _In_
size_t start = 0,
6561 _In_
size_t end = SIZE_MAX,
6562 _In_
int flags = match_default)
6564 _Assume_(text || start >= end);
6565 size_t konec_vrednosti;
6566 this->interval.
end = start;
6567 if (asterisk.match(text, this->interval.end, end, flags)) {
6568 this->interval.
end = konec_vrednosti = asterisk.interval.end;
6571 else if (value.match(text, this->interval.end, end, flags)) {
6572 this->interval.
end = konec_vrednosti = value.interval.end;
6573 asterisk.invalidate();
6576 asterisk.invalidate();
6582 while (this->interval.
end < end && text[this->interval.end] && stdex::isspace(text[this->interval.end])) this->interval.
end++;
6583 if (this->interval.
end < end && text[this->interval.end] ==
';') {
6584 this->interval.
end++;
6585 while (this->interval.
end < end && text[this->interval.end] && stdex::isspace(text[this->interval.end])) this->interval.
end++;
6586 if (this->interval.
end < end && (text[this->interval.end] ==
'q' || text[this->interval.end] ==
'Q')) {
6587 this->interval.
end++;
6588 while (this->interval.
end < end && text[this->interval.end] && stdex::isspace(text[this->interval.end])) this->interval.
end++;
6589 if (this->interval.
end < end && text[this->interval.end] ==
'=') {
6590 this->interval.
end++;
6591 while (this->interval.
end < end && text[this->interval.end] && stdex::isspace(text[this->interval.end])) this->interval.
end++;
6592 if (factor.match(text, this->interval.end, end, flags))
6598 factor.invalidate();
6599 this->interval.
end = konec_vrednosti;
6601 this->interval.
start = start;
6612 virtual void invalidate()
6616 parser::invalidate();
6623 virtual bool do_match(
6624 _In_reads_or_z_(end)
const char* text,
6625 _In_
size_t start = 0,
6626 _In_
size_t end = SIZE_MAX,
6627 _In_
int flags = match_default)
6629 _Assume_(text || start >= end);
6630 this->interval.
end = start;
6631 if (this->interval.
end < end && text[this->interval.end] ==
'$')
6632 this->interval.
end++;
6635 if (name.match(text, this->interval.end, end, flags))
6639 while (m_space.match(text, this->interval.end, end, flags))
6641 if (this->interval.
end < end && text[this->interval.end] ==
'=')
6642 this->interval.
end++;
6645 while (m_space.match(text, this->interval.end, end, flags))
6647 if (value.match(text, this->interval.end, end, flags))
6651 this->interval.
start = start;
6668 virtual void invalidate()
6673 parser::invalidate();
6681 virtual bool do_match(
6682 _In_reads_or_z_(end)
const char* text,
6683 _In_
size_t start = 0,
6684 _In_
size_t end = SIZE_MAX,
6685 _In_
int flags = match_default)
6687 _Assume_(text || start >= end);
6688 this->interval.
end = start;
6689 if (
name.match(text, this->interval.end, end, flags))
6693 while (m_space.match(text, this->interval.end, end, flags))
6695 if (this->interval.
end < end && text[this->interval.end] ==
'=')
6696 this->interval.
end++;
6699 while (m_space.match(text, this->interval.end, end, flags))
6701 if (
value.match(text, this->interval.end, end, flags))
6707 if (this->interval.
end < end && text[this->interval.end]) {
6708 if (m_space.match(text, this->interval.end, end, flags))
6710 else if (text[this->interval.
end] ==
';') {
6711 this->interval.
end++;
6712 while (m_space.match(text, this->interval.end, end, flags))
6715 if (param.match(text, this->interval.end, end, flags)) {
6716 this->interval.
end = param.interval.end;
6717 params.push_back(std::move(param));
6728 this->interval.
start = start;
6746 virtual void invalidate()
6752 parser::invalidate();
6759 virtual bool do_match(
6760 _In_reads_or_z_(end)
const char* text,
6761 _In_
size_t start = 0,
6762 _In_
size_t end = SIZE_MAX,
6763 _In_
int flags = match_default)
6765 _Assume_(text || start >= end);
6766 this->interval.
end = start;
6769 if (this->interval.
end < end && text[this->interval.end]) {
6770 if (text[this->interval.
end] ==
'/') {
6771 type.
end = this->interval.
end;
6772 this->interval.
end++;
6773 version.
start = this->interval.
end;
6775 if (this->interval.
end < end && text[this->interval.end]) {
6776 if (stdex::isspace(text[this->interval.
end])) {
6777 version.
end = this->interval.
end;
6781 this->interval.
end++;
6784 version.
end = this->interval.
end;
6790 else if (stdex::isspace(text[this->interval.
end])) {
6791 type.
end = this->interval.
end;
6795 this->interval.
end++;
6798 type.
end = this->interval.
end;
6803 this->interval.
start = start;
6826 virtual void invalidate()
6830 version_maj.
start = 1;
6831 version_maj.
end = 0;
6832 version_min.
start = 1;
6833 version_min.
end = 0;
6835 parser::invalidate();
6844 virtual bool do_match(
6845 _In_reads_or_z_(end)
const char* text,
6846 _In_
size_t start = 0,
6847 _In_
size_t end = SIZE_MAX,
6848 _In_
int flags = match_default)
6850 _Assume_(text || start >= end);
6851 this->interval.
end = start;
6854 if (this->interval.
end < end && text[this->interval.end]) {
6855 if (text[this->interval.
end] ==
'/') {
6856 type.
end = this->interval.
end;
6857 this->interval.
end++;
6860 else if (stdex::isspace(text[this->interval.
end]))
6863 this->interval.
end++;
6866 type.
end = this->interval.
end;
6870 version_maj.
start = this->interval.
end;
6872 if (this->interval.
end < end && text[this->interval.end]) {
6873 if (text[this->interval.
end] ==
'.') {
6874 version_maj.
end = this->interval.
end;
6875 this->interval.
end++;
6876 version_min.
start = this->interval.
end;
6878 if (this->interval.
end < end && text[this->interval.end]) {
6879 if (stdex::isspace(text[this->interval.
end])) {
6880 version_min.
end = this->interval.
end;
6882 (uint16_t)strtoui(text + version_maj.
start, version_maj.
size(),
nullptr, 10) * 0x100 +
6883 (uint16_t)strtoui(text + version_min.
start, version_min.
size(),
nullptr, 10);
6887 this->interval.
end++;
6894 else if (stdex::isspace(text[this->interval.
end])) {
6895 version_maj.
end = this->interval.
end;
6896 version_min.
start = 1;
6897 version_min.
end = 0;
6898 version = (uint16_t)strtoui(text + version_maj.
start, version_maj.
size(),
nullptr, 10) * 0x100;
6902 this->interval.
end++;
6907 this->interval.
start = start;
6928 virtual void invalidate()
6933 protocol.invalidate();
6934 parser::invalidate();
6942 virtual bool do_match(
6943 _In_reads_or_z_(end)
const char* text,
6944 _In_
size_t start = 0,
6945 _In_
size_t end = SIZE_MAX,
6946 _In_
int flags = match_default)
6948 _Assume_(text || start >= end);
6949 this->interval.
end = start;
6952 if (m_line_break.match(text, this->interval.end, end, flags))
6954 else if (this->interval.
end < end && text[this->interval.end]) {
6955 if (stdex::isspace(text[this->interval.
end]))
6956 this->interval.
end++;
6965 if (m_line_break.match(text, this->interval.end, end, flags))
6967 else if (this->interval.
end < end && text[this->interval.end]) {
6968 if (stdex::isspace(text[this->interval.
end])) {
6969 verb.
end = this->interval.
end;
6970 this->interval.
end++;
6974 this->interval.
end++;
6981 if (m_line_break.match(text, this->interval.end, end, flags))
6983 else if (this->interval.
end < end && text[this->interval.end]) {
6984 if (stdex::isspace(text[this->interval.
end]))
6985 this->interval.
end++;
6992 if (
url.match(text, this->interval.end, end, flags))
6997 protocol.invalidate();
6999 if (m_line_break.match(text, this->interval.end, end, flags)) {
7003 else if (this->interval.
end < end && text[this->interval.end]) {
7004 if (stdex::isspace(text[this->interval.
end]))
7005 this->interval.
end++;
7013 if (m_line_break.match(text, this->interval.end, end, flags)) {
7017 else if (protocol.match(text, this->interval.end, end, flags)) {
7026 if (m_line_break.match(text, this->interval.end, end, flags)) {
7030 else if (this->interval.
end < end && text[this->interval.end])
7031 this->interval.
end++;
7037 this->interval.
start = start;
7054 virtual void invalidate()
7060 parser::invalidate();
7067 virtual bool do_match(
7068 _In_reads_or_z_(end)
const char* text,
7069 _In_
size_t start = 0,
7070 _In_
size_t end = SIZE_MAX,
7071 _In_
int flags = match_default)
7073 _Assume_(text || start >= end);
7074 this->interval.
end = start;
7076 if (m_line_break.match(text, this->interval.end, end, flags) ||
7077 (this->interval.end < end && text[this->interval.end] && stdex::isspace(text[this->interval.end])))
7081 if (m_line_break.match(text, this->interval.end, end, flags))
7083 else if (this->interval.
end < end && text[this->interval.end]) {
7084 if (stdex::isspace(text[this->interval.
end])) {
7085 name.
end = this->interval.
end;
7086 this->interval.
end++;
7088 if (m_line_break.match(text, this->interval.end, end, flags))
7090 else if (this->interval.
end < end && text[this->interval.end]) {
7091 if (stdex::isspace(text[this->interval.
end]))
7092 this->interval.
end++;
7099 if (this->interval.
end < end && text[this->interval.end] ==
':') {
7100 this->interval.
end++;
7107 else if (text[this->interval.
end] ==
':') {
7108 name.
end = this->interval.
end;
7109 this->interval.
end++;
7113 this->interval.
end++;
7118 value.
start = SIZE_MAX;
7121 if (m_line_break.match(text, this->interval.end, end, flags)) {
7123 if (!m_line_break.match(text, this->interval.end, end, flags) &&
7124 this->interval.end < end && text[this->interval.end] && stdex::isspace(text[this->interval.end]))
7125 this->interval.
end++;
7129 else if (this->interval.
end < end && text[this->interval.end]) {
7130 if (stdex::isspace(text[this->interval.
end]))
7131 this->interval.
end++;
7133 if (value.
start == SIZE_MAX) value.
start = this->interval.
end;
7134 value.
end = ++this->interval.
end;
7140 this->interval.
start = start;
7154 template <
class KEY,
class T>
7159 _In_reads_or_z_(end)
const char* text,
7160 _In_
size_t start = 0,
7161 _In_
size_t end = SIZE_MAX,
7162 _In_
int flags = match_default)
7164 while (start < end) {
7165 while (start < end && text[start] && stdex::isspace(text[start])) start++;
7166 if (start < end && text[start] ==
',') {
7168 while (start < end&& text[start] && stdex::isspace(text[start])) start++;
7171 if (el.match(text, start, end, flags)) {
7172 start = el.interval.end;
7173 T::insert(std::move(el));
7183 constexpr bool operator()(
const T& a,
const T& b)
const noexcept
7185 return a.factor.value > b.factor.value;
7192 template <
class T,
class AX = std::allocator<T>>
7214 _In_
const std::locale&
locale = std::locale()) :
7229 virtual void invalidate()
7235 std::basic_string<T> value;
7238 virtual bool do_match(
7239 _In_reads_or_z_opt_(end)
const T* text,
7240 _In_
size_t start = 0,
7241 _In_
size_t end = SIZE_MAX,
7242 _In_
int flags = match_default)
7244 _Assume_(text || start >= end);
7245 this->interval.
end = start;
7246 if (m_quote->match(text, this->interval.end, end, flags)) {
7247 this->interval.
end = m_quote->interval.end;
7250 if (m_quote->match(text, this->interval.end, end, flags)) {
7251 this->interval.
start = start;
7252 this->interval.
end = m_quote->interval.end;
7255 if (m_escape->match(text, this->interval.end, end, flags)) {
7256 if (m_quote->match(text, m_escape->interval.end, end, flags)) {
7257 value +=
'"'; this->interval.
end = m_quote->interval.end;
7260 if (m_sol->match(text, m_escape->interval.end, end, flags)) {
7261 value +=
'/'; this->interval.
end = m_sol->interval.end;
7264 if (m_bs->match(text, m_escape->interval.end, end, flags)) {
7265 value +=
'\b'; this->interval.
end = m_bs->interval.end;
7268 if (m_ff->match(text, m_escape->interval.end, end, flags)) {
7269 value +=
'\f'; this->interval.
end = m_ff->interval.end;
7272 if (m_lf->match(text, m_escape->interval.end, end, flags)) {
7273 value +=
'\n'; this->interval.
end = m_lf->interval.end;
7276 if (m_cr->match(text, m_escape->interval.end, end, flags)) {
7277 value +=
'\r'; this->interval.
end = m_cr->interval.end;
7280 if (m_htab->match(text, m_escape->interval.end, end, flags)) {
7281 value +=
'\t'; this->interval.
end = m_htab->interval.end;
7285 m_uni->match(text, m_escape->interval.end, end, flags) &&
7286 m_hex->match(text, m_uni->interval.end, std::min(m_uni->interval.end + 4, end), flags | match_case_insensitive) &&
7287 m_hex->interval.size() == 4 )
7289 _Assume_(m_hex->value <= 0xffff);
7290 if (
sizeof(T) == 1) {
7291 if (m_hex->value > 0x7ff) {
7292 value += (T)(0xe0 | ((m_hex->value >> 12) & 0x0f));
7293 value += (T)(0x80 | ((m_hex->value >> 6) & 0x3f));
7294 value += (T)(0x80 | (m_hex->value & 0x3f));
7296 else if (m_hex->value > 0x7f) {
7297 value += (T)(0xc0 | ((m_hex->value >> 6) & 0x1f));
7298 value += (T)(0x80 | (m_hex->value & 0x3f));
7301 value += (T)(m_hex->value & 0x7f);
7304 value += (T)m_hex->value;
7305 this->interval.
end = m_hex->interval.end;
7308 if (m_escape->match(text, m_escape->interval.end, end, flags)) {
7309 value +=
'\\'; this->interval.
end = m_escape->interval.end;
7313 if (m_chr->match(text, this->interval.end, end, flags)) {
7314 value.append(text + m_chr->interval.start, m_chr->interval.size());
7315 this->interval.
end = m_chr->interval.end;
7326 std::shared_ptr<basic_parser<T>> m_quote;
7327 std::shared_ptr<basic_parser<T>> m_chr;
7328 std::shared_ptr<basic_parser<T>> m_escape;
7329 std::shared_ptr<basic_parser<T>> m_sol;
7330 std::shared_ptr<basic_parser<T>> m_bs;
7331 std::shared_ptr<basic_parser<T>> m_ff;
7332 std::shared_ptr<basic_parser<T>> m_lf;
7333 std::shared_ptr<basic_parser<T>> m_cr;
7334 std::shared_ptr<basic_parser<T>> m_htab;
7335 std::shared_ptr<basic_parser<T>> m_uni;
7336 std::shared_ptr<basic_integer16<T>> m_hex;
7354 virtual void invalidate()
7363 virtual bool do_match(
7364 _In_reads_or_z_opt_(end)
const T* text,
7365 _In_
size_t start = 0,
7366 _In_
size_t end = SIZE_MAX,
7367 _In_
int flags = match_multiline)
7369 _Unreferenced_(flags);
7370 _Assume_(text || start + 1 >= end);
7371 if (start + 1 < end &&
7372 text[start] ==
'/' &&
7373 text[start + 1] ==
'*')
7376 this->content.
start = this->interval.
end = start + 2;
7378 if (this->interval.
end >= end || !text[this->interval.end])
7380 if (this->interval.
end + 1 < end &&
7381 text[this->interval.end] ==
'*' &&
7382 text[this->interval.end + 1] ==
'/')
7385 this->content.
end = this->interval.
end;
7386 this->interval.
start = start;
7387 this->interval.
end = this->interval.
end + 2;
7390 this->interval.
end++;
7399 using css_comment = basic_css_comment<char>;
7400 using wcss_comment = basic_css_comment<wchar_t>;
7402 using tcss_comment = wcss_comment;
7404 using tcss_comment = css_comment;
7414 virtual bool do_match(
7415 _In_reads_or_z_opt_(end)
const T* text,
7416 _In_
size_t start = 0,
7417 _In_
size_t end = SIZE_MAX,
7418 _In_
int flags = match_multiline)
7420 _Unreferenced_(flags);
7421 _Assume_(text || start + 3 >= end);
7422 if (start + 3 < end &&
7423 text[start] ==
'<' &&
7424 text[start + 1] ==
'!' &&
7425 text[start + 2] ==
'-' &&
7426 text[start + 3] ==
'-')
7428 this->interval.
start = start;
7429 this->interval.
end = start + 4;
7452 virtual bool do_match(
7453 _In_reads_or_z_opt_(end)
const T* text,
7454 _In_
size_t start = 0,
7455 _In_
size_t end = SIZE_MAX,
7456 _In_
int flags = match_multiline)
7458 _Unreferenced_(flags);
7459 _Assume_(text || start + 2 >= end);
7460 if (start + 2 < end &&
7461 text[start] ==
'-' &&
7462 text[start + 1] ==
'-' &&
7463 text[start + 2] ==
'>')
7465 this->interval.
start = start;
7466 this->interval.
end = start + 3;
7489 virtual void invalidate()
7498 virtual bool do_match(
7499 _In_reads_or_z_opt_(end)
const T* text,
7500 _In_
size_t start = 0,
7501 _In_
size_t end = SIZE_MAX,
7502 _In_
int flags = match_multiline)
7504 _Unreferenced_(flags);
7505 this->interval.
end = start;
7506 _Assume_(text || this->interval.
end >= end);
7507 if (this->interval.
end < end &&
7508 (text[this->interval.end] ==
'\"' || text[this->interval.end] ==
'\''))
7511 T quote = text[this->interval.
end];
7512 this->content.
start = ++this->interval.
end;
7514 if (this->interval.
end >= end || !text[this->interval.end])
7516 if (text[this->interval.
end] == quote) {
7518 this->content.
end = this->interval.
end;
7519 this->interval.
start = start;
7520 this->interval.
end++;
7523 if (this->interval.
end + 1 < end &&
7524 text[this->interval.end] ==
'\\' &&
7525 (text[this->interval.end + 1] ==
'\"' || text[this->interval.end + 1] ==
'\''))
7528 this->interval.
end = this->interval.
end + 2;
7531 this->interval.
end++;
7541 using css_string = basic_css_string<char>;
7542 using wcss_string = basic_css_string<wchar_t>;
7544 using tcss_string = wcss_string;
7546 using tcss_string = css_string;
7556 virtual void invalidate()
7565 virtual bool do_match(
7566 _In_reads_or_z_opt_(end)
const T* text,
7567 _In_
size_t start = 0,
7568 _In_
size_t end = SIZE_MAX,
7569 _In_
int flags = match_multiline)
7571 _Unreferenced_(flags);
7572 this->interval.
end = start;
7573 _Assume_(text || this->interval.
end + 3 >= end);
7574 if (this->interval.
end + 3 < end &&
7575 (text[this->interval.end] ==
'u' || text[this->interval.end] ==
'U') &&
7576 (text[this->interval.end + 1] ==
'r' || text[this->interval.end + 1] ==
'R') &&
7577 (text[this->interval.end + 2] ==
'l' || text[this->interval.end + 2] ==
'L') &&
7578 text[this->interval.end + 3] ==
'(')
7581 this->interval.
end = this->interval.
end + 4;
7584 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
7585 for (; this->interval.
end < end && text[this->interval.
end] && ctype.is(ctype.space, text[this->interval.end]); this->interval.
end++);
7587 if (this->interval.
end < end &&
7588 (text[this->interval.end] ==
'\"' || text[this->interval.end] ==
'\''))
7591 T quote = text[this->interval.
end];
7592 this->content.
start = ++this->interval.
end;
7594 if (this->interval.
end >= end || !text[this->interval.end])
7596 if (text[this->interval.
end] == quote) {
7598 this->content.
end = this->interval.
end;
7599 this->interval.
end++;
7602 if (this->interval.
end + 1 < end &&
7603 text[this->interval.end] ==
'\\' &&
7604 (text[this->interval.end + 1] ==
'\"' || text[this->interval.end + 1] ==
'\''))
7607 this->interval.
end = this->interval.
end + 2;
7610 this->interval.
end++;
7614 for (; this->interval.
end < end && text[this->interval.
end] && ctype.is(ctype.space, text[this->interval.end]); this->interval.
end++);
7616 if (this->interval.
end < end &&
7617 text[this->interval.end] ==
')')
7620 this->interval.
start = start;
7621 this->interval.
end++;
7629 if (this->interval.
end >= end || !text[this->interval.end])
7631 if (text[this->interval.
end] ==
')') {
7633 this->interval.
start = start;
7634 this->interval.
end++;
7637 if (ctype.is(ctype.space, text[this->interval.end]))
7638 this->interval.
end++;
7640 this->content.
end = ++this->interval.
end;
7651 using css_uri = basic_css_uri<char>;
7652 using wcss_uri = basic_css_uri<wchar_t>;
7654 using tcss_uri = wcss_uri;
7656 using tcss_uri = css_uri;
7666 virtual void invalidate()
7675 virtual bool do_match(
7676 _In_reads_or_z_opt_(end)
const T* text,
7677 _In_
size_t start = 0,
7678 _In_
size_t end = SIZE_MAX,
7679 _In_
int flags = match_multiline)
7681 _Unreferenced_(flags);
7682 this->interval.
end = start;
7683 _Assume_(text || this->interval.
end + 6 >= end);
7684 if (this->interval.
end + 6 < end &&
7685 text[this->interval.end] ==
'@' &&
7686 (text[this->interval.end + 1] ==
'i' || text[this->interval.end + 1] ==
'I') &&
7687 (text[this->interval.end + 2] ==
'm' || text[this->interval.end + 2] ==
'M') &&
7688 (text[this->interval.end + 3] ==
'p' || text[this->interval.end + 3] ==
'P') &&
7689 (text[this->interval.end + 4] ==
'o' || text[this->interval.end + 4] ==
'O') &&
7690 (text[this->interval.end + 5] ==
'r' || text[this->interval.end + 5] ==
'R') &&
7691 (text[this->interval.end + 6] ==
't' || text[this->interval.end + 6] ==
'T'))
7694 this->interval.
end = this->interval.
end + 7;
7697 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
7698 for (; this->interval.
end < end && text[this->interval.
end] && ctype.is(ctype.space, text[this->interval.end]); this->interval.
end++);
7700 if (this->interval.
end < end &&
7701 (text[this->interval.end] ==
'\"' || text[this->interval.end] ==
'\''))
7704 T quote = text[this->interval.
end];
7705 this->content.
start = ++this->interval.
end;
7707 if (this->interval.
end >= end || !text[this->interval.end])
7709 if (text[this->interval.
end] == quote) {
7711 this->content.
end = this->interval.
end;
7712 this->interval.
start = start;
7713 this->interval.
end++;
7716 if (this->interval.
end + 1 < end &&
7717 text[this->interval.end] ==
'\\' &&
7718 (text[this->interval.end + 1] ==
'\"' || text[this->interval.end + 1] ==
'\''))
7721 this->interval.
end = this->interval.
end + 2;
7724 this->interval.
end++;
7735 using css_import = basic_css_import<char>;
7736 using wcss_import = basic_css_import<wchar_t>;
7738 using tcss_import = wcss_import;
7740 using tcss_import = css_import;
7750 virtual void invalidate()
7763 virtual bool do_match(
7764 _In_reads_or_z_opt_(end)
const T* text,
7765 _In_
size_t start = 0,
7766 _In_
size_t end = SIZE_MAX,
7767 _In_
int flags = match_multiline)
7769 _Unreferenced_(flags);
7770 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
7772 this->interval.
end = start;
7773 this->base_type.
start = this->interval.
end;
7775 _Assume_(text || this->interval.
end >= end);
7776 if (this->interval.
end >= end || !text[this->interval.end])
7778 if (text[this->interval.
end] ==
'/' ||
7779 text[this->interval.end] ==
';' ||
7780 ctype.is(ctype.space, text[this->interval.end]))
7782 this->interval.
end++;
7784 if (this->interval.
end <= this->base_type.start)
7786 this->base_type.
end = this->interval.
end;
7788 if (end <= this->
interval.
end || text[this->interval.end] !=
'/')
7791 this->interval.
end++;
7792 this->sub_type.
start = this->interval.
end;
7794 if (this->interval.
end >= end || !text[this->interval.end])
7796 if (text[this->interval.
end] ==
'/' ||
7797 text[this->interval.end] ==
';' ||
7798 ctype.is(ctype.space, text[this->interval.end]))
7800 this->interval.
end++;
7802 if (this->interval.
end <= this->sub_type.start)
7805 this->sub_type.
end = this->interval.
end;
7807 if (this->interval.
end < end && text[this->interval.end] ==
';') {
7808 this->interval.
end++;
7811 for (; this->interval.
end < end && text[this->interval.
end] && ctype.is(ctype.space, text[this->interval.end]); this->interval.
end++);
7813 if (this->interval.
end + 7 < end &&
7814 (text[this->interval.end] ==
'c' || text[this->interval.end] ==
'C') &&
7815 (text[this->interval.
end + 1] ==
'h' || text[this->interval.
end + 1] ==
'H') &&
7816 (text[this->interval.
end + 2] ==
'a' || text[this->interval.end + 2] ==
'A') &&
7817 (text[this->interval.
end + 3] ==
'r' || text[this->interval.
end + 3] ==
'R') &&
7818 (text[this->interval.
end + 4] ==
's' || text[this->interval.end + 4] ==
'S') &&
7819 (text[this->interval.
end + 5] ==
'e' || text[this->interval.
end + 5] ==
'E') &&
7820 (text[this->interval.
end + 6] ==
't' || text[this->interval.end + 6] ==
'T') &&
7821 text[this->interval.
end + 7] ==
'=')
7823 this->interval.
end = this->interval.
end + 8;
7824 if (this->interval.
end < end &&
7825 (text[this->interval.end] ==
'\"' || text[this->interval.end] ==
'\''))
7828 T quote = text[this->interval.
end];
7829 this->charset.
start = ++this->interval.
end;
7831 if (this->interval.
end >= end || !text[this->interval.end]) {
7836 if (text[this->interval.
end] == quote) {
7838 this->charset.
end = this->interval.
end;
7839 this->interval.
end++;
7842 this->interval.
end++;
7847 this->charset.
start = this->interval.
end;
7849 if (this->interval.
end >= end || !text[this->interval.end] ||
7850 ctype.is(ctype.space, text[this->interval.end])) {
7851 this->charset.
end = this->interval.
end;
7854 this->interval.
end++;
7859 this->interval.
start = start;
7868 using mime_type = basic_mime_type<char>;
7869 using wmime_type = basic_mime_type<wchar_t>;
7871 using tmime_type = wmime_type;
7873 using tmime_type = mime_type;
7883 virtual bool do_match(
7884 _In_reads_or_z_opt_(end)
const T* text,
7885 _In_
size_t start = 0,
7886 _In_
size_t end = SIZE_MAX,
7887 _In_
int flags = match_default)
7889 _Unreferenced_(flags);
7890 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
7891 this->interval.
end = start;
7893 _Assume_(text || this->interval.
end >= end);
7894 if (this->interval.
end >= end || !text[this->interval.end]) {
7896 this->interval.
start = start;
7902 if (text[this->interval.
end] ==
'>' ||
7903 text[this->interval.end] ==
'=' ||
7904 (text[this->interval.end] ==
'/' && this->interval.end + 1 < end && text[this->interval.end + 1] ==
'>') ||
7905 ctype.is(ctype.space, text[this->interval.end]))
7907 this->interval.
start = start;
7910 this->interval.
end++;
7930 virtual void invalidate()
7939 virtual bool do_match(
7940 _In_reads_or_z_opt_(end)
const T* text,
7941 _In_
size_t start = 0,
7942 _In_
size_t end = SIZE_MAX,
7943 _In_
int flags = match_default)
7945 _Unreferenced_(flags);
7946 this->interval.
end = start;
7947 _Assume_(text || this->interval.
end >= end);
7948 if (this->interval.
end < end &&
7949 (text[this->interval.end] ==
'\"' || text[this->interval.end] ==
'\''))
7952 T quote = text[this->interval.
end];
7953 this->content.
start = ++this->interval.
end;
7955 if (this->interval.
end >= end || !text[this->interval.end]) {
7961 if (text[this->interval.
end] == quote) {
7963 this->content.
end = this->interval.
end;
7964 this->interval.
start = start;
7965 this->interval.
end++;
7968 this->interval.
end++;
7973 this->content.
start = this->interval.
end;
7974 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
7976 _Assume_(text || this->interval.
end >= end);
7977 if (this->interval.
end >= end || !text[this->interval.end]) {
7978 this->content.
end = this->interval.
end;
7979 this->interval.
start = start;
7982 if (text[this->interval.
end] ==
'>' ||
7983 (text[this->interval.end] ==
'/' && this->interval.end + 1 < end && text[this->interval.end + 1] ==
'>') ||
7984 ctype.is(ctype.space, text[this->interval.end]))
7986 this->content.
end = this->interval.
end;
7987 this->interval.
start = start;
7990 this->interval.
end++;
7995 using html_value = basic_html_value<char>;
7996 using whtml_value = basic_html_value<wchar_t>;
7998 using thtml_value = whtml_value;
8000 using thtml_value = html_value;
8006 enum class html_sequence_t {
8037 type(html_sequence_t::unknown)
8040 virtual void invalidate()
8042 this->type = html_sequence_t::unknown;
8043 this->name.invalidate();
8053 virtual bool do_match(
8054 _In_reads_or_z_opt_(end)
const T* text,
8055 _In_
size_t start = 0,
8056 _In_
size_t end = SIZE_MAX,
8057 _In_
int flags = match_multiline)
8059 _Assume_(text || start >= end);
8060 if (start >= end || text[start] !=
'<')
8062 this->interval.
end = start + 1;
8063 if (this->interval.
end >= end || !text[this->interval.end])
8065 if (text[this->interval.
end] ==
'/' &&
8066 this->m_ident.match(text, this->interval.end + 1, end, flags))
8069 this->type = html_sequence_t::element_end;
8070 this->name = this->m_ident.interval;
8071 this->interval.
end = this->m_ident.interval.end;
8073 else if (text[this->interval.
end] ==
'!') {
8075 this->interval.
end++;
8076 if (this->interval.
end + 1 < end &&
8077 text[this->interval.end] ==
'-' &&
8078 text[this->interval.end + 1] ==
'-')
8081 this->name.
start = this->interval.
end = this->interval.
end + 2;
8083 if (this->interval.
end >= end || !text[this->interval.end])
8085 if (this->interval.
end + 2 < end &&
8086 text[this->interval.end] ==
'-' &&
8087 text[this->interval.end + 1] ==
'-' &&
8088 text[this->interval.end + 2] ==
'>')
8091 this->type = html_sequence_t::comment;
8092 this->name.
end = this->interval.
end;
8093 this->attributes.clear();
8094 this->interval.
start = start;
8095 this->interval.
end = this->interval.
end + 3;
8098 this->interval.
end++;
8101 this->type = html_sequence_t::declaration;
8102 this->name.
start = this->name.
end = this->interval.
end;
8104 else if (text[this->interval.
end] ==
'?') {
8106 this->name.
start = ++this->interval.
end;
8108 if (this->interval.
end >= end || !text[this->interval.end])
8110 if (text[this->interval.
end] ==
'>') {
8112 this->type = html_sequence_t::instruction;
8113 this->name.
end = this->interval.
end;
8114 this->attributes.clear();
8115 this->interval.
start = start;
8116 this->interval.
end++;
8119 if (this->interval.
end + 1 < end &&
8120 text[this->interval.end] ==
'?' &&
8121 text[this->interval.end + 1] ==
'>')
8124 this->type = html_sequence_t::instruction;
8125 this->name.
end = this->interval.
end;
8126 this->attributes.clear();
8127 this->interval.
start = start;
8128 this->interval.
end = this->interval.
end + 2;
8131 this->interval.
end++;
8134 else if (this->m_ident.match(text, this->interval.end, end, flags)) {
8136 this->type = html_sequence_t::element_start;
8137 this->name = this->m_ident.interval;
8138 this->interval.
end = this->m_ident.interval.end;
8145 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
8146 for (; this->interval.
end < end && text[this->interval.
end] && ctype.is(ctype.space, text[this->interval.end]); this->interval.
end++);
8148 this->attributes.clear();
8150 if (this->type == html_sequence_t::element_start &&
8151 this->interval.
end + 1 < end &&
8152 text[this->interval.end] ==
'/' &&
8153 text[this->interval.end + 1] ==
'>')
8156 this->type = html_sequence_t::element;
8157 this->interval.
end = this->interval.
end + 2;
8160 if (this->interval.
end < end &&
8161 text[this->interval.end] ==
'>')
8164 this->interval.
end++;
8167 if (this->type == html_sequence_t::declaration &&
8168 this->interval.
end + 1 < end &&
8169 text[this->interval.end] ==
'!' &&
8170 text[this->interval.end + 1] ==
'>')
8173 this->interval.
end = this->interval.
end + 2;
8176 if (this->type == html_sequence_t::declaration &&
8177 this->interval.
end + 1 < end &&
8178 text[this->interval.end] ==
'-' &&
8179 text[this->interval.end + 1] ==
'-')
8182 this->interval.
end = this->interval.
end + 2;
8184 if (this->interval.
end >= end || !text[this->interval.end])
8186 if (this->interval.
end + 1 < end &&
8187 text[this->interval.end] ==
'-' &&
8188 text[this->interval.end + 1] ==
'-')
8191 this->interval.
end = this->interval.
end + 2;
8194 this->interval.
end++;
8198 for (; this->interval.
end < end && text[this->interval.
end] && ctype.is(ctype.space, text[this->interval.end]); this->interval.
end++);
8202 if (this->interval.
end >= end || !text[this->interval.end])
8207 if (this->m_ident.match(text, this->interval.end, end, flags)) {
8208 this->attributes.push_back(std::move(
html_attribute{ this->m_ident.interval }));
8209 a = &this->attributes.back();
8211 this->interval.
end = this->m_ident.interval.end;
8215 this->interval.
end++;
8220 for (; this->interval.
end < end && text[this->interval.
end] && ctype.is(ctype.space, text[this->interval.end]); this->interval.
end++);
8222 if (this->interval.
end < end && text[this->interval.end] ==
'=') {
8223 this->interval.
end++;
8226 for (; this->interval.
end < end && text[this->interval.
end] && ctype.is(ctype.space, text[this->interval.end]); this->interval.
end++);
8228 if (this->m_value.match(text, this->interval.end, end, flags)) {
8230 a->value = this->m_value.content;
8231 this->interval.
end = this->m_value.interval.end;
8234 for (; this->interval.
end < end && text[this->interval.
end] && ctype.is(ctype.space, text[this->interval.end]); this->interval.
end++);
8239 a->value.invalidate();
8244 this->interval.
start = start;
8256 using html_tag = basic_html_tag<char>;
8257 using whtml_tag = basic_html_tag<wchar_t>;
8259 using thtml_tag = whtml_tag;
8261 using thtml_tag = html_tag;
8271 virtual void invalidate()
8281 _In_reads_or_z_opt_(end)
const T* text,
8282 _In_
size_t start = 0,
8283 _In_
size_t end = SIZE_MAX,
8284 _In_
int flags = match_multiline)
8286 _Unreferenced_(flags);
8287 _Assume_(text || start + 2 >= end);
8288 if (start + 2 < end &&
8289 text[start] ==
'<' &&
8290 text[start + 1] ==
'!' &&
8291 text[start + 2] ==
'[')
8293 this->interval.
end = start + 3;
8296 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
8297 for (; this->interval.
end < end && text[this->interval.
end] && ctype.is(ctype.space, text[this->interval.end]); this->interval.
end++);
8299 this->condition.
start = this->condition.
end = this->interval.
end;
8302 if (this->interval.
end >= end || !text[this->interval.end])
8304 if (text[this->interval.
end] ==
'[') {
8305 this->interval.
start = start;
8306 this->interval.
end++;
8309 if (ctype.is(ctype.space, text[this->interval.end]))
8310 this->interval.
end++;
8312 this->condition.
end = ++this->interval.
end;
8322 using html_declaration_condition_start = basic_html_declaration_condition_start<char>;
8323 using whtml_declaration_condition_start = basic_html_declaration_condition_start<wchar_t>;
8325 using thtml_declaration_condition_start = whtml_declaration_condition_start;
8327 using thtml_declaration_condition_start = html_declaration_condition_start;
8337 virtual bool do_match(
8338 _In_reads_or_z_opt_(end)
const T* text,
8339 _In_
size_t start = 0,
8340 _In_
size_t end = SIZE_MAX,
8341 _In_
int flags = match_multiline)
8343 _Unreferenced_(flags);
8344 _Assume_(text || start + 2 >= end);
8345 if (start + 2 < end &&
8346 text[start] ==
']' &&
8347 text[start + 1] ==
']' &&
8348 text[start + 2] ==
'>')
8350 this->interval.
start = start;
8351 this->interval.
end = start + 3;
8369#undef ENUM_FLAG_OPERATOR
8372#if defined(_MSC_VER)
8374#elif defined(__GNUC__)
8375#pragma GCC diagnostic pop
locale_t helper class to free_locale when going out of scope.
Definition locale.hpp:74
Test for angle in d°mm'ss.dddd form.
Definition parser.hpp:4360
Test for any code unit.
Definition parser.hpp:215
Test for beginning of line.
Definition parser.hpp:614
Test for any.
Definition parser.hpp:1057
Test for Creditor Reference.
Definition parser.hpp:4924
T reference[22]
Normalized national reference number.
Definition parser.hpp:4946
T check_digits[3]
Two check digits.
Definition parser.hpp:4945
bool is_valid
Is reference valid per ISO 7064.
Definition parser.hpp:4947
Legacy CSS comment end -->
Definition parser.hpp:7450
Legacy CSS comment start <!--
Definition parser.hpp:7412
CSS import directive.
Definition parser.hpp:7664
stdex::interval< size_t > content
content position in source
Definition parser.hpp:7672
CSS string.
Definition parser.hpp:7487
stdex::interval< size_t > content
content position in source
Definition parser.hpp:7495
URI in CSS.
Definition parser.hpp:7554
stdex::interval< size_t > content
content position in source
Definition parser.hpp:7562
Test for any code unit from a given string of code units.
Definition parser.hpp:719
Test for specific code unit.
Definition parser.hpp:287
Test for date.
Definition parser.hpp:3993
Test for valid DNS domain character.
Definition parser.hpp:2775
bool allow_on_edge
Is character allowed at the beginning or an end of a DNS domain?
Definition parser.hpp:2785
Test for DNS domain/hostname.
Definition parser.hpp:2875
bool m_allow_absolute
May DNS names end with a dot (absolute name)?
Definition parser.hpp:2939
Test for e-mail address.
Definition parser.hpp:3767
Test for emoticon.
Definition parser.hpp:3870
std::shared_ptr< basic_parser< T > > apex
apex/eyebrows/halo (e.g. O, 0)
Definition parser.hpp:3898
std::shared_ptr< basic_parser< T > > eyes
eyes (e.g. :, ;, >, |, B)
Definition parser.hpp:3899
std::shared_ptr< basic_set< T > > mouth
mouth (e.g. ), ), (, (, |, P, D, p, d)
Definition parser.hpp:3901
std::shared_ptr< basic_parser< T > > nose
nose (e.g. -, o)
Definition parser.hpp:3900
std::shared_ptr< basic_parser< T > > emoticon
emoticon as a whole (e.g. 😀, 🤔, 😶)
Definition parser.hpp:3897
Test for end of line.
Definition parser.hpp:653
Test for fraction.
Definition parser.hpp:1685
End of condition ...]]>
Definition parser.hpp:8335
Start of condition <![condition[...
Definition parser.hpp:8269
virtual bool do_match(_In_reads_or_z_opt_(end) const T *text, size_t start=0, size_t end=SIZE_MAX, int flags=match_multiline)
condition position in source
Definition parser.hpp:8280
Contiguous sequence of characters representing name of element, attribute etc.
Definition parser.hpp:7881
Tag.
Definition parser.hpp:8033
std::vector< html_attribute > attributes
tag attributes
Definition parser.hpp:8050
html_sequence_t type
tag type
Definition parser.hpp:8048
stdex::interval< size_t > name
tag name position in source
Definition parser.hpp:8049
Optionally-quoted string representing value of an attribute.
Definition parser.hpp:7928
stdex::interval< size_t > content
content position in source
Definition parser.hpp:7936
Test for International Bank Account Number.
Definition parser.hpp:4635
T bban[31]
Normalized Basic Bank Account Number.
Definition parser.hpp:4660
T country[3]
ISO 3166-1 alpha-2 country code.
Definition parser.hpp:4658
T check_digits[3]
Two check digits.
Definition parser.hpp:4659
bool is_valid
Is IBAN valid per ISO 7064.
Definition parser.hpp:4661
Test for decimal integer.
Definition parser.hpp:1295
Test for decimal integer possibly containing thousand separators.
Definition parser.hpp:1380
bool has_separators
Did integer have any separators?
Definition parser.hpp:1401
size_t digit_count
Total number of digits in integer.
Definition parser.hpp:1400
Test for hexadecimal integer.
Definition parser.hpp:1460
Base class for integer testing.
Definition parser.hpp:1273
size_t value
Calculated value of the numeral.
Definition parser.hpp:1287
Test for IPv4 address.
Definition parser.hpp:2343
stdex::interval< size_t > components[4]
Individual component intervals.
Definition parser.hpp:2388
struct in_addr value
IPv4 address value.
Definition parser.hpp:2389
Test for IPv6 address.
Definition parser.hpp:2555
std::shared_ptr< basic_parser< T > > scope_id
Scope ID (e.g. NIC index with link-local addresses)
Definition parser.hpp:2627
stdex::interval< size_t > components[8]
Individual component intervals.
Definition parser.hpp:2625
struct in6_addr value
IPv6 address value.
Definition parser.hpp:2626
Test for valid IPv6 address scope ID character.
Definition parser.hpp:2481
Test for repeating.
Definition parser.hpp:909
bool m_greedy
try to match as long sequence as possible
Definition parser.hpp:948
std::shared_ptr< basic_parser< T > > m_el
repeating element
Definition parser.hpp:945
size_t m_min_iterations
minimum number of iterations
Definition parser.hpp:946
size_t m_max_iterations
maximum number of iterations
Definition parser.hpp:947
Test for JSON string.
Definition parser.hpp:7200
MIME content type.
Definition parser.hpp:7748
stdex::interval< size_t > base_type
basic type position in source
Definition parser.hpp:7758
stdex::interval< size_t > sub_type
sub-type position in source
Definition parser.hpp:7759
stdex::interval< size_t > charset
charset position in source
Definition parser.hpp:7760
Test for mixed numeral.
Definition parser.hpp:1920
std::shared_ptr< basic_parser< T > > fraction
fraction
Definition parser.hpp:1953
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:1951
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:1950
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:1949
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:1952
Test for monetary numeral.
Definition parser.hpp:2214
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2247
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2252
std::shared_ptr< basic_parser< T > > currency
Currency part.
Definition parser.hpp:2250
std::shared_ptr< basic_parser< T > > decimal
Decimal part.
Definition parser.hpp:2253
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2251
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2248
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2249
"No-op" match
Definition parser.hpp:183
Base template for all parsers.
Definition parser.hpp:80
stdex::interval< size_t > interval
Region of the last match.
Definition parser.hpp:120
Test for permutation.
Definition parser.hpp:1197
Test for phone number.
Definition parser.hpp:4483
std::basic_string< T > value
Normalized phone number.
Definition parser.hpp:4508
Test for any punctuation code unit.
Definition parser.hpp:460
Test for Roman numeral.
Definition parser.hpp:1569
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:2091
std::shared_ptr< basic_parser< T > > exponent_symbol
Exponent symbol (e.g. 'e')
Definition parser.hpp:2095
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2089
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2090
double value
Calculated value of the numeral.
Definition parser.hpp:2099
std::shared_ptr< basic_parser< T > > negative_exp_sign
Negative exponent sign (e.g. '-')
Definition parser.hpp:2097
std::shared_ptr< basic_integer< T > > decimal
Decimal part.
Definition parser.hpp:2094
std::shared_ptr< basic_parser< T > > positive_exp_sign
Positive exponent sign (e.g. '+')
Definition parser.hpp:2096
std::shared_ptr< basic_integer< T > > exponent
Exponent part.
Definition parser.hpp:2098
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2093
std::shared_ptr< basic_integer< T > > integer
Integer part.
Definition parser.hpp:2092
Test for match score.
Definition parser.hpp:1748
Test for sequence.
Definition parser.hpp:1005
Definition parser.hpp:688
Test for SI Reference delimiter.
Definition parser.hpp:5118
Test for SI Reference part.
Definition parser.hpp:5072
Test for SI Reference.
Definition parser.hpp:5157
basic_si_reference_part< T > part3
Reference data part 3 (P3)
Definition parser.hpp:5186
basic_si_reference_part< T > part1
Reference data part 1 (P1)
Definition parser.hpp:5184
bool is_valid
Is reference valid.
Definition parser.hpp:5187
T model[3]
Reference model.
Definition parser.hpp:5183
basic_si_reference_part< T > part2
Reference data part 2 (P2)
Definition parser.hpp:5185
Test for signed numeral.
Definition parser.hpp:1834
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:1860
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:1859
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:1858
std::shared_ptr< basic_parser< T > > number
Number.
Definition parser.hpp:1861
Test for any space code unit.
Definition parser.hpp:380
Test for any space or punctuation code unit.
Definition parser.hpp:535
Test for any string.
Definition parser.hpp:1125
Test for given string.
Definition parser.hpp:814
Test for time.
Definition parser.hpp:4258
Test for valid URL password character.
Definition parser.hpp:3059
Test for valid URL path character.
Definition parser.hpp:3161
Test for URL path.
Definition parser.hpp:3271
Test for valid URL username character.
Definition parser.hpp:2958
Test for URL.
Definition parser.hpp:3411
Test for HTTP agent.
Definition parser.hpp:6744
Test for HTTP any type.
Definition parser.hpp:5887
Test for HTTP asterisk.
Definition parser.hpp:6515
Test for HTTP cookie parameter (RFC2109)
Definition parser.hpp:6610
Test for HTTP cookie (RFC2109)
Definition parser.hpp:6666
std::list< http_cookie_parameter > params
List of cookie parameters.
Definition parser.hpp:6678
http_token name
Cookie name.
Definition parser.hpp:6676
http_value value
Cookie value.
Definition parser.hpp:6677
Test for HTTP language (RFC1766)
Definition parser.hpp:6383
Test for HTTP line break (RFC2616: CRLF | LF)
Definition parser.hpp:5569
Test for HTTP parameter (RFC2616: parameter)
Definition parser.hpp:5835
http_token name
Parameter name.
Definition parser.hpp:5844
http_value value
Parameter value.
Definition parser.hpp:5845
Test for HTTP protocol.
Definition parser.hpp:6819
uint16_t version
HTTP protocol version: 0x100 = 1.0, 0x101 = 1.1...
Definition parser.hpp:6841
Test for HTTP quoted string (RFC2616: quoted-string)
Definition parser.hpp:5728
stdex::interval< size_t > content
String content (without quotes)
Definition parser.hpp:5737
Test for HTTP request.
Definition parser.hpp:6920
Test for HTTP space (RFC2616: LWS)
Definition parser.hpp:5605
Test for HTTP text character (RFC2616: TEXT)
Definition parser.hpp:5641
Test for HTTP token (RFC2616: token - tolerates non-ASCII)
Definition parser.hpp:5674
Test for HTTP URL parameter.
Definition parser.hpp:6208
Test for HTTP URL path segment.
Definition parser.hpp:6120
Test for HTTP URL path segment.
Definition parser.hpp:6153
std::vector< http_url_path_segment > segments
Path segments.
Definition parser.hpp:6161
Test for HTTP URL port.
Definition parser.hpp:6064
Test for HTTP URL server.
Definition parser.hpp:6027
Test for HTTP URL.
Definition parser.hpp:6285
Collection of HTTP values.
Definition parser.hpp:7156
Test for HTTP value (RFC2616: value)
Definition parser.hpp:5791
http_quoted_string string
Value when matched as quoted string.
Definition parser.hpp:5800
http_token token
Value when matched as token.
Definition parser.hpp:5801
Test for HTTP weight factor.
Definition parser.hpp:6446
float value
Calculated value of the weight factor.
Definition parser.hpp:6459
Test for HTTP weighted value.
Definition parser.hpp:6538
Base template for collection-holding parsers.
Definition parser.hpp:965
Test for any SGML code point.
Definition parser.hpp:248
Test for any SGML code point from a given string of SGML code points.
Definition parser.hpp:771
Test for specific SGML code point.
Definition parser.hpp:336
Test for valid DNS domain SGML character.
Definition parser.hpp:2830
Test for valid IPv6 address scope ID SGML character.
Definition parser.hpp:2520
Test for any SGML punctuation code point.
Definition parser.hpp:501
Test for any SGML space code point.
Definition parser.hpp:423
Test for any SGML space or punctuation code point.
Definition parser.hpp:578
Test for SGML given string.
Definition parser.hpp:861
Test for valid URL password SGML character.
Definition parser.hpp:3112
Test for valid URL path SGML character.
Definition parser.hpp:3218
Test for valid URL username SGML character.
Definition parser.hpp:3010
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
void invalidate()
Invalidates interval.
Definition interval.hpp:59
T start
interval start
Definition interval.hpp:19
Tag attribute.
Definition parser.hpp:8023
stdex::interval< size_t > name
attribute name position in source
Definition parser.hpp:8024
stdex::interval< size_t > value
attribute value position in source
Definition parser.hpp:8025
Definition parser.hpp:7182