diff --git a/annotated.html b/annotated.html index fcf1a8bf7..b193f85c0 100644 --- a/annotated.html +++ b/annotated.html @@ -186,7 +186,7 @@ $(function() { diff --git a/base64_8hpp_source.html b/base64_8hpp_source.html index e67d759d4..be4eeb0c0 100644 --- a/base64_8hpp_source.html +++ b/base64_8hpp_source.html @@ -318,7 +318,7 @@ $(function() { diff --git a/classes.html b/classes.html index 6b7e25320..1377f2c17 100644 --- a/classes.html +++ b/classes.html @@ -118,7 +118,7 @@ $(function() { diff --git a/classstdex_1_1base64__dec-members.html b/classstdex_1_1base64__dec-members.html index 0c187fd15..6067d0c61 100644 --- a/classstdex_1_1base64__dec-members.html +++ b/classstdex_1_1base64__dec-members.html @@ -90,7 +90,7 @@ $(function() { diff --git a/classstdex_1_1base64__dec.html b/classstdex_1_1base64__dec.html index ea5f1c9db..05064d54b 100644 --- a/classstdex_1_1base64__dec.html +++ b/classstdex_1_1base64__dec.html @@ -230,7 +230,7 @@ template<class _Ty , class _Ax , class _Tchr > diff --git a/classstdex_1_1base64__enc-members.html b/classstdex_1_1base64__enc-members.html index 614141807..c24b67cc9 100644 --- a/classstdex_1_1base64__enc-members.html +++ b/classstdex_1_1base64__enc-members.html @@ -91,7 +91,7 @@ $(function() { diff --git a/classstdex_1_1base64__enc.html b/classstdex_1_1base64__enc.html index aee14d21d..a2214f8a2 100644 --- a/classstdex_1_1base64__enc.html +++ b/classstdex_1_1base64__enc.html @@ -235,7 +235,7 @@ template<class _Elem , class _Traits , class _Ax > diff --git a/classstdex_1_1errno__error-members.html b/classstdex_1_1errno__error-members.html index 274c14504..bb771f6da 100644 --- a/classstdex_1_1errno__error-members.html +++ b/classstdex_1_1errno__error-members.html @@ -89,7 +89,7 @@ $(function() { diff --git a/classstdex_1_1errno__error.html b/classstdex_1_1errno__error.html index 074a6d3b4..b06be7a1e 100644 --- a/classstdex_1_1errno__error.html +++ b/classstdex_1_1errno__error.html @@ -286,7 +286,7 @@ errno_t m_num diff --git a/classstdex_1_1global__progress-members.html b/classstdex_1_1global__progress-members.html index 36dbd7b67..de420a6a1 100644 --- a/classstdex_1_1global__progress-members.html +++ b/classstdex_1_1global__progress-members.html @@ -97,7 +97,7 @@ $(function() { diff --git a/classstdex_1_1global__progress.html b/classstdex_1_1global__progress.html index 39edaedd7..5379df754 100644 --- a/classstdex_1_1global__progress.html +++ b/classstdex_1_1global__progress.html @@ -562,7 +562,7 @@ template<class T > diff --git a/classstdex_1_1hex__dec-members.html b/classstdex_1_1hex__dec-members.html index 8bfd12858..c722b53b8 100644 --- a/classstdex_1_1hex__dec-members.html +++ b/classstdex_1_1hex__dec-members.html @@ -89,7 +89,7 @@ $(function() { diff --git a/classstdex_1_1hex__dec.html b/classstdex_1_1hex__dec.html index caabb2a5a..91ac578c2 100644 --- a/classstdex_1_1hex__dec.html +++ b/classstdex_1_1hex__dec.html @@ -221,7 +221,7 @@ template<class _Ty , class _Ax , class _Tchr > diff --git a/classstdex_1_1hex__enc-members.html b/classstdex_1_1hex__enc-members.html index bee6587a2..9b3be632f 100644 --- a/classstdex_1_1hex__enc-members.html +++ b/classstdex_1_1hex__enc-members.html @@ -86,7 +86,7 @@ $(function() { diff --git a/classstdex_1_1hex__enc.html b/classstdex_1_1hex__enc.html index 2a5530b02..38347fd23 100644 --- a/classstdex_1_1hex__enc.html +++ b/classstdex_1_1hex__enc.html @@ -198,7 +198,7 @@ template<class _Elem , class _Traits , class _Ax > diff --git a/classstdex_1_1idrec_1_1record-members.html b/classstdex_1_1idrec_1_1record-members.html index 146442546..6464a5f6e 100644 --- a/classstdex_1_1idrec_1_1record-members.html +++ b/classstdex_1_1idrec_1_1record-members.html @@ -91,7 +91,7 @@ $(function() { diff --git a/classstdex_1_1idrec_1_1record.html b/classstdex_1_1idrec_1_1record.html index fdb5eb4cc..d40087ffd 100644 --- a/classstdex_1_1idrec_1_1record.html +++ b/classstdex_1_1idrec_1_1record.html @@ -380,7 +380,7 @@ template<class T , class T_ID , const T_ID ID, class T_SIZE , unsigned int AL diff --git a/classstdex_1_1lazy__progress-members.html b/classstdex_1_1lazy__progress-members.html index 3d0ae4604..e03f84b22 100644 --- a/classstdex_1_1lazy__progress-members.html +++ b/classstdex_1_1lazy__progress-members.html @@ -95,7 +95,7 @@ $(function() { diff --git a/classstdex_1_1lazy__progress.html b/classstdex_1_1lazy__progress.html index 688735fcd..4e705121d 100644 --- a/classstdex_1_1lazy__progress.html +++ b/classstdex_1_1lazy__progress.html @@ -285,7 +285,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__angle-members.html b/classstdex_1_1parser_1_1basic__angle-members.html index d98e09a4f..48ef202d3 100644 --- a/classstdex_1_1parser_1_1basic__angle-members.html +++ b/classstdex_1_1parser_1_1basic__angle-members.html @@ -99,7 +99,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__angle.html b/classstdex_1_1parser_1_1basic__angle.html index f49547def..f658ad8b3 100644 --- a/classstdex_1_1parser_1_1basic__angle.html +++ b/classstdex_1_1parser_1_1basic__angle.html @@ -250,7 +250,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__any__cu-members.html b/classstdex_1_1parser_1_1basic__any__cu-members.html index eba5bf983..efccdba93 100644 --- a/classstdex_1_1parser_1_1basic__any__cu-members.html +++ b/classstdex_1_1parser_1_1basic__any__cu-members.html @@ -92,7 +92,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__any__cu.html b/classstdex_1_1parser_1_1basic__any__cu.html index ec34fe7b2..94fa90253 100644 --- a/classstdex_1_1parser_1_1basic__any__cu.html +++ b/classstdex_1_1parser_1_1basic__any__cu.html @@ -194,7 +194,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__bol-members.html b/classstdex_1_1parser_1_1basic__bol-members.html index 94b73e859..5f508ce2f 100644 --- a/classstdex_1_1parser_1_1basic__bol-members.html +++ b/classstdex_1_1parser_1_1basic__bol-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__bol.html b/classstdex_1_1parser_1_1basic__bol.html index 98023fd38..7ce929d57 100644 --- a/classstdex_1_1parser_1_1basic__bol.html +++ b/classstdex_1_1parser_1_1basic__bol.html @@ -201,7 +201,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__branch-members.html b/classstdex_1_1parser_1_1basic__branch-members.html index adc815c66..83379d9aa 100644 --- a/classstdex_1_1parser_1_1basic__branch-members.html +++ b/classstdex_1_1parser_1_1basic__branch-members.html @@ -99,7 +99,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__branch.html b/classstdex_1_1parser_1_1basic__branch.html index 204989807..f26ab3725 100644 --- a/classstdex_1_1parser_1_1basic__branch.html +++ b/classstdex_1_1parser_1_1basic__branch.html @@ -261,7 +261,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__chemical__formula-members.html b/classstdex_1_1parser_1_1basic__chemical__formula-members.html index ebc6dfae1..2c7f452d4 100644 --- a/classstdex_1_1parser_1_1basic__chemical__formula-members.html +++ b/classstdex_1_1parser_1_1basic__chemical__formula-members.html @@ -97,7 +97,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__chemical__formula.html b/classstdex_1_1parser_1_1basic__chemical__formula.html index 7ec210de2..850ea98b8 100644 --- a/classstdex_1_1parser_1_1basic__chemical__formula.html +++ b/classstdex_1_1parser_1_1basic__chemical__formula.html @@ -245,7 +245,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__cu-members.html b/classstdex_1_1parser_1_1basic__cu-members.html index 1ca5a3bc4..51f61b28f 100644 --- a/classstdex_1_1parser_1_1basic__cu-members.html +++ b/classstdex_1_1parser_1_1basic__cu-members.html @@ -94,7 +94,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__cu.html b/classstdex_1_1parser_1_1basic__cu.html index fad3165fa..83d4b7dcf 100644 --- a/classstdex_1_1parser_1_1basic__cu.html +++ b/classstdex_1_1parser_1_1basic__cu.html @@ -204,7 +204,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__cu__set-members.html b/classstdex_1_1parser_1_1basic__cu__set-members.html index 9d5427728..a658325c8 100644 --- a/classstdex_1_1parser_1_1basic__cu__set-members.html +++ b/classstdex_1_1parser_1_1basic__cu__set-members.html @@ -96,7 +96,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__cu__set.html b/classstdex_1_1parser_1_1basic__cu__set.html index 56dc1c21e..07c994299 100644 --- a/classstdex_1_1parser_1_1basic__cu__set.html +++ b/classstdex_1_1parser_1_1basic__cu__set.html @@ -218,7 +218,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__date-members.html b/classstdex_1_1parser_1_1basic__date-members.html index a296089f1..f73ffe6e7 100644 --- a/classstdex_1_1parser_1_1basic__date-members.html +++ b/classstdex_1_1parser_1_1basic__date-members.html @@ -83,25 +83,24 @@ $(function() { basic_date(int format_mask, const std::shared_ptr< basic_integer< T > > &_day, const std::shared_ptr< basic_integer< T > > &_month, const std::shared_ptr< basic_integer< T > > &_year, const std::shared_ptr< basic_set< T > > &separator, const std::shared_ptr< basic_parser< T > > &space, const std::locale &locale=std::locale()) (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T >inline basic_parser(const std::locale &locale=std::locale()) (defined in stdex::parser::basic_parser< T >)stdex::parser::basic_parser< T >inline day (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T > - format enum name (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T > - format (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T > - intervalstdex::parser::basic_parser< T > - invalidate() (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T >inlinevirtual - is_valid(size_t day, size_t month) (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T >inlineprotectedstatic - m_format_mask (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T >protected - m_locale (defined in stdex::parser::basic_parser< T >)stdex::parser::basic_parser< T >protected - m_separator (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T >protected - m_space (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T >protected - match(_In_reads_or_z_(end) const T *text, size_t start=0, size_t end=(size_t) -1, int flags=match_default) (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T >inlinevirtual - match(const std::basic_string< T, _Traits, _Ax > &text, size_t start=0, size_t end=(size_t) -1, int flags=match_default) (defined in stdex::parser::basic_parser< T >)stdex::parser::basic_parser< T >inline - month (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T > - search(_In_reads_or_z_(end) const T *text, size_t start=0, size_t end=(size_t) -1, int flags=match_default) (defined in stdex::parser::basic_parser< T >)stdex::parser::basic_parser< T >inline - year (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T > - ~basic_parser() (defined in stdex::parser::basic_parser< T >)stdex::parser::basic_parser< T >inlinevirtual + format (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T > + intervalstdex::parser::basic_parser< T > + invalidate() (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T >inlinevirtual + is_valid(size_t day, size_t month) (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T >inlineprotectedstatic + m_format_mask (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T >protected + m_locale (defined in stdex::parser::basic_parser< T >)stdex::parser::basic_parser< T >protected + m_separator (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T >protected + m_space (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T >protected + match(_In_reads_or_z_(end) const T *text, size_t start=0, size_t end=(size_t) -1, int flags=match_default) (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T >inlinevirtual + match(const std::basic_string< T, _Traits, _Ax > &text, size_t start=0, size_t end=(size_t) -1, int flags=match_default) (defined in stdex::parser::basic_parser< T >)stdex::parser::basic_parser< T >inline + month (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T > + search(_In_reads_or_z_(end) const T *text, size_t start=0, size_t end=(size_t) -1, int flags=match_default) (defined in stdex::parser::basic_parser< T >)stdex::parser::basic_parser< T >inline + year (defined in stdex::parser::basic_date< T >)stdex::parser::basic_date< T > + ~basic_parser() (defined in stdex::parser::basic_parser< T >)stdex::parser::basic_parser< T >inlinevirtual diff --git a/classstdex_1_1parser_1_1basic__date.html b/classstdex_1_1parser_1_1basic__date.html index 9d5932e7b..600554253 100644 --- a/classstdex_1_1parser_1_1basic__date.html +++ b/classstdex_1_1parser_1_1basic__date.html @@ -75,7 +75,6 @@ $(function() {
-Public Types | Public Member Functions | Public Attributes | Static Protected Member Functions | @@ -99,21 +98,6 @@ Inheritance diagram for stdex::parser::basic_date< T >:
- - - -

-Public Types

enum class  format {
-  dmy = 0x1 -, mdy = 0x2 -, ymd = 0x4 -, ym = 0x8 -,
-  my = 0x10 -, dm = 0x20 -, md = 0x40 -
- }
 

Public Member Functions

@@ -143,9 +127,9 @@ virtual void invalidate - - + + @@ -274,7 +258,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__dns__domain__char-members.html b/classstdex_1_1parser_1_1basic__dns__domain__char-members.html index 68e8d24b6..44aa6aa99 100644 --- a/classstdex_1_1parser_1_1basic__dns__domain__char-members.html +++ b/classstdex_1_1parser_1_1basic__dns__domain__char-members.html @@ -94,7 +94,7 @@ $(function() {

Public Attributes

-format format
 
+date_format_t format
 
std::shared_ptr< basic_integer< T > > day
 
diff --git a/classstdex_1_1parser_1_1basic__dns__domain__char.html b/classstdex_1_1parser_1_1basic__dns__domain__char.html index 77359366e..96427a3a2 100644 --- a/classstdex_1_1parser_1_1basic__dns__domain__char.html +++ b/classstdex_1_1parser_1_1basic__dns__domain__char.html @@ -206,7 +206,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__dns__name-members.html b/classstdex_1_1parser_1_1basic__dns__name-members.html index 837b93d72..8b3947f35 100644 --- a/classstdex_1_1parser_1_1basic__dns__name-members.html +++ b/classstdex_1_1parser_1_1basic__dns__name-members.html @@ -95,7 +95,7 @@ $(function() {
diff --git a/classstdex_1_1parser_1_1basic__dns__name.html b/classstdex_1_1parser_1_1basic__dns__name.html index c985a10e6..bc92b4420 100644 --- a/classstdex_1_1parser_1_1basic__dns__name.html +++ b/classstdex_1_1parser_1_1basic__dns__name.html @@ -208,7 +208,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__email__address-members.html b/classstdex_1_1parser_1_1basic__email__address-members.html index 921c1d39a..7d9c93b27 100644 --- a/classstdex_1_1parser_1_1basic__email__address-members.html +++ b/classstdex_1_1parser_1_1basic__email__address-members.html @@ -99,7 +99,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__email__address.html b/classstdex_1_1parser_1_1basic__email__address.html index f0bca36dd..3857fcb2e 100644 --- a/classstdex_1_1parser_1_1basic__email__address.html +++ b/classstdex_1_1parser_1_1basic__email__address.html @@ -251,7 +251,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__emoticon-members.html b/classstdex_1_1parser_1_1basic__emoticon-members.html index 6c2474cb3..cc2c4e99a 100644 --- a/classstdex_1_1parser_1_1basic__emoticon-members.html +++ b/classstdex_1_1parser_1_1basic__emoticon-members.html @@ -97,7 +97,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__emoticon.html b/classstdex_1_1parser_1_1basic__emoticon.html index 18bc530be..d4dd85d20 100644 --- a/classstdex_1_1parser_1_1basic__emoticon.html +++ b/classstdex_1_1parser_1_1basic__emoticon.html @@ -249,7 +249,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__eol-members.html b/classstdex_1_1parser_1_1basic__eol-members.html index e5eac168b..b6c356028 100644 --- a/classstdex_1_1parser_1_1basic__eol-members.html +++ b/classstdex_1_1parser_1_1basic__eol-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__eol.html b/classstdex_1_1parser_1_1basic__eol.html index 0a7f7ee83..949326578 100644 --- a/classstdex_1_1parser_1_1basic__eol.html +++ b/classstdex_1_1parser_1_1basic__eol.html @@ -201,7 +201,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__fraction-members.html b/classstdex_1_1parser_1_1basic__fraction-members.html index d93862c98..d54a7a72d 100644 --- a/classstdex_1_1parser_1_1basic__fraction-members.html +++ b/classstdex_1_1parser_1_1basic__fraction-members.html @@ -95,7 +95,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__fraction.html b/classstdex_1_1parser_1_1basic__fraction.html index e28cf4dca..efe114e1e 100644 --- a/classstdex_1_1parser_1_1basic__fraction.html +++ b/classstdex_1_1parser_1_1basic__fraction.html @@ -238,7 +238,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__integer-members.html b/classstdex_1_1parser_1_1basic__integer-members.html index e23f92b63..18515ebd3 100644 --- a/classstdex_1_1parser_1_1basic__integer-members.html +++ b/classstdex_1_1parser_1_1basic__integer-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__integer.html b/classstdex_1_1parser_1_1basic__integer.html index 98f1bec6b..00510db00 100644 --- a/classstdex_1_1parser_1_1basic__integer.html +++ b/classstdex_1_1parser_1_1basic__integer.html @@ -183,7 +183,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__integer10-members.html b/classstdex_1_1parser_1_1basic__integer10-members.html index dec798175..03ad3b572 100644 --- a/classstdex_1_1parser_1_1basic__integer10-members.html +++ b/classstdex_1_1parser_1_1basic__integer10-members.html @@ -104,7 +104,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__integer10.html b/classstdex_1_1parser_1_1basic__integer10.html index 31ead02c8..fd03e0022 100644 --- a/classstdex_1_1parser_1_1basic__integer10.html +++ b/classstdex_1_1parser_1_1basic__integer10.html @@ -240,7 +240,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__integer10ts-members.html b/classstdex_1_1parser_1_1basic__integer10ts-members.html index 2c8414f3a..4f53cb122 100644 --- a/classstdex_1_1parser_1_1basic__integer10ts-members.html +++ b/classstdex_1_1parser_1_1basic__integer10ts-members.html @@ -98,7 +98,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__integer10ts.html b/classstdex_1_1parser_1_1basic__integer10ts.html index 9707cdf23..7f7a5b8db 100644 --- a/classstdex_1_1parser_1_1basic__integer10ts.html +++ b/classstdex_1_1parser_1_1basic__integer10ts.html @@ -256,7 +256,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__integer16-members.html b/classstdex_1_1parser_1_1basic__integer16-members.html index 4993d858d..34d3032ef 100644 --- a/classstdex_1_1parser_1_1basic__integer16-members.html +++ b/classstdex_1_1parser_1_1basic__integer16-members.html @@ -110,7 +110,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__integer16.html b/classstdex_1_1parser_1_1basic__integer16.html index f54ba916f..0649b2ef5 100644 --- a/classstdex_1_1parser_1_1basic__integer16.html +++ b/classstdex_1_1parser_1_1basic__integer16.html @@ -258,7 +258,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__ipv4__address-members.html b/classstdex_1_1parser_1_1basic__ipv4__address-members.html index 97d2a4ee2..9f2674bfe 100644 --- a/classstdex_1_1parser_1_1basic__ipv4__address-members.html +++ b/classstdex_1_1parser_1_1basic__ipv4__address-members.html @@ -105,7 +105,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__ipv4__address.html b/classstdex_1_1parser_1_1basic__ipv4__address.html index 0ac356288..5bd6a211d 100644 --- a/classstdex_1_1parser_1_1basic__ipv4__address.html +++ b/classstdex_1_1parser_1_1basic__ipv4__address.html @@ -271,7 +271,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__ipv6__address-members.html b/classstdex_1_1parser_1_1basic__ipv6__address-members.html index 33060c4aa..e90002a66 100644 --- a/classstdex_1_1parser_1_1basic__ipv6__address-members.html +++ b/classstdex_1_1parser_1_1basic__ipv6__address-members.html @@ -113,7 +113,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__ipv6__address.html b/classstdex_1_1parser_1_1basic__ipv6__address.html index b935e7c34..b98c88c90 100644 --- a/classstdex_1_1parser_1_1basic__ipv6__address.html +++ b/classstdex_1_1parser_1_1basic__ipv6__address.html @@ -296,7 +296,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__ipv6__scope__id__char-members.html b/classstdex_1_1parser_1_1basic__ipv6__scope__id__char-members.html index 366af3fc0..6f45e4d29 100644 --- a/classstdex_1_1parser_1_1basic__ipv6__scope__id__char-members.html +++ b/classstdex_1_1parser_1_1basic__ipv6__scope__id__char-members.html @@ -92,7 +92,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__ipv6__scope__id__char.html b/classstdex_1_1parser_1_1basic__ipv6__scope__id__char.html index 52bef4efa..57040f1d4 100644 --- a/classstdex_1_1parser_1_1basic__ipv6__scope__id__char.html +++ b/classstdex_1_1parser_1_1basic__ipv6__scope__id__char.html @@ -194,7 +194,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__iterations-members.html b/classstdex_1_1parser_1_1basic__iterations-members.html index 2b8dd4066..89cea53a3 100644 --- a/classstdex_1_1parser_1_1basic__iterations-members.html +++ b/classstdex_1_1parser_1_1basic__iterations-members.html @@ -96,7 +96,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__iterations.html b/classstdex_1_1parser_1_1basic__iterations.html index ff99c3409..43bb5312c 100644 --- a/classstdex_1_1parser_1_1basic__iterations.html +++ b/classstdex_1_1parser_1_1basic__iterations.html @@ -214,7 +214,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__json__string-members.html b/classstdex_1_1parser_1_1basic__json__string-members.html index acb36eb4a..94dc8a14a 100644 --- a/classstdex_1_1parser_1_1basic__json__string-members.html +++ b/classstdex_1_1parser_1_1basic__json__string-members.html @@ -104,7 +104,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__json__string.html b/classstdex_1_1parser_1_1basic__json__string.html index 48ec07673..5008976fe 100644 --- a/classstdex_1_1parser_1_1basic__json__string.html +++ b/classstdex_1_1parser_1_1basic__json__string.html @@ -266,7 +266,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__mixed__numeral-members.html b/classstdex_1_1parser_1_1basic__mixed__numeral-members.html index 681df9b59..46e2c414c 100644 --- a/classstdex_1_1parser_1_1basic__mixed__numeral-members.html +++ b/classstdex_1_1parser_1_1basic__mixed__numeral-members.html @@ -98,7 +98,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__mixed__numeral.html b/classstdex_1_1parser_1_1basic__mixed__numeral.html index fb9fdb2bf..e45b38d68 100644 --- a/classstdex_1_1parser_1_1basic__mixed__numeral.html +++ b/classstdex_1_1parser_1_1basic__mixed__numeral.html @@ -253,7 +253,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__monetary__numeral-members.html b/classstdex_1_1parser_1_1basic__monetary__numeral-members.html index 7a1f47b21..194a562ab 100644 --- a/classstdex_1_1parser_1_1basic__monetary__numeral-members.html +++ b/classstdex_1_1parser_1_1basic__monetary__numeral-members.html @@ -99,7 +99,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__monetary__numeral.html b/classstdex_1_1parser_1_1basic__monetary__numeral.html index 13b2acf27..e03d85e09 100644 --- a/classstdex_1_1parser_1_1basic__monetary__numeral.html +++ b/classstdex_1_1parser_1_1basic__monetary__numeral.html @@ -257,7 +257,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__noop-members.html b/classstdex_1_1parser_1_1basic__noop-members.html index d8e0ea787..fb74123a0 100644 --- a/classstdex_1_1parser_1_1basic__noop-members.html +++ b/classstdex_1_1parser_1_1basic__noop-members.html @@ -91,7 +91,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__noop.html b/classstdex_1_1parser_1_1basic__noop.html index bc485fa2f..934422cde 100644 --- a/classstdex_1_1parser_1_1basic__noop.html +++ b/classstdex_1_1parser_1_1basic__noop.html @@ -191,7 +191,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__parser-members.html b/classstdex_1_1parser_1_1basic__parser-members.html index 4fdf89217..4f736404c 100644 --- a/classstdex_1_1parser_1_1basic__parser-members.html +++ b/classstdex_1_1parser_1_1basic__parser-members.html @@ -91,7 +91,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__parser.html b/classstdex_1_1parser_1_1basic__parser.html index da397ca1f..e73554d89 100644 --- a/classstdex_1_1parser_1_1basic__parser.html +++ b/classstdex_1_1parser_1_1basic__parser.html @@ -183,7 +183,7 @@ class stdex::parser::basic_parser< T >

Base template for all parse

diff --git a/classstdex_1_1parser_1_1basic__permutation-members.html b/classstdex_1_1parser_1_1basic__permutation-members.html index 02f6c8cef..ac34a7427 100644 --- a/classstdex_1_1parser_1_1basic__permutation-members.html +++ b/classstdex_1_1parser_1_1basic__permutation-members.html @@ -98,7 +98,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__permutation.html b/classstdex_1_1parser_1_1basic__permutation.html index 08ea415a5..c7c155c24 100644 --- a/classstdex_1_1parser_1_1basic__permutation.html +++ b/classstdex_1_1parser_1_1basic__permutation.html @@ -222,7 +222,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__phone__number-members.html b/classstdex_1_1parser_1_1basic__phone__number-members.html index d1d76b103..2a00158a4 100644 --- a/classstdex_1_1parser_1_1basic__phone__number-members.html +++ b/classstdex_1_1parser_1_1basic__phone__number-members.html @@ -99,7 +99,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__phone__number.html b/classstdex_1_1parser_1_1basic__phone__number.html index 671875fc7..b66e17656 100644 --- a/classstdex_1_1parser_1_1basic__phone__number.html +++ b/classstdex_1_1parser_1_1basic__phone__number.html @@ -252,7 +252,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__punct__cu-members.html b/classstdex_1_1parser_1_1basic__punct__cu-members.html index 6355ed39b..395fe1727 100644 --- a/classstdex_1_1parser_1_1basic__punct__cu-members.html +++ b/classstdex_1_1parser_1_1basic__punct__cu-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__punct__cu.html b/classstdex_1_1parser_1_1basic__punct__cu.html index 835da3c2b..6ddaba36a 100644 --- a/classstdex_1_1parser_1_1basic__punct__cu.html +++ b/classstdex_1_1parser_1_1basic__punct__cu.html @@ -201,7 +201,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__roman__numeral-members.html b/classstdex_1_1parser_1_1basic__roman__numeral-members.html index a7a31bc55..bdf921748 100644 --- a/classstdex_1_1parser_1_1basic__roman__numeral-members.html +++ b/classstdex_1_1parser_1_1basic__roman__numeral-members.html @@ -103,7 +103,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__roman__numeral.html b/classstdex_1_1parser_1_1basic__roman__numeral.html index fd44bec77..79c50102f 100644 --- a/classstdex_1_1parser_1_1basic__roman__numeral.html +++ b/classstdex_1_1parser_1_1basic__roman__numeral.html @@ -237,7 +237,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__scientific__numeral-members.html b/classstdex_1_1parser_1_1basic__scientific__numeral-members.html index ee4f6687e..710143c87 100644 --- a/classstdex_1_1parser_1_1basic__scientific__numeral-members.html +++ b/classstdex_1_1parser_1_1basic__scientific__numeral-members.html @@ -103,7 +103,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__scientific__numeral.html b/classstdex_1_1parser_1_1basic__scientific__numeral.html index a13f4629e..b0983d089 100644 --- a/classstdex_1_1parser_1_1basic__scientific__numeral.html +++ b/classstdex_1_1parser_1_1basic__scientific__numeral.html @@ -273,7 +273,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__score-members.html b/classstdex_1_1parser_1_1basic__score-members.html index ba0c197e0..f84f8f3ba 100644 --- a/classstdex_1_1parser_1_1basic__score-members.html +++ b/classstdex_1_1parser_1_1basic__score-members.html @@ -96,7 +96,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__score.html b/classstdex_1_1parser_1_1basic__score.html index eea0784d5..f26f58c65 100644 --- a/classstdex_1_1parser_1_1basic__score.html +++ b/classstdex_1_1parser_1_1basic__score.html @@ -242,7 +242,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__sequence-members.html b/classstdex_1_1parser_1_1basic__sequence-members.html index 87516a0b5..805f4e4b0 100644 --- a/classstdex_1_1parser_1_1basic__sequence-members.html +++ b/classstdex_1_1parser_1_1basic__sequence-members.html @@ -97,7 +97,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__sequence.html b/classstdex_1_1parser_1_1basic__sequence.html index a241f5695..3ea16917c 100644 --- a/classstdex_1_1parser_1_1basic__sequence.html +++ b/classstdex_1_1parser_1_1basic__sequence.html @@ -215,7 +215,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__set-members.html b/classstdex_1_1parser_1_1basic__set-members.html index 8a8c64f1f..fc8b9eb12 100644 --- a/classstdex_1_1parser_1_1basic__set-members.html +++ b/classstdex_1_1parser_1_1basic__set-members.html @@ -94,7 +94,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__set.html b/classstdex_1_1parser_1_1basic__set.html index 8b85f642f..2ac64f839 100644 --- a/classstdex_1_1parser_1_1basic__set.html +++ b/classstdex_1_1parser_1_1basic__set.html @@ -229,7 +229,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__signed__numeral-members.html b/classstdex_1_1parser_1_1basic__signed__numeral-members.html index e2966be2c..ada1722a3 100644 --- a/classstdex_1_1parser_1_1basic__signed__numeral-members.html +++ b/classstdex_1_1parser_1_1basic__signed__numeral-members.html @@ -96,7 +96,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__signed__numeral.html b/classstdex_1_1parser_1_1basic__signed__numeral.html index 6c328fb64..3c7388e71 100644 --- a/classstdex_1_1parser_1_1basic__signed__numeral.html +++ b/classstdex_1_1parser_1_1basic__signed__numeral.html @@ -245,7 +245,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__space__cu-members.html b/classstdex_1_1parser_1_1basic__space__cu-members.html index bc0f870ff..523250b33 100644 --- a/classstdex_1_1parser_1_1basic__space__cu-members.html +++ b/classstdex_1_1parser_1_1basic__space__cu-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__space__cu.html b/classstdex_1_1parser_1_1basic__space__cu.html index f651f85de..bba4de342 100644 --- a/classstdex_1_1parser_1_1basic__space__cu.html +++ b/classstdex_1_1parser_1_1basic__space__cu.html @@ -201,7 +201,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__space__or__punct__cu-members.html b/classstdex_1_1parser_1_1basic__space__or__punct__cu-members.html index fa3666e0d..b018e9bcd 100644 --- a/classstdex_1_1parser_1_1basic__space__or__punct__cu-members.html +++ b/classstdex_1_1parser_1_1basic__space__or__punct__cu-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__space__or__punct__cu.html b/classstdex_1_1parser_1_1basic__space__or__punct__cu.html index 90f42f5f6..a6488facd 100644 --- a/classstdex_1_1parser_1_1basic__space__or__punct__cu.html +++ b/classstdex_1_1parser_1_1basic__space__or__punct__cu.html @@ -201,7 +201,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__string-members.html b/classstdex_1_1parser_1_1basic__string-members.html index 7ca6c0563..6a7a434bc 100644 --- a/classstdex_1_1parser_1_1basic__string-members.html +++ b/classstdex_1_1parser_1_1basic__string-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__string.html b/classstdex_1_1parser_1_1basic__string.html index 5071d6c03..da8cfdb21 100644 --- a/classstdex_1_1parser_1_1basic__string.html +++ b/classstdex_1_1parser_1_1basic__string.html @@ -201,7 +201,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__string__branch-members.html b/classstdex_1_1parser_1_1basic__string__branch-members.html index f56e71f39..0de76ed0b 100644 --- a/classstdex_1_1parser_1_1basic__string__branch-members.html +++ b/classstdex_1_1parser_1_1basic__string__branch-members.html @@ -104,7 +104,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__string__branch.html b/classstdex_1_1parser_1_1basic__string__branch.html index 3a7d3b560..f48e111a3 100644 --- a/classstdex_1_1parser_1_1basic__string__branch.html +++ b/classstdex_1_1parser_1_1basic__string__branch.html @@ -193,7 +193,7 @@ class stdex::parser::basic_string_branch< T, T_parser >

Test for a

diff --git a/classstdex_1_1parser_1_1basic__time-members.html b/classstdex_1_1parser_1_1basic__time-members.html index e479e93f5..4c9aa8f9e 100644 --- a/classstdex_1_1parser_1_1basic__time-members.html +++ b/classstdex_1_1parser_1_1basic__time-members.html @@ -98,7 +98,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__time.html b/classstdex_1_1parser_1_1basic__time.html index 62a009408..c5a5e8631 100644 --- a/classstdex_1_1parser_1_1basic__time.html +++ b/classstdex_1_1parser_1_1basic__time.html @@ -248,7 +248,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__url-members.html b/classstdex_1_1parser_1_1basic__url-members.html index 1ded2765b..7795cfc8a 100644 --- a/classstdex_1_1parser_1_1basic__url-members.html +++ b/classstdex_1_1parser_1_1basic__url-members.html @@ -108,7 +108,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__url.html b/classstdex_1_1parser_1_1basic__url.html index f216e6400..fc55a5211 100644 --- a/classstdex_1_1parser_1_1basic__url.html +++ b/classstdex_1_1parser_1_1basic__url.html @@ -278,7 +278,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__url__password__char-members.html b/classstdex_1_1parser_1_1basic__url__password__char-members.html index 1f1543931..78b97fb5d 100644 --- a/classstdex_1_1parser_1_1basic__url__password__char-members.html +++ b/classstdex_1_1parser_1_1basic__url__password__char-members.html @@ -92,7 +92,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__url__password__char.html b/classstdex_1_1parser_1_1basic__url__password__char.html index 74b6b73f1..733bf0391 100644 --- a/classstdex_1_1parser_1_1basic__url__password__char.html +++ b/classstdex_1_1parser_1_1basic__url__password__char.html @@ -194,7 +194,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__url__path-members.html b/classstdex_1_1parser_1_1basic__url__path-members.html index 893e921ec..121a96e66 100644 --- a/classstdex_1_1parser_1_1basic__url__path-members.html +++ b/classstdex_1_1parser_1_1basic__url__path-members.html @@ -98,7 +98,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__url__path.html b/classstdex_1_1parser_1_1basic__url__path.html index ca347491e..b623828d5 100644 --- a/classstdex_1_1parser_1_1basic__url__path.html +++ b/classstdex_1_1parser_1_1basic__url__path.html @@ -248,7 +248,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__url__path__char-members.html b/classstdex_1_1parser_1_1basic__url__path__char-members.html index db67eeee5..ebce3a81a 100644 --- a/classstdex_1_1parser_1_1basic__url__path__char-members.html +++ b/classstdex_1_1parser_1_1basic__url__path__char-members.html @@ -92,7 +92,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__url__path__char.html b/classstdex_1_1parser_1_1basic__url__path__char.html index 19bec0c21..b56462f30 100644 --- a/classstdex_1_1parser_1_1basic__url__path__char.html +++ b/classstdex_1_1parser_1_1basic__url__path__char.html @@ -194,7 +194,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1basic__url__username__char-members.html b/classstdex_1_1parser_1_1basic__url__username__char-members.html index ca3460fe8..af16eadc4 100644 --- a/classstdex_1_1parser_1_1basic__url__username__char-members.html +++ b/classstdex_1_1parser_1_1basic__url__username__char-members.html @@ -92,7 +92,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__url__username__char.html b/classstdex_1_1parser_1_1basic__url__username__char.html index cecf10adf..b6eff0cb7 100644 --- a/classstdex_1_1parser_1_1basic__url__username__char.html +++ b/classstdex_1_1parser_1_1basic__url__username__char.html @@ -194,7 +194,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1http__agent-members.html b/classstdex_1_1parser_1_1http__agent-members.html index 3df2c06ca..206773771 100644 --- a/classstdex_1_1parser_1_1http__agent-members.html +++ b/classstdex_1_1parser_1_1http__agent-members.html @@ -88,7 +88,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__agent.html b/classstdex_1_1parser_1_1http__agent.html index 6f776f218..bde864532 100644 --- a/classstdex_1_1parser_1_1http__agent.html +++ b/classstdex_1_1parser_1_1http__agent.html @@ -226,7 +226,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__any__type-members.html b/classstdex_1_1parser_1_1http__any__type-members.html index e621c70c3..ebbf55a0a 100644 --- a/classstdex_1_1parser_1_1http__any__type-members.html +++ b/classstdex_1_1parser_1_1http__any__type-members.html @@ -85,7 +85,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__any__type.html b/classstdex_1_1parser_1_1http__any__type.html index a1c349bad..f7ff8979e 100644 --- a/classstdex_1_1parser_1_1http__any__type.html +++ b/classstdex_1_1parser_1_1http__any__type.html @@ -187,7 +187,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__asterisk-members.html b/classstdex_1_1parser_1_1http__asterisk-members.html index 669049f9e..4069f36b7 100644 --- a/classstdex_1_1parser_1_1http__asterisk-members.html +++ b/classstdex_1_1parser_1_1http__asterisk-members.html @@ -85,7 +85,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__asterisk.html b/classstdex_1_1parser_1_1http__asterisk.html index ce0db74f7..2aa8cd25b 100644 --- a/classstdex_1_1parser_1_1http__asterisk.html +++ b/classstdex_1_1parser_1_1http__asterisk.html @@ -187,7 +187,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__cookie-members.html b/classstdex_1_1parser_1_1http__cookie-members.html index e700425bb..a550b3779 100644 --- a/classstdex_1_1parser_1_1http__cookie-members.html +++ b/classstdex_1_1parser_1_1http__cookie-members.html @@ -90,7 +90,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__cookie.html b/classstdex_1_1parser_1_1http__cookie.html index 59037d11d..5f0c2232b 100644 --- a/classstdex_1_1parser_1_1http__cookie.html +++ b/classstdex_1_1parser_1_1http__cookie.html @@ -236,7 +236,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__cookie__parameter-members.html b/classstdex_1_1parser_1_1http__cookie__parameter-members.html index 8a419a9b9..ccb85311f 100644 --- a/classstdex_1_1parser_1_1http__cookie__parameter-members.html +++ b/classstdex_1_1parser_1_1http__cookie__parameter-members.html @@ -89,7 +89,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__cookie__parameter.html b/classstdex_1_1parser_1_1http__cookie__parameter.html index a9166185e..830b1ce56 100644 --- a/classstdex_1_1parser_1_1http__cookie__parameter.html +++ b/classstdex_1_1parser_1_1http__cookie__parameter.html @@ -230,7 +230,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__header-members.html b/classstdex_1_1parser_1_1http__header-members.html index d618a14b4..8d2813d44 100644 --- a/classstdex_1_1parser_1_1http__header-members.html +++ b/classstdex_1_1parser_1_1http__header-members.html @@ -89,7 +89,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__header.html b/classstdex_1_1parser_1_1http__header.html index ce80d36ee..7dd1fdfcc 100644 --- a/classstdex_1_1parser_1_1http__header.html +++ b/classstdex_1_1parser_1_1http__header.html @@ -230,7 +230,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__language-members.html b/classstdex_1_1parser_1_1http__language-members.html index be5de58cf..ffc3262fc 100644 --- a/classstdex_1_1parser_1_1http__language-members.html +++ b/classstdex_1_1parser_1_1http__language-members.html @@ -87,7 +87,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__language.html b/classstdex_1_1parser_1_1http__language.html index abec4c3e8..1f5b90061 100644 --- a/classstdex_1_1parser_1_1http__language.html +++ b/classstdex_1_1parser_1_1http__language.html @@ -223,7 +223,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__line__break-members.html b/classstdex_1_1parser_1_1http__line__break-members.html index 0513c2f11..f560edcef 100644 --- a/classstdex_1_1parser_1_1http__line__break-members.html +++ b/classstdex_1_1parser_1_1http__line__break-members.html @@ -85,7 +85,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__line__break.html b/classstdex_1_1parser_1_1http__line__break.html index 556365b3b..96167bedf 100644 --- a/classstdex_1_1parser_1_1http__line__break.html +++ b/classstdex_1_1parser_1_1http__line__break.html @@ -187,7 +187,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__media__range-members.html b/classstdex_1_1parser_1_1http__media__range-members.html index fe1f563b7..4b6a65ad7 100644 --- a/classstdex_1_1parser_1_1http__media__range-members.html +++ b/classstdex_1_1parser_1_1http__media__range-members.html @@ -89,7 +89,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__media__range.html b/classstdex_1_1parser_1_1http__media__range.html index 5a63138fd..67ba3568d 100644 --- a/classstdex_1_1parser_1_1http__media__range.html +++ b/classstdex_1_1parser_1_1http__media__range.html @@ -231,7 +231,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__media__type-members.html b/classstdex_1_1parser_1_1http__media__type-members.html index 0f017fc6b..d1c447d4c 100644 --- a/classstdex_1_1parser_1_1http__media__type-members.html +++ b/classstdex_1_1parser_1_1http__media__type-members.html @@ -90,7 +90,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__media__type.html b/classstdex_1_1parser_1_1http__media__type.html index 79ed26274..caa4211ea 100644 --- a/classstdex_1_1parser_1_1http__media__type.html +++ b/classstdex_1_1parser_1_1http__media__type.html @@ -239,7 +239,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__parameter-members.html b/classstdex_1_1parser_1_1http__parameter-members.html index dee4b7798..b261231ff 100644 --- a/classstdex_1_1parser_1_1http__parameter-members.html +++ b/classstdex_1_1parser_1_1http__parameter-members.html @@ -89,7 +89,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__parameter.html b/classstdex_1_1parser_1_1http__parameter.html index 66399cb03..f8f8a77c6 100644 --- a/classstdex_1_1parser_1_1http__parameter.html +++ b/classstdex_1_1parser_1_1http__parameter.html @@ -232,7 +232,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__protocol-members.html b/classstdex_1_1parser_1_1http__protocol-members.html index 39d1051b1..aa09f419c 100644 --- a/classstdex_1_1parser_1_1http__protocol-members.html +++ b/classstdex_1_1parser_1_1http__protocol-members.html @@ -91,7 +91,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__protocol.html b/classstdex_1_1parser_1_1http__protocol.html index 3601202da..2d12dbb1c 100644 --- a/classstdex_1_1parser_1_1http__protocol.html +++ b/classstdex_1_1parser_1_1http__protocol.html @@ -236,7 +236,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__quoted__string-members.html b/classstdex_1_1parser_1_1http__quoted__string-members.html index 91d4aa4dd..dfed67d2a 100644 --- a/classstdex_1_1parser_1_1http__quoted__string-members.html +++ b/classstdex_1_1parser_1_1http__quoted__string-members.html @@ -88,7 +88,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__quoted__string.html b/classstdex_1_1parser_1_1http__quoted__string.html index af149ecc4..7e986148d 100644 --- a/classstdex_1_1parser_1_1http__quoted__string.html +++ b/classstdex_1_1parser_1_1http__quoted__string.html @@ -228,7 +228,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__request-members.html b/classstdex_1_1parser_1_1http__request-members.html index 1b470efb7..dc4403e92 100644 --- a/classstdex_1_1parser_1_1http__request-members.html +++ b/classstdex_1_1parser_1_1http__request-members.html @@ -91,7 +91,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__request.html b/classstdex_1_1parser_1_1http__request.html index 93a78f954..d8112217f 100644 --- a/classstdex_1_1parser_1_1http__request.html +++ b/classstdex_1_1parser_1_1http__request.html @@ -236,7 +236,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__space-members.html b/classstdex_1_1parser_1_1http__space-members.html index 359ec80e9..02a9a1f45 100644 --- a/classstdex_1_1parser_1_1http__space-members.html +++ b/classstdex_1_1parser_1_1http__space-members.html @@ -86,7 +86,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__space.html b/classstdex_1_1parser_1_1http__space.html index 81357fe67..fdc622270 100644 --- a/classstdex_1_1parser_1_1http__space.html +++ b/classstdex_1_1parser_1_1http__space.html @@ -194,7 +194,7 @@ Additional Inherited Members diff --git a/classstdex_1_1parser_1_1http__text__char-members.html b/classstdex_1_1parser_1_1http__text__char-members.html index ff6b261cc..d001d7276 100644 --- a/classstdex_1_1parser_1_1http__text__char-members.html +++ b/classstdex_1_1parser_1_1http__text__char-members.html @@ -86,7 +86,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__text__char.html b/classstdex_1_1parser_1_1http__text__char.html index 6448768c6..0b7354315 100644 --- a/classstdex_1_1parser_1_1http__text__char.html +++ b/classstdex_1_1parser_1_1http__text__char.html @@ -194,7 +194,7 @@ Additional Inherited Members diff --git a/classstdex_1_1parser_1_1http__token-members.html b/classstdex_1_1parser_1_1http__token-members.html index 367809f29..e762260a7 100644 --- a/classstdex_1_1parser_1_1http__token-members.html +++ b/classstdex_1_1parser_1_1http__token-members.html @@ -85,7 +85,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__token.html b/classstdex_1_1parser_1_1http__token.html index d518dc3da..756611184 100644 --- a/classstdex_1_1parser_1_1http__token.html +++ b/classstdex_1_1parser_1_1http__token.html @@ -187,7 +187,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__url-members.html b/classstdex_1_1parser_1_1http__url-members.html index 0b325ccc7..22caa73cf 100644 --- a/classstdex_1_1parser_1_1http__url-members.html +++ b/classstdex_1_1parser_1_1http__url-members.html @@ -91,7 +91,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__url.html b/classstdex_1_1parser_1_1http__url.html index 7cc987f7f..3ee0d56ec 100644 --- a/classstdex_1_1parser_1_1http__url.html +++ b/classstdex_1_1parser_1_1http__url.html @@ -235,7 +235,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__url__parameter-members.html b/classstdex_1_1parser_1_1http__url__parameter-members.html index 234e8a5eb..cd616ec4d 100644 --- a/classstdex_1_1parser_1_1http__url__parameter-members.html +++ b/classstdex_1_1parser_1_1http__url__parameter-members.html @@ -88,7 +88,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__url__parameter.html b/classstdex_1_1parser_1_1http__url__parameter.html index 5afeda488..b61f7a1d4 100644 --- a/classstdex_1_1parser_1_1http__url__parameter.html +++ b/classstdex_1_1parser_1_1http__url__parameter.html @@ -226,7 +226,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__url__path-members.html b/classstdex_1_1parser_1_1http__url__path-members.html index 9a0d90aa8..db0632cd8 100644 --- a/classstdex_1_1parser_1_1http__url__path-members.html +++ b/classstdex_1_1parser_1_1http__url__path-members.html @@ -87,7 +87,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__url__path.html b/classstdex_1_1parser_1_1http__url__path.html index 4b6b0a0d7..61fb59b19 100644 --- a/classstdex_1_1parser_1_1http__url__path.html +++ b/classstdex_1_1parser_1_1http__url__path.html @@ -224,7 +224,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__url__path__segment-members.html b/classstdex_1_1parser_1_1http__url__path__segment-members.html index ff6a52c39..646d90a49 100644 --- a/classstdex_1_1parser_1_1http__url__path__segment-members.html +++ b/classstdex_1_1parser_1_1http__url__path__segment-members.html @@ -85,7 +85,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__url__path__segment.html b/classstdex_1_1parser_1_1http__url__path__segment.html index f04e9d87f..31ba425b3 100644 --- a/classstdex_1_1parser_1_1http__url__path__segment.html +++ b/classstdex_1_1parser_1_1http__url__path__segment.html @@ -187,7 +187,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__url__port-members.html b/classstdex_1_1parser_1_1http__url__port-members.html index 6251e2759..d7da06d29 100644 --- a/classstdex_1_1parser_1_1http__url__port-members.html +++ b/classstdex_1_1parser_1_1http__url__port-members.html @@ -88,7 +88,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__url__port.html b/classstdex_1_1parser_1_1http__url__port.html index 518e4bebd..801bceaca 100644 --- a/classstdex_1_1parser_1_1http__url__port.html +++ b/classstdex_1_1parser_1_1http__url__port.html @@ -226,7 +226,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__url__server-members.html b/classstdex_1_1parser_1_1http__url__server-members.html index 7ea63b0a4..d23f30496 100644 --- a/classstdex_1_1parser_1_1http__url__server-members.html +++ b/classstdex_1_1parser_1_1http__url__server-members.html @@ -85,7 +85,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__url__server.html b/classstdex_1_1parser_1_1http__url__server.html index 49cb89204..eee96cbf3 100644 --- a/classstdex_1_1parser_1_1http__url__server.html +++ b/classstdex_1_1parser_1_1http__url__server.html @@ -187,7 +187,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__value-members.html b/classstdex_1_1parser_1_1http__value-members.html index c785a3fcd..0c94931d2 100644 --- a/classstdex_1_1parser_1_1http__value-members.html +++ b/classstdex_1_1parser_1_1http__value-members.html @@ -88,7 +88,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__value.html b/classstdex_1_1parser_1_1http__value.html index 4bdcf2953..c3c830b91 100644 --- a/classstdex_1_1parser_1_1http__value.html +++ b/classstdex_1_1parser_1_1http__value.html @@ -228,7 +228,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__value__collection-members.html b/classstdex_1_1parser_1_1http__value__collection-members.html index 37d8bdb43..6b1db5cf5 100644 --- a/classstdex_1_1parser_1_1http__value__collection-members.html +++ b/classstdex_1_1parser_1_1http__value__collection-members.html @@ -84,7 +84,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__value__collection.html b/classstdex_1_1parser_1_1http__value__collection.html index ddd9d8ed7..936f8ada5 100644 --- a/classstdex_1_1parser_1_1http__value__collection.html +++ b/classstdex_1_1parser_1_1http__value__collection.html @@ -107,7 +107,7 @@ class stdex::parser::http_value_collection< T >

Collection of HTTP

diff --git a/classstdex_1_1parser_1_1http__weight-members.html b/classstdex_1_1parser_1_1http__weight-members.html index 5b1a20bec..6dc25f68b 100644 --- a/classstdex_1_1parser_1_1http__weight-members.html +++ b/classstdex_1_1parser_1_1http__weight-members.html @@ -88,7 +88,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__weight.html b/classstdex_1_1parser_1_1http__weight.html index 5a3592779..4acd28d66 100644 --- a/classstdex_1_1parser_1_1http__weight.html +++ b/classstdex_1_1parser_1_1http__weight.html @@ -227,7 +227,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1http__weighted__value-members.html b/classstdex_1_1parser_1_1http__weighted__value-members.html index e4389529b..9ba177b03 100644 --- a/classstdex_1_1parser_1_1http__weighted__value-members.html +++ b/classstdex_1_1parser_1_1http__weighted__value-members.html @@ -90,7 +90,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1http__weighted__value.html b/classstdex_1_1parser_1_1http__weighted__value.html index 627d374ca..c48514184 100644 --- a/classstdex_1_1parser_1_1http__weighted__value.html +++ b/classstdex_1_1parser_1_1http__weighted__value.html @@ -237,7 +237,7 @@ template<class T , class T_asterisk = http_asterisk> diff --git a/classstdex_1_1parser_1_1parser__collection-members.html b/classstdex_1_1parser_1_1parser__collection-members.html index f135e5cb9..7d5746c86 100644 --- a/classstdex_1_1parser_1_1parser__collection-members.html +++ b/classstdex_1_1parser_1_1parser__collection-members.html @@ -95,7 +95,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1parser__collection.html b/classstdex_1_1parser_1_1parser__collection.html index 8fd626b0d..57abf1a16 100644 --- a/classstdex_1_1parser_1_1parser__collection.html +++ b/classstdex_1_1parser_1_1parser__collection.html @@ -192,7 +192,7 @@ template<class T > diff --git a/classstdex_1_1parser_1_1sgml__any__cp-members.html b/classstdex_1_1parser_1_1sgml__any__cp-members.html index 6301044eb..74829034d 100644 --- a/classstdex_1_1parser_1_1sgml__any__cp-members.html +++ b/classstdex_1_1parser_1_1sgml__any__cp-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1sgml__any__cp.html b/classstdex_1_1parser_1_1sgml__any__cp.html index 3073dfc25..246f496b5 100644 --- a/classstdex_1_1parser_1_1sgml__any__cp.html +++ b/classstdex_1_1parser_1_1sgml__any__cp.html @@ -199,7 +199,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1sgml__cp-members.html b/classstdex_1_1parser_1_1sgml__cp-members.html index 43aff84f9..16c7f7402 100644 --- a/classstdex_1_1parser_1_1sgml__cp-members.html +++ b/classstdex_1_1parser_1_1sgml__cp-members.html @@ -88,7 +88,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1sgml__cp.html b/classstdex_1_1parser_1_1sgml__cp.html index b33135934..f6f80fedb 100644 --- a/classstdex_1_1parser_1_1sgml__cp.html +++ b/classstdex_1_1parser_1_1sgml__cp.html @@ -200,7 +200,7 @@ Additional Inherited Members diff --git a/classstdex_1_1parser_1_1sgml__cp__set-members.html b/classstdex_1_1parser_1_1sgml__cp__set-members.html index 6042b0ce9..4c6e3a421 100644 --- a/classstdex_1_1parser_1_1sgml__cp__set-members.html +++ b/classstdex_1_1parser_1_1sgml__cp__set-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1sgml__cp__set.html b/classstdex_1_1parser_1_1sgml__cp__set.html index 1757c129c..e38324d55 100644 --- a/classstdex_1_1parser_1_1sgml__cp__set.html +++ b/classstdex_1_1parser_1_1sgml__cp__set.html @@ -216,7 +216,7 @@ size_t hit_offset diff --git a/classstdex_1_1parser_1_1sgml__dns__domain__char-members.html b/classstdex_1_1parser_1_1sgml__dns__domain__char-members.html index 4043c5624..a0c27550c 100644 --- a/classstdex_1_1parser_1_1sgml__dns__domain__char-members.html +++ b/classstdex_1_1parser_1_1sgml__dns__domain__char-members.html @@ -94,7 +94,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1sgml__dns__domain__char.html b/classstdex_1_1parser_1_1sgml__dns__domain__char.html index 8659f196e..550d506ae 100644 --- a/classstdex_1_1parser_1_1sgml__dns__domain__char.html +++ b/classstdex_1_1parser_1_1sgml__dns__domain__char.html @@ -208,7 +208,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1sgml__ipv6__scope__id__char-members.html b/classstdex_1_1parser_1_1sgml__ipv6__scope__id__char-members.html index 33f67e191..853c8a9ad 100644 --- a/classstdex_1_1parser_1_1sgml__ipv6__scope__id__char-members.html +++ b/classstdex_1_1parser_1_1sgml__ipv6__scope__id__char-members.html @@ -86,7 +86,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1sgml__ipv6__scope__id__char.html b/classstdex_1_1parser_1_1sgml__ipv6__scope__id__char.html index 7aed208ff..a88afac71 100644 --- a/classstdex_1_1parser_1_1sgml__ipv6__scope__id__char.html +++ b/classstdex_1_1parser_1_1sgml__ipv6__scope__id__char.html @@ -190,7 +190,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1sgml__punct__cp-members.html b/classstdex_1_1parser_1_1sgml__punct__cp-members.html index 10c00f3f3..9bfd73d9a 100644 --- a/classstdex_1_1parser_1_1sgml__punct__cp-members.html +++ b/classstdex_1_1parser_1_1sgml__punct__cp-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1sgml__punct__cp.html b/classstdex_1_1parser_1_1sgml__punct__cp.html index c3f2f7d92..242068674 100644 --- a/classstdex_1_1parser_1_1sgml__punct__cp.html +++ b/classstdex_1_1parser_1_1sgml__punct__cp.html @@ -203,7 +203,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1sgml__space__cp-members.html b/classstdex_1_1parser_1_1sgml__space__cp-members.html index 9de354989..fd07bc873 100644 --- a/classstdex_1_1parser_1_1sgml__space__cp-members.html +++ b/classstdex_1_1parser_1_1sgml__space__cp-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1sgml__space__cp.html b/classstdex_1_1parser_1_1sgml__space__cp.html index f96907cb9..3e5a310a3 100644 --- a/classstdex_1_1parser_1_1sgml__space__cp.html +++ b/classstdex_1_1parser_1_1sgml__space__cp.html @@ -203,7 +203,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1sgml__space__or__punct__cp-members.html b/classstdex_1_1parser_1_1sgml__space__or__punct__cp-members.html index c9cd683ad..14ff580a6 100644 --- a/classstdex_1_1parser_1_1sgml__space__or__punct__cp-members.html +++ b/classstdex_1_1parser_1_1sgml__space__or__punct__cp-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1sgml__space__or__punct__cp.html b/classstdex_1_1parser_1_1sgml__space__or__punct__cp.html index 20a5498cf..493971384 100644 --- a/classstdex_1_1parser_1_1sgml__space__or__punct__cp.html +++ b/classstdex_1_1parser_1_1sgml__space__or__punct__cp.html @@ -203,7 +203,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1sgml__string-members.html b/classstdex_1_1parser_1_1sgml__string-members.html index 0469aa2d2..f0ceb68ae 100644 --- a/classstdex_1_1parser_1_1sgml__string-members.html +++ b/classstdex_1_1parser_1_1sgml__string-members.html @@ -87,7 +87,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1sgml__string.html b/classstdex_1_1parser_1_1sgml__string.html index 05e92a9b7..050e80ac2 100644 --- a/classstdex_1_1parser_1_1sgml__string.html +++ b/classstdex_1_1parser_1_1sgml__string.html @@ -197,7 +197,7 @@ Additional Inherited Members diff --git a/classstdex_1_1parser_1_1sgml__url__password__char-members.html b/classstdex_1_1parser_1_1sgml__url__password__char-members.html index 307d02800..1349cce7c 100644 --- a/classstdex_1_1parser_1_1sgml__url__password__char-members.html +++ b/classstdex_1_1parser_1_1sgml__url__password__char-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1sgml__url__password__char.html b/classstdex_1_1parser_1_1sgml__url__password__char.html index 16ce5ee13..9ca5b2f48 100644 --- a/classstdex_1_1parser_1_1sgml__url__password__char.html +++ b/classstdex_1_1parser_1_1sgml__url__password__char.html @@ -199,7 +199,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1sgml__url__path__char-members.html b/classstdex_1_1parser_1_1sgml__url__path__char-members.html index 5ca7eb448..f7ecdd68c 100644 --- a/classstdex_1_1parser_1_1sgml__url__path__char-members.html +++ b/classstdex_1_1parser_1_1sgml__url__path__char-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1sgml__url__path__char.html b/classstdex_1_1parser_1_1sgml__url__path__char.html index 2643486c2..0c1837367 100644 --- a/classstdex_1_1parser_1_1sgml__url__path__char.html +++ b/classstdex_1_1parser_1_1sgml__url__path__char.html @@ -199,7 +199,7 @@ std::locale m_locale diff --git a/classstdex_1_1parser_1_1sgml__url__username__char-members.html b/classstdex_1_1parser_1_1sgml__url__username__char-members.html index bf5514c99..31b11931c 100644 --- a/classstdex_1_1parser_1_1sgml__url__username__char-members.html +++ b/classstdex_1_1parser_1_1sgml__url__username__char-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1sgml__url__username__char.html b/classstdex_1_1parser_1_1sgml__url__username__char.html index 526b491b1..49edabaf0 100644 --- a/classstdex_1_1parser_1_1sgml__url__username__char.html +++ b/classstdex_1_1parser_1_1sgml__url__username__char.html @@ -199,7 +199,7 @@ std::locale m_locale diff --git a/classstdex_1_1progress-members.html b/classstdex_1_1progress-members.html index 33960cfb2..df5c69cc8 100644 --- a/classstdex_1_1progress-members.html +++ b/classstdex_1_1progress-members.html @@ -88,7 +88,7 @@ $(function() { diff --git a/classstdex_1_1progress.html b/classstdex_1_1progress.html index ee3c75d3e..1e15915db 100644 --- a/classstdex_1_1progress.html +++ b/classstdex_1_1progress.html @@ -319,7 +319,7 @@ template<class T > diff --git a/classstdex_1_1progress__switcher-members.html b/classstdex_1_1progress__switcher-members.html index 0bf63f9ef..1347103fc 100644 --- a/classstdex_1_1progress__switcher-members.html +++ b/classstdex_1_1progress__switcher-members.html @@ -100,7 +100,7 @@ $(function() { diff --git a/classstdex_1_1progress__switcher.html b/classstdex_1_1progress__switcher.html index 83933a0d0..4ecefae7b 100644 --- a/classstdex_1_1progress__switcher.html +++ b/classstdex_1_1progress__switcher.html @@ -178,7 +178,7 @@ class stdex::progress_switcher< T >

Progress indicator switcher. <

diff --git a/classstdex_1_1user__cancelled-members.html b/classstdex_1_1user__cancelled-members.html index 7edddbe68..05b83c840 100644 --- a/classstdex_1_1user__cancelled-members.html +++ b/classstdex_1_1user__cancelled-members.html @@ -84,7 +84,7 @@ $(function() { diff --git a/classstdex_1_1user__cancelled.html b/classstdex_1_1user__cancelled.html index 95910f3e4..63b7684ad 100644 --- a/classstdex_1_1user__cancelled.html +++ b/classstdex_1_1user__cancelled.html @@ -141,7 +141,7 @@ Public Member Functions diff --git a/classstdex_1_1vector__queue-members.html b/classstdex_1_1vector__queue-members.html index a90ba80da..cc3567d21 100644 --- a/classstdex_1_1vector__queue-members.html +++ b/classstdex_1_1vector__queue-members.html @@ -122,7 +122,7 @@ $(function() { diff --git a/classstdex_1_1vector__queue.html b/classstdex_1_1vector__queue.html index fdd1f3283..cde233047 100644 --- a/classstdex_1_1vector__queue.html +++ b/classstdex_1_1vector__queue.html @@ -795,7 +795,7 @@ template<class T > diff --git a/dir_4be4f7b278e009bf0f1906cf31fb73bd.html b/dir_4be4f7b278e009bf0f1906cf31fb73bd.html index 8e9e1bc54..b4701de9e 100644 --- a/dir_4be4f7b278e009bf0f1906cf31fb73bd.html +++ b/dir_4be4f7b278e009bf0f1906cf31fb73bd.html @@ -86,7 +86,7 @@ Files diff --git a/dir_d44c64559bbebec7f509842c48db8b23.html b/dir_d44c64559bbebec7f509842c48db8b23.html index 84c0fc2f5..d92f08b84 100644 --- a/dir_d44c64559bbebec7f509842c48db8b23.html +++ b/dir_d44c64559bbebec7f509842c48db8b23.html @@ -86,7 +86,7 @@ Directories diff --git a/dir_fca3c47b2ea228727bd6729832f89576.html b/dir_fca3c47b2ea228727bd6729832f89576.html index 43c57272e..a0c8f2147 100644 --- a/dir_fca3c47b2ea228727bd6729832f89576.html +++ b/dir_fca3c47b2ea228727bd6729832f89576.html @@ -116,7 +116,7 @@ Files diff --git a/errno_8hpp_source.html b/errno_8hpp_source.html index 8fcd6ca97..ddfe4189d 100644 --- a/errno_8hpp_source.html +++ b/errno_8hpp_source.html @@ -136,7 +136,7 @@ $(function() { diff --git a/exception_8hpp_source.html b/exception_8hpp_source.html index 7b712cc96..c9da09ba4 100644 --- a/exception_8hpp_source.html +++ b/exception_8hpp_source.html @@ -102,7 +102,7 @@ $(function() { diff --git a/files.html b/files.html index 9c985f99c..78c86310a 100644 --- a/files.html +++ b/files.html @@ -100,7 +100,7 @@ $(function() { diff --git a/functions.html b/functions.html index c90ac1e91..320326dc8 100644 --- a/functions.html +++ b/functions.html @@ -256,7 +256,7 @@ $(function() { diff --git a/functions_func.html b/functions_func.html index c4129f881..963e51d90 100644 --- a/functions_func.html +++ b/functions_func.html @@ -205,7 +205,7 @@ $(function() { diff --git a/functions_type.html b/functions_type.html index 75c875e4a..2839b0f68 100644 --- a/functions_type.html +++ b/functions_type.html @@ -81,7 +81,7 @@ $(function() { diff --git a/functions_vars.html b/functions_vars.html index e91f16df1..02b9d05f7 100644 --- a/functions_vars.html +++ b/functions_vars.html @@ -176,7 +176,7 @@ $(function() { diff --git a/hex_8hpp_source.html b/hex_8hpp_source.html index 2d1df5ff9..266f1cc2c 100644 --- a/hex_8hpp_source.html +++ b/hex_8hpp_source.html @@ -209,7 +209,7 @@ $(function() { diff --git a/hierarchy.html b/hierarchy.html index f2e76bdc6..93317c97c 100644 --- a/hierarchy.html +++ b/hierarchy.html @@ -197,7 +197,7 @@ $(function() { diff --git a/idrec_8hpp_source.html b/idrec_8hpp_source.html index 36e6611ef..92dfd17a7 100644 --- a/idrec_8hpp_source.html +++ b/idrec_8hpp_source.html @@ -275,7 +275,7 @@ $(function() { diff --git a/index.html b/index.html index d1619a196..2b04a20f0 100644 --- a/index.html +++ b/index.html @@ -76,7 +76,7 @@ $(function() { diff --git a/interval_8hpp_source.html b/interval_8hpp_source.html index 83640612d..7730f0561 100644 --- a/interval_8hpp_source.html +++ b/interval_8hpp_source.html @@ -128,7 +128,7 @@ $(function() { diff --git a/mapping_8hpp_source.html b/mapping_8hpp_source.html index beac79cf6..04770c7e8 100644 --- a/mapping_8hpp_source.html +++ b/mapping_8hpp_source.html @@ -117,7 +117,7 @@ $(function() { diff --git a/memory_8hpp_source.html b/memory_8hpp_source.html index e69221b9d..facb63e35 100644 --- a/memory_8hpp_source.html +++ b/memory_8hpp_source.html @@ -119,7 +119,7 @@ $(function() { diff --git a/parser_8hpp_source.html b/parser_8hpp_source.html index 3b6c77028..e8ad15186 100644 --- a/parser_8hpp_source.html +++ b/parser_8hpp_source.html @@ -109,6423 +109,6441 @@ $(function() {
30#pragma warning(disable: 4100)
31#endif
32
-
33namespace stdex
-
34{
-
35 namespace parser
-
36 {
-
40 constexpr int match_default = 0;
-
41 constexpr int match_case_insensitive = 0x1;
-
42 constexpr int match_multiline = 0x2;
-
43
-
47 template <class T>
-
48 class basic_parser
-
49 {
-
50 public:
-
51 basic_parser(_In_ const std::locale& locale = std::locale()) : m_locale(locale) {}
-
52 virtual ~basic_parser() {}
-
53
-
54 bool search(
-
55 _In_reads_or_z_(end) const T* text,
-
56 _In_ size_t start = 0,
-
57 _In_ size_t end = (size_t)-1,
-
58 _In_ int flags = match_default)
-
59 {
-
60 for (size_t i = start; i < end && text[i]; i++)
-
61 if (match(text, i, end, flags))
-
62 return true;
-
63 return false;
-
64 }
-
65
-
66 virtual bool match(
-
67 _In_reads_or_z_(end) const T* text,
-
68 _In_ size_t start = 0,
-
69 _In_ size_t end = (size_t)-1,
-
70 _In_ int flags = match_default) = 0;
-
71
-
72 template<class _Traits, class _Ax>
-
73 inline bool match(
-
74 const std::basic_string<T, _Traits, _Ax>& text,
-
75 _In_ size_t start = 0,
-
76 _In_ size_t end = (size_t)-1,
-
77 _In_ int flags = match_default)
-
78 {
-
79 return match(text.c_str(), start, std::min<size_t>(end, text.size()), flags);
-
80 }
-
81
-
82 virtual void invalidate()
-
83 {
-
84 interval.start = 1;
-
85 interval.end = 0;
-
86 }
-
87
-
88 protected:
-
90 const wchar_t* next_sgml_cp(_In_ const char* text, _In_ size_t start, _In_ size_t end, _Out_ size_t& chr_end, _Out_ wchar_t(&buf)[3])
-
91 {
-
92 if (text[start] == '&') {
-
93 // Potential entity start
-
94 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
-
95 for (chr_end = start + 1;; chr_end++) {
-
96 if (chr_end >= end || text[chr_end] == 0) {
-
97 // Unterminated entity
-
98 break;
-
99 }
-
100 if (text[chr_end] == ';') {
-
101 // Entity end
-
102 size_t n = chr_end - start - 1;
-
103 if (n >= 2 && text[start + 1] == '#') {
-
104 // Numerical entity
-
105 char32_t unicode;
-
106 if (text[start + 2] == 'x' || text[start + 2] == 'X')
-
107 unicode = strtou32(text + start + 3, n - 2, nullptr, 16);
-
108 else
-
109 unicode = strtou32(text + start + 2, n - 1, nullptr, 10);
-
110#ifdef _WIN32
-
111 if (unicode < 0x10000) {
-
112 buf[0] = (wchar_t)unicode;
-
113 buf[1] = 0;
-
114 }
-
115 else {
-
116 ucs4_to_surrogate_pair(buf, unicode);
-
117 buf[2] = 0;
-
118 }
-
119#else
-
120 buf[0] = (wchar_t)unicode;
-
121 buf[1] = 0;
-
122#endif
-
123 chr_end++;
-
124 return buf;
-
125 }
-
126 const wchar_t* entity_w = sgml2uni(text + start + 1, n);
-
127 if (entity_w) {
-
128 chr_end++;
-
129 return entity_w;
-
130 }
-
131 // Unknown entity.
-
132 break;
-
133 }
-
134 else if (text[chr_end] == '&' || ctype.is(ctype.space, text[chr_end])) {
-
135 // This char cannot possibly be a part of entity.
-
136 break;
-
137 }
-
138 }
-
139 }
-
140 buf[0] = text[start];
-
141 buf[1] = 0;
-
142 chr_end = start + 1;
-
143 return buf;
-
144 }
-
146
-
147 public:
-
148 interval<size_t> interval;
-
149
-
150 protected:
-
151 std::locale m_locale;
-
152 };
-
153
-
154 using parser = basic_parser<char>;
-
155 using wparser = basic_parser<wchar_t>;
-
156#ifdef _UNICODE
-
157 using tparser = wparser;
-
158#else
-
159 using tparser = parser;
-
160#endif
-
161 using sgml_parser = basic_parser<char>;
-
162
-
166 template <class T>
-
167 class basic_noop : public basic_parser<T>
-
168 {
-
169 public:
-
170 virtual bool match(
-
171 _In_reads_or_z_(end) const T* text,
-
172 _In_ size_t start = 0,
-
173 _In_ size_t end = (size_t)-1,
-
174 _In_ int flags = match_default)
-
175 {
-
176 assert(text || start >= end);
-
177 if (start < end && text[start]) {
-
178 interval.start = interval.end = start;
-
179 return true;
-
180 }
-
181 interval.start = (interval.end = start) + 1;
-
182 return false;
-
183 }
-
184 };
-
185
-
186 using noop = basic_noop<char>;
-
187 using wnoop = basic_noop<wchar_t>;
-
188#ifdef _UNICODE
-
189 using tnoop = wnoop;
-
190#else
-
191 using tnoop = noop;
-
192#endif
-
193 using sgml_noop = basic_noop<char>;
-
194
-
198 template <class T>
-
199 class basic_any_cu : public basic_parser<T>
-
200 {
-
201 public:
-
202 basic_any_cu(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
-
203
-
204 virtual bool match(
-
205 _In_reads_or_z_(end) const T* text,
-
206 _In_ size_t start = 0,
-
207 _In_ size_t end = (size_t)-1,
-
208 _In_ int flags = match_default)
-
209 {
-
210 assert(text || start >= end);
-
211 if (start < end && text[start]) {
-
212 interval.end = (interval.start = start) + 1;
-
213 return true;
-
214 }
-
215 interval.start = (interval.end = start) + 1;
-
216 return false;
-
217 }
-
218 };
-
219
-
220 using any_cu = basic_any_cu<char>;
-
221 using wany_cu = basic_any_cu<wchar_t>;
-
222#ifdef _UNICODE
-
223 using tany_cu = wany_cu;
-
224#else
-
225 using tany_cu = any_cu;
-
226#endif
-
227
-
231 class sgml_any_cp : public basic_any_cu<char>
-
232 {
-
233 public:
-
234 sgml_any_cp(_In_ const std::locale& locale = std::locale()) : basic_any_cu<char>(locale) {}
-
235
-
236 virtual bool match(
-
237 _In_reads_or_z_(end) const char* text,
-
238 _In_ size_t start = 0,
-
239 _In_ size_t end = (size_t)-1,
-
240 _In_ int flags = match_default)
-
241 {
-
242 assert(text || start >= end);
-
243 if (start < end && text[start]) {
-
244 if (text[start] == '&') {
-
245 // SGML entity
-
246 const auto& ctype = std::use_facet<std::ctype<char>>(m_locale);
-
247 for (interval.end = start + 1; interval.end < end && text[interval.end]; interval.end++)
-
248 if (text[interval.end] == ';') {
-
249 interval.end++;
-
250 interval.start = start;
-
251 return true;
-
252 }
-
253 else if (text[interval.end] == '&' || ctype.is(ctype.space, text[interval.end]))
-
254 break;
-
255 // Unterminated entity
-
256 }
-
257 interval.end = (interval.start = start) + 1;
-
258 return true;
-
259 }
-
260 interval.start = (interval.end = start) + 1;
-
261 return false;
-
262 }
-
263 };
-
264
-
268 template <class T>
-
269 class basic_cu : public basic_parser<T>
-
270 {
-
271 public:
-
272 basic_cu(T chr, bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
273 basic_parser<T>(locale),
-
274 m_chr(chr),
-
275 m_invert(invert)
-
276 {}
-
277
-
278 virtual bool match(
-
279 _In_reads_or_z_(end) const T* text,
-
280 _In_ size_t start = 0,
-
281 _In_ size_t end = (size_t)-1,
-
282 _In_ int flags = match_default)
-
283 {
-
284 assert(text || start >= end);
-
285 if (start < end && text[start]) {
-
286 bool r;
-
287 if (flags & match_case_insensitive) {
-
288 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
-
289 r = ctype.tolower(text[start]) == ctype.tolower(m_chr);
-
290 }
-
291 else
-
292 r = text[start] == m_chr;
-
293 if (r && !m_invert || !r && m_invert) {
-
294 interval.end = (interval.start = start) + 1;
-
295 return true;
-
296 }
-
297 }
-
298 interval.start = (interval.end = start) + 1;
-
299 return false;
-
300 }
-
301
-
302 protected:
-
303 T m_chr;
-
304 bool m_invert;
-
305 };
-
306
-
307 using cu = basic_cu<char>;
-
308 using wcu = basic_cu<wchar_t>;
-
309#ifdef _UNICODE
-
310 using tcu = wcu;
-
311#else
-
312 using tcu = cu;
-
313#endif
-
314
-
318 class sgml_cp : public sgml_parser
-
319 {
-
320 public:
-
321 sgml_cp(const char* chr, size_t count = (size_t)-1, bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
322 sgml_parser(locale),
-
323 m_invert(invert)
-
324 {
-
325 assert(chr || !count);
-
326 wchar_t buf[3];
-
327 size_t chr_end;
-
328 m_chr.assign(count ? next_sgml_cp(chr, 0, count, chr_end, buf) : L"");
-
329 }
-
330
-
331 virtual bool match(
-
332 _In_reads_or_z_(end) const char* text,
-
333 _In_ size_t start = 0,
-
334 _In_ size_t end = (size_t)-1,
-
335 _In_ int flags = match_default)
-
336 {
-
337 assert(text || start >= end);
-
338 if (start < end && text[start]) {
-
339 wchar_t buf[3];
-
340 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
-
341 bool r = ((flags & match_case_insensitive) ?
-
342 stdex::strnicmp(chr, (size_t)-1, m_chr.c_str(), m_chr.size(), m_locale) :
-
343 stdex::strncmp(chr, (size_t)-1, m_chr.c_str(), m_chr.size())) == 0;
-
344 if (r && !m_invert || !r && m_invert) {
-
345 interval.start = start;
-
346 return true;
-
347 }
-
348 }
-
349 interval.start = (interval.end = start) + 1;
-
350 return false;
-
351 }
-
352
-
353 protected:
-
354 std::wstring m_chr;
-
355 bool m_invert;
-
356 };
-
357
-
361 template <class T>
-
362 class basic_space_cu : public basic_parser<T>
-
363 {
-
364 public:
-
365 basic_space_cu(bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
366 basic_parser<T>(locale),
-
367 m_invert(invert)
-
368 {}
-
369
-
370 virtual bool match(
-
371 _In_reads_or_z_(end) const T* text,
-
372 _In_ size_t start = 0,
-
373 _In_ size_t end = (size_t)-1,
-
374 _In_ int flags = match_default)
-
375 {
-
376 assert(text || start >= end);
-
377 if (start < end && text[start]) {
-
378 bool r =
-
379 ((flags & match_multiline) || !islbreak(text[start])) &&
-
380 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::space, text[start]);
-
381 if (r && !m_invert || !r && m_invert) {
-
382 interval.end = (interval.start = start) + 1;
-
383 return true;
-
384 }
-
385 }
-
386 interval.start = (interval.end = start) + 1;
-
387 return false;
-
388 }
-
389
-
390 protected:
-
391 bool m_invert;
-
392 };
-
393
-
394 using space_cu = basic_space_cu<char>;
-
395 using wspace_cu = basic_space_cu<wchar_t>;
-
396#ifdef _UNICODE
-
397 using tspace_cu = wspace_cu;
-
398#else
-
399 using tspace_cu = space_cu;
-
400#endif
-
401
-
405 class sgml_space_cp : public basic_space_cu<char>
-
406 {
-
407 public:
-
408 sgml_space_cp(_In_ bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
409 basic_space_cu<char>(invert, locale)
-
410 {}
-
411
-
412 virtual bool match(
-
413 _In_reads_or_z_(end) const char* text,
-
414 _In_ size_t start = 0,
-
415 _In_ size_t end = (size_t)-1,
-
416 _In_ int flags = match_default)
-
417 {
-
418 assert(text || start >= end);
-
419 if (start < end && text[start]) {
-
420 wchar_t buf[3];
-
421 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
-
422 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
423 bool r =
-
424 ((flags & match_multiline) || !islbreak(chr, (size_t)-1)) &&
-
425 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space, chr, chr_end) == chr_end;
-
426 if (r && !m_invert || !r && m_invert) {
-
427 interval.start = start;
-
428 return true;
-
429 }
-
430 }
-
431
-
432 interval.start = (interval.end = start) + 1;
-
433 return false;
-
434 }
-
435 };
-
436
-
440 template <class T>
-
441 class basic_punct_cu : public basic_parser<T>
-
442 {
-
443 public:
-
444 basic_punct_cu(bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
445 basic_parser<T>(locale),
-
446 m_invert(invert)
-
447 {}
-
448
-
449 virtual bool match(
-
450 _In_reads_or_z_(end) const T* text,
-
451 _In_ size_t start = 0,
-
452 _In_ size_t end = (size_t)-1,
-
453 _In_ int flags = match_default)
-
454 {
-
455 assert(text || start >= end);
-
456 if (start < end && text[start]) {
-
457 bool r = std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::punct, text[start]);
-
458 if (r && !m_invert || !r && m_invert) {
-
459 interval.end = (interval.start = start) + 1;
-
460 return true;
-
461 }
-
462 }
-
463 interval.start = (interval.end = start) + 1;
-
464 return false;
-
465 }
-
466
-
467 protected:
-
468 bool m_invert;
-
469 };
-
470
-
471 using punct_cu = basic_punct_cu<char>;
-
472 using wpunct_cu = basic_punct_cu<wchar_t>;
-
473#ifdef _UNICODE
-
474 using tpunct_cu = wpunct_cu;
-
475#else
-
476 using tpunct_cu = punct_cu;
-
477#endif
-
478
-
482 class sgml_punct_cp : public basic_punct_cu<char>
-
483 {
-
484 public:
-
485 sgml_punct_cp(bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
486 basic_punct_cu<char>(invert, locale)
-
487 {}
-
488
-
489 virtual bool match(
-
490 _In_reads_or_z_(end) const char* text,
-
491 _In_ size_t start = 0,
-
492 _In_ size_t end = (size_t)-1,
-
493 _In_ int flags = match_default)
-
494 {
-
495 assert(text || start >= end);
-
496 if (start < end && text[start]) {
-
497 wchar_t buf[3];
-
498 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
-
499 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
500 bool r = std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::punct, chr, chr_end) == chr_end;
-
501 if (r && !m_invert || !r && m_invert) {
-
502 interval.start = start;
-
503 return true;
-
504 }
-
505 }
-
506 interval.start = (interval.end = start) + 1;
-
507 return false;
-
508 }
-
509 };
-
510
-
514 template <class T>
-
515 class basic_space_or_punct_cu : public basic_parser<T>
-
516 {
-
517 public:
-
518 basic_space_or_punct_cu(bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
519 basic_parser<T>(locale),
-
520 m_invert(invert)
-
521 {}
-
522
-
523 virtual bool match(
-
524 _In_reads_or_z_(end) const T* text,
-
525 _In_ size_t start = 0,
-
526 _In_ size_t end = (size_t)-1,
-
527 _In_ int flags = match_default)
-
528 {
-
529 assert(text || start >= end);
-
530 if (start < end && text[start]) {
-
531 bool r =
-
532 ((flags & match_multiline) || !islbreak(text[start])) &&
-
533 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::space | std::ctype_base::punct, text[start]);
-
534 if (r && !m_invert || !r && m_invert) {
-
535 interval.end = (interval.start = start) + 1;
-
536 return true;
-
537 }
-
538 }
-
539 interval.start = (interval.end = start) + 1;
-
540 return false;
-
541 }
-
542
-
543 protected:
-
544 bool m_invert;
-
545 };
-
546
-
547 using space_or_punct_cu = basic_space_or_punct_cu<char>;
-
548 using wspace_or_punct_cu = basic_space_or_punct_cu<wchar_t>;
-
549#ifdef _UNICODE
-
550 using tspace_or_punct_cu = wspace_or_punct_cu;
-
551#else
-
552 using tspace_or_punct_cu = space_or_punct_cu;
-
553#endif
-
554
-
558 class sgml_space_or_punct_cp : public basic_space_or_punct_cu<char>
-
559 {
-
560 public:
-
561 sgml_space_or_punct_cp(bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
562 basic_space_or_punct_cu<char>(invert, locale)
-
563 {}
-
564
-
565 virtual bool match(
-
566 _In_reads_or_z_(end) const char* text,
-
567 _In_ size_t start = 0,
-
568 _In_ size_t end = (size_t)-1,
-
569 _In_ int flags = match_default)
-
570 {
-
571 assert(text || start >= end);
-
572 if (start < end && text[start]) {
-
573 wchar_t buf[3];
-
574 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
-
575 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
576 bool r =
-
577 ((flags & match_multiline) || !islbreak(chr, (size_t)-1)) &&
-
578 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space | std::ctype_base::punct, chr, chr_end) == chr_end;
-
579 if (r && !m_invert || !r && m_invert) {
-
580 interval.start = start;
-
581 return true;
-
582 }
-
583 }
-
584 interval.start = (interval.end = start) + 1;
-
585 return false;
-
586 }
-
587 };
-
588
-
592 template <class T>
-
593 class basic_bol : public basic_parser<T>
-
594 {
-
595 public:
-
596 basic_bol(bool invert = false) : m_invert(invert) {}
-
597
-
598 virtual bool match(
-
599 _In_reads_or_z_(end) const T* text,
-
600 _In_ size_t start = 0,
-
601 _In_ size_t end = (size_t)-1,
-
602 _In_ int flags = match_default)
-
603 {
-
604 assert(text || start >= end);
-
605 bool r = start == 0 || start <= end && islbreak(text[start - 1]);
-
606 if (r && !m_invert || !r && m_invert) {
-
607 interval.end = interval.start = start;
-
608 return true;
-
609 }
-
610 interval.start = (interval.end = start) + 1;
-
611 return false;
-
612 }
-
613
-
614 protected:
-
615 bool m_invert;
-
616 };
-
617
-
618 using bol = basic_bol<char>;
-
619 using wbol = basic_bol<wchar_t>;
-
620#ifdef _UNICODE
-
621 using tbol = wbol;
-
622#else
-
623 using tbol = bol;
-
624#endif
-
625 using sgml_bol = basic_bol<char>;
-
626
-
630 template <class T>
-
631 class basic_eol : public basic_parser<T>
-
632 {
-
633 public:
-
634 basic_eol(bool invert = false) : m_invert(invert) {}
-
635
-
636 virtual bool match(
-
637 _In_reads_or_z_(end) const T* text,
-
638 _In_ size_t start = 0,
-
639 _In_ size_t end = (size_t)-1,
-
640 _In_ int flags = match_default)
-
641 {
-
642 assert(text || start >= end);
-
643 bool r = islbreak(text[start]);
-
644 if (r && !m_invert || !r && m_invert) {
-
645 interval.end = interval.start = start;
-
646 return true;
-
647 }
-
648 interval.start = (interval.end = start) + 1;
-
649 return false;
-
650 }
-
651
-
652 protected:
-
653 bool m_invert;
-
654 };
-
655
-
656 using eol = basic_eol<char>;
-
657 using weol = basic_eol<wchar_t>;
-
658#ifdef _UNICODE
-
659 using teol = weol;
-
660#else
-
661 using teol = eol;
-
662#endif
-
663 using sgml_eol = basic_eol<char>;
-
664
-
665 template <class T>
-
666 class basic_set : public basic_parser<T>
-
667 {
-
668 public:
-
669 basic_set(bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
670 basic_parser<T>(locale),
-
671 hit_offset((size_t)-1),
-
672 m_invert(invert)
-
673 {}
-
674
-
675 virtual bool match(
-
676 _In_reads_or_z_(end) const T* text,
-
677 _In_ size_t start = 0,
-
678 _In_ size_t end = (size_t)-1,
-
679 _In_ int flags = match_default) = 0;
-
680
-
681 virtual void invalidate()
-
682 {
-
683 hit_offset = (size_t)-1;
-
684 basic_parser<T>::invalidate();
-
685 }
-
686
-
687 public:
-
688 size_t hit_offset;
-
689
-
690 protected:
-
691 bool m_invert;
-
692 };
-
693
-
697 template <class T>
-
698 class basic_cu_set : public basic_set<T>
-
699 {
-
700 public:
-
701 basic_cu_set(
-
702 _In_reads_or_z_(count) const T* set,
-
703 _In_ size_t count = (size_t)-1,
-
704 _In_ bool invert = false,
-
705 _In_ const std::locale& locale = std::locale()) :
-
706 basic_set<T>(invert, locale)
-
707 {
-
708 if (set)
-
709 m_set.assign(set, set + stdex::strnlen(set, count));
-
710 }
-
711
-
712 virtual bool match(
-
713 _In_reads_or_z_(end) const T* text,
-
714 _In_ size_t start = 0,
-
715 _In_ size_t end = (size_t)-1,
-
716 _In_ int flags = match_default)
-
717 {
-
718 assert(text || start >= end);
-
719 if (start < end && text[start]) {
-
720 const T* set = m_set.c_str();
-
721 size_t r = (flags & match_case_insensitive) ?
-
722 stdex::strnichr(set, m_set.size(), text[start], m_locale) :
-
723 stdex::strnchr(set, m_set.size(), text[start]);
-
724 if (r != stdex::npos && !m_invert || r == stdex::npos && m_invert) {
-
725 hit_offset = r;
-
726 interval.end = (interval.start = start) + 1;
-
727 return true;
-
728 }
-
729 }
-
730 hit_offset = (size_t)-1;
-
731 interval.start = (interval.end = start) + 1;
-
732 return false;
-
733 }
-
734
-
735 protected:
-
736 std::basic_string<T> m_set;
-
737 };
-
738
-
739 using cu_set = basic_cu_set<char>;
-
740 using wcu_set = basic_cu_set<wchar_t>;
-
741#ifdef _UNICODE
-
742 using tcu_set = wcu_set;
-
743#else
-
744 using tcu_set = cu_set;
-
745#endif
-
746
-
750 class sgml_cp_set : public basic_set<char>
-
751 {
-
752 public:
-
753 sgml_cp_set(const char* set, size_t count = (size_t)-1, bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
754 basic_set<char>(invert, locale)
-
755 {
-
756 if (set)
-
757 m_set = sgml2wstr(set, count);
-
758 }
-
759
-
760 virtual bool match(
-
761 _In_reads_or_z_(end) const char* text,
-
762 _In_ size_t start = 0,
-
763 _In_ size_t end = (size_t)-1,
-
764 _In_ int flags = match_default)
-
765 {
-
766 assert(text || start >= end);
-
767 if (start < end && text[start]) {
-
768 wchar_t buf[3];
-
769 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
-
770 const wchar_t* set = m_set.c_str();
-
771 size_t r = (flags & match_case_insensitive) ?
-
772 stdex::strnistr(set, m_set.size(), chr, m_locale) :
-
773 stdex::strnstr(set, m_set.size(), chr);
-
774 if (r != stdex::npos && !m_invert || r == stdex::npos && m_invert) {
-
775 hit_offset = r;
-
776 interval.start = start;
-
777 return true;
-
778 }
-
779 }
-
780 hit_offset = (size_t)-1;
-
781 interval.start = (interval.end = start) + 1;
-
782 return false;
-
783 }
-
784
-
785 protected:
-
786 std::wstring m_set;
-
787 };
-
788
-
792 template <class T>
-
793 class basic_string : public basic_parser<T>
-
794 {
-
795 public:
-
796 basic_string(
-
797 _In_reads_or_z_(count) const T* str,
-
798 _In_ size_t count = (size_t)-1,
-
799 _In_ const std::locale& locale = std::locale()) :
-
800 basic_parser<T>(locale),
-
801 m_str(str, str + stdex::strnlen(str, count))
-
802 {}
-
803
-
804 virtual bool match(
-
805 _In_reads_or_z_(end) const T* text,
-
806 _In_ size_t start = 0,
-
807 _In_ size_t end = (size_t)-1,
-
808 _In_ int flags = match_default)
-
809 {
-
810 assert(text || start >= end);
-
811 size_t
-
812 m = m_str.size(),
-
813 n = std::min<size_t>(end - start, m);
-
814 bool r = ((flags & match_case_insensitive) ?
-
815 stdex::strnicmp(text + start, n, m_str.c_str(), m, m_locale) :
-
816 stdex::strncmp(text + start, n, m_str.c_str(), m)) == 0;
-
817 if (r) {
-
818 interval.end = (interval.start = start) + n;
-
819 return true;
-
820 }
-
821 interval.start = (interval.end = start) + 1;
-
822 return false;
-
823 }
-
824
-
825 protected:
-
826 std::basic_string<T> m_str;
-
827 };
-
828
-
829 using string = basic_string<char>;
-
830 using wstring = basic_string<wchar_t>;
-
831#ifdef _UNICODE
-
832 using tstring = wstring;
-
833#else
-
834 using tstring = string;
-
835#endif
-
836
-
840 class sgml_string : public sgml_parser
-
841 {
-
842 public:
-
843 sgml_string(const char* str, size_t count = (size_t)-1, _In_ const std::locale& locale = std::locale()) :
-
844 sgml_parser(locale),
-
845 m_str(sgml2wstr(str, count))
-
846 {}
-
847
-
848 virtual bool match(
-
849 _In_reads_or_z_(end) const char* text,
-
850 _In_ size_t start = 0,
-
851 _In_ size_t end = (size_t)-1,
-
852 _In_ int flags = match_default)
-
853 {
-
854 assert(text || start >= end);
-
855 const wchar_t* str = m_str.c_str();
-
856 const bool case_insensitive = flags & match_case_insensitive ? true : false;
-
857 const auto& ctype = std::use_facet<std::ctype<wchar_t>>(m_locale);
-
858 for (interval.end = start;;) {
-
859 if (!*str) {
-
860 interval.start = start;
-
861 return true;
-
862 }
-
863 if (interval.end >= end || !text[interval.end]) {
-
864 interval.start = (interval.end = start) + 1;
-
865 return false;
-
866 }
-
867 wchar_t buf[3];
-
868 const wchar_t* chr = next_sgml_cp(text, interval.end, end, interval.end, buf);
-
869 for (; *chr; ++str, ++chr) {
-
870 if (!*str ||
-
871 (case_insensitive ? ctype.tolower(*str) != ctype.tolower(*chr) : *str != *chr))
-
872 {
-
873 interval.start = (interval.end = start) + 1;
-
874 return false;
-
875 }
+
33#define ENUM_FLAG_OPERATOR(T,X) \
+
34inline T operator X (const T lhs, const T rhs) { return static_cast<T>(static_cast<std::underlying_type_t<T>>(lhs) X static_cast<std::underlying_type_t<T>>(rhs)); } \
+
35inline T operator X (const T lhs, const std::underlying_type_t<T> rhs) { return static_cast<T>(static_cast<std::underlying_type_t<T>>(lhs) X rhs); } \
+
36inline T operator X (const std::underlying_type_t<T> lhs, const T rhs) { return static_cast<T>(lhs X static_cast<std::underlying_type_t<T>>(rhs)); } \
+
37inline T& operator X= (T& lhs, const T rhs) { return lhs = lhs X rhs; } \
+
38inline T& operator X= (T& lhs, const std::underlying_type_t<T> rhs) { return lhs = lhs X rhs; }
+
39#define ENUM_FLAGS(T, type) \
+
40enum class T : type; \
+
41inline T operator ~ (T t) { return (T) (~static_cast<std::underlying_type_t <T>>(t)); } \
+
42ENUM_FLAG_OPERATOR(T,|) \
+
43ENUM_FLAG_OPERATOR(T,^) \
+
44ENUM_FLAG_OPERATOR(T,&) \
+
45enum class T : type
+
46
+
47namespace stdex
+
48{
+
49 namespace parser
+
50 {
+
54 constexpr int match_default = 0;
+
55 constexpr int match_case_insensitive = 0x1;
+
56 constexpr int match_multiline = 0x2;
+
57
+
61 template <class T>
+
62 class basic_parser
+
63 {
+
64 public:
+
65 basic_parser(_In_ const std::locale& locale = std::locale()) : m_locale(locale) {}
+
66 virtual ~basic_parser() {}
+
67
+
68 bool search(
+
69 _In_reads_or_z_(end) const T* text,
+
70 _In_ size_t start = 0,
+
71 _In_ size_t end = (size_t)-1,
+
72 _In_ int flags = match_default)
+
73 {
+
74 for (size_t i = start; i < end && text[i]; i++)
+
75 if (match(text, i, end, flags))
+
76 return true;
+
77 return false;
+
78 }
+
79
+
80 virtual bool match(
+
81 _In_reads_or_z_(end) const T* text,
+
82 _In_ size_t start = 0,
+
83 _In_ size_t end = (size_t)-1,
+
84 _In_ int flags = match_default) = 0;
+
85
+
86 template<class _Traits, class _Ax>
+
87 inline bool match(
+
88 const std::basic_string<T, _Traits, _Ax>& text,
+
89 _In_ size_t start = 0,
+
90 _In_ size_t end = (size_t)-1,
+
91 _In_ int flags = match_default)
+
92 {
+
93 return match(text.c_str(), start, std::min<size_t>(end, text.size()), flags);
+
94 }
+
95
+
96 virtual void invalidate()
+
97 {
+
98 interval.start = 1;
+
99 interval.end = 0;
+
100 }
+
101
+
102 protected:
+
104 const wchar_t* next_sgml_cp(_In_ const char* text, _In_ size_t start, _In_ size_t end, _Out_ size_t& chr_end, _Out_ wchar_t(&buf)[3])
+
105 {
+
106 if (text[start] == '&') {
+
107 // Potential entity start
+
108 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
+
109 for (chr_end = start + 1;; chr_end++) {
+
110 if (chr_end >= end || text[chr_end] == 0) {
+
111 // Unterminated entity
+
112 break;
+
113 }
+
114 if (text[chr_end] == ';') {
+
115 // Entity end
+
116 size_t n = chr_end - start - 1;
+
117 if (n >= 2 && text[start + 1] == '#') {
+
118 // Numerical entity
+
119 char32_t unicode;
+
120 if (text[start + 2] == 'x' || text[start + 2] == 'X')
+
121 unicode = strtou32(text + start + 3, n - 2, nullptr, 16);
+
122 else
+
123 unicode = strtou32(text + start + 2, n - 1, nullptr, 10);
+
124#ifdef _WIN32
+
125 if (unicode < 0x10000) {
+
126 buf[0] = (wchar_t)unicode;
+
127 buf[1] = 0;
+
128 }
+
129 else {
+
130 ucs4_to_surrogate_pair(buf, unicode);
+
131 buf[2] = 0;
+
132 }
+
133#else
+
134 buf[0] = (wchar_t)unicode;
+
135 buf[1] = 0;
+
136#endif
+
137 chr_end++;
+
138 return buf;
+
139 }
+
140 const wchar_t* entity_w = sgml2uni(text + start + 1, n);
+
141 if (entity_w) {
+
142 chr_end++;
+
143 return entity_w;
+
144 }
+
145 // Unknown entity.
+
146 break;
+
147 }
+
148 else if (text[chr_end] == '&' || ctype.is(ctype.space, text[chr_end])) {
+
149 // This char cannot possibly be a part of entity.
+
150 break;
+
151 }
+
152 }
+
153 }
+
154 buf[0] = text[start];
+
155 buf[1] = 0;
+
156 chr_end = start + 1;
+
157 return buf;
+
158 }
+
160
+
161 public:
+
162 interval<size_t> interval;
+
163
+
164 protected:
+
165 std::locale m_locale;
+
166 };
+
167
+
168 using parser = basic_parser<char>;
+
169 using wparser = basic_parser<wchar_t>;
+
170#ifdef _UNICODE
+
171 using tparser = wparser;
+
172#else
+
173 using tparser = parser;
+
174#endif
+
175 using sgml_parser = basic_parser<char>;
+
176
+
180 template <class T>
+
181 class basic_noop : public basic_parser<T>
+
182 {
+
183 public:
+
184 virtual bool match(
+
185 _In_reads_or_z_(end) const T* text,
+
186 _In_ size_t start = 0,
+
187 _In_ size_t end = (size_t)-1,
+
188 _In_ int flags = match_default)
+
189 {
+
190 assert(text || start >= end);
+
191 if (start < end && text[start]) {
+
192 interval.start = interval.end = start;
+
193 return true;
+
194 }
+
195 interval.start = (interval.end = start) + 1;
+
196 return false;
+
197 }
+
198 };
+
199
+
200 using noop = basic_noop<char>;
+
201 using wnoop = basic_noop<wchar_t>;
+
202#ifdef _UNICODE
+
203 using tnoop = wnoop;
+
204#else
+
205 using tnoop = noop;
+
206#endif
+
207 using sgml_noop = basic_noop<char>;
+
208
+
212 template <class T>
+
213 class basic_any_cu : public basic_parser<T>
+
214 {
+
215 public:
+
216 basic_any_cu(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
+
217
+
218 virtual bool match(
+
219 _In_reads_or_z_(end) const T* text,
+
220 _In_ size_t start = 0,
+
221 _In_ size_t end = (size_t)-1,
+
222 _In_ int flags = match_default)
+
223 {
+
224 assert(text || start >= end);
+
225 if (start < end && text[start]) {
+
226 interval.end = (interval.start = start) + 1;
+
227 return true;
+
228 }
+
229 interval.start = (interval.end = start) + 1;
+
230 return false;
+
231 }
+
232 };
+
233
+
234 using any_cu = basic_any_cu<char>;
+
235 using wany_cu = basic_any_cu<wchar_t>;
+
236#ifdef _UNICODE
+
237 using tany_cu = wany_cu;
+
238#else
+
239 using tany_cu = any_cu;
+
240#endif
+
241
+
245 class sgml_any_cp : public basic_any_cu<char>
+
246 {
+
247 public:
+
248 sgml_any_cp(_In_ const std::locale& locale = std::locale()) : basic_any_cu<char>(locale) {}
+
249
+
250 virtual bool match(
+
251 _In_reads_or_z_(end) const char* text,
+
252 _In_ size_t start = 0,
+
253 _In_ size_t end = (size_t)-1,
+
254 _In_ int flags = match_default)
+
255 {
+
256 assert(text || start >= end);
+
257 if (start < end && text[start]) {
+
258 if (text[start] == '&') {
+
259 // SGML entity
+
260 const auto& ctype = std::use_facet<std::ctype<char>>(m_locale);
+
261 for (interval.end = start + 1; interval.end < end && text[interval.end]; interval.end++)
+
262 if (text[interval.end] == ';') {
+
263 interval.end++;
+
264 interval.start = start;
+
265 return true;
+
266 }
+
267 else if (text[interval.end] == '&' || ctype.is(ctype.space, text[interval.end]))
+
268 break;
+
269 // Unterminated entity
+
270 }
+
271 interval.end = (interval.start = start) + 1;
+
272 return true;
+
273 }
+
274 interval.start = (interval.end = start) + 1;
+
275 return false;
+
276 }
+
277 };
+
278
+
282 template <class T>
+
283 class basic_cu : public basic_parser<T>
+
284 {
+
285 public:
+
286 basic_cu(T chr, bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
287 basic_parser<T>(locale),
+
288 m_chr(chr),
+
289 m_invert(invert)
+
290 {}
+
291
+
292 virtual bool match(
+
293 _In_reads_or_z_(end) const T* text,
+
294 _In_ size_t start = 0,
+
295 _In_ size_t end = (size_t)-1,
+
296 _In_ int flags = match_default)
+
297 {
+
298 assert(text || start >= end);
+
299 if (start < end && text[start]) {
+
300 bool r;
+
301 if (flags & match_case_insensitive) {
+
302 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
+
303 r = ctype.tolower(text[start]) == ctype.tolower(m_chr);
+
304 }
+
305 else
+
306 r = text[start] == m_chr;
+
307 if (r && !m_invert || !r && m_invert) {
+
308 interval.end = (interval.start = start) + 1;
+
309 return true;
+
310 }
+
311 }
+
312 interval.start = (interval.end = start) + 1;
+
313 return false;
+
314 }
+
315
+
316 protected:
+
317 T m_chr;
+
318 bool m_invert;
+
319 };
+
320
+
321 using cu = basic_cu<char>;
+
322 using wcu = basic_cu<wchar_t>;
+
323#ifdef _UNICODE
+
324 using tcu = wcu;
+
325#else
+
326 using tcu = cu;
+
327#endif
+
328
+
332 class sgml_cp : public sgml_parser
+
333 {
+
334 public:
+
335 sgml_cp(const char* chr, size_t count = (size_t)-1, bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
336 sgml_parser(locale),
+
337 m_invert(invert)
+
338 {
+
339 assert(chr || !count);
+
340 wchar_t buf[3];
+
341 size_t chr_end;
+
342 m_chr.assign(count ? next_sgml_cp(chr, 0, count, chr_end, buf) : L"");
+
343 }
+
344
+
345 virtual bool match(
+
346 _In_reads_or_z_(end) const char* text,
+
347 _In_ size_t start = 0,
+
348 _In_ size_t end = (size_t)-1,
+
349 _In_ int flags = match_default)
+
350 {
+
351 assert(text || start >= end);
+
352 if (start < end && text[start]) {
+
353 wchar_t buf[3];
+
354 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
+
355 bool r = ((flags & match_case_insensitive) ?
+
356 stdex::strnicmp(chr, (size_t)-1, m_chr.c_str(), m_chr.size(), m_locale) :
+
357 stdex::strncmp(chr, (size_t)-1, m_chr.c_str(), m_chr.size())) == 0;
+
358 if (r && !m_invert || !r && m_invert) {
+
359 interval.start = start;
+
360 return true;
+
361 }
+
362 }
+
363 interval.start = (interval.end = start) + 1;
+
364 return false;
+
365 }
+
366
+
367 protected:
+
368 std::wstring m_chr;
+
369 bool m_invert;
+
370 };
+
371
+
375 template <class T>
+
376 class basic_space_cu : public basic_parser<T>
+
377 {
+
378 public:
+
379 basic_space_cu(bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
380 basic_parser<T>(locale),
+
381 m_invert(invert)
+
382 {}
+
383
+
384 virtual bool match(
+
385 _In_reads_or_z_(end) const T* text,
+
386 _In_ size_t start = 0,
+
387 _In_ size_t end = (size_t)-1,
+
388 _In_ int flags = match_default)
+
389 {
+
390 assert(text || start >= end);
+
391 if (start < end && text[start]) {
+
392 bool r =
+
393 ((flags & match_multiline) || !islbreak(text[start])) &&
+
394 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::space, text[start]);
+
395 if (r && !m_invert || !r && m_invert) {
+
396 interval.end = (interval.start = start) + 1;
+
397 return true;
+
398 }
+
399 }
+
400 interval.start = (interval.end = start) + 1;
+
401 return false;
+
402 }
+
403
+
404 protected:
+
405 bool m_invert;
+
406 };
+
407
+
408 using space_cu = basic_space_cu<char>;
+
409 using wspace_cu = basic_space_cu<wchar_t>;
+
410#ifdef _UNICODE
+
411 using tspace_cu = wspace_cu;
+
412#else
+
413 using tspace_cu = space_cu;
+
414#endif
+
415
+
419 class sgml_space_cp : public basic_space_cu<char>
+
420 {
+
421 public:
+
422 sgml_space_cp(_In_ bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
423 basic_space_cu<char>(invert, locale)
+
424 {}
+
425
+
426 virtual bool match(
+
427 _In_reads_or_z_(end) const char* text,
+
428 _In_ size_t start = 0,
+
429 _In_ size_t end = (size_t)-1,
+
430 _In_ int flags = match_default)
+
431 {
+
432 assert(text || start >= end);
+
433 if (start < end && text[start]) {
+
434 wchar_t buf[3];
+
435 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
+
436 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
437 bool r =
+
438 ((flags & match_multiline) || !islbreak(chr, (size_t)-1)) &&
+
439 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space, chr, chr_end) == chr_end;
+
440 if (r && !m_invert || !r && m_invert) {
+
441 interval.start = start;
+
442 return true;
+
443 }
+
444 }
+
445
+
446 interval.start = (interval.end = start) + 1;
+
447 return false;
+
448 }
+
449 };
+
450
+
454 template <class T>
+
455 class basic_punct_cu : public basic_parser<T>
+
456 {
+
457 public:
+
458 basic_punct_cu(bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
459 basic_parser<T>(locale),
+
460 m_invert(invert)
+
461 {}
+
462
+
463 virtual bool match(
+
464 _In_reads_or_z_(end) const T* text,
+
465 _In_ size_t start = 0,
+
466 _In_ size_t end = (size_t)-1,
+
467 _In_ int flags = match_default)
+
468 {
+
469 assert(text || start >= end);
+
470 if (start < end && text[start]) {
+
471 bool r = std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::punct, text[start]);
+
472 if (r && !m_invert || !r && m_invert) {
+
473 interval.end = (interval.start = start) + 1;
+
474 return true;
+
475 }
+
476 }
+
477 interval.start = (interval.end = start) + 1;
+
478 return false;
+
479 }
+
480
+
481 protected:
+
482 bool m_invert;
+
483 };
+
484
+
485 using punct_cu = basic_punct_cu<char>;
+
486 using wpunct_cu = basic_punct_cu<wchar_t>;
+
487#ifdef _UNICODE
+
488 using tpunct_cu = wpunct_cu;
+
489#else
+
490 using tpunct_cu = punct_cu;
+
491#endif
+
492
+
496 class sgml_punct_cp : public basic_punct_cu<char>
+
497 {
+
498 public:
+
499 sgml_punct_cp(bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
500 basic_punct_cu<char>(invert, locale)
+
501 {}
+
502
+
503 virtual bool match(
+
504 _In_reads_or_z_(end) const char* text,
+
505 _In_ size_t start = 0,
+
506 _In_ size_t end = (size_t)-1,
+
507 _In_ int flags = match_default)
+
508 {
+
509 assert(text || start >= end);
+
510 if (start < end && text[start]) {
+
511 wchar_t buf[3];
+
512 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
+
513 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
514 bool r = std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::punct, chr, chr_end) == chr_end;
+
515 if (r && !m_invert || !r && m_invert) {
+
516 interval.start = start;
+
517 return true;
+
518 }
+
519 }
+
520 interval.start = (interval.end = start) + 1;
+
521 return false;
+
522 }
+
523 };
+
524
+
528 template <class T>
+
529 class basic_space_or_punct_cu : public basic_parser<T>
+
530 {
+
531 public:
+
532 basic_space_or_punct_cu(bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
533 basic_parser<T>(locale),
+
534 m_invert(invert)
+
535 {}
+
536
+
537 virtual bool match(
+
538 _In_reads_or_z_(end) const T* text,
+
539 _In_ size_t start = 0,
+
540 _In_ size_t end = (size_t)-1,
+
541 _In_ int flags = match_default)
+
542 {
+
543 assert(text || start >= end);
+
544 if (start < end && text[start]) {
+
545 bool r =
+
546 ((flags & match_multiline) || !islbreak(text[start])) &&
+
547 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::space | std::ctype_base::punct, text[start]);
+
548 if (r && !m_invert || !r && m_invert) {
+
549 interval.end = (interval.start = start) + 1;
+
550 return true;
+
551 }
+
552 }
+
553 interval.start = (interval.end = start) + 1;
+
554 return false;
+
555 }
+
556
+
557 protected:
+
558 bool m_invert;
+
559 };
+
560
+
561 using space_or_punct_cu = basic_space_or_punct_cu<char>;
+
562 using wspace_or_punct_cu = basic_space_or_punct_cu<wchar_t>;
+
563#ifdef _UNICODE
+
564 using tspace_or_punct_cu = wspace_or_punct_cu;
+
565#else
+
566 using tspace_or_punct_cu = space_or_punct_cu;
+
567#endif
+
568
+
572 class sgml_space_or_punct_cp : public basic_space_or_punct_cu<char>
+
573 {
+
574 public:
+
575 sgml_space_or_punct_cp(bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
576 basic_space_or_punct_cu<char>(invert, locale)
+
577 {}
+
578
+
579 virtual bool match(
+
580 _In_reads_or_z_(end) const char* text,
+
581 _In_ size_t start = 0,
+
582 _In_ size_t end = (size_t)-1,
+
583 _In_ int flags = match_default)
+
584 {
+
585 assert(text || start >= end);
+
586 if (start < end && text[start]) {
+
587 wchar_t buf[3];
+
588 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
+
589 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
590 bool r =
+
591 ((flags & match_multiline) || !islbreak(chr, (size_t)-1)) &&
+
592 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space | std::ctype_base::punct, chr, chr_end) == chr_end;
+
593 if (r && !m_invert || !r && m_invert) {
+
594 interval.start = start;
+
595 return true;
+
596 }
+
597 }
+
598 interval.start = (interval.end = start) + 1;
+
599 return false;
+
600 }
+
601 };
+
602
+
606 template <class T>
+
607 class basic_bol : public basic_parser<T>
+
608 {
+
609 public:
+
610 basic_bol(bool invert = false) : m_invert(invert) {}
+
611
+
612 virtual bool match(
+
613 _In_reads_or_z_(end) const T* text,
+
614 _In_ size_t start = 0,
+
615 _In_ size_t end = (size_t)-1,
+
616 _In_ int flags = match_default)
+
617 {
+
618 assert(text || start >= end);
+
619 bool r = start == 0 || start <= end && islbreak(text[start - 1]);
+
620 if (r && !m_invert || !r && m_invert) {
+
621 interval.end = interval.start = start;
+
622 return true;
+
623 }
+
624 interval.start = (interval.end = start) + 1;
+
625 return false;
+
626 }
+
627
+
628 protected:
+
629 bool m_invert;
+
630 };
+
631
+
632 using bol = basic_bol<char>;
+
633 using wbol = basic_bol<wchar_t>;
+
634#ifdef _UNICODE
+
635 using tbol = wbol;
+
636#else
+
637 using tbol = bol;
+
638#endif
+
639 using sgml_bol = basic_bol<char>;
+
640
+
644 template <class T>
+
645 class basic_eol : public basic_parser<T>
+
646 {
+
647 public:
+
648 basic_eol(bool invert = false) : m_invert(invert) {}
+
649
+
650 virtual bool match(
+
651 _In_reads_or_z_(end) const T* text,
+
652 _In_ size_t start = 0,
+
653 _In_ size_t end = (size_t)-1,
+
654 _In_ int flags = match_default)
+
655 {
+
656 assert(text || start >= end);
+
657 bool r = islbreak(text[start]);
+
658 if (r && !m_invert || !r && m_invert) {
+
659 interval.end = interval.start = start;
+
660 return true;
+
661 }
+
662 interval.start = (interval.end = start) + 1;
+
663 return false;
+
664 }
+
665
+
666 protected:
+
667 bool m_invert;
+
668 };
+
669
+
670 using eol = basic_eol<char>;
+
671 using weol = basic_eol<wchar_t>;
+
672#ifdef _UNICODE
+
673 using teol = weol;
+
674#else
+
675 using teol = eol;
+
676#endif
+
677 using sgml_eol = basic_eol<char>;
+
678
+
679 template <class T>
+
680 class basic_set : public basic_parser<T>
+
681 {
+
682 public:
+
683 basic_set(bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
684 basic_parser<T>(locale),
+
685 hit_offset((size_t)-1),
+
686 m_invert(invert)
+
687 {}
+
688
+
689 virtual bool match(
+
690 _In_reads_or_z_(end) const T* text,
+
691 _In_ size_t start = 0,
+
692 _In_ size_t end = (size_t)-1,
+
693 _In_ int flags = match_default) = 0;
+
694
+
695 virtual void invalidate()
+
696 {
+
697 hit_offset = (size_t)-1;
+
698 basic_parser<T>::invalidate();
+
699 }
+
700
+
701 public:
+
702 size_t hit_offset;
+
703
+
704 protected:
+
705 bool m_invert;
+
706 };
+
707
+
711 template <class T>
+
712 class basic_cu_set : public basic_set<T>
+
713 {
+
714 public:
+
715 basic_cu_set(
+
716 _In_reads_or_z_(count) const T* set,
+
717 _In_ size_t count = (size_t)-1,
+
718 _In_ bool invert = false,
+
719 _In_ const std::locale& locale = std::locale()) :
+
720 basic_set<T>(invert, locale)
+
721 {
+
722 if (set)
+
723 m_set.assign(set, set + stdex::strnlen(set, count));
+
724 }
+
725
+
726 virtual bool match(
+
727 _In_reads_or_z_(end) const T* text,
+
728 _In_ size_t start = 0,
+
729 _In_ size_t end = (size_t)-1,
+
730 _In_ int flags = match_default)
+
731 {
+
732 assert(text || start >= end);
+
733 if (start < end && text[start]) {
+
734 const T* set = m_set.c_str();
+
735 size_t r = (flags & match_case_insensitive) ?
+
736 stdex::strnichr(set, m_set.size(), text[start], m_locale) :
+
737 stdex::strnchr(set, m_set.size(), text[start]);
+
738 if (r != stdex::npos && !m_invert || r == stdex::npos && m_invert) {
+
739 hit_offset = r;
+
740 interval.end = (interval.start = start) + 1;
+
741 return true;
+
742 }
+
743 }
+
744 hit_offset = (size_t)-1;
+
745 interval.start = (interval.end = start) + 1;
+
746 return false;
+
747 }
+
748
+
749 protected:
+
750 std::basic_string<T> m_set;
+
751 };
+
752
+
753 using cu_set = basic_cu_set<char>;
+
754 using wcu_set = basic_cu_set<wchar_t>;
+
755#ifdef _UNICODE
+
756 using tcu_set = wcu_set;
+
757#else
+
758 using tcu_set = cu_set;
+
759#endif
+
760
+
764 class sgml_cp_set : public basic_set<char>
+
765 {
+
766 public:
+
767 sgml_cp_set(const char* set, size_t count = (size_t)-1, bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
768 basic_set<char>(invert, locale)
+
769 {
+
770 if (set)
+
771 m_set = sgml2wstr(set, count);
+
772 }
+
773
+
774 virtual bool match(
+
775 _In_reads_or_z_(end) const char* text,
+
776 _In_ size_t start = 0,
+
777 _In_ size_t end = (size_t)-1,
+
778 _In_ int flags = match_default)
+
779 {
+
780 assert(text || start >= end);
+
781 if (start < end && text[start]) {
+
782 wchar_t buf[3];
+
783 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
+
784 const wchar_t* set = m_set.c_str();
+
785 size_t r = (flags & match_case_insensitive) ?
+
786 stdex::strnistr(set, m_set.size(), chr, m_locale) :
+
787 stdex::strnstr(set, m_set.size(), chr);
+
788 if (r != stdex::npos && !m_invert || r == stdex::npos && m_invert) {
+
789 hit_offset = r;
+
790 interval.start = start;
+
791 return true;
+
792 }
+
793 }
+
794 hit_offset = (size_t)-1;
+
795 interval.start = (interval.end = start) + 1;
+
796 return false;
+
797 }
+
798
+
799 protected:
+
800 std::wstring m_set;
+
801 };
+
802
+
806 template <class T>
+
807 class basic_string : public basic_parser<T>
+
808 {
+
809 public:
+
810 basic_string(
+
811 _In_reads_or_z_(count) const T* str,
+
812 _In_ size_t count = (size_t)-1,
+
813 _In_ const std::locale& locale = std::locale()) :
+
814 basic_parser<T>(locale),
+
815 m_str(str, str + stdex::strnlen(str, count))
+
816 {}
+
817
+
818 virtual bool match(
+
819 _In_reads_or_z_(end) const T* text,
+
820 _In_ size_t start = 0,
+
821 _In_ size_t end = (size_t)-1,
+
822 _In_ int flags = match_default)
+
823 {
+
824 assert(text || start >= end);
+
825 size_t
+
826 m = m_str.size(),
+
827 n = std::min<size_t>(end - start, m);
+
828 bool r = ((flags & match_case_insensitive) ?
+
829 stdex::strnicmp(text + start, n, m_str.c_str(), m, m_locale) :
+
830 stdex::strncmp(text + start, n, m_str.c_str(), m)) == 0;
+
831 if (r) {
+
832 interval.end = (interval.start = start) + n;
+
833 return true;
+
834 }
+
835 interval.start = (interval.end = start) + 1;
+
836 return false;
+
837 }
+
838
+
839 protected:
+
840 std::basic_string<T> m_str;
+
841 };
+
842
+
843 using string = basic_string<char>;
+
844 using wstring = basic_string<wchar_t>;
+
845#ifdef _UNICODE
+
846 using tstring = wstring;
+
847#else
+
848 using tstring = string;
+
849#endif
+
850
+
854 class sgml_string : public sgml_parser
+
855 {
+
856 public:
+
857 sgml_string(const char* str, size_t count = (size_t)-1, _In_ const std::locale& locale = std::locale()) :
+
858 sgml_parser(locale),
+
859 m_str(sgml2wstr(str, count))
+
860 {}
+
861
+
862 virtual bool match(
+
863 _In_reads_or_z_(end) const char* text,
+
864 _In_ size_t start = 0,
+
865 _In_ size_t end = (size_t)-1,
+
866 _In_ int flags = match_default)
+
867 {
+
868 assert(text || start >= end);
+
869 const wchar_t* str = m_str.c_str();
+
870 const bool case_insensitive = flags & match_case_insensitive ? true : false;
+
871 const auto& ctype = std::use_facet<std::ctype<wchar_t>>(m_locale);
+
872 for (interval.end = start;;) {
+
873 if (!*str) {
+
874 interval.start = start;
+
875 return true;
876 }
-
877 }
-
878 }
-
879
-
880 protected:
-
881 std::wstring m_str;
-
882 };
-
883
-
887 template <class T>
-
888 class basic_iterations : public basic_parser<T>
-
889 {
-
890 public:
-
891 basic_iterations(const std::shared_ptr<basic_parser<T>>& el, size_t min_iterations = 0, size_t max_iterations = (size_t)-1, bool greedy = true) :
-
892 m_el(el),
-
893 m_min_iterations(min_iterations),
-
894 m_max_iterations(max_iterations),
-
895 m_greedy(greedy)
-
896 {}
+
877 if (interval.end >= end || !text[interval.end]) {
+
878 interval.start = (interval.end = start) + 1;
+
879 return false;
+
880 }
+
881 wchar_t buf[3];
+
882 const wchar_t* chr = next_sgml_cp(text, interval.end, end, interval.end, buf);
+
883 for (; *chr; ++str, ++chr) {
+
884 if (!*str ||
+
885 (case_insensitive ? ctype.tolower(*str) != ctype.tolower(*chr) : *str != *chr))
+
886 {
+
887 interval.start = (interval.end = start) + 1;
+
888 return false;
+
889 }
+
890 }
+
891 }
+
892 }
+
893
+
894 protected:
+
895 std::wstring m_str;
+
896 };
897
-
898 virtual bool match(
-
899 _In_reads_or_z_(end) const T* text,
-
900 _In_ size_t start = 0,
-
901 _In_ size_t end = (size_t)-1,
-
902 _In_ int flags = match_default)
-
903 {
-
904 assert(text || start >= end);
-
905 interval.start = interval.end = start;
-
906 for (size_t i = 0; ; i++) {
-
907 if (!m_greedy && i >= m_min_iterations || i >= m_max_iterations)
-
908 return true;
-
909 if (!m_el->match(text, interval.end, end, flags)) {
-
910 if (i >= m_min_iterations)
-
911 return true;
-
912 break;
-
913 }
-
914 if (m_el->interval.end == interval.end) {
-
915 // Element did match, but the matching interval was empty. Quit instead of spinning.
-
916 return true;
-
917 }
-
918 interval.end = m_el->interval.end;
-
919 }
-
920 interval.start = (interval.end = start) + 1;
-
921 return false;
-
922 }
-
923
-
924 protected:
-
925 std::shared_ptr<basic_parser<T>> m_el;
-
926 size_t m_min_iterations;
-
927 size_t m_max_iterations;
-
928 bool m_greedy;
-
929 };
-
930
-
931 using iterations = basic_iterations<char>;
-
932 using witerations = basic_iterations<wchar_t>;
-
933#ifdef _UNICODE
-
934 using titerations = witerations;
-
935#else
-
936 using titerations = iterations;
-
937#endif
-
938 using sgml_iterations = basic_iterations<char>;
-
939
-
943 template <class T>
-
944 class parser_collection : public basic_parser<T>
-
945 {
-
946 protected:
-
947 parser_collection(_In_ const std::locale& locale) : basic_parser<T>(locale) {}
-
948
-
949 public:
-
950 parser_collection(
-
951 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el,
-
952 _In_ size_t count,
-
953 _In_ const std::locale& locale = std::locale()) :
-
954 basic_parser<T>(locale)
-
955 {
-
956 assert(el || !count);
-
957 m_collection.reserve(count);
-
958 for (size_t i = 0; i < count; i++)
-
959 m_collection.push_back(el[i]);
-
960 }
-
961
-
962 parser_collection(
-
963 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
-
964 _In_ const std::locale& locale = std::locale()) :
-
965 basic_parser<T>(locale),
-
966 m_collection(std::move(collection))
-
967 {}
-
968
-
969 virtual void invalidate()
-
970 {
-
971 for (auto& el: m_collection)
-
972 el->invalidate();
-
973 basic_parser<T>::invalidate();
+
901 template <class T>
+
902 class basic_iterations : public basic_parser<T>
+
903 {
+
904 public:
+
905 basic_iterations(const std::shared_ptr<basic_parser<T>>& el, size_t min_iterations = 0, size_t max_iterations = (size_t)-1, bool greedy = true) :
+
906 m_el(el),
+
907 m_min_iterations(min_iterations),
+
908 m_max_iterations(max_iterations),
+
909 m_greedy(greedy)
+
910 {}
+
911
+
912 virtual bool match(
+
913 _In_reads_or_z_(end) const T* text,
+
914 _In_ size_t start = 0,
+
915 _In_ size_t end = (size_t)-1,
+
916 _In_ int flags = match_default)
+
917 {
+
918 assert(text || start >= end);
+
919 interval.start = interval.end = start;
+
920 for (size_t i = 0; ; i++) {
+
921 if (!m_greedy && i >= m_min_iterations || i >= m_max_iterations)
+
922 return true;
+
923 if (!m_el->match(text, interval.end, end, flags)) {
+
924 if (i >= m_min_iterations)
+
925 return true;
+
926 break;
+
927 }
+
928 if (m_el->interval.end == interval.end) {
+
929 // Element did match, but the matching interval was empty. Quit instead of spinning.
+
930 return true;
+
931 }
+
932 interval.end = m_el->interval.end;
+
933 }
+
934 interval.start = (interval.end = start) + 1;
+
935 return false;
+
936 }
+
937
+
938 protected:
+
939 std::shared_ptr<basic_parser<T>> m_el;
+
940 size_t m_min_iterations;
+
941 size_t m_max_iterations;
+
942 bool m_greedy;
+
943 };
+
944
+
945 using iterations = basic_iterations<char>;
+
946 using witerations = basic_iterations<wchar_t>;
+
947#ifdef _UNICODE
+
948 using titerations = witerations;
+
949#else
+
950 using titerations = iterations;
+
951#endif
+
952 using sgml_iterations = basic_iterations<char>;
+
953
+
957 template <class T>
+
958 class parser_collection : public basic_parser<T>
+
959 {
+
960 protected:
+
961 parser_collection(_In_ const std::locale& locale) : basic_parser<T>(locale) {}
+
962
+
963 public:
+
964 parser_collection(
+
965 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el,
+
966 _In_ size_t count,
+
967 _In_ const std::locale& locale = std::locale()) :
+
968 basic_parser<T>(locale)
+
969 {
+
970 assert(el || !count);
+
971 m_collection.reserve(count);
+
972 for (size_t i = 0; i < count; i++)
+
973 m_collection.push_back(el[i]);
974 }
975
-
976 protected:
-
977 std::vector<std::shared_ptr<basic_parser<T>>> m_collection;
-
978 };
-
979
-
983 template <class T>
-
984 class basic_sequence : public parser_collection<T>
-
985 {
-
986 public:
-
987 basic_sequence(
-
988 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el = nullptr,
-
989 _In_ size_t count = 0,
-
990 _In_ const std::locale& locale = std::locale()) :
-
991 parser_collection<T>(el, count, locale)
-
992 {}
+
976 parser_collection(
+
977 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
+
978 _In_ const std::locale& locale = std::locale()) :
+
979 basic_parser<T>(locale),
+
980 m_collection(std::move(collection))
+
981 {}
+
982
+
983 virtual void invalidate()
+
984 {
+
985 for (auto& el: m_collection)
+
986 el->invalidate();
+
987 basic_parser<T>::invalidate();
+
988 }
+
989
+
990 protected:
+
991 std::vector<std::shared_ptr<basic_parser<T>>> m_collection;
+
992 };
993
-
994 basic_sequence(
-
995 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
-
996 _In_ const std::locale& locale = std::locale()) :
-
997 parser_collection<T>(std::move(collection), locale)
-
998 {}
-
999
-
1000 virtual bool match(
-
1001 _In_reads_or_z_(end) const T* text,
-
1002 _In_ size_t start = 0,
-
1003 _In_ size_t end = (size_t)-1,
-
1004 _In_ int flags = match_default)
-
1005 {
-
1006 assert(text || start >= end);
-
1007 interval.end = start;
-
1008 for (auto i = m_collection.begin(); i != m_collection.end(); ++i) {
-
1009 if (!(*i)->match(text, interval.end, end, flags)) {
-
1010 for (++i; i != m_collection.end(); ++i)
-
1011 (*i)->invalidate();
-
1012 interval.start = (interval.end = start) + 1;
-
1013 return false;
-
1014 }
-
1015 interval.end = (*i)->interval.end;
-
1016 }
-
1017 interval.start = start;
-
1018 return true;
-
1019 }
-
1020 };
-
1021
-
1022 using sequence = basic_sequence<char>;
-
1023 using wsequence = basic_sequence<wchar_t>;
-
1024#ifdef _UNICODE
-
1025 using tsequence = wsequence;
-
1026#else
-
1027 using tsequence = sequence;
-
1028#endif
-
1029 using sgml_sequence = basic_sequence<char>;
-
1030
-
1034 template <class T>
-
1035 class basic_branch : public parser_collection<T>
-
1036 {
-
1037 protected:
-
1038 basic_branch(_In_ const std::locale& locale) :
-
1039 parser_collection<T>(locale),
-
1040 hit_offset((size_t)-1)
-
1041 {}
-
1042
-
1043 public:
-
1044 basic_branch(
-
1045 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el = nullptr,
-
1046 _In_ size_t count = 0,
-
1047 _In_ const std::locale& locale = std::locale()) :
-
1048 parser_collection<T>(el, count, locale),
-
1049 hit_offset((size_t)-1)
-
1050 {}
-
1051
-
1052 basic_branch(
-
1053 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
-
1054 _In_ const std::locale& locale = std::locale()) :
-
1055 parser_collection<T>(std::move(collection), locale),
-
1056 hit_offset((size_t)-1)
-
1057 {}
-
1058
-
1059 virtual bool match(
-
1060 _In_reads_or_z_(end) const T* text,
-
1061 _In_ size_t start = 0,
-
1062 _In_ size_t end = (size_t)-1,
-
1063 _In_ int flags = match_default)
-
1064 {
-
1065 assert(text || start >= end);
-
1066 hit_offset = 0;
-
1067 for (auto i = m_collection.begin(); i != m_collection.end(); ++i, ++hit_offset) {
-
1068 if ((*i)->match(text, start, end, flags)) {
-
1069 interval = (*i)->interval;
-
1070 for (++i; i != m_collection.end(); ++i)
-
1071 (*i)->invalidate();
-
1072 return true;
-
1073 }
-
1074 }
-
1075 hit_offset = (size_t)-1;
-
1076 interval.start = (interval.end = start) + 1;
-
1077 return false;
-
1078 }
-
1079
-
1080 virtual void invalidate()
-
1081 {
-
1082 hit_offset = (size_t)-1;
-
1083 parser_collection<T>::invalidate();
-
1084 }
-
1085
-
1086 public:
-
1087 size_t hit_offset;
-
1088 };
-
1089
-
1090 using branch = basic_branch<char>;
-
1091 using wbranch = basic_branch<wchar_t>;
-
1092#ifdef _UNICODE
-
1093 using tbranch = wbranch;
-
1094#else
-
1095 using tbranch = branch;
-
1096#endif
-
1097 using sgml_branch = basic_branch<char>;
-
1098
-
1102 template <class T, class T_parser = basic_string<T>>
-
1103 class basic_string_branch : public basic_branch<T>
-
1104 {
-
1105 public:
-
1106 inline basic_string_branch(
-
1107 _In_reads_(count) const T* str_z = nullptr,
-
1108 _In_ size_t count = 0,
-
1109 _In_ const std::locale& locale = std::locale()) :
-
1110 basic_branch<T>(locale)
-
1111 {
-
1112 build(str_z, count);
-
1113 }
-
1114
-
1115 inline basic_string_branch(_In_z_ const T* str, ...) :
-
1116 basic_branch<T>(std::locale())
-
1117 {
-
1118 va_list params;
-
1119 va_start(params, str);
-
1120 build(str, params);
-
1121 va_end(params);
-
1122 }
-
1123
-
1124 inline basic_string_branch(_In_ const std::locale& locale, _In_z_ const T* str, ...) :
-
1125 basic_branch<T>(locale)
-
1126 {
-
1127 va_list params;
-
1128 va_start(params, str);
-
1129 build(str, params);
-
1130 va_end(params);
-
1131 }
-
1132
-
1133 protected:
-
1134 void build(_In_reads_(count) const T* str_z, _In_ size_t count)
-
1135 {
-
1136 assert(str_z || !count);
-
1137 if (count) {
-
1138 size_t offset, n;
-
1139 for (
-
1140 offset = n = 0;
-
1141 offset < count && str_z[offset];
-
1142 offset += stdex::strnlen(str_z + offset, count - offset) + 1, ++n);
-
1143 m_collection.reserve(n);
-
1144 for (
-
1145 offset = 0;
-
1146 offset < count && str_z[offset];
-
1147 offset += stdex::strnlen(str_z + offset, count - offset) + 1)
-
1148 m_collection.push_back(std::move(std::make_shared<T_parser>(str_z + offset, count - offset, m_locale)));
-
1149 }
-
1150 }
-
1151
-
1152 void build(_In_z_ const T* str, _In_ va_list params)
-
1153 {
-
1154 const T* p;
-
1155 for (
-
1156 m_collection.push_back(std::move(std::make_shared<T_parser>(str, (size_t)-1, m_locale)));
-
1157 (p = va_arg(params, const T*)) != nullptr;
-
1158 m_collection.push_back(std::move(std::make_shared<T_parser>(p, (size_t)-1, m_locale))));
-
1159 }
-
1160 };
-
1161
-
1162 using string_branch = basic_string_branch<char>;
-
1163 using wstring_branch = basic_string_branch<wchar_t>;
-
1164#ifdef _UNICODE
-
1165 using tstring_branch = wstring_branch;
-
1166#else
-
1167 using tstring_branch = string_branch;
-
1168#endif
-
1169 using sgml_string_branch = basic_string_branch<char, sgml_string>;
-
1170
-
1174 template <class T>
-
1175 class basic_permutation : public parser_collection<T>
-
1176 {
-
1177 public:
-
1178 basic_permutation(
-
1179 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el = nullptr,
-
1180 _In_ size_t count = 0,
-
1181 _In_ const std::locale& locale = std::locale()) :
-
1182 parser_collection<T>(el, count, locale)
-
1183 {}
+
997 template <class T>
+
998 class basic_sequence : public parser_collection<T>
+
999 {
+
1000 public:
+
1001 basic_sequence(
+
1002 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el = nullptr,
+
1003 _In_ size_t count = 0,
+
1004 _In_ const std::locale& locale = std::locale()) :
+
1005 parser_collection<T>(el, count, locale)
+
1006 {}
+
1007
+
1008 basic_sequence(
+
1009 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
+
1010 _In_ const std::locale& locale = std::locale()) :
+
1011 parser_collection<T>(std::move(collection), locale)
+
1012 {}
+
1013
+
1014 virtual bool match(
+
1015 _In_reads_or_z_(end) const T* text,
+
1016 _In_ size_t start = 0,
+
1017 _In_ size_t end = (size_t)-1,
+
1018 _In_ int flags = match_default)
+
1019 {
+
1020 assert(text || start >= end);
+
1021 interval.end = start;
+
1022 for (auto i = m_collection.begin(); i != m_collection.end(); ++i) {
+
1023 if (!(*i)->match(text, interval.end, end, flags)) {
+
1024 for (++i; i != m_collection.end(); ++i)
+
1025 (*i)->invalidate();
+
1026 interval.start = (interval.end = start) + 1;
+
1027 return false;
+
1028 }
+
1029 interval.end = (*i)->interval.end;
+
1030 }
+
1031 interval.start = start;
+
1032 return true;
+
1033 }
+
1034 };
+
1035
+
1036 using sequence = basic_sequence<char>;
+
1037 using wsequence = basic_sequence<wchar_t>;
+
1038#ifdef _UNICODE
+
1039 using tsequence = wsequence;
+
1040#else
+
1041 using tsequence = sequence;
+
1042#endif
+
1043 using sgml_sequence = basic_sequence<char>;
+
1044
+
1048 template <class T>
+
1049 class basic_branch : public parser_collection<T>
+
1050 {
+
1051 protected:
+
1052 basic_branch(_In_ const std::locale& locale) :
+
1053 parser_collection<T>(locale),
+
1054 hit_offset((size_t)-1)
+
1055 {}
+
1056
+
1057 public:
+
1058 basic_branch(
+
1059 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el = nullptr,
+
1060 _In_ size_t count = 0,
+
1061 _In_ const std::locale& locale = std::locale()) :
+
1062 parser_collection<T>(el, count, locale),
+
1063 hit_offset((size_t)-1)
+
1064 {}
+
1065
+
1066 basic_branch(
+
1067 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
+
1068 _In_ const std::locale& locale = std::locale()) :
+
1069 parser_collection<T>(std::move(collection), locale),
+
1070 hit_offset((size_t)-1)
+
1071 {}
+
1072
+
1073 virtual bool match(
+
1074 _In_reads_or_z_(end) const T* text,
+
1075 _In_ size_t start = 0,
+
1076 _In_ size_t end = (size_t)-1,
+
1077 _In_ int flags = match_default)
+
1078 {
+
1079 assert(text || start >= end);
+
1080 hit_offset = 0;
+
1081 for (auto i = m_collection.begin(); i != m_collection.end(); ++i, ++hit_offset) {
+
1082 if ((*i)->match(text, start, end, flags)) {
+
1083 interval = (*i)->interval;
+
1084 for (++i; i != m_collection.end(); ++i)
+
1085 (*i)->invalidate();
+
1086 return true;
+
1087 }
+
1088 }
+
1089 hit_offset = (size_t)-1;
+
1090 interval.start = (interval.end = start) + 1;
+
1091 return false;
+
1092 }
+
1093
+
1094 virtual void invalidate()
+
1095 {
+
1096 hit_offset = (size_t)-1;
+
1097 parser_collection<T>::invalidate();
+
1098 }
+
1099
+
1100 public:
+
1101 size_t hit_offset;
+
1102 };
+
1103
+
1104 using branch = basic_branch<char>;
+
1105 using wbranch = basic_branch<wchar_t>;
+
1106#ifdef _UNICODE
+
1107 using tbranch = wbranch;
+
1108#else
+
1109 using tbranch = branch;
+
1110#endif
+
1111 using sgml_branch = basic_branch<char>;
+
1112
+
1116 template <class T, class T_parser = basic_string<T>>
+
1117 class basic_string_branch : public basic_branch<T>
+
1118 {
+
1119 public:
+
1120 inline basic_string_branch(
+
1121 _In_reads_(count) const T* str_z = nullptr,
+
1122 _In_ size_t count = 0,
+
1123 _In_ const std::locale& locale = std::locale()) :
+
1124 basic_branch<T>(locale)
+
1125 {
+
1126 build(str_z, count);
+
1127 }
+
1128
+
1129 inline basic_string_branch(_In_z_ const T* str, ...) :
+
1130 basic_branch<T>(std::locale())
+
1131 {
+
1132 va_list params;
+
1133 va_start(params, str);
+
1134 build(str, params);
+
1135 va_end(params);
+
1136 }
+
1137
+
1138 inline basic_string_branch(_In_ const std::locale& locale, _In_z_ const T* str, ...) :
+
1139 basic_branch<T>(locale)
+
1140 {
+
1141 va_list params;
+
1142 va_start(params, str);
+
1143 build(str, params);
+
1144 va_end(params);
+
1145 }
+
1146
+
1147 protected:
+
1148 void build(_In_reads_(count) const T* str_z, _In_ size_t count)
+
1149 {
+
1150 assert(str_z || !count);
+
1151 if (count) {
+
1152 size_t offset, n;
+
1153 for (
+
1154 offset = n = 0;
+
1155 offset < count && str_z[offset];
+
1156 offset += stdex::strnlen(str_z + offset, count - offset) + 1, ++n);
+
1157 m_collection.reserve(n);
+
1158 for (
+
1159 offset = 0;
+
1160 offset < count && str_z[offset];
+
1161 offset += stdex::strnlen(str_z + offset, count - offset) + 1)
+
1162 m_collection.push_back(std::move(std::make_shared<T_parser>(str_z + offset, count - offset, m_locale)));
+
1163 }
+
1164 }
+
1165
+
1166 void build(_In_z_ const T* str, _In_ va_list params)
+
1167 {
+
1168 const T* p;
+
1169 for (
+
1170 m_collection.push_back(std::move(std::make_shared<T_parser>(str, (size_t)-1, m_locale)));
+
1171 (p = va_arg(params, const T*)) != nullptr;
+
1172 m_collection.push_back(std::move(std::make_shared<T_parser>(p, (size_t)-1, m_locale))));
+
1173 }
+
1174 };
+
1175
+
1176 using string_branch = basic_string_branch<char>;
+
1177 using wstring_branch = basic_string_branch<wchar_t>;
+
1178#ifdef _UNICODE
+
1179 using tstring_branch = wstring_branch;
+
1180#else
+
1181 using tstring_branch = string_branch;
+
1182#endif
+
1183 using sgml_string_branch = basic_string_branch<char, sgml_string>;
1184
-
1185 basic_permutation(
-
1186 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
-
1187 _In_ const std::locale& locale = std::locale()) :
-
1188 parser_collection<T>(std::move(collection), locale)
-
1189 {}
-
1190
-
1191 virtual bool match(
-
1192 _In_reads_or_z_(end) const T* text,
-
1193 _In_ size_t start = 0,
-
1194 _In_ size_t end = (size_t)-1,
-
1195 _In_ int flags = match_default)
-
1196 {
-
1197 assert(text || start >= end);
-
1198 for (auto& el: m_collection)
-
1199 el->invalidate();
-
1200 if (match_recursively(text, start, end, flags)) {
-
1201 interval.start = start;
-
1202 return true;
-
1203 }
-
1204 interval.start = (interval.end = start) + 1;
-
1205 return false;
-
1206 }
-
1207
-
1208 protected:
-
1209 bool match_recursively(
-
1210 _In_reads_or_z_(end) const T* text,
-
1211 _In_ size_t start = 0,
-
1212 _In_ size_t end = (size_t)-1,
-
1213 _In_ int flags = match_default)
-
1214 {
-
1215 bool all_matched = true;
-
1216 for (auto& el: m_collection) {
-
1217 if (!el->interval) {
-
1218 // Element was not matched in permutatuion yet.
-
1219 all_matched = false;
-
1220 if (el->match(text, start, end, flags)) {
-
1221 // Element matched for the first time.
-
1222 if (match_recursively(text, el->interval.end, end, flags)) {
-
1223 // Rest of the elements matched too.
-
1224 return true;
-
1225 }
-
1226 el->invalidate();
-
1227 }
-
1228 }
-
1229 }
-
1230 if (all_matched) {
-
1231 interval.end = start;
-
1232 return true;
-
1233 }
-
1234 return false;
-
1235 }
-
1236 };
-
1237
-
1238 using permutation = basic_permutation<char>;
-
1239 using wpermutation = basic_permutation<wchar_t>;
-
1240#ifdef _UNICODE
-
1241 using tpermutation = wpermutation;
-
1242#else
-
1243 using tpermutation = permutation;
-
1244#endif
-
1245 using sgml_permutation = basic_permutation<char>;
-
1246
-
1250 template <class T>
-
1251 class basic_integer : public basic_parser<T>
-
1252 {
-
1253 public:
-
1254 basic_integer(_In_ const std::locale& locale = std::locale()) :
-
1255 basic_parser<T>(locale),
-
1256 value(0)
-
1257 {}
-
1258
-
1259 virtual void invalidate()
-
1260 {
-
1261 value = 0;
-
1262 basic_parser<T>::invalidate();
-
1263 }
-
1264
-
1265 public:
-
1266 size_t value;
-
1267 };
-
1268
-
1272 template <class T>
-
1273 class basic_integer10 : public basic_integer<T>
-
1274 {
-
1275 public:
-
1276 basic_integer10(
-
1277 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
-
1278 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
-
1279 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
-
1280 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
-
1281 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
-
1282 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
-
1283 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
-
1284 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
-
1285 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
-
1286 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
-
1287 _In_ const std::locale& locale = std::locale()) :
-
1288 basic_integer<T>(locale),
-
1289 m_digit_0(digit_0),
-
1290 m_digit_1(digit_1),
-
1291 m_digit_2(digit_2),
-
1292 m_digit_3(digit_3),
-
1293 m_digit_4(digit_4),
-
1294 m_digit_5(digit_5),
-
1295 m_digit_6(digit_6),
-
1296 m_digit_7(digit_7),
-
1297 m_digit_8(digit_8),
-
1298 m_digit_9(digit_9)
-
1299 {}
-
1300
-
1301 virtual bool match(
-
1302 _In_reads_or_z_(end) const T* text,
-
1303 _In_ size_t start = 0,
-
1304 _In_ size_t end = (size_t)-1,
-
1305 _In_ int flags = match_default)
-
1306 {
-
1307 assert(text || start >= end);
-
1308 for (interval.end = start, value = 0; interval.end < end && text[interval.end];) {
-
1309 size_t dig;
-
1310 if (m_digit_0->match(text, interval.end, end, flags)) { dig = 0; interval.end = m_digit_0->interval.end; }
-
1311 else if (m_digit_1->match(text, interval.end, end, flags)) { dig = 1; interval.end = m_digit_1->interval.end; }
-
1312 else if (m_digit_2->match(text, interval.end, end, flags)) { dig = 2; interval.end = m_digit_2->interval.end; }
-
1313 else if (m_digit_3->match(text, interval.end, end, flags)) { dig = 3; interval.end = m_digit_3->interval.end; }
-
1314 else if (m_digit_4->match(text, interval.end, end, flags)) { dig = 4; interval.end = m_digit_4->interval.end; }
-
1315 else if (m_digit_5->match(text, interval.end, end, flags)) { dig = 5; interval.end = m_digit_5->interval.end; }
-
1316 else if (m_digit_6->match(text, interval.end, end, flags)) { dig = 6; interval.end = m_digit_6->interval.end; }
-
1317 else if (m_digit_7->match(text, interval.end, end, flags)) { dig = 7; interval.end = m_digit_7->interval.end; }
-
1318 else if (m_digit_8->match(text, interval.end, end, flags)) { dig = 8; interval.end = m_digit_8->interval.end; }
-
1319 else if (m_digit_9->match(text, interval.end, end, flags)) { dig = 9; interval.end = m_digit_9->interval.end; }
-
1320 else break;
-
1321 value = value * 10 + dig;
-
1322 }
-
1323 if (start < interval.end) {
-
1324 interval.start = start;
-
1325 return true;
-
1326 }
-
1327 interval.start = (interval.end = start) + 1;
-
1328 return false;
-
1329 }
-
1330
-
1331 protected:
-
1332 std::shared_ptr<basic_parser<T>>
-
1333 m_digit_0,
-
1334 m_digit_1,
-
1335 m_digit_2,
-
1336 m_digit_3,
-
1337 m_digit_4,
-
1338 m_digit_5,
-
1339 m_digit_6,
-
1340 m_digit_7,
-
1341 m_digit_8,
-
1342 m_digit_9;
-
1343 };
+
1188 template <class T>
+
1189 class basic_permutation : public parser_collection<T>
+
1190 {
+
1191 public:
+
1192 basic_permutation(
+
1193 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el = nullptr,
+
1194 _In_ size_t count = 0,
+
1195 _In_ const std::locale& locale = std::locale()) :
+
1196 parser_collection<T>(el, count, locale)
+
1197 {}
+
1198
+
1199 basic_permutation(
+
1200 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
+
1201 _In_ const std::locale& locale = std::locale()) :
+
1202 parser_collection<T>(std::move(collection), locale)
+
1203 {}
+
1204
+
1205 virtual bool match(
+
1206 _In_reads_or_z_(end) const T* text,
+
1207 _In_ size_t start = 0,
+
1208 _In_ size_t end = (size_t)-1,
+
1209 _In_ int flags = match_default)
+
1210 {
+
1211 assert(text || start >= end);
+
1212 for (auto& el: m_collection)
+
1213 el->invalidate();
+
1214 if (match_recursively(text, start, end, flags)) {
+
1215 interval.start = start;
+
1216 return true;
+
1217 }
+
1218 interval.start = (interval.end = start) + 1;
+
1219 return false;
+
1220 }
+
1221
+
1222 protected:
+
1223 bool match_recursively(
+
1224 _In_reads_or_z_(end) const T* text,
+
1225 _In_ size_t start = 0,
+
1226 _In_ size_t end = (size_t)-1,
+
1227 _In_ int flags = match_default)
+
1228 {
+
1229 bool all_matched = true;
+
1230 for (auto& el: m_collection) {
+
1231 if (!el->interval) {
+
1232 // Element was not matched in permutatuion yet.
+
1233 all_matched = false;
+
1234 if (el->match(text, start, end, flags)) {
+
1235 // Element matched for the first time.
+
1236 if (match_recursively(text, el->interval.end, end, flags)) {
+
1237 // Rest of the elements matched too.
+
1238 return true;
+
1239 }
+
1240 el->invalidate();
+
1241 }
+
1242 }
+
1243 }
+
1244 if (all_matched) {
+
1245 interval.end = start;
+
1246 return true;
+
1247 }
+
1248 return false;
+
1249 }
+
1250 };
+
1251
+
1252 using permutation = basic_permutation<char>;
+
1253 using wpermutation = basic_permutation<wchar_t>;
+
1254#ifdef _UNICODE
+
1255 using tpermutation = wpermutation;
+
1256#else
+
1257 using tpermutation = permutation;
+
1258#endif
+
1259 using sgml_permutation = basic_permutation<char>;
+
1260
+
1264 template <class T>
+
1265 class basic_integer : public basic_parser<T>
+
1266 {
+
1267 public:
+
1268 basic_integer(_In_ const std::locale& locale = std::locale()) :
+
1269 basic_parser<T>(locale),
+
1270 value(0)
+
1271 {}
+
1272
+
1273 virtual void invalidate()
+
1274 {
+
1275 value = 0;
+
1276 basic_parser<T>::invalidate();
+
1277 }
+
1278
+
1279 public:
+
1280 size_t value;
+
1281 };
+
1282
+
1286 template <class T>
+
1287 class basic_integer10 : public basic_integer<T>
+
1288 {
+
1289 public:
+
1290 basic_integer10(
+
1291 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
+
1292 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
+
1293 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
+
1294 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
+
1295 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
+
1296 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
+
1297 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
+
1298 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
+
1299 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
+
1300 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
+
1301 _In_ const std::locale& locale = std::locale()) :
+
1302 basic_integer<T>(locale),
+
1303 m_digit_0(digit_0),
+
1304 m_digit_1(digit_1),
+
1305 m_digit_2(digit_2),
+
1306 m_digit_3(digit_3),
+
1307 m_digit_4(digit_4),
+
1308 m_digit_5(digit_5),
+
1309 m_digit_6(digit_6),
+
1310 m_digit_7(digit_7),
+
1311 m_digit_8(digit_8),
+
1312 m_digit_9(digit_9)
+
1313 {}
+
1314
+
1315 virtual bool match(
+
1316 _In_reads_or_z_(end) const T* text,
+
1317 _In_ size_t start = 0,
+
1318 _In_ size_t end = (size_t)-1,
+
1319 _In_ int flags = match_default)
+
1320 {
+
1321 assert(text || start >= end);
+
1322 for (interval.end = start, value = 0; interval.end < end && text[interval.end];) {
+
1323 size_t dig;
+
1324 if (m_digit_0->match(text, interval.end, end, flags)) { dig = 0; interval.end = m_digit_0->interval.end; }
+
1325 else if (m_digit_1->match(text, interval.end, end, flags)) { dig = 1; interval.end = m_digit_1->interval.end; }
+
1326 else if (m_digit_2->match(text, interval.end, end, flags)) { dig = 2; interval.end = m_digit_2->interval.end; }
+
1327 else if (m_digit_3->match(text, interval.end, end, flags)) { dig = 3; interval.end = m_digit_3->interval.end; }
+
1328 else if (m_digit_4->match(text, interval.end, end, flags)) { dig = 4; interval.end = m_digit_4->interval.end; }
+
1329 else if (m_digit_5->match(text, interval.end, end, flags)) { dig = 5; interval.end = m_digit_5->interval.end; }
+
1330 else if (m_digit_6->match(text, interval.end, end, flags)) { dig = 6; interval.end = m_digit_6->interval.end; }
+
1331 else if (m_digit_7->match(text, interval.end, end, flags)) { dig = 7; interval.end = m_digit_7->interval.end; }
+
1332 else if (m_digit_8->match(text, interval.end, end, flags)) { dig = 8; interval.end = m_digit_8->interval.end; }
+
1333 else if (m_digit_9->match(text, interval.end, end, flags)) { dig = 9; interval.end = m_digit_9->interval.end; }
+
1334 else break;
+
1335 value = value * 10 + dig;
+
1336 }
+
1337 if (start < interval.end) {
+
1338 interval.start = start;
+
1339 return true;
+
1340 }
+
1341 interval.start = (interval.end = start) + 1;
+
1342 return false;
+
1343 }
1344
-
1345 using integer10 = basic_integer10<char>;
-
1346 using winteger10 = basic_integer10<wchar_t>;
-
1347#ifdef _UNICODE
-
1348 using tinteger10 = winteger10;
-
1349#else
-
1350 using tinteger10 = integer10;
-
1351#endif
-
1352 using sgml_integer10 = basic_integer10<char>;
-
1353
-
1357 template <class T>
-
1358 class basic_integer10ts : public basic_integer<T>
-
1359 {
-
1360 public:
-
1361 basic_integer10ts(
-
1362 _In_ const std::shared_ptr<basic_integer10<T>>& digits,
-
1363 _In_ const std::shared_ptr<basic_set<T>>& separator,
-
1364 _In_ const std::locale& locale = std::locale()) :
-
1365 basic_integer<T>(locale),
-
1366 digit_count(0),
-
1367 has_separators(false),
-
1368 m_digits(digits),
-
1369 m_separator(separator)
-
1370 {}
-
1371
-
1372 virtual bool match(
-
1373 _In_reads_or_z_(end) const T* text,
-
1374 _In_ size_t start = 0,
-
1375 _In_ size_t end = (size_t)-1,
-
1376 _In_ int flags = match_default)
-
1377 {
-
1378 assert(text || start >= end);
-
1379 if (m_digits->match(text, start, end, flags)) {
-
1380 // Leading part match.
-
1381 value = m_digits->value;
-
1382 digit_count = m_digits->interval.size();
-
1383 has_separators = false;
-
1384 interval.start = start;
-
1385 interval.end = m_digits->interval.end;
-
1386 if (m_digits->interval.size() <= 3) {
-
1387 // Maybe separated with thousand separators?
-
1388 size_t hit_offset = (size_t)-1;
-
1389 while (m_separator->match(text, interval.end, end, flags) &&
-
1390 (hit_offset == (size_t)-1 || hit_offset == m_separator->hit_offset) && // All separators must be the same, no mixing.
-
1391 m_digits->match(text, m_separator->interval.end, end, flags) &&
-
1392 m_digits->interval.size() == 3)
-
1393 {
-
1394 // Thousand separator and three-digit integer followed.
-
1395 value = value * 1000 + m_digits->value;
-
1396 digit_count += 3;
-
1397 has_separators = true;
-
1398 interval.end = m_digits->interval.end;
-
1399 hit_offset = m_separator->hit_offset;
-
1400 }
-
1401 }
-
1402
-
1403 return true;
-
1404 }
-
1405 value = 0;
-
1406 interval.start = (interval.end = start) + 1;
-
1407 return false;
-
1408 }
-
1409
-
1410 virtual void invalidate()
-
1411 {
-
1412 digit_count = 0;
-
1413 has_separators = false;
-
1414 basic_integer<T>::invalidate();
-
1415 }
+
1345 protected:
+
1346 std::shared_ptr<basic_parser<T>>
+
1347 m_digit_0,
+
1348 m_digit_1,
+
1349 m_digit_2,
+
1350 m_digit_3,
+
1351 m_digit_4,
+
1352 m_digit_5,
+
1353 m_digit_6,
+
1354 m_digit_7,
+
1355 m_digit_8,
+
1356 m_digit_9;
+
1357 };
+
1358
+
1359 using integer10 = basic_integer10<char>;
+
1360 using winteger10 = basic_integer10<wchar_t>;
+
1361#ifdef _UNICODE
+
1362 using tinteger10 = winteger10;
+
1363#else
+
1364 using tinteger10 = integer10;
+
1365#endif
+
1366 using sgml_integer10 = basic_integer10<char>;
+
1367
+
1371 template <class T>
+
1372 class basic_integer10ts : public basic_integer<T>
+
1373 {
+
1374 public:
+
1375 basic_integer10ts(
+
1376 _In_ const std::shared_ptr<basic_integer10<T>>& digits,
+
1377 _In_ const std::shared_ptr<basic_set<T>>& separator,
+
1378 _In_ const std::locale& locale = std::locale()) :
+
1379 basic_integer<T>(locale),
+
1380 digit_count(0),
+
1381 has_separators(false),
+
1382 m_digits(digits),
+
1383 m_separator(separator)
+
1384 {}
+
1385
+
1386 virtual bool match(
+
1387 _In_reads_or_z_(end) const T* text,
+
1388 _In_ size_t start = 0,
+
1389 _In_ size_t end = (size_t)-1,
+
1390 _In_ int flags = match_default)
+
1391 {
+
1392 assert(text || start >= end);
+
1393 if (m_digits->match(text, start, end, flags)) {
+
1394 // Leading part match.
+
1395 value = m_digits->value;
+
1396 digit_count = m_digits->interval.size();
+
1397 has_separators = false;
+
1398 interval.start = start;
+
1399 interval.end = m_digits->interval.end;
+
1400 if (m_digits->interval.size() <= 3) {
+
1401 // Maybe separated with thousand separators?
+
1402 size_t hit_offset = (size_t)-1;
+
1403 while (m_separator->match(text, interval.end, end, flags) &&
+
1404 (hit_offset == (size_t)-1 || hit_offset == m_separator->hit_offset) && // All separators must be the same, no mixing.
+
1405 m_digits->match(text, m_separator->interval.end, end, flags) &&
+
1406 m_digits->interval.size() == 3)
+
1407 {
+
1408 // Thousand separator and three-digit integer followed.
+
1409 value = value * 1000 + m_digits->value;
+
1410 digit_count += 3;
+
1411 has_separators = true;
+
1412 interval.end = m_digits->interval.end;
+
1413 hit_offset = m_separator->hit_offset;
+
1414 }
+
1415 }
1416
-
1417 public:
-
1418 size_t digit_count;
-
1419 bool has_separators;
-
1420
-
1421 protected:
-
1422 std::shared_ptr<basic_integer10<T>> m_digits;
-
1423 std::shared_ptr<basic_set<T>> m_separator;
-
1424 };
-
1425
-
1426 using integer10ts = basic_integer10ts<char>;
-
1427 using winteger10ts = basic_integer10ts<wchar_t>;
-
1428#ifdef _UNICODE
-
1429 using tinteger10ts = winteger10ts;
-
1430#else
-
1431 using tinteger10ts = integer10ts;
-
1432#endif
-
1433 using sgml_integer10ts = basic_integer10ts<char>;
+
1417 return true;
+
1418 }
+
1419 value = 0;
+
1420 interval.start = (interval.end = start) + 1;
+
1421 return false;
+
1422 }
+
1423
+
1424 virtual void invalidate()
+
1425 {
+
1426 digit_count = 0;
+
1427 has_separators = false;
+
1428 basic_integer<T>::invalidate();
+
1429 }
+
1430
+
1431 public:
+
1432 size_t digit_count;
+
1433 bool has_separators;
1434
-
1438 template <class T>
-
1439 class basic_integer16 : public basic_integer<T>
-
1440 {
-
1441 public:
-
1442 basic_integer16(
-
1443 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
-
1444 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
-
1445 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
-
1446 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
-
1447 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
-
1448 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
-
1449 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
-
1450 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
-
1451 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
-
1452 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
-
1453 _In_ const std::shared_ptr<basic_parser<T>>& digit_10,
-
1454 _In_ const std::shared_ptr<basic_parser<T>>& digit_11,
-
1455 _In_ const std::shared_ptr<basic_parser<T>>& digit_12,
-
1456 _In_ const std::shared_ptr<basic_parser<T>>& digit_13,
-
1457 _In_ const std::shared_ptr<basic_parser<T>>& digit_14,
-
1458 _In_ const std::shared_ptr<basic_parser<T>>& digit_15,
-
1459 _In_ const std::locale& locale = std::locale()) :
-
1460 basic_integer<T>(locale),
-
1461 m_digit_0(digit_0),
-
1462 m_digit_1(digit_1),
-
1463 m_digit_2(digit_2),
-
1464 m_digit_3(digit_3),
-
1465 m_digit_4(digit_4),
-
1466 m_digit_5(digit_5),
-
1467 m_digit_6(digit_6),
-
1468 m_digit_7(digit_7),
-
1469 m_digit_8(digit_8),
-
1470 m_digit_9(digit_9),
-
1471 m_digit_10(digit_10),
-
1472 m_digit_11(digit_11),
-
1473 m_digit_12(digit_12),
-
1474 m_digit_13(digit_13),
-
1475 m_digit_14(digit_14),
-
1476 m_digit_15(digit_15)
-
1477 {}
-
1478
-
1479 virtual bool match(
-
1480 _In_reads_or_z_(end) const T* text,
-
1481 _In_ size_t start = 0,
-
1482 _In_ size_t end = (size_t)-1,
-
1483 _In_ int flags = match_default)
-
1484 {
-
1485 assert(text || start >= end);
-
1486 for (interval.end = start, value = 0; interval.end < end && text[interval.end];) {
-
1487 size_t dig;
-
1488 if (m_digit_0->match(text, interval.end, end, flags)) { dig = 0; interval.end = m_digit_0->interval.end; }
-
1489 else if (m_digit_1->match(text, interval.end, end, flags)) { dig = 1; interval.end = m_digit_1->interval.end; }
-
1490 else if (m_digit_2->match(text, interval.end, end, flags)) { dig = 2; interval.end = m_digit_2->interval.end; }
-
1491 else if (m_digit_3->match(text, interval.end, end, flags)) { dig = 3; interval.end = m_digit_3->interval.end; }
-
1492 else if (m_digit_4->match(text, interval.end, end, flags)) { dig = 4; interval.end = m_digit_4->interval.end; }
-
1493 else if (m_digit_5->match(text, interval.end, end, flags)) { dig = 5; interval.end = m_digit_5->interval.end; }
-
1494 else if (m_digit_6->match(text, interval.end, end, flags)) { dig = 6; interval.end = m_digit_6->interval.end; }
-
1495 else if (m_digit_7->match(text, interval.end, end, flags)) { dig = 7; interval.end = m_digit_7->interval.end; }
-
1496 else if (m_digit_8->match(text, interval.end, end, flags)) { dig = 8; interval.end = m_digit_8->interval.end; }
-
1497 else if (m_digit_9->match(text, interval.end, end, flags)) { dig = 9; interval.end = m_digit_9->interval.end; }
-
1498 else if (m_digit_10->match(text, interval.end, end, flags)) { dig = 10; interval.end = m_digit_10->interval.end; }
-
1499 else if (m_digit_11->match(text, interval.end, end, flags)) { dig = 11; interval.end = m_digit_11->interval.end; }
-
1500 else if (m_digit_12->match(text, interval.end, end, flags)) { dig = 12; interval.end = m_digit_12->interval.end; }
-
1501 else if (m_digit_13->match(text, interval.end, end, flags)) { dig = 13; interval.end = m_digit_13->interval.end; }
-
1502 else if (m_digit_14->match(text, interval.end, end, flags)) { dig = 14; interval.end = m_digit_14->interval.end; }
-
1503 else if (m_digit_15->match(text, interval.end, end, flags)) { dig = 15; interval.end = m_digit_15->interval.end; }
-
1504 else break;
-
1505 value = value * 16 + dig;
-
1506 }
-
1507 if (start < interval.end) {
-
1508 interval.start = start;
-
1509 return true;
-
1510 }
-
1511 interval.start = (interval.end = start) + 1;
-
1512 return false;
-
1513 }
-
1514
-
1515 protected:
-
1516 std::shared_ptr<basic_parser<T>>
-
1517 m_digit_0,
-
1518 m_digit_1,
-
1519 m_digit_2,
-
1520 m_digit_3,
-
1521 m_digit_4,
-
1522 m_digit_5,
-
1523 m_digit_6,
-
1524 m_digit_7,
-
1525 m_digit_8,
-
1526 m_digit_9,
-
1527 m_digit_10,
-
1528 m_digit_11,
-
1529 m_digit_12,
-
1530 m_digit_13,
-
1531 m_digit_14,
-
1532 m_digit_15;
-
1533 };
-
1534
-
1535 using integer16 = basic_integer16<char>;
-
1536 using winteger16 = basic_integer16<wchar_t>;
-
1537#ifdef _UNICODE
-
1538 using tinteger16 = winteger16;
-
1539#else
-
1540 using tinteger16 = integer16;
-
1541#endif
-
1542 using sgml_integer16 = basic_integer16<char>;
-
1543
-
1547 template <class T>
-
1548 class basic_roman_numeral : public basic_integer<T>
-
1549 {
-
1550 public:
-
1551 basic_roman_numeral(
-
1552 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
-
1553 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
-
1554 _In_ const std::shared_ptr<basic_parser<T>>& digit_10,
-
1555 _In_ const std::shared_ptr<basic_parser<T>>& digit_50,
-
1556 _In_ const std::shared_ptr<basic_parser<T>>& digit_100,
-
1557 _In_ const std::shared_ptr<basic_parser<T>>& digit_500,
-
1558 _In_ const std::shared_ptr<basic_parser<T>>& digit_1000,
-
1559 _In_ const std::shared_ptr<basic_parser<T>>& digit_5000,
-
1560 _In_ const std::shared_ptr<basic_parser<T>>& digit_10000,
-
1561 _In_ const std::locale& locale = std::locale()) :
-
1562 basic_integer<T>(locale),
-
1563 m_digit_1(digit_1),
-
1564 m_digit_5(digit_5),
-
1565 m_digit_10(digit_10),
-
1566 m_digit_50(digit_50),
-
1567 m_digit_100(digit_100),
-
1568 m_digit_500(digit_500),
-
1569 m_digit_1000(digit_1000),
-
1570 m_digit_5000(digit_5000),
-
1571 m_digit_10000(digit_10000)
-
1572 {}
-
1573
-
1574 virtual bool match(
-
1575 _In_reads_or_z_(end) const T* text,
-
1576 _In_ size_t start = 0,
-
1577 _In_ size_t end = (size_t)-1,
-
1578 _In_ int flags = match_default)
-
1579 {
-
1580 assert(text || start >= end);
-
1581 size_t
-
1582 dig[5] = { (size_t)-1, (size_t)-1, (size_t)-1, (size_t)-1, (size_t)-1 },
-
1583 end2;
-
1584
-
1585 for (interval.end = start, value = 0; interval.end < end && text[interval.end]; dig[3] = dig[2], dig[2] = dig[1], dig[1] = dig[0], interval.end = end2) {
-
1586 if (m_digit_1 && m_digit_1->match(text, interval.end, end, flags)) { dig[0] = 1; end2 = m_digit_1->interval.end; }
-
1587 else if (m_digit_5 && m_digit_5->match(text, interval.end, end, flags)) { dig[0] = 5; end2 = m_digit_5->interval.end; }
-
1588 else if (m_digit_10 && m_digit_10->match(text, interval.end, end, flags)) { dig[0] = 10; end2 = m_digit_10->interval.end; }
-
1589 else if (m_digit_50 && m_digit_50->match(text, interval.end, end, flags)) { dig[0] = 50; end2 = m_digit_50->interval.end; }
-
1590 else if (m_digit_100 && m_digit_100->match(text, interval.end, end, flags)) { dig[0] = 100; end2 = m_digit_100->interval.end; }
-
1591 else if (m_digit_500 && m_digit_500->match(text, interval.end, end, flags)) { dig[0] = 500; end2 = m_digit_500->interval.end; }
-
1592 else if (m_digit_1000 && m_digit_1000->match(text, interval.end, end, flags)) { dig[0] = 1000; end2 = m_digit_1000->interval.end; }
-
1593 else if (m_digit_5000 && m_digit_5000->match(text, interval.end, end, flags)) { dig[0] = 5000; end2 = m_digit_5000->interval.end; }
-
1594 else if (m_digit_10000 && m_digit_10000->match(text, interval.end, end, flags)) { dig[0] = 10000; end2 = m_digit_10000->interval.end; }
-
1595 else break;
-
1596
-
1597 // Store first digit.
-
1598 if (dig[4] == (size_t)-1) dig[4] = dig[0];
-
1599
-
1600 if (dig[3] == dig[2] && dig[2] == dig[1] && dig[1] == dig[0] && dig[0] != dig[4]) {
-
1601 // Same digit repeated four times. No-go, unless first digit. E.g. XIIII vs. XIV. MMMMMCD allowed, IIII also...
-
1602 break;
-
1603 }
-
1604 if (dig[0] <= dig[1]) {
-
1605 // Digit is less or equal previous one: add.
-
1606 value += dig[0];
-
1607 }
-
1608 else if (
-
1609 dig[1] == 1 && (dig[0] == 5 || dig[0] == 10) ||
-
1610 dig[1] == 10 && (dig[0] == 50 || dig[0] == 100) ||
-
1611 dig[1] == 100 && (dig[0] == 500 || dig[0] == 1000) ||
-
1612 dig[1] == 1000 && (dig[0] == 5000 || dig[0] == 10000))
-
1613 {
-
1614 // Digit is up to two orders bigger than previous one: subtract. But...
-
1615 if (dig[2] < dig[0]) {
-
1616 // Digit is also bigger than pre-previous one. E.g. VIX (V < X => invalid)
-
1617 break;
-
1618 }
-
1619 value -= dig[1]; // Cancel addition in the previous step.
-
1620 dig[0] -= dig[1]; // Combine last two digits.
-
1621 dig[1] = dig[2]; // The true previous digit is now pre-previous one. :)
-
1622 dig[2] = dig[3]; // The true pre-previous digit is now pre-pre-previous one. :)
-
1623 value += dig[0]; // Add combined value.
-
1624 }
-
1625 else {
-
1626 // New digit is too big than the previous one. E.g. VX (V < X => invalid)
-
1627 break;
-
1628 }
-
1629 }
-
1630 if (value) {
-
1631 interval.start = start;
-
1632 return true;
-
1633 }
-
1634 interval.start = (interval.end = start) + 1;
-
1635 return false;
-
1636 }
-
1637
-
1638 protected:
-
1639 std::shared_ptr<basic_parser<T>>
-
1640 m_digit_1,
-
1641 m_digit_5,
-
1642 m_digit_10,
-
1643 m_digit_50,
-
1644 m_digit_100,
-
1645 m_digit_500,
-
1646 m_digit_1000,
-
1647 m_digit_5000,
-
1648 m_digit_10000;
-
1649 };
-
1650
-
1651 using roman_numeral = basic_roman_numeral<char>;
-
1652 using wroman_numeral = basic_roman_numeral<wchar_t>;
-
1653#ifdef _UNICODE
-
1654 using troman_numeral = wroman_numeral;
-
1655#else
-
1656 using troman_numeral = roman_numeral;
-
1657#endif
-
1658 using sgml_roman_numeral = basic_roman_numeral<char>;
-
1659
-
1663 template <class T>
-
1664 class basic_fraction : public basic_parser<T>
-
1665 {
-
1666 public:
-
1667 basic_fraction(
-
1668 _In_ const std::shared_ptr<basic_parser<T>>& _numerator,
-
1669 _In_ const std::shared_ptr<basic_parser<T>>& _fraction_line,
-
1670 _In_ const std::shared_ptr<basic_parser<T>>& _denominator,
-
1671 _In_ const std::locale& locale = std::locale()) :
-
1672 basic_parser<T>(locale),
-
1673 numerator(_numerator),
-
1674 fraction_line(_fraction_line),
-
1675 denominator(_denominator)
-
1676 {}
-
1677
-
1678 virtual bool match(
-
1679 _In_reads_or_z_(end) const T* text,
-
1680 _In_ size_t start = 0,
-
1681 _In_ size_t end = (size_t)-1,
-
1682 _In_ int flags = match_default)
-
1683 {
-
1684 assert(text || start >= end);
-
1685 if (numerator->match(text, start, end, flags) &&
-
1686 fraction_line->match(text, numerator->interval.end, end, flags) &&
-
1687 denominator->match(text, fraction_line->interval.end, end, flags))
-
1688 {
-
1689 interval.start = start;
-
1690 interval.end = denominator->interval.end;
-
1691 return true;
-
1692 }
-
1693 numerator->invalidate();
-
1694 fraction_line->invalidate();
-
1695 denominator->invalidate();
-
1696 interval.start = (interval.end = start) + 1;
-
1697 return false;
-
1698 }
-
1699
-
1700 virtual void invalidate()
-
1701 {
-
1702 numerator->invalidate();
-
1703 fraction_line->invalidate();
-
1704 denominator->invalidate();
-
1705 basic_parser<T>::invalidate();
-
1706 }
-
1707
-
1708 public:
-
1709 std::shared_ptr<basic_parser<T>> numerator;
-
1710 std::shared_ptr<basic_parser<T>> fraction_line;
-
1711 std::shared_ptr<basic_parser<T>> denominator;
-
1712 };
+
1435 protected:
+
1436 std::shared_ptr<basic_integer10<T>> m_digits;
+
1437 std::shared_ptr<basic_set<T>> m_separator;
+
1438 };
+
1439
+
1440 using integer10ts = basic_integer10ts<char>;
+
1441 using winteger10ts = basic_integer10ts<wchar_t>;
+
1442#ifdef _UNICODE
+
1443 using tinteger10ts = winteger10ts;
+
1444#else
+
1445 using tinteger10ts = integer10ts;
+
1446#endif
+
1447 using sgml_integer10ts = basic_integer10ts<char>;
+
1448
+
1452 template <class T>
+
1453 class basic_integer16 : public basic_integer<T>
+
1454 {
+
1455 public:
+
1456 basic_integer16(
+
1457 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
+
1458 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
+
1459 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
+
1460 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
+
1461 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
+
1462 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
+
1463 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
+
1464 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
+
1465 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
+
1466 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
+
1467 _In_ const std::shared_ptr<basic_parser<T>>& digit_10,
+
1468 _In_ const std::shared_ptr<basic_parser<T>>& digit_11,
+
1469 _In_ const std::shared_ptr<basic_parser<T>>& digit_12,
+
1470 _In_ const std::shared_ptr<basic_parser<T>>& digit_13,
+
1471 _In_ const std::shared_ptr<basic_parser<T>>& digit_14,
+
1472 _In_ const std::shared_ptr<basic_parser<T>>& digit_15,
+
1473 _In_ const std::locale& locale = std::locale()) :
+
1474 basic_integer<T>(locale),
+
1475 m_digit_0(digit_0),
+
1476 m_digit_1(digit_1),
+
1477 m_digit_2(digit_2),
+
1478 m_digit_3(digit_3),
+
1479 m_digit_4(digit_4),
+
1480 m_digit_5(digit_5),
+
1481 m_digit_6(digit_6),
+
1482 m_digit_7(digit_7),
+
1483 m_digit_8(digit_8),
+
1484 m_digit_9(digit_9),
+
1485 m_digit_10(digit_10),
+
1486 m_digit_11(digit_11),
+
1487 m_digit_12(digit_12),
+
1488 m_digit_13(digit_13),
+
1489 m_digit_14(digit_14),
+
1490 m_digit_15(digit_15)
+
1491 {}
+
1492
+
1493 virtual bool match(
+
1494 _In_reads_or_z_(end) const T* text,
+
1495 _In_ size_t start = 0,
+
1496 _In_ size_t end = (size_t)-1,
+
1497 _In_ int flags = match_default)
+
1498 {
+
1499 assert(text || start >= end);
+
1500 for (interval.end = start, value = 0; interval.end < end && text[interval.end];) {
+
1501 size_t dig;
+
1502 if (m_digit_0->match(text, interval.end, end, flags)) { dig = 0; interval.end = m_digit_0->interval.end; }
+
1503 else if (m_digit_1->match(text, interval.end, end, flags)) { dig = 1; interval.end = m_digit_1->interval.end; }
+
1504 else if (m_digit_2->match(text, interval.end, end, flags)) { dig = 2; interval.end = m_digit_2->interval.end; }
+
1505 else if (m_digit_3->match(text, interval.end, end, flags)) { dig = 3; interval.end = m_digit_3->interval.end; }
+
1506 else if (m_digit_4->match(text, interval.end, end, flags)) { dig = 4; interval.end = m_digit_4->interval.end; }
+
1507 else if (m_digit_5->match(text, interval.end, end, flags)) { dig = 5; interval.end = m_digit_5->interval.end; }
+
1508 else if (m_digit_6->match(text, interval.end, end, flags)) { dig = 6; interval.end = m_digit_6->interval.end; }
+
1509 else if (m_digit_7->match(text, interval.end, end, flags)) { dig = 7; interval.end = m_digit_7->interval.end; }
+
1510 else if (m_digit_8->match(text, interval.end, end, flags)) { dig = 8; interval.end = m_digit_8->interval.end; }
+
1511 else if (m_digit_9->match(text, interval.end, end, flags)) { dig = 9; interval.end = m_digit_9->interval.end; }
+
1512 else if (m_digit_10->match(text, interval.end, end, flags)) { dig = 10; interval.end = m_digit_10->interval.end; }
+
1513 else if (m_digit_11->match(text, interval.end, end, flags)) { dig = 11; interval.end = m_digit_11->interval.end; }
+
1514 else if (m_digit_12->match(text, interval.end, end, flags)) { dig = 12; interval.end = m_digit_12->interval.end; }
+
1515 else if (m_digit_13->match(text, interval.end, end, flags)) { dig = 13; interval.end = m_digit_13->interval.end; }
+
1516 else if (m_digit_14->match(text, interval.end, end, flags)) { dig = 14; interval.end = m_digit_14->interval.end; }
+
1517 else if (m_digit_15->match(text, interval.end, end, flags)) { dig = 15; interval.end = m_digit_15->interval.end; }
+
1518 else break;
+
1519 value = value * 16 + dig;
+
1520 }
+
1521 if (start < interval.end) {
+
1522 interval.start = start;
+
1523 return true;
+
1524 }
+
1525 interval.start = (interval.end = start) + 1;
+
1526 return false;
+
1527 }
+
1528
+
1529 protected:
+
1530 std::shared_ptr<basic_parser<T>>
+
1531 m_digit_0,
+
1532 m_digit_1,
+
1533 m_digit_2,
+
1534 m_digit_3,
+
1535 m_digit_4,
+
1536 m_digit_5,
+
1537 m_digit_6,
+
1538 m_digit_7,
+
1539 m_digit_8,
+
1540 m_digit_9,
+
1541 m_digit_10,
+
1542 m_digit_11,
+
1543 m_digit_12,
+
1544 m_digit_13,
+
1545 m_digit_14,
+
1546 m_digit_15;
+
1547 };
+
1548
+
1549 using integer16 = basic_integer16<char>;
+
1550 using winteger16 = basic_integer16<wchar_t>;
+
1551#ifdef _UNICODE
+
1552 using tinteger16 = winteger16;
+
1553#else
+
1554 using tinteger16 = integer16;
+
1555#endif
+
1556 using sgml_integer16 = basic_integer16<char>;
+
1557
+
1561 template <class T>
+
1562 class basic_roman_numeral : public basic_integer<T>
+
1563 {
+
1564 public:
+
1565 basic_roman_numeral(
+
1566 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
+
1567 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
+
1568 _In_ const std::shared_ptr<basic_parser<T>>& digit_10,
+
1569 _In_ const std::shared_ptr<basic_parser<T>>& digit_50,
+
1570 _In_ const std::shared_ptr<basic_parser<T>>& digit_100,
+
1571 _In_ const std::shared_ptr<basic_parser<T>>& digit_500,
+
1572 _In_ const std::shared_ptr<basic_parser<T>>& digit_1000,
+
1573 _In_ const std::shared_ptr<basic_parser<T>>& digit_5000,
+
1574 _In_ const std::shared_ptr<basic_parser<T>>& digit_10000,
+
1575 _In_ const std::locale& locale = std::locale()) :
+
1576 basic_integer<T>(locale),
+
1577 m_digit_1(digit_1),
+
1578 m_digit_5(digit_5),
+
1579 m_digit_10(digit_10),
+
1580 m_digit_50(digit_50),
+
1581 m_digit_100(digit_100),
+
1582 m_digit_500(digit_500),
+
1583 m_digit_1000(digit_1000),
+
1584 m_digit_5000(digit_5000),
+
1585 m_digit_10000(digit_10000)
+
1586 {}
+
1587
+
1588 virtual bool match(
+
1589 _In_reads_or_z_(end) const T* text,
+
1590 _In_ size_t start = 0,
+
1591 _In_ size_t end = (size_t)-1,
+
1592 _In_ int flags = match_default)
+
1593 {
+
1594 assert(text || start >= end);
+
1595 size_t
+
1596 dig[5] = { (size_t)-1, (size_t)-1, (size_t)-1, (size_t)-1, (size_t)-1 },
+
1597 end2;
+
1598
+
1599 for (interval.end = start, value = 0; interval.end < end && text[interval.end]; dig[3] = dig[2], dig[2] = dig[1], dig[1] = dig[0], interval.end = end2) {
+
1600 if (m_digit_1 && m_digit_1->match(text, interval.end, end, flags)) { dig[0] = 1; end2 = m_digit_1->interval.end; }
+
1601 else if (m_digit_5 && m_digit_5->match(text, interval.end, end, flags)) { dig[0] = 5; end2 = m_digit_5->interval.end; }
+
1602 else if (m_digit_10 && m_digit_10->match(text, interval.end, end, flags)) { dig[0] = 10; end2 = m_digit_10->interval.end; }
+
1603 else if (m_digit_50 && m_digit_50->match(text, interval.end, end, flags)) { dig[0] = 50; end2 = m_digit_50->interval.end; }
+
1604 else if (m_digit_100 && m_digit_100->match(text, interval.end, end, flags)) { dig[0] = 100; end2 = m_digit_100->interval.end; }
+
1605 else if (m_digit_500 && m_digit_500->match(text, interval.end, end, flags)) { dig[0] = 500; end2 = m_digit_500->interval.end; }
+
1606 else if (m_digit_1000 && m_digit_1000->match(text, interval.end, end, flags)) { dig[0] = 1000; end2 = m_digit_1000->interval.end; }
+
1607 else if (m_digit_5000 && m_digit_5000->match(text, interval.end, end, flags)) { dig[0] = 5000; end2 = m_digit_5000->interval.end; }
+
1608 else if (m_digit_10000 && m_digit_10000->match(text, interval.end, end, flags)) { dig[0] = 10000; end2 = m_digit_10000->interval.end; }
+
1609 else break;
+
1610
+
1611 // Store first digit.
+
1612 if (dig[4] == (size_t)-1) dig[4] = dig[0];
+
1613
+
1614 if (dig[3] == dig[2] && dig[2] == dig[1] && dig[1] == dig[0] && dig[0] != dig[4]) {
+
1615 // Same digit repeated four times. No-go, unless first digit. E.g. XIIII vs. XIV. MMMMMCD allowed, IIII also...
+
1616 break;
+
1617 }
+
1618 if (dig[0] <= dig[1]) {
+
1619 // Digit is less or equal previous one: add.
+
1620 value += dig[0];
+
1621 }
+
1622 else if (
+
1623 dig[1] == 1 && (dig[0] == 5 || dig[0] == 10) ||
+
1624 dig[1] == 10 && (dig[0] == 50 || dig[0] == 100) ||
+
1625 dig[1] == 100 && (dig[0] == 500 || dig[0] == 1000) ||
+
1626 dig[1] == 1000 && (dig[0] == 5000 || dig[0] == 10000))
+
1627 {
+
1628 // Digit is up to two orders bigger than previous one: subtract. But...
+
1629 if (dig[2] < dig[0]) {
+
1630 // Digit is also bigger than pre-previous one. E.g. VIX (V < X => invalid)
+
1631 break;
+
1632 }
+
1633 value -= dig[1]; // Cancel addition in the previous step.
+
1634 dig[0] -= dig[1]; // Combine last two digits.
+
1635 dig[1] = dig[2]; // The true previous digit is now pre-previous one. :)
+
1636 dig[2] = dig[3]; // The true pre-previous digit is now pre-pre-previous one. :)
+
1637 value += dig[0]; // Add combined value.
+
1638 }
+
1639 else {
+
1640 // New digit is too big than the previous one. E.g. VX (V < X => invalid)
+
1641 break;
+
1642 }
+
1643 }
+
1644 if (value) {
+
1645 interval.start = start;
+
1646 return true;
+
1647 }
+
1648 interval.start = (interval.end = start) + 1;
+
1649 return false;
+
1650 }
+
1651
+
1652 protected:
+
1653 std::shared_ptr<basic_parser<T>>
+
1654 m_digit_1,
+
1655 m_digit_5,
+
1656 m_digit_10,
+
1657 m_digit_50,
+
1658 m_digit_100,
+
1659 m_digit_500,
+
1660 m_digit_1000,
+
1661 m_digit_5000,
+
1662 m_digit_10000;
+
1663 };
+
1664
+
1665 using roman_numeral = basic_roman_numeral<char>;
+
1666 using wroman_numeral = basic_roman_numeral<wchar_t>;
+
1667#ifdef _UNICODE
+
1668 using troman_numeral = wroman_numeral;
+
1669#else
+
1670 using troman_numeral = roman_numeral;
+
1671#endif
+
1672 using sgml_roman_numeral = basic_roman_numeral<char>;
+
1673
+
1677 template <class T>
+
1678 class basic_fraction : public basic_parser<T>
+
1679 {
+
1680 public:
+
1681 basic_fraction(
+
1682 _In_ const std::shared_ptr<basic_parser<T>>& _numerator,
+
1683 _In_ const std::shared_ptr<basic_parser<T>>& _fraction_line,
+
1684 _In_ const std::shared_ptr<basic_parser<T>>& _denominator,
+
1685 _In_ const std::locale& locale = std::locale()) :
+
1686 basic_parser<T>(locale),
+
1687 numerator(_numerator),
+
1688 fraction_line(_fraction_line),
+
1689 denominator(_denominator)
+
1690 {}
+
1691
+
1692 virtual bool match(
+
1693 _In_reads_or_z_(end) const T* text,
+
1694 _In_ size_t start = 0,
+
1695 _In_ size_t end = (size_t)-1,
+
1696 _In_ int flags = match_default)
+
1697 {
+
1698 assert(text || start >= end);
+
1699 if (numerator->match(text, start, end, flags) &&
+
1700 fraction_line->match(text, numerator->interval.end, end, flags) &&
+
1701 denominator->match(text, fraction_line->interval.end, end, flags))
+
1702 {
+
1703 interval.start = start;
+
1704 interval.end = denominator->interval.end;
+
1705 return true;
+
1706 }
+
1707 numerator->invalidate();
+
1708 fraction_line->invalidate();
+
1709 denominator->invalidate();
+
1710 interval.start = (interval.end = start) + 1;
+
1711 return false;
+
1712 }
1713
-
1714 using fraction = basic_fraction<char>;
-
1715 using wfraction = basic_fraction<wchar_t>;
-
1716#ifdef _UNICODE
-
1717 using tfraction = wfraction;
-
1718#else
-
1719 using tfraction = fraction;
-
1720#endif
-
1721 using sgml_fraction = basic_fraction<char>;
-
1722
-
1726 template <class T>
-
1727 class basic_score : public basic_parser<T>
-
1728 {
-
1729 public:
-
1730 basic_score(
-
1731 _In_ const std::shared_ptr<basic_parser<T>>& _home,
-
1732 _In_ const std::shared_ptr<basic_parser<T>>& _separator,
-
1733 _In_ const std::shared_ptr<basic_parser<T>>& _guest,
-
1734 _In_ const std::shared_ptr<basic_parser<T>>& space,
-
1735 _In_ const std::locale& locale = std::locale()) :
-
1736 basic_parser<T>(locale),
-
1737 home(_home),
-
1738 separator(_separator),
-
1739 guest(_guest),
-
1740 m_space(space)
-
1741 {}
-
1742
-
1743 virtual bool match(
-
1744 _In_reads_or_z_(end) const T* text,
-
1745 _In_ size_t start = 0,
-
1746 _In_ size_t end = (size_t)-1,
-
1747 _In_ int flags = match_default)
-
1748 {
-
1749 assert(text || start >= end);
-
1750 interval.end = start;
-
1751
-
1752 if (home->match(text, interval.end, end, flags))
-
1753 interval.end = home->interval.end;
-
1754 else
-
1755 goto end;
+
1714 virtual void invalidate()
+
1715 {
+
1716 numerator->invalidate();
+
1717 fraction_line->invalidate();
+
1718 denominator->invalidate();
+
1719 basic_parser<T>::invalidate();
+
1720 }
+
1721
+
1722 public:
+
1723 std::shared_ptr<basic_parser<T>> numerator;
+
1724 std::shared_ptr<basic_parser<T>> fraction_line;
+
1725 std::shared_ptr<basic_parser<T>> denominator;
+
1726 };
+
1727
+
1728 using fraction = basic_fraction<char>;
+
1729 using wfraction = basic_fraction<wchar_t>;
+
1730#ifdef _UNICODE
+
1731 using tfraction = wfraction;
+
1732#else
+
1733 using tfraction = fraction;
+
1734#endif
+
1735 using sgml_fraction = basic_fraction<char>;
+
1736
+
1740 template <class T>
+
1741 class basic_score : public basic_parser<T>
+
1742 {
+
1743 public:
+
1744 basic_score(
+
1745 _In_ const std::shared_ptr<basic_parser<T>>& _home,
+
1746 _In_ const std::shared_ptr<basic_parser<T>>& _separator,
+
1747 _In_ const std::shared_ptr<basic_parser<T>>& _guest,
+
1748 _In_ const std::shared_ptr<basic_parser<T>>& space,
+
1749 _In_ const std::locale& locale = std::locale()) :
+
1750 basic_parser<T>(locale),
+
1751 home(_home),
+
1752 separator(_separator),
+
1753 guest(_guest),
+
1754 m_space(space)
+
1755 {}
1756
-
1757 const int space_match_flags = flags & ~match_multiline; // Spaces in score must never be broken in new line.
-
1758 for (; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
1759
-
1760 if (separator->match(text, interval.end, end, flags))
-
1761 interval.end = separator->interval.end;
-
1762 else
-
1763 goto end;
-
1764
-
1765 for (; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
1766
-
1767 if (guest->match(text, interval.end, end, flags))
-
1768 interval.end = guest->interval.end;
-
1769 else
-
1770 goto end;
-
1771
-
1772 interval.start = start;
-
1773 return true;
-
1774
-
1775 end:
-
1776 home->invalidate();
-
1777 separator->invalidate();
-
1778 guest->invalidate();
-
1779 interval.start = (interval.end = start) + 1;
-
1780 return false;
-
1781 }
-
1782
-
1783 virtual void invalidate()
-
1784 {
-
1785 home->invalidate();
-
1786 separator->invalidate();
-
1787 guest->invalidate();
-
1788 basic_parser<T>::invalidate();
-
1789 }
-
1790
-
1791 public:
-
1792 std::shared_ptr<basic_parser<T>> home;
-
1793 std::shared_ptr<basic_parser<T>> separator;
-
1794 std::shared_ptr<basic_parser<T>> guest;
-
1795
-
1796 protected:
-
1797 std::shared_ptr<basic_parser<T>> m_space;
-
1798 };
-
1799
-
1800 using score = basic_score<char>;
-
1801 using wscore = basic_score<wchar_t>;
-
1802#ifdef _UNICODE
-
1803 using tscore = wscore;
-
1804#else
-
1805 using tscore = score;
-
1806#endif
-
1807 using sgml_score = basic_score<char>;
-
1808
-
1812 template <class T>
-
1813 class basic_signed_numeral : public basic_parser<T>
-
1814 {
-
1815 public:
-
1816 basic_signed_numeral(
-
1817 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
-
1818 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
-
1819 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
-
1820 _In_ const std::shared_ptr<basic_parser<T>>& _number,
-
1821 _In_ const std::locale& locale = std::locale()) :
-
1822 basic_parser<T>(locale),
-
1823 positive_sign(_positive_sign),
-
1824 negative_sign(_negative_sign),
-
1825 special_sign(_special_sign),
-
1826 number(_number)
-
1827 {}
-
1828
-
1829 virtual bool match(
-
1830 _In_reads_or_z_(end) const T* text,
-
1831 _In_ size_t start = 0,
-
1832 _In_ size_t end = (size_t)-1,
-
1833 _In_ int flags = match_default)
-
1834 {
-
1835 assert(text || start >= end);
-
1836 interval.end = start;
-
1837 if (positive_sign && positive_sign->match(text, interval.end, end, flags)) {
-
1838 interval.end = positive_sign->interval.end;
-
1839 if (negative_sign) negative_sign->invalidate();
-
1840 if (special_sign) special_sign->invalidate();
-
1841 }
-
1842 else if (negative_sign && negative_sign->match(text, interval.end, end, flags)) {
-
1843 interval.end = negative_sign->interval.end;
-
1844 if (positive_sign) positive_sign->invalidate();
-
1845 if (special_sign) special_sign->invalidate();
-
1846 }
-
1847 else if (special_sign && special_sign->match(text, interval.end, end, flags)) {
-
1848 interval.end = special_sign->interval.end;
-
1849 if (positive_sign) positive_sign->invalidate();
-
1850 if (negative_sign) negative_sign->invalidate();
-
1851 }
-
1852 else {
-
1853 if (positive_sign) positive_sign->invalidate();
-
1854 if (negative_sign) negative_sign->invalidate();
-
1855 if (special_sign) special_sign->invalidate();
-
1856 }
-
1857 if (number->match(text, interval.end, end, flags)) {
-
1858 interval.start = start;
-
1859 interval.end = number->interval.end;
-
1860 return true;
-
1861 }
-
1862 if (positive_sign) positive_sign->invalidate();
-
1863 if (negative_sign) negative_sign->invalidate();
-
1864 if (special_sign) special_sign->invalidate();
-
1865 number->invalidate();
-
1866 interval.start = (interval.end = start) + 1;
-
1867 return false;
-
1868 }
-
1869
-
1870 virtual void invalidate()
-
1871 {
-
1872 if (positive_sign) positive_sign->invalidate();
-
1873 if (negative_sign) negative_sign->invalidate();
-
1874 if (special_sign) special_sign->invalidate();
-
1875 number->invalidate();
-
1876 basic_parser<T>::invalidate();
-
1877 }
-
1878
-
1879 public:
-
1880 std::shared_ptr<basic_parser<T>> positive_sign;
-
1881 std::shared_ptr<basic_parser<T>> negative_sign;
-
1882 std::shared_ptr<basic_parser<T>> special_sign;
-
1883 std::shared_ptr<basic_parser<T>> number;
-
1884 };
-
1885
-
1886 using signed_numeral = basic_signed_numeral<char>;
-
1887 using wsigned_numeral = basic_signed_numeral<wchar_t>;
-
1888#ifdef _UNICODE
-
1889 using tsigned_numeral = wsigned_numeral;
-
1890#else
-
1891 using tsigned_numeral = signed_numeral;
-
1892#endif
-
1893 using sgml_signed_numeral = basic_signed_numeral<char>;
-
1894
-
1898 template <class T>
-
1899 class basic_mixed_numeral : public basic_parser<T>
-
1900 {
-
1901 public:
-
1902 basic_mixed_numeral(
-
1903 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
-
1904 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
-
1905 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
-
1906 _In_ const std::shared_ptr<basic_parser<T>>& _integer,
-
1907 _In_ const std::shared_ptr<basic_parser<T>>& space,
-
1908 _In_ const std::shared_ptr<basic_parser<T>>& _fraction,
-
1909 _In_ const std::locale& locale = std::locale()) :
-
1910 basic_parser<T>(locale),
-
1911 positive_sign(_positive_sign),
-
1912 negative_sign(_negative_sign),
-
1913 special_sign(_special_sign),
-
1914 integer(_integer),
-
1915 fraction(_fraction),
-
1916 m_space(space)
-
1917 {}
-
1918
-
1919 virtual bool match(
-
1920 _In_reads_or_z_(end) const T* text,
-
1921 _In_ size_t start = 0,
-
1922 _In_ size_t end = (size_t)-1,
-
1923 _In_ int flags = match_default)
-
1924 {
-
1925 assert(text || start >= end);
-
1926 interval.end = start;
-
1927
-
1928 if (positive_sign && positive_sign->match(text, interval.end, end, flags)) {
-
1929 interval.end = positive_sign->interval.end;
-
1930 if (negative_sign) negative_sign->invalidate();
-
1931 if (special_sign) special_sign->invalidate();
-
1932 }
-
1933 else if (negative_sign && negative_sign->match(text, interval.end, end, flags)) {
-
1934 interval.end = negative_sign->interval.end;
-
1935 if (positive_sign) positive_sign->invalidate();
-
1936 if (special_sign) special_sign->invalidate();
-
1937 }
-
1938 else if (special_sign && special_sign->match(text, interval.end, end, flags)) {
-
1939 interval.end = special_sign->interval.end;
-
1940 if (positive_sign) positive_sign->invalidate();
-
1941 if (negative_sign) negative_sign->invalidate();
-
1942 }
-
1943 else {
-
1944 if (positive_sign) positive_sign->invalidate();
-
1945 if (negative_sign) negative_sign->invalidate();
-
1946 if (special_sign) special_sign->invalidate();
-
1947 }
-
1948
-
1949 // Check for <integer> <fraction>
-
1950 const int space_match_flags = flags & ~match_multiline; // Spaces in fractions must never be broken in new line.
-
1951 if (integer->match(text, interval.end, end, flags) &&
-
1952 m_space->match(text, integer->interval.end, end, space_match_flags))
-
1953 {
-
1954 for (interval.end = m_space->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
1955 if (fraction->match(text, interval.end, end, flags)) {
-
1956 interval.start = start;
-
1957 interval.end = fraction->interval.end;
-
1958 return true;
-
1959 }
-
1960 fraction->invalidate();
-
1961 interval.start = start;
-
1962 interval.end = integer->interval.end;
-
1963 return true;
-
1964 }
-
1965
-
1966 // Check for <fraction>
-
1967 if (fraction->match(text, interval.end, end, flags)) {
-
1968 integer->invalidate();
-
1969 interval.start = start;
-
1970 interval.end = fraction->interval.end;
-
1971 return true;
-
1972 }
-
1973
-
1974 // Check for <integer>
-
1975 if (integer->match(text, interval.end, end, flags)) {
-
1976 fraction->invalidate();
-
1977 interval.start = start;
-
1978 interval.end = integer->interval.end;
-
1979 return true;
-
1980 }
-
1981
-
1982 if (positive_sign) positive_sign->invalidate();
-
1983 if (negative_sign) negative_sign->invalidate();
-
1984 if (special_sign) special_sign->invalidate();
-
1985 integer->invalidate();
-
1986 fraction->invalidate();
-
1987 interval.start = (interval.end = start) + 1;
-
1988 return false;
-
1989 }
-
1990
-
1991 virtual void invalidate()
-
1992 {
-
1993 if (positive_sign) positive_sign->invalidate();
-
1994 if (negative_sign) negative_sign->invalidate();
-
1995 if (special_sign) special_sign->invalidate();
-
1996 integer->invalidate();
-
1997 fraction->invalidate();
-
1998 basic_parser<T>::invalidate();
-
1999 }
-
2000
-
2001 public:
-
2002 std::shared_ptr<basic_parser<T>> positive_sign;
-
2003 std::shared_ptr<basic_parser<T>> negative_sign;
-
2004 std::shared_ptr<basic_parser<T>> special_sign;
-
2005 std::shared_ptr<basic_parser<T>> integer;
-
2006 std::shared_ptr<basic_parser<T>> fraction;
-
2007
-
2008 protected:
-
2009 std::shared_ptr<basic_parser<T>> m_space;
-
2010 };
-
2011
-
2012 using mixed_numeral = basic_mixed_numeral<char>;
-
2013 using wmixed_numeral = basic_mixed_numeral<wchar_t>;
-
2014#ifdef _UNICODE
-
2015 using tmixed_numeral = wmixed_numeral;
-
2016#else
-
2017 using tmixed_numeral = mixed_numeral;
-
2018#endif
-
2019 using sgml_mixed_numeral = basic_mixed_numeral<char>;
-
2020
-
2024 template <class T>
-
2025 class basic_scientific_numeral : public basic_parser<T>
-
2026 {
-
2027 public:
-
2028 basic_scientific_numeral(
-
2029 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
-
2030 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
-
2031 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
-
2032 _In_ const std::shared_ptr<basic_integer<T>>& _integer,
-
2033 _In_ const std::shared_ptr<basic_parser<T>>& _decimal_separator,
-
2034 _In_ const std::shared_ptr<basic_integer<T>>& _decimal,
-
2035 _In_ const std::shared_ptr<basic_parser<T>>& _exponent_symbol,
-
2036 _In_ const std::shared_ptr<basic_parser<T>>& _positive_exp_sign,
-
2037 _In_ const std::shared_ptr<basic_parser<T>>& _negative_exp_sign,
-
2038 _In_ const std::shared_ptr<basic_integer<T>>& _exponent,
-
2039 _In_ const std::locale& locale = std::locale()) :
-
2040 basic_parser<T>(locale),
-
2041 positive_sign(_positive_sign),
-
2042 negative_sign(_negative_sign),
-
2043 special_sign(_special_sign),
-
2044 integer(_integer),
-
2045 decimal_separator(_decimal_separator),
-
2046 decimal(_decimal),
-
2047 exponent_symbol(_exponent_symbol),
-
2048 positive_exp_sign(_positive_exp_sign),
-
2049 negative_exp_sign(_negative_exp_sign),
-
2050 exponent(_exponent),
-
2051 value(std::numeric_limits<double>::quiet_NaN())
-
2052 {}
-
2053
-
2054 virtual bool match(
-
2055 _In_reads_or_z_(end) const T* text,
-
2056 _In_ size_t start = 0,
-
2057 _In_ size_t end = (size_t)-1,
-
2058 _In_ int flags = match_default)
-
2059 {
-
2060 assert(text || start >= end);
-
2061 interval.end = start;
-
2062
-
2063 if (positive_sign && positive_sign->match(text, interval.end, end, flags)) {
-
2064 interval.end = positive_sign->interval.end;
-
2065 if (negative_sign) negative_sign->invalidate();
-
2066 if (special_sign) special_sign->invalidate();
-
2067 }
-
2068 else if (negative_sign && negative_sign->match(text, interval.end, end, flags)) {
-
2069 interval.end = negative_sign->interval.end;
-
2070 if (positive_sign) positive_sign->invalidate();
-
2071 if (special_sign) special_sign->invalidate();
-
2072 }
-
2073 else if (special_sign && special_sign->match(text, interval.end, end, flags)) {
-
2074 interval.end = special_sign->interval.end;
-
2075 if (positive_sign) positive_sign->invalidate();
-
2076 if (negative_sign) negative_sign->invalidate();
-
2077 }
-
2078 else {
-
2079 if (positive_sign) positive_sign->invalidate();
-
2080 if (negative_sign) negative_sign->invalidate();
-
2081 if (special_sign) special_sign->invalidate();
-
2082 }
-
2083
-
2084 if (integer->match(text, interval.end, end, flags))
-
2085 interval.end = integer->interval.end;
-
2086
-
2087 if (decimal_separator->match(text, interval.end, end, flags) &&
-
2088 decimal->match(text, decimal_separator->interval.end, end, flags))
-
2089 interval.end = decimal->interval.end;
-
2090 else {
-
2091 decimal_separator->invalidate();
-
2092 decimal->invalidate();
-
2093 }
-
2094
-
2095 if (!integer->interval.empty() &&
-
2096 decimal->interval.empty())
-
2097 {
-
2098 // No integer part, no decimal part.
-
2099 if (positive_sign) positive_sign->invalidate();
-
2100 if (negative_sign) negative_sign->invalidate();
-
2101 if (special_sign) special_sign->invalidate();
-
2102 integer->invalidate();
-
2103 decimal_separator->invalidate();
-
2104 decimal->invalidate();
-
2105 if (exponent_symbol) exponent_symbol->invalidate();
-
2106 if (positive_exp_sign) positive_exp_sign->invalidate();
-
2107 if (negative_exp_sign) negative_exp_sign->invalidate();
-
2108 if (exponent) exponent->invalidate();
-
2109 interval.start = (interval.end = start) + 1;
-
2110 return false;
-
2111 }
-
2112
-
2113 if (exponent_symbol && exponent_symbol->match(text, interval.end, end, flags) &&
-
2114 (positive_exp_sign && positive_exp_sign->match(text, exponent_symbol->interval.end, end, flags) &&
-
2115 exponent && exponent->match(text, positive_exp_sign->interval.end, end, flags) ||
-
2116 exponent && exponent->match(text, exponent_symbol->interval.end, end, flags)))
-
2117 {
-
2118 interval.end = exponent->interval.end;
-
2119 if (negative_exp_sign) negative_exp_sign->invalidate();
-
2120 }
-
2121 else if (exponent_symbol && exponent_symbol->match(text, interval.end, end, flags) &&
-
2122 negative_exp_sign && negative_exp_sign->match(text, exponent_symbol->interval.end, end, flags) &&
-
2123 exponent && exponent->match(text, negative_exp_sign->interval.end, end, flags))
-
2124 {
-
2125 interval.end = exponent->interval.end;
-
2126 if (positive_exp_sign) positive_exp_sign->invalidate();
-
2127 }
-
2128 else {
-
2129 if (exponent_symbol) exponent_symbol->invalidate();
-
2130 if (positive_exp_sign) positive_exp_sign->invalidate();
-
2131 if (negative_exp_sign) negative_exp_sign->invalidate();
-
2132 if (exponent) exponent->invalidate();
-
2133 }
-
2134
-
2135 value = (double)integer->value;
-
2136 if (decimal->interval)
-
2137 value += (double)decimal->value * pow(10.0, -(double)decimal->interval.size());
-
2138 if (negative_sign && negative_sign->interval)
-
2139 value = -value;
-
2140 if (exponent && exponent->interval) {
-
2141 double e = (double)exponent->value;
-
2142 if (negative_exp_sign && negative_exp_sign->interval)
-
2143 e = -e;
-
2144 value *= pow(10.0, e);
-
2145 }
-
2146
-
2147 interval.start = start;
-
2148 return true;
-
2149 }
-
2150
-
2151 virtual void invalidate()
-
2152 {
-
2153 if (positive_sign) positive_sign->invalidate();
-
2154 if (negative_sign) negative_sign->invalidate();
-
2155 if (special_sign) special_sign->invalidate();
-
2156 integer->invalidate();
-
2157 decimal_separator->invalidate();
-
2158 decimal->invalidate();
-
2159 if (exponent_symbol) exponent_symbol->invalidate();
-
2160 if (positive_exp_sign) positive_exp_sign->invalidate();
-
2161 if (negative_exp_sign) negative_exp_sign->invalidate();
-
2162 if (exponent) exponent->invalidate();
-
2163 value = std::numeric_limits<double>::quiet_NaN();
-
2164 basic_parser<T>::invalidate();
-
2165 }
-
2166
-
2167 public:
-
2168 std::shared_ptr<basic_parser<T>> positive_sign;
-
2169 std::shared_ptr<basic_parser<T>> negative_sign;
-
2170 std::shared_ptr<basic_parser<T>> special_sign;
-
2171 std::shared_ptr<basic_integer<T>> integer;
-
2172 std::shared_ptr<basic_parser<T>> decimal_separator;
-
2173 std::shared_ptr<basic_integer<T>> decimal;
-
2174 std::shared_ptr<basic_parser<T>> exponent_symbol;
-
2175 std::shared_ptr<basic_parser<T>> positive_exp_sign;
-
2176 std::shared_ptr<basic_parser<T>> negative_exp_sign;
-
2177 std::shared_ptr<basic_integer<T>> exponent;
-
2178 double value;
-
2179 };
+
1757 virtual bool match(
+
1758 _In_reads_or_z_(end) const T* text,
+
1759 _In_ size_t start = 0,
+
1760 _In_ size_t end = (size_t)-1,
+
1761 _In_ int flags = match_default)
+
1762 {
+
1763 assert(text || start >= end);
+
1764 interval.end = start;
+
1765
+
1766 if (home->match(text, interval.end, end, flags))
+
1767 interval.end = home->interval.end;
+
1768 else
+
1769 goto end;
+
1770
+
1771 const int space_match_flags = flags & ~match_multiline; // Spaces in score must never be broken in new line.
+
1772 for (; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
1773
+
1774 if (separator->match(text, interval.end, end, flags))
+
1775 interval.end = separator->interval.end;
+
1776 else
+
1777 goto end;
+
1778
+
1779 for (; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
1780
+
1781 if (guest->match(text, interval.end, end, flags))
+
1782 interval.end = guest->interval.end;
+
1783 else
+
1784 goto end;
+
1785
+
1786 interval.start = start;
+
1787 return true;
+
1788
+
1789 end:
+
1790 home->invalidate();
+
1791 separator->invalidate();
+
1792 guest->invalidate();
+
1793 interval.start = (interval.end = start) + 1;
+
1794 return false;
+
1795 }
+
1796
+
1797 virtual void invalidate()
+
1798 {
+
1799 home->invalidate();
+
1800 separator->invalidate();
+
1801 guest->invalidate();
+
1802 basic_parser<T>::invalidate();
+
1803 }
+
1804
+
1805 public:
+
1806 std::shared_ptr<basic_parser<T>> home;
+
1807 std::shared_ptr<basic_parser<T>> separator;
+
1808 std::shared_ptr<basic_parser<T>> guest;
+
1809
+
1810 protected:
+
1811 std::shared_ptr<basic_parser<T>> m_space;
+
1812 };
+
1813
+
1814 using score = basic_score<char>;
+
1815 using wscore = basic_score<wchar_t>;
+
1816#ifdef _UNICODE
+
1817 using tscore = wscore;
+
1818#else
+
1819 using tscore = score;
+
1820#endif
+
1821 using sgml_score = basic_score<char>;
+
1822
+
1826 template <class T>
+
1827 class basic_signed_numeral : public basic_parser<T>
+
1828 {
+
1829 public:
+
1830 basic_signed_numeral(
+
1831 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
+
1832 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
+
1833 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
+
1834 _In_ const std::shared_ptr<basic_parser<T>>& _number,
+
1835 _In_ const std::locale& locale = std::locale()) :
+
1836 basic_parser<T>(locale),
+
1837 positive_sign(_positive_sign),
+
1838 negative_sign(_negative_sign),
+
1839 special_sign(_special_sign),
+
1840 number(_number)
+
1841 {}
+
1842
+
1843 virtual bool match(
+
1844 _In_reads_or_z_(end) const T* text,
+
1845 _In_ size_t start = 0,
+
1846 _In_ size_t end = (size_t)-1,
+
1847 _In_ int flags = match_default)
+
1848 {
+
1849 assert(text || start >= end);
+
1850 interval.end = start;
+
1851 if (positive_sign && positive_sign->match(text, interval.end, end, flags)) {
+
1852 interval.end = positive_sign->interval.end;
+
1853 if (negative_sign) negative_sign->invalidate();
+
1854 if (special_sign) special_sign->invalidate();
+
1855 }
+
1856 else if (negative_sign && negative_sign->match(text, interval.end, end, flags)) {
+
1857 interval.end = negative_sign->interval.end;
+
1858 if (positive_sign) positive_sign->invalidate();
+
1859 if (special_sign) special_sign->invalidate();
+
1860 }
+
1861 else if (special_sign && special_sign->match(text, interval.end, end, flags)) {
+
1862 interval.end = special_sign->interval.end;
+
1863 if (positive_sign) positive_sign->invalidate();
+
1864 if (negative_sign) negative_sign->invalidate();
+
1865 }
+
1866 else {
+
1867 if (positive_sign) positive_sign->invalidate();
+
1868 if (negative_sign) negative_sign->invalidate();
+
1869 if (special_sign) special_sign->invalidate();
+
1870 }
+
1871 if (number->match(text, interval.end, end, flags)) {
+
1872 interval.start = start;
+
1873 interval.end = number->interval.end;
+
1874 return true;
+
1875 }
+
1876 if (positive_sign) positive_sign->invalidate();
+
1877 if (negative_sign) negative_sign->invalidate();
+
1878 if (special_sign) special_sign->invalidate();
+
1879 number->invalidate();
+
1880 interval.start = (interval.end = start) + 1;
+
1881 return false;
+
1882 }
+
1883
+
1884 virtual void invalidate()
+
1885 {
+
1886 if (positive_sign) positive_sign->invalidate();
+
1887 if (negative_sign) negative_sign->invalidate();
+
1888 if (special_sign) special_sign->invalidate();
+
1889 number->invalidate();
+
1890 basic_parser<T>::invalidate();
+
1891 }
+
1892
+
1893 public:
+
1894 std::shared_ptr<basic_parser<T>> positive_sign;
+
1895 std::shared_ptr<basic_parser<T>> negative_sign;
+
1896 std::shared_ptr<basic_parser<T>> special_sign;
+
1897 std::shared_ptr<basic_parser<T>> number;
+
1898 };
+
1899
+
1900 using signed_numeral = basic_signed_numeral<char>;
+
1901 using wsigned_numeral = basic_signed_numeral<wchar_t>;
+
1902#ifdef _UNICODE
+
1903 using tsigned_numeral = wsigned_numeral;
+
1904#else
+
1905 using tsigned_numeral = signed_numeral;
+
1906#endif
+
1907 using sgml_signed_numeral = basic_signed_numeral<char>;
+
1908
+
1912 template <class T>
+
1913 class basic_mixed_numeral : public basic_parser<T>
+
1914 {
+
1915 public:
+
1916 basic_mixed_numeral(
+
1917 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
+
1918 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
+
1919 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
+
1920 _In_ const std::shared_ptr<basic_parser<T>>& _integer,
+
1921 _In_ const std::shared_ptr<basic_parser<T>>& space,
+
1922 _In_ const std::shared_ptr<basic_parser<T>>& _fraction,
+
1923 _In_ const std::locale& locale = std::locale()) :
+
1924 basic_parser<T>(locale),
+
1925 positive_sign(_positive_sign),
+
1926 negative_sign(_negative_sign),
+
1927 special_sign(_special_sign),
+
1928 integer(_integer),
+
1929 fraction(_fraction),
+
1930 m_space(space)
+
1931 {}
+
1932
+
1933 virtual bool match(
+
1934 _In_reads_or_z_(end) const T* text,
+
1935 _In_ size_t start = 0,
+
1936 _In_ size_t end = (size_t)-1,
+
1937 _In_ int flags = match_default)
+
1938 {
+
1939 assert(text || start >= end);
+
1940 interval.end = start;
+
1941
+
1942 if (positive_sign && positive_sign->match(text, interval.end, end, flags)) {
+
1943 interval.end = positive_sign->interval.end;
+
1944 if (negative_sign) negative_sign->invalidate();
+
1945 if (special_sign) special_sign->invalidate();
+
1946 }
+
1947 else if (negative_sign && negative_sign->match(text, interval.end, end, flags)) {
+
1948 interval.end = negative_sign->interval.end;
+
1949 if (positive_sign) positive_sign->invalidate();
+
1950 if (special_sign) special_sign->invalidate();
+
1951 }
+
1952 else if (special_sign && special_sign->match(text, interval.end, end, flags)) {
+
1953 interval.end = special_sign->interval.end;
+
1954 if (positive_sign) positive_sign->invalidate();
+
1955 if (negative_sign) negative_sign->invalidate();
+
1956 }
+
1957 else {
+
1958 if (positive_sign) positive_sign->invalidate();
+
1959 if (negative_sign) negative_sign->invalidate();
+
1960 if (special_sign) special_sign->invalidate();
+
1961 }
+
1962
+
1963 // Check for <integer> <fraction>
+
1964 const int space_match_flags = flags & ~match_multiline; // Spaces in fractions must never be broken in new line.
+
1965 if (integer->match(text, interval.end, end, flags) &&
+
1966 m_space->match(text, integer->interval.end, end, space_match_flags))
+
1967 {
+
1968 for (interval.end = m_space->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
1969 if (fraction->match(text, interval.end, end, flags)) {
+
1970 interval.start = start;
+
1971 interval.end = fraction->interval.end;
+
1972 return true;
+
1973 }
+
1974 fraction->invalidate();
+
1975 interval.start = start;
+
1976 interval.end = integer->interval.end;
+
1977 return true;
+
1978 }
+
1979
+
1980 // Check for <fraction>
+
1981 if (fraction->match(text, interval.end, end, flags)) {
+
1982 integer->invalidate();
+
1983 interval.start = start;
+
1984 interval.end = fraction->interval.end;
+
1985 return true;
+
1986 }
+
1987
+
1988 // Check for <integer>
+
1989 if (integer->match(text, interval.end, end, flags)) {
+
1990 fraction->invalidate();
+
1991 interval.start = start;
+
1992 interval.end = integer->interval.end;
+
1993 return true;
+
1994 }
+
1995
+
1996 if (positive_sign) positive_sign->invalidate();
+
1997 if (negative_sign) negative_sign->invalidate();
+
1998 if (special_sign) special_sign->invalidate();
+
1999 integer->invalidate();
+
2000 fraction->invalidate();
+
2001 interval.start = (interval.end = start) + 1;
+
2002 return false;
+
2003 }
+
2004
+
2005 virtual void invalidate()
+
2006 {
+
2007 if (positive_sign) positive_sign->invalidate();
+
2008 if (negative_sign) negative_sign->invalidate();
+
2009 if (special_sign) special_sign->invalidate();
+
2010 integer->invalidate();
+
2011 fraction->invalidate();
+
2012 basic_parser<T>::invalidate();
+
2013 }
+
2014
+
2015 public:
+
2016 std::shared_ptr<basic_parser<T>> positive_sign;
+
2017 std::shared_ptr<basic_parser<T>> negative_sign;
+
2018 std::shared_ptr<basic_parser<T>> special_sign;
+
2019 std::shared_ptr<basic_parser<T>> integer;
+
2020 std::shared_ptr<basic_parser<T>> fraction;
+
2021
+
2022 protected:
+
2023 std::shared_ptr<basic_parser<T>> m_space;
+
2024 };
+
2025
+
2026 using mixed_numeral = basic_mixed_numeral<char>;
+
2027 using wmixed_numeral = basic_mixed_numeral<wchar_t>;
+
2028#ifdef _UNICODE
+
2029 using tmixed_numeral = wmixed_numeral;
+
2030#else
+
2031 using tmixed_numeral = mixed_numeral;
+
2032#endif
+
2033 using sgml_mixed_numeral = basic_mixed_numeral<char>;
+
2034
+
2038 template <class T>
+
2039 class basic_scientific_numeral : public basic_parser<T>
+
2040 {
+
2041 public:
+
2042 basic_scientific_numeral(
+
2043 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
+
2044 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
+
2045 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
+
2046 _In_ const std::shared_ptr<basic_integer<T>>& _integer,
+
2047 _In_ const std::shared_ptr<basic_parser<T>>& _decimal_separator,
+
2048 _In_ const std::shared_ptr<basic_integer<T>>& _decimal,
+
2049 _In_ const std::shared_ptr<basic_parser<T>>& _exponent_symbol,
+
2050 _In_ const std::shared_ptr<basic_parser<T>>& _positive_exp_sign,
+
2051 _In_ const std::shared_ptr<basic_parser<T>>& _negative_exp_sign,
+
2052 _In_ const std::shared_ptr<basic_integer<T>>& _exponent,
+
2053 _In_ const std::locale& locale = std::locale()) :
+
2054 basic_parser<T>(locale),
+
2055 positive_sign(_positive_sign),
+
2056 negative_sign(_negative_sign),
+
2057 special_sign(_special_sign),
+
2058 integer(_integer),
+
2059 decimal_separator(_decimal_separator),
+
2060 decimal(_decimal),
+
2061 exponent_symbol(_exponent_symbol),
+
2062 positive_exp_sign(_positive_exp_sign),
+
2063 negative_exp_sign(_negative_exp_sign),
+
2064 exponent(_exponent),
+
2065 value(std::numeric_limits<double>::quiet_NaN())
+
2066 {}
+
2067
+
2068 virtual bool match(
+
2069 _In_reads_or_z_(end) const T* text,
+
2070 _In_ size_t start = 0,
+
2071 _In_ size_t end = (size_t)-1,
+
2072 _In_ int flags = match_default)
+
2073 {
+
2074 assert(text || start >= end);
+
2075 interval.end = start;
+
2076
+
2077 if (positive_sign && positive_sign->match(text, interval.end, end, flags)) {
+
2078 interval.end = positive_sign->interval.end;
+
2079 if (negative_sign) negative_sign->invalidate();
+
2080 if (special_sign) special_sign->invalidate();
+
2081 }
+
2082 else if (negative_sign && negative_sign->match(text, interval.end, end, flags)) {
+
2083 interval.end = negative_sign->interval.end;
+
2084 if (positive_sign) positive_sign->invalidate();
+
2085 if (special_sign) special_sign->invalidate();
+
2086 }
+
2087 else if (special_sign && special_sign->match(text, interval.end, end, flags)) {
+
2088 interval.end = special_sign->interval.end;
+
2089 if (positive_sign) positive_sign->invalidate();
+
2090 if (negative_sign) negative_sign->invalidate();
+
2091 }
+
2092 else {
+
2093 if (positive_sign) positive_sign->invalidate();
+
2094 if (negative_sign) negative_sign->invalidate();
+
2095 if (special_sign) special_sign->invalidate();
+
2096 }
+
2097
+
2098 if (integer->match(text, interval.end, end, flags))
+
2099 interval.end = integer->interval.end;
+
2100
+
2101 if (decimal_separator->match(text, interval.end, end, flags) &&
+
2102 decimal->match(text, decimal_separator->interval.end, end, flags))
+
2103 interval.end = decimal->interval.end;
+
2104 else {
+
2105 decimal_separator->invalidate();
+
2106 decimal->invalidate();
+
2107 }
+
2108
+
2109 if (!integer->interval.empty() &&
+
2110 decimal->interval.empty())
+
2111 {
+
2112 // No integer part, no decimal part.
+
2113 if (positive_sign) positive_sign->invalidate();
+
2114 if (negative_sign) negative_sign->invalidate();
+
2115 if (special_sign) special_sign->invalidate();
+
2116 integer->invalidate();
+
2117 decimal_separator->invalidate();
+
2118 decimal->invalidate();
+
2119 if (exponent_symbol) exponent_symbol->invalidate();
+
2120 if (positive_exp_sign) positive_exp_sign->invalidate();
+
2121 if (negative_exp_sign) negative_exp_sign->invalidate();
+
2122 if (exponent) exponent->invalidate();
+
2123 interval.start = (interval.end = start) + 1;
+
2124 return false;
+
2125 }
+
2126
+
2127 if (exponent_symbol && exponent_symbol->match(text, interval.end, end, flags) &&
+
2128 (positive_exp_sign && positive_exp_sign->match(text, exponent_symbol->interval.end, end, flags) &&
+
2129 exponent && exponent->match(text, positive_exp_sign->interval.end, end, flags) ||
+
2130 exponent && exponent->match(text, exponent_symbol->interval.end, end, flags)))
+
2131 {
+
2132 interval.end = exponent->interval.end;
+
2133 if (negative_exp_sign) negative_exp_sign->invalidate();
+
2134 }
+
2135 else if (exponent_symbol && exponent_symbol->match(text, interval.end, end, flags) &&
+
2136 negative_exp_sign && negative_exp_sign->match(text, exponent_symbol->interval.end, end, flags) &&
+
2137 exponent && exponent->match(text, negative_exp_sign->interval.end, end, flags))
+
2138 {
+
2139 interval.end = exponent->interval.end;
+
2140 if (positive_exp_sign) positive_exp_sign->invalidate();
+
2141 }
+
2142 else {
+
2143 if (exponent_symbol) exponent_symbol->invalidate();
+
2144 if (positive_exp_sign) positive_exp_sign->invalidate();
+
2145 if (negative_exp_sign) negative_exp_sign->invalidate();
+
2146 if (exponent) exponent->invalidate();
+
2147 }
+
2148
+
2149 value = (double)integer->value;
+
2150 if (decimal->interval)
+
2151 value += (double)decimal->value * pow(10.0, -(double)decimal->interval.size());
+
2152 if (negative_sign && negative_sign->interval)
+
2153 value = -value;
+
2154 if (exponent && exponent->interval) {
+
2155 double e = (double)exponent->value;
+
2156 if (negative_exp_sign && negative_exp_sign->interval)
+
2157 e = -e;
+
2158 value *= pow(10.0, e);
+
2159 }
+
2160
+
2161 interval.start = start;
+
2162 return true;
+
2163 }
+
2164
+
2165 virtual void invalidate()
+
2166 {
+
2167 if (positive_sign) positive_sign->invalidate();
+
2168 if (negative_sign) negative_sign->invalidate();
+
2169 if (special_sign) special_sign->invalidate();
+
2170 integer->invalidate();
+
2171 decimal_separator->invalidate();
+
2172 decimal->invalidate();
+
2173 if (exponent_symbol) exponent_symbol->invalidate();
+
2174 if (positive_exp_sign) positive_exp_sign->invalidate();
+
2175 if (negative_exp_sign) negative_exp_sign->invalidate();
+
2176 if (exponent) exponent->invalidate();
+
2177 value = std::numeric_limits<double>::quiet_NaN();
+
2178 basic_parser<T>::invalidate();
+
2179 }
2180
-
2181 using scientific_numeral = basic_scientific_numeral<char>;
-
2182 using wscientific_numeral = basic_scientific_numeral<wchar_t>;
-
2183#ifdef _UNICODE
-
2184 using tscientific_numeral = wscientific_numeral;
-
2185#else
-
2186 using tscientific_numeral = scientific_numeral;
-
2187#endif
-
2188 using sgml_scientific_numeral = basic_scientific_numeral<char>;
-
2189
-
2193 template <class T>
-
2194 class basic_monetary_numeral : public basic_parser<T>
-
2195 {
-
2196 public:
-
2197 basic_monetary_numeral(
-
2198 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
-
2199 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
-
2200 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
-
2201 _In_ const std::shared_ptr<basic_parser<T>>& _currency,
-
2202 _In_ const std::shared_ptr<basic_parser<T>>& _integer,
-
2203 _In_ const std::shared_ptr<basic_parser<T>>& _decimal_separator,
-
2204 _In_ const std::shared_ptr<basic_parser<T>>& _decimal,
-
2205 _In_ const std::locale& locale = std::locale()) :
-
2206 basic_parser<T>(locale),
-
2207 positive_sign(_positive_sign),
-
2208 negative_sign(_negative_sign),
-
2209 special_sign(_special_sign),
-
2210 currency(_currency),
-
2211 integer(_integer),
-
2212 decimal_separator(_decimal_separator),
-
2213 decimal(_decimal)
-
2214 {}
-
2215
-
2216 virtual bool match(
-
2217 _In_reads_or_z_(end) const T* text,
-
2218 _In_ size_t start = 0,
-
2219 _In_ size_t end = (size_t)-1,
-
2220 _In_ int flags = match_default)
-
2221 {
-
2222 assert(text || start >= end);
-
2223 interval.end = start;
-
2224
-
2225 if (positive_sign->match(text, interval.end, end, flags)) {
-
2226 interval.end = positive_sign->interval.end;
-
2227 if (negative_sign) negative_sign->invalidate();
-
2228 if (special_sign) special_sign->invalidate();
-
2229 }
-
2230 else if (negative_sign->match(text, interval.end, end, flags)) {
-
2231 interval.end = negative_sign->interval.end;
-
2232 if (positive_sign) positive_sign->invalidate();
-
2233 if (special_sign) special_sign->invalidate();
-
2234 }
-
2235 else if (special_sign->match(text, interval.end, end, flags)) {
-
2236 interval.end = special_sign->interval.end;
-
2237 if (positive_sign) positive_sign->invalidate();
-
2238 if (negative_sign) negative_sign->invalidate();
-
2239 }
-
2240 else {
-
2241 if (positive_sign) positive_sign->invalidate();
-
2242 if (negative_sign) negative_sign->invalidate();
-
2243 if (special_sign) special_sign->invalidate();
-
2244 }
-
2245
-
2246 if (currency->match(text, interval.end, end, flags))
-
2247 interval.end = currency->interval.end;
-
2248 else {
-
2249 if (positive_sign) positive_sign->invalidate();
-
2250 if (negative_sign) negative_sign->invalidate();
-
2251 if (special_sign) special_sign->invalidate();
-
2252 integer->invalidate();
-
2253 decimal_separator->invalidate();
-
2254 decimal->invalidate();
-
2255 interval.start = (interval.end = start) + 1;
-
2256 return false;
-
2257 }
-
2258
-
2259 if (integer->match(text, interval.end, end, flags))
-
2260 interval.end = integer->interval.end;
-
2261 if (decimal_separator->match(text, interval.end, end, flags) &&
-
2262 decimal->match(text, decimal_separator->interval.end, end, flags))
-
2263 interval.end = decimal->interval.end;
-
2264 else {
-
2265 decimal_separator->invalidate();
-
2266 decimal->invalidate();
-
2267 }
-
2268
-
2269 if (integer->interval.empty() &&
-
2270 decimal->interval.empty())
-
2271 {
-
2272 // No integer part, no decimal part.
-
2273 if (positive_sign) positive_sign->invalidate();
-
2274 if (negative_sign) negative_sign->invalidate();
-
2275 if (special_sign) special_sign->invalidate();
-
2276 currency->invalidate();
-
2277 integer->invalidate();
-
2278 decimal_separator->invalidate();
-
2279 decimal->invalidate();
-
2280 interval.start = (interval.end = start) + 1;
-
2281 return false;
-
2282 }
-
2283
-
2284 interval.start = start;
-
2285 return true;
-
2286 }
-
2287
-
2288 virtual void invalidate()
-
2289 {
-
2290 if (positive_sign) positive_sign->invalidate();
-
2291 if (negative_sign) negative_sign->invalidate();
-
2292 if (special_sign) special_sign->invalidate();
-
2293 currency->invalidate();
-
2294 integer->invalidate();
-
2295 decimal_separator->invalidate();
-
2296 decimal->invalidate();
-
2297 basic_parser<T>::invalidate();
-
2298 }
-
2299
-
2300 public:
-
2301 std::shared_ptr<basic_parser<T>> positive_sign;
-
2302 std::shared_ptr<basic_parser<T>> negative_sign;
-
2303 std::shared_ptr<basic_parser<T>> special_sign;
-
2304 std::shared_ptr<basic_parser<T>> currency;
-
2305 std::shared_ptr<basic_parser<T>> integer;
-
2306 std::shared_ptr<basic_parser<T>> decimal_separator;
-
2307 std::shared_ptr<basic_parser<T>> decimal;
-
2308 };
-
2309
-
2310 using monetary_numeral = basic_monetary_numeral<char>;
-
2311 using wmonetary_numeral = basic_monetary_numeral<wchar_t>;
-
2312#ifdef _UNICODE
-
2313 using tmonetary_numeral = wmonetary_numeral;
-
2314#else
-
2315 using tmonetary_numeral = monetary_numeral;
-
2316#endif
-
2317 using sgml_monetary_numeral = basic_monetary_numeral<char>;
-
2318
-
2322 template <class T>
-
2323 class basic_ipv4_address : public basic_parser<T>
-
2324 {
-
2325 public:
-
2326 basic_ipv4_address(
-
2327 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
-
2328 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
-
2329 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
-
2330 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
-
2331 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
-
2332 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
-
2333 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
-
2334 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
-
2335 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
-
2336 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
-
2337 _In_ const std::shared_ptr<basic_parser<T>>& separator,
-
2338 _In_ const std::locale& locale = std::locale()) :
-
2339 basic_parser<T>(locale),
-
2340 m_digit_0(digit_0),
-
2341 m_digit_1(digit_1),
-
2342 m_digit_2(digit_2),
-
2343 m_digit_3(digit_3),
-
2344 m_digit_4(digit_4),
-
2345 m_digit_5(digit_5),
-
2346 m_digit_6(digit_6),
-
2347 m_digit_7(digit_7),
-
2348 m_digit_8(digit_8),
-
2349 m_digit_9(digit_9),
-
2350 m_separator(separator)
-
2351 {
-
2352 value.s_addr = 0;
-
2353 }
-
2354
-
2355 virtual bool match(
-
2356 _In_reads_or_z_(end) const T* text,
-
2357 _In_ size_t start = 0,
-
2358 _In_ size_t end = (size_t)-1,
-
2359 _In_ int flags = match_default)
-
2360 {
-
2361 assert(text || start >= end);
-
2362 interval.end = start;
-
2363 value.s_addr = 0;
-
2364
-
2365 size_t i;
-
2366 for (i = 0; i < 4; i++) {
-
2367 if (i) {
-
2368 if (m_separator->match(text, interval.end, end, flags))
-
2369 interval.end = m_separator->interval.end;
-
2370 else
-
2371 goto error;
-
2372 }
-
2373
-
2374 components[i].start = interval.end;
-
2375 bool is_empty = true;
-
2376 size_t x;
-
2377 for (x = 0; interval.end < end && text[interval.end];) {
-
2378 size_t dig, digit_end;
-
2379 if (m_digit_0->match(text, interval.end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
-
2380 else if (m_digit_1->match(text, interval.end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
-
2381 else if (m_digit_2->match(text, interval.end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
-
2382 else if (m_digit_3->match(text, interval.end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
-
2383 else if (m_digit_4->match(text, interval.end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
-
2384 else if (m_digit_5->match(text, interval.end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
-
2385 else if (m_digit_6->match(text, interval.end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
-
2386 else if (m_digit_7->match(text, interval.end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
-
2387 else if (m_digit_8->match(text, interval.end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
-
2388 else if (m_digit_9->match(text, interval.end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
-
2389 else break;
-
2390 size_t x_n = x * 10 + dig;
-
2391 if (x_n <= 255) {
-
2392 x = x_n;
-
2393 interval.end = digit_end;
-
2394 is_empty = false;
-
2395 }
-
2396 else
-
2397 break;
-
2398 }
-
2399 if (is_empty)
-
2400 goto error;
-
2401 components[i].end = interval.end;
-
2402 value.s_addr = (value.s_addr << 8) | (uint8_t)x;
-
2403 }
-
2404 if (i < 4)
-
2405 goto error;
-
2406
-
2407 interval.start = start;
-
2408 return true;
-
2409
-
2410 error:
-
2411 components[0].start = 1;
-
2412 components[0].end = 0;
-
2413 components[1].start = 1;
-
2414 components[1].end = 0;
-
2415 components[2].start = 1;
-
2416 components[2].end = 0;
-
2417 components[3].start = 1;
-
2418 components[3].end = 0;
-
2419 value = 0;
-
2420 interval.start = (interval.end = start) + 1;
-
2421 return false;
-
2422 }
+
2181 public:
+
2182 std::shared_ptr<basic_parser<T>> positive_sign;
+
2183 std::shared_ptr<basic_parser<T>> negative_sign;
+
2184 std::shared_ptr<basic_parser<T>> special_sign;
+
2185 std::shared_ptr<basic_integer<T>> integer;
+
2186 std::shared_ptr<basic_parser<T>> decimal_separator;
+
2187 std::shared_ptr<basic_integer<T>> decimal;
+
2188 std::shared_ptr<basic_parser<T>> exponent_symbol;
+
2189 std::shared_ptr<basic_parser<T>> positive_exp_sign;
+
2190 std::shared_ptr<basic_parser<T>> negative_exp_sign;
+
2191 std::shared_ptr<basic_integer<T>> exponent;
+
2192 double value;
+
2193 };
+
2194
+
2195 using scientific_numeral = basic_scientific_numeral<char>;
+
2196 using wscientific_numeral = basic_scientific_numeral<wchar_t>;
+
2197#ifdef _UNICODE
+
2198 using tscientific_numeral = wscientific_numeral;
+
2199#else
+
2200 using tscientific_numeral = scientific_numeral;
+
2201#endif
+
2202 using sgml_scientific_numeral = basic_scientific_numeral<char>;
+
2203
+
2207 template <class T>
+
2208 class basic_monetary_numeral : public basic_parser<T>
+
2209 {
+
2210 public:
+
2211 basic_monetary_numeral(
+
2212 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
+
2213 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
+
2214 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
+
2215 _In_ const std::shared_ptr<basic_parser<T>>& _currency,
+
2216 _In_ const std::shared_ptr<basic_parser<T>>& _integer,
+
2217 _In_ const std::shared_ptr<basic_parser<T>>& _decimal_separator,
+
2218 _In_ const std::shared_ptr<basic_parser<T>>& _decimal,
+
2219 _In_ const std::locale& locale = std::locale()) :
+
2220 basic_parser<T>(locale),
+
2221 positive_sign(_positive_sign),
+
2222 negative_sign(_negative_sign),
+
2223 special_sign(_special_sign),
+
2224 currency(_currency),
+
2225 integer(_integer),
+
2226 decimal_separator(_decimal_separator),
+
2227 decimal(_decimal)
+
2228 {}
+
2229
+
2230 virtual bool match(
+
2231 _In_reads_or_z_(end) const T* text,
+
2232 _In_ size_t start = 0,
+
2233 _In_ size_t end = (size_t)-1,
+
2234 _In_ int flags = match_default)
+
2235 {
+
2236 assert(text || start >= end);
+
2237 interval.end = start;
+
2238
+
2239 if (positive_sign->match(text, interval.end, end, flags)) {
+
2240 interval.end = positive_sign->interval.end;
+
2241 if (negative_sign) negative_sign->invalidate();
+
2242 if (special_sign) special_sign->invalidate();
+
2243 }
+
2244 else if (negative_sign->match(text, interval.end, end, flags)) {
+
2245 interval.end = negative_sign->interval.end;
+
2246 if (positive_sign) positive_sign->invalidate();
+
2247 if (special_sign) special_sign->invalidate();
+
2248 }
+
2249 else if (special_sign->match(text, interval.end, end, flags)) {
+
2250 interval.end = special_sign->interval.end;
+
2251 if (positive_sign) positive_sign->invalidate();
+
2252 if (negative_sign) negative_sign->invalidate();
+
2253 }
+
2254 else {
+
2255 if (positive_sign) positive_sign->invalidate();
+
2256 if (negative_sign) negative_sign->invalidate();
+
2257 if (special_sign) special_sign->invalidate();
+
2258 }
+
2259
+
2260 if (currency->match(text, interval.end, end, flags))
+
2261 interval.end = currency->interval.end;
+
2262 else {
+
2263 if (positive_sign) positive_sign->invalidate();
+
2264 if (negative_sign) negative_sign->invalidate();
+
2265 if (special_sign) special_sign->invalidate();
+
2266 integer->invalidate();
+
2267 decimal_separator->invalidate();
+
2268 decimal->invalidate();
+
2269 interval.start = (interval.end = start) + 1;
+
2270 return false;
+
2271 }
+
2272
+
2273 if (integer->match(text, interval.end, end, flags))
+
2274 interval.end = integer->interval.end;
+
2275 if (decimal_separator->match(text, interval.end, end, flags) &&
+
2276 decimal->match(text, decimal_separator->interval.end, end, flags))
+
2277 interval.end = decimal->interval.end;
+
2278 else {
+
2279 decimal_separator->invalidate();
+
2280 decimal->invalidate();
+
2281 }
+
2282
+
2283 if (integer->interval.empty() &&
+
2284 decimal->interval.empty())
+
2285 {
+
2286 // No integer part, no decimal part.
+
2287 if (positive_sign) positive_sign->invalidate();
+
2288 if (negative_sign) negative_sign->invalidate();
+
2289 if (special_sign) special_sign->invalidate();
+
2290 currency->invalidate();
+
2291 integer->invalidate();
+
2292 decimal_separator->invalidate();
+
2293 decimal->invalidate();
+
2294 interval.start = (interval.end = start) + 1;
+
2295 return false;
+
2296 }
+
2297
+
2298 interval.start = start;
+
2299 return true;
+
2300 }
+
2301
+
2302 virtual void invalidate()
+
2303 {
+
2304 if (positive_sign) positive_sign->invalidate();
+
2305 if (negative_sign) negative_sign->invalidate();
+
2306 if (special_sign) special_sign->invalidate();
+
2307 currency->invalidate();
+
2308 integer->invalidate();
+
2309 decimal_separator->invalidate();
+
2310 decimal->invalidate();
+
2311 basic_parser<T>::invalidate();
+
2312 }
+
2313
+
2314 public:
+
2315 std::shared_ptr<basic_parser<T>> positive_sign;
+
2316 std::shared_ptr<basic_parser<T>> negative_sign;
+
2317 std::shared_ptr<basic_parser<T>> special_sign;
+
2318 std::shared_ptr<basic_parser<T>> currency;
+
2319 std::shared_ptr<basic_parser<T>> integer;
+
2320 std::shared_ptr<basic_parser<T>> decimal_separator;
+
2321 std::shared_ptr<basic_parser<T>> decimal;
+
2322 };
+
2323
+
2324 using monetary_numeral = basic_monetary_numeral<char>;
+
2325 using wmonetary_numeral = basic_monetary_numeral<wchar_t>;
+
2326#ifdef _UNICODE
+
2327 using tmonetary_numeral = wmonetary_numeral;
+
2328#else
+
2329 using tmonetary_numeral = monetary_numeral;
+
2330#endif
+
2331 using sgml_monetary_numeral = basic_monetary_numeral<char>;
+
2332
+
2336 template <class T>
+
2337 class basic_ipv4_address : public basic_parser<T>
+
2338 {
+
2339 public:
+
2340 basic_ipv4_address(
+
2341 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
+
2342 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
+
2343 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
+
2344 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
+
2345 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
+
2346 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
+
2347 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
+
2348 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
+
2349 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
+
2350 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
+
2351 _In_ const std::shared_ptr<basic_parser<T>>& separator,
+
2352 _In_ const std::locale& locale = std::locale()) :
+
2353 basic_parser<T>(locale),
+
2354 m_digit_0(digit_0),
+
2355 m_digit_1(digit_1),
+
2356 m_digit_2(digit_2),
+
2357 m_digit_3(digit_3),
+
2358 m_digit_4(digit_4),
+
2359 m_digit_5(digit_5),
+
2360 m_digit_6(digit_6),
+
2361 m_digit_7(digit_7),
+
2362 m_digit_8(digit_8),
+
2363 m_digit_9(digit_9),
+
2364 m_separator(separator)
+
2365 {
+
2366 value.s_addr = 0;
+
2367 }
+
2368
+
2369 virtual bool match(
+
2370 _In_reads_or_z_(end) const T* text,
+
2371 _In_ size_t start = 0,
+
2372 _In_ size_t end = (size_t)-1,
+
2373 _In_ int flags = match_default)
+
2374 {
+
2375 assert(text || start >= end);
+
2376 interval.end = start;
+
2377 value.s_addr = 0;
+
2378
+
2379 size_t i;
+
2380 for (i = 0; i < 4; i++) {
+
2381 if (i) {
+
2382 if (m_separator->match(text, interval.end, end, flags))
+
2383 interval.end = m_separator->interval.end;
+
2384 else
+
2385 goto error;
+
2386 }
+
2387
+
2388 components[i].start = interval.end;
+
2389 bool is_empty = true;
+
2390 size_t x;
+
2391 for (x = 0; interval.end < end && text[interval.end];) {
+
2392 size_t dig, digit_end;
+
2393 if (m_digit_0->match(text, interval.end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
+
2394 else if (m_digit_1->match(text, interval.end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
+
2395 else if (m_digit_2->match(text, interval.end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
+
2396 else if (m_digit_3->match(text, interval.end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
+
2397 else if (m_digit_4->match(text, interval.end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
+
2398 else if (m_digit_5->match(text, interval.end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
+
2399 else if (m_digit_6->match(text, interval.end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
+
2400 else if (m_digit_7->match(text, interval.end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
+
2401 else if (m_digit_8->match(text, interval.end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
+
2402 else if (m_digit_9->match(text, interval.end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
+
2403 else break;
+
2404 size_t x_n = x * 10 + dig;
+
2405 if (x_n <= 255) {
+
2406 x = x_n;
+
2407 interval.end = digit_end;
+
2408 is_empty = false;
+
2409 }
+
2410 else
+
2411 break;
+
2412 }
+
2413 if (is_empty)
+
2414 goto error;
+
2415 components[i].end = interval.end;
+
2416 value.s_addr = (value.s_addr << 8) | (uint8_t)x;
+
2417 }
+
2418 if (i < 4)
+
2419 goto error;
+
2420
+
2421 interval.start = start;
+
2422 return true;
2423
-
2424 virtual void invalidate()
-
2425 {
-
2426 components[0].start = 1;
-
2427 components[0].end = 0;
-
2428 components[1].start = 1;
-
2429 components[1].end = 0;
-
2430 components[2].start = 1;
-
2431 components[2].end = 0;
-
2432 components[3].start = 1;
-
2433 components[3].end = 0;
-
2434 value = 0;
-
2435 basic_parser<T>::invalidate();
+
2424 error:
+
2425 components[0].start = 1;
+
2426 components[0].end = 0;
+
2427 components[1].start = 1;
+
2428 components[1].end = 0;
+
2429 components[2].start = 1;
+
2430 components[2].end = 0;
+
2431 components[3].start = 1;
+
2432 components[3].end = 0;
+
2433 value.s_addr = 0;
+
2434 interval.start = (interval.end = start) + 1;
+
2435 return false;
2436 }
2437
-
2438 public:
-
2439 stdex::interval<size_t> components[4];
-
2440 struct in_addr value;
-
2441
-
2442 protected:
-
2443 std::shared_ptr<basic_parser<T>>
-
2444 m_digit_0,
-
2445 m_digit_1,
-
2446 m_digit_2,
-
2447 m_digit_3,
-
2448 m_digit_4,
-
2449 m_digit_5,
-
2450 m_digit_6,
-
2451 m_digit_7,
-
2452 m_digit_8,
-
2453 m_digit_9;
-
2454 std::shared_ptr<basic_parser<T>> m_separator;
-
2455 };
-
2456
-
2457 using ipv4_address = basic_ipv4_address<char>;
-
2458 using wipv4_address = basic_ipv4_address<wchar_t>;
-
2459#ifdef _UNICODE
-
2460 using tipv4_address = wipv4_address;
-
2461#else
-
2462 using tipv4_address = ipv4_address;
-
2463#endif
-
2464 using sgml_ipv4_address = basic_ipv4_address<char>;
-
2465
-
2469 template <class T>
-
2470 class basic_ipv6_scope_id_char : public basic_parser<T>
-
2471 {
-
2472 public:
-
2473 basic_ipv6_scope_id_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
-
2474
-
2475 virtual bool match(
-
2476 _In_reads_or_z_(end) const T* text,
-
2477 _In_ size_t start = 0,
-
2478 _In_ size_t end = (size_t)-1,
-
2479 _In_ int flags = match_default)
-
2480 {
-
2481 assert(text || start >= end);
-
2482 if (start < end && text[start]) {
-
2483 if (text[start] == '-' ||
-
2484 text[start] == '_' ||
-
2485 text[start] == ':' ||
-
2486 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
-
2487 {
-
2488 interval.end = (interval.start = start) + 1;
-
2489 return true;
-
2490 }
-
2491 }
-
2492 interval.start = (interval.end = start) + 1;
-
2493 return false;
-
2494 }
-
2495 };
-
2496
-
2497 using ipv6_scope_id_char = basic_ipv6_scope_id_char<char>;
-
2498 using wipv6_scope_id_char = basic_ipv6_scope_id_char<wchar_t>;
-
2499#ifdef _UNICODE
-
2500 using tipv6_scope_id_char = wipv6_scope_id_char;
-
2501#else
-
2502 using tipv6_scope_id_char = ipv6_scope_id_char;
-
2503#endif
-
2504
-
2508 class sgml_ipv6_scope_id_char : public sgml_parser
-
2509 {
-
2510 public:
-
2511 sgml_ipv6_scope_id_char(_In_ const std::locale& locale = std::locale()) : sgml_parser(locale) {}
-
2512
-
2513 virtual bool match(
-
2514 _In_reads_or_z_(end) const char* text,
-
2515 _In_ size_t start = 0,
-
2516 _In_ size_t end = (size_t)-1,
-
2517 _In_ int flags = match_default)
-
2518 {
-
2519 assert(text || start >= end);
-
2520 if (start < end && text[start]) {
-
2521 wchar_t buf[3];
-
2522 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
-
2523 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
2524 if ((chr[0] == L'-' ||
-
2525 chr[0] == L'_' ||
-
2526 chr[0] == L':') && chr[1] == 0 ||
-
2527 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
-
2528 {
-
2529 interval.start = start;
-
2530 return true;
-
2531 }
-
2532 }
-
2533 interval.start = (interval.end = start) + 1;
-
2534 return false;
-
2535 }
-
2536 };
-
2537
-
2541 template <class T>
-
2542 class basic_ipv6_address : public basic_parser<T>
-
2543 {
-
2544 public:
-
2545 basic_ipv6_address(
-
2546 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
-
2547 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
-
2548 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
-
2549 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
-
2550 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
-
2551 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
-
2552 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
-
2553 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
-
2554 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
-
2555 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
-
2556 _In_ const std::shared_ptr<basic_parser<T>>& digit_10,
-
2557 _In_ const std::shared_ptr<basic_parser<T>>& digit_11,
-
2558 _In_ const std::shared_ptr<basic_parser<T>>& digit_12,
-
2559 _In_ const std::shared_ptr<basic_parser<T>>& digit_13,
-
2560 _In_ const std::shared_ptr<basic_parser<T>>& digit_14,
-
2561 _In_ const std::shared_ptr<basic_parser<T>>& digit_15,
-
2562 _In_ const std::shared_ptr<basic_parser<T>>& separator,
-
2563 _In_ const std::shared_ptr<basic_parser<T>>& scope_id_separator = nullptr,
-
2564 _In_ const std::shared_ptr<basic_parser<T>>& _scope_id = nullptr,
-
2565 _In_ const std::locale& locale = std::locale()) :
-
2566 basic_parser<T>(locale),
-
2567 m_digit_0(digit_0),
-
2568 m_digit_1(digit_1),
-
2569 m_digit_2(digit_2),
-
2570 m_digit_3(digit_3),
-
2571 m_digit_4(digit_4),
-
2572 m_digit_5(digit_5),
-
2573 m_digit_6(digit_6),
-
2574 m_digit_7(digit_7),
-
2575 m_digit_8(digit_8),
-
2576 m_digit_9(digit_9),
-
2577 m_digit_10(digit_10),
-
2578 m_digit_11(digit_11),
-
2579 m_digit_12(digit_12),
-
2580 m_digit_13(digit_13),
-
2581 m_digit_14(digit_14),
-
2582 m_digit_15(digit_15),
-
2583 m_separator(separator),
-
2584 m_scope_id_separator(scope_id_separator),
-
2585 scope_id(_scope_id)
-
2586 {
-
2587 memset(value, 0, sizeof(value));
-
2588 }
-
2589
-
2590 virtual bool match(
-
2591 _In_reads_or_z_(end) const T* text,
-
2592 _In_ size_t start = 0,
-
2593 _In_ size_t end = (size_t)-1,
-
2594 _In_ int flags = match_default)
-
2595 {
-
2596 assert(text || start >= end);
-
2597 interval.end = start;
-
2598 memset(value, 0, sizeof(value));
-
2599
-
2600 size_t i, compaction_i = (size_t)-1, compaction_start = start;
-
2601 for (i = 0; i < 8; i++) {
-
2602 bool is_empty = true;
+
2438 virtual void invalidate()
+
2439 {
+
2440 components[0].start = 1;
+
2441 components[0].end = 0;
+
2442 components[1].start = 1;
+
2443 components[1].end = 0;
+
2444 components[2].start = 1;
+
2445 components[2].end = 0;
+
2446 components[3].start = 1;
+
2447 components[3].end = 0;
+
2448 value.s_addr = 0;
+
2449 basic_parser<T>::invalidate();
+
2450 }
+
2451
+
2452 public:
+
2453 stdex::interval<size_t> components[4];
+
2454 struct in_addr value;
+
2455
+
2456 protected:
+
2457 std::shared_ptr<basic_parser<T>>
+
2458 m_digit_0,
+
2459 m_digit_1,
+
2460 m_digit_2,
+
2461 m_digit_3,
+
2462 m_digit_4,
+
2463 m_digit_5,
+
2464 m_digit_6,
+
2465 m_digit_7,
+
2466 m_digit_8,
+
2467 m_digit_9;
+
2468 std::shared_ptr<basic_parser<T>> m_separator;
+
2469 };
+
2470
+
2471 using ipv4_address = basic_ipv4_address<char>;
+
2472 using wipv4_address = basic_ipv4_address<wchar_t>;
+
2473#ifdef _UNICODE
+
2474 using tipv4_address = wipv4_address;
+
2475#else
+
2476 using tipv4_address = ipv4_address;
+
2477#endif
+
2478 using sgml_ipv4_address = basic_ipv4_address<char>;
+
2479
+
2483 template <class T>
+
2484 class basic_ipv6_scope_id_char : public basic_parser<T>
+
2485 {
+
2486 public:
+
2487 basic_ipv6_scope_id_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
+
2488
+
2489 virtual bool match(
+
2490 _In_reads_or_z_(end) const T* text,
+
2491 _In_ size_t start = 0,
+
2492 _In_ size_t end = (size_t)-1,
+
2493 _In_ int flags = match_default)
+
2494 {
+
2495 assert(text || start >= end);
+
2496 if (start < end && text[start]) {
+
2497 if (text[start] == '-' ||
+
2498 text[start] == '_' ||
+
2499 text[start] == ':' ||
+
2500 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
+
2501 {
+
2502 interval.end = (interval.start = start) + 1;
+
2503 return true;
+
2504 }
+
2505 }
+
2506 interval.start = (interval.end = start) + 1;
+
2507 return false;
+
2508 }
+
2509 };
+
2510
+
2511 using ipv6_scope_id_char = basic_ipv6_scope_id_char<char>;
+
2512 using wipv6_scope_id_char = basic_ipv6_scope_id_char<wchar_t>;
+
2513#ifdef _UNICODE
+
2514 using tipv6_scope_id_char = wipv6_scope_id_char;
+
2515#else
+
2516 using tipv6_scope_id_char = ipv6_scope_id_char;
+
2517#endif
+
2518
+
2522 class sgml_ipv6_scope_id_char : public sgml_parser
+
2523 {
+
2524 public:
+
2525 sgml_ipv6_scope_id_char(_In_ const std::locale& locale = std::locale()) : sgml_parser(locale) {}
+
2526
+
2527 virtual bool match(
+
2528 _In_reads_or_z_(end) const char* text,
+
2529 _In_ size_t start = 0,
+
2530 _In_ size_t end = (size_t)-1,
+
2531 _In_ int flags = match_default)
+
2532 {
+
2533 assert(text || start >= end);
+
2534 if (start < end && text[start]) {
+
2535 wchar_t buf[3];
+
2536 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
+
2537 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
2538 if ((chr[0] == L'-' ||
+
2539 chr[0] == L'_' ||
+
2540 chr[0] == L':') && chr[1] == 0 ||
+
2541 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
+
2542 {
+
2543 interval.start = start;
+
2544 return true;
+
2545 }
+
2546 }
+
2547 interval.start = (interval.end = start) + 1;
+
2548 return false;
+
2549 }
+
2550 };
+
2551
+
2555 template <class T>
+
2556 class basic_ipv6_address : public basic_parser<T>
+
2557 {
+
2558 public:
+
2559 basic_ipv6_address(
+
2560 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
+
2561 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
+
2562 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
+
2563 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
+
2564 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
+
2565 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
+
2566 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
+
2567 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
+
2568 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
+
2569 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
+
2570 _In_ const std::shared_ptr<basic_parser<T>>& digit_10,
+
2571 _In_ const std::shared_ptr<basic_parser<T>>& digit_11,
+
2572 _In_ const std::shared_ptr<basic_parser<T>>& digit_12,
+
2573 _In_ const std::shared_ptr<basic_parser<T>>& digit_13,
+
2574 _In_ const std::shared_ptr<basic_parser<T>>& digit_14,
+
2575 _In_ const std::shared_ptr<basic_parser<T>>& digit_15,
+
2576 _In_ const std::shared_ptr<basic_parser<T>>& separator,
+
2577 _In_ const std::shared_ptr<basic_parser<T>>& scope_id_separator = nullptr,
+
2578 _In_ const std::shared_ptr<basic_parser<T>>& _scope_id = nullptr,
+
2579 _In_ const std::locale& locale = std::locale()) :
+
2580 basic_parser<T>(locale),
+
2581 m_digit_0(digit_0),
+
2582 m_digit_1(digit_1),
+
2583 m_digit_2(digit_2),
+
2584 m_digit_3(digit_3),
+
2585 m_digit_4(digit_4),
+
2586 m_digit_5(digit_5),
+
2587 m_digit_6(digit_6),
+
2588 m_digit_7(digit_7),
+
2589 m_digit_8(digit_8),
+
2590 m_digit_9(digit_9),
+
2591 m_digit_10(digit_10),
+
2592 m_digit_11(digit_11),
+
2593 m_digit_12(digit_12),
+
2594 m_digit_13(digit_13),
+
2595 m_digit_14(digit_14),
+
2596 m_digit_15(digit_15),
+
2597 m_separator(separator),
+
2598 m_scope_id_separator(scope_id_separator),
+
2599 scope_id(_scope_id)
+
2600 {
+
2601 memset(&value, 0, sizeof(value));
+
2602 }
2603
-
2604 if (m_separator->match(text, interval.end, end, flags)) {
-
2605 if (m_separator->match(text, m_separator->interval.end, end, flags)) {
-
2606 // :: found
-
2607 if (compaction_i == (size_t)-1) {
-
2608 // Zero compaction start
-
2609 compaction_i = i;
-
2610 compaction_start = m_separator->interval.start;
-
2611 interval.end = m_separator->interval.end;
-
2612 }
-
2613 else {
-
2614 // More than one zero compaction
-
2615 break;
-
2616 }
-
2617 }
-
2618 else if (i) {
-
2619 // Inner : found
-
2620 interval.end = m_separator->interval.end;
-
2621 }
-
2622 else {
-
2623 // Leading : found
-
2624 goto error;
-
2625 }
-
2626 }
-
2627 else if (i) {
-
2628 // : missing
-
2629 break;
-
2630 }
-
2631
-
2632 components[i].start = interval.end;
-
2633 size_t x;
-
2634 for (x = 0; interval.end < end && text[interval.end];) {
-
2635 size_t dig, digit_end;
-
2636 if (m_digit_0->match(text, interval.end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
-
2637 else if (m_digit_1->match(text, interval.end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
-
2638 else if (m_digit_2->match(text, interval.end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
-
2639 else if (m_digit_3->match(text, interval.end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
-
2640 else if (m_digit_4->match(text, interval.end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
-
2641 else if (m_digit_5->match(text, interval.end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
-
2642 else if (m_digit_6->match(text, interval.end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
-
2643 else if (m_digit_7->match(text, interval.end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
-
2644 else if (m_digit_8->match(text, interval.end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
-
2645 else if (m_digit_9->match(text, interval.end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
-
2646 else if (m_digit_10->match(text, interval.end, end, flags)) { dig = 10; digit_end = m_digit_10->interval.end; }
-
2647 else if (m_digit_11->match(text, interval.end, end, flags)) { dig = 11; digit_end = m_digit_11->interval.end; }
-
2648 else if (m_digit_12->match(text, interval.end, end, flags)) { dig = 12; digit_end = m_digit_12->interval.end; }
-
2649 else if (m_digit_13->match(text, interval.end, end, flags)) { dig = 13; digit_end = m_digit_13->interval.end; }
-
2650 else if (m_digit_14->match(text, interval.end, end, flags)) { dig = 14; digit_end = m_digit_14->interval.end; }
-
2651 else if (m_digit_15->match(text, interval.end, end, flags)) { dig = 15; digit_end = m_digit_15->interval.end; }
-
2652 else break;
-
2653 size_t x_n = x * 16 + dig;
-
2654 if (x_n <= 0xffff) {
-
2655 x = x_n;
-
2656 interval.end = digit_end;
-
2657 is_empty = false;
-
2658 }
-
2659 else
-
2660 break;
-
2661 }
-
2662 if (is_empty) {
-
2663 if (compaction_i != (size_t)-1) {
-
2664 // Zero compaction active: no sweat.
-
2665 break;
-
2666 }
-
2667 goto error;
-
2668 }
-
2669 components[i].end = interval.end;
-
2670 value.s6_words[i] = (uint16_t)x;
-
2671 }
-
2672
-
2673 if (compaction_i != (size_t)-1) {
-
2674 // Align components right due to zero compaction.
-
2675 size_t j, k;
-
2676 for (j = 8, k = i; k > compaction_i;) {
-
2677 value.s6_words[--j] = value.s6_words[--k];
-
2678 components[j] = components[k];
-
2679 }
-
2680 for (; j > compaction_i;) {
-
2681 value.s6_words[--j] = 0;
-
2682 components[j].start =
-
2683 components[j].end = compaction_start;
-
2684 }
+
2604 virtual bool match(
+
2605 _In_reads_or_z_(end) const T* text,
+
2606 _In_ size_t start = 0,
+
2607 _In_ size_t end = (size_t)-1,
+
2608 _In_ int flags = match_default)
+
2609 {
+
2610 assert(text || start >= end);
+
2611 interval.end = start;
+
2612 memset(&value, 0, sizeof(value));
+
2613
+
2614 size_t i, compaction_i = (size_t)-1, compaction_start = start;
+
2615 for (i = 0; i < 8; i++) {
+
2616 bool is_empty = true;
+
2617
+
2618 if (m_separator->match(text, interval.end, end, flags)) {
+
2619 if (m_separator->match(text, m_separator->interval.end, end, flags)) {
+
2620 // :: found
+
2621 if (compaction_i == (size_t)-1) {
+
2622 // Zero compaction start
+
2623 compaction_i = i;
+
2624 compaction_start = m_separator->interval.start;
+
2625 interval.end = m_separator->interval.end;
+
2626 }
+
2627 else {
+
2628 // More than one zero compaction
+
2629 break;
+
2630 }
+
2631 }
+
2632 else if (i) {
+
2633 // Inner : found
+
2634 interval.end = m_separator->interval.end;
+
2635 }
+
2636 else {
+
2637 // Leading : found
+
2638 goto error;
+
2639 }
+
2640 }
+
2641 else if (i) {
+
2642 // : missing
+
2643 break;
+
2644 }
+
2645
+
2646 components[i].start = interval.end;
+
2647 size_t x;
+
2648 for (x = 0; interval.end < end && text[interval.end];) {
+
2649 size_t dig, digit_end;
+
2650 if (m_digit_0->match(text, interval.end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
+
2651 else if (m_digit_1->match(text, interval.end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
+
2652 else if (m_digit_2->match(text, interval.end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
+
2653 else if (m_digit_3->match(text, interval.end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
+
2654 else if (m_digit_4->match(text, interval.end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
+
2655 else if (m_digit_5->match(text, interval.end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
+
2656 else if (m_digit_6->match(text, interval.end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
+
2657 else if (m_digit_7->match(text, interval.end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
+
2658 else if (m_digit_8->match(text, interval.end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
+
2659 else if (m_digit_9->match(text, interval.end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
+
2660 else if (m_digit_10->match(text, interval.end, end, flags)) { dig = 10; digit_end = m_digit_10->interval.end; }
+
2661 else if (m_digit_11->match(text, interval.end, end, flags)) { dig = 11; digit_end = m_digit_11->interval.end; }
+
2662 else if (m_digit_12->match(text, interval.end, end, flags)) { dig = 12; digit_end = m_digit_12->interval.end; }
+
2663 else if (m_digit_13->match(text, interval.end, end, flags)) { dig = 13; digit_end = m_digit_13->interval.end; }
+
2664 else if (m_digit_14->match(text, interval.end, end, flags)) { dig = 14; digit_end = m_digit_14->interval.end; }
+
2665 else if (m_digit_15->match(text, interval.end, end, flags)) { dig = 15; digit_end = m_digit_15->interval.end; }
+
2666 else break;
+
2667 size_t x_n = x * 16 + dig;
+
2668 if (x_n <= 0xffff) {
+
2669 x = x_n;
+
2670 interval.end = digit_end;
+
2671 is_empty = false;
+
2672 }
+
2673 else
+
2674 break;
+
2675 }
+
2676 if (is_empty) {
+
2677 if (compaction_i != (size_t)-1) {
+
2678 // Zero compaction active: no sweat.
+
2679 break;
+
2680 }
+
2681 goto error;
+
2682 }
+
2683 components[i].end = interval.end;
+
2684 value.s6_words[i] = (uint16_t)x;
2685 }
-
2686 else if (i < 8)
-
2687 goto error;
-
2688
-
2689 if (m_scope_id_separator && m_scope_id_separator->match(text, interval.end, end, flags) &&
-
2690 scope_id && scope_id->match(text, m_scope_id_separator->interval.end, end, flags))
-
2691 interval.end = scope_id->interval.end;
-
2692 else if (scope_id)
-
2693 scope_id->invalidate();
-
2694
-
2695 interval.start = start;
-
2696 return true;
-
2697
-
2698 error:
-
2699 components[0].start = 1;
-
2700 components[0].end = 0;
-
2701 components[1].start = 1;
-
2702 components[1].end = 0;
-
2703 components[2].start = 1;
-
2704 components[2].end = 0;
-
2705 components[3].start = 1;
-
2706 components[3].end = 0;
-
2707 components[4].start = 1;
-
2708 components[4].end = 0;
-
2709 components[5].start = 1;
-
2710 components[5].end = 0;
-
2711 components[6].start = 1;
-
2712 components[6].end = 0;
-
2713 components[7].start = 1;
-
2714 components[7].end = 0;
-
2715 memset(value, 0, sizeof(value));
-
2716 if (scope_id) scope_id->invalidate();
-
2717 interval.start = (interval.end = start) + 1;
-
2718 return false;
-
2719 }
-
2720
-
2721 virtual void invalidate()
-
2722 {
-
2723 components[0].start = 1;
-
2724 components[0].end = 0;
-
2725 components[1].start = 1;
-
2726 components[1].end = 0;
-
2727 components[2].start = 1;
-
2728 components[2].end = 0;
-
2729 components[3].start = 1;
-
2730 components[3].end = 0;
-
2731 components[4].start = 1;
-
2732 components[4].end = 0;
-
2733 components[5].start = 1;
-
2734 components[5].end = 0;
-
2735 components[6].start = 1;
-
2736 components[6].end = 0;
-
2737 components[7].start = 1;
-
2738 components[7].end = 0;
-
2739 memset(value, 0, sizeof(value));
-
2740 if (scope_id) scope_id->invalidate();
-
2741 basic_parser<T>::invalidate();
-
2742 }
-
2743
-
2744 public:
-
2745 stdex::interval<size_t> components[8];
-
2746 struct in6_addr value;
-
2747 std::shared_ptr<basic_parser<T>> scope_id;
-
2748
-
2749 protected:
-
2750 std::shared_ptr<basic_parser<T>>
-
2751 m_digit_0,
-
2752 m_digit_1,
-
2753 m_digit_2,
-
2754 m_digit_3,
-
2755 m_digit_4,
-
2756 m_digit_5,
-
2757 m_digit_6,
-
2758 m_digit_7,
-
2759 m_digit_8,
-
2760 m_digit_9,
-
2761 m_digit_10,
-
2762 m_digit_11,
-
2763 m_digit_12,
-
2764 m_digit_13,
-
2765 m_digit_14,
-
2766 m_digit_15;
-
2767 std::shared_ptr<basic_parser<T>> m_separator, m_scope_id_separator;
-
2768 };
-
2769
-
2770 using ipv6_address = basic_ipv6_address<char>;
-
2771 using wipv6_address = basic_ipv6_address<wchar_t>;
-
2772#ifdef _UNICODE
-
2773 using tipv6_address = wipv6_address;
-
2774#else
-
2775 using tipv6_address = ipv6_address;
-
2776#endif
-
2777 using sgml_ipv6_address = basic_ipv6_address<char>;
-
2778
-
2782 template <class T>
-
2783 class basic_dns_domain_char : public basic_parser<T>
-
2784 {
-
2785 public:
-
2786 basic_dns_domain_char(
-
2787 _In_ bool allow_idn,
-
2788 _In_ const std::locale& locale = std::locale()) :
-
2789 basic_parser<T>(locale),
-
2790 m_allow_idn(allow_idn),
-
2791 allow_on_edge(true)
-
2792 {}
-
2793
-
2794 virtual bool match(
-
2795 _In_reads_or_z_(end) const T* text,
-
2796 _In_ size_t start = 0,
-
2797 _In_ size_t end = (size_t)-1,
-
2798 _In_ int flags = match_default)
-
2799 {
-
2800 assert(text || start >= end);
-
2801 if (start < end && text[start]) {
-
2802 if (('A' <= text[start] && text[start] <= 'Z') ||
-
2803 ('a' <= text[start] && text[start] <= 'z') ||
-
2804 ('0' <= text[start] && text[start] <= '9'))
-
2805 allow_on_edge = true;
-
2806 else if (text[start] == '-')
-
2807 allow_on_edge = false;
-
2808 else if (m_allow_idn && std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
-
2809 allow_on_edge = true;
-
2810 else {
-
2811 interval.start = (interval.end = start) + 1;
-
2812 return false;
-
2813 }
-
2814 interval.end = (interval.start = start) + 1;
-
2815 return true;
-
2816 }
-
2817 interval.start = (interval.end = start) + 1;
-
2818 return false;
-
2819 }
-
2820
-
2821 public:
-
2822 bool allow_on_edge;
-
2823
-
2824 protected:
-
2825 bool m_allow_idn;
-
2826 };
-
2827
-
2828 using dns_domain_char = basic_dns_domain_char<char>;
-
2829 using wdns_domain_char = basic_dns_domain_char<wchar_t>;
-
2830#ifdef _UNICODE
-
2831 using tdns_domain_char = wdns_domain_char;
-
2832#else
-
2833 using tdns_domain_char = dns_domain_char;
-
2834#endif
-
2835
-
2839 class sgml_dns_domain_char : public basic_dns_domain_char<char>
-
2840 {
-
2841 public:
-
2842 sgml_dns_domain_char(
-
2843 _In_ bool allow_idn,
-
2844 _In_ const std::locale& locale = std::locale()) :
-
2845 basic_dns_domain_char<char>(allow_idn, locale)
-
2846 {}
-
2847
-
2848 virtual bool match(
-
2849 _In_reads_or_z_(end) const char* text,
-
2850 _In_ size_t start = 0,
-
2851 _In_ size_t end = (size_t)-1,
-
2852 _In_ int flags = match_default)
-
2853 {
-
2854 assert(text || start >= end);
-
2855 if (start < end && text[start]) {
-
2856 wchar_t buf[3];
-
2857 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
-
2858 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
2859 if ((('A' <= chr[0] && chr[0] <= 'Z') ||
-
2860 ('a' <= chr[0] && chr[0] <= 'z') ||
-
2861 ('0' <= chr[0] && chr[0] <= '9')) && chr[1] == 0)
-
2862 allow_on_edge = true;
-
2863 else if (chr[0] == '-' && chr[1] == 0)
-
2864 allow_on_edge = false;
-
2865 else if (m_allow_idn && std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
-
2866 allow_on_edge = true;
-
2867 else {
-
2868 interval.start = (interval.end = start) + 1;
-
2869 return false;
-
2870 }
-
2871 interval.start = start;
-
2872 return true;
-
2873 }
-
2874 interval.start = (interval.end = start) + 1;
-
2875 return false;
-
2876 }
-
2877 };
-
2878
-
2882 template <class T>
-
2883 class basic_dns_name : public basic_parser<T>
-
2884 {
-
2885 public:
-
2886 basic_dns_name(
-
2887 _In_ bool allow_absolute,
-
2888 _In_ const std::shared_ptr<basic_dns_domain_char<T>>& domain_char,
-
2889 _In_ const std::shared_ptr<basic_parser<T>>& separator,
-
2890 _In_ const std::locale& locale = std::locale()) :
-
2891 basic_parser<T>(locale),
-
2892 m_allow_absolute(allow_absolute),
-
2893 m_domain_char(domain_char),
-
2894 m_separator(separator)
-
2895 {}
-
2896
-
2897 virtual bool match(
-
2898 _In_reads_or_z_(end) const T* text,
-
2899 _In_ size_t start = 0,
-
2900 _In_ size_t end = (size_t)-1,
-
2901 _In_ int flags = match_default)
-
2902 {
-
2903 assert(text || start >= end);
-
2904 size_t i = start, count;
-
2905 for (count = 0; i < end && text[i] && count < 127; count++) {
-
2906 if (m_domain_char->match(text, i, end, flags) &&
-
2907 m_domain_char->allow_on_edge)
-
2908 {
-
2909 // Domain start
-
2910 interval.end = i = m_domain_char->interval.end;
-
2911 while (i < end && text[i]) {
-
2912 if (m_domain_char->allow_on_edge &&
-
2913 m_separator->match(text, i, end, flags))
-
2914 {
-
2915 // Domain end
-
2916 if (m_allow_absolute)
-
2917 interval.end = i = m_separator->interval.end;
-
2918 else {
-
2919 interval.end = i;
-
2920 i = m_separator->interval.end;
-
2921 }
-
2922 break;
-
2923 }
-
2924 if (m_domain_char->match(text, i, end, flags)) {
-
2925 if (m_domain_char->allow_on_edge)
-
2926 interval.end = i = m_domain_char->interval.end;
-
2927 else
-
2928 i = m_domain_char->interval.end;
-
2929 }
-
2930 else {
-
2931 interval.start = start;
-
2932 return true;
-
2933 }
-
2934 }
-
2935 }
-
2936 else
-
2937 break;
-
2938 }
-
2939 if (count) {
-
2940 interval.start = start;
-
2941 return true;
-
2942 }
-
2943 interval.start = (interval.end = start) + 1;
-
2944 return false;
-
2945 }
-
2946
-
2947 protected:
-
2948 bool m_allow_absolute;
-
2949 std::shared_ptr<basic_dns_domain_char<T>> m_domain_char;
-
2950 std::shared_ptr<basic_parser<T>> m_separator;
-
2951 };
-
2952
-
2953 using dns_name = basic_dns_name<char>;
-
2954 using wdns_name = basic_dns_name<wchar_t>;
-
2955#ifdef _UNICODE
-
2956 using tdns_name = wdns_name;
-
2957#else
-
2958 using tdns_name = dns_name;
-
2959#endif
-
2960 using sgml_dns_name = basic_dns_name<char>;
-
2961
-
2965 template <class T>
-
2966 class basic_url_username_char : public basic_parser<T>
-
2967 {
-
2968 public:
-
2969 basic_url_username_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
-
2970
-
2971 virtual bool match(
-
2972 _In_reads_or_z_(end) const T* text,
-
2973 _In_ size_t start = 0,
-
2974 _In_ size_t end = (size_t)-1,
-
2975 _In_ int flags = match_default)
-
2976 {
-
2977 assert(text || start >= end);
-
2978 if (start < end && text[start]) {
-
2979 if (text[start] == '-' ||
-
2980 text[start] == '.' ||
-
2981 text[start] == '_' ||
-
2982 text[start] == '~' ||
-
2983 text[start] == '%' ||
-
2984 text[start] == '!' ||
-
2985 text[start] == '$' ||
-
2986 text[start] == '&' ||
-
2987 text[start] == '\'' ||
-
2988 //text[start] == '(' ||
-
2989 //text[start] == ')' ||
-
2990 text[start] == '*' ||
-
2991 text[start] == '+' ||
-
2992 text[start] == ',' ||
-
2993 text[start] == ';' ||
-
2994 text[start] == '=' ||
-
2995 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
-
2996 {
-
2997 interval.end = (interval.start = start) + 1;
-
2998 return true;
-
2999 }
-
3000 }
-
3001 interval.start = (interval.end = start) + 1;
-
3002 return false;
-
3003 }
-
3004 };
-
3005
-
3006 using url_username_char = basic_url_username_char<char>;
-
3007 using wurl_username_char = basic_url_username_char<wchar_t>;
-
3008#ifdef _UNICODE
-
3009 using turl_username_char = wurl_username_char;
-
3010#else
-
3011 using turl_username_char = url_username_char;
-
3012#endif
-
3013
-
3017 class sgml_url_username_char : public basic_url_username_char<char>
-
3018 {
-
3019 public:
-
3020 sgml_url_username_char(_In_ const std::locale& locale = std::locale()) : basic_url_username_char<char>(locale) {}
-
3021
-
3022 virtual bool match(
-
3023 _In_reads_or_z_(end) const char* text,
-
3024 _In_ size_t start = 0,
-
3025 _In_ size_t end = (size_t)-1,
-
3026 _In_ int flags = match_default)
-
3027 {
-
3028 assert(text || start >= end);
-
3029 if (start < end && text[start]) {
-
3030 wchar_t buf[3];
-
3031 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
-
3032 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
3033 if ((chr[0] == L'-' ||
-
3034 chr[0] == L'.' ||
-
3035 chr[0] == L'_' ||
-
3036 chr[0] == L'~' ||
-
3037 chr[0] == L'%' ||
-
3038 chr[0] == L'!' ||
-
3039 chr[0] == L'$' ||
-
3040 chr[0] == L'&' ||
-
3041 chr[0] == L'\'' ||
-
3042 //chr[0] == L'(' ||
-
3043 //chr[0] == L')' ||
-
3044 chr[0] == L'*' ||
-
3045 chr[0] == L'+' ||
-
3046 chr[0] == L',' ||
-
3047 chr[0] == L';' ||
-
3048 chr[0] == L'=') && chr[1] == 0 ||
-
3049 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
-
3050 {
-
3051 interval.start = start;
-
3052 return true;
-
3053 }
-
3054 }
-
3055
-
3056 interval.start = (interval.end = start) + 1;
-
3057 return false;
-
3058 }
-
3059 };
-
3060
-
3064 template <class T>
-
3065 class basic_url_password_char : public basic_parser<T>
-
3066 {
-
3067 public:
-
3068 basic_url_password_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
+
2686
+
2687 if (compaction_i != (size_t)-1) {
+
2688 // Align components right due to zero compaction.
+
2689 size_t j, k;
+
2690 for (j = 8, k = i; k > compaction_i;) {
+
2691 value.s6_words[--j] = value.s6_words[--k];
+
2692 components[j] = components[k];
+
2693 }
+
2694 for (; j > compaction_i;) {
+
2695 value.s6_words[--j] = 0;
+
2696 components[j].start =
+
2697 components[j].end = compaction_start;
+
2698 }
+
2699 }
+
2700 else if (i < 8)
+
2701 goto error;
+
2702
+
2703 if (m_scope_id_separator && m_scope_id_separator->match(text, interval.end, end, flags) &&
+
2704 scope_id && scope_id->match(text, m_scope_id_separator->interval.end, end, flags))
+
2705 interval.end = scope_id->interval.end;
+
2706 else if (scope_id)
+
2707 scope_id->invalidate();
+
2708
+
2709 interval.start = start;
+
2710 return true;
+
2711
+
2712 error:
+
2713 components[0].start = 1;
+
2714 components[0].end = 0;
+
2715 components[1].start = 1;
+
2716 components[1].end = 0;
+
2717 components[2].start = 1;
+
2718 components[2].end = 0;
+
2719 components[3].start = 1;
+
2720 components[3].end = 0;
+
2721 components[4].start = 1;
+
2722 components[4].end = 0;
+
2723 components[5].start = 1;
+
2724 components[5].end = 0;
+
2725 components[6].start = 1;
+
2726 components[6].end = 0;
+
2727 components[7].start = 1;
+
2728 components[7].end = 0;
+
2729 memset(&value, 0, sizeof(value));
+
2730 if (scope_id) scope_id->invalidate();
+
2731 interval.start = (interval.end = start) + 1;
+
2732 return false;
+
2733 }
+
2734
+
2735 virtual void invalidate()
+
2736 {
+
2737 components[0].start = 1;
+
2738 components[0].end = 0;
+
2739 components[1].start = 1;
+
2740 components[1].end = 0;
+
2741 components[2].start = 1;
+
2742 components[2].end = 0;
+
2743 components[3].start = 1;
+
2744 components[3].end = 0;
+
2745 components[4].start = 1;
+
2746 components[4].end = 0;
+
2747 components[5].start = 1;
+
2748 components[5].end = 0;
+
2749 components[6].start = 1;
+
2750 components[6].end = 0;
+
2751 components[7].start = 1;
+
2752 components[7].end = 0;
+
2753 memset(&value, 0, sizeof(value));
+
2754 if (scope_id) scope_id->invalidate();
+
2755 basic_parser<T>::invalidate();
+
2756 }
+
2757
+
2758 public:
+
2759 stdex::interval<size_t> components[8];
+
2760 struct in6_addr value;
+
2761 std::shared_ptr<basic_parser<T>> scope_id;
+
2762
+
2763 protected:
+
2764 std::shared_ptr<basic_parser<T>>
+
2765 m_digit_0,
+
2766 m_digit_1,
+
2767 m_digit_2,
+
2768 m_digit_3,
+
2769 m_digit_4,
+
2770 m_digit_5,
+
2771 m_digit_6,
+
2772 m_digit_7,
+
2773 m_digit_8,
+
2774 m_digit_9,
+
2775 m_digit_10,
+
2776 m_digit_11,
+
2777 m_digit_12,
+
2778 m_digit_13,
+
2779 m_digit_14,
+
2780 m_digit_15;
+
2781 std::shared_ptr<basic_parser<T>> m_separator, m_scope_id_separator;
+
2782 };
+
2783
+
2784 using ipv6_address = basic_ipv6_address<char>;
+
2785 using wipv6_address = basic_ipv6_address<wchar_t>;
+
2786#ifdef _UNICODE
+
2787 using tipv6_address = wipv6_address;
+
2788#else
+
2789 using tipv6_address = ipv6_address;
+
2790#endif
+
2791 using sgml_ipv6_address = basic_ipv6_address<char>;
+
2792
+
2796 template <class T>
+
2797 class basic_dns_domain_char : public basic_parser<T>
+
2798 {
+
2799 public:
+
2800 basic_dns_domain_char(
+
2801 _In_ bool allow_idn,
+
2802 _In_ const std::locale& locale = std::locale()) :
+
2803 basic_parser<T>(locale),
+
2804 m_allow_idn(allow_idn),
+
2805 allow_on_edge(true)
+
2806 {}
+
2807
+
2808 virtual bool match(
+
2809 _In_reads_or_z_(end) const T* text,
+
2810 _In_ size_t start = 0,
+
2811 _In_ size_t end = (size_t)-1,
+
2812 _In_ int flags = match_default)
+
2813 {
+
2814 assert(text || start >= end);
+
2815 if (start < end && text[start]) {
+
2816 if (('A' <= text[start] && text[start] <= 'Z') ||
+
2817 ('a' <= text[start] && text[start] <= 'z') ||
+
2818 ('0' <= text[start] && text[start] <= '9'))
+
2819 allow_on_edge = true;
+
2820 else if (text[start] == '-')
+
2821 allow_on_edge = false;
+
2822 else if (m_allow_idn && std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
+
2823 allow_on_edge = true;
+
2824 else {
+
2825 interval.start = (interval.end = start) + 1;
+
2826 return false;
+
2827 }
+
2828 interval.end = (interval.start = start) + 1;
+
2829 return true;
+
2830 }
+
2831 interval.start = (interval.end = start) + 1;
+
2832 return false;
+
2833 }
+
2834
+
2835 public:
+
2836 bool allow_on_edge;
+
2837
+
2838 protected:
+
2839 bool m_allow_idn;
+
2840 };
+
2841
+
2842 using dns_domain_char = basic_dns_domain_char<char>;
+
2843 using wdns_domain_char = basic_dns_domain_char<wchar_t>;
+
2844#ifdef _UNICODE
+
2845 using tdns_domain_char = wdns_domain_char;
+
2846#else
+
2847 using tdns_domain_char = dns_domain_char;
+
2848#endif
+
2849
+
2853 class sgml_dns_domain_char : public basic_dns_domain_char<char>
+
2854 {
+
2855 public:
+
2856 sgml_dns_domain_char(
+
2857 _In_ bool allow_idn,
+
2858 _In_ const std::locale& locale = std::locale()) :
+
2859 basic_dns_domain_char<char>(allow_idn, locale)
+
2860 {}
+
2861
+
2862 virtual bool match(
+
2863 _In_reads_or_z_(end) const char* text,
+
2864 _In_ size_t start = 0,
+
2865 _In_ size_t end = (size_t)-1,
+
2866 _In_ int flags = match_default)
+
2867 {
+
2868 assert(text || start >= end);
+
2869 if (start < end && text[start]) {
+
2870 wchar_t buf[3];
+
2871 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
+
2872 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
2873 if ((('A' <= chr[0] && chr[0] <= 'Z') ||
+
2874 ('a' <= chr[0] && chr[0] <= 'z') ||
+
2875 ('0' <= chr[0] && chr[0] <= '9')) && chr[1] == 0)
+
2876 allow_on_edge = true;
+
2877 else if (chr[0] == '-' && chr[1] == 0)
+
2878 allow_on_edge = false;
+
2879 else if (m_allow_idn && std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
+
2880 allow_on_edge = true;
+
2881 else {
+
2882 interval.start = (interval.end = start) + 1;
+
2883 return false;
+
2884 }
+
2885 interval.start = start;
+
2886 return true;
+
2887 }
+
2888 interval.start = (interval.end = start) + 1;
+
2889 return false;
+
2890 }
+
2891 };
+
2892
+
2896 template <class T>
+
2897 class basic_dns_name : public basic_parser<T>
+
2898 {
+
2899 public:
+
2900 basic_dns_name(
+
2901 _In_ bool allow_absolute,
+
2902 _In_ const std::shared_ptr<basic_dns_domain_char<T>>& domain_char,
+
2903 _In_ const std::shared_ptr<basic_parser<T>>& separator,
+
2904 _In_ const std::locale& locale = std::locale()) :
+
2905 basic_parser<T>(locale),
+
2906 m_allow_absolute(allow_absolute),
+
2907 m_domain_char(domain_char),
+
2908 m_separator(separator)
+
2909 {}
+
2910
+
2911 virtual bool match(
+
2912 _In_reads_or_z_(end) const T* text,
+
2913 _In_ size_t start = 0,
+
2914 _In_ size_t end = (size_t)-1,
+
2915 _In_ int flags = match_default)
+
2916 {
+
2917 assert(text || start >= end);
+
2918 size_t i = start, count;
+
2919 for (count = 0; i < end && text[i] && count < 127; count++) {
+
2920 if (m_domain_char->match(text, i, end, flags) &&
+
2921 m_domain_char->allow_on_edge)
+
2922 {
+
2923 // Domain start
+
2924 interval.end = i = m_domain_char->interval.end;
+
2925 while (i < end && text[i]) {
+
2926 if (m_domain_char->allow_on_edge &&
+
2927 m_separator->match(text, i, end, flags))
+
2928 {
+
2929 // Domain end
+
2930 if (m_allow_absolute)
+
2931 interval.end = i = m_separator->interval.end;
+
2932 else {
+
2933 interval.end = i;
+
2934 i = m_separator->interval.end;
+
2935 }
+
2936 break;
+
2937 }
+
2938 if (m_domain_char->match(text, i, end, flags)) {
+
2939 if (m_domain_char->allow_on_edge)
+
2940 interval.end = i = m_domain_char->interval.end;
+
2941 else
+
2942 i = m_domain_char->interval.end;
+
2943 }
+
2944 else {
+
2945 interval.start = start;
+
2946 return true;
+
2947 }
+
2948 }
+
2949 }
+
2950 else
+
2951 break;
+
2952 }
+
2953 if (count) {
+
2954 interval.start = start;
+
2955 return true;
+
2956 }
+
2957 interval.start = (interval.end = start) + 1;
+
2958 return false;
+
2959 }
+
2960
+
2961 protected:
+
2962 bool m_allow_absolute;
+
2963 std::shared_ptr<basic_dns_domain_char<T>> m_domain_char;
+
2964 std::shared_ptr<basic_parser<T>> m_separator;
+
2965 };
+
2966
+
2967 using dns_name = basic_dns_name<char>;
+
2968 using wdns_name = basic_dns_name<wchar_t>;
+
2969#ifdef _UNICODE
+
2970 using tdns_name = wdns_name;
+
2971#else
+
2972 using tdns_name = dns_name;
+
2973#endif
+
2974 using sgml_dns_name = basic_dns_name<char>;
+
2975
+
2979 template <class T>
+
2980 class basic_url_username_char : public basic_parser<T>
+
2981 {
+
2982 public:
+
2983 basic_url_username_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
+
2984
+
2985 virtual bool match(
+
2986 _In_reads_or_z_(end) const T* text,
+
2987 _In_ size_t start = 0,
+
2988 _In_ size_t end = (size_t)-1,
+
2989 _In_ int flags = match_default)
+
2990 {
+
2991 assert(text || start >= end);
+
2992 if (start < end && text[start]) {
+
2993 if (text[start] == '-' ||
+
2994 text[start] == '.' ||
+
2995 text[start] == '_' ||
+
2996 text[start] == '~' ||
+
2997 text[start] == '%' ||
+
2998 text[start] == '!' ||
+
2999 text[start] == '$' ||
+
3000 text[start] == '&' ||
+
3001 text[start] == '\'' ||
+
3002 //text[start] == '(' ||
+
3003 //text[start] == ')' ||
+
3004 text[start] == '*' ||
+
3005 text[start] == '+' ||
+
3006 text[start] == ',' ||
+
3007 text[start] == ';' ||
+
3008 text[start] == '=' ||
+
3009 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
+
3010 {
+
3011 interval.end = (interval.start = start) + 1;
+
3012 return true;
+
3013 }
+
3014 }
+
3015 interval.start = (interval.end = start) + 1;
+
3016 return false;
+
3017 }
+
3018 };
+
3019
+
3020 using url_username_char = basic_url_username_char<char>;
+
3021 using wurl_username_char = basic_url_username_char<wchar_t>;
+
3022#ifdef _UNICODE
+
3023 using turl_username_char = wurl_username_char;
+
3024#else
+
3025 using turl_username_char = url_username_char;
+
3026#endif
+
3027
+
3031 class sgml_url_username_char : public basic_url_username_char<char>
+
3032 {
+
3033 public:
+
3034 sgml_url_username_char(_In_ const std::locale& locale = std::locale()) : basic_url_username_char<char>(locale) {}
+
3035
+
3036 virtual bool match(
+
3037 _In_reads_or_z_(end) const char* text,
+
3038 _In_ size_t start = 0,
+
3039 _In_ size_t end = (size_t)-1,
+
3040 _In_ int flags = match_default)
+
3041 {
+
3042 assert(text || start >= end);
+
3043 if (start < end && text[start]) {
+
3044 wchar_t buf[3];
+
3045 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
+
3046 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
3047 if ((chr[0] == L'-' ||
+
3048 chr[0] == L'.' ||
+
3049 chr[0] == L'_' ||
+
3050 chr[0] == L'~' ||
+
3051 chr[0] == L'%' ||
+
3052 chr[0] == L'!' ||
+
3053 chr[0] == L'$' ||
+
3054 chr[0] == L'&' ||
+
3055 chr[0] == L'\'' ||
+
3056 //chr[0] == L'(' ||
+
3057 //chr[0] == L')' ||
+
3058 chr[0] == L'*' ||
+
3059 chr[0] == L'+' ||
+
3060 chr[0] == L',' ||
+
3061 chr[0] == L';' ||
+
3062 chr[0] == L'=') && chr[1] == 0 ||
+
3063 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
+
3064 {
+
3065 interval.start = start;
+
3066 return true;
+
3067 }
+
3068 }
3069
-
3070 virtual bool match(
-
3071 _In_reads_or_z_(end) const T* text,
-
3072 _In_ size_t start = 0,
-
3073 _In_ size_t end = (size_t)-1,
-
3074 _In_ int flags = match_default)
-
3075 {
-
3076 assert(text || start >= end);
-
3077 if (start < end && text[start]) {
-
3078 if (text[start] == '-' ||
-
3079 text[start] == '.' ||
-
3080 text[start] == '_' ||
-
3081 text[start] == '~' ||
-
3082 text[start] == '%' ||
-
3083 text[start] == '!' ||
-
3084 text[start] == '$' ||
-
3085 text[start] == '&' ||
-
3086 text[start] == '\'' ||
-
3087 text[start] == '(' ||
-
3088 text[start] == ')' ||
-
3089 text[start] == '*' ||
-
3090 text[start] == '+' ||
-
3091 text[start] == ',' ||
-
3092 text[start] == ';' ||
-
3093 text[start] == '=' ||
-
3094 text[start] == ':' ||
-
3095 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
-
3096 {
-
3097 interval.end = (interval.start = start) + 1;
-
3098 return true;
-
3099 }
-
3100 }
-
3101 interval.start = (interval.end = start) + 1;
-
3102 return false;
-
3103 }
-
3104 };
-
3105
-
3106 using url_password_char = basic_url_password_char<char>;
-
3107 using wurl_password_char = basic_url_password_char<wchar_t>;
-
3108#ifdef _UNICODE
-
3109 using turl_password_char = wurl_password_char;
-
3110#else
-
3111 using turl_password_char = url_password_char;
-
3112#endif
-
3113
-
3117 class sgml_url_password_char : public basic_url_password_char<char>
-
3118 {
-
3119 public:
-
3120 sgml_url_password_char(_In_ const std::locale& locale = std::locale()) : basic_url_password_char<char>(locale) {}
-
3121
-
3122 virtual bool match(
-
3123 _In_reads_or_z_(end) const char* text,
-
3124 _In_ size_t start = 0,
-
3125 _In_ size_t end = (size_t)-1,
-
3126 _In_ int flags = match_default)
-
3127 {
-
3128 assert(text || start >= end);
-
3129 if (start < end && text[start]) {
-
3130 wchar_t buf[3];
-
3131 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
-
3132 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
3133 if ((chr[0] == L'-' ||
-
3134 chr[0] == L'.' ||
-
3135 chr[0] == L'_' ||
-
3136 chr[0] == L'~' ||
-
3137 chr[0] == L'%' ||
-
3138 chr[0] == L'!' ||
-
3139 chr[0] == L'$' ||
-
3140 chr[0] == L'&' ||
-
3141 chr[0] == L'\'' ||
-
3142 chr[0] == L'(' ||
-
3143 chr[0] == L')' ||
-
3144 chr[0] == L'*' ||
-
3145 chr[0] == L'+' ||
-
3146 chr[0] == L',' ||
-
3147 chr[0] == L';' ||
-
3148 chr[0] == L'=' ||
-
3149 chr[0] == L':') && chr[1] == 0 ||
-
3150 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
-
3151 {
-
3152 interval.start = start;
-
3153 return true;
-
3154 }
-
3155 }
-
3156 interval.start = (interval.end = start) + 1;
-
3157 return false;
-
3158 }
-
3159 };
-
3160
-
3164 template <class T>
-
3165 class basic_url_path_char : public basic_parser<T>
-
3166 {
-
3167 public:
-
3168 basic_url_path_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
-
3169
-
3170 virtual bool match(
-
3171 _In_reads_or_z_(end) const T* text,
-
3172 _In_ size_t start = 0,
-
3173 _In_ size_t end = (size_t)-1,
-
3174 _In_ int flags = match_default)
-
3175 {
-
3176 assert(text || start >= end);
-
3177 if (start < end && text[start]) {
-
3178 if (text[start] == '/' ||
-
3179 text[start] == '-' ||
-
3180 text[start] == '.' ||
-
3181 text[start] == '_' ||
-
3182 text[start] == '~' ||
-
3183 text[start] == '%' ||
-
3184 text[start] == '!' ||
-
3185 text[start] == '$' ||
-
3186 text[start] == '&' ||
-
3187 text[start] == '\'' ||
-
3188 text[start] == '(' ||
-
3189 text[start] == ')' ||
-
3190 text[start] == '*' ||
-
3191 text[start] == '+' ||
-
3192 text[start] == ',' ||
-
3193 text[start] == ';' ||
-
3194 text[start] == '=' ||
-
3195 text[start] == ':' ||
-
3196 text[start] == '@' ||
-
3197 text[start] == '?' ||
-
3198 text[start] == '#' ||
-
3199 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
-
3200 {
-
3201 interval.end = (interval.start = start) + 1;
-
3202 return true;
-
3203 }
-
3204 }
-
3205 interval.start = (interval.end = start) + 1;
-
3206 return false;
-
3207 }
-
3208 };
-
3209
-
3210 using url_path_char = basic_url_path_char<char>;
-
3211 using wurl_path_char = basic_url_path_char<wchar_t>;
-
3212#ifdef _UNICODE
-
3213 using turl_path_char = wurl_path_char;
-
3214#else
-
3215 using turl_path_char = url_path_char;
-
3216#endif
-
3217
-
3221 class sgml_url_path_char : public basic_url_path_char<char>
-
3222 {
-
3223 public:
-
3224 sgml_url_path_char(_In_ const std::locale& locale = std::locale()) : basic_url_path_char<char>(locale) {}
-
3225
-
3226 virtual bool match(
-
3227 _In_reads_or_z_(end) const char* text,
-
3228 _In_ size_t start = 0,
-
3229 _In_ size_t end = (size_t)-1,
-
3230 _In_ int flags = match_default)
-
3231 {
-
3232 assert(text || start >= end);
-
3233 if (start < end && text[start]) {
-
3234 wchar_t buf[3];
-
3235 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
-
3236 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
3237 if ((chr[0] == L'/' ||
-
3238 chr[0] == L'-' ||
-
3239 chr[0] == L'.' ||
-
3240 chr[0] == L'_' ||
-
3241 chr[0] == L'~' ||
-
3242 chr[0] == L'%' ||
-
3243 chr[0] == L'!' ||
-
3244 chr[0] == L'$' ||
-
3245 chr[0] == L'&' ||
-
3246 chr[0] == L'\'' ||
-
3247 chr[0] == L'(' ||
-
3248 chr[0] == L')' ||
-
3249 chr[0] == L'*' ||
-
3250 chr[0] == L'+' ||
-
3251 chr[0] == L',' ||
-
3252 chr[0] == L';' ||
-
3253 chr[0] == L'=' ||
-
3254 chr[0] == L':' ||
-
3255 chr[0] == L'@' ||
-
3256 chr[0] == L'?' ||
-
3257 chr[0] == L'#') && chr[1] == 0 ||
-
3258 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
-
3259 {
-
3260 interval.start = start;
-
3261 return true;
-
3262 }
-
3263 }
-
3264 interval.start = (interval.end = start) + 1;
-
3265 return false;
-
3266 }
-
3267 };
-
3268
-
3272 template <class T>
-
3273 class basic_url_path : public basic_parser<T>
-
3274 {
-
3275 public:
-
3276 basic_url_path(
-
3277 _In_ const std::shared_ptr<basic_parser<T>>& path_char,
-
3278 _In_ const std::shared_ptr<basic_parser<T>>& query_start,
-
3279 _In_ const std::shared_ptr<basic_parser<T>>& bookmark_start,
-
3280 _In_ const std::locale& locale = std::locale()) :
-
3281 basic_parser<T>(locale),
-
3282 m_path_char(path_char),
-
3283 m_query_start(query_start),
-
3284 m_bookmark_start(bookmark_start)
-
3285 {}
-
3286
-
3287 virtual bool match(
-
3288 _In_reads_or_z_(end) const T* text,
-
3289 _In_ size_t start = 0,
-
3290 _In_ size_t end = (size_t)-1,
-
3291 _In_ int flags = match_default)
-
3292 {
-
3293 assert(text || start >= end);
-
3294
-
3295 interval.end = start;
-
3296 path.start = start;
-
3297 query.start = 1;
-
3298 query.end = 0;
-
3299 bookmark.start = 1;
-
3300 bookmark.end = 0;
-
3301
-
3302 for (;;) {
-
3303 if (interval.end >= end || !text[interval.end])
-
3304 break;
-
3305 if (m_query_start->match(text, interval.end, end, flags)) {
-
3306 path.end = interval.end;
-
3307 query.start = interval.end = m_query_start->interval.end;
-
3308 for (;;) {
-
3309 if (interval.end >= end || !text[interval.end]) {
-
3310 query.end = interval.end;
-
3311 break;
-
3312 }
-
3313 if (m_bookmark_start->match(text, interval.end, end, flags)) {
-
3314 query.end = interval.end;
-
3315 bookmark.start = interval.end = m_bookmark_start->interval.end;
-
3316 for (;;) {
-
3317 if (interval.end >= end || !text[interval.end]) {
-
3318 bookmark.end = interval.end;
-
3319 break;
-
3320 }
-
3321 if (m_path_char->match(text, interval.end, end, flags))
-
3322 interval.end = m_path_char->interval.end;
-
3323 else {
-
3324 bookmark.end = interval.end;
-
3325 break;
-
3326 }
-
3327 }
-
3328 interval.start = start;
-
3329 return true;
-
3330 }
-
3331 if (m_path_char->match(text, interval.end, end, flags))
-
3332 interval.end = m_path_char->interval.end;
-
3333 else {
-
3334 query.end = interval.end;
-
3335 break;
-
3336 }
-
3337 }
-
3338 interval.start = start;
-
3339 return true;
-
3340 }
-
3341 if (m_bookmark_start->match(text, interval.end, end, flags)) {
-
3342 path.end = interval.end;
-
3343 bookmark.start = interval.end = m_bookmark_start->interval.end;
-
3344 for (;;) {
-
3345 if (interval.end >= end || !text[interval.end]) {
-
3346 bookmark.end = interval.end;
-
3347 break;
-
3348 }
-
3349 if (m_path_char->match(text, interval.end, end, flags))
-
3350 interval.end = m_path_char->interval.end;
-
3351 else {
-
3352 bookmark.end = interval.end;
-
3353 break;
-
3354 }
-
3355 }
-
3356 interval.start = start;
-
3357 return true;
-
3358 }
-
3359 if (m_path_char->match(text, interval.end, end, flags))
-
3360 interval.end = m_path_char->interval.end;
-
3361 else
-
3362 break;
-
3363 }
-
3364
-
3365 if (start < interval.end) {
-
3366 path.end = interval.end;
-
3367 interval.start = start;
-
3368 return true;
-
3369 }
-
3370
-
3371 path.start = 1;
-
3372 path.end = 0;
-
3373 bookmark.start = 1;
-
3374 bookmark.end = 0;
-
3375 interval.start = (interval.end = start) + 1;
-
3376 return false;
-
3377 }
+
3070 interval.start = (interval.end = start) + 1;
+
3071 return false;
+
3072 }
+
3073 };
+
3074
+
3078 template <class T>
+
3079 class basic_url_password_char : public basic_parser<T>
+
3080 {
+
3081 public:
+
3082 basic_url_password_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
+
3083
+
3084 virtual bool match(
+
3085 _In_reads_or_z_(end) const T* text,
+
3086 _In_ size_t start = 0,
+
3087 _In_ size_t end = (size_t)-1,
+
3088 _In_ int flags = match_default)
+
3089 {
+
3090 assert(text || start >= end);
+
3091 if (start < end && text[start]) {
+
3092 if (text[start] == '-' ||
+
3093 text[start] == '.' ||
+
3094 text[start] == '_' ||
+
3095 text[start] == '~' ||
+
3096 text[start] == '%' ||
+
3097 text[start] == '!' ||
+
3098 text[start] == '$' ||
+
3099 text[start] == '&' ||
+
3100 text[start] == '\'' ||
+
3101 text[start] == '(' ||
+
3102 text[start] == ')' ||
+
3103 text[start] == '*' ||
+
3104 text[start] == '+' ||
+
3105 text[start] == ',' ||
+
3106 text[start] == ';' ||
+
3107 text[start] == '=' ||
+
3108 text[start] == ':' ||
+
3109 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
+
3110 {
+
3111 interval.end = (interval.start = start) + 1;
+
3112 return true;
+
3113 }
+
3114 }
+
3115 interval.start = (interval.end = start) + 1;
+
3116 return false;
+
3117 }
+
3118 };
+
3119
+
3120 using url_password_char = basic_url_password_char<char>;
+
3121 using wurl_password_char = basic_url_password_char<wchar_t>;
+
3122#ifdef _UNICODE
+
3123 using turl_password_char = wurl_password_char;
+
3124#else
+
3125 using turl_password_char = url_password_char;
+
3126#endif
+
3127
+
3131 class sgml_url_password_char : public basic_url_password_char<char>
+
3132 {
+
3133 public:
+
3134 sgml_url_password_char(_In_ const std::locale& locale = std::locale()) : basic_url_password_char<char>(locale) {}
+
3135
+
3136 virtual bool match(
+
3137 _In_reads_or_z_(end) const char* text,
+
3138 _In_ size_t start = 0,
+
3139 _In_ size_t end = (size_t)-1,
+
3140 _In_ int flags = match_default)
+
3141 {
+
3142 assert(text || start >= end);
+
3143 if (start < end && text[start]) {
+
3144 wchar_t buf[3];
+
3145 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
+
3146 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
3147 if ((chr[0] == L'-' ||
+
3148 chr[0] == L'.' ||
+
3149 chr[0] == L'_' ||
+
3150 chr[0] == L'~' ||
+
3151 chr[0] == L'%' ||
+
3152 chr[0] == L'!' ||
+
3153 chr[0] == L'$' ||
+
3154 chr[0] == L'&' ||
+
3155 chr[0] == L'\'' ||
+
3156 chr[0] == L'(' ||
+
3157 chr[0] == L')' ||
+
3158 chr[0] == L'*' ||
+
3159 chr[0] == L'+' ||
+
3160 chr[0] == L',' ||
+
3161 chr[0] == L';' ||
+
3162 chr[0] == L'=' ||
+
3163 chr[0] == L':') && chr[1] == 0 ||
+
3164 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
+
3165 {
+
3166 interval.start = start;
+
3167 return true;
+
3168 }
+
3169 }
+
3170 interval.start = (interval.end = start) + 1;
+
3171 return false;
+
3172 }
+
3173 };
+
3174
+
3178 template <class T>
+
3179 class basic_url_path_char : public basic_parser<T>
+
3180 {
+
3181 public:
+
3182 basic_url_path_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
+
3183
+
3184 virtual bool match(
+
3185 _In_reads_or_z_(end) const T* text,
+
3186 _In_ size_t start = 0,
+
3187 _In_ size_t end = (size_t)-1,
+
3188 _In_ int flags = match_default)
+
3189 {
+
3190 assert(text || start >= end);
+
3191 if (start < end && text[start]) {
+
3192 if (text[start] == '/' ||
+
3193 text[start] == '-' ||
+
3194 text[start] == '.' ||
+
3195 text[start] == '_' ||
+
3196 text[start] == '~' ||
+
3197 text[start] == '%' ||
+
3198 text[start] == '!' ||
+
3199 text[start] == '$' ||
+
3200 text[start] == '&' ||
+
3201 text[start] == '\'' ||
+
3202 text[start] == '(' ||
+
3203 text[start] == ')' ||
+
3204 text[start] == '*' ||
+
3205 text[start] == '+' ||
+
3206 text[start] == ',' ||
+
3207 text[start] == ';' ||
+
3208 text[start] == '=' ||
+
3209 text[start] == ':' ||
+
3210 text[start] == '@' ||
+
3211 text[start] == '?' ||
+
3212 text[start] == '#' ||
+
3213 std::use_facet<std::ctype<T>>(m_locale).is(std::ctype_base::alnum, text[start]))
+
3214 {
+
3215 interval.end = (interval.start = start) + 1;
+
3216 return true;
+
3217 }
+
3218 }
+
3219 interval.start = (interval.end = start) + 1;
+
3220 return false;
+
3221 }
+
3222 };
+
3223
+
3224 using url_path_char = basic_url_path_char<char>;
+
3225 using wurl_path_char = basic_url_path_char<wchar_t>;
+
3226#ifdef _UNICODE
+
3227 using turl_path_char = wurl_path_char;
+
3228#else
+
3229 using turl_path_char = url_path_char;
+
3230#endif
+
3231
+
3235 class sgml_url_path_char : public basic_url_path_char<char>
+
3236 {
+
3237 public:
+
3238 sgml_url_path_char(_In_ const std::locale& locale = std::locale()) : basic_url_path_char<char>(locale) {}
+
3239
+
3240 virtual bool match(
+
3241 _In_reads_or_z_(end) const char* text,
+
3242 _In_ size_t start = 0,
+
3243 _In_ size_t end = (size_t)-1,
+
3244 _In_ int flags = match_default)
+
3245 {
+
3246 assert(text || start >= end);
+
3247 if (start < end && text[start]) {
+
3248 wchar_t buf[3];
+
3249 const wchar_t* chr = next_sgml_cp(text, start, end, interval.end, buf);
+
3250 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
3251 if ((chr[0] == L'/' ||
+
3252 chr[0] == L'-' ||
+
3253 chr[0] == L'.' ||
+
3254 chr[0] == L'_' ||
+
3255 chr[0] == L'~' ||
+
3256 chr[0] == L'%' ||
+
3257 chr[0] == L'!' ||
+
3258 chr[0] == L'$' ||
+
3259 chr[0] == L'&' ||
+
3260 chr[0] == L'\'' ||
+
3261 chr[0] == L'(' ||
+
3262 chr[0] == L')' ||
+
3263 chr[0] == L'*' ||
+
3264 chr[0] == L'+' ||
+
3265 chr[0] == L',' ||
+
3266 chr[0] == L';' ||
+
3267 chr[0] == L'=' ||
+
3268 chr[0] == L':' ||
+
3269 chr[0] == L'@' ||
+
3270 chr[0] == L'?' ||
+
3271 chr[0] == L'#') && chr[1] == 0 ||
+
3272 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
+
3273 {
+
3274 interval.start = start;
+
3275 return true;
+
3276 }
+
3277 }
+
3278 interval.start = (interval.end = start) + 1;
+
3279 return false;
+
3280 }
+
3281 };
+
3282
+
3286 template <class T>
+
3287 class basic_url_path : public basic_parser<T>
+
3288 {
+
3289 public:
+
3290 basic_url_path(
+
3291 _In_ const std::shared_ptr<basic_parser<T>>& path_char,
+
3292 _In_ const std::shared_ptr<basic_parser<T>>& query_start,
+
3293 _In_ const std::shared_ptr<basic_parser<T>>& bookmark_start,
+
3294 _In_ const std::locale& locale = std::locale()) :
+
3295 basic_parser<T>(locale),
+
3296 m_path_char(path_char),
+
3297 m_query_start(query_start),
+
3298 m_bookmark_start(bookmark_start)
+
3299 {}
+
3300
+
3301 virtual bool match(
+
3302 _In_reads_or_z_(end) const T* text,
+
3303 _In_ size_t start = 0,
+
3304 _In_ size_t end = (size_t)-1,
+
3305 _In_ int flags = match_default)
+
3306 {
+
3307 assert(text || start >= end);
+
3308
+
3309 interval.end = start;
+
3310 path.start = start;
+
3311 query.start = 1;
+
3312 query.end = 0;
+
3313 bookmark.start = 1;
+
3314 bookmark.end = 0;
+
3315
+
3316 for (;;) {
+
3317 if (interval.end >= end || !text[interval.end])
+
3318 break;
+
3319 if (m_query_start->match(text, interval.end, end, flags)) {
+
3320 path.end = interval.end;
+
3321 query.start = interval.end = m_query_start->interval.end;
+
3322 for (;;) {
+
3323 if (interval.end >= end || !text[interval.end]) {
+
3324 query.end = interval.end;
+
3325 break;
+
3326 }
+
3327 if (m_bookmark_start->match(text, interval.end, end, flags)) {
+
3328 query.end = interval.end;
+
3329 bookmark.start = interval.end = m_bookmark_start->interval.end;
+
3330 for (;;) {
+
3331 if (interval.end >= end || !text[interval.end]) {
+
3332 bookmark.end = interval.end;
+
3333 break;
+
3334 }
+
3335 if (m_path_char->match(text, interval.end, end, flags))
+
3336 interval.end = m_path_char->interval.end;
+
3337 else {
+
3338 bookmark.end = interval.end;
+
3339 break;
+
3340 }
+
3341 }
+
3342 interval.start = start;
+
3343 return true;
+
3344 }
+
3345 if (m_path_char->match(text, interval.end, end, flags))
+
3346 interval.end = m_path_char->interval.end;
+
3347 else {
+
3348 query.end = interval.end;
+
3349 break;
+
3350 }
+
3351 }
+
3352 interval.start = start;
+
3353 return true;
+
3354 }
+
3355 if (m_bookmark_start->match(text, interval.end, end, flags)) {
+
3356 path.end = interval.end;
+
3357 bookmark.start = interval.end = m_bookmark_start->interval.end;
+
3358 for (;;) {
+
3359 if (interval.end >= end || !text[interval.end]) {
+
3360 bookmark.end = interval.end;
+
3361 break;
+
3362 }
+
3363 if (m_path_char->match(text, interval.end, end, flags))
+
3364 interval.end = m_path_char->interval.end;
+
3365 else {
+
3366 bookmark.end = interval.end;
+
3367 break;
+
3368 }
+
3369 }
+
3370 interval.start = start;
+
3371 return true;
+
3372 }
+
3373 if (m_path_char->match(text, interval.end, end, flags))
+
3374 interval.end = m_path_char->interval.end;
+
3375 else
+
3376 break;
+
3377 }
3378
-
3379 virtual void invalidate()
-
3380 {
-
3381 path.start = 1;
-
3382 path.end = 0;
-
3383 query.start = 1;
-
3384 query.end = 0;
-
3385 bookmark.start = 1;
-
3386 bookmark.end = 0;
-
3387 basic_parser<T>::invalidate();
-
3388 }
-
3389
-
3390 public:
-
3391 stdex::interval<size_t> path;
-
3392 stdex::interval<size_t> query;
-
3393 stdex::interval<size_t> bookmark;
-
3394
-
3395 protected:
-
3396 std::shared_ptr<basic_parser<T>> m_path_char;
-
3397 std::shared_ptr<basic_parser<T>> m_query_start;
-
3398 std::shared_ptr<basic_parser<T>> m_bookmark_start;
-
3399 };
-
3400
-
3401 using url_path = basic_url_path<char>;
-
3402 using wurl_path = basic_url_path<wchar_t>;
-
3403#ifdef _UNICODE
-
3404 using turl_path = wurl_path;
-
3405#else
-
3406 using turl_path = url_path;
-
3407#endif
-
3408 using sgml_url_path = basic_url_path<char>;
-
3409
-
3413 template <class T>
-
3414 class basic_url : public basic_parser<T>
-
3415 {
-
3416 public:
-
3417 basic_url(
-
3418 _In_ const std::shared_ptr<basic_parser<T>>& _http_scheme,
-
3419 _In_ const std::shared_ptr<basic_parser<T>>& _ftp_scheme,
-
3420 _In_ const std::shared_ptr<basic_parser<T>>& _mailto_scheme,
-
3421 _In_ const std::shared_ptr<basic_parser<T>>& _file_scheme,
-
3422 _In_ const std::shared_ptr<basic_parser<T>>& colon,
-
3423 _In_ const std::shared_ptr<basic_parser<T>>& slash,
-
3424 _In_ const std::shared_ptr<basic_parser<T>>& _username,
-
3425 _In_ const std::shared_ptr<basic_parser<T>>& _password,
-
3426 _In_ const std::shared_ptr<basic_parser<T>>& at,
-
3427 _In_ const std::shared_ptr<basic_parser<T>>& ip_lbracket,
-
3428 _In_ const std::shared_ptr<basic_parser<T>>& ip_rbracket,
-
3429 _In_ const std::shared_ptr<basic_parser<T>>& _ipv4_host,
-
3430 _In_ const std::shared_ptr<basic_parser<T>>& _ipv6_host,
-
3431 _In_ const std::shared_ptr<basic_parser<T>>& _dns_host,
-
3432 _In_ const std::shared_ptr<basic_parser<T>>& _port,
-
3433 _In_ const std::shared_ptr<basic_parser<T>>& _path,
-
3434 _In_ const std::locale& locale = std::locale()) :
-
3435 basic_parser<T>(locale),
-
3436 http_scheme(_http_scheme),
-
3437 ftp_scheme(_ftp_scheme),
-
3438 mailto_scheme(_mailto_scheme),
-
3439 file_scheme(_file_scheme),
-
3440 m_colon(colon),
-
3441 m_slash(slash),
-
3442 username(_username),
-
3443 password(_password),
-
3444 m_at(at),
-
3445 m_ip_lbracket(ip_lbracket),
-
3446 m_ip_rbracket(ip_rbracket),
-
3447 ipv4_host(_ipv4_host),
-
3448 ipv6_host(_ipv6_host),
-
3449 dns_host(_dns_host),
-
3450 port(_port),
-
3451 path(_path)
-
3452 {}
-
3453
-
3454 virtual bool match(
-
3455 _In_reads_or_z_(end) const T* text,
-
3456 _In_ size_t start = 0,
-
3457 _In_ size_t end = (size_t)-1,
-
3458 _In_ int flags = match_default)
-
3459 {
-
3460 assert(text || start >= end);
-
3461
-
3462 interval.end = start;
-
3463
-
3464 if (http_scheme->match(text, interval.end, end, flags) &&
-
3465 m_colon->match(text, http_scheme->interval.end, end, flags) &&
-
3466 m_slash->match(text, m_colon->interval.end, end, flags) &&
-
3467 m_slash->match(text, m_slash->interval.end, end, flags))
-
3468 {
-
3469 // http://
-
3470 interval.end = m_slash->interval.end;
-
3471 ftp_scheme->invalidate();
-
3472 mailto_scheme->invalidate();
-
3473 file_scheme->invalidate();
-
3474 }
-
3475 else if (ftp_scheme->match(text, interval.end, end, flags) &&
-
3476 m_colon->match(text, ftp_scheme->interval.end, end, flags) &&
-
3477 m_slash->match(text, m_colon->interval.end, end, flags) &&
-
3478 m_slash->match(text, m_slash->interval.end, end, flags))
-
3479 {
-
3480 // ftp://
-
3481 interval.end = m_slash->interval.end;
-
3482 http_scheme->invalidate();
-
3483 mailto_scheme->invalidate();
-
3484 file_scheme->invalidate();
-
3485 }
-
3486 else if (mailto_scheme->match(text, interval.end, end, flags) &&
-
3487 m_colon->match(text, mailto_scheme->interval.end, end, flags))
-
3488 {
-
3489 // mailto:
-
3490 interval.end = m_colon->interval.end;
-
3491 http_scheme->invalidate();
-
3492 ftp_scheme->invalidate();
-
3493 file_scheme->invalidate();
-
3494 }
-
3495 else if (file_scheme->match(text, interval.end, end, flags) &&
-
3496 m_colon->match(text, file_scheme->interval.end, end, flags) &&
-
3497 m_slash->match(text, m_colon->interval.end, end, flags) &&
-
3498 m_slash->match(text, m_slash->interval.end, end, flags))
-
3499 {
-
3500 // file://
-
3501 interval.end = m_slash->interval.end;
-
3502 http_scheme->invalidate();
-
3503 ftp_scheme->invalidate();
-
3504 mailto_scheme->invalidate();
-
3505 }
-
3506 else {
-
3507 // Default to http:
-
3508 http_scheme->invalidate();
-
3509 ftp_scheme->invalidate();
-
3510 mailto_scheme->invalidate();
-
3511 file_scheme->invalidate();
-
3512 }
-
3513
-
3514 if (ftp_scheme->interval) {
-
3515 if (username->match(text, interval.end, end, flags)) {
-
3516 if (m_colon->match(text, username->interval.end, end, flags) &&
-
3517 password->match(text, m_colon->interval.end, end, flags) &&
-
3518 m_at->match(text, password->interval.end, end, flags))
-
3519 {
-
3520 // Username and password
-
3521 interval.end = m_at->interval.end;
-
3522 }
-
3523 else if (m_at->match(text, interval.end, end, flags)) {
-
3524 // Username only
-
3525 interval.end = m_at->interval.end;
-
3526 password->invalidate();
-
3527 }
-
3528 else {
-
3529 username->invalidate();
-
3530 password->invalidate();
-
3531 }
-
3532 }
-
3533 else {
-
3534 username->invalidate();
-
3535 password->invalidate();
-
3536 }
-
3537
-
3538 if (ipv4_host->match(text, interval.end, end, flags)) {
-
3539 // Host is IPv4
-
3540 interval.end = ipv4_host->interval.end;
-
3541 ipv6_host->invalidate();
-
3542 dns_host->invalidate();
-
3543 }
-
3544 else if (
-
3545 m_ip_lbracket->match(text, interval.end, end, flags) &&
-
3546 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
-
3547 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
-
3548 {
-
3549 // Host is IPv6
-
3550 interval.end = m_ip_rbracket->interval.end;
-
3551 ipv4_host->invalidate();
-
3552 dns_host->invalidate();
-
3553 }
-
3554 else if (dns_host->match(text, interval.end, end, flags)) {
-
3555 // Host is hostname
-
3556 interval.end = dns_host->interval.end;
-
3557 ipv4_host->invalidate();
-
3558 ipv6_host->invalidate();
-
3559 }
-
3560 else {
-
3561 invalidate();
-
3562 return false;
-
3563 }
-
3564
-
3565 if (m_colon->match(text, interval.end, end, flags) &&
-
3566 port->match(text, m_colon->interval.end, end, flags))
-
3567 {
-
3568 // Port
-
3569 interval.end = port->interval.end;
-
3570 }
-
3571 else
-
3572 port->invalidate();
-
3573
-
3574 if (path->match(text, interval.end, end, flags)) {
-
3575 // Path
-
3576 interval.end = path->interval.end;
+
3379 if (start < interval.end) {
+
3380 path.end = interval.end;
+
3381 interval.start = start;
+
3382 return true;
+
3383 }
+
3384
+
3385 path.start = 1;
+
3386 path.end = 0;
+
3387 bookmark.start = 1;
+
3388 bookmark.end = 0;
+
3389 interval.start = (interval.end = start) + 1;
+
3390 return false;
+
3391 }
+
3392
+
3393 virtual void invalidate()
+
3394 {
+
3395 path.start = 1;
+
3396 path.end = 0;
+
3397 query.start = 1;
+
3398 query.end = 0;
+
3399 bookmark.start = 1;
+
3400 bookmark.end = 0;
+
3401 basic_parser<T>::invalidate();
+
3402 }
+
3403
+
3404 public:
+
3405 stdex::interval<size_t> path;
+
3406 stdex::interval<size_t> query;
+
3407 stdex::interval<size_t> bookmark;
+
3408
+
3409 protected:
+
3410 std::shared_ptr<basic_parser<T>> m_path_char;
+
3411 std::shared_ptr<basic_parser<T>> m_query_start;
+
3412 std::shared_ptr<basic_parser<T>> m_bookmark_start;
+
3413 };
+
3414
+
3415 using url_path = basic_url_path<char>;
+
3416 using wurl_path = basic_url_path<wchar_t>;
+
3417#ifdef _UNICODE
+
3418 using turl_path = wurl_path;
+
3419#else
+
3420 using turl_path = url_path;
+
3421#endif
+
3422 using sgml_url_path = basic_url_path<char>;
+
3423
+
3427 template <class T>
+
3428 class basic_url : public basic_parser<T>
+
3429 {
+
3430 public:
+
3431 basic_url(
+
3432 _In_ const std::shared_ptr<basic_parser<T>>& _http_scheme,
+
3433 _In_ const std::shared_ptr<basic_parser<T>>& _ftp_scheme,
+
3434 _In_ const std::shared_ptr<basic_parser<T>>& _mailto_scheme,
+
3435 _In_ const std::shared_ptr<basic_parser<T>>& _file_scheme,
+
3436 _In_ const std::shared_ptr<basic_parser<T>>& colon,
+
3437 _In_ const std::shared_ptr<basic_parser<T>>& slash,
+
3438 _In_ const std::shared_ptr<basic_parser<T>>& _username,
+
3439 _In_ const std::shared_ptr<basic_parser<T>>& _password,
+
3440 _In_ const std::shared_ptr<basic_parser<T>>& at,
+
3441 _In_ const std::shared_ptr<basic_parser<T>>& ip_lbracket,
+
3442 _In_ const std::shared_ptr<basic_parser<T>>& ip_rbracket,
+
3443 _In_ const std::shared_ptr<basic_parser<T>>& _ipv4_host,
+
3444 _In_ const std::shared_ptr<basic_parser<T>>& _ipv6_host,
+
3445 _In_ const std::shared_ptr<basic_parser<T>>& _dns_host,
+
3446 _In_ const std::shared_ptr<basic_parser<T>>& _port,
+
3447 _In_ const std::shared_ptr<basic_parser<T>>& _path,
+
3448 _In_ const std::locale& locale = std::locale()) :
+
3449 basic_parser<T>(locale),
+
3450 http_scheme(_http_scheme),
+
3451 ftp_scheme(_ftp_scheme),
+
3452 mailto_scheme(_mailto_scheme),
+
3453 file_scheme(_file_scheme),
+
3454 m_colon(colon),
+
3455 m_slash(slash),
+
3456 username(_username),
+
3457 password(_password),
+
3458 m_at(at),
+
3459 m_ip_lbracket(ip_lbracket),
+
3460 m_ip_rbracket(ip_rbracket),
+
3461 ipv4_host(_ipv4_host),
+
3462 ipv6_host(_ipv6_host),
+
3463 dns_host(_dns_host),
+
3464 port(_port),
+
3465 path(_path)
+
3466 {}
+
3467
+
3468 virtual bool match(
+
3469 _In_reads_or_z_(end) const T* text,
+
3470 _In_ size_t start = 0,
+
3471 _In_ size_t end = (size_t)-1,
+
3472 _In_ int flags = match_default)
+
3473 {
+
3474 assert(text || start >= end);
+
3475
+
3476 interval.end = start;
+
3477
+
3478 if (http_scheme->match(text, interval.end, end, flags) &&
+
3479 m_colon->match(text, http_scheme->interval.end, end, flags) &&
+
3480 m_slash->match(text, m_colon->interval.end, end, flags) &&
+
3481 m_slash->match(text, m_slash->interval.end, end, flags))
+
3482 {
+
3483 // http://
+
3484 interval.end = m_slash->interval.end;
+
3485 ftp_scheme->invalidate();
+
3486 mailto_scheme->invalidate();
+
3487 file_scheme->invalidate();
+
3488 }
+
3489 else if (ftp_scheme->match(text, interval.end, end, flags) &&
+
3490 m_colon->match(text, ftp_scheme->interval.end, end, flags) &&
+
3491 m_slash->match(text, m_colon->interval.end, end, flags) &&
+
3492 m_slash->match(text, m_slash->interval.end, end, flags))
+
3493 {
+
3494 // ftp://
+
3495 interval.end = m_slash->interval.end;
+
3496 http_scheme->invalidate();
+
3497 mailto_scheme->invalidate();
+
3498 file_scheme->invalidate();
+
3499 }
+
3500 else if (mailto_scheme->match(text, interval.end, end, flags) &&
+
3501 m_colon->match(text, mailto_scheme->interval.end, end, flags))
+
3502 {
+
3503 // mailto:
+
3504 interval.end = m_colon->interval.end;
+
3505 http_scheme->invalidate();
+
3506 ftp_scheme->invalidate();
+
3507 file_scheme->invalidate();
+
3508 }
+
3509 else if (file_scheme->match(text, interval.end, end, flags) &&
+
3510 m_colon->match(text, file_scheme->interval.end, end, flags) &&
+
3511 m_slash->match(text, m_colon->interval.end, end, flags) &&
+
3512 m_slash->match(text, m_slash->interval.end, end, flags))
+
3513 {
+
3514 // file://
+
3515 interval.end = m_slash->interval.end;
+
3516 http_scheme->invalidate();
+
3517 ftp_scheme->invalidate();
+
3518 mailto_scheme->invalidate();
+
3519 }
+
3520 else {
+
3521 // Default to http:
+
3522 http_scheme->invalidate();
+
3523 ftp_scheme->invalidate();
+
3524 mailto_scheme->invalidate();
+
3525 file_scheme->invalidate();
+
3526 }
+
3527
+
3528 if (ftp_scheme->interval) {
+
3529 if (username->match(text, interval.end, end, flags)) {
+
3530 if (m_colon->match(text, username->interval.end, end, flags) &&
+
3531 password->match(text, m_colon->interval.end, end, flags) &&
+
3532 m_at->match(text, password->interval.end, end, flags))
+
3533 {
+
3534 // Username and password
+
3535 interval.end = m_at->interval.end;
+
3536 }
+
3537 else if (m_at->match(text, interval.end, end, flags)) {
+
3538 // Username only
+
3539 interval.end = m_at->interval.end;
+
3540 password->invalidate();
+
3541 }
+
3542 else {
+
3543 username->invalidate();
+
3544 password->invalidate();
+
3545 }
+
3546 }
+
3547 else {
+
3548 username->invalidate();
+
3549 password->invalidate();
+
3550 }
+
3551
+
3552 if (ipv4_host->match(text, interval.end, end, flags)) {
+
3553 // Host is IPv4
+
3554 interval.end = ipv4_host->interval.end;
+
3555 ipv6_host->invalidate();
+
3556 dns_host->invalidate();
+
3557 }
+
3558 else if (
+
3559 m_ip_lbracket->match(text, interval.end, end, flags) &&
+
3560 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
+
3561 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
+
3562 {
+
3563 // Host is IPv6
+
3564 interval.end = m_ip_rbracket->interval.end;
+
3565 ipv4_host->invalidate();
+
3566 dns_host->invalidate();
+
3567 }
+
3568 else if (dns_host->match(text, interval.end, end, flags)) {
+
3569 // Host is hostname
+
3570 interval.end = dns_host->interval.end;
+
3571 ipv4_host->invalidate();
+
3572 ipv6_host->invalidate();
+
3573 }
+
3574 else {
+
3575 invalidate();
+
3576 return false;
3577 }
3578
-
3579 interval.start = start;
-
3580 return true;
-
3581 }
-
3582
-
3583 if (mailto_scheme->interval) {
-
3584 if (username->match(text, interval.end, end, flags) &&
-
3585 m_at->match(text, username->interval.end, end, flags))
-
3586 {
-
3587 // Username
-
3588 interval.end = m_at->interval.end;
-
3589 }
-
3590 else {
-
3591 invalidate();
-
3592 return false;
-
3593 }
-
3594
-
3595 if (m_ip_lbracket->match(text, interval.end, end, flags) &&
-
3596 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
-
3597 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
-
3598 {
-
3599 // Host is IPv4
-
3600 interval.end = m_ip_rbracket->interval.end;
-
3601 ipv6_host->invalidate();
-
3602 dns_host->invalidate();
+
3579 if (m_colon->match(text, interval.end, end, flags) &&
+
3580 port->match(text, m_colon->interval.end, end, flags))
+
3581 {
+
3582 // Port
+
3583 interval.end = port->interval.end;
+
3584 }
+
3585 else
+
3586 port->invalidate();
+
3587
+
3588 if (path->match(text, interval.end, end, flags)) {
+
3589 // Path
+
3590 interval.end = path->interval.end;
+
3591 }
+
3592
+
3593 interval.start = start;
+
3594 return true;
+
3595 }
+
3596
+
3597 if (mailto_scheme->interval) {
+
3598 if (username->match(text, interval.end, end, flags) &&
+
3599 m_at->match(text, username->interval.end, end, flags))
+
3600 {
+
3601 // Username
+
3602 interval.end = m_at->interval.end;
3603 }
-
3604 else if (
-
3605 m_ip_lbracket->match(text, interval.end, end, flags) &&
-
3606 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
-
3607 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
-
3608 {
-
3609 // Host is IPv6
-
3610 interval.end = m_ip_rbracket->interval.end;
-
3611 ipv4_host->invalidate();
-
3612 dns_host->invalidate();
-
3613 }
-
3614 else if (dns_host->match(text, interval.end, end, flags)) {
-
3615 // Host is hostname
-
3616 interval.end = dns_host->interval.end;
-
3617 ipv4_host->invalidate();
-
3618 ipv6_host->invalidate();
-
3619 }
-
3620 else {
-
3621 invalidate();
-
3622 return false;
-
3623 }
-
3624
-
3625 password->invalidate();
-
3626 port->invalidate();
-
3627 path->invalidate();
-
3628 interval.start = start;
-
3629 return true;
-
3630 }
-
3631
-
3632 if (file_scheme->interval) {
-
3633 if (path->match(text, interval.end, end, flags)) {
-
3634 // Path
-
3635 interval.end = path->interval.end;
-
3636 }
-
3637
-
3638 username->invalidate();
+
3604 else {
+
3605 invalidate();
+
3606 return false;
+
3607 }
+
3608
+
3609 if (m_ip_lbracket->match(text, interval.end, end, flags) &&
+
3610 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
+
3611 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
+
3612 {
+
3613 // Host is IPv4
+
3614 interval.end = m_ip_rbracket->interval.end;
+
3615 ipv6_host->invalidate();
+
3616 dns_host->invalidate();
+
3617 }
+
3618 else if (
+
3619 m_ip_lbracket->match(text, interval.end, end, flags) &&
+
3620 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
+
3621 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
+
3622 {
+
3623 // Host is IPv6
+
3624 interval.end = m_ip_rbracket->interval.end;
+
3625 ipv4_host->invalidate();
+
3626 dns_host->invalidate();
+
3627 }
+
3628 else if (dns_host->match(text, interval.end, end, flags)) {
+
3629 // Host is hostname
+
3630 interval.end = dns_host->interval.end;
+
3631 ipv4_host->invalidate();
+
3632 ipv6_host->invalidate();
+
3633 }
+
3634 else {
+
3635 invalidate();
+
3636 return false;
+
3637 }
+
3638
3639 password->invalidate();
-
3640 ipv4_host->invalidate();
-
3641 ipv6_host->invalidate();
-
3642 dns_host->invalidate();
-
3643 port->invalidate();
-
3644 interval.start = start;
-
3645 return true;
-
3646 }
-
3647
-
3648 // "http://" found or defaulted to
-
3649
-
3650 // If "http://" explicit, test for username&password.
-
3651 if (http_scheme->interval &&
-
3652 username->match(text, interval.end, end, flags))
-
3653 {
-
3654 if (m_colon->match(text, username->interval.end, end, flags) &&
-
3655 password->match(text, m_colon->interval.end, end, flags) &&
-
3656 m_at->match(text, password->interval.end, end, flags))
-
3657 {
-
3658 // Username and password
-
3659 interval.end = m_at->interval.end;
-
3660 }
-
3661 else if (m_at->match(text, username->interval.end, end, flags)) {
-
3662 // Username only
-
3663 interval.end = m_at->interval.end;
-
3664 password->invalidate();
-
3665 }
-
3666 else {
-
3667 username->invalidate();
-
3668 password->invalidate();
-
3669 }
-
3670 }
-
3671 else {
-
3672 username->invalidate();
-
3673 password->invalidate();
-
3674 }
-
3675
-
3676 if (ipv4_host->match(text, interval.end, end, flags)) {
-
3677 // Host is IPv4
-
3678 interval.end = ipv4_host->interval.end;
-
3679 ipv6_host->invalidate();
-
3680 dns_host->invalidate();
-
3681 }
-
3682 else if (
-
3683 m_ip_lbracket->match(text, interval.end, end, flags) &&
-
3684 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
-
3685 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
-
3686 {
-
3687 // Host is IPv6
-
3688 interval.end = m_ip_rbracket->interval.end;
-
3689 ipv4_host->invalidate();
-
3690 dns_host->invalidate();
-
3691 }
-
3692 else if (dns_host->match(text, interval.end, end, flags)) {
-
3693 // Host is hostname
-
3694 interval.end = dns_host->interval.end;
-
3695 ipv4_host->invalidate();
-
3696 ipv6_host->invalidate();
-
3697 }
-
3698 else {
-
3699 invalidate();
-
3700 return false;
-
3701 }
-
3702
-
3703 if (m_colon->match(text, interval.end, end, flags) &&
-
3704 port->match(text, m_colon->interval.end, end, flags))
-
3705 {
-
3706 // Port
-
3707 interval.end = port->interval.end;
-
3708 }
-
3709 else
-
3710 port->invalidate();
-
3711
-
3712 if (path->match(text, interval.end, end, flags)) {
-
3713 // Path
-
3714 interval.end = path->interval.end;
+
3640 port->invalidate();
+
3641 path->invalidate();
+
3642 interval.start = start;
+
3643 return true;
+
3644 }
+
3645
+
3646 if (file_scheme->interval) {
+
3647 if (path->match(text, interval.end, end, flags)) {
+
3648 // Path
+
3649 interval.end = path->interval.end;
+
3650 }
+
3651
+
3652 username->invalidate();
+
3653 password->invalidate();
+
3654 ipv4_host->invalidate();
+
3655 ipv6_host->invalidate();
+
3656 dns_host->invalidate();
+
3657 port->invalidate();
+
3658 interval.start = start;
+
3659 return true;
+
3660 }
+
3661
+
3662 // "http://" found or defaulted to
+
3663
+
3664 // If "http://" explicit, test for username&password.
+
3665 if (http_scheme->interval &&
+
3666 username->match(text, interval.end, end, flags))
+
3667 {
+
3668 if (m_colon->match(text, username->interval.end, end, flags) &&
+
3669 password->match(text, m_colon->interval.end, end, flags) &&
+
3670 m_at->match(text, password->interval.end, end, flags))
+
3671 {
+
3672 // Username and password
+
3673 interval.end = m_at->interval.end;
+
3674 }
+
3675 else if (m_at->match(text, username->interval.end, end, flags)) {
+
3676 // Username only
+
3677 interval.end = m_at->interval.end;
+
3678 password->invalidate();
+
3679 }
+
3680 else {
+
3681 username->invalidate();
+
3682 password->invalidate();
+
3683 }
+
3684 }
+
3685 else {
+
3686 username->invalidate();
+
3687 password->invalidate();
+
3688 }
+
3689
+
3690 if (ipv4_host->match(text, interval.end, end, flags)) {
+
3691 // Host is IPv4
+
3692 interval.end = ipv4_host->interval.end;
+
3693 ipv6_host->invalidate();
+
3694 dns_host->invalidate();
+
3695 }
+
3696 else if (
+
3697 m_ip_lbracket->match(text, interval.end, end, flags) &&
+
3698 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
+
3699 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
+
3700 {
+
3701 // Host is IPv6
+
3702 interval.end = m_ip_rbracket->interval.end;
+
3703 ipv4_host->invalidate();
+
3704 dns_host->invalidate();
+
3705 }
+
3706 else if (dns_host->match(text, interval.end, end, flags)) {
+
3707 // Host is hostname
+
3708 interval.end = dns_host->interval.end;
+
3709 ipv4_host->invalidate();
+
3710 ipv6_host->invalidate();
+
3711 }
+
3712 else {
+
3713 invalidate();
+
3714 return false;
3715 }
3716
-
3717 interval.start = start;
-
3718 return true;
-
3719 }
-
3720
-
3721 virtual void invalidate()
-
3722 {
-
3723 http_scheme->invalidate();
-
3724 ftp_scheme->invalidate();
-
3725 mailto_scheme->invalidate();
-
3726 file_scheme->invalidate();
-
3727 username->invalidate();
-
3728 password->invalidate();
-
3729 ipv4_host->invalidate();
-
3730 ipv6_host->invalidate();
-
3731 dns_host->invalidate();
-
3732 port->invalidate();
-
3733 path->invalidate();
-
3734 basic_parser<T>::invalidate();
-
3735 }
-
3736
-
3737 public:
-
3738 std::shared_ptr<basic_parser<T>> http_scheme;
-
3739 std::shared_ptr<basic_parser<T>> ftp_scheme;
-
3740 std::shared_ptr<basic_parser<T>> mailto_scheme;
-
3741 std::shared_ptr<basic_parser<T>> file_scheme;
-
3742 std::shared_ptr<basic_parser<T>> username;
-
3743 std::shared_ptr<basic_parser<T>> password;
-
3744 std::shared_ptr<basic_parser<T>> ipv4_host;
-
3745 std::shared_ptr<basic_parser<T>> ipv6_host;
-
3746 std::shared_ptr<basic_parser<T>> dns_host;
-
3747 std::shared_ptr<basic_parser<T>> port;
-
3748 std::shared_ptr<basic_parser<T>> path;
-
3749
-
3750 protected:
-
3751 std::shared_ptr<basic_parser<T>> m_colon;
-
3752 std::shared_ptr<basic_parser<T>> m_slash;
-
3753 std::shared_ptr<basic_parser<T>> m_at;
-
3754 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
-
3755 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
-
3756 };
-
3757
-
3758 using url = basic_url<char>;
-
3759 using wurl = basic_url<wchar_t>;
-
3760#ifdef _UNICODE
-
3761 using turl = wurl;
-
3762#else
-
3763 using turl = url;
-
3764#endif
-
3765 using sgml_url = basic_url<char>;
-
3766
-
3770 template <class T>
-
3771 class basic_email_address : public basic_parser<T>
-
3772 {
-
3773 public:
-
3774 basic_email_address(
-
3775 _In_ const std::shared_ptr<basic_parser<T>>& _username,
-
3776 _In_ const std::shared_ptr<basic_parser<T>>& at,
-
3777 _In_ const std::shared_ptr<basic_parser<T>>& ip_lbracket,
-
3778 _In_ const std::shared_ptr<basic_parser<T>>& ip_rbracket,
-
3779 _In_ const std::shared_ptr<basic_parser<T>>& _ipv4_host,
-
3780 _In_ const std::shared_ptr<basic_parser<T>>& _ipv6_host,
-
3781 _In_ const std::shared_ptr<basic_parser<T>>& _dns_host,
-
3782 _In_ const std::locale& locale = std::locale()) :
-
3783 basic_parser<T>(locale),
-
3784 username(_username),
-
3785 m_at(at),
-
3786 m_ip_lbracket(ip_lbracket),
-
3787 m_ip_rbracket(ip_rbracket),
-
3788 ipv4_host(_ipv4_host),
-
3789 ipv6_host(_ipv6_host),
-
3790 dns_host(_dns_host)
-
3791 {}
-
3792
-
3793 virtual bool match(
-
3794 _In_reads_or_z_(end) const T* text,
-
3795 _In_ size_t start = 0,
-
3796 _In_ size_t end = (size_t)-1,
-
3797 _In_ int flags = match_default)
-
3798 {
-
3799 assert(text || start >= end);
-
3800
-
3801 if (username->match(text, start, end, flags) &&
-
3802 m_at->match(text, username->interval.end, end, flags))
-
3803 {
-
3804 // Username@
-
3805 if (m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
-
3806 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
-
3807 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
-
3808 {
-
3809 // Host is IPv4
-
3810 interval.end = m_ip_rbracket->interval.end;
-
3811 ipv6_host->invalidate();
-
3812 dns_host->invalidate();
-
3813 }
-
3814 else if (
-
3815 m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
-
3816 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
-
3817 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
-
3818 {
-
3819 // Host is IPv6
-
3820 interval.end = m_ip_rbracket->interval.end;
-
3821 ipv4_host->invalidate();
-
3822 dns_host->invalidate();
-
3823 }
-
3824 else if (dns_host->match(text, m_at->interval.end, end, flags)) {
-
3825 // Host is hostname
-
3826 interval.end = dns_host->interval.end;
-
3827 ipv4_host->invalidate();
-
3828 ipv6_host->invalidate();
-
3829 }
-
3830 else
-
3831 goto error;
-
3832 interval.start = start;
-
3833 return true;
-
3834 }
-
3835
-
3836 error:
-
3837 username->invalidate();
-
3838 ipv4_host->invalidate();
-
3839 ipv6_host->invalidate();
-
3840 dns_host->invalidate();
-
3841 interval.start = (interval.end = start) + 1;
-
3842 return false;
-
3843 }
-
3844
-
3845 virtual void invalidate()
-
3846 {
-
3847 username->invalidate();
-
3848 ipv4_host->invalidate();
-
3849 ipv6_host->invalidate();
-
3850 dns_host->invalidate();
-
3851 basic_parser<T>::invalidate();
-
3852 }
-
3853
-
3854 public:
-
3855 std::shared_ptr<basic_parser<T>> username;
-
3856 std::shared_ptr<basic_parser<T>> ipv4_host;
-
3857 std::shared_ptr<basic_parser<T>> ipv6_host;
-
3858 std::shared_ptr<basic_parser<T>> dns_host;
-
3859
-
3860 protected:
-
3861 std::shared_ptr<basic_parser<T>> m_at;
-
3862 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
-
3863 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
-
3864 };
-
3865
-
3866 using email_address = basic_email_address<char>;
-
3867 using wemail_address = basic_email_address<wchar_t>;
-
3868#ifdef _UNICODE
-
3869 using temail_address = wemail_address;
-
3870#else
-
3871 using temail_address = email_address;
-
3872#endif
-
3873 using sgml_email_address = basic_email_address<char>;
-
3874
-
3878 template <class T>
-
3879 class basic_emoticon : public basic_parser<T>
-
3880 {
-
3881 public:
-
3882 basic_emoticon(
-
3883 _In_ const std::shared_ptr<basic_parser<T>>& _emoticon,
-
3884 _In_ const std::shared_ptr<basic_parser<T>>& _apex,
-
3885 _In_ const std::shared_ptr<basic_parser<T>>& _eyes,
-
3886 _In_ const std::shared_ptr<basic_parser<T>>& _nose,
-
3887 _In_ const std::shared_ptr<basic_set<T>>& _mouth,
-
3888 _In_ const std::locale& locale = std::locale()) :
-
3889 basic_parser<T>(locale),
-
3890 emoticon(_emoticon),
-
3891 apex(_apex),
-
3892 eyes(_eyes),
-
3893 nose(_nose),
-
3894 mouth(_mouth)
-
3895 {}
-
3896
-
3897 virtual bool match(
-
3898 _In_reads_or_z_(end) const T* text,
-
3899 _In_ size_t start = 0,
-
3900 _In_ size_t end = (size_t)-1,
-
3901 _In_ int flags = match_default)
-
3902 {
-
3903 assert(text || start >= end);
-
3904
-
3905 if (emoticon && emoticon->match(text, start, end, flags)) {
-
3906 if (apex) apex->invalidate();
-
3907 eyes->invalidate();
-
3908 if (nose) nose->invalidate();
-
3909 mouth->invalidate();
-
3910 interval.start = start;
-
3911 interval.end = emoticon->interval.end;
-
3912 return true;
-
3913 }
-
3914
-
3915 interval.end = start;
-
3916
-
3917 if (apex && apex->match(text, interval.end, end, flags))
-
3918 interval.end = apex->interval.end;
-
3919
-
3920 if (eyes->match(text, interval.end, end, flags)) {
-
3921 if (nose && nose->match(text, eyes->interval.end, end, flags) &&
-
3922 mouth->match(text, nose->interval.end, end, flags))
-
3923 {
-
3924 size_t
-
3925 start_mouth = mouth->interval.start,
-
3926 hit_offset = mouth->hit_offset;
-
3927 // Mouth may repeat :-)))))))
-
3928 for (interval.end = mouth->interval.end; mouth->match(text, interval.end, end, flags) && mouth->hit_offset == hit_offset; interval.end = mouth->interval.end);
-
3929 mouth->interval.start = start_mouth;
-
3930 mouth->interval.end = interval.end;
-
3931 interval.start = start;
-
3932 return true;
-
3933 }
-
3934 if (mouth->match(text, eyes->interval.end, end, flags)) {
-
3935 size_t
-
3936 start_mouth = mouth->interval.start,
-
3937 hit_offset = mouth->hit_offset;
-
3938 // Mouth may repeat :-)))))))
-
3939 for (interval.end = mouth->interval.end; mouth->match(text, interval.end, end, flags) && mouth->hit_offset == hit_offset; interval.end = mouth->interval.end);
-
3940 if (nose) nose->invalidate();
-
3941 mouth->interval.start = start_mouth;
-
3942 mouth->interval.end = interval.end;
-
3943 interval.start = start;
-
3944 return true;
-
3945 }
-
3946 }
-
3947
-
3948 if (emoticon) emoticon->invalidate();
-
3949 if (apex) apex->invalidate();
-
3950 eyes->invalidate();
-
3951 if (nose) nose->invalidate();
-
3952 mouth->invalidate();
-
3953 interval.start = (interval.end = start) + 1;
-
3954 return false;
-
3955 }
-
3956
-
3957 virtual void invalidate()
-
3958 {
-
3959 if (emoticon) emoticon->invalidate();
-
3960 if (apex) apex->invalidate();
-
3961 eyes->invalidate();
-
3962 if (nose) nose->invalidate();
-
3963 mouth->invalidate();
-
3964 basic_parser<T>::invalidate();
-
3965 }
-
3966
-
3967 public:
-
3968 std::shared_ptr<basic_parser<T>> emoticon;
-
3969 std::shared_ptr<basic_parser<T>> apex;
-
3970 std::shared_ptr<basic_parser<T>> eyes;
-
3971 std::shared_ptr<basic_parser<T>> nose;
-
3972 std::shared_ptr<basic_set<T>> mouth;
-
3973 };
-
3974
-
3975 using emoticon = basic_emoticon<char>;
-
3976 using wemoticon = basic_emoticon<wchar_t>;
-
3977#ifdef _UNICODE
-
3978 using temoticon = wemoticon;
-
3979#else
-
3980 using temoticon = emoticon;
-
3981#endif
-
3982 using sgml_emoticon = basic_emoticon<char>;
-
3983
-
3987 template <class T>
-
3988 class basic_date : public basic_parser<T>
-
3989 {
-
3990 public:
-
3991 enum class format {
-
3992 dmy = 0x1,
-
3993 mdy = 0x2,
-
3994 ymd = 0x4,
-
3995 ym = 0x8,
-
3996 my = 0x10,
-
3997 dm = 0x20,
-
3998 md = 0x40,
-
3999 };
-
4000
-
4001 basic_date(
-
4002 _In_ int format_mask,
-
4003 _In_ const std::shared_ptr<basic_integer<T>>& _day,
-
4004 _In_ const std::shared_ptr<basic_integer<T>>& _month,
-
4005 _In_ const std::shared_ptr<basic_integer<T>>& _year,
-
4006 _In_ const std::shared_ptr<basic_set<T>>& separator,
-
4007 _In_ const std::shared_ptr<basic_parser<T>>& space,
-
4008 _In_ const std::locale& locale = std::locale()) :
-
4009 basic_parser<T>(locale),
-
4010 format(0),
-
4011 m_format_mask(format_mask),
-
4012 day(_day),
-
4013 month(_month),
-
4014 year(_year),
-
4015 m_separator(separator),
-
4016 m_space(space)
-
4017 {}
-
4018
-
4019 virtual bool match(
-
4020 _In_reads_or_z_(end) const T* text,
-
4021 _In_ size_t start = 0,
-
4022 _In_ size_t end = (size_t)-1,
-
4023 _In_ int flags = match_default)
-
4024 {
-
4025 assert(text || start >= end);
-
4026
-
4027 const int space_match_flags = flags & ~match_multiline; // Spaces in dates must never be broken in new line.
-
4028 if ((m_format_mask & format::dmy) != 0) {
-
4029 if (day->match(text, start, end, flags)) {
-
4030 for (interval.end = day->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4031 if (m_separator->match(text, interval.end, end, flags)) {
-
4032 size_t hit_offset = m_separator->hit_offset;
-
4033 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4034 if (month->match(text, interval.end, end, flags)) {
-
4035 for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4036 if (m_separator->match(text, interval.end, end, flags) &&
-
4037 m_separator->hit_offset == hit_offset) // Both separators must match.
-
4038 {
-
4039 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4040 if (year->match(text, interval.end, end, flags) &&
-
4041 is_valid(day->value, month->value))
-
4042 {
-
4043 interval.start = start;
-
4044 interval.end = year->interval.end;
-
4045 format = format::dmy;
-
4046 return true;
-
4047 }
-
4048 }
-
4049 }
-
4050 }
-
4051 }
-
4052 }
-
4053
-
4054 if ((m_format_mask & format::mdy) != 0) {
-
4055 if (month->match(text, start, end, flags)) {
-
4056 for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4057 if (m_separator->match(text, interval.end, end, flags)) {
-
4058 size_t hit_offset = m_separator->hit_offset;
-
4059 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4060 if (day->match(text, interval.end, end, flags)) {
-
4061 for (interval.end = day->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4062 if (m_separator->match(text, interval.end, end, flags) &&
-
4063 m_separator->hit_offset == hit_offset) // Both separators must match.
-
4064 {
-
4065 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4066 if (year->match(text, interval.end, end, flags) &&
-
4067 is_valid(day->value, month->value))
-
4068 {
-
4069 interval.start = start;
-
4070 interval.end = year->interval.end;
-
4071 format = format::mdy;
-
4072 return true;
-
4073 }
-
4074 }
-
4075 }
-
4076 }
-
4077 }
-
4078 }
-
4079
-
4080 if ((m_format_mask & format::ymd) != 0) {
-
4081 if (year->match(text, start, end, flags)) {
-
4082 for (interval.end = year->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4083 if (m_separator->match(text, interval.end, end, flags)) {
-
4084 size_t hit_offset = m_separator->hit_offset;
-
4085 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4086 if (month->match(text, interval.end, end, flags)) {
-
4087 for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4088 if (m_separator->match(text, interval.end, end, flags) &&
-
4089 m_separator->hit_offset == hit_offset) // Both separators must match.
-
4090 {
-
4091 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4092 if (day->match(text, interval.end, end, flags) &&
-
4093 is_valid(day->value, month->value))
-
4094 {
-
4095 interval.start = start;
-
4096 interval.end = day->interval.end;
-
4097 format = format::ymd;
-
4098 return true;
-
4099 }
-
4100 }
-
4101 }
-
4102 }
-
4103 }
-
4104 }
-
4105
-
4106 if ((m_format_mask & format::ym) != 0) {
-
4107 if (year->match(text, start, end, flags)) {
-
4108 for (interval.end = year->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4109 if (m_separator->match(text, interval.end, end, flags)) {
-
4110 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4111 if (month->match(text, interval.end, end, flags) &&
-
4112 is_valid((size_t)-1, month->value))
-
4113 {
-
4114 if (day) day->invalidate();
-
4115 interval.start = start;
-
4116 interval.end = month->interval.end;
-
4117 format = format::ym;
-
4118 return true;
+
3717 if (m_colon->match(text, interval.end, end, flags) &&
+
3718 port->match(text, m_colon->interval.end, end, flags))
+
3719 {
+
3720 // Port
+
3721 interval.end = port->interval.end;
+
3722 }
+
3723 else
+
3724 port->invalidate();
+
3725
+
3726 if (path->match(text, interval.end, end, flags)) {
+
3727 // Path
+
3728 interval.end = path->interval.end;
+
3729 }
+
3730
+
3731 interval.start = start;
+
3732 return true;
+
3733 }
+
3734
+
3735 virtual void invalidate()
+
3736 {
+
3737 http_scheme->invalidate();
+
3738 ftp_scheme->invalidate();
+
3739 mailto_scheme->invalidate();
+
3740 file_scheme->invalidate();
+
3741 username->invalidate();
+
3742 password->invalidate();
+
3743 ipv4_host->invalidate();
+
3744 ipv6_host->invalidate();
+
3745 dns_host->invalidate();
+
3746 port->invalidate();
+
3747 path->invalidate();
+
3748 basic_parser<T>::invalidate();
+
3749 }
+
3750
+
3751 public:
+
3752 std::shared_ptr<basic_parser<T>> http_scheme;
+
3753 std::shared_ptr<basic_parser<T>> ftp_scheme;
+
3754 std::shared_ptr<basic_parser<T>> mailto_scheme;
+
3755 std::shared_ptr<basic_parser<T>> file_scheme;
+
3756 std::shared_ptr<basic_parser<T>> username;
+
3757 std::shared_ptr<basic_parser<T>> password;
+
3758 std::shared_ptr<basic_parser<T>> ipv4_host;
+
3759 std::shared_ptr<basic_parser<T>> ipv6_host;
+
3760 std::shared_ptr<basic_parser<T>> dns_host;
+
3761 std::shared_ptr<basic_parser<T>> port;
+
3762 std::shared_ptr<basic_parser<T>> path;
+
3763
+
3764 protected:
+
3765 std::shared_ptr<basic_parser<T>> m_colon;
+
3766 std::shared_ptr<basic_parser<T>> m_slash;
+
3767 std::shared_ptr<basic_parser<T>> m_at;
+
3768 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
+
3769 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
+
3770 };
+
3771
+
3772 using url = basic_url<char>;
+
3773 using wurl = basic_url<wchar_t>;
+
3774#ifdef _UNICODE
+
3775 using turl = wurl;
+
3776#else
+
3777 using turl = url;
+
3778#endif
+
3779 using sgml_url = basic_url<char>;
+
3780
+
3784 template <class T>
+
3785 class basic_email_address : public basic_parser<T>
+
3786 {
+
3787 public:
+
3788 basic_email_address(
+
3789 _In_ const std::shared_ptr<basic_parser<T>>& _username,
+
3790 _In_ const std::shared_ptr<basic_parser<T>>& at,
+
3791 _In_ const std::shared_ptr<basic_parser<T>>& ip_lbracket,
+
3792 _In_ const std::shared_ptr<basic_parser<T>>& ip_rbracket,
+
3793 _In_ const std::shared_ptr<basic_parser<T>>& _ipv4_host,
+
3794 _In_ const std::shared_ptr<basic_parser<T>>& _ipv6_host,
+
3795 _In_ const std::shared_ptr<basic_parser<T>>& _dns_host,
+
3796 _In_ const std::locale& locale = std::locale()) :
+
3797 basic_parser<T>(locale),
+
3798 username(_username),
+
3799 m_at(at),
+
3800 m_ip_lbracket(ip_lbracket),
+
3801 m_ip_rbracket(ip_rbracket),
+
3802 ipv4_host(_ipv4_host),
+
3803 ipv6_host(_ipv6_host),
+
3804 dns_host(_dns_host)
+
3805 {}
+
3806
+
3807 virtual bool match(
+
3808 _In_reads_or_z_(end) const T* text,
+
3809 _In_ size_t start = 0,
+
3810 _In_ size_t end = (size_t)-1,
+
3811 _In_ int flags = match_default)
+
3812 {
+
3813 assert(text || start >= end);
+
3814
+
3815 if (username->match(text, start, end, flags) &&
+
3816 m_at->match(text, username->interval.end, end, flags))
+
3817 {
+
3818 // Username@
+
3819 if (m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
+
3820 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
+
3821 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
+
3822 {
+
3823 // Host is IPv4
+
3824 interval.end = m_ip_rbracket->interval.end;
+
3825 ipv6_host->invalidate();
+
3826 dns_host->invalidate();
+
3827 }
+
3828 else if (
+
3829 m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
+
3830 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
+
3831 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
+
3832 {
+
3833 // Host is IPv6
+
3834 interval.end = m_ip_rbracket->interval.end;
+
3835 ipv4_host->invalidate();
+
3836 dns_host->invalidate();
+
3837 }
+
3838 else if (dns_host->match(text, m_at->interval.end, end, flags)) {
+
3839 // Host is hostname
+
3840 interval.end = dns_host->interval.end;
+
3841 ipv4_host->invalidate();
+
3842 ipv6_host->invalidate();
+
3843 }
+
3844 else
+
3845 goto error;
+
3846 interval.start = start;
+
3847 return true;
+
3848 }
+
3849
+
3850 error:
+
3851 username->invalidate();
+
3852 ipv4_host->invalidate();
+
3853 ipv6_host->invalidate();
+
3854 dns_host->invalidate();
+
3855 interval.start = (interval.end = start) + 1;
+
3856 return false;
+
3857 }
+
3858
+
3859 virtual void invalidate()
+
3860 {
+
3861 username->invalidate();
+
3862 ipv4_host->invalidate();
+
3863 ipv6_host->invalidate();
+
3864 dns_host->invalidate();
+
3865 basic_parser<T>::invalidate();
+
3866 }
+
3867
+
3868 public:
+
3869 std::shared_ptr<basic_parser<T>> username;
+
3870 std::shared_ptr<basic_parser<T>> ipv4_host;
+
3871 std::shared_ptr<basic_parser<T>> ipv6_host;
+
3872 std::shared_ptr<basic_parser<T>> dns_host;
+
3873
+
3874 protected:
+
3875 std::shared_ptr<basic_parser<T>> m_at;
+
3876 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
+
3877 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
+
3878 };
+
3879
+
3880 using email_address = basic_email_address<char>;
+
3881 using wemail_address = basic_email_address<wchar_t>;
+
3882#ifdef _UNICODE
+
3883 using temail_address = wemail_address;
+
3884#else
+
3885 using temail_address = email_address;
+
3886#endif
+
3887 using sgml_email_address = basic_email_address<char>;
+
3888
+
3892 template <class T>
+
3893 class basic_emoticon : public basic_parser<T>
+
3894 {
+
3895 public:
+
3896 basic_emoticon(
+
3897 _In_ const std::shared_ptr<basic_parser<T>>& _emoticon,
+
3898 _In_ const std::shared_ptr<basic_parser<T>>& _apex,
+
3899 _In_ const std::shared_ptr<basic_parser<T>>& _eyes,
+
3900 _In_ const std::shared_ptr<basic_parser<T>>& _nose,
+
3901 _In_ const std::shared_ptr<basic_set<T>>& _mouth,
+
3902 _In_ const std::locale& locale = std::locale()) :
+
3903 basic_parser<T>(locale),
+
3904 emoticon(_emoticon),
+
3905 apex(_apex),
+
3906 eyes(_eyes),
+
3907 nose(_nose),
+
3908 mouth(_mouth)
+
3909 {}
+
3910
+
3911 virtual bool match(
+
3912 _In_reads_or_z_(end) const T* text,
+
3913 _In_ size_t start = 0,
+
3914 _In_ size_t end = (size_t)-1,
+
3915 _In_ int flags = match_default)
+
3916 {
+
3917 assert(text || start >= end);
+
3918
+
3919 if (emoticon && emoticon->match(text, start, end, flags)) {
+
3920 if (apex) apex->invalidate();
+
3921 eyes->invalidate();
+
3922 if (nose) nose->invalidate();
+
3923 mouth->invalidate();
+
3924 interval.start = start;
+
3925 interval.end = emoticon->interval.end;
+
3926 return true;
+
3927 }
+
3928
+
3929 interval.end = start;
+
3930
+
3931 if (apex && apex->match(text, interval.end, end, flags))
+
3932 interval.end = apex->interval.end;
+
3933
+
3934 if (eyes->match(text, interval.end, end, flags)) {
+
3935 if (nose && nose->match(text, eyes->interval.end, end, flags) &&
+
3936 mouth->match(text, nose->interval.end, end, flags))
+
3937 {
+
3938 size_t
+
3939 start_mouth = mouth->interval.start,
+
3940 hit_offset = mouth->hit_offset;
+
3941 // Mouth may repeat :-)))))))
+
3942 for (interval.end = mouth->interval.end; mouth->match(text, interval.end, end, flags) && mouth->hit_offset == hit_offset; interval.end = mouth->interval.end);
+
3943 mouth->interval.start = start_mouth;
+
3944 mouth->interval.end = interval.end;
+
3945 interval.start = start;
+
3946 return true;
+
3947 }
+
3948 if (mouth->match(text, eyes->interval.end, end, flags)) {
+
3949 size_t
+
3950 start_mouth = mouth->interval.start,
+
3951 hit_offset = mouth->hit_offset;
+
3952 // Mouth may repeat :-)))))))
+
3953 for (interval.end = mouth->interval.end; mouth->match(text, interval.end, end, flags) && mouth->hit_offset == hit_offset; interval.end = mouth->interval.end);
+
3954 if (nose) nose->invalidate();
+
3955 mouth->interval.start = start_mouth;
+
3956 mouth->interval.end = interval.end;
+
3957 interval.start = start;
+
3958 return true;
+
3959 }
+
3960 }
+
3961
+
3962 if (emoticon) emoticon->invalidate();
+
3963 if (apex) apex->invalidate();
+
3964 eyes->invalidate();
+
3965 if (nose) nose->invalidate();
+
3966 mouth->invalidate();
+
3967 interval.start = (interval.end = start) + 1;
+
3968 return false;
+
3969 }
+
3970
+
3971 virtual void invalidate()
+
3972 {
+
3973 if (emoticon) emoticon->invalidate();
+
3974 if (apex) apex->invalidate();
+
3975 eyes->invalidate();
+
3976 if (nose) nose->invalidate();
+
3977 mouth->invalidate();
+
3978 basic_parser<T>::invalidate();
+
3979 }
+
3980
+
3981 public:
+
3982 std::shared_ptr<basic_parser<T>> emoticon;
+
3983 std::shared_ptr<basic_parser<T>> apex;
+
3984 std::shared_ptr<basic_parser<T>> eyes;
+
3985 std::shared_ptr<basic_parser<T>> nose;
+
3986 std::shared_ptr<basic_set<T>> mouth;
+
3987 };
+
3988
+
3989 using emoticon = basic_emoticon<char>;
+
3990 using wemoticon = basic_emoticon<wchar_t>;
+
3991#ifdef _UNICODE
+
3992 using temoticon = wemoticon;
+
3993#else
+
3994 using temoticon = emoticon;
+
3995#endif
+
3996 using sgml_emoticon = basic_emoticon<char>;
+
3997
+
4001 ENUM_FLAGS(date_format_t, int) {
+
4002 none = 0,
+
4003 dmy = 0x1,
+
4004 mdy = 0x2,
+
4005 ymd = 0x4,
+
4006 ym = 0x8,
+
4007 my = 0x10,
+
4008 dm = 0x20,
+
4009 md = 0x40,
+
4010 };
+
4011
+
4015 template <class T>
+
4016 class basic_date : public basic_parser<T>
+
4017 {
+
4018 public:
+
4019 basic_date(
+
4020 _In_ int format_mask,
+
4021 _In_ const std::shared_ptr<basic_integer<T>>& _day,
+
4022 _In_ const std::shared_ptr<basic_integer<T>>& _month,
+
4023 _In_ const std::shared_ptr<basic_integer<T>>& _year,
+
4024 _In_ const std::shared_ptr<basic_set<T>>& separator,
+
4025 _In_ const std::shared_ptr<basic_parser<T>>& space,
+
4026 _In_ const std::locale& locale = std::locale()) :
+
4027 basic_parser<T>(locale),
+
4028 format(date_format_t::none),
+
4029 m_format_mask(format_mask),
+
4030 day(_day),
+
4031 month(_month),
+
4032 year(_year),
+
4033 m_separator(separator),
+
4034 m_space(space)
+
4035 {}
+
4036
+
4037 virtual bool match(
+
4038 _In_reads_or_z_(end) const T* text,
+
4039 _In_ size_t start = 0,
+
4040 _In_ size_t end = (size_t)-1,
+
4041 _In_ int flags = match_default)
+
4042 {
+
4043 assert(text || start >= end);
+
4044
+
4045 const int space_match_flags = flags & ~match_multiline; // Spaces in dates must never be broken in new line.
+
4046 if ((m_format_mask & date_format_t::dmy) == date_format_t::dmy) {
+
4047 if (day->match(text, start, end, flags)) {
+
4048 for (interval.end = day->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4049 if (m_separator->match(text, interval.end, end, flags)) {
+
4050 size_t hit_offset = m_separator->hit_offset;
+
4051 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4052 if (month->match(text, interval.end, end, flags)) {
+
4053 for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4054 if (m_separator->match(text, interval.end, end, flags) &&
+
4055 m_separator->hit_offset == hit_offset) // Both separators must match.
+
4056 {
+
4057 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4058 if (year->match(text, interval.end, end, flags) &&
+
4059 is_valid(day->value, month->value))
+
4060 {
+
4061 interval.start = start;
+
4062 interval.end = year->interval.end;
+
4063 format = date_format_t::dmy;
+
4064 return true;
+
4065 }
+
4066 }
+
4067 }
+
4068 }
+
4069 }
+
4070 }
+
4071
+
4072 if ((m_format_mask & date_format_t::mdy) == date_format_t::mdy) {
+
4073 if (month->match(text, start, end, flags)) {
+
4074 for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4075 if (m_separator->match(text, interval.end, end, flags)) {
+
4076 size_t hit_offset = m_separator->hit_offset;
+
4077 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4078 if (day->match(text, interval.end, end, flags)) {
+
4079 for (interval.end = day->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4080 if (m_separator->match(text, interval.end, end, flags) &&
+
4081 m_separator->hit_offset == hit_offset) // Both separators must match.
+
4082 {
+
4083 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4084 if (year->match(text, interval.end, end, flags) &&
+
4085 is_valid(day->value, month->value))
+
4086 {
+
4087 interval.start = start;
+
4088 interval.end = year->interval.end;
+
4089 format = date_format_t::mdy;
+
4090 return true;
+
4091 }
+
4092 }
+
4093 }
+
4094 }
+
4095 }
+
4096 }
+
4097
+
4098 if ((m_format_mask & date_format_t::ymd) == date_format_t::ymd) {
+
4099 if (year->match(text, start, end, flags)) {
+
4100 for (interval.end = year->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4101 if (m_separator->match(text, interval.end, end, flags)) {
+
4102 size_t hit_offset = m_separator->hit_offset;
+
4103 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4104 if (month->match(text, interval.end, end, flags)) {
+
4105 for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4106 if (m_separator->match(text, interval.end, end, flags) &&
+
4107 m_separator->hit_offset == hit_offset) // Both separators must match.
+
4108 {
+
4109 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4110 if (day->match(text, interval.end, end, flags) &&
+
4111 is_valid(day->value, month->value))
+
4112 {
+
4113 interval.start = start;
+
4114 interval.end = day->interval.end;
+
4115 format = date_format_t::ymd;
+
4116 return true;
+
4117 }
+
4118 }
4119 }
4120 }
4121 }
4122 }
4123
-
4124 if ((m_format_mask & format::my) != 0) {
-
4125 if (month->match(text, start, end, flags)) {
-
4126 for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4124 if ((m_format_mask & date_format_t::ym) == date_format_t::ym) {
+
4125 if (year->match(text, start, end, flags)) {
+
4126 for (interval.end = year->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
4127 if (m_separator->match(text, interval.end, end, flags)) {
4128 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4129 if (year->match(text, interval.end, end, flags) &&
+
4129 if (month->match(text, interval.end, end, flags) &&
4130 is_valid((size_t)-1, month->value))
4131 {
4132 if (day) day->invalidate();
4133 interval.start = start;
-
4134 interval.end = year->interval.end;
-
4135 format = format::my;
+
4134 interval.end = month->interval.end;
+
4135 format = date_format_t::ym;
4136 return true;
4137 }
4138 }
4139 }
4140 }
4141
-
4142 if ((m_format_mask & format::dm) != 0) {
-
4143 if (day->match(text, start, end, flags)) {
-
4144 for (interval.end = day->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4142 if ((m_format_mask & date_format_t::my) == date_format_t::my) {
+
4143 if (month->match(text, start, end, flags)) {
+
4144 for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
4145 if (m_separator->match(text, interval.end, end, flags)) {
-
4146 size_t hit_offset = m_separator->hit_offset;
-
4147 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4148 if (month->match(text, interval.end, end, flags) &&
-
4149 is_valid(day->value, month->value))
-
4150 {
-
4151 if (year) year->invalidate();
-
4152 interval.start = start;
-
4153 for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4154 if (m_separator->match(text, interval.end, end, flags) &&
-
4155 m_separator->hit_offset == hit_offset) // Both separators must match.
-
4156 interval.end = m_separator->interval.end;
-
4157 else
-
4158 interval.end = month->interval.end;
-
4159 format = format::dm;
-
4160 return true;
-
4161 }
-
4162 }
-
4163 }
-
4164 }
-
4165
-
4166 if ((m_format_mask & format::md) != 0) {
-
4167 if (month->match(text, start, end, flags)) {
-
4168 for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4169 if (m_separator->match(text, interval.end, end, flags)) {
-
4170 size_t hit_offset = m_separator->hit_offset;
-
4171 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4172 if (day->match(text, interval.end, end, flags) &&
-
4173 is_valid(day->value, month->value))
-
4174 {
-
4175 if (year) year->invalidate();
-
4176 interval.start = start;
-
4177 for (interval.end = day->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
-
4178 if (m_separator->match(text, interval.end, end, flags) &&
-
4179 m_separator->hit_offset == hit_offset) // Both separators must match.
-
4180 interval.end = m_separator->interval.end;
-
4181 else
-
4182 interval.end = day->interval.end;
-
4183 format = format::md;
-
4184 return true;
-
4185 }
-
4186 }
-
4187 }
-
4188 }
-
4189
-
4190 if (day) day->invalidate();
-
4191 if (month) month->invalidate();
-
4192 if (year) year->invalidate();
-
4193 format = 0;
-
4194 interval.start = (interval.end = start) + 1;
-
4195 return false;
-
4196 }
-
4197
-
4198 virtual void invalidate()
-
4199 {
-
4200 if (day) day->invalidate();
-
4201 if (month) month->invalidate();
-
4202 if (year) year->invalidate();
-
4203 format = 0;
-
4204 basic_parser<T>::invalidate();
-
4205 }
-
4206
-
4207 protected:
-
4208 static inline bool is_valid(size_t day, size_t month)
-
4209 {
-
4210 if (month == (size_t)-1) {
-
4211 // Default to January. This allows validating day only, as January has all 31 days.
-
4212 month = 1;
-
4213 }
-
4214 if (day == (size_t)-1) {
-
4215 // Default to 1st day in month. This allows validating month only, as each month has 1st day.
-
4216 day = 1;
-
4217 }
-
4218
-
4219 switch (month) {
-
4220 case 1:
-
4221 case 3:
-
4222 case 5:
-
4223 case 7:
-
4224 case 8:
-
4225 case 10:
-
4226 case 12:
-
4227 return 1 <= day && day <= 31;
-
4228 case 2:
-
4229 return 1 <= day && day <= 29;
-
4230 case 4:
-
4231 case 6:
-
4232 case 9:
-
4233 case 11:
-
4234 return 1 <= day && day <= 30;
-
4235 default:
-
4236 return false;
-
4237 }
-
4238 }
-
4239
-
4240 public:
-
4241 format format;
-
4242 std::shared_ptr<basic_integer<T>> day;
-
4243 std::shared_ptr<basic_integer<T>> month;
-
4244 std::shared_ptr<basic_integer<T>> year;
-
4245
-
4246 protected:
-
4247 int m_format_mask;
-
4248 std::shared_ptr<basic_set<T>> m_separator;
-
4249 std::shared_ptr<basic_parser<T>> m_space;
-
4250 };
-
4251
-
4252 using date = basic_date<char>;
-
4253 using wdate = basic_date<wchar_t>;
-
4254#ifdef _UNICODE
-
4255 using tdate = wdate;
-
4256#else
-
4257 using tdate = date;
-
4258#endif
-
4259 using sgml_date = basic_date<char>;
-
4260
-
4264 template <class T>
-
4265 class basic_time : public basic_parser<T>
-
4266 {
-
4267 public:
-
4268 basic_time(
-
4269 _In_ const std::shared_ptr<basic_integer10<T>>& _hour,
-
4270 _In_ const std::shared_ptr<basic_integer10<T>>& _minute,
-
4271 _In_ const std::shared_ptr<basic_integer10<T>>& _second,
-
4272 _In_ const std::shared_ptr<basic_integer10<T>>& _millisecond,
-
4273 _In_ const std::shared_ptr<basic_set<T>>& separator,
-
4274 _In_ const std::shared_ptr<basic_parser<T>>& millisecond_separator,
-
4275 _In_ const std::locale& locale = std::locale()) :
-
4276 basic_parser<T>(locale),
-
4277 hour(_hour),
-
4278 minute(_minute),
-
4279 second(_second),
-
4280 millisecond(_millisecond),
-
4281 m_separator(separator),
-
4282 m_millisecond_separator(millisecond_separator)
-
4283 {}
-
4284
-
4285 virtual bool match(
-
4286 _In_reads_or_z_(end) const T* text,
-
4287 _In_ size_t start = 0,
-
4288 _In_ size_t end = (size_t)-1,
-
4289 _In_ int flags = match_default)
-
4290 {
-
4291 assert(text || start >= end);
-
4292
-
4293 if (hour->match(text, start, end, flags) &&
-
4294 m_separator->match(text, hour->interval.end, end, flags) &&
-
4295 minute->match(text, m_separator->interval.end, end, flags) &&
-
4296 minute->value < 60)
-
4297 {
-
4298 // hh::mm
-
4299 size_t hit_offset = m_separator->hit_offset;
-
4300 if (m_separator->match(text, minute->interval.end, end, flags) &&
-
4301 m_separator->hit_offset == hit_offset && // Both separators must match.
-
4302 second && second->match(text, m_separator->interval.end, end, flags) &&
-
4303 second->value < 60)
-
4304 {
-
4305 // hh::mm:ss
-
4306 if (m_millisecond_separator && m_millisecond_separator->match(text, second->interval.end, end, flags) &&
-
4307 millisecond && millisecond->match(text, m_millisecond_separator->interval.end, end, flags) &&
-
4308 millisecond->value < 1000)
-
4309 {
-
4310 // hh::mm:ss.mmmm
-
4311 interval.end = millisecond->interval.end;
-
4312 }
-
4313 else {
-
4314 if (millisecond) millisecond->invalidate();
-
4315 interval.end = second->interval.end;
-
4316 }
-
4317 }
-
4318 else {
-
4319 if (second) second->invalidate();
-
4320 if (millisecond) millisecond->invalidate();
-
4321 interval.end = minute->interval.end;
-
4322 }
-
4323 interval.start = start;
-
4324 return true;
-
4325 }
-
4326
-
4327 hour->invalidate();
-
4328 minute->invalidate();
-
4329 if (second) second->invalidate();
-
4330 if (millisecond) millisecond->invalidate();
-
4331 interval.start = (interval.end = start) + 1;
-
4332 return false;
-
4333 }
-
4334
-
4335 virtual void invalidate()
-
4336 {
-
4337 hour->invalidate();
-
4338 minute->invalidate();
-
4339 if (second) second->invalidate();
-
4340 if (millisecond) millisecond->invalidate();
-
4341 basic_parser<T>::invalidate();
-
4342 }
-
4343
-
4344 public:
-
4345 std::shared_ptr<basic_integer10<T>> hour;
-
4346 std::shared_ptr<basic_integer10<T>> minute;
-
4347 std::shared_ptr<basic_integer10<T>> second;
-
4348 std::shared_ptr<basic_integer10<T>> millisecond;
-
4349
-
4350 protected:
-
4351 std::shared_ptr<basic_set<T>> m_separator;
-
4352 std::shared_ptr<basic_parser<T>> m_millisecond_separator;
-
4353 };
-
4354
-
4355 using time = basic_time<char>;
-
4356 using wtime = basic_time<wchar_t>;
-
4357#ifdef _UNICODE
-
4358 using ttime = wtime;
-
4359#else
-
4360 using ttime = time;
-
4361#endif
-
4362 using sgml_time = basic_time<char>;
-
4363
-
4367 template <class T>
-
4368 class basic_angle : public basic_parser<T>
-
4369 {
-
4370 public:
-
4371 basic_angle(
-
4372 _In_ const std::shared_ptr<basic_integer10<T>>& _degree,
-
4373 _In_ const std::shared_ptr<basic_parser<T>>& _degree_separator,
-
4374 _In_ const std::shared_ptr<basic_integer10<T>>& _minute,
-
4375 _In_ const std::shared_ptr<basic_parser<T>>& _minute_separator,
-
4376 _In_ const std::shared_ptr<basic_integer10<T>>& _second,
-
4377 _In_ const std::shared_ptr<basic_parser<T>>& _second_separator,
-
4378 _In_ const std::shared_ptr<basic_parser<T>>& _decimal,
-
4379 _In_ const std::locale& locale = std::locale()) :
-
4380 basic_parser<T>(locale),
-
4381 degree(_degree),
-
4382 degree_separator(_degree_separator),
-
4383 minute(_minute),
-
4384 minute_separator(_minute_separator),
-
4385 second(_second),
-
4386 second_separator(_second_separator),
-
4387 decimal(_decimal)
-
4388 {}
-
4389
-
4390 virtual bool match(
-
4391 _In_reads_or_z_(end) const T* text,
-
4392 _In_ size_t start = 0,
-
4393 _In_ size_t end = (size_t)-1,
-
4394 _In_ int flags = match_default)
-
4395 {
-
4396 assert(text || start >= end);
-
4397
-
4398 interval.end = start;
-
4399
-
4400 if (degree->match(text, interval.end, end, flags) &&
-
4401 degree_separator->match(text, degree->interval.end, end, flags))
-
4402 {
-
4403 // Degrees
-
4404 interval.end = degree_separator->interval.end;
-
4405 }
-
4406 else {
-
4407 degree->invalidate();
-
4408 degree_separator->invalidate();
-
4409 }
-
4410
-
4411 if (minute->match(text, interval.end, end, flags) &&
-
4412 minute->value < 60 &&
-
4413 minute_separator->match(text, minute->interval.end, end, flags))
-
4414 {
-
4415 // Minutes
-
4416 interval.end = minute_separator->interval.end;
-
4417 }
-
4418 else {
-
4419 minute->invalidate();
-
4420 minute_separator->invalidate();
-
4421 }
-
4422
-
4423 if (second && second->match(text, interval.end, end, flags) &&
-
4424 second->value < 60)
-
4425 {
-
4426 // Seconds
-
4427 interval.end = second->interval.end;
-
4428 if (second_separator && second_separator->match(text, interval.end, end, flags))
-
4429 interval.end = second_separator->interval.end;
-
4430 else
-
4431 if (second_separator) second_separator->invalidate();
-
4432 }
-
4433 else {
-
4434 if (second) second->invalidate();
-
4435 if (second_separator) second_separator->invalidate();
-
4436 }
-
4437
-
4438 if (degree->interval.start < degree->interval.end ||
-
4439 minute->interval.start < minute->interval.end ||
-
4440 second && second->interval.start < second->interval.end)
-
4441 {
-
4442 if (decimal && decimal->match(text, interval.end, end, flags)) {
-
4443 // Decimals
-
4444 interval.end = decimal->interval.end;
-
4445 }
-
4446 else if (decimal)
-
4447 decimal->invalidate();
-
4448 interval.start = start;
-
4449 return true;
+
4146 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4147 if (year->match(text, interval.end, end, flags) &&
+
4148 is_valid((size_t)-1, month->value))
+
4149 {
+
4150 if (day) day->invalidate();
+
4151 interval.start = start;
+
4152 interval.end = year->interval.end;
+
4153 format = date_format_t::my;
+
4154 return true;
+
4155 }
+
4156 }
+
4157 }
+
4158 }
+
4159
+
4160 if ((m_format_mask & date_format_t::dm) == date_format_t::dm) {
+
4161 if (day->match(text, start, end, flags)) {
+
4162 for (interval.end = day->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4163 if (m_separator->match(text, interval.end, end, flags)) {
+
4164 size_t hit_offset = m_separator->hit_offset;
+
4165 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4166 if (month->match(text, interval.end, end, flags) &&
+
4167 is_valid(day->value, month->value))
+
4168 {
+
4169 if (year) year->invalidate();
+
4170 interval.start = start;
+
4171 for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4172 if (m_separator->match(text, interval.end, end, flags) &&
+
4173 m_separator->hit_offset == hit_offset) // Both separators must match.
+
4174 interval.end = m_separator->interval.end;
+
4175 else
+
4176 interval.end = month->interval.end;
+
4177 format = date_format_t::dm;
+
4178 return true;
+
4179 }
+
4180 }
+
4181 }
+
4182 }
+
4183
+
4184 if ((m_format_mask & date_format_t::md) == date_format_t::md) {
+
4185 if (month->match(text, start, end, flags)) {
+
4186 for (interval.end = month->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4187 if (m_separator->match(text, interval.end, end, flags)) {
+
4188 size_t hit_offset = m_separator->hit_offset;
+
4189 for (interval.end = m_separator->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4190 if (day->match(text, interval.end, end, flags) &&
+
4191 is_valid(day->value, month->value))
+
4192 {
+
4193 if (year) year->invalidate();
+
4194 interval.start = start;
+
4195 for (interval.end = day->interval.end; m_space->match(text, interval.end, end, space_match_flags); interval.end = m_space->interval.end);
+
4196 if (m_separator->match(text, interval.end, end, flags) &&
+
4197 m_separator->hit_offset == hit_offset) // Both separators must match.
+
4198 interval.end = m_separator->interval.end;
+
4199 else
+
4200 interval.end = day->interval.end;
+
4201 format = date_format_t::md;
+
4202 return true;
+
4203 }
+
4204 }
+
4205 }
+
4206 }
+
4207
+
4208 if (day) day->invalidate();
+
4209 if (month) month->invalidate();
+
4210 if (year) year->invalidate();
+
4211 format = date_format_t::none;
+
4212 interval.start = (interval.end = start) + 1;
+
4213 return false;
+
4214 }
+
4215
+
4216 virtual void invalidate()
+
4217 {
+
4218 if (day) day->invalidate();
+
4219 if (month) month->invalidate();
+
4220 if (year) year->invalidate();
+
4221 format = date_format_t::none;
+
4222 basic_parser<T>::invalidate();
+
4223 }
+
4224
+
4225 protected:
+
4226 static inline bool is_valid(size_t day, size_t month)
+
4227 {
+
4228 if (month == (size_t)-1) {
+
4229 // Default to January. This allows validating day only, as January has all 31 days.
+
4230 month = 1;
+
4231 }
+
4232 if (day == (size_t)-1) {
+
4233 // Default to 1st day in month. This allows validating month only, as each month has 1st day.
+
4234 day = 1;
+
4235 }
+
4236
+
4237 switch (month) {
+
4238 case 1:
+
4239 case 3:
+
4240 case 5:
+
4241 case 7:
+
4242 case 8:
+
4243 case 10:
+
4244 case 12:
+
4245 return 1 <= day && day <= 31;
+
4246 case 2:
+
4247 return 1 <= day && day <= 29;
+
4248 case 4:
+
4249 case 6:
+
4250 case 9:
+
4251 case 11:
+
4252 return 1 <= day && day <= 30;
+
4253 default:
+
4254 return false;
+
4255 }
+
4256 }
+
4257
+
4258 public:
+
4259 date_format_t format;
+
4260 std::shared_ptr<basic_integer<T>> day;
+
4261 std::shared_ptr<basic_integer<T>> month;
+
4262 std::shared_ptr<basic_integer<T>> year;
+
4263
+
4264 protected:
+
4265 int m_format_mask;
+
4266 std::shared_ptr<basic_set<T>> m_separator;
+
4267 std::shared_ptr<basic_parser<T>> m_space;
+
4268 };
+
4269
+
4270 using date = basic_date<char>;
+
4271 using wdate = basic_date<wchar_t>;
+
4272#ifdef _UNICODE
+
4273 using tdate = wdate;
+
4274#else
+
4275 using tdate = date;
+
4276#endif
+
4277 using sgml_date = basic_date<char>;
+
4278
+
4282 template <class T>
+
4283 class basic_time : public basic_parser<T>
+
4284 {
+
4285 public:
+
4286 basic_time(
+
4287 _In_ const std::shared_ptr<basic_integer10<T>>& _hour,
+
4288 _In_ const std::shared_ptr<basic_integer10<T>>& _minute,
+
4289 _In_ const std::shared_ptr<basic_integer10<T>>& _second,
+
4290 _In_ const std::shared_ptr<basic_integer10<T>>& _millisecond,
+
4291 _In_ const std::shared_ptr<basic_set<T>>& separator,
+
4292 _In_ const std::shared_ptr<basic_parser<T>>& millisecond_separator,
+
4293 _In_ const std::locale& locale = std::locale()) :
+
4294 basic_parser<T>(locale),
+
4295 hour(_hour),
+
4296 minute(_minute),
+
4297 second(_second),
+
4298 millisecond(_millisecond),
+
4299 m_separator(separator),
+
4300 m_millisecond_separator(millisecond_separator)
+
4301 {}
+
4302
+
4303 virtual bool match(
+
4304 _In_reads_or_z_(end) const T* text,
+
4305 _In_ size_t start = 0,
+
4306 _In_ size_t end = (size_t)-1,
+
4307 _In_ int flags = match_default)
+
4308 {
+
4309 assert(text || start >= end);
+
4310
+
4311 if (hour->match(text, start, end, flags) &&
+
4312 m_separator->match(text, hour->interval.end, end, flags) &&
+
4313 minute->match(text, m_separator->interval.end, end, flags) &&
+
4314 minute->value < 60)
+
4315 {
+
4316 // hh::mm
+
4317 size_t hit_offset = m_separator->hit_offset;
+
4318 if (m_separator->match(text, minute->interval.end, end, flags) &&
+
4319 m_separator->hit_offset == hit_offset && // Both separators must match.
+
4320 second && second->match(text, m_separator->interval.end, end, flags) &&
+
4321 second->value < 60)
+
4322 {
+
4323 // hh::mm:ss
+
4324 if (m_millisecond_separator && m_millisecond_separator->match(text, second->interval.end, end, flags) &&
+
4325 millisecond && millisecond->match(text, m_millisecond_separator->interval.end, end, flags) &&
+
4326 millisecond->value < 1000)
+
4327 {
+
4328 // hh::mm:ss.mmmm
+
4329 interval.end = millisecond->interval.end;
+
4330 }
+
4331 else {
+
4332 if (millisecond) millisecond->invalidate();
+
4333 interval.end = second->interval.end;
+
4334 }
+
4335 }
+
4336 else {
+
4337 if (second) second->invalidate();
+
4338 if (millisecond) millisecond->invalidate();
+
4339 interval.end = minute->interval.end;
+
4340 }
+
4341 interval.start = start;
+
4342 return true;
+
4343 }
+
4344
+
4345 hour->invalidate();
+
4346 minute->invalidate();
+
4347 if (second) second->invalidate();
+
4348 if (millisecond) millisecond->invalidate();
+
4349 interval.start = (interval.end = start) + 1;
+
4350 return false;
+
4351 }
+
4352
+
4353 virtual void invalidate()
+
4354 {
+
4355 hour->invalidate();
+
4356 minute->invalidate();
+
4357 if (second) second->invalidate();
+
4358 if (millisecond) millisecond->invalidate();
+
4359 basic_parser<T>::invalidate();
+
4360 }
+
4361
+
4362 public:
+
4363 std::shared_ptr<basic_integer10<T>> hour;
+
4364 std::shared_ptr<basic_integer10<T>> minute;
+
4365 std::shared_ptr<basic_integer10<T>> second;
+
4366 std::shared_ptr<basic_integer10<T>> millisecond;
+
4367
+
4368 protected:
+
4369 std::shared_ptr<basic_set<T>> m_separator;
+
4370 std::shared_ptr<basic_parser<T>> m_millisecond_separator;
+
4371 };
+
4372
+
4373 using time = basic_time<char>;
+
4374 using wtime = basic_time<wchar_t>;
+
4375#ifdef _UNICODE
+
4376 using ttime = wtime;
+
4377#else
+
4378 using ttime = time;
+
4379#endif
+
4380 using sgml_time = basic_time<char>;
+
4381
+
4385 template <class T>
+
4386 class basic_angle : public basic_parser<T>
+
4387 {
+
4388 public:
+
4389 basic_angle(
+
4390 _In_ const std::shared_ptr<basic_integer10<T>>& _degree,
+
4391 _In_ const std::shared_ptr<basic_parser<T>>& _degree_separator,
+
4392 _In_ const std::shared_ptr<basic_integer10<T>>& _minute,
+
4393 _In_ const std::shared_ptr<basic_parser<T>>& _minute_separator,
+
4394 _In_ const std::shared_ptr<basic_integer10<T>>& _second,
+
4395 _In_ const std::shared_ptr<basic_parser<T>>& _second_separator,
+
4396 _In_ const std::shared_ptr<basic_parser<T>>& _decimal,
+
4397 _In_ const std::locale& locale = std::locale()) :
+
4398 basic_parser<T>(locale),
+
4399 degree(_degree),
+
4400 degree_separator(_degree_separator),
+
4401 minute(_minute),
+
4402 minute_separator(_minute_separator),
+
4403 second(_second),
+
4404 second_separator(_second_separator),
+
4405 decimal(_decimal)
+
4406 {}
+
4407
+
4408 virtual bool match(
+
4409 _In_reads_or_z_(end) const T* text,
+
4410 _In_ size_t start = 0,
+
4411 _In_ size_t end = (size_t)-1,
+
4412 _In_ int flags = match_default)
+
4413 {
+
4414 assert(text || start >= end);
+
4415
+
4416 interval.end = start;
+
4417
+
4418 if (degree->match(text, interval.end, end, flags) &&
+
4419 degree_separator->match(text, degree->interval.end, end, flags))
+
4420 {
+
4421 // Degrees
+
4422 interval.end = degree_separator->interval.end;
+
4423 }
+
4424 else {
+
4425 degree->invalidate();
+
4426 degree_separator->invalidate();
+
4427 }
+
4428
+
4429 if (minute->match(text, interval.end, end, flags) &&
+
4430 minute->value < 60 &&
+
4431 minute_separator->match(text, minute->interval.end, end, flags))
+
4432 {
+
4433 // Minutes
+
4434 interval.end = minute_separator->interval.end;
+
4435 }
+
4436 else {
+
4437 minute->invalidate();
+
4438 minute_separator->invalidate();
+
4439 }
+
4440
+
4441 if (second && second->match(text, interval.end, end, flags) &&
+
4442 second->value < 60)
+
4443 {
+
4444 // Seconds
+
4445 interval.end = second->interval.end;
+
4446 if (second_separator && second_separator->match(text, interval.end, end, flags))
+
4447 interval.end = second_separator->interval.end;
+
4448 else
+
4449 if (second_separator) second_separator->invalidate();
4450 }
-
4451 if (decimal) decimal->invalidate();
-
4452 interval.start = (interval.end = start) + 1;
-
4453 return false;
-
4454 }
+
4451 else {
+
4452 if (second) second->invalidate();
+
4453 if (second_separator) second_separator->invalidate();
+
4454 }
4455
-
4456 virtual void invalidate()
-
4457 {
-
4458 degree->invalidate();
-
4459 degree_separator->invalidate();
-
4460 minute->invalidate();
-
4461 minute_separator->invalidate();
-
4462 if (second) second->invalidate();
-
4463 if (second_separator) second_separator->invalidate();
-
4464 if (decimal) decimal->invalidate();
-
4465 basic_parser<T>::invalidate();
-
4466 }
-
4467
-
4468 public:
-
4469 std::shared_ptr<basic_integer10<T>> degree;
-
4470 std::shared_ptr<basic_parser<T>> degree_separator;
-
4471 std::shared_ptr<basic_integer10<T>> minute;
-
4472 std::shared_ptr<basic_parser<T>> minute_separator;
-
4473 std::shared_ptr<basic_integer10<T>> second;
-
4474 std::shared_ptr<basic_parser<T>> second_separator;
-
4475 std::shared_ptr<basic_parser<T>> decimal;
-
4476 };
-
4477
-
4478 using angle = basic_angle<char>;
-
4479 using wangle = basic_angle<wchar_t>;
-
4480#ifdef _UNICODE
-
4481 using RRegElKot = wangle;
-
4482#else
-
4483 using RRegElKot = angle;
-
4484#endif
-
4485 using sgml_angle = basic_angle<char>;
-
4486
-
4490 template <class T>
-
4491 class basic_phone_number : public basic_parser<T>
-
4492 {
-
4493 public:
-
4494 basic_phone_number(
-
4495 _In_ const std::shared_ptr<basic_parser<T>>& digit,
-
4496 _In_ const std::shared_ptr<basic_parser<T>>& plus_sign,
-
4497 _In_ const std::shared_ptr<basic_set<T>>& lparenthesis,
-
4498 _In_ const std::shared_ptr<basic_set<T>>& rparenthesis,
-
4499 _In_ const std::shared_ptr<basic_parser<T>>& separator,
-
4500 _In_ const std::shared_ptr<basic_parser<T>>& space,
-
4501 _In_ const std::locale& locale = std::locale()) :
-
4502 basic_parser<T>(locale),
-
4503 m_digit(digit),
-
4504 m_plus_sign(plus_sign),
-
4505 m_lparenthesis(lparenthesis),
-
4506 m_rparenthesis(rparenthesis),
-
4507 m_separator(separator),
-
4508 m_space(space)
-
4509 {}
-
4510
-
4511 virtual bool match(
-
4512 _In_reads_or_z_(end) const T* text,
-
4513 _In_ size_t start = 0,
-
4514 _In_ size_t end = (size_t)-1,
-
4515 _In_ int flags = match_default)
-
4516 {
-
4517 assert(text || start >= end);
-
4518
-
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; // Spaces in phone numbers must never be broken in new line.
-
4522
-
4523 interval.end = start;
-
4524 value.clear();
-
4525 m_lparenthesis->invalidate();
-
4526 m_rparenthesis->invalidate();
-
4527
-
4528 if (m_plus_sign && m_plus_sign->match(text, interval.end, end, flags)) {
-
4529 value.append(text + m_plus_sign->interval.start, text + m_plus_sign->interval.end);
-
4530 safe_value_size = value.size();
-
4531 interval.end = m_plus_sign->interval.end;
-
4532 }
-
4533
-
4534 for (;;) {
-
4535 assert(text || interval.end >= end);
-
4536 if (interval.end >= end || !text[interval.end])
-
4537 break;
-
4538 if (m_digit->match(text, interval.end, end, flags)) {
-
4539 // Digit
-
4540 value.append(text + m_digit->interval.start, text + m_digit->interval.end);
-
4541 interval.end = m_digit->interval.end;
-
4542 if (!in_parentheses) {
-
4543 safe_digit_end = interval.end;
-
4544 safe_value_size = value.size();
-
4545 has_digits = true;
-
4546 }
-
4547 after_digit = true;
-
4548 after_parentheses = false;
-
4549 }
-
4550 else if (
-
4551 m_lparenthesis && !m_lparenthesis->interval && // No left parenthesis yet
-
4552 m_rparenthesis && !m_rparenthesis->interval && // Right parenthesis after left
-
4553 m_lparenthesis->match(text, interval.end, end, flags))
-
4554 {
-
4555 // Left parenthesis
-
4556 value.Prilepi(text + m_lparenthesis->interval.start, m_lparenthesis->interval.size());
-
4557 interval.end = m_lparenthesis->interval.end;
-
4558 in_parentheses = true;
-
4559 after_digit = false;
-
4560 after_parentheses = false;
-
4561 }
-
4562 else if (
-
4563 in_parentheses && // After left parenthesis
-
4564 m_rparenthesis && !m_rparenthesis->interval && // No right parenthesis yet
-
4565 m_rparenthesis->match(text, interval.end, end, flags) &&
-
4566 m_lparenthesis->hit_offset == m_rparenthesis->hit_offset) // Left and right parentheses must match
-
4567 {
-
4568 // Right parenthesis
-
4569 value.append(text + m_rparenthesis->interval.start, text + m_rparenthesis->interval.end);
-
4570 interval.end = m_rparenthesis->interval.end;
-
4571 safe_digit_end = interval.end;
-
4572 safe_value_size = value.size();
-
4573 in_parentheses = false;
-
4574 after_digit = false;
-
4575 after_parentheses = true;
-
4576 }
-
4577 else if (
-
4578 after_digit &&
-
4579 !in_parentheses && // No separators inside parentheses
-
4580 !after_parentheses && // No separators following right parenthesis
-
4581 m_separator && m_separator->match(text, interval.end, end, flags))
-
4582 {
-
4583 // Separator
-
4584 interval.end = m_separator->interval.end;
-
4585 after_digit = false;
-
4586 after_parentheses = false;
-
4587 }
-
4588 else if (
-
4589 (after_digit || after_parentheses) &&
-
4590 m_space && m_space->match(text, interval.end, end, space_match_flags))
-
4591 {
-
4592 // Space
-
4593 interval.end = m_space->interval.end;
-
4594 after_digit = false;
-
4595 after_parentheses = false;
-
4596 }
-
4597 else
-
4598 break;
-
4599 }
-
4600 if (has_digits) {
-
4601 value.erase(safe_value_size);
-
4602 interval.start = start;
-
4603 interval.end = safe_digit_end;
-
4604 return true;
-
4605 }
-
4606 value.clear();
-
4607 interval.start = (interval.end = start) + 1;
-
4608 return false;
-
4609 }
-
4610
-
4611 virtual void invalidate()
-
4612 {
-
4613 value.clear();
-
4614 basic_parser<T>::invalidate();
-
4615 }
-
4616
-
4617 public:
-
4618 std::basic_string<T> value;
-
4619
-
4620 protected:
-
4621 std::shared_ptr<basic_parser<T>> m_digit;
-
4622 std::shared_ptr<basic_parser<T>> m_plus_sign;
-
4623 std::shared_ptr<basic_set<T>> m_lparenthesis;
-
4624 std::shared_ptr<basic_set<T>> m_rparenthesis;
-
4625 std::shared_ptr<basic_parser<T>> m_separator;
-
4626 std::shared_ptr<basic_parser<T>> m_space;
-
4627 };
+
4456 if (degree->interval.start < degree->interval.end ||
+
4457 minute->interval.start < minute->interval.end ||
+
4458 second && second->interval.start < second->interval.end)
+
4459 {
+
4460 if (decimal && decimal->match(text, interval.end, end, flags)) {
+
4461 // Decimals
+
4462 interval.end = decimal->interval.end;
+
4463 }
+
4464 else if (decimal)
+
4465 decimal->invalidate();
+
4466 interval.start = start;
+
4467 return true;
+
4468 }
+
4469 if (decimal) decimal->invalidate();
+
4470 interval.start = (interval.end = start) + 1;
+
4471 return false;
+
4472 }
+
4473
+
4474 virtual void invalidate()
+
4475 {
+
4476 degree->invalidate();
+
4477 degree_separator->invalidate();
+
4478 minute->invalidate();
+
4479 minute_separator->invalidate();
+
4480 if (second) second->invalidate();
+
4481 if (second_separator) second_separator->invalidate();
+
4482 if (decimal) decimal->invalidate();
+
4483 basic_parser<T>::invalidate();
+
4484 }
+
4485
+
4486 public:
+
4487 std::shared_ptr<basic_integer10<T>> degree;
+
4488 std::shared_ptr<basic_parser<T>> degree_separator;
+
4489 std::shared_ptr<basic_integer10<T>> minute;
+
4490 std::shared_ptr<basic_parser<T>> minute_separator;
+
4491 std::shared_ptr<basic_integer10<T>> second;
+
4492 std::shared_ptr<basic_parser<T>> second_separator;
+
4493 std::shared_ptr<basic_parser<T>> decimal;
+
4494 };
+
4495
+
4496 using angle = basic_angle<char>;
+
4497 using wangle = basic_angle<wchar_t>;
+
4498#ifdef _UNICODE
+
4499 using RRegElKot = wangle;
+
4500#else
+
4501 using RRegElKot = angle;
+
4502#endif
+
4503 using sgml_angle = basic_angle<char>;
+
4504
+
4508 template <class T>
+
4509 class basic_phone_number : public basic_parser<T>
+
4510 {
+
4511 public:
+
4512 basic_phone_number(
+
4513 _In_ const std::shared_ptr<basic_parser<T>>& digit,
+
4514 _In_ const std::shared_ptr<basic_parser<T>>& plus_sign,
+
4515 _In_ const std::shared_ptr<basic_set<T>>& lparenthesis,
+
4516 _In_ const std::shared_ptr<basic_set<T>>& rparenthesis,
+
4517 _In_ const std::shared_ptr<basic_parser<T>>& separator,
+
4518 _In_ const std::shared_ptr<basic_parser<T>>& space,
+
4519 _In_ const std::locale& locale = std::locale()) :
+
4520 basic_parser<T>(locale),
+
4521 m_digit(digit),
+
4522 m_plus_sign(plus_sign),
+
4523 m_lparenthesis(lparenthesis),
+
4524 m_rparenthesis(rparenthesis),
+
4525 m_separator(separator),
+
4526 m_space(space)
+
4527 {}
+
4528
+
4529 virtual bool match(
+
4530 _In_reads_or_z_(end) const T* text,
+
4531 _In_ size_t start = 0,
+
4532 _In_ size_t end = (size_t)-1,
+
4533 _In_ int flags = match_default)
+
4534 {
+
4535 assert(text || start >= end);
+
4536
+
4537 size_t safe_digit_end = start, safe_value_size = 0;
+
4538 bool has_digits = false, after_digit = false, in_parentheses = false, after_parentheses = false;
+
4539 const int space_match_flags = flags & ~match_multiline; // Spaces in phone numbers must never be broken in new line.
+
4540
+
4541 interval.end = start;
+
4542 value.clear();
+
4543 m_lparenthesis->invalidate();
+
4544 m_rparenthesis->invalidate();
+
4545
+
4546 if (m_plus_sign && m_plus_sign->match(text, interval.end, end, flags)) {
+
4547 value.append(text + m_plus_sign->interval.start, text + m_plus_sign->interval.end);
+
4548 safe_value_size = value.size();
+
4549 interval.end = m_plus_sign->interval.end;
+
4550 }
+
4551
+
4552 for (;;) {
+
4553 assert(text || interval.end >= end);
+
4554 if (interval.end >= end || !text[interval.end])
+
4555 break;
+
4556 if (m_digit->match(text, interval.end, end, flags)) {
+
4557 // Digit
+
4558 value.append(text + m_digit->interval.start, text + m_digit->interval.end);
+
4559 interval.end = m_digit->interval.end;
+
4560 if (!in_parentheses) {
+
4561 safe_digit_end = interval.end;
+
4562 safe_value_size = value.size();
+
4563 has_digits = true;
+
4564 }
+
4565 after_digit = true;
+
4566 after_parentheses = false;
+
4567 }
+
4568 else if (
+
4569 m_lparenthesis && !m_lparenthesis->interval && // No left parenthesis yet
+
4570 m_rparenthesis && !m_rparenthesis->interval && // Right parenthesis after left
+
4571 m_lparenthesis->match(text, interval.end, end, flags))
+
4572 {
+
4573 // Left parenthesis
+
4574 value.append(text + m_lparenthesis->interval.start, m_lparenthesis->interval.size());
+
4575 interval.end = m_lparenthesis->interval.end;
+
4576 in_parentheses = true;
+
4577 after_digit = false;
+
4578 after_parentheses = false;
+
4579 }
+
4580 else if (
+
4581 in_parentheses && // After left parenthesis
+
4582 m_rparenthesis && !m_rparenthesis->interval && // No right parenthesis yet
+
4583 m_rparenthesis->match(text, interval.end, end, flags) &&
+
4584 m_lparenthesis->hit_offset == m_rparenthesis->hit_offset) // Left and right parentheses must match
+
4585 {
+
4586 // Right parenthesis
+
4587 value.append(text + m_rparenthesis->interval.start, text + m_rparenthesis->interval.end);
+
4588 interval.end = m_rparenthesis->interval.end;
+
4589 safe_digit_end = interval.end;
+
4590 safe_value_size = value.size();
+
4591 in_parentheses = false;
+
4592 after_digit = false;
+
4593 after_parentheses = true;
+
4594 }
+
4595 else if (
+
4596 after_digit &&
+
4597 !in_parentheses && // No separators inside parentheses
+
4598 !after_parentheses && // No separators following right parenthesis
+
4599 m_separator && m_separator->match(text, interval.end, end, flags))
+
4600 {
+
4601 // Separator
+
4602 interval.end = m_separator->interval.end;
+
4603 after_digit = false;
+
4604 after_parentheses = false;
+
4605 }
+
4606 else if (
+
4607 (after_digit || after_parentheses) &&
+
4608 m_space && m_space->match(text, interval.end, end, space_match_flags))
+
4609 {
+
4610 // Space
+
4611 interval.end = m_space->interval.end;
+
4612 after_digit = false;
+
4613 after_parentheses = false;
+
4614 }
+
4615 else
+
4616 break;
+
4617 }
+
4618 if (has_digits) {
+
4619 value.erase(safe_value_size);
+
4620 interval.start = start;
+
4621 interval.end = safe_digit_end;
+
4622 return true;
+
4623 }
+
4624 value.clear();
+
4625 interval.start = (interval.end = start) + 1;
+
4626 return false;
+
4627 }
4628
-
4629 using phone_number = basic_phone_number<char>;
-
4630 using wphone_number = basic_phone_number<wchar_t>;
-
4631#ifdef _UNICODE
-
4632 using tphone_number = wphone_number;
-
4633#else
-
4634 using tphone_number = phone_number;
-
4635#endif
-
4636 using sgml_phone_number = basic_phone_number<char>;
+
4629 virtual void invalidate()
+
4630 {
+
4631 value.clear();
+
4632 basic_parser<T>::invalidate();
+
4633 }
+
4634
+
4635 public:
+
4636 std::basic_string<T> value;
4637
-
4641 template <class T>
-
4642 class basic_chemical_formula : public basic_parser<T>
-
4643 {
-
4644 public:
-
4645 basic_chemical_formula(
-
4646 _In_ const std::shared_ptr<basic_parser<T>>& element,
-
4647 _In_ const std::shared_ptr<basic_parser<T>>& digit,
-
4648 _In_ const std::shared_ptr<basic_parser<T>>& sign,
-
4649 _In_ const std::locale& locale = std::locale()) :
-
4650 basic_parser<T>(locale),
-
4651 m_element(element),
-
4652 m_digit(digit),
-
4653 m_sign(sign),
-
4654 has_digits(false),
-
4655 has_charge(false)
-
4656 {}
-
4657
-
4658 virtual bool match(
-
4659 _In_reads_or_z_(end) const T* text,
-
4660 _In_ size_t start = 0,
-
4661 _In_ size_t end = (size_t)-1,
-
4662 _In_ int flags = match_default)
-
4663 {
-
4664 assert(text || start >= end);
-
4665
-
4666 has_digits = false;
-
4667 has_charge = false;
-
4668 interval.end = start;
-
4669
-
4670 const int element_match_flags = flags & ~match_case_insensitive; // Chemical elements are always case-sensitive.
-
4671 for (;;) {
-
4672 if (m_element->match(text, interval.end, end, element_match_flags)) {
-
4673 interval.end = m_element->interval.end;
-
4674 while (m_digit->match(text, interval.end, end, flags)) {
-
4675 interval.end = m_digit->interval.end;
-
4676 has_digits = true;
-
4677 }
-
4678 }
-
4679 else if (start < interval.end) {
-
4680 if (m_sign->match(text, interval.end, end, flags)) {
-
4681 interval.end = m_sign->interval.end;
-
4682 has_charge = true;
-
4683 }
-
4684 interval.start = start;
-
4685 return true;
-
4686 }
-
4687 else {
-
4688 interval.start = (interval.end = start) + 1;
-
4689 return false;
-
4690 }
-
4691 }
-
4692 }
-
4693
-
4694 virtual void invalidate()
-
4695 {
-
4696 has_digits = false;
-
4697 has_charge = false;
-
4698 basic_parser<T>::invalidate();
-
4699 }
-
4700
-
4701 public:
-
4702 bool has_digits;
-
4703 bool has_charge;
-
4704
-
4705 protected:
-
4706 std::shared_ptr<basic_parser<T>> m_element;
-
4707 std::shared_ptr<basic_parser<T>> m_digit;
-
4708 std::shared_ptr<basic_parser<T>> m_sign;
-
4709 };
-
4710
-
4711 using chemical_formula = basic_chemical_formula<char>;
-
4712 using wchemical_formula = basic_chemical_formula<wchar_t>;
-
4713#ifdef _UNICODE
-
4714 using tchemical_formula = wchemical_formula;
-
4715#else
-
4716 using tchemical_formula = chemical_formula;
-
4717#endif
-
4718 using sgml_chemical_formula = basic_chemical_formula<char>;
-
4719
-
4723 class http_line_break : public parser
-
4724 {
-
4725 public:
-
4726 virtual bool match(
-
4727 _In_reads_or_z_(end) const char* text,
-
4728 _In_ size_t start = 0,
-
4729 _In_ size_t end = (size_t)-1,
-
4730 _In_ int flags = match_default)
-
4731 {
-
4732 assert(text || start >= end);
-
4733 interval.end = start;
-
4734
-
4735 assert(text || interval.end >= end);
-
4736 if (interval.end < end && text[interval.end]) {
-
4737 if (text[interval.end] == '\r') {
-
4738 interval.end++;
-
4739 if (interval.end < end && text[interval.end] == '\n') {
-
4740 interval.start = start;
-
4741 interval.end++;
-
4742 return true;
-
4743 }
-
4744 }
-
4745 else if (text[interval.end] == '\n') {
-
4746 interval.start = start;
-
4747 interval.end++;
-
4748 return true;
-
4749 }
-
4750 }
-
4751 interval.start = (interval.end = start) + 1;
-
4752 return false;
-
4753 }
-
4754 };
-
4755
-
4759 class http_space : public parser
-
4760 {
-
4761 public:
-
4762 virtual bool match(
-
4763 _In_reads_or_z_(end) const char* text,
-
4764 _In_ size_t start = 0,
-
4765 _In_ size_t end = (size_t)-1,
-
4766 _In_ int flags = match_default)
-
4767 {
-
4768 assert(text || start >= end);
-
4769 interval.end = start;
-
4770 if (m_line_break.match(text, interval.end, end, flags)) {
-
4771 interval.end = m_line_break.interval.end;
-
4772 if (interval.end < end && text[interval.end] && isspace(text[interval.end])) {
-
4773 interval.start = start;
-
4774 interval.end++;
-
4775 while (interval.end < end && text[interval.end] && isspace(text[interval.end])) interval.end++;
-
4776 return true;
-
4777 }
-
4778 }
-
4779 else if (interval.end < end && text[interval.end] && isspace(text[interval.end])) {
-
4780 interval.start = start;
-
4781 interval.end++;
-
4782 while (interval.end < end && text[interval.end] && isspace(text[interval.end])) interval.end++;
-
4783 return true;
-
4784 }
-
4785 interval.start = (interval.end = start) + 1;
-
4786 return false;
-
4787 }
-
4788
-
4789 protected:
-
4790 http_line_break m_line_break;
-
4791 };
-
4792
-
4796 class http_text_char : public parser
-
4797 {
-
4798 public:
-
4799 virtual bool match(
-
4800 _In_reads_or_z_(end) const char* text,
-
4801 _In_ size_t start = 0,
-
4802 _In_ size_t end = (size_t)-1,
-
4803 _In_ int flags = match_default)
-
4804 {
-
4805 assert(text || start >= end);
-
4806 interval.end = start;
-
4807
-
4808 assert(text || interval.end >= end);
-
4809 if (m_space.match(text, interval.end, end, flags)) {
-
4810 interval.start = start;
-
4811 interval.end = m_space.interval.end;
-
4812 return true;
-
4813 }
-
4814 else if (interval.end < end && text[interval.end] && text[interval.end] >= 0x20) {
-
4815 interval.start = start;
-
4816 interval.end++;
-
4817 return true;
-
4818 }
-
4819 interval.start = (interval.end = start) + 1;
-
4820 return false;
-
4821 }
-
4822
-
4823 protected:
-
4824 http_space m_space;
-
4825 };
-
4826
-
4830 class http_token : public parser
-
4831 {
-
4832 public:
-
4833 virtual bool match(
-
4834 _In_reads_or_z_(end) const char* text,
-
4835 _In_ size_t start = 0,
-
4836 _In_ size_t end = (size_t)-1,
-
4837 _In_ int flags = match_default)
-
4838 {
-
4839 assert(text || start >= end);
-
4840 interval.end = start;
-
4841 for (;;) {
-
4842 if (interval.end < end && text[interval.end]) {
-
4843 if ((unsigned int)text[interval.end] < 0x20 ||
-
4844 (unsigned int)text[interval.end] == 0x7f ||
-
4845 text[interval.end] == '(' ||
-
4846 text[interval.end] == ')' ||
-
4847 text[interval.end] == '<' ||
-
4848 text[interval.end] == '>' ||
-
4849 text[interval.end] == '@' ||
-
4850 text[interval.end] == ',' ||
-
4851 text[interval.end] == ';' ||
-
4852 text[interval.end] == ':' ||
-
4853 text[interval.end] == '\\' ||
-
4854 text[interval.end] == '\"' ||
-
4855 text[interval.end] == '/' ||
-
4856 text[interval.end] == '[' ||
-
4857 text[interval.end] == ']' ||
-
4858 text[interval.end] == '?' ||
-
4859 text[interval.end] == '=' ||
-
4860 text[interval.end] == '{' ||
-
4861 text[interval.end] == '}' ||
-
4862 isspace(text[interval.end]))
-
4863 break;
-
4864 else
-
4865 interval.end++;
-
4866 }
-
4867 else
-
4868 break;
-
4869 }
-
4870 if (start < interval.end) {
-
4871 interval.start = start;
-
4872 return true;
-
4873 }
-
4874 else {
-
4875 interval.start = (interval.end = start) + 1;
-
4876 return false;
-
4877 }
-
4878 }
-
4879 };
-
4880
-
4884 class http_quoted_string : public parser
-
4885 {
-
4886 public:
-
4887 virtual bool match(
-
4888 _In_reads_or_z_(end) const char* text,
-
4889 _In_ size_t start = 0,
-
4890 _In_ size_t end = (size_t)-1,
-
4891 _In_ int flags = match_default)
-
4892 {
-
4893 assert(text || start >= end);
-
4894 interval.end = start;
-
4895 if (interval.end < end && text[interval.end] != '"')
-
4896 goto error;
-
4897 interval.end++;
-
4898 content.start = interval.end;
-
4899 for (;;) {
-
4900 assert(text || interval.end >= end);
-
4901 if (interval.end < end && text[interval.end]) {
-
4902 if (text[interval.end] == '"') {
-
4903 content.end = interval.end;
-
4904 interval.end++;
-
4905 break;
-
4906 }
-
4907 else if (text[interval.end] == '\\') {
-
4908 interval.end++;
-
4909 if (interval.end < end && text[interval.end]) {
-
4910 interval.end++;
-
4911 }
-
4912 else
-
4913 goto error;
-
4914 }
-
4915 else if (m_chr.match(text, interval.end, end, flags))
-
4916 interval.end++;
-
4917 else
-
4918 goto error;
-
4919 }
-
4920 else
-
4921 goto error;
-
4922 }
-
4923 interval.start = start;
-
4924 return true;
-
4925
-
4926 error:
-
4927 content.start = 1;
-
4928 content.end = 0;
-
4929 interval.start = (interval.end = start) + 1;
-
4930 return false;
-
4931 }
-
4932
-
4933 virtual void invalidate()
-
4934 {
-
4935 content.start = 1;
-
4936 content.end = 0;
-
4937 parser::invalidate();
-
4938 }
-
4939
-
4940 public:
-
4941 stdex::interval<size_t> content;
-
4942
-
4943 protected:
-
4944 http_text_char m_chr;
-
4945 };
-
4946
-
4950 class http_value : public parser
-
4951 {
-
4952 public:
-
4953 virtual bool match(
-
4954 _In_reads_or_z_(end) const char* text,
-
4955 _In_ size_t start = 0,
-
4956 _In_ size_t end = (size_t)-1,
-
4957 _In_ int flags = match_default)
-
4958 {
-
4959 assert(text || start >= end);
-
4960 interval.end = start;
-
4961 if (string.match(text, interval.end, end, flags)) {
-
4962 token.invalidate();
-
4963 interval.end = string.interval.end;
-
4964 interval.start = start;
-
4965 return true;
-
4966 }
-
4967 else if (token.match(text, interval.end, end, flags)) {
-
4968 string.invalidate();
-
4969 interval.end = token.interval.end;
-
4970 interval.start = start;
-
4971 return true;
-
4972 }
-
4973 else {
-
4974 interval.start = (interval.end = start) + 1;
-
4975 return false;
-
4976 }
-
4977 }
-
4978
-
4979 virtual void invalidate()
-
4980 {
-
4981 string.invalidate();
-
4982 token.invalidate();
-
4983 parser::invalidate();
-
4984 }
-
4985
-
4986 public:
-
4987 http_quoted_string string;
-
4988 http_token token;
-
4989 };
-
4990
-
4994 class http_parameter : public parser
-
4995 {
-
4996 public:
-
4997 virtual bool match(
-
4998 _In_reads_or_z_(end) const char* text,
-
4999 _In_ size_t start = 0,
-
5000 _In_ size_t end = (size_t)-1,
-
5001 _In_ int flags = match_default)
-
5002 {
-
5003 assert(text || start >= end);
-
5004 interval.end = start;
-
5005 if (name.match(text, interval.end, end, flags))
-
5006 interval.end = name.interval.end;
-
5007 else
-
5008 goto error;
-
5009 while (m_space.match(text, interval.end, end, flags))
-
5010 interval.end = m_space.interval.end;
-
5011 assert(text || interval.end >= end);
-
5012 if (interval.end < end && text[interval.end] == '=')
-
5013 interval.end++;
-
5014 else
-
5015 while (m_space.match(text, interval.end, end, flags))
-
5016 interval.end = m_space.interval.end;
-
5017 if (value.match(text, interval.end, end, flags))
-
5018 interval.end = value.interval.end;
-
5019 else
-
5020 goto error;
-
5021 interval.start = start;
-
5022 return true;
-
5023
-
5024 error:
-
5025 name.invalidate();
-
5026 value.invalidate();
-
5027 interval.start = (interval.end = start) + 1;
-
5028 return false;
-
5029 }
-
5030
-
5031 virtual void invalidate()
-
5032 {
-
5033 name.invalidate();
-
5034 value.invalidate();
-
5035 parser::invalidate();
-
5036 }
-
5037
-
5038 public:
-
5039 http_token name;
-
5040 http_value value;
+
4638 protected:
+
4639 std::shared_ptr<basic_parser<T>> m_digit;
+
4640 std::shared_ptr<basic_parser<T>> m_plus_sign;
+
4641 std::shared_ptr<basic_set<T>> m_lparenthesis;
+
4642 std::shared_ptr<basic_set<T>> m_rparenthesis;
+
4643 std::shared_ptr<basic_parser<T>> m_separator;
+
4644 std::shared_ptr<basic_parser<T>> m_space;
+
4645 };
+
4646
+
4647 using phone_number = basic_phone_number<char>;
+
4648 using wphone_number = basic_phone_number<wchar_t>;
+
4649#ifdef _UNICODE
+
4650 using tphone_number = wphone_number;
+
4651#else
+
4652 using tphone_number = phone_number;
+
4653#endif
+
4654 using sgml_phone_number = basic_phone_number<char>;
+
4655
+
4659 template <class T>
+
4660 class basic_chemical_formula : public basic_parser<T>
+
4661 {
+
4662 public:
+
4663 basic_chemical_formula(
+
4664 _In_ const std::shared_ptr<basic_parser<T>>& element,
+
4665 _In_ const std::shared_ptr<basic_parser<T>>& digit,
+
4666 _In_ const std::shared_ptr<basic_parser<T>>& sign,
+
4667 _In_ const std::locale& locale = std::locale()) :
+
4668 basic_parser<T>(locale),
+
4669 m_element(element),
+
4670 m_digit(digit),
+
4671 m_sign(sign),
+
4672 has_digits(false),
+
4673 has_charge(false)
+
4674 {}
+
4675
+
4676 virtual bool match(
+
4677 _In_reads_or_z_(end) const T* text,
+
4678 _In_ size_t start = 0,
+
4679 _In_ size_t end = (size_t)-1,
+
4680 _In_ int flags = match_default)
+
4681 {
+
4682 assert(text || start >= end);
+
4683
+
4684 has_digits = false;
+
4685 has_charge = false;
+
4686 interval.end = start;
+
4687
+
4688 const int element_match_flags = flags & ~match_case_insensitive; // Chemical elements are always case-sensitive.
+
4689 for (;;) {
+
4690 if (m_element->match(text, interval.end, end, element_match_flags)) {
+
4691 interval.end = m_element->interval.end;
+
4692 while (m_digit->match(text, interval.end, end, flags)) {
+
4693 interval.end = m_digit->interval.end;
+
4694 has_digits = true;
+
4695 }
+
4696 }
+
4697 else if (start < interval.end) {
+
4698 if (m_sign->match(text, interval.end, end, flags)) {
+
4699 interval.end = m_sign->interval.end;
+
4700 has_charge = true;
+
4701 }
+
4702 interval.start = start;
+
4703 return true;
+
4704 }
+
4705 else {
+
4706 interval.start = (interval.end = start) + 1;
+
4707 return false;
+
4708 }
+
4709 }
+
4710 }
+
4711
+
4712 virtual void invalidate()
+
4713 {
+
4714 has_digits = false;
+
4715 has_charge = false;
+
4716 basic_parser<T>::invalidate();
+
4717 }
+
4718
+
4719 public:
+
4720 bool has_digits;
+
4721 bool has_charge;
+
4722
+
4723 protected:
+
4724 std::shared_ptr<basic_parser<T>> m_element;
+
4725 std::shared_ptr<basic_parser<T>> m_digit;
+
4726 std::shared_ptr<basic_parser<T>> m_sign;
+
4727 };
+
4728
+
4729 using chemical_formula = basic_chemical_formula<char>;
+
4730 using wchemical_formula = basic_chemical_formula<wchar_t>;
+
4731#ifdef _UNICODE
+
4732 using tchemical_formula = wchemical_formula;
+
4733#else
+
4734 using tchemical_formula = chemical_formula;
+
4735#endif
+
4736 using sgml_chemical_formula = basic_chemical_formula<char>;
+
4737
+
4741 class http_line_break : public parser
+
4742 {
+
4743 public:
+
4744 virtual bool match(
+
4745 _In_reads_or_z_(end) const char* text,
+
4746 _In_ size_t start = 0,
+
4747 _In_ size_t end = (size_t)-1,
+
4748 _In_ int flags = match_default)
+
4749 {
+
4750 assert(text || start >= end);
+
4751 interval.end = start;
+
4752
+
4753 assert(text || interval.end >= end);
+
4754 if (interval.end < end && text[interval.end]) {
+
4755 if (text[interval.end] == '\r') {
+
4756 interval.end++;
+
4757 if (interval.end < end && text[interval.end] == '\n') {
+
4758 interval.start = start;
+
4759 interval.end++;
+
4760 return true;
+
4761 }
+
4762 }
+
4763 else if (text[interval.end] == '\n') {
+
4764 interval.start = start;
+
4765 interval.end++;
+
4766 return true;
+
4767 }
+
4768 }
+
4769 interval.start = (interval.end = start) + 1;
+
4770 return false;
+
4771 }
+
4772 };
+
4773
+
4777 class http_space : public parser
+
4778 {
+
4779 public:
+
4780 virtual bool match(
+
4781 _In_reads_or_z_(end) const char* text,
+
4782 _In_ size_t start = 0,
+
4783 _In_ size_t end = (size_t)-1,
+
4784 _In_ int flags = match_default)
+
4785 {
+
4786 assert(text || start >= end);
+
4787 interval.end = start;
+
4788 if (m_line_break.match(text, interval.end, end, flags)) {
+
4789 interval.end = m_line_break.interval.end;
+
4790 if (interval.end < end && text[interval.end] && isspace(text[interval.end])) {
+
4791 interval.start = start;
+
4792 interval.end++;
+
4793 while (interval.end < end && text[interval.end] && isspace(text[interval.end])) interval.end++;
+
4794 return true;
+
4795 }
+
4796 }
+
4797 else if (interval.end < end && text[interval.end] && isspace(text[interval.end])) {
+
4798 interval.start = start;
+
4799 interval.end++;
+
4800 while (interval.end < end && text[interval.end] && isspace(text[interval.end])) interval.end++;
+
4801 return true;
+
4802 }
+
4803 interval.start = (interval.end = start) + 1;
+
4804 return false;
+
4805 }
+
4806
+
4807 protected:
+
4808 http_line_break m_line_break;
+
4809 };
+
4810
+
4814 class http_text_char : public parser
+
4815 {
+
4816 public:
+
4817 virtual bool match(
+
4818 _In_reads_or_z_(end) const char* text,
+
4819 _In_ size_t start = 0,
+
4820 _In_ size_t end = (size_t)-1,
+
4821 _In_ int flags = match_default)
+
4822 {
+
4823 assert(text || start >= end);
+
4824 interval.end = start;
+
4825
+
4826 assert(text || interval.end >= end);
+
4827 if (m_space.match(text, interval.end, end, flags)) {
+
4828 interval.start = start;
+
4829 interval.end = m_space.interval.end;
+
4830 return true;
+
4831 }
+
4832 else if (interval.end < end && text[interval.end] && text[interval.end] >= 0x20) {
+
4833 interval.start = start;
+
4834 interval.end++;
+
4835 return true;
+
4836 }
+
4837 interval.start = (interval.end = start) + 1;
+
4838 return false;
+
4839 }
+
4840
+
4841 protected:
+
4842 http_space m_space;
+
4843 };
+
4844
+
4848 class http_token : public parser
+
4849 {
+
4850 public:
+
4851 virtual bool match(
+
4852 _In_reads_or_z_(end) const char* text,
+
4853 _In_ size_t start = 0,
+
4854 _In_ size_t end = (size_t)-1,
+
4855 _In_ int flags = match_default)
+
4856 {
+
4857 assert(text || start >= end);
+
4858 interval.end = start;
+
4859 for (;;) {
+
4860 if (interval.end < end && text[interval.end]) {
+
4861 if ((unsigned int)text[interval.end] < 0x20 ||
+
4862 (unsigned int)text[interval.end] == 0x7f ||
+
4863 text[interval.end] == '(' ||
+
4864 text[interval.end] == ')' ||
+
4865 text[interval.end] == '<' ||
+
4866 text[interval.end] == '>' ||
+
4867 text[interval.end] == '@' ||
+
4868 text[interval.end] == ',' ||
+
4869 text[interval.end] == ';' ||
+
4870 text[interval.end] == ':' ||
+
4871 text[interval.end] == '\\' ||
+
4872 text[interval.end] == '\"' ||
+
4873 text[interval.end] == '/' ||
+
4874 text[interval.end] == '[' ||
+
4875 text[interval.end] == ']' ||
+
4876 text[interval.end] == '?' ||
+
4877 text[interval.end] == '=' ||
+
4878 text[interval.end] == '{' ||
+
4879 text[interval.end] == '}' ||
+
4880 isspace(text[interval.end]))
+
4881 break;
+
4882 else
+
4883 interval.end++;
+
4884 }
+
4885 else
+
4886 break;
+
4887 }
+
4888 if (start < interval.end) {
+
4889 interval.start = start;
+
4890 return true;
+
4891 }
+
4892 else {
+
4893 interval.start = (interval.end = start) + 1;
+
4894 return false;
+
4895 }
+
4896 }
+
4897 };
+
4898
+
4902 class http_quoted_string : public parser
+
4903 {
+
4904 public:
+
4905 virtual bool match(
+
4906 _In_reads_or_z_(end) const char* text,
+
4907 _In_ size_t start = 0,
+
4908 _In_ size_t end = (size_t)-1,
+
4909 _In_ int flags = match_default)
+
4910 {
+
4911 assert(text || start >= end);
+
4912 interval.end = start;
+
4913 if (interval.end < end && text[interval.end] != '"')
+
4914 goto error;
+
4915 interval.end++;
+
4916 content.start = interval.end;
+
4917 for (;;) {
+
4918 assert(text || interval.end >= end);
+
4919 if (interval.end < end && text[interval.end]) {
+
4920 if (text[interval.end] == '"') {
+
4921 content.end = interval.end;
+
4922 interval.end++;
+
4923 break;
+
4924 }
+
4925 else if (text[interval.end] == '\\') {
+
4926 interval.end++;
+
4927 if (interval.end < end && text[interval.end]) {
+
4928 interval.end++;
+
4929 }
+
4930 else
+
4931 goto error;
+
4932 }
+
4933 else if (m_chr.match(text, interval.end, end, flags))
+
4934 interval.end++;
+
4935 else
+
4936 goto error;
+
4937 }
+
4938 else
+
4939 goto error;
+
4940 }
+
4941 interval.start = start;
+
4942 return true;
+
4943
+
4944 error:
+
4945 content.start = 1;
+
4946 content.end = 0;
+
4947 interval.start = (interval.end = start) + 1;
+
4948 return false;
+
4949 }
+
4950
+
4951 virtual void invalidate()
+
4952 {
+
4953 content.start = 1;
+
4954 content.end = 0;
+
4955 parser::invalidate();
+
4956 }
+
4957
+
4958 public:
+
4959 stdex::interval<size_t> content;
+
4960
+
4961 protected:
+
4962 http_text_char m_chr;
+
4963 };
+
4964
+
4968 class http_value : public parser
+
4969 {
+
4970 public:
+
4971 virtual bool match(
+
4972 _In_reads_or_z_(end) const char* text,
+
4973 _In_ size_t start = 0,
+
4974 _In_ size_t end = (size_t)-1,
+
4975 _In_ int flags = match_default)
+
4976 {
+
4977 assert(text || start >= end);
+
4978 interval.end = start;
+
4979 if (string.match(text, interval.end, end, flags)) {
+
4980 token.invalidate();
+
4981 interval.end = string.interval.end;
+
4982 interval.start = start;
+
4983 return true;
+
4984 }
+
4985 else if (token.match(text, interval.end, end, flags)) {
+
4986 string.invalidate();
+
4987 interval.end = token.interval.end;
+
4988 interval.start = start;
+
4989 return true;
+
4990 }
+
4991 else {
+
4992 interval.start = (interval.end = start) + 1;
+
4993 return false;
+
4994 }
+
4995 }
+
4996
+
4997 virtual void invalidate()
+
4998 {
+
4999 string.invalidate();
+
5000 token.invalidate();
+
5001 parser::invalidate();
+
5002 }
+
5003
+
5004 public:
+
5005 http_quoted_string string;
+
5006 http_token token;
+
5007 };
+
5008
+
5012 class http_parameter : public parser
+
5013 {
+
5014 public:
+
5015 virtual bool match(
+
5016 _In_reads_or_z_(end) const char* text,
+
5017 _In_ size_t start = 0,
+
5018 _In_ size_t end = (size_t)-1,
+
5019 _In_ int flags = match_default)
+
5020 {
+
5021 assert(text || start >= end);
+
5022 interval.end = start;
+
5023 if (name.match(text, interval.end, end, flags))
+
5024 interval.end = name.interval.end;
+
5025 else
+
5026 goto error;
+
5027 while (m_space.match(text, interval.end, end, flags))
+
5028 interval.end = m_space.interval.end;
+
5029 assert(text || interval.end >= end);
+
5030 if (interval.end < end && text[interval.end] == '=')
+
5031 interval.end++;
+
5032 else
+
5033 while (m_space.match(text, interval.end, end, flags))
+
5034 interval.end = m_space.interval.end;
+
5035 if (value.match(text, interval.end, end, flags))
+
5036 interval.end = value.interval.end;
+
5037 else
+
5038 goto error;
+
5039 interval.start = start;
+
5040 return true;
5041
-
5042 protected:
-
5043 http_space m_space;
-
5044 };
-
5045
-
5049 class http_any_type : public parser
-
5050 {
-
5051 public:
-
5052 virtual bool match(
-
5053 _In_reads_or_z_(end) const char* text,
-
5054 _In_ size_t start = 0,
-
5055 _In_ size_t end = (size_t)-1,
-
5056 _In_ int flags = match_default)
-
5057 {
-
5058 assert(text || start >= end);
-
5059 if (start + 2 < end &&
-
5060 text[start] == '*' &&
-
5061 text[start + 1] == '/' &&
-
5062 text[start + 2] == '*')
-
5063 {
-
5064 interval.end = (interval.start = start) + 3;
-
5065 return true;
-
5066 }
-
5067 else if (start < end && text[start] == '*') {
-
5068 interval.end = (interval.start = start) + 1;
-
5069 return true;
-
5070 }
-
5071 else {
-
5072 interval.start = (interval.end = start) + 1;
-
5073 return false;
-
5074 }
-
5075 }
-
5076 };
-
5077
-
5081 class http_media_range : public parser
-
5082 {
-
5083 public:
-
5084 virtual bool match(
-
5085 _In_reads_or_z_(end) const char* text,
-
5086 _In_ size_t start = 0,
-
5087 _In_ size_t end = (size_t)-1,
-
5088 _In_ int flags = match_default)
-
5089 {
-
5090 assert(text || start >= end);
-
5091 interval.end = start;
-
5092 if (type.match(text, interval.end, end, flags))
-
5093 interval.end = type.interval.end;
-
5094 else
-
5095 goto error;
-
5096 while (m_space.match(text, interval.end, end, flags))
-
5097 interval.end = m_space.interval.end;
-
5098 if (interval.end < end && text[interval.end] == '/')
-
5099 interval.end++;
-
5100 else
-
5101 goto error;
-
5102 while (m_space.match(text, interval.end, end, flags))
-
5103 interval.end = m_space.interval.end;
-
5104 if (subtype.match(text, interval.end, end, flags))
-
5105 interval.end = subtype.interval.end;
-
5106 else
-
5107 goto error;
-
5108 interval.start = start;
-
5109 return true;
-
5110
-
5111 error:
-
5112 type.invalidate();
-
5113 subtype.invalidate();
-
5114 interval.start = (interval.end = start) + 1;
-
5115 return false;
-
5116 }
-
5117
-
5118 virtual void invalidate()
-
5119 {
-
5120 type.invalidate();
-
5121 subtype.invalidate();
-
5122 parser::invalidate();
-
5123 }
-
5124
-
5125 public:
-
5126 http_token type;
-
5127 http_token subtype;
+
5042 error:
+
5043 name.invalidate();
+
5044 value.invalidate();
+
5045 interval.start = (interval.end = start) + 1;
+
5046 return false;
+
5047 }
+
5048
+
5049 virtual void invalidate()
+
5050 {
+
5051 name.invalidate();
+
5052 value.invalidate();
+
5053 parser::invalidate();
+
5054 }
+
5055
+
5056 public:
+
5057 http_token name;
+
5058 http_value value;
+
5059
+
5060 protected:
+
5061 http_space m_space;
+
5062 };
+
5063
+
5067 class http_any_type : public parser
+
5068 {
+
5069 public:
+
5070 virtual bool match(
+
5071 _In_reads_or_z_(end) const char* text,
+
5072 _In_ size_t start = 0,
+
5073 _In_ size_t end = (size_t)-1,
+
5074 _In_ int flags = match_default)
+
5075 {
+
5076 assert(text || start >= end);
+
5077 if (start + 2 < end &&
+
5078 text[start] == '*' &&
+
5079 text[start + 1] == '/' &&
+
5080 text[start + 2] == '*')
+
5081 {
+
5082 interval.end = (interval.start = start) + 3;
+
5083 return true;
+
5084 }
+
5085 else if (start < end && text[start] == '*') {
+
5086 interval.end = (interval.start = start) + 1;
+
5087 return true;
+
5088 }
+
5089 else {
+
5090 interval.start = (interval.end = start) + 1;
+
5091 return false;
+
5092 }
+
5093 }
+
5094 };
+
5095
+
5099 class http_media_range : public parser
+
5100 {
+
5101 public:
+
5102 virtual bool match(
+
5103 _In_reads_or_z_(end) const char* text,
+
5104 _In_ size_t start = 0,
+
5105 _In_ size_t end = (size_t)-1,
+
5106 _In_ int flags = match_default)
+
5107 {
+
5108 assert(text || start >= end);
+
5109 interval.end = start;
+
5110 if (type.match(text, interval.end, end, flags))
+
5111 interval.end = type.interval.end;
+
5112 else
+
5113 goto error;
+
5114 while (m_space.match(text, interval.end, end, flags))
+
5115 interval.end = m_space.interval.end;
+
5116 if (interval.end < end && text[interval.end] == '/')
+
5117 interval.end++;
+
5118 else
+
5119 goto error;
+
5120 while (m_space.match(text, interval.end, end, flags))
+
5121 interval.end = m_space.interval.end;
+
5122 if (subtype.match(text, interval.end, end, flags))
+
5123 interval.end = subtype.interval.end;
+
5124 else
+
5125 goto error;
+
5126 interval.start = start;
+
5127 return true;
5128
-
5129 protected:
-
5130 http_space m_space;
-
5131 };
-
5132
-
5136 class http_media_type : public http_media_range
-
5137 {
-
5138 public:
-
5139 virtual bool match(
-
5140 _In_reads_or_z_(end) const char* text,
-
5141 _In_ size_t start = 0,
-
5142 _In_ size_t end = (size_t)-1,
-
5143 _In_ int flags = match_default)
-
5144 {
-
5145 assert(text || start >= end);
-
5146 if (!http_media_range::match(text, start, end, flags))
-
5147 goto error;
-
5148 params.clear();
-
5149 for (;;) {
-
5150 if (interval.end < end && text[interval.end]) {
-
5151 if (m_space.match(text, interval.end, end, flags))
-
5152 interval.end = m_space.interval.end;
-
5153 else if (text[interval.end] == ';') {
-
5154 interval.end++;
-
5155 while (m_space.match(text, interval.end, end, flags))
-
5156 interval.end = m_space.interval.end;
-
5157 http_parameter param;
-
5158 if (param.match(text, interval.end, end, flags)) {
-
5159 interval.end = param.interval.end;
-
5160 params.push_back(std::move(param));
-
5161 }
-
5162 else
-
5163 break;
-
5164 }
-
5165 else
-
5166 break;
-
5167 }
-
5168 else
-
5169 break;
-
5170 }
-
5171 interval.end = params.empty() ? subtype.interval.end : params.back().interval.end;
-
5172 return true;
-
5173
-
5174 error:
-
5175 http_media_range::invalidate();
-
5176 params.clear();
-
5177 interval.start = (interval.end = start) + 1;
-
5178 return false;
-
5179 }
-
5180
-
5181 virtual void invalidate()
-
5182 {
-
5183 params.clear();
-
5184 http_media_range::invalidate();
-
5185 }
-
5186
-
5187 public:
-
5188 std::list<http_parameter> params;
-
5189 };
-
5190
-
5194 class http_url_server : public parser
-
5195 {
-
5196 public:
-
5197 virtual bool match(
-
5198 _In_reads_or_z_(end) const char* text,
-
5199 _In_ size_t start = 0,
-
5200 _In_ size_t end = (size_t)-1,
-
5201 _In_ int flags = match_default)
-
5202 {
-
5203 assert(text || start >= end);
-
5204 interval.end = start;
-
5205 for (;;) {
-
5206 if (interval.end < end && text[interval.end]) {
-
5207 if ((unsigned int)text[interval.end] < 0x20 ||
-
5208 (unsigned int)text[interval.end] == 0x7f ||
-
5209 text[interval.end] == ':' ||
-
5210 text[interval.end] == '/' ||
-
5211 isspace(text[interval.end]))
-
5212 break;
-
5213 else
-
5214 interval.end++;
-
5215 }
-
5216 else
-
5217 break;
-
5218 }
-
5219 if (start < interval.end) {
-
5220 interval.start = start;
-
5221 return true;
-
5222 }
-
5223 interval.start = (interval.end = start) + 1;
-
5224 return false;
-
5225 }
-
5226 };
-
5227
-
5231 class http_url_port : public parser
-
5232 {
-
5233 public:
-
5234 http_url_port(_In_ const std::locale& locale = std::locale()) :
-
5235 parser(locale),
-
5236 value(0)
-
5237 {}
-
5238
-
5239 virtual bool match(
-
5240 _In_reads_or_z_(end) const char* text,
-
5241 _In_ size_t start = 0,
-
5242 _In_ size_t end = (size_t)-1,
-
5243 _In_ int flags = match_default)
-
5244 {
-
5245 assert(text || start >= end);
-
5246 value = 0;
-
5247 interval.end = start;
-
5248 for (;;) {
-
5249 if (interval.end < end && text[interval.end]) {
-
5250 if ('0' <= text[interval.end] && text[interval.end] <= '9') {
-
5251 size_t _value = (size_t)value * 10 + text[interval.end] - '0';
-
5252 if (_value > (uint16_t)-1) {
-
5253 value = 0;
-
5254 interval.start = (interval.end = start) + 1;
-
5255 return false;
-
5256 }
-
5257 value = (uint16_t)_value;
-
5258 interval.end++;
-
5259 }
-
5260 else
-
5261 break;
-
5262 }
-
5263 else
-
5264 break;
-
5265 }
-
5266 if (start < interval.end) {
-
5267 interval.start = start;
-
5268 return true;
-
5269 }
-
5270 interval.start = (interval.end = start) + 1;
-
5271 return false;
-
5272 }
-
5273
-
5274 virtual void invalidate()
-
5275 {
-
5276 value = 0;
-
5277 parser::invalidate();
-
5278 }
-
5279
-
5280 public:
-
5281 uint16_t value;
-
5282 };
-
5283
-
5287 class http_url_path_segment : public parser
-
5288 {
-
5289 public:
-
5290 virtual bool match(
-
5291 _In_reads_or_z_(end) const char* text,
-
5292 _In_ size_t start = 0,
-
5293 _In_ size_t end = (size_t)-1,
-
5294 _In_ int flags = match_default)
-
5295 {
-
5296 assert(text || start >= end);
-
5297 interval.end = start;
-
5298 for (;;) {
-
5299 if (interval.end < end && text[interval.end]) {
-
5300 if ((unsigned int)text[interval.end] < 0x20 ||
-
5301 (unsigned int)text[interval.end] == 0x7f ||
-
5302 text[interval.end] == '?' ||
-
5303 text[interval.end] == '/' ||
-
5304 isspace(text[interval.end]))
-
5305 break;
-
5306 else
-
5307 interval.end++;
-
5308 }
-
5309 else
-
5310 break;
-
5311 }
-
5312 interval.start = start;
-
5313 return true;
-
5314 }
-
5315 };
-
5316
-
5320 class http_url_path : public parser
-
5321 {
-
5322 public:
-
5323 virtual bool match(
-
5324 _In_reads_or_z_(end) const char* text,
-
5325 _In_ size_t start = 0,
-
5326 _In_ size_t end = (size_t)-1,
-
5327 _In_ int flags = match_default)
-
5328 {
-
5329 assert(text || start >= end);
-
5330 http_url_path_segment s;
-
5331 interval.end = start;
-
5332 segments.clear();
-
5333 assert(text || interval.end >= end);
-
5334 if (interval.end < end && text[interval.end] != '/')
-
5335 goto error;
-
5336 interval.end++;
-
5337 s.match(text, interval.end, end, flags);
-
5338 segments.push_back(s);
-
5339 interval.end = s.interval.end;
-
5340 for (;;) {
-
5341 if (interval.end < end && text[interval.end]) {
-
5342 if (text[interval.end] == '/') {
-
5343 interval.end++;
-
5344 s.match(text, interval.end, end, flags);
-
5345 segments.push_back(s);
-
5346 interval.end = s.interval.end;
-
5347 }
-
5348 else
-
5349 break;
-
5350 }
-
5351 else
-
5352 break;
-
5353 }
-
5354 interval.start = start;
-
5355 return true;
-
5356
-
5357 error:
-
5358 segments.clear();
-
5359 interval.start = (interval.end = start) + 1;
-
5360 return false;
-
5361 }
-
5362
-
5363 virtual void invalidate()
-
5364 {
-
5365 segments.clear();
-
5366 parser::invalidate();
-
5367 }
-
5368
-
5369 public:
-
5370 std::vector<http_url_path_segment> segments;
-
5371 };
-
5372
-
5376 class http_url_parameter : public parser
-
5377 {
-
5378 public:
-
5379 virtual bool match(
-
5380 _In_reads_or_z_(end) const char* text,
-
5381 _In_ size_t start = 0,
-
5382 _In_ size_t end = (size_t)-1,
-
5383 _In_ int flags = match_default)
-
5384 {
-
5385 assert(text || start >= end);
-
5386 interval.end = start;
-
5387 name.start = interval.end;
-
5388 for (;;) {
-
5389 if (interval.end < end && text[interval.end]) {
-
5390 if ((unsigned int)text[interval.end] < 0x20 ||
-
5391 (unsigned int)text[interval.end] == 0x7f ||
-
5392 text[interval.end] == '&' ||
-
5393 text[interval.end] == '=' ||
-
5394 isspace(text[interval.end]))
-
5395 break;
-
5396 else
-
5397 interval.end++;
-
5398 }
-
5399 else
-
5400 break;
-
5401 }
-
5402 if (start < interval.end)
-
5403 name.end = interval.end;
-
5404 else
-
5405 goto error;
-
5406 if (text[interval.end] == '=') {
-
5407 interval.end++;
-
5408 value.start = interval.end;
-
5409 for (;;) {
-
5410 if (interval.end < end && text[interval.end]) {
-
5411 if ((unsigned int)text[interval.end] < 0x20 ||
-
5412 (unsigned int)text[interval.end] == 0x7f ||
-
5413 text[interval.end] == '&' ||
-
5414 isspace(text[interval.end]))
-
5415 break;
-
5416 else
-
5417 interval.end++;
-
5418 }
-
5419 else
-
5420 break;
-
5421 }
-
5422 value.end = interval.end;
-
5423 }
-
5424 else {
-
5425 value.start = 1;
-
5426 value.end = 0;
-
5427 }
-
5428 interval.start = start;
-
5429 return true;
-
5430
-
5431 error:
-
5432 name.start = 1;
-
5433 name.end = 0;
-
5434 value.start = 1;
-
5435 value.end = 0;
-
5436 interval.start = (interval.end = start) + 1;
-
5437 return false;
-
5438 }
-
5439
-
5440 virtual void invalidate()
-
5441 {
-
5442 name.start = 1;
-
5443 name.end = 0;
-
5444 value.start = 1;
-
5445 value.end = 0;
-
5446 parser::invalidate();
-
5447 }
+
5129 error:
+
5130 type.invalidate();
+
5131 subtype.invalidate();
+
5132 interval.start = (interval.end = start) + 1;
+
5133 return false;
+
5134 }
+
5135
+
5136 virtual void invalidate()
+
5137 {
+
5138 type.invalidate();
+
5139 subtype.invalidate();
+
5140 parser::invalidate();
+
5141 }
+
5142
+
5143 public:
+
5144 http_token type;
+
5145 http_token subtype;
+
5146
+
5147 protected:
+
5148 http_space m_space;
+
5149 };
+
5150
+
5154 class http_media_type : public http_media_range
+
5155 {
+
5156 public:
+
5157 virtual bool match(
+
5158 _In_reads_or_z_(end) const char* text,
+
5159 _In_ size_t start = 0,
+
5160 _In_ size_t end = (size_t)-1,
+
5161 _In_ int flags = match_default)
+
5162 {
+
5163 assert(text || start >= end);
+
5164 if (!http_media_range::match(text, start, end, flags))
+
5165 goto error;
+
5166 params.clear();
+
5167 for (;;) {
+
5168 if (interval.end < end && text[interval.end]) {
+
5169 if (m_space.match(text, interval.end, end, flags))
+
5170 interval.end = m_space.interval.end;
+
5171 else if (text[interval.end] == ';') {
+
5172 interval.end++;
+
5173 while (m_space.match(text, interval.end, end, flags))
+
5174 interval.end = m_space.interval.end;
+
5175 http_parameter param;
+
5176 if (param.match(text, interval.end, end, flags)) {
+
5177 interval.end = param.interval.end;
+
5178 params.push_back(std::move(param));
+
5179 }
+
5180 else
+
5181 break;
+
5182 }
+
5183 else
+
5184 break;
+
5185 }
+
5186 else
+
5187 break;
+
5188 }
+
5189 interval.end = params.empty() ? subtype.interval.end : params.back().interval.end;
+
5190 return true;
+
5191
+
5192 error:
+
5193 http_media_range::invalidate();
+
5194 params.clear();
+
5195 interval.start = (interval.end = start) + 1;
+
5196 return false;
+
5197 }
+
5198
+
5199 virtual void invalidate()
+
5200 {
+
5201 params.clear();
+
5202 http_media_range::invalidate();
+
5203 }
+
5204
+
5205 public:
+
5206 std::list<http_parameter> params;
+
5207 };
+
5208
+
5212 class http_url_server : public parser
+
5213 {
+
5214 public:
+
5215 virtual bool match(
+
5216 _In_reads_or_z_(end) const char* text,
+
5217 _In_ size_t start = 0,
+
5218 _In_ size_t end = (size_t)-1,
+
5219 _In_ int flags = match_default)
+
5220 {
+
5221 assert(text || start >= end);
+
5222 interval.end = start;
+
5223 for (;;) {
+
5224 if (interval.end < end && text[interval.end]) {
+
5225 if ((unsigned int)text[interval.end] < 0x20 ||
+
5226 (unsigned int)text[interval.end] == 0x7f ||
+
5227 text[interval.end] == ':' ||
+
5228 text[interval.end] == '/' ||
+
5229 isspace(text[interval.end]))
+
5230 break;
+
5231 else
+
5232 interval.end++;
+
5233 }
+
5234 else
+
5235 break;
+
5236 }
+
5237 if (start < interval.end) {
+
5238 interval.start = start;
+
5239 return true;
+
5240 }
+
5241 interval.start = (interval.end = start) + 1;
+
5242 return false;
+
5243 }
+
5244 };
+
5245
+
5249 class http_url_port : public parser
+
5250 {
+
5251 public:
+
5252 http_url_port(_In_ const std::locale& locale = std::locale()) :
+
5253 parser(locale),
+
5254 value(0)
+
5255 {}
+
5256
+
5257 virtual bool match(
+
5258 _In_reads_or_z_(end) const char* text,
+
5259 _In_ size_t start = 0,
+
5260 _In_ size_t end = (size_t)-1,
+
5261 _In_ int flags = match_default)
+
5262 {
+
5263 assert(text || start >= end);
+
5264 value = 0;
+
5265 interval.end = start;
+
5266 for (;;) {
+
5267 if (interval.end < end && text[interval.end]) {
+
5268 if ('0' <= text[interval.end] && text[interval.end] <= '9') {
+
5269 size_t _value = (size_t)value * 10 + text[interval.end] - '0';
+
5270 if (_value > (uint16_t)-1) {
+
5271 value = 0;
+
5272 interval.start = (interval.end = start) + 1;
+
5273 return false;
+
5274 }
+
5275 value = (uint16_t)_value;
+
5276 interval.end++;
+
5277 }
+
5278 else
+
5279 break;
+
5280 }
+
5281 else
+
5282 break;
+
5283 }
+
5284 if (start < interval.end) {
+
5285 interval.start = start;
+
5286 return true;
+
5287 }
+
5288 interval.start = (interval.end = start) + 1;
+
5289 return false;
+
5290 }
+
5291
+
5292 virtual void invalidate()
+
5293 {
+
5294 value = 0;
+
5295 parser::invalidate();
+
5296 }
+
5297
+
5298 public:
+
5299 uint16_t value;
+
5300 };
+
5301
+
5305 class http_url_path_segment : public parser
+
5306 {
+
5307 public:
+
5308 virtual bool match(
+
5309 _In_reads_or_z_(end) const char* text,
+
5310 _In_ size_t start = 0,
+
5311 _In_ size_t end = (size_t)-1,
+
5312 _In_ int flags = match_default)
+
5313 {
+
5314 assert(text || start >= end);
+
5315 interval.end = start;
+
5316 for (;;) {
+
5317 if (interval.end < end && text[interval.end]) {
+
5318 if ((unsigned int)text[interval.end] < 0x20 ||
+
5319 (unsigned int)text[interval.end] == 0x7f ||
+
5320 text[interval.end] == '?' ||
+
5321 text[interval.end] == '/' ||
+
5322 isspace(text[interval.end]))
+
5323 break;
+
5324 else
+
5325 interval.end++;
+
5326 }
+
5327 else
+
5328 break;
+
5329 }
+
5330 interval.start = start;
+
5331 return true;
+
5332 }
+
5333 };
+
5334
+
5338 class http_url_path : public parser
+
5339 {
+
5340 public:
+
5341 virtual bool match(
+
5342 _In_reads_or_z_(end) const char* text,
+
5343 _In_ size_t start = 0,
+
5344 _In_ size_t end = (size_t)-1,
+
5345 _In_ int flags = match_default)
+
5346 {
+
5347 assert(text || start >= end);
+
5348 http_url_path_segment s;
+
5349 interval.end = start;
+
5350 segments.clear();
+
5351 assert(text || interval.end >= end);
+
5352 if (interval.end < end && text[interval.end] != '/')
+
5353 goto error;
+
5354 interval.end++;
+
5355 s.match(text, interval.end, end, flags);
+
5356 segments.push_back(s);
+
5357 interval.end = s.interval.end;
+
5358 for (;;) {
+
5359 if (interval.end < end && text[interval.end]) {
+
5360 if (text[interval.end] == '/') {
+
5361 interval.end++;
+
5362 s.match(text, interval.end, end, flags);
+
5363 segments.push_back(s);
+
5364 interval.end = s.interval.end;
+
5365 }
+
5366 else
+
5367 break;
+
5368 }
+
5369 else
+
5370 break;
+
5371 }
+
5372 interval.start = start;
+
5373 return true;
+
5374
+
5375 error:
+
5376 segments.clear();
+
5377 interval.start = (interval.end = start) + 1;
+
5378 return false;
+
5379 }
+
5380
+
5381 virtual void invalidate()
+
5382 {
+
5383 segments.clear();
+
5384 parser::invalidate();
+
5385 }
+
5386
+
5387 public:
+
5388 std::vector<http_url_path_segment> segments;
+
5389 };
+
5390
+
5394 class http_url_parameter : public parser
+
5395 {
+
5396 public:
+
5397 virtual bool match(
+
5398 _In_reads_or_z_(end) const char* text,
+
5399 _In_ size_t start = 0,
+
5400 _In_ size_t end = (size_t)-1,
+
5401 _In_ int flags = match_default)
+
5402 {
+
5403 assert(text || start >= end);
+
5404 interval.end = start;
+
5405 name.start = interval.end;
+
5406 for (;;) {
+
5407 if (interval.end < end && text[interval.end]) {
+
5408 if ((unsigned int)text[interval.end] < 0x20 ||
+
5409 (unsigned int)text[interval.end] == 0x7f ||
+
5410 text[interval.end] == '&' ||
+
5411 text[interval.end] == '=' ||
+
5412 isspace(text[interval.end]))
+
5413 break;
+
5414 else
+
5415 interval.end++;
+
5416 }
+
5417 else
+
5418 break;
+
5419 }
+
5420 if (start < interval.end)
+
5421 name.end = interval.end;
+
5422 else
+
5423 goto error;
+
5424 if (text[interval.end] == '=') {
+
5425 interval.end++;
+
5426 value.start = interval.end;
+
5427 for (;;) {
+
5428 if (interval.end < end && text[interval.end]) {
+
5429 if ((unsigned int)text[interval.end] < 0x20 ||
+
5430 (unsigned int)text[interval.end] == 0x7f ||
+
5431 text[interval.end] == '&' ||
+
5432 isspace(text[interval.end]))
+
5433 break;
+
5434 else
+
5435 interval.end++;
+
5436 }
+
5437 else
+
5438 break;
+
5439 }
+
5440 value.end = interval.end;
+
5441 }
+
5442 else {
+
5443 value.start = 1;
+
5444 value.end = 0;
+
5445 }
+
5446 interval.start = start;
+
5447 return true;
5448
-
5449 public:
-
5450 stdex::interval<size_t> name;
-
5451 stdex::interval<size_t> value;
-
5452 };
-
5453
-
5457 class http_url : public parser
-
5458 {
-
5459 public:
-
5460 http_url(_In_ const std::locale& locale = std::locale()) :
-
5461 parser(locale),
-
5462 port(locale)
-
5463 {}
-
5464
-
5465 virtual bool match(
-
5466 _In_reads_or_z_(end) const char* text,
-
5467 _In_ size_t start = 0,
-
5468 _In_ size_t end = (size_t)-1,
-
5469 _In_ int flags = match_default)
-
5470 {
-
5471 assert(text || start >= end);
-
5472 interval.end = start;
-
5473
-
5474 if (interval.end + 7 <= end && stdex::strnicmp(text + interval.end, 7, "http://", (size_t)-1, m_locale) == 0) {
-
5475 interval.end += 7;
-
5476 if (server.match(text, interval.end, end, flags))
-
5477 interval.end = server.interval.end;
-
5478 else
-
5479 goto error;
-
5480 if (interval.end < end && text[interval.end] == ':') {
-
5481 interval.end++;
-
5482 if (port.match(text, interval.end, end, flags))
-
5483 interval.end = port.interval.end;
-
5484 }
-
5485 else {
-
5486 port.invalidate();
-
5487 port.value = 80;
-
5488 }
-
5489 }
-
5490 else {
-
5491 server.invalidate();
-
5492 port.invalidate();
-
5493 port.value = 80;
-
5494 }
-
5495
-
5496 if (path.match(text, interval.end, end, flags))
-
5497 interval.end = path.interval.end;
-
5498 else
-
5499 goto error;
-
5500
-
5501 params.clear();
-
5502
-
5503 if (interval.end < end && text[interval.end] == '?') {
-
5504 interval.end++;
-
5505 for (;;) {
-
5506 if (interval.end < end && text[interval.end]) {
-
5507 if ((unsigned int)text[interval.end] < 0x20 ||
-
5508 (unsigned int)text[interval.end] == 0x7f ||
-
5509 isspace(text[interval.end]))
-
5510 break;
-
5511 else if (text[interval.end] == '&')
-
5512 interval.end++;
-
5513 else {
-
5514 http_url_parameter param;
-
5515 if (param.match(text, interval.end, end, flags)) {
-
5516 interval.end = param.interval.end;
-
5517 params.push_back(std::move(param));
-
5518 }
-
5519 else
-
5520 break;
-
5521 }
-
5522 }
-
5523 else
-
5524 break;
-
5525 }
-
5526 }
-
5527
-
5528 interval.start = start;
-
5529 return true;
-
5530
-
5531 error:
-
5532 server.invalidate();
-
5533 port.invalidate();
-
5534 path.invalidate();
-
5535 params.clear();
-
5536 interval.start = (interval.end = start) + 1;
-
5537 return false;
-
5538 }
-
5539
-
5540 virtual void invalidate()
-
5541 {
-
5542 server.invalidate();
-
5543 port.invalidate();
-
5544 path.invalidate();
-
5545 params.clear();
-
5546 parser::invalidate();
-
5547 }
+
5449 error:
+
5450 name.start = 1;
+
5451 name.end = 0;
+
5452 value.start = 1;
+
5453 value.end = 0;
+
5454 interval.start = (interval.end = start) + 1;
+
5455 return false;
+
5456 }
+
5457
+
5458 virtual void invalidate()
+
5459 {
+
5460 name.start = 1;
+
5461 name.end = 0;
+
5462 value.start = 1;
+
5463 value.end = 0;
+
5464 parser::invalidate();
+
5465 }
+
5466
+
5467 public:
+
5468 stdex::interval<size_t> name;
+
5469 stdex::interval<size_t> value;
+
5470 };
+
5471
+
5475 class http_url : public parser
+
5476 {
+
5477 public:
+
5478 http_url(_In_ const std::locale& locale = std::locale()) :
+
5479 parser(locale),
+
5480 port(locale)
+
5481 {}
+
5482
+
5483 virtual bool match(
+
5484 _In_reads_or_z_(end) const char* text,
+
5485 _In_ size_t start = 0,
+
5486 _In_ size_t end = (size_t)-1,
+
5487 _In_ int flags = match_default)
+
5488 {
+
5489 assert(text || start >= end);
+
5490 interval.end = start;
+
5491
+
5492 if (interval.end + 7 <= end && stdex::strnicmp(text + interval.end, 7, "http://", (size_t)-1, m_locale) == 0) {
+
5493 interval.end += 7;
+
5494 if (server.match(text, interval.end, end, flags))
+
5495 interval.end = server.interval.end;
+
5496 else
+
5497 goto error;
+
5498 if (interval.end < end && text[interval.end] == ':') {
+
5499 interval.end++;
+
5500 if (port.match(text, interval.end, end, flags))
+
5501 interval.end = port.interval.end;
+
5502 }
+
5503 else {
+
5504 port.invalidate();
+
5505 port.value = 80;
+
5506 }
+
5507 }
+
5508 else {
+
5509 server.invalidate();
+
5510 port.invalidate();
+
5511 port.value = 80;
+
5512 }
+
5513
+
5514 if (path.match(text, interval.end, end, flags))
+
5515 interval.end = path.interval.end;
+
5516 else
+
5517 goto error;
+
5518
+
5519 params.clear();
+
5520
+
5521 if (interval.end < end && text[interval.end] == '?') {
+
5522 interval.end++;
+
5523 for (;;) {
+
5524 if (interval.end < end && text[interval.end]) {
+
5525 if ((unsigned int)text[interval.end] < 0x20 ||
+
5526 (unsigned int)text[interval.end] == 0x7f ||
+
5527 isspace(text[interval.end]))
+
5528 break;
+
5529 else if (text[interval.end] == '&')
+
5530 interval.end++;
+
5531 else {
+
5532 http_url_parameter param;
+
5533 if (param.match(text, interval.end, end, flags)) {
+
5534 interval.end = param.interval.end;
+
5535 params.push_back(std::move(param));
+
5536 }
+
5537 else
+
5538 break;
+
5539 }
+
5540 }
+
5541 else
+
5542 break;
+
5543 }
+
5544 }
+
5545
+
5546 interval.start = start;
+
5547 return true;
5548
-
5549 public:
-
5550 http_url_server server;
-
5551 http_url_port port;
-
5552 http_url_path path;
-
5553 std::list<http_url_parameter> params;
-
5554 };
-
5555
-
5559 class http_language : public parser
-
5560 {
-
5561 public:
-
5562 virtual bool match(
-
5563 _In_reads_or_z_(end) const char* text,
-
5564 _In_ size_t start = 0,
-
5565 _In_ size_t end = (size_t)-1,
-
5566 _In_ int flags = match_default)
-
5567 {
-
5568 assert(text || start >= end);
-
5569 interval.end = start;
-
5570 components.clear();
-
5571 for (;;) {
-
5572 if (interval.end < end && text[interval.end]) {
-
5573 stdex::interval<size_t> k;
-
5574 k.end = interval.end;
-
5575 for (;;) {
-
5576 if (k.end < end && text[k.end]) {
-
5577 if (isalpha(text[k.end]))
-
5578 k.end++;
-
5579 else
-
5580 break;
-
5581 }
-
5582 else
-
5583 break;
-
5584 }
-
5585 if (interval.end < k.end) {
-
5586 k.start = interval.end;
-
5587 interval.end = k.end;
-
5588 components.push_back(k);
-
5589 }
-
5590 else
-
5591 break;
-
5592 if (interval.end < end && text[interval.end] == '-')
-
5593 interval.end++;
-
5594 else
-
5595 break;
-
5596 }
-
5597 else
-
5598 break;
-
5599 }
-
5600 if (!components.empty()) {
-
5601 interval.start = start;
-
5602 interval.end = components.back().end;
-
5603 return true;
-
5604 }
-
5605 interval.start = (interval.end = start) + 1;
-
5606 return false;
-
5607 }
-
5608
-
5609 virtual void invalidate()
-
5610 {
-
5611 components.clear();
-
5612 parser::invalidate();
-
5613 }
-
5614
-
5615 public:
-
5616 std::vector<stdex::interval<size_t>> components;
-
5617 };
-
5618
-
5622 class http_weight : public parser
-
5623 {
-
5624 public:
-
5625 http_weight(_In_ const std::locale& locale = std::locale()) :
-
5626 parser(locale),
-
5627 value(1.0f)
-
5628 {}
-
5629
-
5630 virtual bool match(
-
5631 _In_reads_or_z_(end) const char* text,
-
5632 _In_ size_t start = 0,
-
5633 _In_ size_t end = (size_t)-1,
-
5634 _In_ int flags = match_default)
-
5635 {
-
5636 assert(text || start >= end);
-
5637 size_t celi_del = 0, decimalni_del = 0, decimalni_del_n = 1;
-
5638 interval.end = start;
-
5639 for (;;) {
-
5640 if (interval.end < end && text[interval.end]) {
-
5641 if ('0' <= text[interval.end] && text[interval.end] <= '9') {
-
5642 celi_del = celi_del * 10 + text[interval.end] - '0';
-
5643 interval.end++;
-
5644 }
-
5645 else if (text[interval.end] == '.') {
-
5646 interval.end++;
-
5647 for (;;) {
-
5648 if (interval.end < end && text[interval.end]) {
-
5649 if ('0' <= text[interval.end] && text[interval.end] <= '9') {
-
5650 decimalni_del = decimalni_del * 10 + text[interval.end] - '0';
-
5651 decimalni_del_n *= 10;
-
5652 interval.end++;
-
5653 }
-
5654 else
-
5655 break;
-
5656 }
-
5657 else
-
5658 break;
-
5659 }
-
5660 break;
-
5661 }
-
5662 else
-
5663 break;
-
5664 }
-
5665 else
-
5666 break;
-
5667 }
-
5668 if (start < interval.end) {
-
5669 value = (float)((double)celi_del + (double)decimalni_del / decimalni_del_n);
-
5670 interval.start = start;
-
5671 return true;
-
5672 }
-
5673 value = 1.0f;
-
5674 interval.start = (interval.end = start) + 1;
-
5675 return false;
-
5676 }
-
5677
-
5678 virtual void invalidate()
-
5679 {
-
5680 value = 1.0f;
-
5681 parser::invalidate();
-
5682 }
-
5683
-
5684 public:
-
5685 float value;
-
5686 };
-
5687
-
5691 class http_asterisk : public parser
-
5692 {
-
5693 public:
-
5694 virtual bool match(
-
5695 _In_reads_or_z_(end) const char* text,
-
5696 _In_ size_t start = 0,
-
5697 _In_ size_t end = (size_t)-1,
-
5698 _In_ int flags = match_default)
-
5699 {
-
5700 assert(text || end <= start);
-
5701 if (start < end && text[start] == '*') {
-
5702 interval.end = (interval.start = start) + 1;
-
5703 return true;
-
5704 }
-
5705 interval.start = (interval.end = start) + 1;
-
5706 return false;
-
5707 }
-
5708 };
-
5709
-
5713 template <class T, class T_asterisk = http_asterisk>
-
5714 class http_weighted_value : public parser
-
5715 {
-
5716 public:
-
5717 http_weighted_value(_In_ const std::locale& locale = std::locale()) :
-
5718 parser(locale),
-
5719 factor(locale)
-
5720 {}
-
5721
-
5722 virtual bool match(
-
5723 _In_reads_or_z_(end) const char* text,
-
5724 _In_ size_t start = 0,
-
5725 _In_ size_t end = (size_t)-1,
-
5726 _In_ int flags = match_default)
-
5727 {
-
5728 assert(text || start >= end);
-
5729 size_t konec_vrednosti;
-
5730 interval.end = start;
-
5731 if (asterisk.match(text, interval.end, end, flags)) {
-
5732 interval.end = konec_vrednosti = asterisk.interval.end;
-
5733 value.invalidate();
-
5734 }
-
5735 else if (value.match(text, interval.end, end, flags)) {
-
5736 interval.end = konec_vrednosti = value.interval.end;
-
5737 asterisk.invalidate();
-
5738 }
-
5739 else {
-
5740 asterisk.invalidate();
-
5741 value.invalidate();
-
5742 interval.start = (interval.end = start) + 1;
-
5743 return false;
-
5744 }
-
5745
-
5746 while (interval.end < end && text[interval.end] && isspace(text[interval.end])) interval.end++;
-
5747 if (interval.end < end && text[interval.end] == ';') {
-
5748 interval.end++;
-
5749 while (interval.end < end && text[interval.end] && isspace(text[interval.end])) interval.end++;
-
5750 if (interval.end < end && (text[interval.end] == 'q' || text[interval.end] == 'Q')) {
-
5751 interval.end++;
-
5752 while (interval.end < end && text[interval.end] && isspace(text[interval.end])) interval.end++;
-
5753 if (interval.end < end && text[interval.end] == '=') {
-
5754 interval.end++;
-
5755 while (interval.end < end && text[interval.end] && isspace(text[interval.end])) interval.end++;
-
5756 if (factor.match(text, interval.end, end, flags))
-
5757 interval.end = factor.interval.end;
-
5758 }
-
5759 }
-
5760 }
-
5761 if (!factor.interval) {
-
5762 factor.invalidate();
-
5763 interval.end = konec_vrednosti;
-
5764 }
-
5765 interval.start = start;
-
5766 return true;
-
5767 }
-
5768
-
5769 virtual void invalidate()
-
5770 {
-
5771 asterisk.invalidate();
-
5772 value.invalidate();
-
5773 factor.invalidate();
-
5774 parser::invalidate();
-
5775 }
-
5776
-
5777 public:
-
5778 T_asterisk asterisk;
-
5779 T value;
-
5780 http_weight factor;
-
5781 };
-
5782
-
5786 class http_cookie_parameter : public parser
-
5787 {
-
5788 public:
-
5789 virtual bool match(
-
5790 _In_reads_or_z_(end) const char* text,
-
5791 _In_ size_t start = 0,
-
5792 _In_ size_t end = (size_t)-1,
-
5793 _In_ int flags = match_default)
-
5794 {
-
5795 assert(text || start >= end);
-
5796 interval.end = start;
-
5797 if (interval.end < end && text[interval.end] == '$')
-
5798 interval.end++;
-
5799 else
-
5800 goto error;
-
5801 if (name.match(text, interval.end, end, flags))
-
5802 interval.end = name.interval.end;
-
5803 else
-
5804 goto error;
-
5805 while (m_space.match(text, interval.end, end, flags))
-
5806 interval.end = m_space.interval.end;
-
5807 if (interval.end < end && text[interval.end] == '=')
-
5808 interval.end++;
-
5809 else
-
5810 goto error;
-
5811 while (m_space.match(text, interval.end, end, flags))
-
5812 interval.end = m_space.interval.end;
-
5813 if (value.match(text, interval.end, end, flags))
-
5814 interval.end = value.interval.end;
-
5815 else
-
5816 goto error;
-
5817 interval.start = start;
-
5818 return true;
-
5819
-
5820 error:
-
5821 name.invalidate();
-
5822 value.invalidate();
-
5823 interval.start = (interval.end = start) + 1;
-
5824 return false;
-
5825 }
-
5826
-
5827 virtual void invalidate()
-
5828 {
-
5829 name.invalidate();
-
5830 value.invalidate();
-
5831 parser::invalidate();
-
5832 }
-
5833
-
5834 public:
-
5835 http_token name;
-
5836 http_value value;
+
5549 error:
+
5550 server.invalidate();
+
5551 port.invalidate();
+
5552 path.invalidate();
+
5553 params.clear();
+
5554 interval.start = (interval.end = start) + 1;
+
5555 return false;
+
5556 }
+
5557
+
5558 virtual void invalidate()
+
5559 {
+
5560 server.invalidate();
+
5561 port.invalidate();
+
5562 path.invalidate();
+
5563 params.clear();
+
5564 parser::invalidate();
+
5565 }
+
5566
+
5567 public:
+
5568 http_url_server server;
+
5569 http_url_port port;
+
5570 http_url_path path;
+
5571 std::list<http_url_parameter> params;
+
5572 };
+
5573
+
5577 class http_language : public parser
+
5578 {
+
5579 public:
+
5580 virtual bool match(
+
5581 _In_reads_or_z_(end) const char* text,
+
5582 _In_ size_t start = 0,
+
5583 _In_ size_t end = (size_t)-1,
+
5584 _In_ int flags = match_default)
+
5585 {
+
5586 assert(text || start >= end);
+
5587 interval.end = start;
+
5588 components.clear();
+
5589 for (;;) {
+
5590 if (interval.end < end && text[interval.end]) {
+
5591 stdex::interval<size_t> k;
+
5592 k.end = interval.end;
+
5593 for (;;) {
+
5594 if (k.end < end && text[k.end]) {
+
5595 if (isalpha(text[k.end]))
+
5596 k.end++;
+
5597 else
+
5598 break;
+
5599 }
+
5600 else
+
5601 break;
+
5602 }
+
5603 if (interval.end < k.end) {
+
5604 k.start = interval.end;
+
5605 interval.end = k.end;
+
5606 components.push_back(k);
+
5607 }
+
5608 else
+
5609 break;
+
5610 if (interval.end < end && text[interval.end] == '-')
+
5611 interval.end++;
+
5612 else
+
5613 break;
+
5614 }
+
5615 else
+
5616 break;
+
5617 }
+
5618 if (!components.empty()) {
+
5619 interval.start = start;
+
5620 interval.end = components.back().end;
+
5621 return true;
+
5622 }
+
5623 interval.start = (interval.end = start) + 1;
+
5624 return false;
+
5625 }
+
5626
+
5627 virtual void invalidate()
+
5628 {
+
5629 components.clear();
+
5630 parser::invalidate();
+
5631 }
+
5632
+
5633 public:
+
5634 std::vector<stdex::interval<size_t>> components;
+
5635 };
+
5636
+
5640 class http_weight : public parser
+
5641 {
+
5642 public:
+
5643 http_weight(_In_ const std::locale& locale = std::locale()) :
+
5644 parser(locale),
+
5645 value(1.0f)
+
5646 {}
+
5647
+
5648 virtual bool match(
+
5649 _In_reads_or_z_(end) const char* text,
+
5650 _In_ size_t start = 0,
+
5651 _In_ size_t end = (size_t)-1,
+
5652 _In_ int flags = match_default)
+
5653 {
+
5654 assert(text || start >= end);
+
5655 size_t celi_del = 0, decimalni_del = 0, decimalni_del_n = 1;
+
5656 interval.end = start;
+
5657 for (;;) {
+
5658 if (interval.end < end && text[interval.end]) {
+
5659 if ('0' <= text[interval.end] && text[interval.end] <= '9') {
+
5660 celi_del = celi_del * 10 + text[interval.end] - '0';
+
5661 interval.end++;
+
5662 }
+
5663 else if (text[interval.end] == '.') {
+
5664 interval.end++;
+
5665 for (;;) {
+
5666 if (interval.end < end && text[interval.end]) {
+
5667 if ('0' <= text[interval.end] && text[interval.end] <= '9') {
+
5668 decimalni_del = decimalni_del * 10 + text[interval.end] - '0';
+
5669 decimalni_del_n *= 10;
+
5670 interval.end++;
+
5671 }
+
5672 else
+
5673 break;
+
5674 }
+
5675 else
+
5676 break;
+
5677 }
+
5678 break;
+
5679 }
+
5680 else
+
5681 break;
+
5682 }
+
5683 else
+
5684 break;
+
5685 }
+
5686 if (start < interval.end) {
+
5687 value = (float)((double)celi_del + (double)decimalni_del / decimalni_del_n);
+
5688 interval.start = start;
+
5689 return true;
+
5690 }
+
5691 value = 1.0f;
+
5692 interval.start = (interval.end = start) + 1;
+
5693 return false;
+
5694 }
+
5695
+
5696 virtual void invalidate()
+
5697 {
+
5698 value = 1.0f;
+
5699 parser::invalidate();
+
5700 }
+
5701
+
5702 public:
+
5703 float value;
+
5704 };
+
5705
+
5709 class http_asterisk : public parser
+
5710 {
+
5711 public:
+
5712 virtual bool match(
+
5713 _In_reads_or_z_(end) const char* text,
+
5714 _In_ size_t start = 0,
+
5715 _In_ size_t end = (size_t)-1,
+
5716 _In_ int flags = match_default)
+
5717 {
+
5718 assert(text || end <= start);
+
5719 if (start < end && text[start] == '*') {
+
5720 interval.end = (interval.start = start) + 1;
+
5721 return true;
+
5722 }
+
5723 interval.start = (interval.end = start) + 1;
+
5724 return false;
+
5725 }
+
5726 };
+
5727
+
5731 template <class T, class T_asterisk = http_asterisk>
+
5732 class http_weighted_value : public parser
+
5733 {
+
5734 public:
+
5735 http_weighted_value(_In_ const std::locale& locale = std::locale()) :
+
5736 parser(locale),
+
5737 factor(locale)
+
5738 {}
+
5739
+
5740 virtual bool match(
+
5741 _In_reads_or_z_(end) const char* text,
+
5742 _In_ size_t start = 0,
+
5743 _In_ size_t end = (size_t)-1,
+
5744 _In_ int flags = match_default)
+
5745 {
+
5746 assert(text || start >= end);
+
5747 size_t konec_vrednosti;
+
5748 interval.end = start;
+
5749 if (asterisk.match(text, interval.end, end, flags)) {
+
5750 interval.end = konec_vrednosti = asterisk.interval.end;
+
5751 value.invalidate();
+
5752 }
+
5753 else if (value.match(text, interval.end, end, flags)) {
+
5754 interval.end = konec_vrednosti = value.interval.end;
+
5755 asterisk.invalidate();
+
5756 }
+
5757 else {
+
5758 asterisk.invalidate();
+
5759 value.invalidate();
+
5760 interval.start = (interval.end = start) + 1;
+
5761 return false;
+
5762 }
+
5763
+
5764 while (interval.end < end && text[interval.end] && isspace(text[interval.end])) interval.end++;
+
5765 if (interval.end < end && text[interval.end] == ';') {
+
5766 interval.end++;
+
5767 while (interval.end < end && text[interval.end] && isspace(text[interval.end])) interval.end++;
+
5768 if (interval.end < end && (text[interval.end] == 'q' || text[interval.end] == 'Q')) {
+
5769 interval.end++;
+
5770 while (interval.end < end && text[interval.end] && isspace(text[interval.end])) interval.end++;
+
5771 if (interval.end < end && text[interval.end] == '=') {
+
5772 interval.end++;
+
5773 while (interval.end < end && text[interval.end] && isspace(text[interval.end])) interval.end++;
+
5774 if (factor.match(text, interval.end, end, flags))
+
5775 interval.end = factor.interval.end;
+
5776 }
+
5777 }
+
5778 }
+
5779 if (!factor.interval) {
+
5780 factor.invalidate();
+
5781 interval.end = konec_vrednosti;
+
5782 }
+
5783 interval.start = start;
+
5784 return true;
+
5785 }
+
5786
+
5787 virtual void invalidate()
+
5788 {
+
5789 asterisk.invalidate();
+
5790 value.invalidate();
+
5791 factor.invalidate();
+
5792 parser::invalidate();
+
5793 }
+
5794
+
5795 public:
+
5796 T_asterisk asterisk;
+
5797 T value;
+
5798 http_weight factor;
+
5799 };
+
5800
+
5804 class http_cookie_parameter : public parser
+
5805 {
+
5806 public:
+
5807 virtual bool match(
+
5808 _In_reads_or_z_(end) const char* text,
+
5809 _In_ size_t start = 0,
+
5810 _In_ size_t end = (size_t)-1,
+
5811 _In_ int flags = match_default)
+
5812 {
+
5813 assert(text || start >= end);
+
5814 interval.end = start;
+
5815 if (interval.end < end && text[interval.end] == '$')
+
5816 interval.end++;
+
5817 else
+
5818 goto error;
+
5819 if (name.match(text, interval.end, end, flags))
+
5820 interval.end = name.interval.end;
+
5821 else
+
5822 goto error;
+
5823 while (m_space.match(text, interval.end, end, flags))
+
5824 interval.end = m_space.interval.end;
+
5825 if (interval.end < end && text[interval.end] == '=')
+
5826 interval.end++;
+
5827 else
+
5828 goto error;
+
5829 while (m_space.match(text, interval.end, end, flags))
+
5830 interval.end = m_space.interval.end;
+
5831 if (value.match(text, interval.end, end, flags))
+
5832 interval.end = value.interval.end;
+
5833 else
+
5834 goto error;
+
5835 interval.start = start;
+
5836 return true;
5837
-
5838 protected:
-
5839 http_space m_space;
-
5840 };
-
5841
-
5845 class http_cookie : public parser
-
5846 {
-
5847 public:
-
5848 virtual bool match(
-
5849 _In_reads_or_z_(end) const char* text,
-
5850 _In_ size_t start = 0,
-
5851 _In_ size_t end = (size_t)-1,
-
5852 _In_ int flags = match_default)
-
5853 {
-
5854 assert(text || start >= end);
-
5855 interval.end = start;
-
5856 if (name.match(text, interval.end, end, flags))
-
5857 interval.end = name.interval.end;
-
5858 else
-
5859 goto error;
-
5860 while (m_space.match(text, interval.end, end, flags))
-
5861 interval.end = m_space.interval.end;
-
5862 if (interval.end < end && text[interval.end] == '=')
-
5863 interval.end++;
-
5864 else
-
5865 goto error;
-
5866 while (m_space.match(text, interval.end, end, flags))
-
5867 interval.end = m_space.interval.end;
-
5868 if (value.match(text, interval.end, end, flags))
-
5869 interval.end = value.interval.end;
-
5870 else
-
5871 goto error;
-
5872 params.clear();
-
5873 for (;;) {
-
5874 if (interval.end < end && text[interval.end]) {
-
5875 if (m_space.match(text, interval.end, end, flags))
-
5876 interval.end = m_space.interval.end;
-
5877 else if (text[interval.end] == ';') {
-
5878 interval.end++;
-
5879 while (m_space.match(text, interval.end, end, flags))
-
5880 interval.end = m_space.interval.end;
-
5881 http_cookie_parameter param;
-
5882 if (param.match(text, interval.end, end, flags)) {
-
5883 interval.end = param.interval.end;
-
5884 params.push_back(std::move(param));
-
5885 }
-
5886 else
-
5887 break;
-
5888 }
-
5889 else
-
5890 break;
-
5891 }
-
5892 else
-
5893 break;
-
5894 }
-
5895 interval.start = start;
-
5896 interval.end = params.empty() ? value.interval.end : params.back().interval.end;
-
5897 return true;
-
5898
-
5899 error:
-
5900 name.invalidate();
-
5901 value.invalidate();
-
5902 params.clear();
-
5903 interval.start = (interval.end = start) + 1;
-
5904 return false;
-
5905 }
-
5906
-
5907 virtual void invalidate()
-
5908 {
-
5909 name.invalidate();
-
5910 value.invalidate();
-
5911 params.clear();
-
5912 parser::invalidate();
-
5913 }
-
5914
-
5915 public:
-
5916 http_token name;
-
5917 http_value value;
-
5918 std::list<http_cookie_parameter> params;
-
5919
-
5920 protected:
-
5921 http_space m_space;
-
5922 };
-
5923
-
5927 class http_agent : public parser
-
5928 {
-
5929 public:
-
5930 virtual bool match(
-
5931 _In_reads_or_z_(end) const char* text,
-
5932 _In_ size_t start = 0,
-
5933 _In_ size_t end = (size_t)-1,
-
5934 _In_ int flags = match_default)
-
5935 {
-
5936 assert(text || start >= end);
-
5937 interval.end = start;
-
5938 type.start = interval.end;
-
5939 for (;;) {
-
5940 if (interval.end < end && text[interval.end]) {
-
5941 if (text[interval.end] == '/') {
-
5942 type.end = interval.end;
-
5943 interval.end++;
-
5944 version.start = interval.end;
-
5945 for (;;) {
-
5946 if (interval.end < end && text[interval.end]) {
-
5947 if (isspace(text[interval.end])) {
-
5948 version.end = interval.end;
-
5949 break;
-
5950 }
-
5951 else
-
5952 interval.end++;
-
5953 }
-
5954 else {
-
5955 version.end = interval.end;
-
5956 break;
-
5957 }
-
5958 }
-
5959 break;
-
5960 }
-
5961 else if (isspace(text[interval.end])) {
-
5962 type.end = interval.end;
-
5963 break;
-
5964 }
-
5965 else
-
5966 interval.end++;
-
5967 }
-
5968 else {
-
5969 type.end = interval.end;
-
5970 break;
-
5971 }
-
5972 }
-
5973 if (start < interval.end) {
-
5974 interval.start = start;
-
5975 return true;
-
5976 }
-
5977 type.start = 1;
-
5978 type.end = 0;
-
5979 version.start = 1;
-
5980 version.end = 0;
-
5981 interval.start = 1;
-
5982 interval.end = 0;
-
5983 return false;
-
5984 }
-
5985
-
5986 virtual void invalidate()
-
5987 {
-
5988 type.start = 1;
-
5989 type.end = 0;
-
5990 version.start = 1;
-
5991 version.end = 0;
-
5992 parser::invalidate();
-
5993 }
-
5994
-
5995 public:
-
5996 stdex::interval<size_t> type;
-
5997 stdex::interval<size_t> version;
-
5998 };
-
5999
-
6003 class http_protocol : public parser
-
6004 {
-
6005 public:
-
6006 http_protocol(_In_ const std::locale& locale = std::locale()) :
-
6007 parser(locale),
-
6008 version(0x009)
-
6009 {}
-
6010
-
6011 virtual bool match(
-
6012 _In_reads_or_z_(end) const char* text,
-
6013 _In_ size_t start = 0,
-
6014 _In_ size_t end = (size_t)-1,
-
6015 _In_ int flags = match_default)
-
6016 {
-
6017 assert(text || start >= end);
-
6018 interval.end = start;
-
6019 type.start = interval.end;
-
6020 for (;;) {
-
6021 if (interval.end < end && text[interval.end]) {
-
6022 if (text[interval.end] == '/') {
-
6023 type.end = interval.end;
-
6024 interval.end++;
-
6025 break;
-
6026 }
-
6027 else if (isspace(text[interval.end]))
-
6028 goto error;
-
6029 else
-
6030 interval.end++;
-
6031 }
-
6032 else {
-
6033 type.end = interval.end;
-
6034 goto error;
-
6035 }
-
6036 }
-
6037 version_maj.start = interval.end;
+
5838 error:
+
5839 name.invalidate();
+
5840 value.invalidate();
+
5841 interval.start = (interval.end = start) + 1;
+
5842 return false;
+
5843 }
+
5844
+
5845 virtual void invalidate()
+
5846 {
+
5847 name.invalidate();
+
5848 value.invalidate();
+
5849 parser::invalidate();
+
5850 }
+
5851
+
5852 public:
+
5853 http_token name;
+
5854 http_value value;
+
5855
+
5856 protected:
+
5857 http_space m_space;
+
5858 };
+
5859
+
5863 class http_cookie : public parser
+
5864 {
+
5865 public:
+
5866 virtual bool match(
+
5867 _In_reads_or_z_(end) const char* text,
+
5868 _In_ size_t start = 0,
+
5869 _In_ size_t end = (size_t)-1,
+
5870 _In_ int flags = match_default)
+
5871 {
+
5872 assert(text || start >= end);
+
5873 interval.end = start;
+
5874 if (name.match(text, interval.end, end, flags))
+
5875 interval.end = name.interval.end;
+
5876 else
+
5877 goto error;
+
5878 while (m_space.match(text, interval.end, end, flags))
+
5879 interval.end = m_space.interval.end;
+
5880 if (interval.end < end && text[interval.end] == '=')
+
5881 interval.end++;
+
5882 else
+
5883 goto error;
+
5884 while (m_space.match(text, interval.end, end, flags))
+
5885 interval.end = m_space.interval.end;
+
5886 if (value.match(text, interval.end, end, flags))
+
5887 interval.end = value.interval.end;
+
5888 else
+
5889 goto error;
+
5890 params.clear();
+
5891 for (;;) {
+
5892 if (interval.end < end && text[interval.end]) {
+
5893 if (m_space.match(text, interval.end, end, flags))
+
5894 interval.end = m_space.interval.end;
+
5895 else if (text[interval.end] == ';') {
+
5896 interval.end++;
+
5897 while (m_space.match(text, interval.end, end, flags))
+
5898 interval.end = m_space.interval.end;
+
5899 http_cookie_parameter param;
+
5900 if (param.match(text, interval.end, end, flags)) {
+
5901 interval.end = param.interval.end;
+
5902 params.push_back(std::move(param));
+
5903 }
+
5904 else
+
5905 break;
+
5906 }
+
5907 else
+
5908 break;
+
5909 }
+
5910 else
+
5911 break;
+
5912 }
+
5913 interval.start = start;
+
5914 interval.end = params.empty() ? value.interval.end : params.back().interval.end;
+
5915 return true;
+
5916
+
5917 error:
+
5918 name.invalidate();
+
5919 value.invalidate();
+
5920 params.clear();
+
5921 interval.start = (interval.end = start) + 1;
+
5922 return false;
+
5923 }
+
5924
+
5925 virtual void invalidate()
+
5926 {
+
5927 name.invalidate();
+
5928 value.invalidate();
+
5929 params.clear();
+
5930 parser::invalidate();
+
5931 }
+
5932
+
5933 public:
+
5934 http_token name;
+
5935 http_value value;
+
5936 std::list<http_cookie_parameter> params;
+
5937
+
5938 protected:
+
5939 http_space m_space;
+
5940 };
+
5941
+
5945 class http_agent : public parser
+
5946 {
+
5947 public:
+
5948 virtual bool match(
+
5949 _In_reads_or_z_(end) const char* text,
+
5950 _In_ size_t start = 0,
+
5951 _In_ size_t end = (size_t)-1,
+
5952 _In_ int flags = match_default)
+
5953 {
+
5954 assert(text || start >= end);
+
5955 interval.end = start;
+
5956 type.start = interval.end;
+
5957 for (;;) {
+
5958 if (interval.end < end && text[interval.end]) {
+
5959 if (text[interval.end] == '/') {
+
5960 type.end = interval.end;
+
5961 interval.end++;
+
5962 version.start = interval.end;
+
5963 for (;;) {
+
5964 if (interval.end < end && text[interval.end]) {
+
5965 if (isspace(text[interval.end])) {
+
5966 version.end = interval.end;
+
5967 break;
+
5968 }
+
5969 else
+
5970 interval.end++;
+
5971 }
+
5972 else {
+
5973 version.end = interval.end;
+
5974 break;
+
5975 }
+
5976 }
+
5977 break;
+
5978 }
+
5979 else if (isspace(text[interval.end])) {
+
5980 type.end = interval.end;
+
5981 break;
+
5982 }
+
5983 else
+
5984 interval.end++;
+
5985 }
+
5986 else {
+
5987 type.end = interval.end;
+
5988 break;
+
5989 }
+
5990 }
+
5991 if (start < interval.end) {
+
5992 interval.start = start;
+
5993 return true;
+
5994 }
+
5995 type.start = 1;
+
5996 type.end = 0;
+
5997 version.start = 1;
+
5998 version.end = 0;
+
5999 interval.start = 1;
+
6000 interval.end = 0;
+
6001 return false;
+
6002 }
+
6003
+
6004 virtual void invalidate()
+
6005 {
+
6006 type.start = 1;
+
6007 type.end = 0;
+
6008 version.start = 1;
+
6009 version.end = 0;
+
6010 parser::invalidate();
+
6011 }
+
6012
+
6013 public:
+
6014 stdex::interval<size_t> type;
+
6015 stdex::interval<size_t> version;
+
6016 };
+
6017
+
6021 class http_protocol : public parser
+
6022 {
+
6023 public:
+
6024 http_protocol(_In_ const std::locale& locale = std::locale()) :
+
6025 parser(locale),
+
6026 version(0x009)
+
6027 {}
+
6028
+
6029 virtual bool match(
+
6030 _In_reads_or_z_(end) const char* text,
+
6031 _In_ size_t start = 0,
+
6032 _In_ size_t end = (size_t)-1,
+
6033 _In_ int flags = match_default)
+
6034 {
+
6035 assert(text || start >= end);
+
6036 interval.end = start;
+
6037 type.start = interval.end;
6038 for (;;) {
6039 if (interval.end < end && text[interval.end]) {
-
6040 if (text[interval.end] == '.') {
-
6041 version_maj.end = interval.end;
+
6040 if (text[interval.end] == '/') {
+
6041 type.end = interval.end;
6042 interval.end++;
-
6043 version_min.start = interval.end;
-
6044 for (;;) {
-
6045 if (interval.end < end && text[interval.end]) {
-
6046 if (isspace(text[interval.end])) {
-
6047 version_min.end = interval.end;
-
6048 version =
-
6049 (uint16_t)strtoui(text + version_maj.start, version_maj.size(), nullptr, 10) * 0x100 +
-
6050 (uint16_t)strtoui(text + version_min.start, version_min.size(), nullptr, 10);
-
6051 break;
-
6052 }
-
6053 else
-
6054 interval.end++;
-
6055 }
-
6056 else
-
6057 goto error;
-
6058 }
-
6059 break;
-
6060 }
-
6061 else if (isspace(text[interval.end])) {
-
6062 version_maj.end = interval.end;
-
6063 version_min.start = 1;
-
6064 version_min.end = 0;
-
6065 version = (uint16_t)strtoui(text + version_maj.start, version_maj.size(), nullptr, 10) * 0x100;
-
6066 break;
-
6067 }
-
6068 else
-
6069 interval.end++;
-
6070 }
-
6071 else
-
6072 goto error;
-
6073 }
-
6074 interval.start = start;
-
6075 return true;
-
6076
-
6077 error:
-
6078 type.start = 1;
-
6079 type.end = 0;
-
6080 version_maj.start = 1;
-
6081 version_maj.end = 0;
-
6082 version_min.start = 1;
-
6083 version_min.end = 0;
-
6084 version = 0x009;
-
6085 interval.start = 1;
-
6086 interval.end = 0;
-
6087 return false;
-
6088 }
-
6089
-
6090 virtual void invalidate()
-
6091 {
-
6092 type.start = 1;
-
6093 type.end = 0;
-
6094 version_maj.start = 1;
-
6095 version_maj.end = 0;
-
6096 version_min.start = 1;
-
6097 version_min.end = 0;
-
6098 version = 0x009;
-
6099 parser::invalidate();
-
6100 }
-
6101
-
6102 public:
-
6103 stdex::interval<size_t> type;
-
6104 stdex::interval<size_t> version_maj;
-
6105 stdex::interval<size_t> version_min;
-
6106 uint16_t version;
-
6107 };
-
6108
-
6112 class http_request : public parser
-
6113 {
-
6114 public:
-
6115 http_request(_In_ const std::locale& locale = std::locale()) :
-
6116 parser(locale),
-
6117 url(locale),
-
6118 protocol(locale)
-
6119 {}
-
6120
-
6121 virtual bool match(
-
6122 _In_reads_or_z_(end) const char* text,
-
6123 _In_ size_t start = 0,
-
6124 _In_ size_t end = (size_t)-1,
-
6125 _In_ int flags = match_default)
-
6126 {
-
6127 assert(text || start >= end);
-
6128 interval.end = start;
-
6129
-
6130 for (;;) {
-
6131 if (m_line_break.match(text, interval.end, end, flags))
-
6132 goto error;
-
6133 else if (interval.end < end && text[interval.end]) {
-
6134 if (isspace(text[interval.end]))
-
6135 interval.end++;
-
6136 else
-
6137 break;
-
6138 }
-
6139 else
-
6140 goto error;
-
6141 }
-
6142 verb.start = interval.end;
-
6143 for (;;) {
-
6144 if (m_line_break.match(text, interval.end, end, flags))
-
6145 goto error;
-
6146 else if (interval.end < end && text[interval.end]) {
-
6147 if (isspace(text[interval.end])) {
-
6148 verb.end = interval.end;
-
6149 interval.end++;
-
6150 break;
-
6151 }
-
6152 else
+
6043 break;
+
6044 }
+
6045 else if (isspace(text[interval.end]))
+
6046 goto error;
+
6047 else
+
6048 interval.end++;
+
6049 }
+
6050 else {
+
6051 type.end = interval.end;
+
6052 goto error;
+
6053 }
+
6054 }
+
6055 version_maj.start = interval.end;
+
6056 for (;;) {
+
6057 if (interval.end < end && text[interval.end]) {
+
6058 if (text[interval.end] == '.') {
+
6059 version_maj.end = interval.end;
+
6060 interval.end++;
+
6061 version_min.start = interval.end;
+
6062 for (;;) {
+
6063 if (interval.end < end && text[interval.end]) {
+
6064 if (isspace(text[interval.end])) {
+
6065 version_min.end = interval.end;
+
6066 version =
+
6067 (uint16_t)strtoui(text + version_maj.start, version_maj.size(), nullptr, 10) * 0x100 +
+
6068 (uint16_t)strtoui(text + version_min.start, version_min.size(), nullptr, 10);
+
6069 break;
+
6070 }
+
6071 else
+
6072 interval.end++;
+
6073 }
+
6074 else
+
6075 goto error;
+
6076 }
+
6077 break;
+
6078 }
+
6079 else if (isspace(text[interval.end])) {
+
6080 version_maj.end = interval.end;
+
6081 version_min.start = 1;
+
6082 version_min.end = 0;
+
6083 version = (uint16_t)strtoui(text + version_maj.start, version_maj.size(), nullptr, 10) * 0x100;
+
6084 break;
+
6085 }
+
6086 else
+
6087 interval.end++;
+
6088 }
+
6089 else
+
6090 goto error;
+
6091 }
+
6092 interval.start = start;
+
6093 return true;
+
6094
+
6095 error:
+
6096 type.start = 1;
+
6097 type.end = 0;
+
6098 version_maj.start = 1;
+
6099 version_maj.end = 0;
+
6100 version_min.start = 1;
+
6101 version_min.end = 0;
+
6102 version = 0x009;
+
6103 interval.start = 1;
+
6104 interval.end = 0;
+
6105 return false;
+
6106 }
+
6107
+
6108 virtual void invalidate()
+
6109 {
+
6110 type.start = 1;
+
6111 type.end = 0;
+
6112 version_maj.start = 1;
+
6113 version_maj.end = 0;
+
6114 version_min.start = 1;
+
6115 version_min.end = 0;
+
6116 version = 0x009;
+
6117 parser::invalidate();
+
6118 }
+
6119
+
6120 public:
+
6121 stdex::interval<size_t> type;
+
6122 stdex::interval<size_t> version_maj;
+
6123 stdex::interval<size_t> version_min;
+
6124 uint16_t version;
+
6125 };
+
6126
+
6130 class http_request : public parser
+
6131 {
+
6132 public:
+
6133 http_request(_In_ const std::locale& locale = std::locale()) :
+
6134 parser(locale),
+
6135 url(locale),
+
6136 protocol(locale)
+
6137 {}
+
6138
+
6139 virtual bool match(
+
6140 _In_reads_or_z_(end) const char* text,
+
6141 _In_ size_t start = 0,
+
6142 _In_ size_t end = (size_t)-1,
+
6143 _In_ int flags = match_default)
+
6144 {
+
6145 assert(text || start >= end);
+
6146 interval.end = start;
+
6147
+
6148 for (;;) {
+
6149 if (m_line_break.match(text, interval.end, end, flags))
+
6150 goto error;
+
6151 else if (interval.end < end && text[interval.end]) {
+
6152 if (isspace(text[interval.end]))
6153 interval.end++;
-
6154 }
-
6155 else
-
6156 goto error;
-
6157 }
-
6158
-
6159 for (;;) {
-
6160 if (m_line_break.match(text, interval.end, end, flags))
-
6161 goto error;
-
6162 else if (interval.end < end && text[interval.end]) {
-
6163 if (isspace(text[interval.end]))
-
6164 interval.end++;
-
6165 else
-
6166 break;
-
6167 }
-
6168 else
-
6169 goto error;
-
6170 }
-
6171 if (url.match(text, interval.end, end, flags))
-
6172 interval.end = url.interval.end;
-
6173 else
-
6174 goto error;
-
6175
-
6176 protocol.invalidate();
+
6154 else
+
6155 break;
+
6156 }
+
6157 else
+
6158 goto error;
+
6159 }
+
6160 verb.start = interval.end;
+
6161 for (;;) {
+
6162 if (m_line_break.match(text, interval.end, end, flags))
+
6163 goto error;
+
6164 else if (interval.end < end && text[interval.end]) {
+
6165 if (isspace(text[interval.end])) {
+
6166 verb.end = interval.end;
+
6167 interval.end++;
+
6168 break;
+
6169 }
+
6170 else
+
6171 interval.end++;
+
6172 }
+
6173 else
+
6174 goto error;
+
6175 }
+
6176
6177 for (;;) {
-
6178 if (m_line_break.match(text, interval.end, end, flags)) {
-
6179 interval.end = m_line_break.interval.end;
-
6180 goto end;
-
6181 }
-
6182 else if (interval.end < end && text[interval.end]) {
-
6183 if (isspace(text[interval.end]))
-
6184 interval.end++;
-
6185 else
-
6186 break;
-
6187 }
-
6188 else
-
6189 goto end;
-
6190 }
-
6191 for (;;) {
-
6192 if (m_line_break.match(text, interval.end, end, flags)) {
-
6193 interval.end = m_line_break.interval.end;
-
6194 goto end;
-
6195 }
-
6196 else if (protocol.match(text, interval.end, end, flags)) {
-
6197 interval.end = protocol.interval.end;
-
6198 break;
+
6178 if (m_line_break.match(text, interval.end, end, flags))
+
6179 goto error;
+
6180 else if (interval.end < end && text[interval.end]) {
+
6181 if (isspace(text[interval.end]))
+
6182 interval.end++;
+
6183 else
+
6184 break;
+
6185 }
+
6186 else
+
6187 goto error;
+
6188 }
+
6189 if (url.match(text, interval.end, end, flags))
+
6190 interval.end = url.interval.end;
+
6191 else
+
6192 goto error;
+
6193
+
6194 protocol.invalidate();
+
6195 for (;;) {
+
6196 if (m_line_break.match(text, interval.end, end, flags)) {
+
6197 interval.end = m_line_break.interval.end;
+
6198 goto end;
6199 }
-
6200 else
-
6201 goto end;
-
6202 }
-
6203
-
6204 for (;;) {
-
6205 if (m_line_break.match(text, interval.end, end, flags)) {
-
6206 interval.end = m_line_break.interval.end;
-
6207 break;
-
6208 }
-
6209 else if (interval.end < end && text[interval.end])
-
6210 interval.end++;
-
6211 else
+
6200 else if (interval.end < end && text[interval.end]) {
+
6201 if (isspace(text[interval.end]))
+
6202 interval.end++;
+
6203 else
+
6204 break;
+
6205 }
+
6206 else
+
6207 goto end;
+
6208 }
+
6209 for (;;) {
+
6210 if (m_line_break.match(text, interval.end, end, flags)) {
+
6211 interval.end = m_line_break.interval.end;
6212 goto end;
-
6213 }
-
6214
-
6215 end:
-
6216 interval.start = start;
-
6217 return true;
-
6218
-
6219 error:
-
6220 verb.start = 1;
-
6221 verb.end = 0;
-
6222 url.invalidate();
-
6223 protocol.invalidate();
-
6224 interval.start = 1;
-
6225 interval.end = 0;
-
6226 return false;
-
6227 }
-
6228
-
6229 virtual void invalidate()
-
6230 {
-
6231 verb.start = 1;
-
6232 verb.end = 0;
-
6233 url.invalidate();
-
6234 protocol.invalidate();
-
6235 parser::invalidate();
-
6236 }
-
6237
-
6238 public:
-
6239 stdex::interval<size_t> verb;
-
6240 http_url url;
-
6241 http_protocol protocol;
-
6242
-
6243 protected:
-
6244 http_line_break m_line_break;
-
6245 };
+
6213 }
+
6214 else if (protocol.match(text, interval.end, end, flags)) {
+
6215 interval.end = protocol.interval.end;
+
6216 break;
+
6217 }
+
6218 else
+
6219 goto end;
+
6220 }
+
6221
+
6222 for (;;) {
+
6223 if (m_line_break.match(text, interval.end, end, flags)) {
+
6224 interval.end = m_line_break.interval.end;
+
6225 break;
+
6226 }
+
6227 else if (interval.end < end && text[interval.end])
+
6228 interval.end++;
+
6229 else
+
6230 goto end;
+
6231 }
+
6232
+
6233 end:
+
6234 interval.start = start;
+
6235 return true;
+
6236
+
6237 error:
+
6238 verb.start = 1;
+
6239 verb.end = 0;
+
6240 url.invalidate();
+
6241 protocol.invalidate();
+
6242 interval.start = 1;
+
6243 interval.end = 0;
+
6244 return false;
+
6245 }
6246
-
6250 class http_header : public parser
-
6251 {
-
6252 public:
-
6253 virtual bool match(
-
6254 _In_reads_or_z_(end) const char* text,
-
6255 _In_ size_t start = 0,
-
6256 _In_ size_t end = (size_t)-1,
-
6257 _In_ int flags = match_default)
-
6258 {
-
6259 assert(text || start >= end);
-
6260 interval.end = start;
-
6261
-
6262 if (m_line_break.match(text, interval.end, end, flags) ||
-
6263 interval.end < end && text[interval.end] && isspace(text[interval.end]))
-
6264 goto error;
-
6265 name.start = interval.end;
-
6266 for (;;) {
-
6267 if (m_line_break.match(text, interval.end, end, flags))
-
6268 goto error;
-
6269 else if (interval.end < end && text[interval.end]) {
-
6270 if (isspace(text[interval.end])) {
-
6271 name.end = interval.end;
-
6272 interval.end++;
-
6273 for (;;) {
-
6274 if (m_line_break.match(text, interval.end, end, flags))
-
6275 goto error;
-
6276 else if (interval.end < end && text[interval.end]) {
-
6277 if (isspace(text[interval.end]))
-
6278 interval.end++;
-
6279 else
-
6280 break;
-
6281 }
-
6282 else
-
6283 goto error;
-
6284 }
-
6285 if (interval.end < end && text[interval.end] == ':') {
-
6286 interval.end++;
-
6287 break;
-
6288 }
-
6289 else
-
6290 goto error;
-
6291 break;
-
6292 }
-
6293 else if (text[interval.end] == ':') {
-
6294 name.end = interval.end;
-
6295 interval.end++;
-
6296 break;
-
6297 }
-
6298 else
-
6299 interval.end++;
-
6300 }
-
6301 else
-
6302 goto error;
-
6303 }
-
6304 value.start = (size_t)-1;
-
6305 value.end = 0;
-
6306 for (;;) {
-
6307 if (m_line_break.match(text, interval.end, end, flags)) {
-
6308 interval.end = m_line_break.interval.end;
-
6309 if (!m_line_break.match(text, interval.end, end, flags) &&
-
6310 interval.end < end && text[interval.end] && isspace(text[interval.end]))
-
6311 interval.end++;
-
6312 else
-
6313 break;
-
6314 }
-
6315 else if (interval.end < end && text[interval.end]) {
-
6316 if (isspace(text[interval.end]))
+
6247 virtual void invalidate()
+
6248 {
+
6249 verb.start = 1;
+
6250 verb.end = 0;
+
6251 url.invalidate();
+
6252 protocol.invalidate();
+
6253 parser::invalidate();
+
6254 }
+
6255
+
6256 public:
+
6257 stdex::interval<size_t> verb;
+
6258 http_url url;
+
6259 http_protocol protocol;
+
6260
+
6261 protected:
+
6262 http_line_break m_line_break;
+
6263 };
+
6264
+
6268 class http_header : public parser
+
6269 {
+
6270 public:
+
6271 virtual bool match(
+
6272 _In_reads_or_z_(end) const char* text,
+
6273 _In_ size_t start = 0,
+
6274 _In_ size_t end = (size_t)-1,
+
6275 _In_ int flags = match_default)
+
6276 {
+
6277 assert(text || start >= end);
+
6278 interval.end = start;
+
6279
+
6280 if (m_line_break.match(text, interval.end, end, flags) ||
+
6281 interval.end < end && text[interval.end] && isspace(text[interval.end]))
+
6282 goto error;
+
6283 name.start = interval.end;
+
6284 for (;;) {
+
6285 if (m_line_break.match(text, interval.end, end, flags))
+
6286 goto error;
+
6287 else if (interval.end < end && text[interval.end]) {
+
6288 if (isspace(text[interval.end])) {
+
6289 name.end = interval.end;
+
6290 interval.end++;
+
6291 for (;;) {
+
6292 if (m_line_break.match(text, interval.end, end, flags))
+
6293 goto error;
+
6294 else if (interval.end < end && text[interval.end]) {
+
6295 if (isspace(text[interval.end]))
+
6296 interval.end++;
+
6297 else
+
6298 break;
+
6299 }
+
6300 else
+
6301 goto error;
+
6302 }
+
6303 if (interval.end < end && text[interval.end] == ':') {
+
6304 interval.end++;
+
6305 break;
+
6306 }
+
6307 else
+
6308 goto error;
+
6309 break;
+
6310 }
+
6311 else if (text[interval.end] == ':') {
+
6312 name.end = interval.end;
+
6313 interval.end++;
+
6314 break;
+
6315 }
+
6316 else
6317 interval.end++;
-
6318 else {
-
6319 if (value.start == (size_t)-1) value.start = interval.end;
-
6320 value.end = ++interval.end;
-
6321 }
-
6322 }
-
6323 else
-
6324 break;
-
6325 }
-
6326 interval.start = start;
-
6327 return true;
-
6328
-
6329 error:
-
6330 name.start = 1;
-
6331 name.end = 0;
-
6332 value.start = 1;
-
6333 value.end = 0;
-
6334 interval.start = 1;
-
6335 interval.end = 0;
-
6336 return false;
-
6337 }
-
6338
-
6339 virtual void invalidate()
-
6340 {
-
6341 name.start = 1;
-
6342 name.end = 0;
-
6343 value.start = 1;
-
6344 value.end = 0;
-
6345 parser::invalidate();
-
6346 }
-
6347
-
6348 public:
-
6349 stdex::interval<size_t> name;
-
6350 stdex::interval<size_t> value;
-
6351
-
6352 protected:
-
6353 http_line_break m_line_break;
-
6354 };
-
6355
-
6359 template <class T>
-
6360 class http_value_collection : public T
-
6361 {
-
6362 public:
-
6363 void insert(
-
6364 _In_reads_or_z_(end) const char* text,
-
6365 _In_ size_t start = 0,
-
6366 _In_ size_t end = (size_t)-1,
-
6367 _In_ int flags = match_default)
-
6368 {
-
6369 while (start < end) {
-
6370 while (start < end && text[start] && isspace(text[start])) start++;
-
6371 if (start < end && text[start] == ',') {
-
6372 start++;
-
6373 while (start < end&& text[start] && isspace(text[start])) start++;
-
6374 }
-
6375 T::key_type el;
-
6376 if (el.match(text, start, end, flags)) {
-
6377 start = el.interval.end;
-
6378 T::insert(std::move(el));
-
6379 }
-
6380 else
-
6381 break;
-
6382 }
-
6383 }
-
6384 };
-
6385
-
6386 template <class T>
-
6387 struct http_factor_more {
-
6388 constexpr bool operator()(const T& a, const T& b) const noexcept
-
6389 {
-
6390 return a.factor.value > b.factor.value;
-
6391 }
-
6392 };
-
6393
-
6397 template <class T, class _Alloc = std::allocator<T>>
-
6398 using http_weighted_collection = http_value_collection<std::multiset<T, http_factor_more<T>, _Alloc>>;
-
6399
-
6403 template <class T>
-
6404 class basic_json_string : public basic_parser<T>
-
6405 {
-
6406 public:
-
6407 basic_json_string(
-
6408 _In_ const std::shared_ptr<basic_parser<T>>& quote,
-
6409 _In_ const std::shared_ptr<basic_parser<T>>& chr,
-
6410 _In_ const std::shared_ptr<basic_parser<T>>& escape,
-
6411 _In_ const std::shared_ptr<basic_parser<T>>& sol,
-
6412 _In_ const std::shared_ptr<basic_parser<T>>& bs,
-
6413 _In_ const std::shared_ptr<basic_parser<T>>& ff,
-
6414 _In_ const std::shared_ptr<basic_parser<T>>& lf,
-
6415 _In_ const std::shared_ptr<basic_parser<T>>& cr,
-
6416 _In_ const std::shared_ptr<basic_parser<T>>& htab,
-
6417 _In_ const std::shared_ptr<basic_parser<T>>& uni,
-
6418 _In_ const std::shared_ptr<basic_integer16<T>>& hex,
-
6419 _In_ const std::locale& locale = std::locale()) :
-
6420 basic_parser<T>(locale),
-
6421 m_quote(quote),
-
6422 m_chr(chr),
-
6423 m_escape(escape),
-
6424 m_sol(sol),
-
6425 m_bs(bs),
-
6426 m_ff(ff),
-
6427 m_lf(lf),
-
6428 m_cr(cr),
-
6429 m_htab(htab),
-
6430 m_uni(uni),
-
6431 m_hex(hex)
-
6432 {}
-
6433
-
6434 virtual bool match(
-
6435 _In_reads_or_z_(end) const T* text,
-
6436 _In_ size_t start = 0,
-
6437 _In_ size_t end = (size_t)-1,
-
6438 _In_ int flags = match_default)
-
6439 {
-
6440 assert(text || start >= end);
-
6441 interval.end = start;
-
6442 if (m_quote->match(text, interval.end, end, flags)) {
-
6443 interval.end = m_quote->interval.end;
-
6444 value.clear();
-
6445 for (;;) {
-
6446 if (m_quote->match(text, interval.end, end, flags)) {
-
6447 interval.start = start;
-
6448 interval.end = m_quote->interval.end;
-
6449 return true;
-
6450 }
-
6451 if (m_escape->match(text, interval.end, end, flags)) {
-
6452 if (m_quote->match(text, m_escape->interval.end, end, flags)) {
-
6453 value += '"'; interval.end = m_quote->interval.end;
-
6454 continue;
-
6455 }
-
6456 if (m_sol->match(text, m_escape->interval.end, end, flags)) {
-
6457 value += '/'; interval.end = m_sol->interval.end;
-
6458 continue;
-
6459 }
-
6460 if (m_bs->match(text, m_escape->interval.end, end, flags)) {
-
6461 value += '\b'; interval.end = m_bs->interval.end;
-
6462 continue;
-
6463 }
-
6464 if (m_ff->match(text, m_escape->interval.end, end, flags)) {
-
6465 value += '\f'; interval.end = m_ff->interval.end;
-
6466 continue;
-
6467 }
-
6468 if (m_lf->match(text, m_escape->interval.end, end, flags)) {
-
6469 value += '\n'; interval.end = m_lf->interval.end;
-
6470 continue;
-
6471 }
-
6472 if (m_cr->match(text, m_escape->interval.end, end, flags)) {
-
6473 value += '\r'; interval.end = m_cr->interval.end;
-
6474 continue;
-
6475 }
-
6476 if (m_htab->match(text, m_escape->interval.end, end, flags)) {
-
6477 value += '\t'; interval.end = m_htab->interval.end;
-
6478 continue;
-
6479 }
-
6480 if (
-
6481 m_uni->match(text, m_escape->interval.end, end, flags) &&
-
6482 m_hex->match(text, m_uni->interval.end, std::min(m_uni->interval.end + 4, end), flags | match_case_insensitive) &&
-
6483 m_hex->interval.size() == 4 /* JSON requests 4-digit Unicode sequneces: \u.... */)
-
6484 {
-
6485 assert(m_hex->value <= 0xffff);
-
6486 if (sizeof(T) == 1) {
-
6487 if (m_hex->value > 0x7ff) {
-
6488 value += (T)(0xe0 | (m_hex->value >> 12) & 0x0f);
-
6489 value += (T)(0x80 | (m_hex->value >> 6) & 0x3f);
-
6490 value += (T)(0x80 | m_hex->value & 0x3f);
-
6491 }
-
6492 else if (m_hex->value > 0x7f) {
-
6493 value += (T)(0xc0 | (m_hex->value >> 6) & 0x1f);
-
6494 value += (T)(0x80 | m_hex->value & 0x3f);
-
6495 }
-
6496 else
-
6497 value += (T)(m_hex->value & 0x7f);
-
6498 }
-
6499 else
-
6500 value += (T)m_hex->value;
-
6501 interval.end = m_hex->interval.end;
-
6502 continue;
-
6503 }
-
6504 if (m_escape->match(text, m_escape->interval.end, end, flags)) {
-
6505 value += '\\'; interval.end = m_escape->interval.end;
-
6506 continue;
-
6507 }
-
6508 }
-
6509 if (m_chr->match(text, interval.end, end, flags)) {
-
6510 value.Prilepi(text + m_chr->interval.start, m_chr->interval.size());
-
6511 interval.end = m_chr->interval.end;
-
6512 continue;
-
6513 }
-
6514 break;
-
6515 }
-
6516 }
-
6517 value.clear();
-
6518 interval.start = (interval.end = start) + 1;
-
6519 return false;
-
6520 }
-
6521
-
6522 virtual void invalidate()
-
6523 {
-
6524 value.clear();
-
6525 basic_parser<T>::invalidate();
-
6526 }
-
6527
-
6528 public:
-
6529 std::basic_string<T> value;
-
6530
-
6531 protected:
-
6532 std::shared_ptr<basic_parser<T>> m_quote;
-
6533 std::shared_ptr<basic_parser<T>> m_chr;
-
6534 std::shared_ptr<basic_parser<T>> m_escape;
-
6535 std::shared_ptr<basic_parser<T>> m_sol;
-
6536 std::shared_ptr<basic_parser<T>> m_bs;
-
6537 std::shared_ptr<basic_parser<T>> m_ff;
-
6538 std::shared_ptr<basic_parser<T>> m_lf;
-
6539 std::shared_ptr<basic_parser<T>> m_cr;
-
6540 std::shared_ptr<basic_parser<T>> m_htab;
-
6541 std::shared_ptr<basic_parser<T>> m_uni;
-
6542 std::shared_ptr<basic_integer16<T>> m_hex;
-
6543 };
-
6544
-
6545 using json_string = basic_json_string<char>;
-
6546 using wjson_string = basic_json_string<wchar_t>;
-
6547#ifdef _UNICODE
-
6548 using tjson_string = wjson_string;
-
6549#else
-
6550 using tjson_string = json_string;
-
6551#endif
-
6552 }
-
6553}
-
6554
-
6555#ifdef _MSC_VER
-
6556#pragma warning(pop)
-
6557#endif
-
stdex::parser::basic_angle
Test for angle in d°mm'ss.dddd form.
Definition parser.hpp:4369
-
stdex::parser::basic_any_cu
Test for any code unit.
Definition parser.hpp:200
-
stdex::parser::basic_bol
Test for beginning of line.
Definition parser.hpp:594
-
stdex::parser::basic_branch
Test for any.
Definition parser.hpp:1036
-
stdex::parser::basic_chemical_formula
Test for chemical formula.
Definition parser.hpp:4643
-
stdex::parser::basic_cu_set
Test for any code unit from a given string of code units.
Definition parser.hpp:699
-
stdex::parser::basic_cu
Test for specific code unit.
Definition parser.hpp:270
-
stdex::parser::basic_date
Test for date.
Definition parser.hpp:3989
-
stdex::parser::basic_dns_domain_char
Test for valid DNS domain character.
Definition parser.hpp:2784
-
stdex::parser::basic_dns_domain_char::allow_on_edge
bool allow_on_edge
Is character allowed at the beginning or an end of a DNS domain?
Definition parser.hpp:2822
-
stdex::parser::basic_dns_name
Test for DNS domain/hostname.
Definition parser.hpp:2884
-
stdex::parser::basic_dns_name::m_allow_absolute
bool m_allow_absolute
May DNS names end with a dot (absolute name)?
Definition parser.hpp:2948
-
stdex::parser::basic_email_address
Test for e-mail address.
Definition parser.hpp:3772
-
stdex::parser::basic_emoticon
Test for emoticon.
Definition parser.hpp:3880
-
stdex::parser::basic_emoticon::apex
std::shared_ptr< basic_parser< T > > apex
apex/eyebrows/halo (e.g. O, 0)
Definition parser.hpp:3969
-
stdex::parser::basic_emoticon::eyes
std::shared_ptr< basic_parser< T > > eyes
eyes (e.g. :, ;, >, |, B)
Definition parser.hpp:3970
-
stdex::parser::basic_emoticon::mouth
std::shared_ptr< basic_set< T > > mouth
mouth (e.g. ), ), (, (, |, P, D, p, d)
Definition parser.hpp:3972
-
stdex::parser::basic_emoticon::nose
std::shared_ptr< basic_parser< T > > nose
nose (e.g. -, o)
Definition parser.hpp:3971
-
stdex::parser::basic_emoticon::emoticon
std::shared_ptr< basic_parser< T > > emoticon
emoticon as a whole (e.g. 😀, 🤔, 😶)
Definition parser.hpp:3968
-
stdex::parser::basic_eol
Test for end of line.
Definition parser.hpp:632
-
stdex::parser::basic_fraction
Test for fraction.
Definition parser.hpp:1665
-
stdex::parser::basic_integer10
Test for decimal integer.
Definition parser.hpp:1274
-
stdex::parser::basic_integer10ts
Test for decimal integer possibly containing thousand separators.
Definition parser.hpp:1359
-
stdex::parser::basic_integer10ts::has_separators
bool has_separators
Did integer have any separators?
Definition parser.hpp:1419
-
stdex::parser::basic_integer10ts::digit_count
size_t digit_count
Total number of digits in integer.
Definition parser.hpp:1418
-
stdex::parser::basic_integer16
Test for hexadecimal integer.
Definition parser.hpp:1440
-
stdex::parser::basic_integer
Base class for integer testing.
Definition parser.hpp:1252
-
stdex::parser::basic_integer::value
size_t value
Calculated value of the numeral.
Definition parser.hpp:1266
-
stdex::parser::basic_ipv4_address
Test for IPv4 address.
Definition parser.hpp:2324
-
stdex::parser::basic_ipv4_address::components
stdex::interval< size_t > components[4]
Individual component intervals.
Definition parser.hpp:2439
-
stdex::parser::basic_ipv4_address::value
struct in_addr value
IPv4 address value.
Definition parser.hpp:2440
-
stdex::parser::basic_ipv6_address
Test for IPv6 address.
Definition parser.hpp:2543
-
stdex::parser::basic_ipv6_address::scope_id
std::shared_ptr< basic_parser< T > > scope_id
Scope ID (e.g. NIC index with link-local addresses)
Definition parser.hpp:2747
-
stdex::parser::basic_ipv6_address::components
stdex::interval< size_t > components[8]
Individual component intervals.
Definition parser.hpp:2745
-
stdex::parser::basic_ipv6_address::value
struct in6_addr value
IPv6 address value.
Definition parser.hpp:2746
-
stdex::parser::basic_ipv6_scope_id_char
Test for valid IPv6 address scope ID character.
Definition parser.hpp:2471
-
stdex::parser::basic_iterations
Test for repeating.
Definition parser.hpp:889
-
stdex::parser::basic_iterations::m_greedy
bool m_greedy
try to match as long sequence as possible
Definition parser.hpp:928
-
stdex::parser::basic_iterations::m_el
std::shared_ptr< basic_parser< T > > m_el
repeating element
Definition parser.hpp:925
-
stdex::parser::basic_iterations::m_min_iterations
size_t m_min_iterations
minimum number of iterations
Definition parser.hpp:926
-
stdex::parser::basic_iterations::m_max_iterations
size_t m_max_iterations
maximum number of iterations
Definition parser.hpp:927
-
stdex::parser::basic_json_string
Test for JSON string.
Definition parser.hpp:6405
-
stdex::parser::basic_mixed_numeral
Test for mixed numeral.
Definition parser.hpp:1900
-
stdex::parser::basic_mixed_numeral::fraction
std::shared_ptr< basic_parser< T > > fraction
fraction
Definition parser.hpp:2006
-
stdex::parser::basic_mixed_numeral::special_sign
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2004
-
stdex::parser::basic_mixed_numeral::negative_sign
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2003
-
stdex::parser::basic_mixed_numeral::positive_sign
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2002
-
stdex::parser::basic_mixed_numeral::integer
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2005
-
stdex::parser::basic_monetary_numeral
Test for monetary numeral.
Definition parser.hpp:2195
-
stdex::parser::basic_monetary_numeral::positive_sign
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2301
-
stdex::parser::basic_monetary_numeral::decimal_separator
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2306
-
stdex::parser::basic_monetary_numeral::currency
std::shared_ptr< basic_parser< T > > currency
Currency part.
Definition parser.hpp:2304
-
stdex::parser::basic_monetary_numeral::decimal
std::shared_ptr< basic_parser< T > > decimal
Decimal part.
Definition parser.hpp:2307
-
stdex::parser::basic_monetary_numeral::integer
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2305
-
stdex::parser::basic_monetary_numeral::negative_sign
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2302
-
stdex::parser::basic_monetary_numeral::special_sign
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2303
-
stdex::parser::basic_noop
"No-op" match
Definition parser.hpp:168
-
stdex::parser::basic_parser
Base template for all parsers.
Definition parser.hpp:49
-
stdex::parser::basic_parser::interval
interval< size_t > interval
Region of the last match.
Definition parser.hpp:148
-
stdex::parser::basic_permutation
Test for permutation.
Definition parser.hpp:1176
-
stdex::parser::basic_phone_number
Test for phone number.
Definition parser.hpp:4492
-
stdex::parser::basic_phone_number::value
std::basic_string< T > value
Normalized phone number.
Definition parser.hpp:4618
-
stdex::parser::basic_punct_cu
Test for any punctuation code unit.
Definition parser.hpp:442
-
stdex::parser::basic_roman_numeral
Test for Roman numeral.
Definition parser.hpp:1549
-
stdex::parser::basic_scientific_numeral
Test for scientific numeral.
Definition parser.hpp:2026
-
stdex::parser::basic_scientific_numeral::special_sign
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2170
-
stdex::parser::basic_scientific_numeral::exponent_symbol
std::shared_ptr< basic_parser< T > > exponent_symbol
Exponent symbol (e.g. 'e')
Definition parser.hpp:2174
-
stdex::parser::basic_scientific_numeral::positive_sign
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2168
-
stdex::parser::basic_scientific_numeral::negative_sign
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2169
-
stdex::parser::basic_scientific_numeral::value
double value
Calculated value of the numeral.
Definition parser.hpp:2178
-
stdex::parser::basic_scientific_numeral::negative_exp_sign
std::shared_ptr< basic_parser< T > > negative_exp_sign
Negative exponent sign (e.g. '-')
Definition parser.hpp:2176
-
stdex::parser::basic_scientific_numeral::decimal
std::shared_ptr< basic_integer< T > > decimal
Decimal part.
Definition parser.hpp:2173
-
stdex::parser::basic_scientific_numeral::positive_exp_sign
std::shared_ptr< basic_parser< T > > positive_exp_sign
Positive exponent sign (e.g. '+')
Definition parser.hpp:2175
-
stdex::parser::basic_scientific_numeral::exponent
std::shared_ptr< basic_integer< T > > exponent
Exponent part.
Definition parser.hpp:2177
-
stdex::parser::basic_scientific_numeral::decimal_separator
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2172
-
stdex::parser::basic_scientific_numeral::integer
std::shared_ptr< basic_integer< T > > integer
Integer part.
Definition parser.hpp:2171
-
stdex::parser::basic_score
Test for match score.
Definition parser.hpp:1728
-
stdex::parser::basic_sequence
Test for sequence.
Definition parser.hpp:985
-
stdex::parser::basic_set
Definition parser.hpp:667
-
stdex::parser::basic_signed_numeral
Test for signed numeral.
Definition parser.hpp:1814
-
stdex::parser::basic_signed_numeral::special_sign
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:1882
-
stdex::parser::basic_signed_numeral::negative_sign
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:1881
-
stdex::parser::basic_signed_numeral::positive_sign
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:1880
-
stdex::parser::basic_signed_numeral::number
std::shared_ptr< basic_parser< T > > number
Number.
Definition parser.hpp:1883
-
stdex::parser::basic_space_cu
Test for any space code unit.
Definition parser.hpp:363
-
stdex::parser::basic_space_or_punct_cu
Test for any space or punctuation code unit.
Definition parser.hpp:516
-
stdex::parser::basic_string_branch
Test for any string.
Definition parser.hpp:1104
-
stdex::parser::basic_string
Test for given string.
Definition parser.hpp:794
-
stdex::parser::basic_time
Test for time.
Definition parser.hpp:4266
-
stdex::parser::basic_url_password_char
Test for valid URL password character.
Definition parser.hpp:3066
-
stdex::parser::basic_url_path_char
Test for valid URL path character.
Definition parser.hpp:3166
-
stdex::parser::basic_url_path
Test for URL path.
Definition parser.hpp:3274
-
stdex::parser::basic_url_username_char
Test for valid URL username character.
Definition parser.hpp:2967
-
stdex::parser::basic_url
Test for URL.
Definition parser.hpp:3415
-
stdex::parser::http_agent
Test for HTTP agent.
Definition parser.hpp:5928
-
stdex::parser::http_any_type
Test for HTTP any type.
Definition parser.hpp:5050
-
stdex::parser::http_asterisk
Test for HTTP asterisk.
Definition parser.hpp:5692
- - - - - -
stdex::parser::http_header
Test for HTTP header.
Definition parser.hpp:6251
-
stdex::parser::http_language
Test for HTTP language (RFC1766)
Definition parser.hpp:5560
-
stdex::parser::http_line_break
Test for HTTP line break (RFC2616: CRLF | LF)
Definition parser.hpp:4724
-
stdex::parser::http_media_range
Test for HTTP media range (RFC2616: media-range)
Definition parser.hpp:5082
-
stdex::parser::http_media_type
Test for HTTP media type (RFC2616: media-type)
Definition parser.hpp:5137
-
stdex::parser::http_parameter
Test for HTTP parameter (RFC2616: parameter)
Definition parser.hpp:4995
-
stdex::parser::http_parameter::name
http_token name
Parameter name.
Definition parser.hpp:5039
-
stdex::parser::http_parameter::value
http_value value
Parameter value.
Definition parser.hpp:5040
-
stdex::parser::http_protocol
Test for HTTP protocol.
Definition parser.hpp:6004
-
stdex::parser::http_protocol::version
uint16_t version
HTTP protocol version: 0x100 = 1.0, 0x101 = 1.1...
Definition parser.hpp:6106
-
stdex::parser::http_quoted_string
Test for HTTP quoted string (RFC2616: quoted-string)
Definition parser.hpp:4885
-
stdex::parser::http_quoted_string::content
stdex::interval< size_t > content
String content (without quotes)
Definition parser.hpp:4941
-
stdex::parser::http_request
Test for HTTP request.
Definition parser.hpp:6113
-
stdex::parser::http_space
Test for HTTP space (RFC2616: LWS)
Definition parser.hpp:4760
-
stdex::parser::http_text_char
Test for HTTP text character (RFC2616: TEXT)
Definition parser.hpp:4797
-
stdex::parser::http_token
Test for HTTP token (RFC2616: token - tolerates non-ASCII)
Definition parser.hpp:4831
-
stdex::parser::http_url_parameter
Test for HTTP URL parameter.
Definition parser.hpp:5377
-
stdex::parser::http_url_path_segment
Test for HTTP URL path segment.
Definition parser.hpp:5288
-
stdex::parser::http_url_path
Test for HTTP URL path segment.
Definition parser.hpp:5321
-
stdex::parser::http_url_path::segments
std::vector< http_url_path_segment > segments
Path segments.
Definition parser.hpp:5370
-
stdex::parser::http_url_port
Test for HTTP URL port.
Definition parser.hpp:5232
-
stdex::parser::http_url_server
Test for HTTP URL server.
Definition parser.hpp:5195
-
stdex::parser::http_url
Test for HTTP URL.
Definition parser.hpp:5458
-
stdex::parser::http_value_collection
Collection of HTTP values.
Definition parser.hpp:6361
-
stdex::parser::http_value
Test for HTTP value (RFC2616: value)
Definition parser.hpp:4951
-
stdex::parser::http_value::string
http_quoted_string string
Value when matched as quoted string.
Definition parser.hpp:4987
-
stdex::parser::http_value::token
http_token token
Value when matched as token.
Definition parser.hpp:4988
-
stdex::parser::http_weight
Test for HTTP weight factor.
Definition parser.hpp:5623
-
stdex::parser::http_weight::value
float value
Calculated value of the weight factor.
Definition parser.hpp:5685
-
stdex::parser::http_weighted_value
Test for HTTP weighted value.
Definition parser.hpp:5715
-
stdex::parser::parser_collection
Base template for collection-holding parsers.
Definition parser.hpp:945
-
stdex::parser::sgml_any_cp
Test for any SGML code point.
Definition parser.hpp:232
-
stdex::parser::sgml_cp_set
Test for any SGML code point from a given string of SGML code points.
Definition parser.hpp:751
-
stdex::parser::sgml_cp
Test for specific SGML code point.
Definition parser.hpp:319
-
stdex::parser::sgml_dns_domain_char
Test for valid DNS domain SGML character.
Definition parser.hpp:2840
-
stdex::parser::sgml_ipv6_scope_id_char
Test for valid IPv6 address scope ID SGML character.
Definition parser.hpp:2509
-
stdex::parser::sgml_punct_cp
Test for any SGML punctuation code point.
Definition parser.hpp:483
-
stdex::parser::sgml_space_cp
Test for any SGML space code point.
Definition parser.hpp:406
-
stdex::parser::sgml_space_or_punct_cp
Test for any SGML space or punctuation code point.
Definition parser.hpp:559
-
stdex::parser::sgml_string
Test for SGML given string.
Definition parser.hpp:841
-
stdex::parser::sgml_url_password_char
Test for valid URL password SGML character.
Definition parser.hpp:3118
-
stdex::parser::sgml_url_path_char
Test for valid URL path SGML character.
Definition parser.hpp:3222
-
stdex::parser::sgml_url_username_char
Test for valid URL username SGML character.
Definition parser.hpp:3018
+
6318 }
+
6319 else
+
6320 goto error;
+
6321 }
+
6322 value.start = (size_t)-1;
+
6323 value.end = 0;
+
6324 for (;;) {
+
6325 if (m_line_break.match(text, interval.end, end, flags)) {
+
6326 interval.end = m_line_break.interval.end;
+
6327 if (!m_line_break.match(text, interval.end, end, flags) &&
+
6328 interval.end < end && text[interval.end] && isspace(text[interval.end]))
+
6329 interval.end++;
+
6330 else
+
6331 break;
+
6332 }
+
6333 else if (interval.end < end && text[interval.end]) {
+
6334 if (isspace(text[interval.end]))
+
6335 interval.end++;
+
6336 else {
+
6337 if (value.start == (size_t)-1) value.start = interval.end;
+
6338 value.end = ++interval.end;
+
6339 }
+
6340 }
+
6341 else
+
6342 break;
+
6343 }
+
6344 interval.start = start;
+
6345 return true;
+
6346
+
6347 error:
+
6348 name.start = 1;
+
6349 name.end = 0;
+
6350 value.start = 1;
+
6351 value.end = 0;
+
6352 interval.start = 1;
+
6353 interval.end = 0;
+
6354 return false;
+
6355 }
+
6356
+
6357 virtual void invalidate()
+
6358 {
+
6359 name.start = 1;
+
6360 name.end = 0;
+
6361 value.start = 1;
+
6362 value.end = 0;
+
6363 parser::invalidate();
+
6364 }
+
6365
+
6366 public:
+
6367 stdex::interval<size_t> name;
+
6368 stdex::interval<size_t> value;
+
6369
+
6370 protected:
+
6371 http_line_break m_line_break;
+
6372 };
+
6373
+
6377 template <class T>
+
6378 class http_value_collection : public T
+
6379 {
+
6380 public:
+
6381 void insert(
+
6382 _In_reads_or_z_(end) const char* text,
+
6383 _In_ size_t start = 0,
+
6384 _In_ size_t end = (size_t)-1,
+
6385 _In_ int flags = match_default)
+
6386 {
+
6387 while (start < end) {
+
6388 while (start < end && text[start] && isspace(text[start])) start++;
+
6389 if (start < end && text[start] == ',') {
+
6390 start++;
+
6391 while (start < end&& text[start] && isspace(text[start])) start++;
+
6392 }
+
6393 T::key_type el;
+
6394 if (el.match(text, start, end, flags)) {
+
6395 start = el.interval.end;
+
6396 T::insert(std::move(el));
+
6397 }
+
6398 else
+
6399 break;
+
6400 }
+
6401 }
+
6402 };
+
6403
+
6404 template <class T>
+
6405 struct http_factor_more {
+
6406 constexpr bool operator()(const T& a, const T& b) const noexcept
+
6407 {
+
6408 return a.factor.value > b.factor.value;
+
6409 }
+
6410 };
+
6411
+
6415 template <class T, class _Alloc = std::allocator<T>>
+
6416 using http_weighted_collection = http_value_collection<std::multiset<T, http_factor_more<T>, _Alloc>>;
+
6417
+
6421 template <class T>
+
6422 class basic_json_string : public basic_parser<T>
+
6423 {
+
6424 public:
+
6425 basic_json_string(
+
6426 _In_ const std::shared_ptr<basic_parser<T>>& quote,
+
6427 _In_ const std::shared_ptr<basic_parser<T>>& chr,
+
6428 _In_ const std::shared_ptr<basic_parser<T>>& escape,
+
6429 _In_ const std::shared_ptr<basic_parser<T>>& sol,
+
6430 _In_ const std::shared_ptr<basic_parser<T>>& bs,
+
6431 _In_ const std::shared_ptr<basic_parser<T>>& ff,
+
6432 _In_ const std::shared_ptr<basic_parser<T>>& lf,
+
6433 _In_ const std::shared_ptr<basic_parser<T>>& cr,
+
6434 _In_ const std::shared_ptr<basic_parser<T>>& htab,
+
6435 _In_ const std::shared_ptr<basic_parser<T>>& uni,
+
6436 _In_ const std::shared_ptr<basic_integer16<T>>& hex,
+
6437 _In_ const std::locale& locale = std::locale()) :
+
6438 basic_parser<T>(locale),
+
6439 m_quote(quote),
+
6440 m_chr(chr),
+
6441 m_escape(escape),
+
6442 m_sol(sol),
+
6443 m_bs(bs),
+
6444 m_ff(ff),
+
6445 m_lf(lf),
+
6446 m_cr(cr),
+
6447 m_htab(htab),
+
6448 m_uni(uni),
+
6449 m_hex(hex)
+
6450 {}
+
6451
+
6452 virtual bool match(
+
6453 _In_reads_or_z_(end) const T* text,
+
6454 _In_ size_t start = 0,
+
6455 _In_ size_t end = (size_t)-1,
+
6456 _In_ int flags = match_default)
+
6457 {
+
6458 assert(text || start >= end);
+
6459 interval.end = start;
+
6460 if (m_quote->match(text, interval.end, end, flags)) {
+
6461 interval.end = m_quote->interval.end;
+
6462 value.clear();
+
6463 for (;;) {
+
6464 if (m_quote->match(text, interval.end, end, flags)) {
+
6465 interval.start = start;
+
6466 interval.end = m_quote->interval.end;
+
6467 return true;
+
6468 }
+
6469 if (m_escape->match(text, interval.end, end, flags)) {
+
6470 if (m_quote->match(text, m_escape->interval.end, end, flags)) {
+
6471 value += '"'; interval.end = m_quote->interval.end;
+
6472 continue;
+
6473 }
+
6474 if (m_sol->match(text, m_escape->interval.end, end, flags)) {
+
6475 value += '/'; interval.end = m_sol->interval.end;
+
6476 continue;
+
6477 }
+
6478 if (m_bs->match(text, m_escape->interval.end, end, flags)) {
+
6479 value += '\b'; interval.end = m_bs->interval.end;
+
6480 continue;
+
6481 }
+
6482 if (m_ff->match(text, m_escape->interval.end, end, flags)) {
+
6483 value += '\f'; interval.end = m_ff->interval.end;
+
6484 continue;
+
6485 }
+
6486 if (m_lf->match(text, m_escape->interval.end, end, flags)) {
+
6487 value += '\n'; interval.end = m_lf->interval.end;
+
6488 continue;
+
6489 }
+
6490 if (m_cr->match(text, m_escape->interval.end, end, flags)) {
+
6491 value += '\r'; interval.end = m_cr->interval.end;
+
6492 continue;
+
6493 }
+
6494 if (m_htab->match(text, m_escape->interval.end, end, flags)) {
+
6495 value += '\t'; interval.end = m_htab->interval.end;
+
6496 continue;
+
6497 }
+
6498 if (
+
6499 m_uni->match(text, m_escape->interval.end, end, flags) &&
+
6500 m_hex->match(text, m_uni->interval.end, std::min(m_uni->interval.end + 4, end), flags | match_case_insensitive) &&
+
6501 m_hex->interval.size() == 4 /* JSON requests 4-digit Unicode sequneces: \u.... */)
+
6502 {
+
6503 assert(m_hex->value <= 0xffff);
+
6504 if (sizeof(T) == 1) {
+
6505 if (m_hex->value > 0x7ff) {
+
6506 value += (T)(0xe0 | (m_hex->value >> 12) & 0x0f);
+
6507 value += (T)(0x80 | (m_hex->value >> 6) & 0x3f);
+
6508 value += (T)(0x80 | m_hex->value & 0x3f);
+
6509 }
+
6510 else if (m_hex->value > 0x7f) {
+
6511 value += (T)(0xc0 | (m_hex->value >> 6) & 0x1f);
+
6512 value += (T)(0x80 | m_hex->value & 0x3f);
+
6513 }
+
6514 else
+
6515 value += (T)(m_hex->value & 0x7f);
+
6516 }
+
6517 else
+
6518 value += (T)m_hex->value;
+
6519 interval.end = m_hex->interval.end;
+
6520 continue;
+
6521 }
+
6522 if (m_escape->match(text, m_escape->interval.end, end, flags)) {
+
6523 value += '\\'; interval.end = m_escape->interval.end;
+
6524 continue;
+
6525 }
+
6526 }
+
6527 if (m_chr->match(text, interval.end, end, flags)) {
+
6528 value.Prilepi(text + m_chr->interval.start, m_chr->interval.size());
+
6529 interval.end = m_chr->interval.end;
+
6530 continue;
+
6531 }
+
6532 break;
+
6533 }
+
6534 }
+
6535 value.clear();
+
6536 interval.start = (interval.end = start) + 1;
+
6537 return false;
+
6538 }
+
6539
+
6540 virtual void invalidate()
+
6541 {
+
6542 value.clear();
+
6543 basic_parser<T>::invalidate();
+
6544 }
+
6545
+
6546 public:
+
6547 std::basic_string<T> value;
+
6548
+
6549 protected:
+
6550 std::shared_ptr<basic_parser<T>> m_quote;
+
6551 std::shared_ptr<basic_parser<T>> m_chr;
+
6552 std::shared_ptr<basic_parser<T>> m_escape;
+
6553 std::shared_ptr<basic_parser<T>> m_sol;
+
6554 std::shared_ptr<basic_parser<T>> m_bs;
+
6555 std::shared_ptr<basic_parser<T>> m_ff;
+
6556 std::shared_ptr<basic_parser<T>> m_lf;
+
6557 std::shared_ptr<basic_parser<T>> m_cr;
+
6558 std::shared_ptr<basic_parser<T>> m_htab;
+
6559 std::shared_ptr<basic_parser<T>> m_uni;
+
6560 std::shared_ptr<basic_integer16<T>> m_hex;
+
6561 };
+
6562
+
6563 using json_string = basic_json_string<char>;
+
6564 using wjson_string = basic_json_string<wchar_t>;
+
6565#ifdef _UNICODE
+
6566 using tjson_string = wjson_string;
+
6567#else
+
6568 using tjson_string = json_string;
+
6569#endif
+
6570 }
+
6571}
+
6572
+
6573#undef ENUM_FLAG_OPERATOR
+
6574#undef ENUM_FLAGS
+
6575
+
6576#ifdef _MSC_VER
+
6577#pragma warning(pop)
+
6578#endif
+
stdex::parser::basic_angle
Test for angle in d°mm'ss.dddd form.
Definition parser.hpp:4387
+
stdex::parser::basic_any_cu
Test for any code unit.
Definition parser.hpp:214
+
stdex::parser::basic_bol
Test for beginning of line.
Definition parser.hpp:608
+
stdex::parser::basic_branch
Test for any.
Definition parser.hpp:1050
+
stdex::parser::basic_chemical_formula
Test for chemical formula.
Definition parser.hpp:4661
+
stdex::parser::basic_cu_set
Test for any code unit from a given string of code units.
Definition parser.hpp:713
+
stdex::parser::basic_cu
Test for specific code unit.
Definition parser.hpp:284
+
stdex::parser::basic_date
Test for date.
Definition parser.hpp:4017
+
stdex::parser::basic_dns_domain_char
Test for valid DNS domain character.
Definition parser.hpp:2798
+
stdex::parser::basic_dns_domain_char::allow_on_edge
bool allow_on_edge
Is character allowed at the beginning or an end of a DNS domain?
Definition parser.hpp:2836
+
stdex::parser::basic_dns_name
Test for DNS domain/hostname.
Definition parser.hpp:2898
+
stdex::parser::basic_dns_name::m_allow_absolute
bool m_allow_absolute
May DNS names end with a dot (absolute name)?
Definition parser.hpp:2962
+
stdex::parser::basic_email_address
Test for e-mail address.
Definition parser.hpp:3786
+
stdex::parser::basic_emoticon
Test for emoticon.
Definition parser.hpp:3894
+
stdex::parser::basic_emoticon::apex
std::shared_ptr< basic_parser< T > > apex
apex/eyebrows/halo (e.g. O, 0)
Definition parser.hpp:3983
+
stdex::parser::basic_emoticon::eyes
std::shared_ptr< basic_parser< T > > eyes
eyes (e.g. :, ;, >, |, B)
Definition parser.hpp:3984
+
stdex::parser::basic_emoticon::mouth
std::shared_ptr< basic_set< T > > mouth
mouth (e.g. ), ), (, (, |, P, D, p, d)
Definition parser.hpp:3986
+
stdex::parser::basic_emoticon::nose
std::shared_ptr< basic_parser< T > > nose
nose (e.g. -, o)
Definition parser.hpp:3985
+
stdex::parser::basic_emoticon::emoticon
std::shared_ptr< basic_parser< T > > emoticon
emoticon as a whole (e.g. 😀, 🤔, 😶)
Definition parser.hpp:3982
+
stdex::parser::basic_eol
Test for end of line.
Definition parser.hpp:646
+
stdex::parser::basic_fraction
Test for fraction.
Definition parser.hpp:1679
+
stdex::parser::basic_integer10
Test for decimal integer.
Definition parser.hpp:1288
+
stdex::parser::basic_integer10ts
Test for decimal integer possibly containing thousand separators.
Definition parser.hpp:1373
+
stdex::parser::basic_integer10ts::has_separators
bool has_separators
Did integer have any separators?
Definition parser.hpp:1433
+
stdex::parser::basic_integer10ts::digit_count
size_t digit_count
Total number of digits in integer.
Definition parser.hpp:1432
+
stdex::parser::basic_integer16
Test for hexadecimal integer.
Definition parser.hpp:1454
+
stdex::parser::basic_integer
Base class for integer testing.
Definition parser.hpp:1266
+
stdex::parser::basic_integer::value
size_t value
Calculated value of the numeral.
Definition parser.hpp:1280
+
stdex::parser::basic_ipv4_address
Test for IPv4 address.
Definition parser.hpp:2338
+
stdex::parser::basic_ipv4_address::components
stdex::interval< size_t > components[4]
Individual component intervals.
Definition parser.hpp:2453
+
stdex::parser::basic_ipv4_address::value
struct in_addr value
IPv4 address value.
Definition parser.hpp:2454
+
stdex::parser::basic_ipv6_address
Test for IPv6 address.
Definition parser.hpp:2557
+
stdex::parser::basic_ipv6_address::scope_id
std::shared_ptr< basic_parser< T > > scope_id
Scope ID (e.g. NIC index with link-local addresses)
Definition parser.hpp:2761
+
stdex::parser::basic_ipv6_address::components
stdex::interval< size_t > components[8]
Individual component intervals.
Definition parser.hpp:2759
+
stdex::parser::basic_ipv6_address::value
struct in6_addr value
IPv6 address value.
Definition parser.hpp:2760
+
stdex::parser::basic_ipv6_scope_id_char
Test for valid IPv6 address scope ID character.
Definition parser.hpp:2485
+
stdex::parser::basic_iterations
Test for repeating.
Definition parser.hpp:903
+
stdex::parser::basic_iterations::m_greedy
bool m_greedy
try to match as long sequence as possible
Definition parser.hpp:942
+
stdex::parser::basic_iterations::m_el
std::shared_ptr< basic_parser< T > > m_el
repeating element
Definition parser.hpp:939
+
stdex::parser::basic_iterations::m_min_iterations
size_t m_min_iterations
minimum number of iterations
Definition parser.hpp:940
+
stdex::parser::basic_iterations::m_max_iterations
size_t m_max_iterations
maximum number of iterations
Definition parser.hpp:941
+
stdex::parser::basic_json_string
Test for JSON string.
Definition parser.hpp:6423
+
stdex::parser::basic_mixed_numeral
Test for mixed numeral.
Definition parser.hpp:1914
+
stdex::parser::basic_mixed_numeral::fraction
std::shared_ptr< basic_parser< T > > fraction
fraction
Definition parser.hpp:2020
+
stdex::parser::basic_mixed_numeral::special_sign
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2018
+
stdex::parser::basic_mixed_numeral::negative_sign
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2017
+
stdex::parser::basic_mixed_numeral::positive_sign
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2016
+
stdex::parser::basic_mixed_numeral::integer
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2019
+
stdex::parser::basic_monetary_numeral
Test for monetary numeral.
Definition parser.hpp:2209
+
stdex::parser::basic_monetary_numeral::positive_sign
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2315
+
stdex::parser::basic_monetary_numeral::decimal_separator
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2320
+
stdex::parser::basic_monetary_numeral::currency
std::shared_ptr< basic_parser< T > > currency
Currency part.
Definition parser.hpp:2318
+
stdex::parser::basic_monetary_numeral::decimal
std::shared_ptr< basic_parser< T > > decimal
Decimal part.
Definition parser.hpp:2321
+
stdex::parser::basic_monetary_numeral::integer
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2319
+
stdex::parser::basic_monetary_numeral::negative_sign
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2316
+
stdex::parser::basic_monetary_numeral::special_sign
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2317
+
stdex::parser::basic_noop
"No-op" match
Definition parser.hpp:182
+
stdex::parser::basic_parser
Base template for all parsers.
Definition parser.hpp:63
+
stdex::parser::basic_parser::interval
interval< size_t > interval
Region of the last match.
Definition parser.hpp:162
+
stdex::parser::basic_permutation
Test for permutation.
Definition parser.hpp:1190
+
stdex::parser::basic_phone_number
Test for phone number.
Definition parser.hpp:4510
+
stdex::parser::basic_phone_number::value
std::basic_string< T > value
Normalized phone number.
Definition parser.hpp:4636
+
stdex::parser::basic_punct_cu
Test for any punctuation code unit.
Definition parser.hpp:456
+
stdex::parser::basic_roman_numeral
Test for Roman numeral.
Definition parser.hpp:1563
+
stdex::parser::basic_scientific_numeral
Test for scientific numeral.
Definition parser.hpp:2040
+
stdex::parser::basic_scientific_numeral::special_sign
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2184
+
stdex::parser::basic_scientific_numeral::exponent_symbol
std::shared_ptr< basic_parser< T > > exponent_symbol
Exponent symbol (e.g. 'e')
Definition parser.hpp:2188
+
stdex::parser::basic_scientific_numeral::positive_sign
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2182
+
stdex::parser::basic_scientific_numeral::negative_sign
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2183
+
stdex::parser::basic_scientific_numeral::value
double value
Calculated value of the numeral.
Definition parser.hpp:2192
+
stdex::parser::basic_scientific_numeral::negative_exp_sign
std::shared_ptr< basic_parser< T > > negative_exp_sign
Negative exponent sign (e.g. '-')
Definition parser.hpp:2190
+
stdex::parser::basic_scientific_numeral::decimal
std::shared_ptr< basic_integer< T > > decimal
Decimal part.
Definition parser.hpp:2187
+
stdex::parser::basic_scientific_numeral::positive_exp_sign
std::shared_ptr< basic_parser< T > > positive_exp_sign
Positive exponent sign (e.g. '+')
Definition parser.hpp:2189
+
stdex::parser::basic_scientific_numeral::exponent
std::shared_ptr< basic_integer< T > > exponent
Exponent part.
Definition parser.hpp:2191
+
stdex::parser::basic_scientific_numeral::decimal_separator
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2186
+
stdex::parser::basic_scientific_numeral::integer
std::shared_ptr< basic_integer< T > > integer
Integer part.
Definition parser.hpp:2185
+
stdex::parser::basic_score
Test for match score.
Definition parser.hpp:1742
+
stdex::parser::basic_sequence
Test for sequence.
Definition parser.hpp:999
+
stdex::parser::basic_set
Definition parser.hpp:681
+
stdex::parser::basic_signed_numeral
Test for signed numeral.
Definition parser.hpp:1828
+
stdex::parser::basic_signed_numeral::special_sign
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:1896
+
stdex::parser::basic_signed_numeral::negative_sign
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:1895
+
stdex::parser::basic_signed_numeral::positive_sign
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:1894
+
stdex::parser::basic_signed_numeral::number
std::shared_ptr< basic_parser< T > > number
Number.
Definition parser.hpp:1897
+
stdex::parser::basic_space_cu
Test for any space code unit.
Definition parser.hpp:377
+
stdex::parser::basic_space_or_punct_cu
Test for any space or punctuation code unit.
Definition parser.hpp:530
+
stdex::parser::basic_string_branch
Test for any string.
Definition parser.hpp:1118
+
stdex::parser::basic_string
Test for given string.
Definition parser.hpp:808
+
stdex::parser::basic_time
Test for time.
Definition parser.hpp:4284
+
stdex::parser::basic_url_password_char
Test for valid URL password character.
Definition parser.hpp:3080
+
stdex::parser::basic_url_path_char
Test for valid URL path character.
Definition parser.hpp:3180
+
stdex::parser::basic_url_path
Test for URL path.
Definition parser.hpp:3288
+
stdex::parser::basic_url_username_char
Test for valid URL username character.
Definition parser.hpp:2981
+
stdex::parser::basic_url
Test for URL.
Definition parser.hpp:3429
+
stdex::parser::http_agent
Test for HTTP agent.
Definition parser.hpp:5946
+
stdex::parser::http_any_type
Test for HTTP any type.
Definition parser.hpp:5068
+
stdex::parser::http_asterisk
Test for HTTP asterisk.
Definition parser.hpp:5710
+ + + + + +
stdex::parser::http_header
Test for HTTP header.
Definition parser.hpp:6269
+
stdex::parser::http_language
Test for HTTP language (RFC1766)
Definition parser.hpp:5578
+
stdex::parser::http_line_break
Test for HTTP line break (RFC2616: CRLF | LF)
Definition parser.hpp:4742
+
stdex::parser::http_media_range
Test for HTTP media range (RFC2616: media-range)
Definition parser.hpp:5100
+
stdex::parser::http_media_type
Test for HTTP media type (RFC2616: media-type)
Definition parser.hpp:5155
+
stdex::parser::http_parameter
Test for HTTP parameter (RFC2616: parameter)
Definition parser.hpp:5013
+
stdex::parser::http_parameter::name
http_token name
Parameter name.
Definition parser.hpp:5057
+
stdex::parser::http_parameter::value
http_value value
Parameter value.
Definition parser.hpp:5058
+
stdex::parser::http_protocol
Test for HTTP protocol.
Definition parser.hpp:6022
+
stdex::parser::http_protocol::version
uint16_t version
HTTP protocol version: 0x100 = 1.0, 0x101 = 1.1...
Definition parser.hpp:6124
+
stdex::parser::http_quoted_string
Test for HTTP quoted string (RFC2616: quoted-string)
Definition parser.hpp:4903
+
stdex::parser::http_quoted_string::content
stdex::interval< size_t > content
String content (without quotes)
Definition parser.hpp:4959
+
stdex::parser::http_request
Test for HTTP request.
Definition parser.hpp:6131
+
stdex::parser::http_space
Test for HTTP space (RFC2616: LWS)
Definition parser.hpp:4778
+
stdex::parser::http_text_char
Test for HTTP text character (RFC2616: TEXT)
Definition parser.hpp:4815
+
stdex::parser::http_token
Test for HTTP token (RFC2616: token - tolerates non-ASCII)
Definition parser.hpp:4849
+
stdex::parser::http_url_parameter
Test for HTTP URL parameter.
Definition parser.hpp:5395
+
stdex::parser::http_url_path_segment
Test for HTTP URL path segment.
Definition parser.hpp:5306
+
stdex::parser::http_url_path
Test for HTTP URL path segment.
Definition parser.hpp:5339
+
stdex::parser::http_url_path::segments
std::vector< http_url_path_segment > segments
Path segments.
Definition parser.hpp:5388
+
stdex::parser::http_url_port
Test for HTTP URL port.
Definition parser.hpp:5250
+
stdex::parser::http_url_server
Test for HTTP URL server.
Definition parser.hpp:5213
+
stdex::parser::http_url
Test for HTTP URL.
Definition parser.hpp:5476
+
stdex::parser::http_value_collection
Collection of HTTP values.
Definition parser.hpp:6379
+
stdex::parser::http_value
Test for HTTP value (RFC2616: value)
Definition parser.hpp:4969
+
stdex::parser::http_value::string
http_quoted_string string
Value when matched as quoted string.
Definition parser.hpp:5005
+
stdex::parser::http_value::token
http_token token
Value when matched as token.
Definition parser.hpp:5006
+
stdex::parser::http_weight
Test for HTTP weight factor.
Definition parser.hpp:5641
+
stdex::parser::http_weight::value
float value
Calculated value of the weight factor.
Definition parser.hpp:5703
+
stdex::parser::http_weighted_value
Test for HTTP weighted value.
Definition parser.hpp:5733
+
stdex::parser::parser_collection
Base template for collection-holding parsers.
Definition parser.hpp:959
+
stdex::parser::sgml_any_cp
Test for any SGML code point.
Definition parser.hpp:246
+
stdex::parser::sgml_cp_set
Test for any SGML code point from a given string of SGML code points.
Definition parser.hpp:765
+
stdex::parser::sgml_cp
Test for specific SGML code point.
Definition parser.hpp:333
+
stdex::parser::sgml_dns_domain_char
Test for valid DNS domain SGML character.
Definition parser.hpp:2854
+
stdex::parser::sgml_ipv6_scope_id_char
Test for valid IPv6 address scope ID SGML character.
Definition parser.hpp:2523
+
stdex::parser::sgml_punct_cp
Test for any SGML punctuation code point.
Definition parser.hpp:497
+
stdex::parser::sgml_space_cp
Test for any SGML space code point.
Definition parser.hpp:420
+
stdex::parser::sgml_space_or_punct_cp
Test for any SGML space or punctuation code point.
Definition parser.hpp:573
+
stdex::parser::sgml_string
Test for SGML given string.
Definition parser.hpp:855
+
stdex::parser::sgml_url_password_char
Test for valid URL password SGML character.
Definition parser.hpp:3132
+
stdex::parser::sgml_url_path_char
Test for valid URL path SGML character.
Definition parser.hpp:3236
+
stdex::parser::sgml_url_username_char
Test for valid URL username SGML character.
Definition parser.hpp:3032
stdex::interval
Numerical interval.
Definition interval.hpp:18
stdex::interval::size
T size() const
Returns interval size.
Definition interval.hpp:47
stdex::interval::end
T end
interval end
Definition interval.hpp:20
stdex::interval::interval
interval() noexcept
Constructs an invalid interval.
Definition interval.hpp:25
stdex::interval::start
T start
interval start
Definition interval.hpp:19
-
stdex::parser::http_factor_more
Definition parser.hpp:6387
+
stdex::parser::http_factor_more
Definition parser.hpp:6405
diff --git a/pch_8h_source.html b/pch_8h_source.html index 7b8650e93..e16cb72b1 100644 --- a/pch_8h_source.html +++ b/pch_8h_source.html @@ -105,7 +105,7 @@ $(function() { diff --git a/progress_8hpp_source.html b/progress_8hpp_source.html index 154e5b868..8efb15694 100644 --- a/progress_8hpp_source.html +++ b/progress_8hpp_source.html @@ -282,7 +282,7 @@ $(function() { diff --git a/sal_8hpp_source.html b/sal_8hpp_source.html index 614a4bd04..ba49e986a 100644 --- a/sal_8hpp_source.html +++ b/sal_8hpp_source.html @@ -143,7 +143,7 @@ $(function() { diff --git a/sgml_8hpp_source.html b/sgml_8hpp_source.html index 3720dcfb0..e1bf8f226 100644 --- a/sgml_8hpp_source.html +++ b/sgml_8hpp_source.html @@ -423,7 +423,7 @@ $(function() { diff --git a/sgml__unicode_8hpp_source.html b/sgml__unicode_8hpp_source.html index 8c84cc195..f72c42925 100644 --- a/sgml__unicode_8hpp_source.html +++ b/sgml__unicode_8hpp_source.html @@ -3170,7 +3170,7 @@ $(function() { diff --git a/string_8hpp_source.html b/string_8hpp_source.html index fa520114c..4bb1f9f16 100644 --- a/string_8hpp_source.html +++ b/string_8hpp_source.html @@ -691,7 +691,7 @@ $(function() { diff --git a/structstdex_1_1interval-members.html b/structstdex_1_1interval-members.html index 4d7bc9e9f..5ff198b44 100644 --- a/structstdex_1_1interval-members.html +++ b/structstdex_1_1interval-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/structstdex_1_1interval.html b/structstdex_1_1interval.html index 9e4ea5205..0cd789a19 100644 --- a/structstdex_1_1interval.html +++ b/structstdex_1_1interval.html @@ -384,7 +384,7 @@ template<class T > diff --git a/structstdex_1_1mapping-members.html b/structstdex_1_1mapping-members.html index 096b23373..8cf778680 100644 --- a/structstdex_1_1mapping-members.html +++ b/structstdex_1_1mapping-members.html @@ -90,7 +90,7 @@ $(function() { diff --git a/structstdex_1_1mapping.html b/structstdex_1_1mapping.html index 5e2facd87..300c0528f 100644 --- a/structstdex_1_1mapping.html +++ b/structstdex_1_1mapping.html @@ -283,7 +283,7 @@ template<class T > diff --git a/structstdex_1_1no__delete-members.html b/structstdex_1_1no__delete-members.html index eea67365d..a6d34f332 100644 --- a/structstdex_1_1no__delete-members.html +++ b/structstdex_1_1no__delete-members.html @@ -86,7 +86,7 @@ $(function() { diff --git a/structstdex_1_1no__delete.html b/structstdex_1_1no__delete.html index ffbb3f2f4..839ce4cb8 100644 --- a/structstdex_1_1no__delete.html +++ b/structstdex_1_1no__delete.html @@ -105,7 +105,7 @@ struct stdex::no_delete< T >

Noop deleter.

diff --git a/structstdex_1_1no__delete_3_01_t_0f_0e_4-members.html b/structstdex_1_1no__delete_3_01_t_0f_0e_4-members.html index e527bd1ac..420e0d758 100644 --- a/structstdex_1_1no__delete_3_01_t_0f_0e_4-members.html +++ b/structstdex_1_1no__delete_3_01_t_0f_0e_4-members.html @@ -86,7 +86,7 @@ $(function() { diff --git a/structstdex_1_1no__delete_3_01_t_0f_0e_4.html b/structstdex_1_1no__delete_3_01_t_0f_0e_4.html index ec4d577ac..acd51b62e 100644 --- a/structstdex_1_1no__delete_3_01_t_0f_0e_4.html +++ b/structstdex_1_1no__delete_3_01_t_0f_0e_4.html @@ -106,7 +106,7 @@ struct stdex::no_delete< T[]>

Noop array deleter.

diff --git a/structstdex_1_1parser_1_1http__factor__more-members.html b/structstdex_1_1parser_1_1http__factor__more-members.html index 2c9865b93..0039abc01 100644 --- a/structstdex_1_1parser_1_1http__factor__more-members.html +++ b/structstdex_1_1parser_1_1http__factor__more-members.html @@ -84,7 +84,7 @@ $(function() { diff --git a/structstdex_1_1parser_1_1http__factor__more.html b/structstdex_1_1parser_1_1http__factor__more.html index 861c2a0b0..c9b84067c 100644 --- a/structstdex_1_1parser_1_1http__factor__more.html +++ b/structstdex_1_1parser_1_1http__factor__more.html @@ -93,7 +93,7 @@ constexpr bool operator()< diff --git a/unicode_8hpp_source.html b/unicode_8hpp_source.html index c82ef2c46..fa8149eaa 100644 --- a/unicode_8hpp_source.html +++ b/unicode_8hpp_source.html @@ -208,7 +208,7 @@ $(function() { diff --git a/vector__queue_8hpp_source.html b/vector__queue_8hpp_source.html index 284046d7c..40a07fde0 100644 --- a/vector__queue_8hpp_source.html +++ b/vector__queue_8hpp_source.html @@ -386,7 +386,7 @@ $(function() {