diff --git a/_unit_tests_2compat_8hpp_source.html b/_unit_tests_2compat_8hpp_source.html index 2b1447280..54141c8c7 100644 --- a/_unit_tests_2compat_8hpp_source.html +++ b/_unit_tests_2compat_8hpp_source.html @@ -170,7 +170,7 @@ $(document).ready(function() { init_codefold(0); }); diff --git a/annotated.html b/annotated.html index 6f2399b59..a804c9398 100644 --- a/annotated.html +++ b/annotated.html @@ -236,7 +236,7 @@ $(function() { diff --git a/base64_8hpp_source.html b/base64_8hpp_source.html index 872797a2a..91958c45a 100644 --- a/base64_8hpp_source.html +++ b/base64_8hpp_source.html @@ -542,7 +542,7 @@ $(document).ready(function() { init_codefold(0); }); diff --git a/chrono_8hpp_source.html b/chrono_8hpp_source.html index b791d3b42..b0c7907c7 100644 --- a/chrono_8hpp_source.html +++ b/chrono_8hpp_source.html @@ -466,7 +466,7 @@ $(document).ready(function() { init_codefold(0); }); diff --git a/classes.html b/classes.html index e2e6adb3e..c2cd55c49 100644 --- a/classes.html +++ b/classes.html @@ -130,7 +130,7 @@ $(function() { diff --git a/classstdex_1_1base64__dec-members.html b/classstdex_1_1base64__dec-members.html index 77617ef1b..5c73b8bf7 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 6fa779084..3f4ed72c3 100644 --- a/classstdex_1_1base64__dec.html +++ b/classstdex_1_1base64__dec.html @@ -239,7 +239,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 9dc4a9395..3dc27e555 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 09e5f0bd7..b63e23564 100644 --- a/classstdex_1_1base64__enc.html +++ b/classstdex_1_1base64__enc.html @@ -244,7 +244,7 @@ template<class _Elem , class _Traits , class _Ax > diff --git a/classstdex_1_1base64__reader-members.html b/classstdex_1_1base64__reader-members.html index 0942ea4fd..b5c06b680 100644 --- a/classstdex_1_1base64__reader-members.html +++ b/classstdex_1_1base64__reader-members.html @@ -162,7 +162,7 @@ $(function() { diff --git a/classstdex_1_1base64__reader.html b/classstdex_1_1base64__reader.html index 061d970d0..b8fc6ebc2 100644 --- a/classstdex_1_1base64__reader.html +++ b/classstdex_1_1base64__reader.html @@ -443,7 +443,7 @@ size_t m_num diff --git a/classstdex_1_1base64__writer-members.html b/classstdex_1_1base64__writer-members.html index 599c02f5f..97ee03160 100644 --- a/classstdex_1_1base64__writer-members.html +++ b/classstdex_1_1base64__writer-members.html @@ -164,7 +164,7 @@ $(function() { diff --git a/classstdex_1_1base64__writer.html b/classstdex_1_1base64__writer.html index f94d61db8..402de2ad1 100644 --- a/classstdex_1_1base64__writer.html +++ b/classstdex_1_1base64__writer.html @@ -450,7 +450,7 @@ size_t m_num diff --git a/classstdex_1_1basic__hash-members.html b/classstdex_1_1basic__hash-members.html index 476c5071c..64396d6a3 100644 --- a/classstdex_1_1basic__hash-members.html +++ b/classstdex_1_1basic__hash-members.html @@ -90,7 +90,7 @@ $(function() { diff --git a/classstdex_1_1basic__hash.html b/classstdex_1_1basic__hash.html index 1d1a93657..fdc401aca 100644 --- a/classstdex_1_1basic__hash.html +++ b/classstdex_1_1basic__hash.html @@ -255,7 +255,7 @@ template<class T > diff --git a/classstdex_1_1block__hash-members.html b/classstdex_1_1block__hash-members.html index 5a77d42ff..e67d89ea6 100644 --- a/classstdex_1_1block__hash-members.html +++ b/classstdex_1_1block__hash-members.html @@ -94,7 +94,7 @@ $(function() { diff --git a/classstdex_1_1block__hash.html b/classstdex_1_1block__hash.html index 2bcd91d25..1ae8b13ed 100644 --- a/classstdex_1_1block__hash.html +++ b/classstdex_1_1block__hash.html @@ -245,7 +245,7 @@ template<class T > diff --git a/classstdex_1_1charset__encoder-members.html b/classstdex_1_1charset__encoder-members.html index 1c8512f09..bfd01a9cc 100644 --- a/classstdex_1_1charset__encoder-members.html +++ b/classstdex_1_1charset__encoder-members.html @@ -102,7 +102,7 @@ $(function() { diff --git a/classstdex_1_1charset__encoder.html b/classstdex_1_1charset__encoder.html index 99d134b5c..b76898b82 100644 --- a/classstdex_1_1charset__encoder.html +++ b/classstdex_1_1charset__encoder.html @@ -607,7 +607,7 @@ template<class _Traits_to = std::char_traits<T_to>, class _Alloc_to = diff --git a/classstdex_1_1crc32__hash-members.html b/classstdex_1_1crc32__hash-members.html index 0c0440bf3..6337fc1f6 100644 --- a/classstdex_1_1crc32__hash-members.html +++ b/classstdex_1_1crc32__hash-members.html @@ -90,7 +90,7 @@ $(function() { diff --git a/classstdex_1_1crc32__hash.html b/classstdex_1_1crc32__hash.html index c1515b22b..ec1e551c3 100644 --- a/classstdex_1_1crc32__hash.html +++ b/classstdex_1_1crc32__hash.html @@ -245,7 +245,7 @@ crc32_t m_value diff --git a/classstdex_1_1global__progress-members.html b/classstdex_1_1global__progress-members.html index c3d82de21..d0c5bf7d9 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 c4a8b1709..d4c069049 100644 --- a/classstdex_1_1global__progress.html +++ b/classstdex_1_1global__progress.html @@ -547,7 +547,7 @@ template<class T > diff --git a/classstdex_1_1hex__dec-members.html b/classstdex_1_1hex__dec-members.html index b32147e3c..78fcf6247 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 c82508221..dec29ce52 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 9cb3f27f4..7a7a3af2a 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 495feb297..6e460de05 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 ecfbaae23..c5acc01a4 100644 --- a/classstdex_1_1idrec_1_1record-members.html +++ b/classstdex_1_1idrec_1_1record-members.html @@ -100,7 +100,7 @@ $(function() { diff --git a/classstdex_1_1idrec_1_1record.html b/classstdex_1_1idrec_1_1record.html index ef8833eef..b9d8e656f 100644 --- a/classstdex_1_1idrec_1_1record.html +++ b/classstdex_1_1idrec_1_1record.html @@ -837,7 +837,7 @@ template<class T , class T_ID , const T_ID ID, class T_SIZE , T_SIZE ALIGN> diff --git a/classstdex_1_1lazy__progress-members.html b/classstdex_1_1lazy__progress-members.html index fd278f73e..dd102504f 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 f3477d0e7..019d7d541 100644 --- a/classstdex_1_1lazy__progress.html +++ b/classstdex_1_1lazy__progress.html @@ -279,7 +279,7 @@ template<class T > diff --git a/classstdex_1_1md5__hash-members.html b/classstdex_1_1md5__hash-members.html index 4b3bddca6..5fb7acbcb 100644 --- a/classstdex_1_1md5__hash-members.html +++ b/classstdex_1_1md5__hash-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1md5__hash.html b/classstdex_1_1md5__hash.html index c60bfcebd..ad0b225ca 100644 --- a/classstdex_1_1md5__hash.html +++ b/classstdex_1_1md5__hash.html @@ -259,7 +259,7 @@ uint32_t m_temp [16] diff --git a/classstdex_1_1parser_1_1basic__angle-members.html b/classstdex_1_1parser_1_1basic__angle-members.html index a2b6f182b..f7d3b77d2 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 44fd853ea..7e5399daa 100644 --- a/classstdex_1_1parser_1_1basic__angle.html +++ b/classstdex_1_1parser_1_1basic__angle.html @@ -244,7 +244,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__any__cu-members.html b/classstdex_1_1parser_1_1basic__any__cu-members.html index c5298ea63..40a8e938a 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 84dffd4e4..cc80dd4b1 100644 --- a/classstdex_1_1parser_1_1basic__any__cu.html +++ b/classstdex_1_1parser_1_1basic__any__cu.html @@ -191,7 +191,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__bol-members.html b/classstdex_1_1parser_1_1basic__bol-members.html index 3d8648e17..03313bbf2 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 101001877..3f3d40f1e 100644 --- a/classstdex_1_1parser_1_1basic__bol.html +++ b/classstdex_1_1parser_1_1basic__bol.html @@ -198,7 +198,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__branch-members.html b/classstdex_1_1parser_1_1basic__branch-members.html index 9a0cef307..a85d855a5 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 5bda54e23..cb9c5c50e 100644 --- a/classstdex_1_1parser_1_1basic__branch.html +++ b/classstdex_1_1parser_1_1basic__branch.html @@ -253,7 +253,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__chemical__formula-members.html b/classstdex_1_1parser_1_1basic__chemical__formula-members.html index 267213427..b91ecdb5e 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 00a572e49..acdc4d504 100644 --- a/classstdex_1_1parser_1_1basic__chemical__formula.html +++ b/classstdex_1_1parser_1_1basic__chemical__formula.html @@ -239,7 +239,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__creditor__reference-members.html b/classstdex_1_1parser_1_1basic__creditor__reference-members.html index 3e5900aa1..0e7e8e9c2 100644 --- a/classstdex_1_1parser_1_1basic__creditor__reference-members.html +++ b/classstdex_1_1parser_1_1basic__creditor__reference-members.html @@ -96,7 +96,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__creditor__reference.html b/classstdex_1_1parser_1_1basic__creditor__reference.html index 5968db20c..c9ae412b8 100644 --- a/classstdex_1_1parser_1_1basic__creditor__reference.html +++ b/classstdex_1_1parser_1_1basic__creditor__reference.html @@ -240,7 +240,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__cu-members.html b/classstdex_1_1parser_1_1basic__cu-members.html index bf11117e8..6429e4f46 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 4a2998f42..b81ab1281 100644 --- a/classstdex_1_1parser_1_1basic__cu.html +++ b/classstdex_1_1parser_1_1basic__cu.html @@ -201,7 +201,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__cu__set-members.html b/classstdex_1_1parser_1_1basic__cu__set-members.html index 60a4a19ed..1afccf812 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 bf62cabe5..0d6539843 100644 --- a/classstdex_1_1parser_1_1basic__cu__set.html +++ b/classstdex_1_1parser_1_1basic__cu__set.html @@ -210,7 +210,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__date-members.html b/classstdex_1_1parser_1_1basic__date-members.html index 91e71e42b..7fb714037 100644 --- a/classstdex_1_1parser_1_1basic__date-members.html +++ b/classstdex_1_1parser_1_1basic__date-members.html @@ -100,7 +100,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__date.html b/classstdex_1_1parser_1_1basic__date.html index 7994290ff..d82d2ceb2 100644 --- a/classstdex_1_1parser_1_1basic__date.html +++ b/classstdex_1_1parser_1_1basic__date.html @@ -252,7 +252,7 @@ template<clas 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 e2242ce30..959005252 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() { diff --git a/classstdex_1_1parser_1_1basic__dns__domain__char.html b/classstdex_1_1parser_1_1basic__dns__domain__char.html index d1999d376..4e8086b9c 100644 --- a/classstdex_1_1parser_1_1basic__dns__domain__char.html +++ b/classstdex_1_1parser_1_1basic__dns__domain__char.html @@ -203,7 +203,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__dns__name-members.html b/classstdex_1_1parser_1_1basic__dns__name-members.html index 760497941..ea3936d6a 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 afabe2ce2..fc79a57cb 100644 --- a/classstdex_1_1parser_1_1basic__dns__name.html +++ b/classstdex_1_1parser_1_1basic__dns__name.html @@ -205,7 +205,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__email__address-members.html b/classstdex_1_1parser_1_1basic__email__address-members.html index 37e1e23e4..ef57a50d0 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 63a59bad6..0ed12a7cc 100644 --- a/classstdex_1_1parser_1_1basic__email__address.html +++ b/classstdex_1_1parser_1_1basic__email__address.html @@ -245,7 +245,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__emoticon-members.html b/classstdex_1_1parser_1_1basic__emoticon-members.html index c43655344..26aee64da 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 ed56e3055..c97629db8 100644 --- a/classstdex_1_1parser_1_1basic__emoticon.html +++ b/classstdex_1_1parser_1_1basic__emoticon.html @@ -243,7 +243,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__eol-members.html b/classstdex_1_1parser_1_1basic__eol-members.html index 9e901d590..b7406c754 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 129186a79..c83b51c58 100644 --- a/classstdex_1_1parser_1_1basic__eol.html +++ b/classstdex_1_1parser_1_1basic__eol.html @@ -198,7 +198,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__fraction-members.html b/classstdex_1_1parser_1_1basic__fraction-members.html index f3f158b8d..ada1a23ae 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 59720cd98..8cf5711c2 100644 --- a/classstdex_1_1parser_1_1basic__fraction.html +++ b/classstdex_1_1parser_1_1basic__fraction.html @@ -232,7 +232,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__iban-members.html b/classstdex_1_1parser_1_1basic__iban-members.html index ece96180c..d588460ff 100644 --- a/classstdex_1_1parser_1_1basic__iban-members.html +++ b/classstdex_1_1parser_1_1basic__iban-members.html @@ -97,7 +97,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__iban.html b/classstdex_1_1parser_1_1basic__iban.html index 9a2280829..113258ad3 100644 --- a/classstdex_1_1parser_1_1basic__iban.html +++ b/classstdex_1_1parser_1_1basic__iban.html @@ -244,7 +244,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__integer-members.html b/classstdex_1_1parser_1_1basic__integer-members.html index 296028314..bb1812ee6 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 f095fe0e1..b40cc1a6f 100644 --- a/classstdex_1_1parser_1_1basic__integer.html +++ b/classstdex_1_1parser_1_1basic__integer.html @@ -180,7 +180,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__integer10-members.html b/classstdex_1_1parser_1_1basic__integer10-members.html index 7ef4ea87a..a4e3547fe 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 ab5e27d82..71acb226f 100644 --- a/classstdex_1_1parser_1_1basic__integer10.html +++ b/classstdex_1_1parser_1_1basic__integer10.html @@ -234,7 +234,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__integer10ts-members.html b/classstdex_1_1parser_1_1basic__integer10ts-members.html index ab83c351a..e800f0622 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 2bdc6eb50..429afe859 100644 --- a/classstdex_1_1parser_1_1basic__integer10ts.html +++ b/classstdex_1_1parser_1_1basic__integer10ts.html @@ -248,7 +248,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__integer16-members.html b/classstdex_1_1parser_1_1basic__integer16-members.html index e695b6c59..8e17c5baa 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 356d51317..ac357c347 100644 --- a/classstdex_1_1parser_1_1basic__integer16.html +++ b/classstdex_1_1parser_1_1basic__integer16.html @@ -252,7 +252,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__ipv4__address-members.html b/classstdex_1_1parser_1_1basic__ipv4__address-members.html index 29726675e..8346a3e17 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 ae2108160..7d7c74f0b 100644 --- a/classstdex_1_1parser_1_1basic__ipv4__address.html +++ b/classstdex_1_1parser_1_1basic__ipv4__address.html @@ -265,7 +265,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__ipv6__address-members.html b/classstdex_1_1parser_1_1basic__ipv6__address-members.html index 83d787bf4..7509ad150 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 30eb877aa..ab07f8857 100644 --- a/classstdex_1_1parser_1_1basic__ipv6__address.html +++ b/classstdex_1_1parser_1_1basic__ipv6__address.html @@ -290,7 +290,7 @@ template<clas 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 99d2985bc..359b28c86 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 0dd79e966..1a0367f84 100644 --- a/classstdex_1_1parser_1_1basic__ipv6__scope__id__char.html +++ b/classstdex_1_1parser_1_1basic__ipv6__scope__id__char.html @@ -191,7 +191,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__iterations-members.html b/classstdex_1_1parser_1_1basic__iterations-members.html index bd5f1e57e..e4a1acc0d 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 049968166..ddce2d5d1 100644 --- a/classstdex_1_1parser_1_1basic__iterations.html +++ b/classstdex_1_1parser_1_1basic__iterations.html @@ -211,7 +211,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__json__string-members.html b/classstdex_1_1parser_1_1basic__json__string-members.html index 3c7464c90..941bf5ec9 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 67e4d5ad1..1518b86b7 100644 --- a/classstdex_1_1parser_1_1basic__json__string.html +++ b/classstdex_1_1parser_1_1basic__json__string.html @@ -260,7 +260,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__mixed__numeral-members.html b/classstdex_1_1parser_1_1basic__mixed__numeral-members.html index 45c406408..eb16258a0 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 ba0648327..44d967af1 100644 --- a/classstdex_1_1parser_1_1basic__mixed__numeral.html +++ b/classstdex_1_1parser_1_1basic__mixed__numeral.html @@ -247,7 +247,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__monetary__numeral-members.html b/classstdex_1_1parser_1_1basic__monetary__numeral-members.html index fde7f1623..9807e371d 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 3f01ab8f0..46c12cdfa 100644 --- a/classstdex_1_1parser_1_1basic__monetary__numeral.html +++ b/classstdex_1_1parser_1_1basic__monetary__numeral.html @@ -251,7 +251,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__noop-members.html b/classstdex_1_1parser_1_1basic__noop-members.html index c944120f5..884f1765d 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 d64052427..7ae22ee7e 100644 --- a/classstdex_1_1parser_1_1basic__noop.html +++ b/classstdex_1_1parser_1_1basic__noop.html @@ -188,7 +188,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__parser-members.html b/classstdex_1_1parser_1_1basic__parser-members.html index 407e1d557..538bc9400 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 c3c491817..965462f9b 100644 --- a/classstdex_1_1parser_1_1basic__parser.html +++ b/classstdex_1_1parser_1_1basic__parser.html @@ -188,7 +188,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 e4c7f5fb3..7640a20e5 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 0bbd2068f..b70e30293 100644 --- a/classstdex_1_1parser_1_1basic__permutation.html +++ b/classstdex_1_1parser_1_1basic__permutation.html @@ -216,7 +216,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__phone__number-members.html b/classstdex_1_1parser_1_1basic__phone__number-members.html index 402c82298..d355a1052 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 280e76a7d..70db05b8f 100644 --- a/classstdex_1_1parser_1_1basic__phone__number.html +++ b/classstdex_1_1parser_1_1basic__phone__number.html @@ -246,7 +246,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__punct__cu-members.html b/classstdex_1_1parser_1_1basic__punct__cu-members.html index 8263106e8..6cf355654 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 40bd575a0..012372169 100644 --- a/classstdex_1_1parser_1_1basic__punct__cu.html +++ b/classstdex_1_1parser_1_1basic__punct__cu.html @@ -198,7 +198,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__roman__numeral-members.html b/classstdex_1_1parser_1_1basic__roman__numeral-members.html index c96117f77..d7ebe4ce4 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 3d2815cc9..09d2a52be 100644 --- a/classstdex_1_1parser_1_1basic__roman__numeral.html +++ b/classstdex_1_1parser_1_1basic__roman__numeral.html @@ -231,7 +231,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__scientific__numeral-members.html b/classstdex_1_1parser_1_1basic__scientific__numeral-members.html index 8be190bd0..27799b909 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 483012a48..d09f561eb 100644 --- a/classstdex_1_1parser_1_1basic__scientific__numeral.html +++ b/classstdex_1_1parser_1_1basic__scientific__numeral.html @@ -267,7 +267,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__score-members.html b/classstdex_1_1parser_1_1basic__score-members.html index 08328d642..5570f945b 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 b8264a9f1..425f26be3 100644 --- a/classstdex_1_1parser_1_1basic__score.html +++ b/classstdex_1_1parser_1_1basic__score.html @@ -236,7 +236,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__sequence-members.html b/classstdex_1_1parser_1_1basic__sequence-members.html index 75804a7e4..e055dca01 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 fb1e118e8..9fcf6b657 100644 --- a/classstdex_1_1parser_1_1basic__sequence.html +++ b/classstdex_1_1parser_1_1basic__sequence.html @@ -209,7 +209,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__set-members.html b/classstdex_1_1parser_1_1basic__set-members.html index a6e100acf..5b263922e 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 1bb956cc9..832253ede 100644 --- a/classstdex_1_1parser_1_1basic__set.html +++ b/classstdex_1_1parser_1_1basic__set.html @@ -223,7 +223,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__si__reference-members.html b/classstdex_1_1parser_1_1basic__si__reference-members.html index aba8d8d70..13f745688 100644 --- a/classstdex_1_1parser_1_1basic__si__reference-members.html +++ b/classstdex_1_1parser_1_1basic__si__reference-members.html @@ -102,7 +102,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__si__reference.html b/classstdex_1_1parser_1_1basic__si__reference.html index 6c5ac21a8..ed96e3b2e 100644 --- a/classstdex_1_1parser_1_1basic__si__reference.html +++ b/classstdex_1_1parser_1_1basic__si__reference.html @@ -265,7 +265,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__si__reference__delimiter-members.html b/classstdex_1_1parser_1_1basic__si__reference__delimiter-members.html index 2926a83f7..ef2ec2688 100644 --- a/classstdex_1_1parser_1_1basic__si__reference__delimiter-members.html +++ b/classstdex_1_1parser_1_1basic__si__reference__delimiter-members.html @@ -92,7 +92,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__si__reference__delimiter.html b/classstdex_1_1parser_1_1basic__si__reference__delimiter.html index a76f7a51c..6787db58c 100644 --- a/classstdex_1_1parser_1_1basic__si__reference__delimiter.html +++ b/classstdex_1_1parser_1_1basic__si__reference__delimiter.html @@ -192,7 +192,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__si__reference__part-members.html b/classstdex_1_1parser_1_1basic__si__reference__part-members.html index ef685457b..dca2ae8b9 100644 --- a/classstdex_1_1parser_1_1basic__si__reference__part-members.html +++ b/classstdex_1_1parser_1_1basic__si__reference__part-members.html @@ -92,7 +92,7 @@ $(function() { diff --git a/classstdex_1_1parser_1_1basic__si__reference__part.html b/classstdex_1_1parser_1_1basic__si__reference__part.html index 68a8be19c..f3a6cd79f 100644 --- a/classstdex_1_1parser_1_1basic__si__reference__part.html +++ b/classstdex_1_1parser_1_1basic__si__reference__part.html @@ -192,7 +192,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__signed__numeral-members.html b/classstdex_1_1parser_1_1basic__signed__numeral-members.html index 055d2ea1d..8f5e6879b 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 d7ee394f8..04b831c4c 100644 --- a/classstdex_1_1parser_1_1basic__signed__numeral.html +++ b/classstdex_1_1parser_1_1basic__signed__numeral.html @@ -239,7 +239,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__space__cu-members.html b/classstdex_1_1parser_1_1basic__space__cu-members.html index 7ed7576c4..52a0409b1 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 2a8223a25..84e06c924 100644 --- a/classstdex_1_1parser_1_1basic__space__cu.html +++ b/classstdex_1_1parser_1_1basic__space__cu.html @@ -198,7 +198,7 @@ template<clas 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 e46b73156..06c210633 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 73fdbf795..a902b57c0 100644 --- a/classstdex_1_1parser_1_1basic__space__or__punct__cu.html +++ b/classstdex_1_1parser_1_1basic__space__or__punct__cu.html @@ -198,7 +198,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__string-members.html b/classstdex_1_1parser_1_1basic__string-members.html index f7774fa11..483d76888 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 3ea7a5af5..c77b465aa 100644 --- a/classstdex_1_1parser_1_1basic__string.html +++ b/classstdex_1_1parser_1_1basic__string.html @@ -198,7 +198,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__string__branch-members.html b/classstdex_1_1parser_1_1basic__string__branch-members.html index 9753b6b9e..b172e81d7 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 da0c6ec89..0729e60f1 100644 --- a/classstdex_1_1parser_1_1basic__string__branch.html +++ b/classstdex_1_1parser_1_1basic__string__branch.html @@ -185,7 +185,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 fde7064e0..dc184d7fd 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 c40bd7037..c1055d6b6 100644 --- a/classstdex_1_1parser_1_1basic__time.html +++ b/classstdex_1_1parser_1_1basic__time.html @@ -242,7 +242,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__url-members.html b/classstdex_1_1parser_1_1basic__url-members.html index c41d2996c..e6efa2eb3 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 f1648a14b..df15a5ccf 100644 --- a/classstdex_1_1parser_1_1basic__url.html +++ b/classstdex_1_1parser_1_1basic__url.html @@ -272,7 +272,7 @@ template<clas 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 28d4fee77..b0127bbc8 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 15602fe21..4f0eb8f0a 100644 --- a/classstdex_1_1parser_1_1basic__url__password__char.html +++ b/classstdex_1_1parser_1_1basic__url__password__char.html @@ -191,7 +191,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1basic__url__path-members.html b/classstdex_1_1parser_1_1basic__url__path-members.html index 41c3f76e9..042b068bb 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 4d3945e3e..5df842630 100644 --- a/classstdex_1_1parser_1_1basic__url__path.html +++ b/classstdex_1_1parser_1_1basic__url__path.html @@ -242,7 +242,7 @@ template<clas 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 f3864b5e8..f322104f7 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 20a87297e..09cf9bea4 100644 --- a/classstdex_1_1parser_1_1basic__url__path__char.html +++ b/classstdex_1_1parser_1_1basic__url__path__char.html @@ -191,7 +191,7 @@ template<clas 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 72047afdc..7e925acdd 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 bd6254dda..d94e1877f 100644 --- a/classstdex_1_1parser_1_1basic__url__username__char.html +++ b/classstdex_1_1parser_1_1basic__url__username__char.html @@ -191,7 +191,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1http__agent-members.html b/classstdex_1_1parser_1_1http__agent-members.html index 9e83fa2f2..08a9465fa 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 d8b6659ec..ec4be8da2 100644 --- a/classstdex_1_1parser_1_1http__agent.html +++ b/classstdex_1_1parser_1_1http__agent.html @@ -220,7 +220,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 1fbfe3a2f..676880c53 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 a8e8462f3..387419418 100644 --- a/classstdex_1_1parser_1_1http__any__type.html +++ b/classstdex_1_1parser_1_1http__any__type.html @@ -184,7 +184,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 0222eb532..e37b3adf6 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 318bb9d43..bbf50f255 100644 --- a/classstdex_1_1parser_1_1http__asterisk.html +++ b/classstdex_1_1parser_1_1http__asterisk.html @@ -184,7 +184,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 09e75d059..c9c12f673 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 cad293a7e..c49c53351 100644 --- a/classstdex_1_1parser_1_1http__cookie.html +++ b/classstdex_1_1parser_1_1http__cookie.html @@ -230,7 +230,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 d80d73dc4..6c2328b1b 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 9a10dec6a..2a3e988d3 100644 --- a/classstdex_1_1parser_1_1http__cookie__parameter.html +++ b/classstdex_1_1parser_1_1http__cookie__parameter.html @@ -224,7 +224,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 9f747f26c..6b898947d 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 fa2fc4b2e..9a23c8a14 100644 --- a/classstdex_1_1parser_1_1http__header.html +++ b/classstdex_1_1parser_1_1http__header.html @@ -224,7 +224,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 6dbb2ec9c..08a2cb052 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 eee14bcfc..aee727652 100644 --- a/classstdex_1_1parser_1_1http__language.html +++ b/classstdex_1_1parser_1_1http__language.html @@ -217,7 +217,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 d4d609a45..a482e2afb 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 d6509a920..3b3781c95 100644 --- a/classstdex_1_1parser_1_1http__line__break.html +++ b/classstdex_1_1parser_1_1http__line__break.html @@ -184,7 +184,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 a3a236d1f..13a964abe 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 2b424061e..acfd664cf 100644 --- a/classstdex_1_1parser_1_1http__media__range.html +++ b/classstdex_1_1parser_1_1http__media__range.html @@ -225,7 +225,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 4444dd6f6..cbb385323 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 e5d9d5d53..da131bf0a 100644 --- a/classstdex_1_1parser_1_1http__media__type.html +++ b/classstdex_1_1parser_1_1http__media__type.html @@ -229,7 +229,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 ed3539ac0..aa2fc75cf 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 e6fe37bb8..53409c0cb 100644 --- a/classstdex_1_1parser_1_1http__parameter.html +++ b/classstdex_1_1parser_1_1http__parameter.html @@ -226,7 +226,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 59bd4d557..234d6981c 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 f65f1a358..05ae24420 100644 --- a/classstdex_1_1parser_1_1http__protocol.html +++ b/classstdex_1_1parser_1_1http__protocol.html @@ -230,7 +230,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 fd4b42a71..9775f21f0 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 58a9fbbdb..3bb45e3e4 100644 --- a/classstdex_1_1parser_1_1http__quoted__string.html +++ b/classstdex_1_1parser_1_1http__quoted__string.html @@ -222,7 +222,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 c7b712431..f4a206720 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 d5a6262d4..4d9316288 100644 --- a/classstdex_1_1parser_1_1http__request.html +++ b/classstdex_1_1parser_1_1http__request.html @@ -230,7 +230,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 ca7960b6f..ecebcb0cb 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 938ad871f..43b2cc9b1 100644 --- a/classstdex_1_1parser_1_1http__space.html +++ b/classstdex_1_1parser_1_1http__space.html @@ -191,7 +191,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 6f15e498b..b48ae7bac 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 ed42b2855..f01637b82 100644 --- a/classstdex_1_1parser_1_1http__text__char.html +++ b/classstdex_1_1parser_1_1http__text__char.html @@ -191,7 +191,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 1bb86a491..792bc8168 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 23a885f2d..44b6e783d 100644 --- a/classstdex_1_1parser_1_1http__token.html +++ b/classstdex_1_1parser_1_1http__token.html @@ -184,7 +184,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 0c2af1463..6c34b3156 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 8b711f451..1cfde9f8e 100644 --- a/classstdex_1_1parser_1_1http__url.html +++ b/classstdex_1_1parser_1_1http__url.html @@ -229,7 +229,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 0d2b40921..53c6485fc 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 9b6893efc..230e4f4c1 100644 --- a/classstdex_1_1parser_1_1http__url__parameter.html +++ b/classstdex_1_1parser_1_1http__url__parameter.html @@ -220,7 +220,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 d996a6954..fd68b33b6 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 30d8af9d0..007a09a1c 100644 --- a/classstdex_1_1parser_1_1http__url__path.html +++ b/classstdex_1_1parser_1_1http__url__path.html @@ -218,7 +218,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 30ee12e38..38d48f1f4 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 14ecc8f83..472e40616 100644 --- a/classstdex_1_1parser_1_1http__url__path__segment.html +++ b/classstdex_1_1parser_1_1http__url__path__segment.html @@ -184,7 +184,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 72ef2f3ee..dea91cdd6 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 2f35b49ec..f00c7512c 100644 --- a/classstdex_1_1parser_1_1http__url__port.html +++ b/classstdex_1_1parser_1_1http__url__port.html @@ -220,7 +220,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 755da79f2..b4374bfae 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 1707ebf1e..17f1ae04e 100644 --- a/classstdex_1_1parser_1_1http__url__server.html +++ b/classstdex_1_1parser_1_1http__url__server.html @@ -184,7 +184,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 4419644bd..a72f1642f 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 68cead6cc..d3599d46d 100644 --- a/classstdex_1_1parser_1_1http__value.html +++ b/classstdex_1_1parser_1_1http__value.html @@ -222,7 +222,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 ae68e7b51..a062edad8 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 7ab5ee716..35fe93b6b 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< _Key, T >

Collection o

diff --git a/classstdex_1_1parser_1_1http__weight-members.html b/classstdex_1_1parser_1_1http__weight-members.html index 697d3455b..ab0bc0de8 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 fb9b59cb8..40dc60247 100644 --- a/classstdex_1_1parser_1_1http__weight.html +++ b/classstdex_1_1parser_1_1http__weight.html @@ -221,7 +221,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 b2a7e8628..c2e989d81 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 d844ca6d1..158f408fc 100644 --- a/classstdex_1_1parser_1_1http__weighted__value.html +++ b/classstdex_1_1parser_1_1http__weighted__value.html @@ -231,7 +231,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1parser__collection-members.html b/classstdex_1_1parser_1_1parser__collection-members.html index ab57f633d..5abfa3fc9 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 6f8201842..c18af79d6 100644 --- a/classstdex_1_1parser_1_1parser__collection.html +++ b/classstdex_1_1parser_1_1parser__collection.html @@ -189,7 +189,7 @@ template<clas diff --git a/classstdex_1_1parser_1_1sgml__any__cp-members.html b/classstdex_1_1parser_1_1sgml__any__cp-members.html index 39825cb8a..f4e60ab13 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 c96d07dba..fc26be1fc 100644 --- a/classstdex_1_1parser_1_1sgml__any__cp.html +++ b/classstdex_1_1parser_1_1sgml__any__cp.html @@ -196,7 +196,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 54468b94b..59d31af21 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 a0a390820..eac1d8387 100644 --- a/classstdex_1_1parser_1_1sgml__cp.html +++ b/classstdex_1_1parser_1_1sgml__cp.html @@ -197,7 +197,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 d1633e3a0..e447e32d3 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 543941e94..8d3ca3110 100644 --- a/classstdex_1_1parser_1_1sgml__cp__set.html +++ b/classstdex_1_1parser_1_1sgml__cp__set.html @@ -210,7 +210,7 @@ Additional Inherited Members 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 e2d2580bf..37b194c7d 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 9dc5cf981..d03ced73f 100644 --- a/classstdex_1_1parser_1_1sgml__dns__domain__char.html +++ b/classstdex_1_1parser_1_1sgml__dns__domain__char.html @@ -205,7 +205,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 757d4830c..61ee04080 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 d7f67425c..3f6a7aaeb 100644 --- a/classstdex_1_1parser_1_1sgml__ipv6__scope__id__char.html +++ b/classstdex_1_1parser_1_1sgml__ipv6__scope__id__char.html @@ -187,7 +187,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 3da9afeb0..836f612c1 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 5e093dd95..7a5f7dffc 100644 --- a/classstdex_1_1parser_1_1sgml__punct__cp.html +++ b/classstdex_1_1parser_1_1sgml__punct__cp.html @@ -200,7 +200,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 d3a77b209..f2d833802 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 ce3aca7c8..26b489d58 100644 --- a/classstdex_1_1parser_1_1sgml__space__cp.html +++ b/classstdex_1_1parser_1_1sgml__space__cp.html @@ -200,7 +200,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 c2f1b511c..5e2e661aa 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 2bd3a4f9b..d414233b8 100644 --- a/classstdex_1_1parser_1_1sgml__space__or__punct__cp.html +++ b/classstdex_1_1parser_1_1sgml__space__or__punct__cp.html @@ -200,7 +200,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 ea528ee5a..3e6d644fe 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 11f2b716a..931b3f831 100644 --- a/classstdex_1_1parser_1_1sgml__string.html +++ b/classstdex_1_1parser_1_1sgml__string.html @@ -194,7 +194,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 43332e8d0..f3bd7871b 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 fef8c8565..7b767b56f 100644 --- a/classstdex_1_1parser_1_1sgml__url__password__char.html +++ b/classstdex_1_1parser_1_1sgml__url__password__char.html @@ -196,7 +196,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 42b254831..cb2df4464 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 272d7266d..78aa2289e 100644 --- a/classstdex_1_1parser_1_1sgml__url__path__char.html +++ b/classstdex_1_1parser_1_1sgml__url__path__char.html @@ -196,7 +196,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 0e47b11e2..2fe129f49 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 b5828b4d3..a3941db8a 100644 --- a/classstdex_1_1parser_1_1sgml__url__username__char.html +++ b/classstdex_1_1parser_1_1sgml__url__username__char.html @@ -196,7 +196,7 @@ std::locale m_locale diff --git a/classstdex_1_1progress-members.html b/classstdex_1_1progress-members.html index c4fc7f456..d9164f394 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 7ebc9149f..0b7990615 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 ae2af3d4e..6140e172a 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 1c7f01d94..e27bba03a 100644 --- a/classstdex_1_1progress__switcher.html +++ b/classstdex_1_1progress__switcher.html @@ -163,7 +163,7 @@ class stdex::progress_switcher< T >

Progress indicator switcher. <

diff --git a/classstdex_1_1ring-members.html b/classstdex_1_1ring-members.html index 66a072901..b834c8743 100644 --- a/classstdex_1_1ring-members.html +++ b/classstdex_1_1ring-members.html @@ -100,7 +100,7 @@ $(function() { diff --git a/classstdex_1_1ring.html b/classstdex_1_1ring.html index 295a744c5..f16cfed4e 100644 --- a/classstdex_1_1ring.html +++ b/classstdex_1_1ring.html @@ -296,7 +296,7 @@ template<class T , size_t CAPACITY> diff --git a/classstdex_1_1sha1__hash-members.html b/classstdex_1_1sha1__hash-members.html index ca8c80b20..f1b0844fd 100644 --- a/classstdex_1_1sha1__hash-members.html +++ b/classstdex_1_1sha1__hash-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1sha1__hash.html b/classstdex_1_1sha1__hash.html index c365a460c..c93ed9b35 100644 --- a/classstdex_1_1sha1__hash.html +++ b/classstdex_1_1sha1__hash.html @@ -259,7 +259,7 @@ uint32_t m_temp [16] diff --git a/classstdex_1_1stream_1_1async__reader-members.html b/classstdex_1_1stream_1_1async__reader-members.html index dc4341a1c..d8bf3ae63 100644 --- a/classstdex_1_1stream_1_1async__reader-members.html +++ b/classstdex_1_1stream_1_1async__reader-members.html @@ -155,7 +155,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1async__reader.html b/classstdex_1_1stream_1_1async__reader.html index 5ff0892e8..454db8c76 100644 --- a/classstdex_1_1stream_1_1async__reader.html +++ b/classstdex_1_1stream_1_1async__reader.html @@ -414,7 +414,7 @@ template<size_t CAPACITY = default_async_limit> diff --git a/classstdex_1_1stream_1_1async__writer-members.html b/classstdex_1_1stream_1_1async__writer-members.html index 8b14a6fb0..7b5a4e5d2 100644 --- a/classstdex_1_1stream_1_1async__writer-members.html +++ b/classstdex_1_1stream_1_1async__writer-members.html @@ -155,7 +155,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1async__writer.html b/classstdex_1_1stream_1_1async__writer.html index 6781bfffd..989acddad 100644 --- a/classstdex_1_1stream_1_1async__writer.html +++ b/classstdex_1_1stream_1_1async__writer.html @@ -445,7 +445,7 @@ template<size_t CAPACITY = default_async_limit> diff --git a/classstdex_1_1stream_1_1basic-members.html b/classstdex_1_1stream_1_1basic-members.html index c7a2cdce6..be06a8ad6 100644 --- a/classstdex_1_1stream_1_1basic-members.html +++ b/classstdex_1_1stream_1_1basic-members.html @@ -148,7 +148,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1basic.html b/classstdex_1_1stream_1_1basic.html index 8fb65f830..270ef0095 100644 --- a/classstdex_1_1stream_1_1basic.html +++ b/classstdex_1_1stream_1_1basic.html @@ -1400,7 +1400,7 @@ template<class T > diff --git a/classstdex_1_1stream_1_1basic__file-members.html b/classstdex_1_1stream_1_1basic__file-members.html index 2740a977c..68a2bf648 100644 --- a/classstdex_1_1stream_1_1basic__file-members.html +++ b/classstdex_1_1stream_1_1basic__file-members.html @@ -164,7 +164,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1basic__file.html b/classstdex_1_1stream_1_1basic__file.html index 70163e64a..410fb8620 100644 --- a/classstdex_1_1stream_1_1basic__file.html +++ b/classstdex_1_1stream_1_1basic__file.html @@ -961,7 +961,7 @@ state_t m_state diff --git a/classstdex_1_1stream_1_1basic__sys-members.html b/classstdex_1_1stream_1_1basic__sys-members.html index 941f1628c..c8b00b1db 100644 --- a/classstdex_1_1stream_1_1basic__sys-members.html +++ b/classstdex_1_1stream_1_1basic__sys-members.html @@ -160,7 +160,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1basic__sys.html b/classstdex_1_1stream_1_1basic__sys.html index 05fdb1f5c..35efead72 100644 --- a/classstdex_1_1stream_1_1basic__sys.html +++ b/classstdex_1_1stream_1_1basic__sys.html @@ -527,7 +527,7 @@ sys_handle m_h diff --git a/classstdex_1_1stream_1_1buffer-members.html b/classstdex_1_1stream_1_1buffer-members.html index f71a254b2..cafc88e50 100644 --- a/classstdex_1_1stream_1_1buffer-members.html +++ b/classstdex_1_1stream_1_1buffer-members.html @@ -155,7 +155,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1buffer.html b/classstdex_1_1stream_1_1buffer.html index 85ba507e9..980b6d16c 100644 --- a/classstdex_1_1stream_1_1buffer.html +++ b/classstdex_1_1stream_1_1buffer.html @@ -489,7 +489,7 @@ state_t m_state diff --git a/classstdex_1_1stream_1_1buffered__sys-members.html b/classstdex_1_1stream_1_1buffered__sys-members.html index 484315d2e..e5d2dc5b8 100644 --- a/classstdex_1_1stream_1_1buffered__sys-members.html +++ b/classstdex_1_1stream_1_1buffered__sys-members.html @@ -157,7 +157,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1buffered__sys.html b/classstdex_1_1stream_1_1buffered__sys.html index 32eae0d6e..592cf71a5 100644 --- a/classstdex_1_1stream_1_1buffered__sys.html +++ b/classstdex_1_1stream_1_1buffered__sys.html @@ -365,7 +365,7 @@ void flush_write () diff --git a/classstdex_1_1stream_1_1cache-members.html b/classstdex_1_1stream_1_1cache-members.html index a27653943..38415af19 100644 --- a/classstdex_1_1stream_1_1cache-members.html +++ b/classstdex_1_1stream_1_1cache-members.html @@ -166,7 +166,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1cache.html b/classstdex_1_1stream_1_1cache.html index 76db6d73b..ea6f6f013 100644 --- a/classstdex_1_1stream_1_1cache.html +++ b/classstdex_1_1stream_1_1cache.html @@ -925,7 +925,7 @@ state_t m_state diff --git a/classstdex_1_1stream_1_1cached__file-members.html b/classstdex_1_1stream_1_1cached__file-members.html index c5e5ad830..9dd59034d 100644 --- a/classstdex_1_1stream_1_1cached__file-members.html +++ b/classstdex_1_1stream_1_1cached__file-members.html @@ -173,7 +173,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1cached__file.html b/classstdex_1_1stream_1_1cached__file.html index 4db3d1120..0b1c532ad 100644 --- a/classstdex_1_1stream_1_1cached__file.html +++ b/classstdex_1_1stream_1_1cached__file.html @@ -600,7 +600,7 @@ state_t m_state diff --git a/classstdex_1_1stream_1_1converter-members.html b/classstdex_1_1stream_1_1converter-members.html index 4316534aa..b86dd4024 100644 --- a/classstdex_1_1stream_1_1converter-members.html +++ b/classstdex_1_1stream_1_1converter-members.html @@ -150,7 +150,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1converter.html b/classstdex_1_1stream_1_1converter.html index ccb16ccac..3010b60f8 100644 --- a/classstdex_1_1stream_1_1converter.html +++ b/classstdex_1_1stream_1_1converter.html @@ -507,7 +507,7 @@ state_t m_state diff --git a/classstdex_1_1stream_1_1diag__file-members.html b/classstdex_1_1stream_1_1diag__file-members.html index 1985d82eb..c53745552 100644 --- a/classstdex_1_1stream_1_1diag__file-members.html +++ b/classstdex_1_1stream_1_1diag__file-members.html @@ -167,7 +167,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1diag__file.html b/classstdex_1_1stream_1_1diag__file.html index 29addf0d1..7149e2eec 100644 --- a/classstdex_1_1stream_1_1diag__file.html +++ b/classstdex_1_1stream_1_1diag__file.html @@ -754,7 +754,7 @@ state_t m_state diff --git a/classstdex_1_1stream_1_1fifo-members.html b/classstdex_1_1stream_1_1fifo-members.html index 5b139baf9..f6ee16624 100644 --- a/classstdex_1_1stream_1_1fifo-members.html +++ b/classstdex_1_1stream_1_1fifo-members.html @@ -155,7 +155,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1fifo.html b/classstdex_1_1stream_1_1fifo.html index d060c9b1a..3cb2c8207 100644 --- a/classstdex_1_1stream_1_1fifo.html +++ b/classstdex_1_1stream_1_1fifo.html @@ -479,7 +479,7 @@ state_t m_state diff --git a/classstdex_1_1stream_1_1file-members.html b/classstdex_1_1stream_1_1file-members.html index 6ae673942..c68a841be 100644 --- a/classstdex_1_1stream_1_1file-members.html +++ b/classstdex_1_1stream_1_1file-members.html @@ -189,7 +189,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1file.html b/classstdex_1_1stream_1_1file.html index 346991de6..eb7215363 100644 --- a/classstdex_1_1stream_1_1file.html +++ b/classstdex_1_1stream_1_1file.html @@ -1161,7 +1161,7 @@ sys_handle m_h diff --git a/classstdex_1_1stream_1_1file__window-members.html b/classstdex_1_1stream_1_1file__window-members.html index 5ad04889e..6bc78dd4a 100644 --- a/classstdex_1_1stream_1_1file__window-members.html +++ b/classstdex_1_1stream_1_1file__window-members.html @@ -168,7 +168,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1file__window.html b/classstdex_1_1stream_1_1file__window.html index 966f87326..1ecb54c1c 100644 --- a/classstdex_1_1stream_1_1file__window.html +++ b/classstdex_1_1stream_1_1file__window.html @@ -787,7 +787,7 @@ state_t m_state diff --git a/classstdex_1_1stream_1_1limiter-members.html b/classstdex_1_1stream_1_1limiter-members.html index 26ed1c351..69588d142 100644 --- a/classstdex_1_1stream_1_1limiter-members.html +++ b/classstdex_1_1stream_1_1limiter-members.html @@ -153,7 +153,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1limiter.html b/classstdex_1_1stream_1_1limiter.html index 09c3734a8..f14f64f21 100644 --- a/classstdex_1_1stream_1_1limiter.html +++ b/classstdex_1_1stream_1_1limiter.html @@ -456,7 +456,7 @@ state_t m_state diff --git a/classstdex_1_1stream_1_1memory__file-members.html b/classstdex_1_1stream_1_1memory__file-members.html index 4ec85bb06..59bdf27bf 100644 --- a/classstdex_1_1stream_1_1memory__file-members.html +++ b/classstdex_1_1stream_1_1memory__file-members.html @@ -208,7 +208,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1memory__file.html b/classstdex_1_1stream_1_1memory__file.html index d25f2f33f..67db9ea1c 100644 --- a/classstdex_1_1stream_1_1memory__file.html +++ b/classstdex_1_1stream_1_1memory__file.html @@ -1690,7 +1690,7 @@ template<class T > diff --git a/classstdex_1_1stream_1_1replicator-members.html b/classstdex_1_1stream_1_1replicator-members.html index 9a507f2aa..65af33244 100644 --- a/classstdex_1_1stream_1_1replicator-members.html +++ b/classstdex_1_1stream_1_1replicator-members.html @@ -153,7 +153,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1replicator.html b/classstdex_1_1stream_1_1replicator.html index ef88a7efb..7b10aad7c 100644 --- a/classstdex_1_1stream_1_1replicator.html +++ b/classstdex_1_1stream_1_1replicator.html @@ -462,7 +462,7 @@ state_t m_state diff --git a/classstdex_1_1stream_1_1replicator_1_1worker-members.html b/classstdex_1_1stream_1_1replicator_1_1worker-members.html index ed185deaf..cf4dace3d 100644 --- a/classstdex_1_1stream_1_1replicator_1_1worker-members.html +++ b/classstdex_1_1stream_1_1replicator_1_1worker-members.html @@ -93,7 +93,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1replicator_1_1worker.html b/classstdex_1_1stream_1_1replicator_1_1worker.html index fa303d1ed..6f1ba26e6 100644 --- a/classstdex_1_1stream_1_1replicator_1_1worker.html +++ b/classstdex_1_1stream_1_1replicator_1_1worker.html @@ -149,7 +149,7 @@ void process_op () diff --git a/classstdex_1_1stream_1_1socket-members.html b/classstdex_1_1stream_1_1socket-members.html index d2f530e39..d64263773 100644 --- a/classstdex_1_1stream_1_1socket-members.html +++ b/classstdex_1_1stream_1_1socket-members.html @@ -156,7 +156,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1socket.html b/classstdex_1_1stream_1_1socket.html index f32312d80..fee1e7d2b 100644 --- a/classstdex_1_1stream_1_1socket.html +++ b/classstdex_1_1stream_1_1socket.html @@ -533,7 +533,7 @@ state_t m_state diff --git a/classstdex_1_1stream_1_1window-members.html b/classstdex_1_1stream_1_1window-members.html index 9e598e178..152694db1 100644 --- a/classstdex_1_1stream_1_1window-members.html +++ b/classstdex_1_1stream_1_1window-members.html @@ -156,7 +156,7 @@ $(function() { diff --git a/classstdex_1_1stream_1_1window.html b/classstdex_1_1stream_1_1window.html index dd4c63fb8..be0e79eab 100644 --- a/classstdex_1_1stream_1_1window.html +++ b/classstdex_1_1stream_1_1window.html @@ -465,7 +465,7 @@ state_t m_state diff --git a/classstdex_1_1stream__hasher-members.html b/classstdex_1_1stream__hasher-members.html index a8108a967..4af3c8176 100644 --- a/classstdex_1_1stream__hasher-members.html +++ b/classstdex_1_1stream__hasher-members.html @@ -152,7 +152,7 @@ $(function() { diff --git a/classstdex_1_1stream__hasher.html b/classstdex_1_1stream__hasher.html index f40dae624..9c7b559a4 100644 --- a/classstdex_1_1stream__hasher.html +++ b/classstdex_1_1stream__hasher.html @@ -448,7 +448,7 @@ template<class T > diff --git a/classstdex_1_1sys__object-members.html b/classstdex_1_1sys__object-members.html index b096a97c2..2bd5a3555 100644 --- a/classstdex_1_1sys__object-members.html +++ b/classstdex_1_1sys__object-members.html @@ -95,7 +95,7 @@ $(function() { diff --git a/classstdex_1_1sys__object.html b/classstdex_1_1sys__object.html index 97b0115cf..083a68dab 100644 --- a/classstdex_1_1sys__object.html +++ b/classstdex_1_1sys__object.html @@ -182,7 +182,7 @@ sys_handle m_h diff --git a/classstdex_1_1user__cancelled-members.html b/classstdex_1_1user__cancelled-members.html index aab306a34..8a5e149b0 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 c1469b38e..00146866d 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 452091d63..0bd10f12f 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 d82423651..2dede4f74 100644 --- a/classstdex_1_1vector__queue.html +++ b/classstdex_1_1vector__queue.html @@ -795,7 +795,7 @@ template<class T > diff --git a/classstdex_1_1watchdog-members.html b/classstdex_1_1watchdog-members.html index 6c75986cb..f0e335357 100644 --- a/classstdex_1_1watchdog-members.html +++ b/classstdex_1_1watchdog-members.html @@ -94,7 +94,7 @@ $(function() { diff --git a/classstdex_1_1watchdog.html b/classstdex_1_1watchdog.html index fbbf9e50e..7f4e0c177 100644 --- a/classstdex_1_1watchdog.html +++ b/classstdex_1_1watchdog.html @@ -223,7 +223,7 @@ template<class _Clock , class _Duration = typename _Clock::duration> diff --git a/dir_4be4f7b278e009bf0f1906cf31fb73bd.html b/dir_4be4f7b278e009bf0f1906cf31fb73bd.html index 672c0ad51..dd0b6f07d 100644 --- a/dir_4be4f7b278e009bf0f1906cf31fb73bd.html +++ b/dir_4be4f7b278e009bf0f1906cf31fb73bd.html @@ -104,7 +104,7 @@ Files diff --git a/dir_d44c64559bbebec7f509842c48db8b23.html b/dir_d44c64559bbebec7f509842c48db8b23.html index c0cbbaaec..0280dbf9f 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 6df8d5c32..66cf70174 100644 --- a/dir_fca3c47b2ea228727bd6729832f89576.html +++ b/dir_fca3c47b2ea228727bd6729832f89576.html @@ -130,7 +130,7 @@ Files diff --git a/endian_8hpp_source.html b/endian_8hpp_source.html index cb9a8297a..409c44a3d 100644 --- a/endian_8hpp_source.html +++ b/endian_8hpp_source.html @@ -225,7 +225,7 @@ $(document).ready(function() { init_codefold(0); }); diff --git a/exception_8hpp_source.html b/exception_8hpp_source.html index 22c0366a7..bae1cfc9d 100644 --- a/exception_8hpp_source.html +++ b/exception_8hpp_source.html @@ -90,7 +90,7 @@ $(document).ready(function() { init_codefold(0); });
6#pragma once
7
8#include "compat.hpp"
-
9#include <exception>
+
9#include <stdexcept>
10
11namespace stdex
12{
@@ -107,7 +107,7 @@ $(document).ready(function() { init_codefold(0); }); diff --git a/files.html b/files.html index 3beeb5340..f8a4d7e8a 100644 --- a/files.html +++ b/files.html @@ -116,7 +116,7 @@ $(function() { diff --git a/functions.html b/functions.html index d8c6bb590..b765e579c 100644 --- a/functions.html +++ b/functions.html @@ -85,7 +85,7 @@ $(function() { diff --git a/functions_b.html b/functions_b.html index c3f916872..300c2b281 100644 --- a/functions_b.html +++ b/functions_b.html @@ -82,7 +82,7 @@ $(function() { diff --git a/functions_c.html b/functions_c.html index 1dcc189a6..ab5613b2e 100644 --- a/functions_c.html +++ b/functions_c.html @@ -92,7 +92,7 @@ $(function() { diff --git a/functions_d.html b/functions_d.html index 76552ef56..b48656f56 100644 --- a/functions_d.html +++ b/functions_d.html @@ -87,7 +87,7 @@ $(function() { diff --git a/functions_e.html b/functions_e.html index c391c10cf..62474a1a4 100644 --- a/functions_e.html +++ b/functions_e.html @@ -87,7 +87,7 @@ $(function() { diff --git a/functions_f.html b/functions_f.html index 5d2ce7a36..3edf8458b 100644 --- a/functions_f.html +++ b/functions_f.html @@ -87,7 +87,7 @@ $(function() { diff --git a/functions_func.html b/functions_func.html index c04c71a78..145e25403 100644 --- a/functions_func.html +++ b/functions_func.html @@ -82,7 +82,7 @@ $(function() { diff --git a/functions_func_b.html b/functions_func_b.html index 04955bde2..3f472c10d 100644 --- a/functions_func_b.html +++ b/functions_func_b.html @@ -80,7 +80,7 @@ $(function() { diff --git a/functions_func_c.html b/functions_func_c.html index 7304b719f..5d0cb1f99 100644 --- a/functions_func_c.html +++ b/functions_func_c.html @@ -85,7 +85,7 @@ $(function() { diff --git a/functions_func_d.html b/functions_func_d.html index a90323cd9..ce0c9b056 100644 --- a/functions_func_d.html +++ b/functions_func_d.html @@ -84,7 +84,7 @@ $(function() { diff --git a/functions_func_e.html b/functions_func_e.html index ae4ef0729..bbc6a696f 100644 --- a/functions_func_e.html +++ b/functions_func_e.html @@ -81,7 +81,7 @@ $(function() { diff --git a/functions_func_f.html b/functions_func_f.html index 59113fa85..c37002bd4 100644 --- a/functions_func_f.html +++ b/functions_func_f.html @@ -86,7 +86,7 @@ $(function() { diff --git a/functions_func_g.html b/functions_func_g.html index 792a83355..b3c525594 100644 --- a/functions_func_g.html +++ b/functions_func_g.html @@ -79,7 +79,7 @@ $(function() { diff --git a/functions_func_h.html b/functions_func_h.html index 101259ac9..69dade2ff 100644 --- a/functions_func_h.html +++ b/functions_func_h.html @@ -81,7 +81,7 @@ $(function() { diff --git a/functions_func_i.html b/functions_func_i.html index 09e520e8d..93b2c51d8 100644 --- a/functions_func_i.html +++ b/functions_func_i.html @@ -79,7 +79,7 @@ $(function() { diff --git a/functions_func_l.html b/functions_func_l.html index 34a9a74b1..0d56555ee 100644 --- a/functions_func_l.html +++ b/functions_func_l.html @@ -80,7 +80,7 @@ $(function() { diff --git a/functions_func_m.html b/functions_func_m.html index 6f13c1f81..58bcd3974 100644 --- a/functions_func_m.html +++ b/functions_func_m.html @@ -80,7 +80,7 @@ $(function() { diff --git a/functions_func_n.html b/functions_func_n.html index 94257de9a..26ab3cc3d 100644 --- a/functions_func_n.html +++ b/functions_func_n.html @@ -78,7 +78,7 @@ $(function() { diff --git a/functions_func_o.html b/functions_func_o.html index 15d853fc9..3489c5b04 100644 --- a/functions_func_o.html +++ b/functions_func_o.html @@ -90,7 +90,7 @@ $(function() { diff --git a/functions_func_p.html b/functions_func_p.html index 6c30a8139..b8259630a 100644 --- a/functions_func_p.html +++ b/functions_func_p.html @@ -83,7 +83,7 @@ $(function() { diff --git a/functions_func_q.html b/functions_func_q.html index 0871e9872..1dbb85293 100644 --- a/functions_func_q.html +++ b/functions_func_q.html @@ -78,7 +78,7 @@ $(function() { diff --git a/functions_func_r.html b/functions_func_r.html index a475ec3b4..00c1869ba 100644 --- a/functions_func_r.html +++ b/functions_func_r.html @@ -91,7 +91,7 @@ $(function() { diff --git a/functions_func_s.html b/functions_func_s.html index c6ab7f1a9..19de5a17f 100644 --- a/functions_func_s.html +++ b/functions_func_s.html @@ -98,7 +98,7 @@ $(function() { diff --git a/functions_func_t.html b/functions_func_t.html index bd48fd8d8..b9fb8814e 100644 --- a/functions_func_t.html +++ b/functions_func_t.html @@ -83,7 +83,7 @@ $(function() { diff --git a/functions_func_u.html b/functions_func_u.html index bc026dfce..9dbb687c2 100644 --- a/functions_func_u.html +++ b/functions_func_u.html @@ -79,7 +79,7 @@ $(function() { diff --git a/functions_func_v.html b/functions_func_v.html index 31d1efa48..bf067edfb 100644 --- a/functions_func_v.html +++ b/functions_func_v.html @@ -78,7 +78,7 @@ $(function() { diff --git a/functions_func_w.html b/functions_func_w.html index 20b05ed46..82032b2cc 100644 --- a/functions_func_w.html +++ b/functions_func_w.html @@ -87,7 +87,7 @@ $(function() { diff --git a/functions_func_~.html b/functions_func_~.html index 8175d5c96..de6cfb05d 100644 --- a/functions_func_~.html +++ b/functions_func_~.html @@ -79,7 +79,7 @@ $(function() { diff --git a/functions_g.html b/functions_g.html index 1997f51fc..438e1e57b 100644 --- a/functions_g.html +++ b/functions_g.html @@ -79,7 +79,7 @@ $(function() { diff --git a/functions_h.html b/functions_h.html index f196468b7..eece14926 100644 --- a/functions_h.html +++ b/functions_h.html @@ -82,7 +82,7 @@ $(function() { diff --git a/functions_i.html b/functions_i.html index 0d4977b1e..5ed62aa20 100644 --- a/functions_i.html +++ b/functions_i.html @@ -82,7 +82,7 @@ $(function() { diff --git a/functions_l.html b/functions_l.html index 4c0c2c45d..ef80fef4d 100644 --- a/functions_l.html +++ b/functions_l.html @@ -81,7 +81,7 @@ $(function() { diff --git a/functions_m.html b/functions_m.html index 574974f1c..8f87db567 100644 --- a/functions_m.html +++ b/functions_m.html @@ -105,7 +105,7 @@ $(function() { diff --git a/functions_n.html b/functions_n.html index 52671b2c8..6ffac74af 100644 --- a/functions_n.html +++ b/functions_n.html @@ -85,7 +85,7 @@ $(function() { diff --git a/functions_o.html b/functions_o.html index ed841be05..12da2aeba 100644 --- a/functions_o.html +++ b/functions_o.html @@ -94,7 +94,7 @@ $(function() { diff --git a/functions_p.html b/functions_p.html index b503907ea..aa8bcf3cc 100644 --- a/functions_p.html +++ b/functions_p.html @@ -90,7 +90,7 @@ $(function() { diff --git a/functions_q.html b/functions_q.html index f13ddbdba..f0b1a5761 100644 --- a/functions_q.html +++ b/functions_q.html @@ -78,7 +78,7 @@ $(function() { diff --git a/functions_r.html b/functions_r.html index 3e8baf77b..4720c8743 100644 --- a/functions_r.html +++ b/functions_r.html @@ -94,7 +94,7 @@ $(function() { diff --git a/functions_rela.html b/functions_rela.html index 36729ea85..ec111794f 100644 --- a/functions_rela.html +++ b/functions_rela.html @@ -77,7 +77,7 @@ $(function() { diff --git a/functions_s.html b/functions_s.html index f8cc51642..156d38bbf 100644 --- a/functions_s.html +++ b/functions_s.html @@ -104,7 +104,7 @@ $(function() { diff --git a/functions_t.html b/functions_t.html index 70b38c1de..f9a604ffa 100644 --- a/functions_t.html +++ b/functions_t.html @@ -84,7 +84,7 @@ $(function() { diff --git a/functions_type.html b/functions_type.html index 20c07f625..d887a26e4 100644 --- a/functions_type.html +++ b/functions_type.html @@ -81,7 +81,7 @@ $(function() { diff --git a/functions_u.html b/functions_u.html index e345568d2..bce878c41 100644 --- a/functions_u.html +++ b/functions_u.html @@ -79,7 +79,7 @@ $(function() { diff --git a/functions_v.html b/functions_v.html index 6ce0e7156..56e7c3db1 100644 --- a/functions_v.html +++ b/functions_v.html @@ -81,7 +81,7 @@ $(function() { diff --git a/functions_vars.html b/functions_vars.html index d048a74cd..eea64f8fa 100644 --- a/functions_vars.html +++ b/functions_vars.html @@ -225,7 +225,7 @@ $(function() { diff --git a/functions_w.html b/functions_w.html index 1c7f52188..48781b044 100644 --- a/functions_w.html +++ b/functions_w.html @@ -89,7 +89,7 @@ $(function() { diff --git a/functions_~.html b/functions_~.html index 32eefa3c0..7392ac533 100644 --- a/functions_~.html +++ b/functions_~.html @@ -79,7 +79,7 @@ $(function() { diff --git a/hash_8cpp_source.html b/hash_8cpp_source.html index 8f89b4c4a..ff26580bd 100644 --- a/hash_8cpp_source.html +++ b/hash_8cpp_source.html @@ -164,7 +164,7 @@ $(document).ready(function() { init_codefold(0); }); diff --git a/hash_8hpp_source.html b/hash_8hpp_source.html index 3308defb0..4c39a1e1b 100644 --- a/hash_8hpp_source.html +++ b/hash_8hpp_source.html @@ -743,7 +743,7 @@ $(document).ready(function() { init_codefold(0); }); diff --git a/hex_8hpp_source.html b/hex_8hpp_source.html index fe6334391..9ebbfca88 100644 --- a/hex_8hpp_source.html +++ b/hex_8hpp_source.html @@ -231,7 +231,7 @@ $(document).ready(function() { init_codefold(0); }); diff --git a/hierarchy.html b/hierarchy.html index 32c325d7b..d327efd9e 100644 --- a/hierarchy.html +++ b/hierarchy.html @@ -256,7 +256,7 @@ $(function() { diff --git a/idrec_8hpp_source.html b/idrec_8hpp_source.html index 272a51956..6ca5d9bcb 100644 --- a/idrec_8hpp_source.html +++ b/idrec_8hpp_source.html @@ -471,7 +471,7 @@ $(document).ready(function() { init_codefold(0); }); diff --git a/include_2stdex_2compat_8hpp_source.html b/include_2stdex_2compat_8hpp_source.html index 5fe7bdb1c..1cabb412c 100644 --- a/include_2stdex_2compat_8hpp_source.html +++ b/include_2stdex_2compat_8hpp_source.html @@ -92,209 +92,210 @@ $(document).ready(function() { init_codefold(0); });
8#include <assert.h>
9#include <stddef.h>
10#ifdef _WIN32
-
11#include <sal.h>
-
12#endif
-
13#include <type_traits>
-
14
-
15#ifndef _In_
-
16#define _In_
-
17#endif
-
18#ifndef _In_bytecount_
-
19#define _In_bytecount_(p)
-
20#endif
-
21#ifndef _In_count_
-
22#define _In_count_(p)
-
23#endif
-
24#ifndef _In_opt_
-
25#define _In_opt_
-
26#endif
-
27#ifndef _In_opt_count_
-
28#define _In_opt_count_(p)
-
29#endif
-
30#ifndef _In_opt_z_count_
-
31#define _In_opt_z_count_(p)
-
32#endif
-
33#ifndef _In_z_
-
34#define _In_z_
-
35#endif
-
36#ifndef _In_opt_z_
-
37#define _In_opt_z_
-
38#endif
-
39#ifndef _In_z_count_
-
40#define _In_z_count_(p)
-
41#endif
-
42#ifndef _In_reads_
-
43#define _In_reads_(p)
-
44#endif
-
45#ifndef _In_reads_z_
-
46#define _In_reads_z_(p)
-
47#endif
-
48#ifndef _In_reads_opt_
-
49#define _In_reads_opt_(p)
-
50#endif
-
51#ifndef _In_reads_opt_z_
-
52#define _In_reads_opt_z_(p)
-
53#endif
-
54#ifndef _In_reads_or_z_
-
55#define _In_reads_or_z_(p)
-
56#endif
-
57#ifndef _In_reads_or_z_opt_
-
58#define _In_reads_or_z_opt_(p)
-
59#endif
-
60#ifndef _In_reads_bytes_opt_
-
61#define _In_reads_bytes_opt_(p)
-
62#endif
-
63#ifndef _Printf_format_string_params_
-
64#define _Printf_format_string_params_(n)
-
65#endif
-
66
-
67#ifndef _Inout_
-
68#define _Inout_
-
69#endif
-
70#ifndef _Inout_opt_
-
71#define _Inout_opt_
-
72#endif
-
73#ifndef _Inout_z_
-
74#define _Inout_z_
-
75#endif
-
76#ifndef _Inout_cap_
-
77#define _Inout_cap_(p)
-
78#endif
-
79#ifndef _Inout_count_
-
80#define _Inout_count_(p)
-
81#endif
-
82#ifndef _Inout_updates_z_
-
83#define _Inout_updates_z_(p)
-
84#endif
-
85
-
86#ifndef _Use_decl_annotations_
-
87#define _Use_decl_annotations_
-
88#endif
-
89
-
90#ifndef _Out_
-
91#define _Out_
-
92#endif
-
93#ifndef _Out_opt_
-
94#define _Out_opt_
-
95#endif
-
96#ifndef _Out_z_cap_
-
97#define _Out_z_cap_(p)
-
98#endif
-
99#ifndef _Out_writes_
-
100#define _Out_writes_(p)
-
101#endif
-
102#ifndef _Out_writes_opt_
-
103#define _Out_writes_opt_(p)
-
104#endif
-
105#ifndef _Out_writes_opt_z_
-
106#define _Out_writes_opt_z_(p)
-
107#endif
-
108#ifndef _Out_writes_bytes_
-
109#define _Out_writes_bytes_(p)
-
110#endif
-
111#ifndef _Out_writes_to_
-
112#define _Out_writes_to_(p, q)
-
113#endif
-
114#ifndef _Out_writes_all_
-
115#define _Out_writes_all_(p)
-
116#endif
-
117#ifndef _Out_writes_z_
-
118#define _Out_writes_z_(p)
-
119#endif
-
120#ifndef _Out_writes_bytes_to_opt_
-
121#define _Out_writes_bytes_to_opt_(p, q)
-
122#endif
-
123
-
124#ifndef _Success_
-
125#define _Success_(p)
-
126#endif
-
127#ifndef _Ret_maybenull_
-
128#define _Ret_maybenull_
-
129#endif
-
130#ifndef _Ret_maybenull_z_
-
131#define _Ret_maybenull_z_
-
132#endif
-
133#ifndef _Ret_notnull_
-
134#define _Ret_notnull_
-
135#endif
-
136#ifndef _Ret_z_
-
137#define _Ret_z_
-
138#endif
-
139#ifndef _Must_inspect_result_
-
140#define _Must_inspect_result_
-
141#endif
-
142#ifndef _Check_return_
-
143#define _Check_return_
-
144#endif
-
145#ifndef _Post_maybez_
-
146#define _Post_maybez_
-
147#endif
-
148#ifndef _Null_terminated_
-
149#define _Null_terminated_
-
150#endif
-
151
-
152#ifndef _Likely_
-
153#if _HAS_CXX20
-
154#define _Likely_ [[likely]]
-
155#else
-
156#define _Likely_
-
157#endif
+
11#include <windows.h>
+
12#include <sal.h>
+
13#endif
+
14#include <type_traits>
+
15
+
16#ifndef _In_
+
17#define _In_
+
18#endif
+
19#ifndef _In_bytecount_
+
20#define _In_bytecount_(p)
+
21#endif
+
22#ifndef _In_count_
+
23#define _In_count_(p)
+
24#endif
+
25#ifndef _In_opt_
+
26#define _In_opt_
+
27#endif
+
28#ifndef _In_opt_count_
+
29#define _In_opt_count_(p)
+
30#endif
+
31#ifndef _In_opt_z_count_
+
32#define _In_opt_z_count_(p)
+
33#endif
+
34#ifndef _In_z_
+
35#define _In_z_
+
36#endif
+
37#ifndef _In_opt_z_
+
38#define _In_opt_z_
+
39#endif
+
40#ifndef _In_z_count_
+
41#define _In_z_count_(p)
+
42#endif
+
43#ifndef _In_reads_
+
44#define _In_reads_(p)
+
45#endif
+
46#ifndef _In_reads_z_
+
47#define _In_reads_z_(p)
+
48#endif
+
49#ifndef _In_reads_opt_
+
50#define _In_reads_opt_(p)
+
51#endif
+
52#ifndef _In_reads_opt_z_
+
53#define _In_reads_opt_z_(p)
+
54#endif
+
55#ifndef _In_reads_or_z_
+
56#define _In_reads_or_z_(p)
+
57#endif
+
58#ifndef _In_reads_or_z_opt_
+
59#define _In_reads_or_z_opt_(p)
+
60#endif
+
61#ifndef _In_reads_bytes_opt_
+
62#define _In_reads_bytes_opt_(p)
+
63#endif
+
64#ifndef _Printf_format_string_params_
+
65#define _Printf_format_string_params_(n)
+
66#endif
+
67
+
68#ifndef _Inout_
+
69#define _Inout_
+
70#endif
+
71#ifndef _Inout_opt_
+
72#define _Inout_opt_
+
73#endif
+
74#ifndef _Inout_z_
+
75#define _Inout_z_
+
76#endif
+
77#ifndef _Inout_cap_
+
78#define _Inout_cap_(p)
+
79#endif
+
80#ifndef _Inout_count_
+
81#define _Inout_count_(p)
+
82#endif
+
83#ifndef _Inout_updates_z_
+
84#define _Inout_updates_z_(p)
+
85#endif
+
86
+
87#ifndef _Use_decl_annotations_
+
88#define _Use_decl_annotations_
+
89#endif
+
90
+
91#ifndef _Out_
+
92#define _Out_
+
93#endif
+
94#ifndef _Out_opt_
+
95#define _Out_opt_
+
96#endif
+
97#ifndef _Out_z_cap_
+
98#define _Out_z_cap_(p)
+
99#endif
+
100#ifndef _Out_writes_
+
101#define _Out_writes_(p)
+
102#endif
+
103#ifndef _Out_writes_opt_
+
104#define _Out_writes_opt_(p)
+
105#endif
+
106#ifndef _Out_writes_opt_z_
+
107#define _Out_writes_opt_z_(p)
+
108#endif
+
109#ifndef _Out_writes_bytes_
+
110#define _Out_writes_bytes_(p)
+
111#endif
+
112#ifndef _Out_writes_to_
+
113#define _Out_writes_to_(p, q)
+
114#endif
+
115#ifndef _Out_writes_all_
+
116#define _Out_writes_all_(p)
+
117#endif
+
118#ifndef _Out_writes_z_
+
119#define _Out_writes_z_(p)
+
120#endif
+
121#ifndef _Out_writes_bytes_to_opt_
+
122#define _Out_writes_bytes_to_opt_(p, q)
+
123#endif
+
124
+
125#ifndef _Success_
+
126#define _Success_(p)
+
127#endif
+
128#ifndef _Ret_maybenull_
+
129#define _Ret_maybenull_
+
130#endif
+
131#ifndef _Ret_maybenull_z_
+
132#define _Ret_maybenull_z_
+
133#endif
+
134#ifndef _Ret_notnull_
+
135#define _Ret_notnull_
+
136#endif
+
137#ifndef _Ret_z_
+
138#define _Ret_z_
+
139#endif
+
140#ifndef _Must_inspect_result_
+
141#define _Must_inspect_result_
+
142#endif
+
143#ifndef _Check_return_
+
144#define _Check_return_
+
145#endif
+
146#ifndef _Post_maybez_
+
147#define _Post_maybez_
+
148#endif
+
149#ifndef _Null_terminated_
+
150#define _Null_terminated_
+
151#endif
+
152
+
153#ifndef _Likely_
+
154#if _HAS_CXX20
+
155#define _Likely_ [[likely]]
+
156#else
+
157#define _Likely_
158#endif
-
159
-
160#ifndef _Unlikely_
-
161#if _HAS_CXX20
-
162#define _Unlikely_ [[unlikely]]
-
163#else
-
164#define _Unlikely_
-
165#endif
+
159#endif
+
160
+
161#ifndef _Unlikely_
+
162#if _HAS_CXX20
+
163#define _Unlikely_ [[unlikely]]
+
164#else
+
165#define _Unlikely_
166#endif
-
167
-
168#if _HAS_CXX17
-
169#define _Constexpr_ constexpr
-
170#else
-
171#define _Constexpr_
-
172#endif
-
173
-
174#ifdef _MSC_VER
-
175#define _Deprecated_(message) __declspec(deprecated(message))
-
176#else
-
177#define _Deprecated_(message) [[deprecated(message)]]
-
178#endif
-
179
-
180#ifdef _WIN32
-
181#define _Unreferenced_(x) UNREFERENCED_PARAMETER(x)
-
182#else
-
183#define _Unreferenced_(x)
-
184#endif
-
185
-
186#ifndef _WIN32
-
187template <typename T, size_t N>
-
188size_t _countof(T (&arr)[N])
-
189{
-
190 return std::extent<T[N]>::value;
-
191}
-
192#endif
-
193
-
194#ifndef _Analysis_assume_
-
195#define _Analysis_assume_(p)
-
196#endif
-
197#ifdef NDEBUG
-
198#define _Assume_(p) _Analysis_assume_(p)
-
199#else
-
200#define _Assume_(p) assert(p)
-
201#endif
-
202
-
203#ifdef __APPLE__
-
204#define off64_t off_t
-
205#define lseek64 lseek
-
206#define lockf64 lockf
-
207#define ftruncate64 ftruncate
-
208#endif
-
209
+
167#endif
+
168
+
169#if _HAS_CXX17
+
170#define _Constexpr_ constexpr
+
171#else
+
172#define _Constexpr_
+
173#endif
+
174
+
175#ifdef _MSC_VER
+
176#define _Deprecated_(message) __declspec(deprecated(message))
+
177#else
+
178#define _Deprecated_(message) [[deprecated(message)]]
+
179#endif
+
180
+
181#ifdef _WIN32
+
182#define _Unreferenced_(x) UNREFERENCED_PARAMETER(x)
+
183#else
+
184#define _Unreferenced_(x)
+
185#endif
+
186
+
187#ifndef _WIN32
+
188template <typename T, size_t N>
+
189size_t _countof(T (&arr)[N])
+
190{
+
191 return std::extent<T[N]>::value;
+
192}
+
193#endif
+
194
+
195#ifndef _Analysis_assume_
+
196#define _Analysis_assume_(p)
+
197#endif
+
198#ifdef NDEBUG
+
199#define _Assume_(p) _Analysis_assume_(p)
+
200#else
+
201#define _Assume_(p) assert(p)
+
202#endif
+
203
+
204#ifdef __APPLE__
+
205#define off64_t off_t
+
206#define lseek64 lseek
+
207#define lockf64 lockf
+
208#define ftruncate64 ftruncate
+
209#endif
+
210
diff --git a/index.html b/index.html index 73c99221c..d1f2a146b 100644 --- a/index.html +++ b/index.html @@ -78,7 +78,7 @@ $(function() { diff --git a/interval_8hpp_source.html b/interval_8hpp_source.html index c04e63fc8..6f8b9b02d 100644 --- a/interval_8hpp_source.html +++ b/interval_8hpp_source.html @@ -222,7 +222,7 @@ $(document).ready(function() { init_codefold(0); }); diff --git a/mapping_8hpp_source.html b/mapping_8hpp_source.html index b53ec1d00..7efea64c2 100644 --- a/mapping_8hpp_source.html +++ b/mapping_8hpp_source.html @@ -124,7 +124,7 @@ $(document).ready(function() { init_codefold(0); }); diff --git a/math_8cpp_source.html b/math_8cpp_source.html index e6cc1d01f..4455079b9 100644 --- a/math_8cpp_source.html +++ b/math_8cpp_source.html @@ -129,7 +129,7 @@ $(document).ready(function() { init_codefold(0); }); diff --git a/math_8hpp_source.html b/math_8hpp_source.html index 4655c4f3c..abe07adf5 100644 --- a/math_8hpp_source.html +++ b/math_8hpp_source.html @@ -90,61 +90,64 @@ $(document).ready(function() { init_codefold(0); });
6#pragma once
7
8#include "compat.hpp"
-
9#include "system.hpp"
-
10#include <stdexcept>
-
11
-
12namespace stdex
-
13{
-
22 inline size_t mul(size_t a, size_t b)
-
23 {
-
24#if _MSC_VER >= 1300
-
25 SIZE_T result;
-
26 if (SUCCEEDED(SIZETMult(a, b, &result)))
-
27 return result;
-
28#elif defined(_MSC_VER)
-
29 if (a == 0)
-
30 return 0;
-
31 if (b <= SIZE_MAX / a)
-
32 return a * b;
-
33#else
-
34 size_t result;
-
35 if (!__builtin_mul_overflow(a, b, &result))
-
36 return result;
-
37#endif
-
38 throw std::invalid_argument("multiply overflow");
-
39 }
-
40
-
49 inline size_t add(size_t a, size_t b)
-
50 {
-
51#if _MSC_VER >= 1300
-
52 SIZE_T result;
-
53 if (SUCCEEDED(SIZETAdd(a, b, &result)))
-
54 return result;
-
55#elif defined(_MSC_VER)
-
56 if (a <= SIZE_MAX - b)
-
57 return a + b;
-
58#else
-
59 size_t result;
-
60 if (!__builtin_add_overflow(a, b, &result))
-
61 return result;
-
62#endif
-
63 throw std::invalid_argument("add overflow");
-
64 }
-
65
-
66
-
75 inline uint32_t rol(_In_ uint32_t value, _In_ int bits)
-
76 {
-
77#ifdef _WIN32
-
78 return _rotl(value, bits);
-
79#else
-
80 return (value << bits) | (value >> (32 - bits));
-
81#endif
-
82 }
-
83}
+
9#ifdef _WIN32
+
10#include <windows.h>
+
11#include <intrin.h>
+
12#include <intsafe.h>
+
13#endif
+
14#include <stdexcept>
+
15
+
16namespace stdex
+
17{
+
26 inline size_t mul(size_t a, size_t b)
+
27 {
+
28#if _MSC_VER >= 1300
+
29 SIZE_T result;
+
30 if (SUCCEEDED(SIZETMult(a, b, &result)))
+
31 return result;
+
32#elif defined(_MSC_VER)
+
33 if (a == 0)
+
34 return 0;
+
35 if (b <= SIZE_MAX / a)
+
36 return a * b;
+
37#else
+
38 size_t result;
+
39 if (!__builtin_mul_overflow(a, b, &result))
+
40 return result;
+
41#endif
+
42 throw std::invalid_argument("multiply overflow");
+
43 }
+
44
+
53 inline size_t add(size_t a, size_t b)
+
54 {
+
55#if _MSC_VER >= 1300
+
56 SIZE_T result;
+
57 if (SUCCEEDED(SIZETAdd(a, b, &result)))
+
58 return result;
+
59#elif defined(_MSC_VER)
+
60 if (a <= SIZE_MAX - b)
+
61 return a + b;
+
62#else
+
63 size_t result;
+
64 if (!__builtin_add_overflow(a, b, &result))
+
65 return result;
+
66#endif
+
67 throw std::invalid_argument("add overflow");
+
68 }
+
69
+
78 inline uint32_t rol(_In_ uint32_t value, _In_ int bits)
+
79 {
+
80#ifdef _WIN32
+
81 return _rotl(value, bits);
+
82#else
+
83 return (value << bits) | (value >> (32 - bits));
+
84#endif
+
85 }
+
86}
diff --git a/memory_8hpp_source.html b/memory_8hpp_source.html index 0246db7f8..9730c7973 100644 --- a/memory_8hpp_source.html +++ b/memory_8hpp_source.html @@ -89,46 +89,47 @@ $(document).ready(function() { init_codefold(0); });
5
6#pragma once
7
-
8#include <memory>
-
9
-
10namespace stdex
-
11{
-
15 template <class T>
-
-
16 struct no_delete {
-
17 constexpr no_delete() noexcept = default;
-
18
-
19 template <class T2, std::enable_if_t<std::is_convertible_v<T2*, T*>, int> = 0>
-
20 inline no_delete(const no_delete<T2>&) noexcept {}
-
21
-
22 inline void operator()(T* p) const noexcept { _Unreferenced_(p); }
-
23 };
+
8#include "compat.hpp"
+
9#include <memory>
+
10
+
11namespace stdex
+
12{
+
16 template <class T>
+
+
17 struct no_delete {
+
18 constexpr no_delete() noexcept = default;
+
19
+
20 template <class T2, std::enable_if_t<std::is_convertible_v<T2*, T*>, int> = 0>
+
21 inline no_delete(const no_delete<T2>&) noexcept {}
+
22
+
23 inline void operator()(T* p) const noexcept { _Unreferenced_(p); }
+
24 };
-
24
-
28 template <class T>
-
-
29 struct no_delete<T[]> {
-
30 constexpr no_delete() noexcept = default;
-
31
-
32 template <class _Uty, std::enable_if_t<std::is_convertible_v<_Uty(*)[], T(*)[]>, int> = 0>
-
33 inline no_delete(const no_delete<_Uty[]>&) noexcept {}
-
34
-
35 template <class _Uty, std::enable_if_t<std::is_convertible_v<_Uty(*)[], T(*)[]>, int> = 0>
-
36 inline void operator()(_Uty* p) const noexcept { p; }
-
37 };
+
25
+
29 template <class T>
+
+
30 struct no_delete<T[]> {
+
31 constexpr no_delete() noexcept = default;
+
32
+
33 template <class _Uty, std::enable_if_t<std::is_convertible_v<_Uty(*)[], T(*)[]>, int> = 0>
+
34 inline no_delete(const no_delete<_Uty[]>&) noexcept {}
+
35
+
36 template <class _Uty, std::enable_if_t<std::is_convertible_v<_Uty(*)[], T(*)[]>, int> = 0>
+
37 inline void operator()(_Uty* p) const noexcept { p; }
+
38 };
-
38
-
47 template <class T>
-
48 inline std::shared_ptr<T> make_shared_no_delete(_In_ T* p)
-
49 {
-
50 return std::shared_ptr<T>(p, no_delete<T>{});
-
51 }
-
52}
-
Noop deleter.
Definition memory.hpp:16
+
39
+
48 template <class T>
+
49 inline std::shared_ptr<T> make_shared_no_delete(_In_ T* p)
+
50 {
+
51 return std::shared_ptr<T>(p, no_delete<T>{});
+
52 }
+
53}
+
Noop deleter.
Definition memory.hpp:17
diff --git a/parser_8cpp_source.html b/parser_8cpp_source.html index aff6d2b71..91529e8de 100644 --- a/parser_8cpp_source.html +++ b/parser_8cpp_source.html @@ -584,12 +584,12 @@ $(document).ready(function() { init_codefold(0); });
500 };
501}
stdex::parser::basic_parser< char >
-
stdex::parser::basic_parser::interval
interval< size_t > interval
Region of the last match.
Definition parser.hpp:177
-
stdex::parser::basic_string
Test for given string.
Definition parser.hpp:823
-
stdex::parser::http_header
Test for HTTP header.
Definition parser.hpp:7155
-
stdex::parser::http_request
Test for HTTP request.
Definition parser.hpp:7017
-
stdex::parser::sgml_cp
Test for specific SGML code point.
Definition parser.hpp:348
-
stdex::parser::sgml_space_cp
Test for any SGML space code point.
Definition parser.hpp:435
+
stdex::parser::basic_parser::interval
interval< size_t > interval
Region of the last match.
Definition parser.hpp:176
+
stdex::parser::basic_string
Test for given string.
Definition parser.hpp:822
+
stdex::parser::http_header
Test for HTTP header.
Definition parser.hpp:7154
+
stdex::parser::http_request
Test for HTTP request.
Definition parser.hpp:7016
+
stdex::parser::sgml_cp
Test for specific SGML code point.
Definition parser.hpp:347
+
stdex::parser::sgml_space_cp
Test for any SGML space code point.
Definition parser.hpp:434
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
@@ -597,7 +597,7 @@ $(document).ready(function() { init_codefold(0); }); diff --git a/parser_8hpp_source.html b/parser_8hpp_source.html index 63862bac5..87bc0642d 100644 --- a/parser_8hpp_source.html +++ b/parser_8hpp_source.html @@ -94,7521 +94,7520 @@ $(document).ready(function() { init_codefold(0); });
10#include "memory.hpp"
11#include "sgml.hpp"
12#include "string.hpp"
-
13#include "system.hpp"
-
14#include <stdarg.h>
-
15#include <stdint.h>
-
16#include <math.h>
-
17#if defined(_WIN32)
-
18#include <winsock2.h>
-
19#if _MSC_VER >= 1300
-
20#include <ws2ipdef.h>
-
21#endif
-
22#include <ws2tcpip.h>
-
23#elif defined(__APPLE__)
-
24#include <netinet/in.h>
-
25#else
-
26#include <inaddr.h>
-
27#include <in6addr.h>
-
28#endif
-
29#include <limits>
-
30#include <list>
-
31#include <locale>
-
32#include <memory>
-
33#include <set>
-
34#include <string>
-
35
-
36#ifdef _MSC_VER
-
37#pragma warning(push)
-
38#pragma warning(disable: 4100)
-
39#endif
-
40
-
41#define ENUM_FLAG_OPERATOR(T,X) \
-
42inline 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)); } \
-
43inline 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); } \
-
44inline 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)); } \
-
45inline T& operator X= (T& lhs, const T rhs) { return lhs = lhs X rhs; } \
-
46inline T& operator X= (T& lhs, const std::underlying_type_t<T> rhs) { return lhs = lhs X rhs; }
-
47#define ENUM_FLAGS(T, type) \
-
48enum class T : type; \
-
49inline T operator ~ (T t) { return (T) (~static_cast<std::underlying_type_t <T>>(t)); } \
-
50ENUM_FLAG_OPERATOR(T,|) \
-
51ENUM_FLAG_OPERATOR(T,^) \
-
52ENUM_FLAG_OPERATOR(T,&) \
-
53enum class T : type
-
54
-
55#if defined(_WIN32)
-
56#elif defined(__APPLE__)
-
57#define s6_words __u6_addr.__u6_addr16
-
58#else
-
59#error Unsupported platform
-
60#endif
-
61
-
62namespace stdex
-
63{
-
64 namespace parser
-
65 {
-
69 constexpr int match_default = 0;
-
70 constexpr int match_case_insensitive = 0x1;
-
71 constexpr int match_multiline = 0x2;
-
72
-
76 template <class T>
-
-
77 class basic_parser
-
78 {
-
79 public:
-
80 basic_parser(_In_ const std::locale& locale = std::locale()) : m_locale(locale) {}
-
81 virtual ~basic_parser() {}
-
82
-
83 bool search(
-
84 _In_reads_or_z_(end) const T* text,
-
85 _In_ size_t start = 0,
-
86 _In_ size_t end = (size_t)-1,
-
87 _In_ int flags = match_default)
-
88 {
-
89 for (size_t i = start; i < end && text[i]; i++)
-
90 if (match(text, i, end, flags))
-
91 return true;
-
92 return false;
-
93 }
-
94
-
95 virtual bool match(
-
96 _In_reads_or_z_(end) const T* text,
-
97 _In_ size_t start = 0,
-
98 _In_ size_t end = (size_t)-1,
-
99 _In_ int flags = match_default) = 0;
-
100
-
101 template<class _Traits, class _Ax>
-
102 inline bool match(
-
103 const std::basic_string<T, _Traits, _Ax>& text,
-
104 _In_ size_t start = 0,
-
105 _In_ size_t end = (size_t)-1,
-
106 _In_ int flags = match_default)
-
107 {
-
108 return match(text.c_str(), start, std::min<size_t>(end, text.size()), flags);
-
109 }
-
110
-
111 virtual void invalidate()
-
112 {
-
113 this->interval.start = 1;
-
114 this->interval.end = 0;
-
115 }
-
116
-
117 protected:
-
119 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])
-
120 {
-
121 if (text[start] == '&') {
-
122 // Potential entity start
-
123 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
-
124 for (chr_end = start + 1;; chr_end++) {
-
125 if (chr_end >= end || text[chr_end] == 0) {
-
126 // Unterminated entity
-
127 break;
-
128 }
-
129 if (text[chr_end] == ';') {
-
130 // Entity end
-
131 size_t n = chr_end - start - 1;
-
132 if (n >= 2 && text[start + 1] == '#') {
-
133 // Numerical entity
-
134 char32_t unicode;
-
135 if (text[start + 2] == 'x' || text[start + 2] == 'X')
-
136 unicode = strtou32(text + start + 3, n - 2, nullptr, 16);
-
137 else
-
138 unicode = strtou32(text + start + 2, n - 1, nullptr, 10);
-
139#ifdef _WIN32
-
140 if (unicode < 0x10000) {
-
141 buf[0] = (wchar_t)unicode;
-
142 buf[1] = 0;
-
143 }
-
144 else {
-
145 ucs4_to_surrogate_pair(buf, unicode);
-
146 buf[2] = 0;
-
147 }
-
148#else
-
149 buf[0] = (wchar_t)unicode;
-
150 buf[1] = 0;
-
151#endif
-
152 chr_end++;
-
153 return buf;
-
154 }
-
155 const wchar_t* entity_w = sgml2uni(text + start + 1, n);
-
156 if (entity_w) {
-
157 chr_end++;
-
158 return entity_w;
-
159 }
-
160 // Unknown entity.
-
161 break;
-
162 }
-
163 else if (text[chr_end] == '&' || ctype.is(ctype.space, text[chr_end])) {
-
164 // This char cannot possibly be a part of entity.
-
165 break;
-
166 }
-
167 }
-
168 }
-
169 buf[0] = text[start];
-
170 buf[1] = 0;
-
171 chr_end = start + 1;
-
172 return buf;
-
173 }
-
175
-
176 public:
-
177 interval<size_t> interval;
-
178
-
179 protected:
-
180 std::locale m_locale;
-
181 };
+
13#include <stdarg.h>
+
14#include <stdint.h>
+
15#include <math.h>
+
16#if defined(_WIN32)
+
17#include <winsock2.h>
+
18#if _MSC_VER >= 1300
+
19#include <ws2ipdef.h>
+
20#endif
+
21#include <ws2tcpip.h>
+
22#elif defined(__APPLE__)
+
23#include <netinet/in.h>
+
24#else
+
25#include <inaddr.h>
+
26#include <in6addr.h>
+
27#endif
+
28#include <limits>
+
29#include <list>
+
30#include <locale>
+
31#include <memory>
+
32#include <set>
+
33#include <string>
+
34
+
35#ifdef _MSC_VER
+
36#pragma warning(push)
+
37#pragma warning(disable: 4100)
+
38#endif
+
39
+
40#define ENUM_FLAG_OPERATOR(T,X) \
+
41inline 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)); } \
+
42inline 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); } \
+
43inline 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)); } \
+
44inline T& operator X= (T& lhs, const T rhs) { return lhs = lhs X rhs; } \
+
45inline T& operator X= (T& lhs, const std::underlying_type_t<T> rhs) { return lhs = lhs X rhs; }
+
46#define ENUM_FLAGS(T, type) \
+
47enum class T : type; \
+
48inline T operator ~ (T t) { return (T) (~static_cast<std::underlying_type_t <T>>(t)); } \
+
49ENUM_FLAG_OPERATOR(T,|) \
+
50ENUM_FLAG_OPERATOR(T,^) \
+
51ENUM_FLAG_OPERATOR(T,&) \
+
52enum class T : type
+
53
+
54#if defined(_WIN32)
+
55#elif defined(__APPLE__)
+
56#define s6_words __u6_addr.__u6_addr16
+
57#else
+
58#error Unsupported platform
+
59#endif
+
60
+
61namespace stdex
+
62{
+
63 namespace parser
+
64 {
+
68 constexpr int match_default = 0;
+
69 constexpr int match_case_insensitive = 0x1;
+
70 constexpr int match_multiline = 0x2;
+
71
+
75 template <class T>
+
+ +
77 {
+
78 public:
+
79 basic_parser(_In_ const std::locale& locale = std::locale()) : m_locale(locale) {}
+
80 virtual ~basic_parser() {}
+
81
+
82 bool search(
+
83 _In_reads_or_z_(end) const T* text,
+
84 _In_ size_t start = 0,
+
85 _In_ size_t end = (size_t)-1,
+
86 _In_ int flags = match_default)
+
87 {
+
88 for (size_t i = start; i < end && text[i]; i++)
+
89 if (match(text, i, end, flags))
+
90 return true;
+
91 return false;
+
92 }
+
93
+
94 virtual bool match(
+
95 _In_reads_or_z_(end) const T* text,
+
96 _In_ size_t start = 0,
+
97 _In_ size_t end = (size_t)-1,
+
98 _In_ int flags = match_default) = 0;
+
99
+
100 template<class _Traits, class _Ax>
+
101 inline bool match(
+
102 const std::basic_string<T, _Traits, _Ax>& text,
+
103 _In_ size_t start = 0,
+
104 _In_ size_t end = (size_t)-1,
+
105 _In_ int flags = match_default)
+
106 {
+
107 return match(text.c_str(), start, std::min<size_t>(end, text.size()), flags);
+
108 }
+
109
+
110 virtual void invalidate()
+
111 {
+
112 this->interval.start = 1;
+
113 this->interval.end = 0;
+
114 }
+
115
+
116 protected:
+
118 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])
+
119 {
+
120 if (text[start] == '&') {
+
121 // Potential entity start
+
122 const auto& ctype = std::use_facet<std::ctype<T>>(m_locale);
+
123 for (chr_end = start + 1;; chr_end++) {
+
124 if (chr_end >= end || text[chr_end] == 0) {
+
125 // Unterminated entity
+
126 break;
+
127 }
+
128 if (text[chr_end] == ';') {
+
129 // Entity end
+
130 size_t n = chr_end - start - 1;
+
131 if (n >= 2 && text[start + 1] == '#') {
+
132 // Numerical entity
+
133 char32_t unicode;
+
134 if (text[start + 2] == 'x' || text[start + 2] == 'X')
+
135 unicode = strtou32(text + start + 3, n - 2, nullptr, 16);
+
136 else
+
137 unicode = strtou32(text + start + 2, n - 1, nullptr, 10);
+
138#ifdef _WIN32
+
139 if (unicode < 0x10000) {
+
140 buf[0] = (wchar_t)unicode;
+
141 buf[1] = 0;
+
142 }
+
143 else {
+
144 ucs4_to_surrogate_pair(buf, unicode);
+
145 buf[2] = 0;
+
146 }
+
147#else
+
148 buf[0] = (wchar_t)unicode;
+
149 buf[1] = 0;
+
150#endif
+
151 chr_end++;
+
152 return buf;
+
153 }
+
154 const wchar_t* entity_w = sgml2uni(text + start + 1, n);
+
155 if (entity_w) {
+
156 chr_end++;
+
157 return entity_w;
+
158 }
+
159 // Unknown entity.
+
160 break;
+
161 }
+
162 else if (text[chr_end] == '&' || ctype.is(ctype.space, text[chr_end])) {
+
163 // This char cannot possibly be a part of entity.
+
164 break;
+
165 }
+
166 }
+
167 }
+
168 buf[0] = text[start];
+
169 buf[1] = 0;
+
170 chr_end = start + 1;
+
171 return buf;
+
172 }
+
174
+
175 public:
+ +
177
+
178 protected:
+
179 std::locale m_locale;
+
180 };
-
182
-
183 using parser = basic_parser<char>;
-
184 using wparser = basic_parser<wchar_t>;
-
185#ifdef _UNICODE
-
186 using tparser = wparser;
-
187#else
-
188 using tparser = parser;
-
189#endif
-
190 using sgml_parser = basic_parser<char>;
-
191
-
195 template <class T>
-
-
196 class basic_noop : public basic_parser<T>
-
197 {
-
198 public:
-
199 virtual bool match(
-
200 _In_reads_or_z_(end) const T* text,
-
201 _In_ size_t start = 0,
-
202 _In_ size_t end = (size_t)-1,
-
203 _In_ int flags = match_default)
-
204 {
-
205 _Assume_(text || start >= end);
-
206 if (start < end && text[start]) {
-
207 this->interval.start = this->interval.end = start;
-
208 return true;
-
209 }
-
210 this->interval.start = (this->interval.end = start) + 1;
-
211 return false;
-
212 }
-
213 };
+
181
+ + +
184#ifdef _UNICODE
+
185 using tparser = wparser;
+
186#else
+
187 using tparser = parser;
+
188#endif
+ +
190
+
194 template <class T>
+
+
195 class basic_noop : public basic_parser<T>
+
196 {
+
197 public:
+
198 virtual bool match(
+
199 _In_reads_or_z_(end) const T* text,
+
200 _In_ size_t start = 0,
+
201 _In_ size_t end = (size_t)-1,
+
202 _In_ int flags = match_default)
+
203 {
+
204 _Assume_(text || start >= end);
+
205 if (start < end && text[start]) {
+
206 this->interval.start = this->interval.end = start;
+
207 return true;
+
208 }
+
209 this->interval.start = (this->interval.end = start) + 1;
+
210 return false;
+
211 }
+
212 };
-
214
-
215 using noop = basic_noop<char>;
- -
217#ifdef _UNICODE
-
218 using tnoop = wnoop;
-
219#else
-
220 using tnoop = noop;
-
221#endif
- -
223
-
227 template <class T>
-
-
228 class basic_any_cu : public basic_parser<T>
-
229 {
-
230 public:
-
231 basic_any_cu(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
-
232
-
233 virtual bool match(
-
234 _In_reads_or_z_(end) const T* text,
-
235 _In_ size_t start = 0,
-
236 _In_ size_t end = (size_t)-1,
-
237 _In_ int flags = match_default)
-
238 {
-
239 _Assume_(text || start >= end);
-
240 if (start < end && text[start]) {
-
241 this->interval.end = (this->interval.start = start) + 1;
-
242 return true;
-
243 }
-
244 this->interval.start = (this->interval.end = start) + 1;
-
245 return false;
-
246 }
-
247 };
+
213
+
214 using noop = basic_noop<char>;
+ +
216#ifdef _UNICODE
+
217 using tnoop = wnoop;
+
218#else
+
219 using tnoop = noop;
+
220#endif
+ +
222
+
226 template <class T>
+
+
227 class basic_any_cu : public basic_parser<T>
+
228 {
+
229 public:
+
230 basic_any_cu(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
+
231
+
232 virtual bool match(
+
233 _In_reads_or_z_(end) const T* text,
+
234 _In_ size_t start = 0,
+
235 _In_ size_t end = (size_t)-1,
+
236 _In_ int flags = match_default)
+
237 {
+
238 _Assume_(text || start >= end);
+
239 if (start < end && text[start]) {
+
240 this->interval.end = (this->interval.start = start) + 1;
+
241 return true;
+
242 }
+
243 this->interval.start = (this->interval.end = start) + 1;
+
244 return false;
+
245 }
+
246 };
-
248
- - -
251#ifdef _UNICODE
-
252 using tany_cu = wany_cu;
-
253#else
-
254 using tany_cu = any_cu;
-
255#endif
-
256
-
-
260 class sgml_any_cp : public basic_any_cu<char>
-
261 {
-
262 public:
-
263 sgml_any_cp(_In_ const std::locale& locale = std::locale()) : basic_any_cu<char>(locale) {}
-
264
-
265 virtual bool match(
-
266 _In_reads_or_z_(end) const char* text,
-
267 _In_ size_t start = 0,
-
268 _In_ size_t end = (size_t)-1,
-
269 _In_ int flags = match_default)
-
270 {
-
271 _Assume_(text || start >= end);
-
272 if (start < end && text[start]) {
-
273 if (text[start] == '&') {
-
274 // SGML entity
-
275 const auto& ctype = std::use_facet<std::ctype<char>>(m_locale);
-
276 for (this->interval.end = start + 1; this->interval.end < end && text[this->interval.end]; this->interval.end++)
-
277 if (text[this->interval.end] == ';') {
-
278 this->interval.end++;
-
279 this->interval.start = start;
-
280 return true;
-
281 }
-
282 else if (text[this->interval.end] == '&' || ctype.is(ctype.space, text[this->interval.end]))
-
283 break;
-
284 // Unterminated entity
-
285 }
-
286 this->interval.end = (this->interval.start = start) + 1;
-
287 return true;
-
288 }
-
289 this->interval.start = (this->interval.end = start) + 1;
-
290 return false;
-
291 }
-
292 };
+
247
+ + +
250#ifdef _UNICODE
+
251 using tany_cu = wany_cu;
+
252#else
+
253 using tany_cu = any_cu;
+
254#endif
+
255
+
+
259 class sgml_any_cp : public basic_any_cu<char>
+
260 {
+
261 public:
+
262 sgml_any_cp(_In_ const std::locale& locale = std::locale()) : basic_any_cu<char>(locale) {}
+
263
+
264 virtual bool match(
+
265 _In_reads_or_z_(end) const char* text,
+
266 _In_ size_t start = 0,
+
267 _In_ size_t end = (size_t)-1,
+
268 _In_ int flags = match_default)
+
269 {
+
270 _Assume_(text || start >= end);
+
271 if (start < end && text[start]) {
+
272 if (text[start] == '&') {
+
273 // SGML entity
+
274 const auto& ctype = std::use_facet<std::ctype<char>>(m_locale);
+
275 for (this->interval.end = start + 1; this->interval.end < end && text[this->interval.end]; this->interval.end++)
+
276 if (text[this->interval.end] == ';') {
+
277 this->interval.end++;
+
278 this->interval.start = start;
+
279 return true;
+
280 }
+
281 else if (text[this->interval.end] == '&' || ctype.is(ctype.space, text[this->interval.end]))
+
282 break;
+
283 // Unterminated entity
+
284 }
+
285 this->interval.end = (this->interval.start = start) + 1;
+
286 return true;
+
287 }
+
288 this->interval.start = (this->interval.end = start) + 1;
+
289 return false;
+
290 }
+
291 };
-
293
-
297 template <class T>
-
-
298 class basic_cu : public basic_parser<T>
-
299 {
-
300 public:
-
301 basic_cu(T chr, bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
302 basic_parser<T>(locale),
-
303 m_chr(chr),
-
304 m_invert(invert)
-
305 {}
-
306
-
307 virtual bool match(
-
308 _In_reads_or_z_(end) const T* text,
-
309 _In_ size_t start = 0,
-
310 _In_ size_t end = (size_t)-1,
-
311 _In_ int flags = match_default)
-
312 {
-
313 _Assume_(text || start >= end);
-
314 if (start < end && text[start]) {
-
315 bool r;
-
316 if (flags & match_case_insensitive) {
-
317 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
-
318 r = ctype.tolower(text[start]) == ctype.tolower(m_chr);
-
319 }
-
320 else
-
321 r = text[start] == m_chr;
-
322 if ((r && !m_invert) || (!r && m_invert)) {
-
323 this->interval.end = (this->interval.start = start) + 1;
-
324 return true;
-
325 }
-
326 }
-
327 this->interval.start = (this->interval.end = start) + 1;
-
328 return false;
-
329 }
-
330
-
331 protected:
-
332 T m_chr;
-
333 bool m_invert;
-
334 };
+
292
+
296 template <class T>
+
+
297 class basic_cu : public basic_parser<T>
+
298 {
+
299 public:
+
300 basic_cu(T chr, bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
301 basic_parser<T>(locale),
+
302 m_chr(chr),
+
303 m_invert(invert)
+
304 {}
+
305
+
306 virtual bool match(
+
307 _In_reads_or_z_(end) const T* text,
+
308 _In_ size_t start = 0,
+
309 _In_ size_t end = (size_t)-1,
+
310 _In_ int flags = match_default)
+
311 {
+
312 _Assume_(text || start >= end);
+
313 if (start < end && text[start]) {
+
314 bool r;
+
315 if (flags & match_case_insensitive) {
+
316 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
+
317 r = ctype.tolower(text[start]) == ctype.tolower(m_chr);
+
318 }
+
319 else
+
320 r = text[start] == m_chr;
+
321 if ((r && !m_invert) || (!r && m_invert)) {
+
322 this->interval.end = (this->interval.start = start) + 1;
+
323 return true;
+
324 }
+
325 }
+
326 this->interval.start = (this->interval.end = start) + 1;
+
327 return false;
+
328 }
+
329
+
330 protected:
+
331 T m_chr;
+
332 bool m_invert;
+
333 };
-
335
-
336 using cu = basic_cu<char>;
-
337 using wcu = basic_cu<wchar_t>;
-
338#ifdef _UNICODE
-
339 using tcu = wcu;
-
340#else
-
341 using tcu = cu;
-
342#endif
-
343
-
-
347 class sgml_cp : public sgml_parser
-
348 {
-
349 public:
-
350 sgml_cp(const char* chr, size_t count = (size_t)-1, bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
351 sgml_parser(locale),
-
352 m_invert(invert)
-
353 {
-
354 _Assume_(chr || !count);
-
355 wchar_t buf[3];
-
356 size_t chr_end;
-
357 m_chr.assign(count ? next_sgml_cp(chr, 0, count, chr_end, buf) : L"");
-
358 }
-
359
-
360 virtual bool match(
-
361 _In_reads_or_z_(end) const char* text,
-
362 _In_ size_t start = 0,
-
363 _In_ size_t end = (size_t)-1,
-
364 _In_ int flags = match_default)
-
365 {
-
366 _Assume_(text || start >= end);
-
367 if (start < end && text[start]) {
-
368 wchar_t buf[3];
-
369 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
-
370 bool r = ((flags & match_case_insensitive) ?
-
371 stdex::strnicmp(chr, (size_t)-1, m_chr.c_str(), m_chr.size(), m_locale) :
-
372 stdex::strncmp(chr, (size_t)-1, m_chr.c_str(), m_chr.size())) == 0;
-
373 if ((r && !m_invert) || (!r && m_invert)) {
-
374 this->interval.start = start;
-
375 return true;
-
376 }
-
377 }
-
378 this->interval.start = (this->interval.end = start) + 1;
-
379 return false;
-
380 }
-
381
-
382 protected:
-
383 std::wstring m_chr;
-
384 bool m_invert;
-
385 };
+
334
+
335 using cu = basic_cu<char>;
+
336 using wcu = basic_cu<wchar_t>;
+
337#ifdef _UNICODE
+
338 using tcu = wcu;
+
339#else
+
340 using tcu = cu;
+
341#endif
+
342
+
+
346 class sgml_cp : public sgml_parser
+
347 {
+
348 public:
+
349 sgml_cp(const char* chr, size_t count = (size_t)-1, bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
350 sgml_parser(locale),
+
351 m_invert(invert)
+
352 {
+
353 _Assume_(chr || !count);
+
354 wchar_t buf[3];
+
355 size_t chr_end;
+
356 m_chr.assign(count ? next_sgml_cp(chr, 0, count, chr_end, buf) : L"");
+
357 }
+
358
+
359 virtual bool match(
+
360 _In_reads_or_z_(end) const char* text,
+
361 _In_ size_t start = 0,
+
362 _In_ size_t end = (size_t)-1,
+
363 _In_ int flags = match_default)
+
364 {
+
365 _Assume_(text || start >= end);
+
366 if (start < end && text[start]) {
+
367 wchar_t buf[3];
+
368 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
+
369 bool r = ((flags & match_case_insensitive) ?
+
370 stdex::strnicmp(chr, (size_t)-1, m_chr.c_str(), m_chr.size(), m_locale) :
+
371 stdex::strncmp(chr, (size_t)-1, m_chr.c_str(), m_chr.size())) == 0;
+
372 if ((r && !m_invert) || (!r && m_invert)) {
+
373 this->interval.start = start;
+
374 return true;
+
375 }
+
376 }
+
377 this->interval.start = (this->interval.end = start) + 1;
+
378 return false;
+
379 }
+
380
+
381 protected:
+
382 std::wstring m_chr;
+
383 bool m_invert;
+
384 };
-
386
-
390 template <class T>
-
-
391 class basic_space_cu : public basic_parser<T>
-
392 {
-
393 public:
-
394 basic_space_cu(bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
395 basic_parser<T>(locale),
-
396 m_invert(invert)
-
397 {}
-
398
-
399 virtual bool match(
-
400 _In_reads_or_z_(end) const T* text,
-
401 _In_ size_t start = 0,
-
402 _In_ size_t end = (size_t)-1,
-
403 _In_ int flags = match_default)
-
404 {
-
405 _Assume_(text || start >= end);
-
406 if (start < end && text[start]) {
-
407 bool r =
-
408 ((flags & match_multiline) || !islbreak(text[start])) &&
-
409 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::space, text[start]);
-
410 if ((r && !m_invert) || (!r && m_invert)) {
-
411 this->interval.end = (this->interval.start = start) + 1;
-
412 return true;
-
413 }
-
414 }
-
415 this->interval.start = (this->interval.end = start) + 1;
-
416 return false;
-
417 }
-
418
-
419 protected:
-
420 bool m_invert;
-
421 };
+
385
+
389 template <class T>
+
+
390 class basic_space_cu : public basic_parser<T>
+
391 {
+
392 public:
+
393 basic_space_cu(bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
394 basic_parser<T>(locale),
+
395 m_invert(invert)
+
396 {}
+
397
+
398 virtual bool match(
+
399 _In_reads_or_z_(end) const T* text,
+
400 _In_ size_t start = 0,
+
401 _In_ size_t end = (size_t)-1,
+
402 _In_ int flags = match_default)
+
403 {
+
404 _Assume_(text || start >= end);
+
405 if (start < end && text[start]) {
+
406 bool r =
+
407 ((flags & match_multiline) || !islbreak(text[start])) &&
+
408 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::space, text[start]);
+
409 if ((r && !m_invert) || (!r && m_invert)) {
+
410 this->interval.end = (this->interval.start = start) + 1;
+
411 return true;
+
412 }
+
413 }
+
414 this->interval.start = (this->interval.end = start) + 1;
+
415 return false;
+
416 }
+
417
+
418 protected:
+
419 bool m_invert;
+
420 };
-
422
- - -
425#ifdef _UNICODE
-
426 using tspace_cu = wspace_cu;
-
427#else
-
428 using tspace_cu = space_cu;
-
429#endif
-
430
-
-
434 class sgml_space_cp : public basic_space_cu<char>
-
435 {
-
436 public:
-
437 sgml_space_cp(_In_ bool invert = false, _In_ const std::locale& locale = std::locale()) :
- -
439 {}
-
440
-
441 virtual bool match(
-
442 _In_reads_or_z_(end) const char* text,
-
443 _In_ size_t start = 0,
-
444 _In_ size_t end = (size_t)-1,
-
445 _In_ int flags = match_default)
-
446 {
-
447 _Assume_(text || start >= end);
-
448 if (start < end && text[start]) {
-
449 wchar_t buf[3];
-
450 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
-
451 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
452 bool r =
-
453 ((flags & match_multiline) || !islbreak(chr, (size_t)-1)) &&
-
454 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space, chr, chr_end) == chr_end;
-
455 if ((r && !m_invert) || (!r && m_invert)) {
-
456 this->interval.start = start;
-
457 return true;
-
458 }
-
459 }
-
460
-
461 this->interval.start = (this->interval.end = start) + 1;
-
462 return false;
-
463 }
-
464 };
+
421
+ + +
424#ifdef _UNICODE
+
425 using tspace_cu = wspace_cu;
+
426#else
+
427 using tspace_cu = space_cu;
+
428#endif
+
429
+
+
433 class sgml_space_cp : public basic_space_cu<char>
+
434 {
+
435 public:
+
436 sgml_space_cp(_In_ bool invert = false, _In_ const std::locale& locale = std::locale()) :
+ +
438 {}
+
439
+
440 virtual bool match(
+
441 _In_reads_or_z_(end) const char* text,
+
442 _In_ size_t start = 0,
+
443 _In_ size_t end = (size_t)-1,
+
444 _In_ int flags = match_default)
+
445 {
+
446 _Assume_(text || start >= end);
+
447 if (start < end && text[start]) {
+
448 wchar_t buf[3];
+
449 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
+
450 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
451 bool r =
+
452 ((flags & match_multiline) || !islbreak(chr, (size_t)-1)) &&
+
453 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space, chr, chr_end) == chr_end;
+
454 if ((r && !m_invert) || (!r && m_invert)) {
+
455 this->interval.start = start;
+
456 return true;
+
457 }
+
458 }
+
459
+
460 this->interval.start = (this->interval.end = start) + 1;
+
461 return false;
+
462 }
+
463 };
-
465
-
469 template <class T>
-
-
470 class basic_punct_cu : public basic_parser<T>
-
471 {
-
472 public:
-
473 basic_punct_cu(bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
474 basic_parser<T>(locale),
-
475 m_invert(invert)
-
476 {}
-
477
-
478 virtual bool match(
-
479 _In_reads_or_z_(end) const T* text,
-
480 _In_ size_t start = 0,
-
481 _In_ size_t end = (size_t)-1,
-
482 _In_ int flags = match_default)
-
483 {
-
484 _Assume_(text || start >= end);
-
485 if (start < end && text[start]) {
-
486 bool r = std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::punct, text[start]);
-
487 if ((r && !m_invert) || (!r && m_invert)) {
-
488 this->interval.end = (this->interval.start = start) + 1;
-
489 return true;
-
490 }
-
491 }
-
492 this->interval.start = (this->interval.end = start) + 1;
-
493 return false;
-
494 }
-
495
-
496 protected:
-
497 bool m_invert;
-
498 };
+
464
+
468 template <class T>
+
+
469 class basic_punct_cu : public basic_parser<T>
+
470 {
+
471 public:
+
472 basic_punct_cu(bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
473 basic_parser<T>(locale),
+
474 m_invert(invert)
+
475 {}
+
476
+
477 virtual bool match(
+
478 _In_reads_or_z_(end) const T* text,
+
479 _In_ size_t start = 0,
+
480 _In_ size_t end = (size_t)-1,
+
481 _In_ int flags = match_default)
+
482 {
+
483 _Assume_(text || start >= end);
+
484 if (start < end && text[start]) {
+
485 bool r = std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::punct, text[start]);
+
486 if ((r && !m_invert) || (!r && m_invert)) {
+
487 this->interval.end = (this->interval.start = start) + 1;
+
488 return true;
+
489 }
+
490 }
+
491 this->interval.start = (this->interval.end = start) + 1;
+
492 return false;
+
493 }
+
494
+
495 protected:
+
496 bool m_invert;
+
497 };
-
499
- - -
502#ifdef _UNICODE
-
503 using tpunct_cu = wpunct_cu;
-
504#else
-
505 using tpunct_cu = punct_cu;
-
506#endif
-
507
-
-
511 class sgml_punct_cp : public basic_punct_cu<char>
-
512 {
-
513 public:
-
514 sgml_punct_cp(bool invert = false, _In_ const std::locale& locale = std::locale()) :
- -
516 {}
-
517
-
518 virtual bool match(
-
519 _In_reads_or_z_(end) const char* text,
-
520 _In_ size_t start = 0,
-
521 _In_ size_t end = (size_t)-1,
-
522 _In_ int flags = match_default)
-
523 {
-
524 _Assume_(text || start >= end);
-
525 if (start < end && text[start]) {
-
526 wchar_t buf[3];
-
527 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
-
528 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
529 bool r = std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::punct, chr, chr_end) == chr_end;
-
530 if ((r && !m_invert) || (!r && m_invert)) {
-
531 this->interval.start = start;
-
532 return true;
-
533 }
-
534 }
-
535 this->interval.start = (this->interval.end = start) + 1;
-
536 return false;
-
537 }
-
538 };
+
498
+ + +
501#ifdef _UNICODE
+
502 using tpunct_cu = wpunct_cu;
+
503#else
+
504 using tpunct_cu = punct_cu;
+
505#endif
+
506
+
+
510 class sgml_punct_cp : public basic_punct_cu<char>
+
511 {
+
512 public:
+
513 sgml_punct_cp(bool invert = false, _In_ const std::locale& locale = std::locale()) :
+ +
515 {}
+
516
+
517 virtual bool match(
+
518 _In_reads_or_z_(end) const char* text,
+
519 _In_ size_t start = 0,
+
520 _In_ size_t end = (size_t)-1,
+
521 _In_ int flags = match_default)
+
522 {
+
523 _Assume_(text || start >= end);
+
524 if (start < end && text[start]) {
+
525 wchar_t buf[3];
+
526 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
+
527 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
528 bool r = std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::punct, chr, chr_end) == chr_end;
+
529 if ((r && !m_invert) || (!r && m_invert)) {
+
530 this->interval.start = start;
+
531 return true;
+
532 }
+
533 }
+
534 this->interval.start = (this->interval.end = start) + 1;
+
535 return false;
+
536 }
+
537 };
-
539
-
543 template <class T>
-
- -
545 {
-
546 public:
-
547 basic_space_or_punct_cu(bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
548 basic_parser<T>(locale),
-
549 m_invert(invert)
-
550 {}
-
551
-
552 virtual bool match(
-
553 _In_reads_or_z_(end) const T* text,
-
554 _In_ size_t start = 0,
-
555 _In_ size_t end = (size_t)-1,
-
556 _In_ int flags = match_default)
-
557 {
-
558 _Assume_(text || start >= end);
-
559 if (start < end && text[start]) {
-
560 bool r =
-
561 ((flags & match_multiline) || !islbreak(text[start])) &&
-
562 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::space | std::ctype_base::punct, text[start]);
-
563 if ((r && !m_invert) || (!r && m_invert)) {
-
564 this->interval.end = (this->interval.start = start) + 1;
-
565 return true;
-
566 }
-
567 }
-
568 this->interval.start = (this->interval.end = start) + 1;
-
569 return false;
-
570 }
-
571
-
572 protected:
-
573 bool m_invert;
-
574 };
+
538
+
542 template <class T>
+
+ +
544 {
+
545 public:
+
546 basic_space_or_punct_cu(bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
547 basic_parser<T>(locale),
+
548 m_invert(invert)
+
549 {}
+
550
+
551 virtual bool match(
+
552 _In_reads_or_z_(end) const T* text,
+
553 _In_ size_t start = 0,
+
554 _In_ size_t end = (size_t)-1,
+
555 _In_ int flags = match_default)
+
556 {
+
557 _Assume_(text || start >= end);
+
558 if (start < end && text[start]) {
+
559 bool r =
+
560 ((flags & match_multiline) || !islbreak(text[start])) &&
+
561 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::space | std::ctype_base::punct, text[start]);
+
562 if ((r && !m_invert) || (!r && m_invert)) {
+
563 this->interval.end = (this->interval.start = start) + 1;
+
564 return true;
+
565 }
+
566 }
+
567 this->interval.start = (this->interval.end = start) + 1;
+
568 return false;
+
569 }
+
570
+
571 protected:
+
572 bool m_invert;
+
573 };
-
575
- - -
578#ifdef _UNICODE
- -
580#else
- -
582#endif
-
583
-
- -
588 {
-
589 public:
-
590 sgml_space_or_punct_cp(bool invert = false, _In_ const std::locale& locale = std::locale()) :
- -
592 {}
-
593
-
594 virtual bool match(
-
595 _In_reads_or_z_(end) const char* text,
-
596 _In_ size_t start = 0,
-
597 _In_ size_t end = (size_t)-1,
-
598 _In_ int flags = match_default)
-
599 {
-
600 _Assume_(text || start >= end);
-
601 if (start < end && text[start]) {
-
602 wchar_t buf[3];
-
603 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
-
604 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
605 bool r =
-
606 ((flags & match_multiline) || !islbreak(chr, (size_t)-1)) &&
-
607 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space | std::ctype_base::punct, chr, chr_end) == chr_end;
-
608 if ((r && !m_invert) || (!r && m_invert)) {
-
609 this->interval.start = start;
-
610 return true;
-
611 }
-
612 }
-
613 this->interval.start = (this->interval.end = start) + 1;
-
614 return false;
-
615 }
-
616 };
+
574
+ + +
577#ifdef _UNICODE
+ +
579#else
+ +
581#endif
+
582
+
+ +
587 {
+
588 public:
+
589 sgml_space_or_punct_cp(bool invert = false, _In_ const std::locale& locale = std::locale()) :
+ +
591 {}
+
592
+
593 virtual bool match(
+
594 _In_reads_or_z_(end) const char* text,
+
595 _In_ size_t start = 0,
+
596 _In_ size_t end = (size_t)-1,
+
597 _In_ int flags = match_default)
+
598 {
+
599 _Assume_(text || start >= end);
+
600 if (start < end && text[start]) {
+
601 wchar_t buf[3];
+
602 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
+
603 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
604 bool r =
+
605 ((flags & match_multiline) || !islbreak(chr, (size_t)-1)) &&
+
606 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::space | std::ctype_base::punct, chr, chr_end) == chr_end;
+
607 if ((r && !m_invert) || (!r && m_invert)) {
+
608 this->interval.start = start;
+
609 return true;
+
610 }
+
611 }
+
612 this->interval.start = (this->interval.end = start) + 1;
+
613 return false;
+
614 }
+
615 };
-
617
-
621 template <class T>
-
-
622 class basic_bol : public basic_parser<T>
-
623 {
-
624 public:
-
625 basic_bol(bool invert = false) : m_invert(invert) {}
-
626
-
627 virtual bool match(
-
628 _In_reads_or_z_(end) const T* text,
-
629 _In_ size_t start = 0,
-
630 _In_ size_t end = (size_t)-1,
-
631 _In_ int flags = match_default)
-
632 {
-
633 _Assume_(text || start >= end);
-
634 bool r = start == 0 || (start <= end && islbreak(text[start - 1]));
-
635 if ((r && !m_invert) || (!r && m_invert)) {
-
636 this->interval.end = this->interval.start = start;
-
637 return true;
-
638 }
-
639 this->interval.start = (this->interval.end = start) + 1;
-
640 return false;
-
641 }
-
642
-
643 protected:
-
644 bool m_invert;
-
645 };
+
616
+
620 template <class T>
+
+
621 class basic_bol : public basic_parser<T>
+
622 {
+
623 public:
+
624 basic_bol(bool invert = false) : m_invert(invert) {}
+
625
+
626 virtual bool match(
+
627 _In_reads_or_z_(end) const T* text,
+
628 _In_ size_t start = 0,
+
629 _In_ size_t end = (size_t)-1,
+
630 _In_ int flags = match_default)
+
631 {
+
632 _Assume_(text || start >= end);
+
633 bool r = start == 0 || (start <= end && islbreak(text[start - 1]));
+
634 if ((r && !m_invert) || (!r && m_invert)) {
+
635 this->interval.end = this->interval.start = start;
+
636 return true;
+
637 }
+
638 this->interval.start = (this->interval.end = start) + 1;
+
639 return false;
+
640 }
+
641
+
642 protected:
+
643 bool m_invert;
+
644 };
-
646
-
647 using bol = basic_bol<char>;
-
648 using wbol = basic_bol<wchar_t>;
-
649#ifdef _UNICODE
-
650 using tbol = wbol;
-
651#else
-
652 using tbol = bol;
-
653#endif
- -
655
-
659 template <class T>
-
-
660 class basic_eol : public basic_parser<T>
-
661 {
-
662 public:
-
663 basic_eol(bool invert = false) : m_invert(invert) {}
-
664
-
665 virtual bool match(
-
666 _In_reads_or_z_(end) const T* text,
-
667 _In_ size_t start = 0,
-
668 _In_ size_t end = (size_t)-1,
-
669 _In_ int flags = match_default)
-
670 {
-
671 _Assume_(text || start >= end);
-
672 bool r = islbreak(text[start]);
-
673 if ((r && !m_invert) || (!r && m_invert)) {
-
674 this->interval.end = this->interval.start = start;
-
675 return true;
-
676 }
-
677 this->interval.start = (this->interval.end = start) + 1;
-
678 return false;
-
679 }
-
680
-
681 protected:
-
682 bool m_invert;
-
683 };
+
645
+
646 using bol = basic_bol<char>;
+
647 using wbol = basic_bol<wchar_t>;
+
648#ifdef _UNICODE
+
649 using tbol = wbol;
+
650#else
+
651 using tbol = bol;
+
652#endif
+ +
654
+
658 template <class T>
+
+
659 class basic_eol : public basic_parser<T>
+
660 {
+
661 public:
+
662 basic_eol(bool invert = false) : m_invert(invert) {}
+
663
+
664 virtual bool match(
+
665 _In_reads_or_z_(end) const T* text,
+
666 _In_ size_t start = 0,
+
667 _In_ size_t end = (size_t)-1,
+
668 _In_ int flags = match_default)
+
669 {
+
670 _Assume_(text || start >= end);
+
671 bool r = islbreak(text[start]);
+
672 if ((r && !m_invert) || (!r && m_invert)) {
+
673 this->interval.end = this->interval.start = start;
+
674 return true;
+
675 }
+
676 this->interval.start = (this->interval.end = start) + 1;
+
677 return false;
+
678 }
+
679
+
680 protected:
+
681 bool m_invert;
+
682 };
-
684
-
685 using eol = basic_eol<char>;
-
686 using weol = basic_eol<wchar_t>;
-
687#ifdef _UNICODE
-
688 using teol = weol;
-
689#else
-
690 using teol = eol;
-
691#endif
- -
693
-
694 template <class T>
-
-
695 class basic_set : public basic_parser<T>
-
696 {
-
697 public:
-
698 basic_set(bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
699 basic_parser<T>(locale),
-
700 hit_offset((size_t)-1),
-
701 m_invert(invert)
-
702 {}
-
703
-
704 virtual bool match(
-
705 _In_reads_or_z_(end) const T* text,
-
706 _In_ size_t start = 0,
-
707 _In_ size_t end = (size_t)-1,
-
708 _In_ int flags = match_default) = 0;
-
709
-
710 virtual void invalidate()
-
711 {
-
712 hit_offset = (size_t)-1;
- -
714 }
-
715
-
716 public:
-
717 size_t hit_offset;
-
718
-
719 protected:
-
720 bool m_invert;
-
721 };
+
683
+
684 using eol = basic_eol<char>;
+
685 using weol = basic_eol<wchar_t>;
+
686#ifdef _UNICODE
+
687 using teol = weol;
+
688#else
+
689 using teol = eol;
+
690#endif
+ +
692
+
693 template <class T>
+
+
694 class basic_set : public basic_parser<T>
+
695 {
+
696 public:
+
697 basic_set(bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
698 basic_parser<T>(locale),
+
699 hit_offset((size_t)-1),
+
700 m_invert(invert)
+
701 {}
+
702
+
703 virtual bool match(
+
704 _In_reads_or_z_(end) const T* text,
+
705 _In_ size_t start = 0,
+
706 _In_ size_t end = (size_t)-1,
+
707 _In_ int flags = match_default) = 0;
+
708
+
709 virtual void invalidate()
+
710 {
+
711 hit_offset = (size_t)-1;
+ +
713 }
+
714
+
715 public:
+
716 size_t hit_offset;
+
717
+
718 protected:
+
719 bool m_invert;
+
720 };
-
722
-
726 template <class T>
-
-
727 class basic_cu_set : public basic_set<T>
-
728 {
-
729 public:
- -
731 _In_reads_or_z_(count) const T* set,
-
732 _In_ size_t count = (size_t)-1,
-
733 _In_ bool invert = false,
-
734 _In_ const std::locale& locale = std::locale()) :
-
735 basic_set<T>(invert, locale)
-
736 {
-
737 if (set)
-
738 m_set.assign(set, set + stdex::strnlen(set, count));
-
739 }
-
740
-
741 virtual bool match(
-
742 _In_reads_or_z_(end) const T* text,
-
743 _In_ size_t start = 0,
-
744 _In_ size_t end = (size_t)-1,
-
745 _In_ int flags = match_default)
-
746 {
-
747 _Assume_(text || start >= end);
-
748 if (start < end && text[start]) {
-
749 const T* set = m_set.c_str();
-
750 size_t r = (flags & match_case_insensitive) ?
-
751 stdex::strnichr(set, m_set.size(), text[start], this->m_locale) :
-
752 stdex::strnchr(set, m_set.size(), text[start]);
-
753 if ((r != stdex::npos && !this->m_invert) || (r == stdex::npos && this->m_invert)) {
-
754 this->hit_offset = r;
-
755 this->interval.end = (this->interval.start = start) + 1;
-
756 return true;
-
757 }
-
758 }
-
759 this->hit_offset = (size_t)-1;
-
760 this->interval.start = (this->interval.end = start) + 1;
-
761 return false;
-
762 }
-
763
-
764 protected:
-
765 std::basic_string<T> m_set;
-
766 };
+
721
+
725 template <class T>
+
+
726 class basic_cu_set : public basic_set<T>
+
727 {
+
728 public:
+ +
730 _In_reads_or_z_(count) const T* set,
+
731 _In_ size_t count = (size_t)-1,
+
732 _In_ bool invert = false,
+
733 _In_ const std::locale& locale = std::locale()) :
+
734 basic_set<T>(invert, locale)
+
735 {
+
736 if (set)
+
737 m_set.assign(set, set + stdex::strnlen(set, count));
+
738 }
+
739
+
740 virtual bool match(
+
741 _In_reads_or_z_(end) const T* text,
+
742 _In_ size_t start = 0,
+
743 _In_ size_t end = (size_t)-1,
+
744 _In_ int flags = match_default)
+
745 {
+
746 _Assume_(text || start >= end);
+
747 if (start < end && text[start]) {
+
748 const T* set = m_set.c_str();
+
749 size_t r = (flags & match_case_insensitive) ?
+
750 stdex::strnichr(set, m_set.size(), text[start], this->m_locale) :
+
751 stdex::strnchr(set, m_set.size(), text[start]);
+
752 if ((r != stdex::npos && !this->m_invert) || (r == stdex::npos && this->m_invert)) {
+
753 this->hit_offset = r;
+
754 this->interval.end = (this->interval.start = start) + 1;
+
755 return true;
+
756 }
+
757 }
+
758 this->hit_offset = (size_t)-1;
+
759 this->interval.start = (this->interval.end = start) + 1;
+
760 return false;
+
761 }
+
762
+
763 protected:
+
764 std::basic_string<T> m_set;
+
765 };
-
767
- - -
770#ifdef _UNICODE
-
771 using tcu_set = wcu_set;
-
772#else
-
773 using tcu_set = cu_set;
-
774#endif
-
775
-
-
779 class sgml_cp_set : public basic_set<char>
-
780 {
-
781 public:
-
782 sgml_cp_set(const char* set, size_t count = (size_t)-1, bool invert = false, _In_ const std::locale& locale = std::locale()) :
-
783 basic_set<char>(invert, locale)
-
784 {
-
785 if (set)
-
786 m_set = sgml2wstr(set, count);
-
787 }
-
788
-
789 virtual bool match(
-
790 _In_reads_or_z_(end) const char* text,
-
791 _In_ size_t start = 0,
-
792 _In_ size_t end = (size_t)-1,
-
793 _In_ int flags = match_default)
-
794 {
-
795 _Assume_(text || start >= end);
-
796 if (start < end && text[start]) {
-
797 wchar_t buf[3];
-
798 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
-
799 const wchar_t* set = m_set.c_str();
-
800 size_t r = (flags & match_case_insensitive) ?
-
801 stdex::strnistr(set, m_set.size(), chr, m_locale) :
-
802 stdex::strnstr(set, m_set.size(), chr);
-
803 if ((r != stdex::npos && !m_invert) || (r == stdex::npos && m_invert)) {
-
804 hit_offset = r;
-
805 this->interval.start = start;
-
806 return true;
-
807 }
-
808 }
-
809 hit_offset = (size_t)-1;
-
810 this->interval.start = (this->interval.end = start) + 1;
-
811 return false;
-
812 }
-
813
-
814 protected:
-
815 std::wstring m_set;
-
816 };
+
766
+ + +
769#ifdef _UNICODE
+
770 using tcu_set = wcu_set;
+
771#else
+
772 using tcu_set = cu_set;
+
773#endif
+
774
+
+
778 class sgml_cp_set : public basic_set<char>
+
779 {
+
780 public:
+
781 sgml_cp_set(const char* set, size_t count = (size_t)-1, bool invert = false, _In_ const std::locale& locale = std::locale()) :
+
782 basic_set<char>(invert, locale)
+
783 {
+
784 if (set)
+
785 m_set = sgml2wstr(set, count);
+
786 }
+
787
+
788 virtual bool match(
+
789 _In_reads_or_z_(end) const char* text,
+
790 _In_ size_t start = 0,
+
791 _In_ size_t end = (size_t)-1,
+
792 _In_ int flags = match_default)
+
793 {
+
794 _Assume_(text || start >= end);
+
795 if (start < end && text[start]) {
+
796 wchar_t buf[3];
+
797 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
+
798 const wchar_t* set = m_set.c_str();
+
799 size_t r = (flags & match_case_insensitive) ?
+
800 stdex::strnistr(set, m_set.size(), chr, m_locale) :
+
801 stdex::strnstr(set, m_set.size(), chr);
+
802 if ((r != stdex::npos && !m_invert) || (r == stdex::npos && m_invert)) {
+
803 hit_offset = r;
+
804 this->interval.start = start;
+
805 return true;
+
806 }
+
807 }
+
808 hit_offset = (size_t)-1;
+
809 this->interval.start = (this->interval.end = start) + 1;
+
810 return false;
+
811 }
+
812
+
813 protected:
+
814 std::wstring m_set;
+
815 };
-
817
-
821 template <class T>
-
-
822 class basic_string : public basic_parser<T>
-
823 {
-
824 public:
- -
826 _In_reads_or_z_(count) const T* str,
-
827 _In_ size_t count = (size_t)-1,
-
828 _In_ const std::locale& locale = std::locale()) :
-
829 basic_parser<T>(locale),
-
830 m_str(str, str + stdex::strnlen(str, count))
-
831 {}
-
832
-
833 virtual bool match(
-
834 _In_reads_or_z_(end) const T* text,
-
835 _In_ size_t start = 0,
-
836 _In_ size_t end = (size_t)-1,
-
837 _In_ int flags = match_default)
-
838 {
-
839 _Assume_(text || start >= end);
-
840 size_t
-
841 m = m_str.size(),
-
842 n = std::min<size_t>(end - start, m);
-
843 bool r = ((flags & match_case_insensitive) ?
-
844 stdex::strnicmp(text + start, n, m_str.c_str(), m, this->m_locale) :
-
845 stdex::strncmp(text + start, n, m_str.c_str(), m)) == 0;
-
846 if (r) {
-
847 this->interval.end = (this->interval.start = start) + n;
-
848 return true;
-
849 }
-
850 this->interval.start = (this->interval.end = start) + 1;
-
851 return false;
-
852 }
-
853
-
854 protected:
-
855 std::basic_string<T> m_str;
-
856 };
+
816
+
820 template <class T>
+
+
821 class basic_string : public basic_parser<T>
+
822 {
+
823 public:
+ +
825 _In_reads_or_z_(count) const T* str,
+
826 _In_ size_t count = (size_t)-1,
+
827 _In_ const std::locale& locale = std::locale()) :
+
828 basic_parser<T>(locale),
+
829 m_str(str, str + stdex::strnlen(str, count))
+
830 {}
+
831
+
832 virtual bool match(
+
833 _In_reads_or_z_(end) const T* text,
+
834 _In_ size_t start = 0,
+
835 _In_ size_t end = (size_t)-1,
+
836 _In_ int flags = match_default)
+
837 {
+
838 _Assume_(text || start >= end);
+
839 size_t
+
840 m = m_str.size(),
+
841 n = std::min<size_t>(end - start, m);
+
842 bool r = ((flags & match_case_insensitive) ?
+
843 stdex::strnicmp(text + start, n, m_str.c_str(), m, this->m_locale) :
+
844 stdex::strncmp(text + start, n, m_str.c_str(), m)) == 0;
+
845 if (r) {
+
846 this->interval.end = (this->interval.start = start) + n;
+
847 return true;
+
848 }
+
849 this->interval.start = (this->interval.end = start) + 1;
+
850 return false;
+
851 }
+
852
+
853 protected:
+
854 std::basic_string<T> m_str;
+
855 };
-
857
- - -
860#ifdef _UNICODE
-
861 using tstring = wstring;
-
862#else
-
863 using tstring = string;
-
864#endif
-
865
-
- -
870 {
-
871 public:
-
872 sgml_string(const char* str, size_t count = (size_t)-1, _In_ const std::locale& locale = std::locale()) :
-
873 sgml_parser(locale),
-
874 m_str(sgml2wstr(str, count))
-
875 {}
-
876
-
877 virtual bool match(
-
878 _In_reads_or_z_(end) const char* text,
-
879 _In_ size_t start = 0,
-
880 _In_ size_t end = (size_t)-1,
-
881 _In_ int flags = match_default)
-
882 {
-
883 _Assume_(text || start >= end);
-
884 const wchar_t* str = m_str.c_str();
-
885 const bool case_insensitive = flags & match_case_insensitive ? true : false;
-
886 const auto& ctype = std::use_facet<std::ctype<wchar_t>>(m_locale);
-
887 for (this->interval.end = start;;) {
-
888 if (!*str) {
-
889 this->interval.start = start;
-
890 return true;
-
891 }
-
892 if (this->interval.end >= end || !text[this->interval.end]) {
-
893 this->interval.start = (this->interval.end = start) + 1;
-
894 return false;
-
895 }
-
896 wchar_t buf[3];
-
897 const wchar_t* chr = next_sgml_cp(text, this->interval.end, end, this->interval.end, buf);
-
898 for (; *chr; ++str, ++chr) {
-
899 if (!*str ||
-
900 (case_insensitive ? ctype.tolower(*str) != ctype.tolower(*chr) : *str != *chr))
-
901 {
-
902 this->interval.start = (this->interval.end = start) + 1;
-
903 return false;
-
904 }
-
905 }
-
906 }
-
907 }
-
908
-
909 protected:
-
910 std::wstring m_str;
-
911 };
+
856
+ + +
859#ifdef _UNICODE
+
860 using tstring = wstring;
+
861#else
+
862 using tstring = string;
+
863#endif
+
864
+
+ +
869 {
+
870 public:
+
871 sgml_string(const char* str, size_t count = (size_t)-1, _In_ const std::locale& locale = std::locale()) :
+
872 sgml_parser(locale),
+
873 m_str(sgml2wstr(str, count))
+
874 {}
+
875
+
876 virtual bool match(
+
877 _In_reads_or_z_(end) const char* text,
+
878 _In_ size_t start = 0,
+
879 _In_ size_t end = (size_t)-1,
+
880 _In_ int flags = match_default)
+
881 {
+
882 _Assume_(text || start >= end);
+
883 const wchar_t* str = m_str.c_str();
+
884 const bool case_insensitive = flags & match_case_insensitive ? true : false;
+
885 const auto& ctype = std::use_facet<std::ctype<wchar_t>>(m_locale);
+
886 for (this->interval.end = start;;) {
+
887 if (!*str) {
+
888 this->interval.start = start;
+
889 return true;
+
890 }
+
891 if (this->interval.end >= end || !text[this->interval.end]) {
+
892 this->interval.start = (this->interval.end = start) + 1;
+
893 return false;
+
894 }
+
895 wchar_t buf[3];
+
896 const wchar_t* chr = next_sgml_cp(text, this->interval.end, end, this->interval.end, buf);
+
897 for (; *chr; ++str, ++chr) {
+
898 if (!*str ||
+
899 (case_insensitive ? ctype.tolower(*str) != ctype.tolower(*chr) : *str != *chr))
+
900 {
+
901 this->interval.start = (this->interval.end = start) + 1;
+
902 return false;
+
903 }
+
904 }
+
905 }
+
906 }
+
907
+
908 protected:
+
909 std::wstring m_str;
+
910 };
-
912
-
916 template <class T>
-
- -
918 {
-
919 public:
-
920 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) :
-
921 m_el(el),
- - - -
925 {}
-
926
-
927 virtual bool match(
-
928 _In_reads_or_z_(end) const T* text,
-
929 _In_ size_t start = 0,
-
930 _In_ size_t end = (size_t)-1,
-
931 _In_ int flags = match_default)
-
932 {
-
933 _Assume_(text || start >= end);
-
934 this->interval.start = this->interval.end = start;
-
935 for (size_t i = 0; ; i++) {
-
936 if ((!m_greedy && i >= m_min_iterations) || i >= m_max_iterations)
-
937 return true;
-
938 if (!m_el->match(text, this->interval.end, end, flags)) {
-
939 if (i >= m_min_iterations)
-
940 return true;
-
941 break;
-
942 }
-
943 if (m_el->interval.end == this->interval.end) {
-
944 // Element did match, but the matching interval was empty. Quit instead of spinning.
-
945 return true;
-
946 }
-
947 this->interval.end = m_el->interval.end;
-
948 }
-
949 this->interval.start = (this->interval.end = start) + 1;
-
950 return false;
-
951 }
-
952
-
953 protected:
-
954 std::shared_ptr<basic_parser<T>> m_el;
- - -
957 bool m_greedy;
-
958 };
+
911
+
915 template <class T>
+
+ +
917 {
+
918 public:
+
919 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) :
+
920 m_el(el),
+ + + +
924 {}
+
925
+
926 virtual bool match(
+
927 _In_reads_or_z_(end) const T* text,
+
928 _In_ size_t start = 0,
+
929 _In_ size_t end = (size_t)-1,
+
930 _In_ int flags = match_default)
+
931 {
+
932 _Assume_(text || start >= end);
+
933 this->interval.start = this->interval.end = start;
+
934 for (size_t i = 0; ; i++) {
+
935 if ((!m_greedy && i >= m_min_iterations) || i >= m_max_iterations)
+
936 return true;
+
937 if (!m_el->match(text, this->interval.end, end, flags)) {
+
938 if (i >= m_min_iterations)
+
939 return true;
+
940 break;
+
941 }
+
942 if (m_el->interval.end == this->interval.end) {
+
943 // Element did match, but the matching interval was empty. Quit instead of spinning.
+
944 return true;
+
945 }
+
946 this->interval.end = m_el->interval.end;
+
947 }
+
948 this->interval.start = (this->interval.end = start) + 1;
+
949 return false;
+
950 }
+
951
+
952 protected:
+
953 std::shared_ptr<basic_parser<T>> m_el;
+ + +
956 bool m_greedy;
+
957 };
-
959
- - -
962#ifdef _UNICODE
-
963 using titerations = witerations;
-
964#else
-
965 using titerations = iterations;
-
966#endif
- -
968
-
972 template <class T>
-
- -
974 {
-
975 protected:
-
976 parser_collection(_In_ const std::locale& locale) : basic_parser<T>(locale) {}
-
977
-
978 public:
- -
980 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el,
-
981 _In_ size_t count,
-
982 _In_ const std::locale& locale = std::locale()) :
-
983 basic_parser<T>(locale)
-
984 {
-
985 _Assume_(el || !count);
-
986 m_collection.reserve(count);
-
987 for (size_t i = 0; i < count; i++)
-
988 m_collection.push_back(el[i]);
-
989 }
-
990
- -
992 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
-
993 _In_ const std::locale& locale = std::locale()) :
-
994 basic_parser<T>(locale),
-
995 m_collection(std::move(collection))
-
996 {}
-
997
-
998 virtual void invalidate()
-
999 {
-
1000 for (auto& el: m_collection)
-
1001 el->invalidate();
- -
1003 }
-
1004
-
1005 protected:
-
1006 std::vector<std::shared_ptr<basic_parser<T>>> m_collection;
-
1007 };
+
958
+ + +
961#ifdef _UNICODE
+
962 using titerations = witerations;
+
963#else
+
964 using titerations = iterations;
+
965#endif
+ +
967
+
971 template <class T>
+
+ +
973 {
+
974 protected:
+
975 parser_collection(_In_ const std::locale& locale) : basic_parser<T>(locale) {}
+
976
+
977 public:
+ +
979 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el,
+
980 _In_ size_t count,
+
981 _In_ const std::locale& locale = std::locale()) :
+
982 basic_parser<T>(locale)
+
983 {
+
984 _Assume_(el || !count);
+
985 m_collection.reserve(count);
+
986 for (size_t i = 0; i < count; i++)
+
987 m_collection.push_back(el[i]);
+
988 }
+
989
+ +
991 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
+
992 _In_ const std::locale& locale = std::locale()) :
+
993 basic_parser<T>(locale),
+
994 m_collection(std::move(collection))
+
995 {}
+
996
+
997 virtual void invalidate()
+
998 {
+
999 for (auto& el: m_collection)
+
1000 el->invalidate();
+ +
1002 }
+
1003
+
1004 protected:
+
1005 std::vector<std::shared_ptr<basic_parser<T>>> m_collection;
+
1006 };
-
1008
-
1012 template <class T>
-
- -
1014 {
-
1015 public:
- -
1017 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el = nullptr,
-
1018 _In_ size_t count = 0,
-
1019 _In_ const std::locale& locale = std::locale()) :
-
1020 parser_collection<T>(el, count, locale)
-
1021 {}
-
1022
- -
1024 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
-
1025 _In_ const std::locale& locale = std::locale()) :
-
1026 parser_collection<T>(std::move(collection), locale)
-
1027 {}
-
1028
-
1029 virtual bool match(
-
1030 _In_reads_or_z_(end) const T* text,
-
1031 _In_ size_t start = 0,
-
1032 _In_ size_t end = (size_t)-1,
-
1033 _In_ int flags = match_default)
-
1034 {
-
1035 _Assume_(text || start >= end);
-
1036 this->interval.end = start;
-
1037 for (auto i = this->m_collection.begin(); i != this->m_collection.end(); ++i) {
-
1038 if (!(*i)->match(text, this->interval.end, end, flags)) {
-
1039 for (++i; i != this->m_collection.end(); ++i)
-
1040 (*i)->invalidate();
-
1041 this->interval.start = (this->interval.end = start) + 1;
-
1042 return false;
-
1043 }
-
1044 this->interval.end = (*i)->interval.end;
-
1045 }
-
1046 this->interval.start = start;
-
1047 return true;
-
1048 }
-
1049 };
+
1007
+
1011 template <class T>
+
+ +
1013 {
+
1014 public:
+ +
1016 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el = nullptr,
+
1017 _In_ size_t count = 0,
+
1018 _In_ const std::locale& locale = std::locale()) :
+
1019 parser_collection<T>(el, count, locale)
+
1020 {}
+
1021
+ +
1023 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
+
1024 _In_ const std::locale& locale = std::locale()) :
+
1025 parser_collection<T>(std::move(collection), locale)
+
1026 {}
+
1027
+
1028 virtual bool match(
+
1029 _In_reads_or_z_(end) const T* text,
+
1030 _In_ size_t start = 0,
+
1031 _In_ size_t end = (size_t)-1,
+
1032 _In_ int flags = match_default)
+
1033 {
+
1034 _Assume_(text || start >= end);
+
1035 this->interval.end = start;
+
1036 for (auto i = this->m_collection.begin(); i != this->m_collection.end(); ++i) {
+
1037 if (!(*i)->match(text, this->interval.end, end, flags)) {
+
1038 for (++i; i != this->m_collection.end(); ++i)
+
1039 (*i)->invalidate();
+
1040 this->interval.start = (this->interval.end = start) + 1;
+
1041 return false;
+
1042 }
+
1043 this->interval.end = (*i)->interval.end;
+
1044 }
+
1045 this->interval.start = start;
+
1046 return true;
+
1047 }
+
1048 };
-
1050
- - -
1053#ifdef _UNICODE
-
1054 using tsequence = wsequence;
-
1055#else
-
1056 using tsequence = sequence;
-
1057#endif
- -
1059
-
1063 template <class T>
-
- -
1065 {
-
1066 protected:
-
1067 basic_branch(_In_ const std::locale& locale) :
-
1068 parser_collection<T>(locale),
-
1069 hit_offset((size_t)-1)
-
1070 {}
-
1071
-
1072 public:
- -
1074 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el = nullptr,
-
1075 _In_ size_t count = 0,
-
1076 _In_ const std::locale& locale = std::locale()) :
-
1077 parser_collection<T>(el, count, locale),
-
1078 hit_offset((size_t)-1)
-
1079 {}
-
1080
- -
1082 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
-
1083 _In_ const std::locale& locale = std::locale()) :
-
1084 parser_collection<T>(std::move(collection), locale),
-
1085 hit_offset((size_t)-1)
-
1086 {}
-
1087
-
1088 virtual bool match(
-
1089 _In_reads_or_z_(end) const T* text,
-
1090 _In_ size_t start = 0,
-
1091 _In_ size_t end = (size_t)-1,
-
1092 _In_ int flags = match_default)
-
1093 {
-
1094 _Assume_(text || start >= end);
-
1095 hit_offset = 0;
-
1096 for (auto i = this->m_collection.begin(); i != this->m_collection.end(); ++i, ++hit_offset) {
-
1097 if ((*i)->match(text, start, end, flags)) {
-
1098 this->interval = (*i)->interval;
-
1099 for (++i; i != this->m_collection.end(); ++i)
-
1100 (*i)->invalidate();
-
1101 return true;
-
1102 }
-
1103 }
-
1104 hit_offset = (size_t)-1;
-
1105 this->interval.start = (this->interval.end = start) + 1;
-
1106 return false;
-
1107 }
-
1108
-
1109 virtual void invalidate()
-
1110 {
-
1111 hit_offset = (size_t)-1;
- -
1113 }
-
1114
-
1115 public:
-
1116 size_t hit_offset;
-
1117 };
+
1049
+ + +
1052#ifdef _UNICODE
+
1053 using tsequence = wsequence;
+
1054#else
+
1055 using tsequence = sequence;
+
1056#endif
+ +
1058
+
1062 template <class T>
+
+ +
1064 {
+
1065 protected:
+
1066 basic_branch(_In_ const std::locale& locale) :
+
1067 parser_collection<T>(locale),
+
1068 hit_offset((size_t)-1)
+
1069 {}
+
1070
+
1071 public:
+ +
1073 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el = nullptr,
+
1074 _In_ size_t count = 0,
+
1075 _In_ const std::locale& locale = std::locale()) :
+
1076 parser_collection<T>(el, count, locale),
+
1077 hit_offset((size_t)-1)
+
1078 {}
+
1079
+ +
1081 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
+
1082 _In_ const std::locale& locale = std::locale()) :
+
1083 parser_collection<T>(std::move(collection), locale),
+
1084 hit_offset((size_t)-1)
+
1085 {}
+
1086
+
1087 virtual bool match(
+
1088 _In_reads_or_z_(end) const T* text,
+
1089 _In_ size_t start = 0,
+
1090 _In_ size_t end = (size_t)-1,
+
1091 _In_ int flags = match_default)
+
1092 {
+
1093 _Assume_(text || start >= end);
+
1094 hit_offset = 0;
+
1095 for (auto i = this->m_collection.begin(); i != this->m_collection.end(); ++i, ++hit_offset) {
+
1096 if ((*i)->match(text, start, end, flags)) {
+
1097 this->interval = (*i)->interval;
+
1098 for (++i; i != this->m_collection.end(); ++i)
+
1099 (*i)->invalidate();
+
1100 return true;
+
1101 }
+
1102 }
+
1103 hit_offset = (size_t)-1;
+
1104 this->interval.start = (this->interval.end = start) + 1;
+
1105 return false;
+
1106 }
+
1107
+
1108 virtual void invalidate()
+
1109 {
+
1110 hit_offset = (size_t)-1;
+ +
1112 }
+
1113
+
1114 public:
+
1115 size_t hit_offset;
+
1116 };
-
1118
-
1119 using branch = basic_branch<char>;
- -
1121#ifdef _UNICODE
-
1122 using tbranch = wbranch;
-
1123#else
-
1124 using tbranch = branch;
-
1125#endif
- -
1127
-
1131 template <class T, class T_parser = basic_string<T>>
-
- -
1133 {
-
1134 public:
-
1135 inline basic_string_branch(
-
1136 _In_reads_(count) const T* str_z = nullptr,
-
1137 _In_ size_t count = 0,
-
1138 _In_ const std::locale& locale = std::locale()) :
-
1139 basic_branch<T>(locale)
-
1140 {
-
1141 build(str_z, count);
-
1142 }
-
1143
-
1144 inline basic_string_branch(_In_z_ const T* str, ...) :
-
1145 basic_branch<T>(std::locale())
-
1146 {
-
1147 va_list params;
-
1148 va_start(params, str);
-
1149 build(str, params);
-
1150 va_end(params);
-
1151 }
-
1152
-
1153 inline basic_string_branch(_In_ const std::locale& locale, _In_z_ const T* str, ...) :
-
1154 basic_branch<T>(locale)
-
1155 {
-
1156 va_list params;
-
1157 va_start(params, str);
-
1158 build(str, params);
-
1159 va_end(params);
-
1160 }
-
1161
-
1162 protected:
-
1163 void build(_In_reads_(count) const T* str_z, _In_ size_t count)
-
1164 {
-
1165 _Assume_(str_z || !count);
-
1166 if (count) {
-
1167 size_t offset, n;
-
1168 for (
-
1169 offset = n = 0;
-
1170 offset < count && str_z[offset];
-
1171 offset += stdex::strnlen(str_z + offset, count - offset) + 1, ++n);
-
1172 this->m_collection.reserve(n);
-
1173 for (
-
1174 offset = 0;
-
1175 offset < count && str_z[offset];
-
1176 offset += stdex::strnlen(str_z + offset, count - offset) + 1)
-
1177 this->m_collection.push_back(std::move(std::make_shared<T_parser>(str_z + offset, count - offset, this->m_locale)));
-
1178 }
-
1179 }
-
1180
-
1181 void build(_In_z_ const T* str, _In_ va_list params)
-
1182 {
-
1183 const T* p;
-
1184 for (
-
1185 this->m_collection.push_back(std::move(std::make_shared<T_parser>(str, (size_t)-1, this->m_locale)));
-
1186 (p = va_arg(params, const T*)) != nullptr;
-
1187 this->m_collection.push_back(std::move(std::make_shared<T_parser>(p, (size_t)-1, this->m_locale))));
-
1188 }
-
1189 };
+
1117
+
1118 using branch = basic_branch<char>;
+ +
1120#ifdef _UNICODE
+
1121 using tbranch = wbranch;
+
1122#else
+
1123 using tbranch = branch;
+
1124#endif
+ +
1126
+
1130 template <class T, class T_parser = basic_string<T>>
+
+ +
1132 {
+
1133 public:
+
1134 inline basic_string_branch(
+
1135 _In_reads_(count) const T* str_z = nullptr,
+
1136 _In_ size_t count = 0,
+
1137 _In_ const std::locale& locale = std::locale()) :
+
1138 basic_branch<T>(locale)
+
1139 {
+
1140 build(str_z, count);
+
1141 }
+
1142
+
1143 inline basic_string_branch(_In_z_ const T* str, ...) :
+
1144 basic_branch<T>(std::locale())
+
1145 {
+
1146 va_list params;
+
1147 va_start(params, str);
+
1148 build(str, params);
+
1149 va_end(params);
+
1150 }
+
1151
+
1152 inline basic_string_branch(_In_ const std::locale& locale, _In_z_ const T* str, ...) :
+
1153 basic_branch<T>(locale)
+
1154 {
+
1155 va_list params;
+
1156 va_start(params, str);
+
1157 build(str, params);
+
1158 va_end(params);
+
1159 }
+
1160
+
1161 protected:
+
1162 void build(_In_reads_(count) const T* str_z, _In_ size_t count)
+
1163 {
+
1164 _Assume_(str_z || !count);
+
1165 if (count) {
+
1166 size_t offset, n;
+
1167 for (
+
1168 offset = n = 0;
+
1169 offset < count && str_z[offset];
+
1170 offset += stdex::strnlen(str_z + offset, count - offset) + 1, ++n);
+
1171 this->m_collection.reserve(n);
+
1172 for (
+
1173 offset = 0;
+
1174 offset < count && str_z[offset];
+
1175 offset += stdex::strnlen(str_z + offset, count - offset) + 1)
+
1176 this->m_collection.push_back(std::move(std::make_shared<T_parser>(str_z + offset, count - offset, this->m_locale)));
+
1177 }
+
1178 }
+
1179
+
1180 void build(_In_z_ const T* str, _In_ va_list params)
+
1181 {
+
1182 const T* p;
+
1183 for (
+
1184 this->m_collection.push_back(std::move(std::make_shared<T_parser>(str, (size_t)-1, this->m_locale)));
+
1185 (p = va_arg(params, const T*)) != nullptr;
+
1186 this->m_collection.push_back(std::move(std::make_shared<T_parser>(p, (size_t)-1, this->m_locale))));
+
1187 }
+
1188 };
-
1190
- - -
1193#ifdef _UNICODE
- -
1195#else
- -
1197#endif
- -
1199
-
1203 template <class T>
-
- -
1205 {
-
1206 public:
- -
1208 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el = nullptr,
-
1209 _In_ size_t count = 0,
-
1210 _In_ const std::locale& locale = std::locale()) :
-
1211 parser_collection<T>(el, count, locale)
-
1212 {}
-
1213
- -
1215 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
-
1216 _In_ const std::locale& locale = std::locale()) :
-
1217 parser_collection<T>(std::move(collection), locale)
-
1218 {}
-
1219
-
1220 virtual bool match(
-
1221 _In_reads_or_z_(end) const T* text,
-
1222 _In_ size_t start = 0,
-
1223 _In_ size_t end = (size_t)-1,
-
1224 _In_ int flags = match_default)
-
1225 {
-
1226 _Assume_(text || start >= end);
-
1227 for (auto& el: this->m_collection)
-
1228 el->invalidate();
-
1229 if (match_recursively(text, start, end, flags)) {
-
1230 this->interval.start = start;
-
1231 return true;
-
1232 }
-
1233 this->interval.start = (this->interval.end = start) + 1;
-
1234 return false;
-
1235 }
-
1236
-
1237 protected:
-
1238 bool match_recursively(
-
1239 _In_reads_or_z_(end) const T* text,
-
1240 _In_ size_t start = 0,
-
1241 _In_ size_t end = (size_t)-1,
-
1242 _In_ int flags = match_default)
-
1243 {
-
1244 bool all_matched = true;
-
1245 for (auto& el: this->m_collection) {
-
1246 if (!el->interval) {
-
1247 // Element was not matched in permutatuion yet.
-
1248 all_matched = false;
-
1249 if (el->match(text, start, end, flags)) {
-
1250 // Element matched for the first time.
-
1251 if (match_recursively(text, el->interval.end, end, flags)) {
-
1252 // Rest of the elements matched too.
-
1253 return true;
-
1254 }
-
1255 el->invalidate();
-
1256 }
-
1257 }
-
1258 }
-
1259 if (all_matched) {
-
1260 this->interval.end = start;
-
1261 return true;
-
1262 }
-
1263 return false;
-
1264 }
-
1265 };
+
1189
+ + +
1192#ifdef _UNICODE
+ +
1194#else
+ +
1196#endif
+ +
1198
+
1202 template <class T>
+
+ +
1204 {
+
1205 public:
+ +
1207 _In_count_(count) const std::shared_ptr<basic_parser<T>>* el = nullptr,
+
1208 _In_ size_t count = 0,
+
1209 _In_ const std::locale& locale = std::locale()) :
+
1210 parser_collection<T>(el, count, locale)
+
1211 {}
+
1212
+ +
1214 _Inout_ std::vector<std::shared_ptr<basic_parser<T>>>&& collection,
+
1215 _In_ const std::locale& locale = std::locale()) :
+
1216 parser_collection<T>(std::move(collection), locale)
+
1217 {}
+
1218
+
1219 virtual bool match(
+
1220 _In_reads_or_z_(end) const T* text,
+
1221 _In_ size_t start = 0,
+
1222 _In_ size_t end = (size_t)-1,
+
1223 _In_ int flags = match_default)
+
1224 {
+
1225 _Assume_(text || start >= end);
+
1226 for (auto& el: this->m_collection)
+
1227 el->invalidate();
+
1228 if (match_recursively(text, start, end, flags)) {
+
1229 this->interval.start = start;
+
1230 return true;
+
1231 }
+
1232 this->interval.start = (this->interval.end = start) + 1;
+
1233 return false;
+
1234 }
+
1235
+
1236 protected:
+
1237 bool match_recursively(
+
1238 _In_reads_or_z_(end) const T* text,
+
1239 _In_ size_t start = 0,
+
1240 _In_ size_t end = (size_t)-1,
+
1241 _In_ int flags = match_default)
+
1242 {
+
1243 bool all_matched = true;
+
1244 for (auto& el: this->m_collection) {
+
1245 if (!el->interval) {
+
1246 // Element was not matched in permutatuion yet.
+
1247 all_matched = false;
+
1248 if (el->match(text, start, end, flags)) {
+
1249 // Element matched for the first time.
+
1250 if (match_recursively(text, el->interval.end, end, flags)) {
+
1251 // Rest of the elements matched too.
+
1252 return true;
+
1253 }
+
1254 el->invalidate();
+
1255 }
+
1256 }
+
1257 }
+
1258 if (all_matched) {
+
1259 this->interval.end = start;
+
1260 return true;
+
1261 }
+
1262 return false;
+
1263 }
+
1264 };
-
1266
- - -
1269#ifdef _UNICODE
-
1270 using tpermutation = wpermutation;
-
1271#else
-
1272 using tpermutation = permutation;
-
1273#endif
- -
1275
-
1279 template <class T>
-
-
1280 class basic_integer : public basic_parser<T>
-
1281 {
-
1282 public:
-
1283 basic_integer(_In_ const std::locale& locale = std::locale()) :
-
1284 basic_parser<T>(locale),
-
1285 value(0)
-
1286 {}
-
1287
-
1288 virtual void invalidate()
-
1289 {
-
1290 value = 0;
- -
1292 }
-
1293
-
1294 public:
-
1295 size_t value;
-
1296 };
+
1265
+ + +
1268#ifdef _UNICODE
+
1269 using tpermutation = wpermutation;
+
1270#else
+
1271 using tpermutation = permutation;
+
1272#endif
+ +
1274
+
1278 template <class T>
+
+
1279 class basic_integer : public basic_parser<T>
+
1280 {
+
1281 public:
+
1282 basic_integer(_In_ const std::locale& locale = std::locale()) :
+
1283 basic_parser<T>(locale),
+
1284 value(0)
+
1285 {}
+
1286
+
1287 virtual void invalidate()
+
1288 {
+
1289 value = 0;
+ +
1291 }
+
1292
+
1293 public:
+
1294 size_t value;
+
1295 };
-
1297
-
1301 template <class T>
-
- -
1303 {
-
1304 public:
- -
1306 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
-
1307 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
-
1308 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
-
1309 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
-
1310 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
-
1311 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
-
1312 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
-
1313 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
-
1314 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
-
1315 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
-
1316 _In_ const std::locale& locale = std::locale()) :
-
1317 basic_integer<T>(locale),
-
1318 m_digit_0(digit_0),
-
1319 m_digit_1(digit_1),
-
1320 m_digit_2(digit_2),
-
1321 m_digit_3(digit_3),
-
1322 m_digit_4(digit_4),
-
1323 m_digit_5(digit_5),
-
1324 m_digit_6(digit_6),
-
1325 m_digit_7(digit_7),
-
1326 m_digit_8(digit_8),
-
1327 m_digit_9(digit_9)
-
1328 {}
-
1329
-
1330 virtual bool match(
-
1331 _In_reads_or_z_(end) const T* text,
-
1332 _In_ size_t start = 0,
-
1333 _In_ size_t end = (size_t)-1,
-
1334 _In_ int flags = match_default)
-
1335 {
-
1336 _Assume_(text || start >= end);
-
1337 for (this->interval.end = start, this->value = 0; this->interval.end < end && text[this->interval.end];) {
-
1338 size_t dig;
-
1339 if (m_digit_0->match(text, this->interval.end, end, flags)) { dig = 0; this->interval.end = m_digit_0->interval.end; }
-
1340 else if (m_digit_1->match(text, this->interval.end, end, flags)) { dig = 1; this->interval.end = m_digit_1->interval.end; }
-
1341 else if (m_digit_2->match(text, this->interval.end, end, flags)) { dig = 2; this->interval.end = m_digit_2->interval.end; }
-
1342 else if (m_digit_3->match(text, this->interval.end, end, flags)) { dig = 3; this->interval.end = m_digit_3->interval.end; }
-
1343 else if (m_digit_4->match(text, this->interval.end, end, flags)) { dig = 4; this->interval.end = m_digit_4->interval.end; }
-
1344 else if (m_digit_5->match(text, this->interval.end, end, flags)) { dig = 5; this->interval.end = m_digit_5->interval.end; }
-
1345 else if (m_digit_6->match(text, this->interval.end, end, flags)) { dig = 6; this->interval.end = m_digit_6->interval.end; }
-
1346 else if (m_digit_7->match(text, this->interval.end, end, flags)) { dig = 7; this->interval.end = m_digit_7->interval.end; }
-
1347 else if (m_digit_8->match(text, this->interval.end, end, flags)) { dig = 8; this->interval.end = m_digit_8->interval.end; }
-
1348 else if (m_digit_9->match(text, this->interval.end, end, flags)) { dig = 9; this->interval.end = m_digit_9->interval.end; }
-
1349 else break;
-
1350 this->value = this->value * 10 + dig;
-
1351 }
- -
1353 this->interval.start = start;
-
1354 return true;
-
1355 }
-
1356 this->interval.start = (this->interval.end = start) + 1;
-
1357 return false;
-
1358 }
-
1359
-
1360 protected:
-
1361 std::shared_ptr<basic_parser<T>>
-
1362 m_digit_0,
-
1363 m_digit_1,
-
1364 m_digit_2,
-
1365 m_digit_3,
-
1366 m_digit_4,
-
1367 m_digit_5,
-
1368 m_digit_6,
-
1369 m_digit_7,
-
1370 m_digit_8,
-
1371 m_digit_9;
-
1372 };
+
1296
+
1300 template <class T>
+
+ +
1302 {
+
1303 public:
+ +
1305 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
+
1306 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
+
1307 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
+
1308 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
+
1309 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
+
1310 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
+
1311 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
+
1312 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
+
1313 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
+
1314 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
+
1315 _In_ const std::locale& locale = std::locale()) :
+
1316 basic_integer<T>(locale),
+
1317 m_digit_0(digit_0),
+
1318 m_digit_1(digit_1),
+
1319 m_digit_2(digit_2),
+
1320 m_digit_3(digit_3),
+
1321 m_digit_4(digit_4),
+
1322 m_digit_5(digit_5),
+
1323 m_digit_6(digit_6),
+
1324 m_digit_7(digit_7),
+
1325 m_digit_8(digit_8),
+
1326 m_digit_9(digit_9)
+
1327 {}
+
1328
+
1329 virtual bool match(
+
1330 _In_reads_or_z_(end) const T* text,
+
1331 _In_ size_t start = 0,
+
1332 _In_ size_t end = (size_t)-1,
+
1333 _In_ int flags = match_default)
+
1334 {
+
1335 _Assume_(text || start >= end);
+
1336 for (this->interval.end = start, this->value = 0; this->interval.end < end && text[this->interval.end];) {
+
1337 size_t dig;
+
1338 if (m_digit_0->match(text, this->interval.end, end, flags)) { dig = 0; this->interval.end = m_digit_0->interval.end; }
+
1339 else if (m_digit_1->match(text, this->interval.end, end, flags)) { dig = 1; this->interval.end = m_digit_1->interval.end; }
+
1340 else if (m_digit_2->match(text, this->interval.end, end, flags)) { dig = 2; this->interval.end = m_digit_2->interval.end; }
+
1341 else if (m_digit_3->match(text, this->interval.end, end, flags)) { dig = 3; this->interval.end = m_digit_3->interval.end; }
+
1342 else if (m_digit_4->match(text, this->interval.end, end, flags)) { dig = 4; this->interval.end = m_digit_4->interval.end; }
+
1343 else if (m_digit_5->match(text, this->interval.end, end, flags)) { dig = 5; this->interval.end = m_digit_5->interval.end; }
+
1344 else if (m_digit_6->match(text, this->interval.end, end, flags)) { dig = 6; this->interval.end = m_digit_6->interval.end; }
+
1345 else if (m_digit_7->match(text, this->interval.end, end, flags)) { dig = 7; this->interval.end = m_digit_7->interval.end; }
+
1346 else if (m_digit_8->match(text, this->interval.end, end, flags)) { dig = 8; this->interval.end = m_digit_8->interval.end; }
+
1347 else if (m_digit_9->match(text, this->interval.end, end, flags)) { dig = 9; this->interval.end = m_digit_9->interval.end; }
+
1348 else break;
+
1349 this->value = this->value * 10 + dig;
+
1350 }
+ +
1352 this->interval.start = start;
+
1353 return true;
+
1354 }
+
1355 this->interval.start = (this->interval.end = start) + 1;
+
1356 return false;
+
1357 }
+
1358
+
1359 protected:
+
1360 std::shared_ptr<basic_parser<T>>
+
1361 m_digit_0,
+
1362 m_digit_1,
+
1363 m_digit_2,
+
1364 m_digit_3,
+
1365 m_digit_4,
+
1366 m_digit_5,
+
1367 m_digit_6,
+
1368 m_digit_7,
+
1369 m_digit_8,
+
1370 m_digit_9;
+
1371 };
-
1373
- - -
1376#ifdef _UNICODE
-
1377 using tinteger10 = winteger10;
-
1378#else
-
1379 using tinteger10 = integer10;
-
1380#endif
- -
1382
-
1386 template <class T>
-
- -
1388 {
-
1389 public:
- -
1391 _In_ const std::shared_ptr<basic_integer10<T>>& digits,
-
1392 _In_ const std::shared_ptr<basic_set<T>>& separator,
-
1393 _In_ const std::locale& locale = std::locale()) :
-
1394 basic_integer<T>(locale),
-
1395 digit_count(0),
-
1396 has_separators(false),
-
1397 m_digits(digits),
-
1398 m_separator(separator)
-
1399 {}
-
1400
-
1401 virtual bool match(
-
1402 _In_reads_or_z_(end) const T* text,
-
1403 _In_ size_t start = 0,
-
1404 _In_ size_t end = (size_t)-1,
-
1405 _In_ int flags = match_default)
-
1406 {
-
1407 _Assume_(text || start >= end);
-
1408 if (m_digits->match(text, start, end, flags)) {
-
1409 // Leading part match.
-
1410 this->value = m_digits->value;
-
1411 digit_count = m_digits->interval.size();
-
1412 has_separators = false;
-
1413 this->interval.start = start;
-
1414 this->interval.end = m_digits->interval.end;
-
1415 if (m_digits->interval.size() <= 3) {
-
1416 // Maybe separated with thousand separators?
-
1417 size_t hit_offset = (size_t)-1;
-
1418 while (m_separator->match(text, this->interval.end, end, flags) &&
-
1419 (hit_offset == (size_t)-1 || hit_offset == m_separator->hit_offset) && // All separators must be the same, no mixing.
-
1420 m_digits->match(text, m_separator->interval.end, end, flags) &&
-
1421 m_digits->interval.size() == 3)
-
1422 {
-
1423 // Thousand separator and three-digit integer followed.
-
1424 this->value = this->value * 1000 + m_digits->value;
-
1425 digit_count += 3;
-
1426 has_separators = true;
-
1427 this->interval.end = m_digits->interval.end;
-
1428 hit_offset = m_separator->hit_offset;
-
1429 }
-
1430 }
-
1431
-
1432 return true;
-
1433 }
-
1434 this->value = 0;
-
1435 this->interval.start = (this->interval.end = start) + 1;
-
1436 return false;
-
1437 }
-
1438
-
1439 virtual void invalidate()
-
1440 {
-
1441 digit_count = 0;
-
1442 has_separators = false;
- -
1444 }
-
1445
-
1446 public:
- - -
1449
-
1450 protected:
-
1451 std::shared_ptr<basic_integer10<T>> m_digits;
-
1452 std::shared_ptr<basic_set<T>> m_separator;
-
1453 };
+
1372
+ + +
1375#ifdef _UNICODE
+
1376 using tinteger10 = winteger10;
+
1377#else
+
1378 using tinteger10 = integer10;
+
1379#endif
+ +
1381
+
1385 template <class T>
+
+ +
1387 {
+
1388 public:
+ +
1390 _In_ const std::shared_ptr<basic_integer10<T>>& digits,
+
1391 _In_ const std::shared_ptr<basic_set<T>>& separator,
+
1392 _In_ const std::locale& locale = std::locale()) :
+
1393 basic_integer<T>(locale),
+
1394 digit_count(0),
+
1395 has_separators(false),
+
1396 m_digits(digits),
+
1397 m_separator(separator)
+
1398 {}
+
1399
+
1400 virtual bool match(
+
1401 _In_reads_or_z_(end) const T* text,
+
1402 _In_ size_t start = 0,
+
1403 _In_ size_t end = (size_t)-1,
+
1404 _In_ int flags = match_default)
+
1405 {
+
1406 _Assume_(text || start >= end);
+
1407 if (m_digits->match(text, start, end, flags)) {
+
1408 // Leading part match.
+
1409 this->value = m_digits->value;
+
1410 digit_count = m_digits->interval.size();
+
1411 has_separators = false;
+
1412 this->interval.start = start;
+
1413 this->interval.end = m_digits->interval.end;
+
1414 if (m_digits->interval.size() <= 3) {
+
1415 // Maybe separated with thousand separators?
+
1416 size_t hit_offset = (size_t)-1;
+
1417 while (m_separator->match(text, this->interval.end, end, flags) &&
+
1418 (hit_offset == (size_t)-1 || hit_offset == m_separator->hit_offset) && // All separators must be the same, no mixing.
+
1419 m_digits->match(text, m_separator->interval.end, end, flags) &&
+
1420 m_digits->interval.size() == 3)
+
1421 {
+
1422 // Thousand separator and three-digit integer followed.
+
1423 this->value = this->value * 1000 + m_digits->value;
+
1424 digit_count += 3;
+
1425 has_separators = true;
+
1426 this->interval.end = m_digits->interval.end;
+
1427 hit_offset = m_separator->hit_offset;
+
1428 }
+
1429 }
+
1430
+
1431 return true;
+
1432 }
+
1433 this->value = 0;
+
1434 this->interval.start = (this->interval.end = start) + 1;
+
1435 return false;
+
1436 }
+
1437
+
1438 virtual void invalidate()
+
1439 {
+
1440 digit_count = 0;
+
1441 has_separators = false;
+ +
1443 }
+
1444
+
1445 public:
+ + +
1448
+
1449 protected:
+
1450 std::shared_ptr<basic_integer10<T>> m_digits;
+
1451 std::shared_ptr<basic_set<T>> m_separator;
+
1452 };
-
1454
- - -
1457#ifdef _UNICODE
-
1458 using tinteger10ts = winteger10ts;
-
1459#else
-
1460 using tinteger10ts = integer10ts;
-
1461#endif
- -
1463
-
1467 template <class T>
-
- -
1469 {
-
1470 public:
- -
1472 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
-
1473 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
-
1474 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
-
1475 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
-
1476 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
-
1477 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
-
1478 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
-
1479 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
-
1480 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
-
1481 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
-
1482 _In_ const std::shared_ptr<basic_parser<T>>& digit_10,
-
1483 _In_ const std::shared_ptr<basic_parser<T>>& digit_11,
-
1484 _In_ const std::shared_ptr<basic_parser<T>>& digit_12,
-
1485 _In_ const std::shared_ptr<basic_parser<T>>& digit_13,
-
1486 _In_ const std::shared_ptr<basic_parser<T>>& digit_14,
-
1487 _In_ const std::shared_ptr<basic_parser<T>>& digit_15,
-
1488 _In_ const std::locale& locale = std::locale()) :
-
1489 basic_integer<T>(locale),
-
1490 m_digit_0(digit_0),
-
1491 m_digit_1(digit_1),
-
1492 m_digit_2(digit_2),
-
1493 m_digit_3(digit_3),
-
1494 m_digit_4(digit_4),
-
1495 m_digit_5(digit_5),
-
1496 m_digit_6(digit_6),
-
1497 m_digit_7(digit_7),
-
1498 m_digit_8(digit_8),
-
1499 m_digit_9(digit_9),
-
1500 m_digit_10(digit_10),
-
1501 m_digit_11(digit_11),
-
1502 m_digit_12(digit_12),
-
1503 m_digit_13(digit_13),
-
1504 m_digit_14(digit_14),
-
1505 m_digit_15(digit_15)
-
1506 {}
-
1507
-
1508 virtual bool match(
-
1509 _In_reads_or_z_(end) const T* text,
-
1510 _In_ size_t start = 0,
-
1511 _In_ size_t end = (size_t)-1,
-
1512 _In_ int flags = match_default)
-
1513 {
-
1514 _Assume_(text || start >= end);
-
1515 for (this->interval.end = start, this->value = 0; this->interval.end < end && text[this->interval.end];) {
-
1516 size_t dig;
-
1517 if (m_digit_0->match(text, this->interval.end, end, flags)) { dig = 0; this->interval.end = m_digit_0->interval.end; }
-
1518 else if (m_digit_1->match(text, this->interval.end, end, flags)) { dig = 1; this->interval.end = m_digit_1->interval.end; }
-
1519 else if (m_digit_2->match(text, this->interval.end, end, flags)) { dig = 2; this->interval.end = m_digit_2->interval.end; }
-
1520 else if (m_digit_3->match(text, this->interval.end, end, flags)) { dig = 3; this->interval.end = m_digit_3->interval.end; }
-
1521 else if (m_digit_4->match(text, this->interval.end, end, flags)) { dig = 4; this->interval.end = m_digit_4->interval.end; }
-
1522 else if (m_digit_5->match(text, this->interval.end, end, flags)) { dig = 5; this->interval.end = m_digit_5->interval.end; }
-
1523 else if (m_digit_6->match(text, this->interval.end, end, flags)) { dig = 6; this->interval.end = m_digit_6->interval.end; }
-
1524 else if (m_digit_7->match(text, this->interval.end, end, flags)) { dig = 7; this->interval.end = m_digit_7->interval.end; }
-
1525 else if (m_digit_8->match(text, this->interval.end, end, flags)) { dig = 8; this->interval.end = m_digit_8->interval.end; }
-
1526 else if (m_digit_9->match(text, this->interval.end, end, flags)) { dig = 9; this->interval.end = m_digit_9->interval.end; }
-
1527 else if (m_digit_10->match(text, this->interval.end, end, flags)) { dig = 10; this->interval.end = m_digit_10->interval.end; }
-
1528 else if (m_digit_11->match(text, this->interval.end, end, flags)) { dig = 11; this->interval.end = m_digit_11->interval.end; }
-
1529 else if (m_digit_12->match(text, this->interval.end, end, flags)) { dig = 12; this->interval.end = m_digit_12->interval.end; }
-
1530 else if (m_digit_13->match(text, this->interval.end, end, flags)) { dig = 13; this->interval.end = m_digit_13->interval.end; }
-
1531 else if (m_digit_14->match(text, this->interval.end, end, flags)) { dig = 14; this->interval.end = m_digit_14->interval.end; }
-
1532 else if (m_digit_15->match(text, this->interval.end, end, flags)) { dig = 15; this->interval.end = m_digit_15->interval.end; }
-
1533 else break;
-
1534 this->value = this->value * 16 + dig;
-
1535 }
- -
1537 this->interval.start = start;
-
1538 return true;
-
1539 }
-
1540 this->interval.start = (this->interval.end = start) + 1;
-
1541 return false;
-
1542 }
-
1543
-
1544 protected:
-
1545 std::shared_ptr<basic_parser<T>>
-
1546 m_digit_0,
-
1547 m_digit_1,
-
1548 m_digit_2,
-
1549 m_digit_3,
-
1550 m_digit_4,
-
1551 m_digit_5,
-
1552 m_digit_6,
-
1553 m_digit_7,
-
1554 m_digit_8,
-
1555 m_digit_9,
-
1556 m_digit_10,
-
1557 m_digit_11,
-
1558 m_digit_12,
-
1559 m_digit_13,
-
1560 m_digit_14,
-
1561 m_digit_15;
-
1562 };
+
1453
+ + +
1456#ifdef _UNICODE
+
1457 using tinteger10ts = winteger10ts;
+
1458#else
+
1459 using tinteger10ts = integer10ts;
+
1460#endif
+ +
1462
+
1466 template <class T>
+
+ +
1468 {
+
1469 public:
+ +
1471 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
+
1472 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
+
1473 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
+
1474 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
+
1475 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
+
1476 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
+
1477 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
+
1478 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
+
1479 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
+
1480 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
+
1481 _In_ const std::shared_ptr<basic_parser<T>>& digit_10,
+
1482 _In_ const std::shared_ptr<basic_parser<T>>& digit_11,
+
1483 _In_ const std::shared_ptr<basic_parser<T>>& digit_12,
+
1484 _In_ const std::shared_ptr<basic_parser<T>>& digit_13,
+
1485 _In_ const std::shared_ptr<basic_parser<T>>& digit_14,
+
1486 _In_ const std::shared_ptr<basic_parser<T>>& digit_15,
+
1487 _In_ const std::locale& locale = std::locale()) :
+
1488 basic_integer<T>(locale),
+
1489 m_digit_0(digit_0),
+
1490 m_digit_1(digit_1),
+
1491 m_digit_2(digit_2),
+
1492 m_digit_3(digit_3),
+
1493 m_digit_4(digit_4),
+
1494 m_digit_5(digit_5),
+
1495 m_digit_6(digit_6),
+
1496 m_digit_7(digit_7),
+
1497 m_digit_8(digit_8),
+
1498 m_digit_9(digit_9),
+
1499 m_digit_10(digit_10),
+
1500 m_digit_11(digit_11),
+
1501 m_digit_12(digit_12),
+
1502 m_digit_13(digit_13),
+
1503 m_digit_14(digit_14),
+
1504 m_digit_15(digit_15)
+
1505 {}
+
1506
+
1507 virtual bool match(
+
1508 _In_reads_or_z_(end) const T* text,
+
1509 _In_ size_t start = 0,
+
1510 _In_ size_t end = (size_t)-1,
+
1511 _In_ int flags = match_default)
+
1512 {
+
1513 _Assume_(text || start >= end);
+
1514 for (this->interval.end = start, this->value = 0; this->interval.end < end && text[this->interval.end];) {
+
1515 size_t dig;
+
1516 if (m_digit_0->match(text, this->interval.end, end, flags)) { dig = 0; this->interval.end = m_digit_0->interval.end; }
+
1517 else if (m_digit_1->match(text, this->interval.end, end, flags)) { dig = 1; this->interval.end = m_digit_1->interval.end; }
+
1518 else if (m_digit_2->match(text, this->interval.end, end, flags)) { dig = 2; this->interval.end = m_digit_2->interval.end; }
+
1519 else if (m_digit_3->match(text, this->interval.end, end, flags)) { dig = 3; this->interval.end = m_digit_3->interval.end; }
+
1520 else if (m_digit_4->match(text, this->interval.end, end, flags)) { dig = 4; this->interval.end = m_digit_4->interval.end; }
+
1521 else if (m_digit_5->match(text, this->interval.end, end, flags)) { dig = 5; this->interval.end = m_digit_5->interval.end; }
+
1522 else if (m_digit_6->match(text, this->interval.end, end, flags)) { dig = 6; this->interval.end = m_digit_6->interval.end; }
+
1523 else if (m_digit_7->match(text, this->interval.end, end, flags)) { dig = 7; this->interval.end = m_digit_7->interval.end; }
+
1524 else if (m_digit_8->match(text, this->interval.end, end, flags)) { dig = 8; this->interval.end = m_digit_8->interval.end; }
+
1525 else if (m_digit_9->match(text, this->interval.end, end, flags)) { dig = 9; this->interval.end = m_digit_9->interval.end; }
+
1526 else if (m_digit_10->match(text, this->interval.end, end, flags)) { dig = 10; this->interval.end = m_digit_10->interval.end; }
+
1527 else if (m_digit_11->match(text, this->interval.end, end, flags)) { dig = 11; this->interval.end = m_digit_11->interval.end; }
+
1528 else if (m_digit_12->match(text, this->interval.end, end, flags)) { dig = 12; this->interval.end = m_digit_12->interval.end; }
+
1529 else if (m_digit_13->match(text, this->interval.end, end, flags)) { dig = 13; this->interval.end = m_digit_13->interval.end; }
+
1530 else if (m_digit_14->match(text, this->interval.end, end, flags)) { dig = 14; this->interval.end = m_digit_14->interval.end; }
+
1531 else if (m_digit_15->match(text, this->interval.end, end, flags)) { dig = 15; this->interval.end = m_digit_15->interval.end; }
+
1532 else break;
+
1533 this->value = this->value * 16 + dig;
+
1534 }
+ +
1536 this->interval.start = start;
+
1537 return true;
+
1538 }
+
1539 this->interval.start = (this->interval.end = start) + 1;
+
1540 return false;
+
1541 }
+
1542
+
1543 protected:
+
1544 std::shared_ptr<basic_parser<T>>
+
1545 m_digit_0,
+
1546 m_digit_1,
+
1547 m_digit_2,
+
1548 m_digit_3,
+
1549 m_digit_4,
+
1550 m_digit_5,
+
1551 m_digit_6,
+
1552 m_digit_7,
+
1553 m_digit_8,
+
1554 m_digit_9,
+
1555 m_digit_10,
+
1556 m_digit_11,
+
1557 m_digit_12,
+
1558 m_digit_13,
+
1559 m_digit_14,
+
1560 m_digit_15;
+
1561 };
-
1563
- - -
1566#ifdef _UNICODE
-
1567 using tinteger16 = winteger16;
-
1568#else
-
1569 using tinteger16 = integer16;
-
1570#endif
- -
1572
-
1576 template <class T>
-
- -
1578 {
-
1579 public:
- -
1581 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
-
1582 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
-
1583 _In_ const std::shared_ptr<basic_parser<T>>& digit_10,
-
1584 _In_ const std::shared_ptr<basic_parser<T>>& digit_50,
-
1585 _In_ const std::shared_ptr<basic_parser<T>>& digit_100,
-
1586 _In_ const std::shared_ptr<basic_parser<T>>& digit_500,
-
1587 _In_ const std::shared_ptr<basic_parser<T>>& digit_1000,
-
1588 _In_ const std::shared_ptr<basic_parser<T>>& digit_5000,
-
1589 _In_ const std::shared_ptr<basic_parser<T>>& digit_10000,
-
1590 _In_ const std::locale& locale = std::locale()) :
-
1591 basic_integer<T>(locale),
-
1592 m_digit_1(digit_1),
-
1593 m_digit_5(digit_5),
-
1594 m_digit_10(digit_10),
-
1595 m_digit_50(digit_50),
-
1596 m_digit_100(digit_100),
-
1597 m_digit_500(digit_500),
-
1598 m_digit_1000(digit_1000),
-
1599 m_digit_5000(digit_5000),
-
1600 m_digit_10000(digit_10000)
-
1601 {}
-
1602
-
1603 virtual bool match(
-
1604 _In_reads_or_z_(end) const T* text,
-
1605 _In_ size_t start = 0,
-
1606 _In_ size_t end = (size_t)-1,
-
1607 _In_ int flags = match_default)
-
1608 {
-
1609 _Assume_(text || start >= end);
-
1610 size_t
-
1611 dig[5] = { (size_t)-1, (size_t)-1, (size_t)-1, (size_t)-1, (size_t)-1 },
-
1612 end2;
-
1613
-
1614 for (this->interval.end = start, this->value = 0; this->interval.end < end && text[this->interval.end]; dig[3] = dig[2], dig[2] = dig[1], dig[1] = dig[0], this->interval.end = end2) {
-
1615 if (m_digit_1 && m_digit_1->match(text, this->interval.end, end, flags)) { dig[0] = 1; end2 = m_digit_1->interval.end; }
-
1616 else if (m_digit_5 && m_digit_5->match(text, this->interval.end, end, flags)) { dig[0] = 5; end2 = m_digit_5->interval.end; }
-
1617 else if (m_digit_10 && m_digit_10->match(text, this->interval.end, end, flags)) { dig[0] = 10; end2 = m_digit_10->interval.end; }
-
1618 else if (m_digit_50 && m_digit_50->match(text, this->interval.end, end, flags)) { dig[0] = 50; end2 = m_digit_50->interval.end; }
-
1619 else if (m_digit_100 && m_digit_100->match(text, this->interval.end, end, flags)) { dig[0] = 100; end2 = m_digit_100->interval.end; }
-
1620 else if (m_digit_500 && m_digit_500->match(text, this->interval.end, end, flags)) { dig[0] = 500; end2 = m_digit_500->interval.end; }
-
1621 else if (m_digit_1000 && m_digit_1000->match(text, this->interval.end, end, flags)) { dig[0] = 1000; end2 = m_digit_1000->interval.end; }
-
1622 else if (m_digit_5000 && m_digit_5000->match(text, this->interval.end, end, flags)) { dig[0] = 5000; end2 = m_digit_5000->interval.end; }
-
1623 else if (m_digit_10000 && m_digit_10000->match(text, this->interval.end, end, flags)) { dig[0] = 10000; end2 = m_digit_10000->interval.end; }
-
1624 else break;
-
1625
-
1626 // Store first digit.
-
1627 if (dig[4] == (size_t)-1) dig[4] = dig[0];
-
1628
-
1629 if (dig[3] == dig[2] && dig[2] == dig[1] && dig[1] == dig[0] && dig[0] != dig[4]) {
-
1630 // Same digit repeated four times. No-go, unless first digit. E.g. XIIII vs. XIV. MMMMMCD allowed, IIII also...
-
1631 break;
-
1632 }
-
1633 if (dig[0] <= dig[1]) {
-
1634 // Digit is less or equal previous one: add.
-
1635 this->value += dig[0];
-
1636 }
-
1637 else if (
-
1638 (dig[1] == 1 && (dig[0] == 5 || dig[0] == 10)) ||
-
1639 (dig[1] == 10 && (dig[0] == 50 || dig[0] == 100)) ||
-
1640 (dig[1] == 100 && (dig[0] == 500 || dig[0] == 1000)) ||
-
1641 (dig[1] == 1000 && (dig[0] == 5000 || dig[0] == 10000)))
-
1642 {
-
1643 // Digit is up to two orders bigger than previous one: subtract. But...
-
1644 if (dig[2] < dig[0]) {
-
1645 // Digit is also bigger than pre-previous one. E.g. VIX (V < X => invalid)
-
1646 break;
-
1647 }
-
1648 this->value -= dig[1]; // Cancel addition in the previous step.
-
1649 dig[0] -= dig[1]; // Combine last two digits.
-
1650 dig[1] = dig[2]; // The true previous digit is now pre-previous one. :)
-
1651 dig[2] = dig[3]; // The true pre-previous digit is now pre-pre-previous one. :)
-
1652 this->value += dig[0]; // Add combined value.
-
1653 }
-
1654 else {
-
1655 // New digit is too big than the previous one. E.g. VX (V < X => invalid)
-
1656 break;
-
1657 }
-
1658 }
-
1659 if (this->value) {
-
1660 this->interval.start = start;
-
1661 return true;
-
1662 }
-
1663 this->interval.start = (this->interval.end = start) + 1;
-
1664 return false;
-
1665 }
-
1666
-
1667 protected:
-
1668 std::shared_ptr<basic_parser<T>>
-
1669 m_digit_1,
-
1670 m_digit_5,
-
1671 m_digit_10,
-
1672 m_digit_50,
-
1673 m_digit_100,
-
1674 m_digit_500,
-
1675 m_digit_1000,
-
1676 m_digit_5000,
-
1677 m_digit_10000;
-
1678 };
+
1562
+ + +
1565#ifdef _UNICODE
+
1566 using tinteger16 = winteger16;
+
1567#else
+
1568 using tinteger16 = integer16;
+
1569#endif
+ +
1571
+
1575 template <class T>
+
+ +
1577 {
+
1578 public:
+ +
1580 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
+
1581 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
+
1582 _In_ const std::shared_ptr<basic_parser<T>>& digit_10,
+
1583 _In_ const std::shared_ptr<basic_parser<T>>& digit_50,
+
1584 _In_ const std::shared_ptr<basic_parser<T>>& digit_100,
+
1585 _In_ const std::shared_ptr<basic_parser<T>>& digit_500,
+
1586 _In_ const std::shared_ptr<basic_parser<T>>& digit_1000,
+
1587 _In_ const std::shared_ptr<basic_parser<T>>& digit_5000,
+
1588 _In_ const std::shared_ptr<basic_parser<T>>& digit_10000,
+
1589 _In_ const std::locale& locale = std::locale()) :
+
1590 basic_integer<T>(locale),
+
1591 m_digit_1(digit_1),
+
1592 m_digit_5(digit_5),
+
1593 m_digit_10(digit_10),
+
1594 m_digit_50(digit_50),
+
1595 m_digit_100(digit_100),
+
1596 m_digit_500(digit_500),
+
1597 m_digit_1000(digit_1000),
+
1598 m_digit_5000(digit_5000),
+
1599 m_digit_10000(digit_10000)
+
1600 {}
+
1601
+
1602 virtual bool match(
+
1603 _In_reads_or_z_(end) const T* text,
+
1604 _In_ size_t start = 0,
+
1605 _In_ size_t end = (size_t)-1,
+
1606 _In_ int flags = match_default)
+
1607 {
+
1608 _Assume_(text || start >= end);
+
1609 size_t
+
1610 dig[5] = { (size_t)-1, (size_t)-1, (size_t)-1, (size_t)-1, (size_t)-1 },
+
1611 end2;
+
1612
+
1613 for (this->interval.end = start, this->value = 0; this->interval.end < end && text[this->interval.end]; dig[3] = dig[2], dig[2] = dig[1], dig[1] = dig[0], this->interval.end = end2) {
+
1614 if (m_digit_1 && m_digit_1->match(text, this->interval.end, end, flags)) { dig[0] = 1; end2 = m_digit_1->interval.end; }
+
1615 else if (m_digit_5 && m_digit_5->match(text, this->interval.end, end, flags)) { dig[0] = 5; end2 = m_digit_5->interval.end; }
+
1616 else if (m_digit_10 && m_digit_10->match(text, this->interval.end, end, flags)) { dig[0] = 10; end2 = m_digit_10->interval.end; }
+
1617 else if (m_digit_50 && m_digit_50->match(text, this->interval.end, end, flags)) { dig[0] = 50; end2 = m_digit_50->interval.end; }
+
1618 else if (m_digit_100 && m_digit_100->match(text, this->interval.end, end, flags)) { dig[0] = 100; end2 = m_digit_100->interval.end; }
+
1619 else if (m_digit_500 && m_digit_500->match(text, this->interval.end, end, flags)) { dig[0] = 500; end2 = m_digit_500->interval.end; }
+
1620 else if (m_digit_1000 && m_digit_1000->match(text, this->interval.end, end, flags)) { dig[0] = 1000; end2 = m_digit_1000->interval.end; }
+
1621 else if (m_digit_5000 && m_digit_5000->match(text, this->interval.end, end, flags)) { dig[0] = 5000; end2 = m_digit_5000->interval.end; }
+
1622 else if (m_digit_10000 && m_digit_10000->match(text, this->interval.end, end, flags)) { dig[0] = 10000; end2 = m_digit_10000->interval.end; }
+
1623 else break;
+
1624
+
1625 // Store first digit.
+
1626 if (dig[4] == (size_t)-1) dig[4] = dig[0];
+
1627
+
1628 if (dig[3] == dig[2] && dig[2] == dig[1] && dig[1] == dig[0] && dig[0] != dig[4]) {
+
1629 // Same digit repeated four times. No-go, unless first digit. E.g. XIIII vs. XIV. MMMMMCD allowed, IIII also...
+
1630 break;
+
1631 }
+
1632 if (dig[0] <= dig[1]) {
+
1633 // Digit is less or equal previous one: add.
+
1634 this->value += dig[0];
+
1635 }
+
1636 else if (
+
1637 (dig[1] == 1 && (dig[0] == 5 || dig[0] == 10)) ||
+
1638 (dig[1] == 10 && (dig[0] == 50 || dig[0] == 100)) ||
+
1639 (dig[1] == 100 && (dig[0] == 500 || dig[0] == 1000)) ||
+
1640 (dig[1] == 1000 && (dig[0] == 5000 || dig[0] == 10000)))
+
1641 {
+
1642 // Digit is up to two orders bigger than previous one: subtract. But...
+
1643 if (dig[2] < dig[0]) {
+
1644 // Digit is also bigger than pre-previous one. E.g. VIX (V < X => invalid)
+
1645 break;
+
1646 }
+
1647 this->value -= dig[1]; // Cancel addition in the previous step.
+
1648 dig[0] -= dig[1]; // Combine last two digits.
+
1649 dig[1] = dig[2]; // The true previous digit is now pre-previous one. :)
+
1650 dig[2] = dig[3]; // The true pre-previous digit is now pre-pre-previous one. :)
+
1651 this->value += dig[0]; // Add combined value.
+
1652 }
+
1653 else {
+
1654 // New digit is too big than the previous one. E.g. VX (V < X => invalid)
+
1655 break;
+
1656 }
+
1657 }
+
1658 if (this->value) {
+
1659 this->interval.start = start;
+
1660 return true;
+
1661 }
+
1662 this->interval.start = (this->interval.end = start) + 1;
+
1663 return false;
+
1664 }
+
1665
+
1666 protected:
+
1667 std::shared_ptr<basic_parser<T>>
+
1668 m_digit_1,
+
1669 m_digit_5,
+
1670 m_digit_10,
+
1671 m_digit_50,
+
1672 m_digit_100,
+
1673 m_digit_500,
+
1674 m_digit_1000,
+
1675 m_digit_5000,
+
1676 m_digit_10000;
+
1677 };
-
1679
- - -
1682#ifdef _UNICODE
- -
1684#else
- -
1686#endif
- -
1688
-
1692 template <class T>
-
- -
1694 {
-
1695 public:
- -
1697 _In_ const std::shared_ptr<basic_parser<T>>& _numerator,
-
1698 _In_ const std::shared_ptr<basic_parser<T>>& _fraction_line,
-
1699 _In_ const std::shared_ptr<basic_parser<T>>& _denominator,
-
1700 _In_ const std::locale& locale = std::locale()) :
-
1701 basic_parser<T>(locale),
-
1702 numerator(_numerator),
-
1703 fraction_line(_fraction_line),
-
1704 denominator(_denominator)
-
1705 {}
-
1706
-
1707 virtual bool match(
-
1708 _In_reads_or_z_(end) const T* text,
-
1709 _In_ size_t start = 0,
-
1710 _In_ size_t end = (size_t)-1,
-
1711 _In_ int flags = match_default)
-
1712 {
-
1713 _Assume_(text || start >= end);
-
1714 if (numerator->match(text, start, end, flags) &&
-
1715 fraction_line->match(text, numerator->interval.end, end, flags) &&
-
1716 denominator->match(text, fraction_line->interval.end, end, flags))
-
1717 {
-
1718 this->interval.start = start;
-
1719 this->interval.end = denominator->interval.end;
-
1720 return true;
-
1721 }
-
1722 numerator->invalidate();
-
1723 fraction_line->invalidate();
-
1724 denominator->invalidate();
-
1725 this->interval.start = (this->interval.end = start) + 1;
-
1726 return false;
-
1727 }
-
1728
-
1729 virtual void invalidate()
-
1730 {
-
1731 numerator->invalidate();
-
1732 fraction_line->invalidate();
-
1733 denominator->invalidate();
- -
1735 }
-
1736
-
1737 public:
-
1738 std::shared_ptr<basic_parser<T>> numerator;
-
1739 std::shared_ptr<basic_parser<T>> fraction_line;
-
1740 std::shared_ptr<basic_parser<T>> denominator;
-
1741 };
+
1678
+ + +
1681#ifdef _UNICODE
+ +
1683#else
+ +
1685#endif
+ +
1687
+
1691 template <class T>
+
+ +
1693 {
+
1694 public:
+ +
1696 _In_ const std::shared_ptr<basic_parser<T>>& _numerator,
+
1697 _In_ const std::shared_ptr<basic_parser<T>>& _fraction_line,
+
1698 _In_ const std::shared_ptr<basic_parser<T>>& _denominator,
+
1699 _In_ const std::locale& locale = std::locale()) :
+
1700 basic_parser<T>(locale),
+
1701 numerator(_numerator),
+
1702 fraction_line(_fraction_line),
+
1703 denominator(_denominator)
+
1704 {}
+
1705
+
1706 virtual bool match(
+
1707 _In_reads_or_z_(end) const T* text,
+
1708 _In_ size_t start = 0,
+
1709 _In_ size_t end = (size_t)-1,
+
1710 _In_ int flags = match_default)
+
1711 {
+
1712 _Assume_(text || start >= end);
+
1713 if (numerator->match(text, start, end, flags) &&
+
1714 fraction_line->match(text, numerator->interval.end, end, flags) &&
+
1715 denominator->match(text, fraction_line->interval.end, end, flags))
+
1716 {
+
1717 this->interval.start = start;
+
1718 this->interval.end = denominator->interval.end;
+
1719 return true;
+
1720 }
+
1721 numerator->invalidate();
+
1722 fraction_line->invalidate();
+
1723 denominator->invalidate();
+
1724 this->interval.start = (this->interval.end = start) + 1;
+
1725 return false;
+
1726 }
+
1727
+
1728 virtual void invalidate()
+
1729 {
+
1730 numerator->invalidate();
+
1731 fraction_line->invalidate();
+
1732 denominator->invalidate();
+ +
1734 }
+
1735
+
1736 public:
+
1737 std::shared_ptr<basic_parser<T>> numerator;
+
1738 std::shared_ptr<basic_parser<T>> fraction_line;
+
1739 std::shared_ptr<basic_parser<T>> denominator;
+
1740 };
-
1742
- - -
1745#ifdef _UNICODE
-
1746 using tfraction = wfraction;
-
1747#else
-
1748 using tfraction = fraction;
-
1749#endif
- -
1751
-
1755 template <class T>
-
-
1756 class basic_score : public basic_parser<T>
-
1757 {
-
1758 public:
- -
1760 _In_ const std::shared_ptr<basic_parser<T>>& _home,
-
1761 _In_ const std::shared_ptr<basic_parser<T>>& _separator,
-
1762 _In_ const std::shared_ptr<basic_parser<T>>& _guest,
-
1763 _In_ const std::shared_ptr<basic_parser<T>>& space,
-
1764 _In_ const std::locale& locale = std::locale()) :
-
1765 basic_parser<T>(locale),
-
1766 home(_home),
-
1767 separator(_separator),
-
1768 guest(_guest),
-
1769 m_space(space)
-
1770 {}
-
1771
-
1772 virtual bool match(
-
1773 _In_reads_or_z_(end) const T* text,
-
1774 _In_ size_t start = 0,
-
1775 _In_ size_t end = (size_t)-1,
-
1776 _In_ int flags = match_default)
-
1777 {
-
1778 _Assume_(text || start >= end);
-
1779 this->interval.end = start;
-
1780
-
1781 const int space_match_flags = flags & ~match_multiline; // Spaces in score must never be broken in new line.
-
1782
-
1783 if (home->match(text, this->interval.end, end, flags))
-
1784 this->interval.end = home->interval.end;
-
1785 else
-
1786 goto end;
-
1787
-
1788 for (; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
1789
-
1790 if (separator->match(text, this->interval.end, end, flags))
-
1791 this->interval.end = separator->interval.end;
-
1792 else
-
1793 goto end;
-
1794
-
1795 for (; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
1796
-
1797 if (guest->match(text, this->interval.end, end, flags))
-
1798 this->interval.end = guest->interval.end;
-
1799 else
-
1800 goto end;
-
1801
-
1802 this->interval.start = start;
-
1803 return true;
-
1804
-
1805 end:
-
1806 home->invalidate();
-
1807 separator->invalidate();
-
1808 guest->invalidate();
-
1809 this->interval.start = (this->interval.end = start) + 1;
-
1810 return false;
-
1811 }
-
1812
-
1813 virtual void invalidate()
-
1814 {
-
1815 home->invalidate();
-
1816 separator->invalidate();
-
1817 guest->invalidate();
- -
1819 }
-
1820
-
1821 public:
-
1822 std::shared_ptr<basic_parser<T>> home;
-
1823 std::shared_ptr<basic_parser<T>> separator;
-
1824 std::shared_ptr<basic_parser<T>> guest;
-
1825
-
1826 protected:
-
1827 std::shared_ptr<basic_parser<T>> m_space;
-
1828 };
+
1741
+ + +
1744#ifdef _UNICODE
+
1745 using tfraction = wfraction;
+
1746#else
+
1747 using tfraction = fraction;
+
1748#endif
+ +
1750
+
1754 template <class T>
+
+
1755 class basic_score : public basic_parser<T>
+
1756 {
+
1757 public:
+ +
1759 _In_ const std::shared_ptr<basic_parser<T>>& _home,
+
1760 _In_ const std::shared_ptr<basic_parser<T>>& _separator,
+
1761 _In_ const std::shared_ptr<basic_parser<T>>& _guest,
+
1762 _In_ const std::shared_ptr<basic_parser<T>>& space,
+
1763 _In_ const std::locale& locale = std::locale()) :
+
1764 basic_parser<T>(locale),
+
1765 home(_home),
+
1766 separator(_separator),
+
1767 guest(_guest),
+
1768 m_space(space)
+
1769 {}
+
1770
+
1771 virtual bool match(
+
1772 _In_reads_or_z_(end) const T* text,
+
1773 _In_ size_t start = 0,
+
1774 _In_ size_t end = (size_t)-1,
+
1775 _In_ int flags = match_default)
+
1776 {
+
1777 _Assume_(text || start >= end);
+
1778 this->interval.end = start;
+
1779
+
1780 const int space_match_flags = flags & ~match_multiline; // Spaces in score must never be broken in new line.
+
1781
+
1782 if (home->match(text, this->interval.end, end, flags))
+
1783 this->interval.end = home->interval.end;
+
1784 else
+
1785 goto end;
+
1786
+
1787 for (; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
1788
+
1789 if (separator->match(text, this->interval.end, end, flags))
+
1790 this->interval.end = separator->interval.end;
+
1791 else
+
1792 goto end;
+
1793
+
1794 for (; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
1795
+
1796 if (guest->match(text, this->interval.end, end, flags))
+
1797 this->interval.end = guest->interval.end;
+
1798 else
+
1799 goto end;
+
1800
+
1801 this->interval.start = start;
+
1802 return true;
+
1803
+
1804 end:
+
1805 home->invalidate();
+
1806 separator->invalidate();
+
1807 guest->invalidate();
+
1808 this->interval.start = (this->interval.end = start) + 1;
+
1809 return false;
+
1810 }
+
1811
+
1812 virtual void invalidate()
+
1813 {
+
1814 home->invalidate();
+
1815 separator->invalidate();
+
1816 guest->invalidate();
+ +
1818 }
+
1819
+
1820 public:
+
1821 std::shared_ptr<basic_parser<T>> home;
+
1822 std::shared_ptr<basic_parser<T>> separator;
+
1823 std::shared_ptr<basic_parser<T>> guest;
+
1824
+
1825 protected:
+
1826 std::shared_ptr<basic_parser<T>> m_space;
+
1827 };
-
1829
-
1830 using score = basic_score<char>;
- -
1832#ifdef _UNICODE
-
1833 using tscore = wscore;
-
1834#else
-
1835 using tscore = score;
-
1836#endif
- -
1838
-
1842 template <class T>
-
- -
1844 {
-
1845 public:
- -
1847 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
-
1848 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
-
1849 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
-
1850 _In_ const std::shared_ptr<basic_parser<T>>& _number,
-
1851 _In_ const std::locale& locale = std::locale()) :
-
1852 basic_parser<T>(locale),
- - - - -
1857 {}
-
1858
-
1859 virtual bool match(
-
1860 _In_reads_or_z_(end) const T* text,
-
1861 _In_ size_t start = 0,
-
1862 _In_ size_t end = (size_t)-1,
-
1863 _In_ int flags = match_default)
-
1864 {
-
1865 _Assume_(text || start >= end);
-
1866 this->interval.end = start;
-
1867 if (positive_sign && positive_sign->match(text, this->interval.end, end, flags)) {
-
1868 this->interval.end = positive_sign->interval.end;
-
1869 if (negative_sign) negative_sign->invalidate();
-
1870 if (special_sign) special_sign->invalidate();
-
1871 }
-
1872 else if (negative_sign && negative_sign->match(text, this->interval.end, end, flags)) {
-
1873 this->interval.end = negative_sign->interval.end;
-
1874 if (positive_sign) positive_sign->invalidate();
-
1875 if (special_sign) special_sign->invalidate();
-
1876 }
-
1877 else if (special_sign && special_sign->match(text, this->interval.end, end, flags)) {
-
1878 this->interval.end = special_sign->interval.end;
-
1879 if (positive_sign) positive_sign->invalidate();
-
1880 if (negative_sign) negative_sign->invalidate();
-
1881 }
-
1882 else {
-
1883 if (positive_sign) positive_sign->invalidate();
-
1884 if (negative_sign) negative_sign->invalidate();
-
1885 if (special_sign) special_sign->invalidate();
-
1886 }
-
1887 if (number->match(text, this->interval.end, end, flags)) {
-
1888 this->interval.start = start;
-
1889 this->interval.end = number->interval.end;
-
1890 return true;
-
1891 }
-
1892 if (positive_sign) positive_sign->invalidate();
-
1893 if (negative_sign) negative_sign->invalidate();
-
1894 if (special_sign) special_sign->invalidate();
-
1895 number->invalidate();
-
1896 this->interval.start = (this->interval.end = start) + 1;
-
1897 return false;
-
1898 }
-
1899
-
1900 virtual void invalidate()
-
1901 {
-
1902 if (positive_sign) positive_sign->invalidate();
-
1903 if (negative_sign) negative_sign->invalidate();
-
1904 if (special_sign) special_sign->invalidate();
-
1905 number->invalidate();
- -
1907 }
-
1908
-
1909 public:
-
1910 std::shared_ptr<basic_parser<T>> positive_sign;
-
1911 std::shared_ptr<basic_parser<T>> negative_sign;
-
1912 std::shared_ptr<basic_parser<T>> special_sign;
-
1913 std::shared_ptr<basic_parser<T>> number;
-
1914 };
+
1828
+
1829 using score = basic_score<char>;
+ +
1831#ifdef _UNICODE
+
1832 using tscore = wscore;
+
1833#else
+
1834 using tscore = score;
+
1835#endif
+ +
1837
+
1841 template <class T>
+
+ +
1843 {
+
1844 public:
+ +
1846 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
+
1847 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
+
1848 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
+
1849 _In_ const std::shared_ptr<basic_parser<T>>& _number,
+
1850 _In_ const std::locale& locale = std::locale()) :
+
1851 basic_parser<T>(locale),
+ + + + +
1856 {}
+
1857
+
1858 virtual bool match(
+
1859 _In_reads_or_z_(end) const T* text,
+
1860 _In_ size_t start = 0,
+
1861 _In_ size_t end = (size_t)-1,
+
1862 _In_ int flags = match_default)
+
1863 {
+
1864 _Assume_(text || start >= end);
+
1865 this->interval.end = start;
+
1866 if (positive_sign && positive_sign->match(text, this->interval.end, end, flags)) {
+
1867 this->interval.end = positive_sign->interval.end;
+
1868 if (negative_sign) negative_sign->invalidate();
+
1869 if (special_sign) special_sign->invalidate();
+
1870 }
+
1871 else if (negative_sign && negative_sign->match(text, this->interval.end, end, flags)) {
+
1872 this->interval.end = negative_sign->interval.end;
+
1873 if (positive_sign) positive_sign->invalidate();
+
1874 if (special_sign) special_sign->invalidate();
+
1875 }
+
1876 else if (special_sign && special_sign->match(text, this->interval.end, end, flags)) {
+
1877 this->interval.end = special_sign->interval.end;
+
1878 if (positive_sign) positive_sign->invalidate();
+
1879 if (negative_sign) negative_sign->invalidate();
+
1880 }
+
1881 else {
+
1882 if (positive_sign) positive_sign->invalidate();
+
1883 if (negative_sign) negative_sign->invalidate();
+
1884 if (special_sign) special_sign->invalidate();
+
1885 }
+
1886 if (number->match(text, this->interval.end, end, flags)) {
+
1887 this->interval.start = start;
+
1888 this->interval.end = number->interval.end;
+
1889 return true;
+
1890 }
+
1891 if (positive_sign) positive_sign->invalidate();
+
1892 if (negative_sign) negative_sign->invalidate();
+
1893 if (special_sign) special_sign->invalidate();
+
1894 number->invalidate();
+
1895 this->interval.start = (this->interval.end = start) + 1;
+
1896 return false;
+
1897 }
+
1898
+
1899 virtual void invalidate()
+
1900 {
+
1901 if (positive_sign) positive_sign->invalidate();
+
1902 if (negative_sign) negative_sign->invalidate();
+
1903 if (special_sign) special_sign->invalidate();
+
1904 number->invalidate();
+ +
1906 }
+
1907
+
1908 public:
+
1909 std::shared_ptr<basic_parser<T>> positive_sign;
+
1910 std::shared_ptr<basic_parser<T>> negative_sign;
+
1911 std::shared_ptr<basic_parser<T>> special_sign;
+
1912 std::shared_ptr<basic_parser<T>> number;
+
1913 };
-
1915
- - -
1918#ifdef _UNICODE
- -
1920#else
- -
1922#endif
- -
1924
-
1928 template <class T>
-
- -
1930 {
-
1931 public:
- -
1933 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
-
1934 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
-
1935 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
-
1936 _In_ const std::shared_ptr<basic_parser<T>>& _integer,
-
1937 _In_ const std::shared_ptr<basic_parser<T>>& space,
-
1938 _In_ const std::shared_ptr<basic_parser<T>>& _fraction,
-
1939 _In_ const std::locale& locale = std::locale()) :
-
1940 basic_parser<T>(locale),
- - - - - -
1946 m_space(space)
-
1947 {}
-
1948
-
1949 virtual bool match(
-
1950 _In_reads_or_z_(end) const T* text,
-
1951 _In_ size_t start = 0,
-
1952 _In_ size_t end = (size_t)-1,
-
1953 _In_ int flags = match_default)
-
1954 {
-
1955 _Assume_(text || start >= end);
-
1956 this->interval.end = start;
-
1957
-
1958 if (positive_sign && positive_sign->match(text, this->interval.end, end, flags)) {
-
1959 this->interval.end = positive_sign->interval.end;
-
1960 if (negative_sign) negative_sign->invalidate();
-
1961 if (special_sign) special_sign->invalidate();
-
1962 }
-
1963 else if (negative_sign && negative_sign->match(text, this->interval.end, end, flags)) {
-
1964 this->interval.end = negative_sign->interval.end;
-
1965 if (positive_sign) positive_sign->invalidate();
-
1966 if (special_sign) special_sign->invalidate();
-
1967 }
-
1968 else if (special_sign && special_sign->match(text, this->interval.end, end, flags)) {
-
1969 this->interval.end = special_sign->interval.end;
-
1970 if (positive_sign) positive_sign->invalidate();
-
1971 if (negative_sign) negative_sign->invalidate();
-
1972 }
-
1973 else {
-
1974 if (positive_sign) positive_sign->invalidate();
-
1975 if (negative_sign) negative_sign->invalidate();
-
1976 if (special_sign) special_sign->invalidate();
-
1977 }
-
1978
-
1979 // Check for <integer> <fraction>
-
1980 const int space_match_flags = flags & ~match_multiline; // Spaces in fractions must never be broken in new line.
-
1981 if (integer->match(text, this->interval.end, end, flags) &&
-
1982 m_space->match(text, integer->interval.end, end, space_match_flags))
-
1983 {
-
1984 for (this->interval.end = m_space->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
1985 if (fraction->match(text, this->interval.end, end, flags)) {
-
1986 this->interval.start = start;
-
1987 this->interval.end = fraction->interval.end;
-
1988 return true;
-
1989 }
-
1990 fraction->invalidate();
-
1991 this->interval.start = start;
-
1992 this->interval.end = integer->interval.end;
-
1993 return true;
-
1994 }
-
1995
-
1996 // Check for <fraction>
-
1997 if (fraction->match(text, this->interval.end, end, flags)) {
-
1998 integer->invalidate();
-
1999 this->interval.start = start;
-
2000 this->interval.end = fraction->interval.end;
-
2001 return true;
-
2002 }
-
2003
-
2004 // Check for <integer>
-
2005 if (integer->match(text, this->interval.end, end, flags)) {
-
2006 fraction->invalidate();
-
2007 this->interval.start = start;
-
2008 this->interval.end = integer->interval.end;
-
2009 return true;
-
2010 }
-
2011
-
2012 if (positive_sign) positive_sign->invalidate();
-
2013 if (negative_sign) negative_sign->invalidate();
-
2014 if (special_sign) special_sign->invalidate();
-
2015 integer->invalidate();
-
2016 fraction->invalidate();
-
2017 this->interval.start = (this->interval.end = start) + 1;
-
2018 return false;
-
2019 }
-
2020
-
2021 virtual void invalidate()
-
2022 {
-
2023 if (positive_sign) positive_sign->invalidate();
-
2024 if (negative_sign) negative_sign->invalidate();
-
2025 if (special_sign) special_sign->invalidate();
-
2026 integer->invalidate();
-
2027 fraction->invalidate();
- -
2029 }
-
2030
-
2031 public:
-
2032 std::shared_ptr<basic_parser<T>> positive_sign;
-
2033 std::shared_ptr<basic_parser<T>> negative_sign;
-
2034 std::shared_ptr<basic_parser<T>> special_sign;
-
2035 std::shared_ptr<basic_parser<T>> integer;
-
2036 std::shared_ptr<basic_parser<T>> fraction;
-
2037
-
2038 protected:
-
2039 std::shared_ptr<basic_parser<T>> m_space;
-
2040 };
+
1914
+ + +
1917#ifdef _UNICODE
+ +
1919#else
+ +
1921#endif
+ +
1923
+
1927 template <class T>
+
+ +
1929 {
+
1930 public:
+ +
1932 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
+
1933 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
+
1934 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
+
1935 _In_ const std::shared_ptr<basic_parser<T>>& _integer,
+
1936 _In_ const std::shared_ptr<basic_parser<T>>& space,
+
1937 _In_ const std::shared_ptr<basic_parser<T>>& _fraction,
+
1938 _In_ const std::locale& locale = std::locale()) :
+
1939 basic_parser<T>(locale),
+ + + + + +
1945 m_space(space)
+
1946 {}
+
1947
+
1948 virtual bool match(
+
1949 _In_reads_or_z_(end) const T* text,
+
1950 _In_ size_t start = 0,
+
1951 _In_ size_t end = (size_t)-1,
+
1952 _In_ int flags = match_default)
+
1953 {
+
1954 _Assume_(text || start >= end);
+
1955 this->interval.end = start;
+
1956
+
1957 if (positive_sign && positive_sign->match(text, this->interval.end, end, flags)) {
+
1958 this->interval.end = positive_sign->interval.end;
+
1959 if (negative_sign) negative_sign->invalidate();
+
1960 if (special_sign) special_sign->invalidate();
+
1961 }
+
1962 else if (negative_sign && negative_sign->match(text, this->interval.end, end, flags)) {
+
1963 this->interval.end = negative_sign->interval.end;
+
1964 if (positive_sign) positive_sign->invalidate();
+
1965 if (special_sign) special_sign->invalidate();
+
1966 }
+
1967 else if (special_sign && special_sign->match(text, this->interval.end, end, flags)) {
+
1968 this->interval.end = special_sign->interval.end;
+
1969 if (positive_sign) positive_sign->invalidate();
+
1970 if (negative_sign) negative_sign->invalidate();
+
1971 }
+
1972 else {
+
1973 if (positive_sign) positive_sign->invalidate();
+
1974 if (negative_sign) negative_sign->invalidate();
+
1975 if (special_sign) special_sign->invalidate();
+
1976 }
+
1977
+
1978 // Check for <integer> <fraction>
+
1979 const int space_match_flags = flags & ~match_multiline; // Spaces in fractions must never be broken in new line.
+
1980 if (integer->match(text, this->interval.end, end, flags) &&
+
1981 m_space->match(text, integer->interval.end, end, space_match_flags))
+
1982 {
+
1983 for (this->interval.end = m_space->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
1984 if (fraction->match(text, this->interval.end, end, flags)) {
+
1985 this->interval.start = start;
+
1986 this->interval.end = fraction->interval.end;
+
1987 return true;
+
1988 }
+
1989 fraction->invalidate();
+
1990 this->interval.start = start;
+
1991 this->interval.end = integer->interval.end;
+
1992 return true;
+
1993 }
+
1994
+
1995 // Check for <fraction>
+
1996 if (fraction->match(text, this->interval.end, end, flags)) {
+
1997 integer->invalidate();
+
1998 this->interval.start = start;
+
1999 this->interval.end = fraction->interval.end;
+
2000 return true;
+
2001 }
+
2002
+
2003 // Check for <integer>
+
2004 if (integer->match(text, this->interval.end, end, flags)) {
+
2005 fraction->invalidate();
+
2006 this->interval.start = start;
+
2007 this->interval.end = integer->interval.end;
+
2008 return true;
+
2009 }
+
2010
+
2011 if (positive_sign) positive_sign->invalidate();
+
2012 if (negative_sign) negative_sign->invalidate();
+
2013 if (special_sign) special_sign->invalidate();
+
2014 integer->invalidate();
+
2015 fraction->invalidate();
+
2016 this->interval.start = (this->interval.end = start) + 1;
+
2017 return false;
+
2018 }
+
2019
+
2020 virtual void invalidate()
+
2021 {
+
2022 if (positive_sign) positive_sign->invalidate();
+
2023 if (negative_sign) negative_sign->invalidate();
+
2024 if (special_sign) special_sign->invalidate();
+
2025 integer->invalidate();
+
2026 fraction->invalidate();
+ +
2028 }
+
2029
+
2030 public:
+
2031 std::shared_ptr<basic_parser<T>> positive_sign;
+
2032 std::shared_ptr<basic_parser<T>> negative_sign;
+
2033 std::shared_ptr<basic_parser<T>> special_sign;
+
2034 std::shared_ptr<basic_parser<T>> integer;
+
2035 std::shared_ptr<basic_parser<T>> fraction;
+
2036
+
2037 protected:
+
2038 std::shared_ptr<basic_parser<T>> m_space;
+
2039 };
-
2041
- - -
2044#ifdef _UNICODE
- -
2046#else
- -
2048#endif
- -
2050
-
2054 template <class T>
-
- -
2056 {
-
2057 public:
- -
2059 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
-
2060 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
-
2061 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
-
2062 _In_ const std::shared_ptr<basic_integer<T>>& _integer,
-
2063 _In_ const std::shared_ptr<basic_parser<T>>& _decimal_separator,
-
2064 _In_ const std::shared_ptr<basic_integer<T>>& _decimal,
-
2065 _In_ const std::shared_ptr<basic_parser<T>>& _exponent_symbol,
-
2066 _In_ const std::shared_ptr<basic_parser<T>>& _positive_exp_sign,
-
2067 _In_ const std::shared_ptr<basic_parser<T>>& _negative_exp_sign,
-
2068 _In_ const std::shared_ptr<basic_integer<T>>& _exponent,
-
2069 _In_ const std::locale& locale = std::locale()) :
-
2070 basic_parser<T>(locale),
- - - - - - - - - - -
2081 value(std::numeric_limits<double>::quiet_NaN())
-
2082 {}
-
2083
-
2084 virtual bool match(
-
2085 _In_reads_or_z_(end) const T* text,
-
2086 _In_ size_t start = 0,
-
2087 _In_ size_t end = (size_t)-1,
-
2088 _In_ int flags = match_default)
-
2089 {
-
2090 _Assume_(text || start >= end);
-
2091 this->interval.end = start;
-
2092
-
2093 if (positive_sign && positive_sign->match(text, this->interval.end, end, flags)) {
-
2094 this->interval.end = positive_sign->interval.end;
-
2095 if (negative_sign) negative_sign->invalidate();
-
2096 if (special_sign) special_sign->invalidate();
-
2097 }
-
2098 else if (negative_sign && negative_sign->match(text, this->interval.end, end, flags)) {
-
2099 this->interval.end = negative_sign->interval.end;
-
2100 if (positive_sign) positive_sign->invalidate();
-
2101 if (special_sign) special_sign->invalidate();
-
2102 }
-
2103 else if (special_sign && special_sign->match(text, this->interval.end, end, flags)) {
-
2104 this->interval.end = special_sign->interval.end;
-
2105 if (positive_sign) positive_sign->invalidate();
-
2106 if (negative_sign) negative_sign->invalidate();
-
2107 }
-
2108 else {
-
2109 if (positive_sign) positive_sign->invalidate();
-
2110 if (negative_sign) negative_sign->invalidate();
-
2111 if (special_sign) special_sign->invalidate();
-
2112 }
-
2113
-
2114 if (integer->match(text, this->interval.end, end, flags))
-
2115 this->interval.end = integer->interval.end;
-
2116
-
2117 if (decimal_separator->match(text, this->interval.end, end, flags) &&
- -
2119 this->interval.end = decimal->interval.end;
-
2120 else {
-
2121 decimal_separator->invalidate();
-
2122 decimal->invalidate();
-
2123 }
-
2124
-
2125 if (integer->interval.empty() &&
-
2126 decimal->interval.empty())
-
2127 {
-
2128 // No integer part, no decimal part.
-
2129 if (positive_sign) positive_sign->invalidate();
-
2130 if (negative_sign) negative_sign->invalidate();
-
2131 if (special_sign) special_sign->invalidate();
-
2132 integer->invalidate();
-
2133 decimal_separator->invalidate();
-
2134 decimal->invalidate();
-
2135 if (exponent_symbol) exponent_symbol->invalidate();
-
2136 if (positive_exp_sign) positive_exp_sign->invalidate();
-
2137 if (negative_exp_sign) negative_exp_sign->invalidate();
-
2138 if (exponent) exponent->invalidate();
-
2139 this->interval.start = (this->interval.end = start) + 1;
-
2140 return false;
-
2141 }
-
2142
-
2143 if (exponent_symbol && exponent_symbol->match(text, this->interval.end, end, flags) &&
- - -
2146 (exponent && exponent->match(text, exponent_symbol->interval.end, end, flags))))
-
2147 {
-
2148 this->interval.end = exponent->interval.end;
-
2149 if (negative_exp_sign) negative_exp_sign->invalidate();
-
2150 }
-
2151 else if (exponent_symbol && exponent_symbol->match(text, this->interval.end, end, flags) &&
- - -
2154 {
-
2155 this->interval.end = exponent->interval.end;
-
2156 if (positive_exp_sign) positive_exp_sign->invalidate();
-
2157 }
-
2158 else {
-
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 }
-
2164
-
2165 value = (double)integer->value;
-
2166 if (decimal->interval)
-
2167 value += (double)decimal->value * pow(10.0, -(double)decimal->interval.size());
-
2168 if (negative_sign && negative_sign->interval)
-
2169 value = -value;
-
2170 if (exponent && exponent->interval) {
-
2171 double e = (double)exponent->value;
-
2172 if (negative_exp_sign && negative_exp_sign->interval)
-
2173 e = -e;
-
2174 value *= pow(10.0, e);
-
2175 }
-
2176
-
2177 this->interval.start = start;
-
2178 return true;
-
2179 }
-
2180
-
2181 virtual void invalidate()
-
2182 {
-
2183 if (positive_sign) positive_sign->invalidate();
-
2184 if (negative_sign) negative_sign->invalidate();
-
2185 if (special_sign) special_sign->invalidate();
-
2186 integer->invalidate();
-
2187 decimal_separator->invalidate();
-
2188 decimal->invalidate();
-
2189 if (exponent_symbol) exponent_symbol->invalidate();
-
2190 if (positive_exp_sign) positive_exp_sign->invalidate();
-
2191 if (negative_exp_sign) negative_exp_sign->invalidate();
-
2192 if (exponent) exponent->invalidate();
-
2193 value = std::numeric_limits<double>::quiet_NaN();
- -
2195 }
-
2196
-
2197 public:
-
2198 std::shared_ptr<basic_parser<T>> positive_sign;
-
2199 std::shared_ptr<basic_parser<T>> negative_sign;
-
2200 std::shared_ptr<basic_parser<T>> special_sign;
-
2201 std::shared_ptr<basic_integer<T>> integer;
-
2202 std::shared_ptr<basic_parser<T>> decimal_separator;
-
2203 std::shared_ptr<basic_integer<T>> decimal;
-
2204 std::shared_ptr<basic_parser<T>> exponent_symbol;
-
2205 std::shared_ptr<basic_parser<T>> positive_exp_sign;
-
2206 std::shared_ptr<basic_parser<T>> negative_exp_sign;
-
2207 std::shared_ptr<basic_integer<T>> exponent;
-
2208 double value;
-
2209 };
+
2040
+ + +
2043#ifdef _UNICODE
+ +
2045#else
+ +
2047#endif
+ +
2049
+
2053 template <class T>
+
+ +
2055 {
+
2056 public:
+ +
2058 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
+
2059 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
+
2060 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
+
2061 _In_ const std::shared_ptr<basic_integer<T>>& _integer,
+
2062 _In_ const std::shared_ptr<basic_parser<T>>& _decimal_separator,
+
2063 _In_ const std::shared_ptr<basic_integer<T>>& _decimal,
+
2064 _In_ const std::shared_ptr<basic_parser<T>>& _exponent_symbol,
+
2065 _In_ const std::shared_ptr<basic_parser<T>>& _positive_exp_sign,
+
2066 _In_ const std::shared_ptr<basic_parser<T>>& _negative_exp_sign,
+
2067 _In_ const std::shared_ptr<basic_integer<T>>& _exponent,
+
2068 _In_ const std::locale& locale = std::locale()) :
+
2069 basic_parser<T>(locale),
+ + + + + + + + + + +
2080 value(std::numeric_limits<double>::quiet_NaN())
+
2081 {}
+
2082
+
2083 virtual bool match(
+
2084 _In_reads_or_z_(end) const T* text,
+
2085 _In_ size_t start = 0,
+
2086 _In_ size_t end = (size_t)-1,
+
2087 _In_ int flags = match_default)
+
2088 {
+
2089 _Assume_(text || start >= end);
+
2090 this->interval.end = start;
+
2091
+
2092 if (positive_sign && positive_sign->match(text, this->interval.end, end, flags)) {
+
2093 this->interval.end = positive_sign->interval.end;
+
2094 if (negative_sign) negative_sign->invalidate();
+
2095 if (special_sign) special_sign->invalidate();
+
2096 }
+
2097 else if (negative_sign && negative_sign->match(text, this->interval.end, end, flags)) {
+
2098 this->interval.end = negative_sign->interval.end;
+
2099 if (positive_sign) positive_sign->invalidate();
+
2100 if (special_sign) special_sign->invalidate();
+
2101 }
+
2102 else if (special_sign && special_sign->match(text, this->interval.end, end, flags)) {
+
2103 this->interval.end = special_sign->interval.end;
+
2104 if (positive_sign) positive_sign->invalidate();
+
2105 if (negative_sign) negative_sign->invalidate();
+
2106 }
+
2107 else {
+
2108 if (positive_sign) positive_sign->invalidate();
+
2109 if (negative_sign) negative_sign->invalidate();
+
2110 if (special_sign) special_sign->invalidate();
+
2111 }
+
2112
+
2113 if (integer->match(text, this->interval.end, end, flags))
+
2114 this->interval.end = integer->interval.end;
+
2115
+
2116 if (decimal_separator->match(text, this->interval.end, end, flags) &&
+ +
2118 this->interval.end = decimal->interval.end;
+
2119 else {
+
2120 decimal_separator->invalidate();
+
2121 decimal->invalidate();
+
2122 }
+
2123
+
2124 if (integer->interval.empty() &&
+
2125 decimal->interval.empty())
+
2126 {
+
2127 // No integer part, no decimal part.
+
2128 if (positive_sign) positive_sign->invalidate();
+
2129 if (negative_sign) negative_sign->invalidate();
+
2130 if (special_sign) special_sign->invalidate();
+
2131 integer->invalidate();
+
2132 decimal_separator->invalidate();
+
2133 decimal->invalidate();
+
2134 if (exponent_symbol) exponent_symbol->invalidate();
+
2135 if (positive_exp_sign) positive_exp_sign->invalidate();
+
2136 if (negative_exp_sign) negative_exp_sign->invalidate();
+
2137 if (exponent) exponent->invalidate();
+
2138 this->interval.start = (this->interval.end = start) + 1;
+
2139 return false;
+
2140 }
+
2141
+
2142 if (exponent_symbol && exponent_symbol->match(text, this->interval.end, end, flags) &&
+ + +
2145 (exponent && exponent->match(text, exponent_symbol->interval.end, end, flags))))
+
2146 {
+
2147 this->interval.end = exponent->interval.end;
+
2148 if (negative_exp_sign) negative_exp_sign->invalidate();
+
2149 }
+
2150 else if (exponent_symbol && exponent_symbol->match(text, this->interval.end, end, flags) &&
+ + +
2153 {
+
2154 this->interval.end = exponent->interval.end;
+
2155 if (positive_exp_sign) positive_exp_sign->invalidate();
+
2156 }
+
2157 else {
+
2158 if (exponent_symbol) exponent_symbol->invalidate();
+
2159 if (positive_exp_sign) positive_exp_sign->invalidate();
+
2160 if (negative_exp_sign) negative_exp_sign->invalidate();
+
2161 if (exponent) exponent->invalidate();
+
2162 }
+
2163
+
2164 value = (double)integer->value;
+
2165 if (decimal->interval)
+
2166 value += (double)decimal->value * pow(10.0, -(double)decimal->interval.size());
+
2167 if (negative_sign && negative_sign->interval)
+
2168 value = -value;
+
2169 if (exponent && exponent->interval) {
+
2170 double e = (double)exponent->value;
+
2171 if (negative_exp_sign && negative_exp_sign->interval)
+
2172 e = -e;
+
2173 value *= pow(10.0, e);
+
2174 }
+
2175
+
2176 this->interval.start = start;
+
2177 return true;
+
2178 }
+
2179
+
2180 virtual void invalidate()
+
2181 {
+
2182 if (positive_sign) positive_sign->invalidate();
+
2183 if (negative_sign) negative_sign->invalidate();
+
2184 if (special_sign) special_sign->invalidate();
+
2185 integer->invalidate();
+
2186 decimal_separator->invalidate();
+
2187 decimal->invalidate();
+
2188 if (exponent_symbol) exponent_symbol->invalidate();
+
2189 if (positive_exp_sign) positive_exp_sign->invalidate();
+
2190 if (negative_exp_sign) negative_exp_sign->invalidate();
+
2191 if (exponent) exponent->invalidate();
+
2192 value = std::numeric_limits<double>::quiet_NaN();
+ +
2194 }
+
2195
+
2196 public:
+
2197 std::shared_ptr<basic_parser<T>> positive_sign;
+
2198 std::shared_ptr<basic_parser<T>> negative_sign;
+
2199 std::shared_ptr<basic_parser<T>> special_sign;
+
2200 std::shared_ptr<basic_integer<T>> integer;
+
2201 std::shared_ptr<basic_parser<T>> decimal_separator;
+
2202 std::shared_ptr<basic_integer<T>> decimal;
+
2203 std::shared_ptr<basic_parser<T>> exponent_symbol;
+
2204 std::shared_ptr<basic_parser<T>> positive_exp_sign;
+
2205 std::shared_ptr<basic_parser<T>> negative_exp_sign;
+
2206 std::shared_ptr<basic_integer<T>> exponent;
+
2207 double value;
+
2208 };
-
2210
- - -
2213#ifdef _UNICODE
- -
2215#else
- -
2217#endif
- -
2219
-
2223 template <class T>
-
- -
2225 {
-
2226 public:
- -
2228 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
-
2229 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
-
2230 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
-
2231 _In_ const std::shared_ptr<basic_parser<T>>& _currency,
-
2232 _In_ const std::shared_ptr<basic_parser<T>>& _integer,
-
2233 _In_ const std::shared_ptr<basic_parser<T>>& _decimal_separator,
-
2234 _In_ const std::shared_ptr<basic_parser<T>>& _decimal,
-
2235 _In_ const std::locale& locale = std::locale()) :
-
2236 basic_parser<T>(locale),
- - - - - - - -
2244 {}
-
2245
-
2246 virtual bool match(
-
2247 _In_reads_or_z_(end) const T* text,
-
2248 _In_ size_t start = 0,
-
2249 _In_ size_t end = (size_t)-1,
-
2250 _In_ int flags = match_default)
-
2251 {
-
2252 _Assume_(text || start >= end);
-
2253 this->interval.end = start;
-
2254
-
2255 if (positive_sign->match(text, this->interval.end, end, flags)) {
-
2256 this->interval.end = positive_sign->interval.end;
-
2257 if (negative_sign) negative_sign->invalidate();
-
2258 if (special_sign) special_sign->invalidate();
-
2259 }
-
2260 else if (negative_sign->match(text, this->interval.end, end, flags)) {
-
2261 this->interval.end = negative_sign->interval.end;
-
2262 if (positive_sign) positive_sign->invalidate();
-
2263 if (special_sign) special_sign->invalidate();
-
2264 }
-
2265 else if (special_sign->match(text, this->interval.end, end, flags)) {
-
2266 this->interval.end = special_sign->interval.end;
-
2267 if (positive_sign) positive_sign->invalidate();
-
2268 if (negative_sign) negative_sign->invalidate();
-
2269 }
-
2270 else {
-
2271 if (positive_sign) positive_sign->invalidate();
-
2272 if (negative_sign) negative_sign->invalidate();
-
2273 if (special_sign) special_sign->invalidate();
-
2274 }
-
2275
-
2276 if (currency->match(text, this->interval.end, end, flags))
-
2277 this->interval.end = currency->interval.end;
-
2278 else {
-
2279 if (positive_sign) positive_sign->invalidate();
-
2280 if (negative_sign) negative_sign->invalidate();
-
2281 if (special_sign) special_sign->invalidate();
-
2282 integer->invalidate();
-
2283 decimal_separator->invalidate();
-
2284 decimal->invalidate();
-
2285 this->interval.start = (this->interval.end = start) + 1;
-
2286 return false;
-
2287 }
-
2288
-
2289 if (integer->match(text, this->interval.end, end, flags))
-
2290 this->interval.end = integer->interval.end;
-
2291 if (decimal_separator->match(text, this->interval.end, end, flags) &&
- -
2293 this->interval.end = decimal->interval.end;
-
2294 else {
-
2295 decimal_separator->invalidate();
-
2296 decimal->invalidate();
-
2297 }
-
2298
-
2299 if (integer->interval.empty() &&
-
2300 decimal->interval.empty())
-
2301 {
-
2302 // No integer part, no decimal part.
-
2303 if (positive_sign) positive_sign->invalidate();
-
2304 if (negative_sign) negative_sign->invalidate();
-
2305 if (special_sign) special_sign->invalidate();
-
2306 currency->invalidate();
-
2307 integer->invalidate();
-
2308 decimal_separator->invalidate();
-
2309 decimal->invalidate();
-
2310 this->interval.start = (this->interval.end = start) + 1;
-
2311 return false;
-
2312 }
-
2313
-
2314 this->interval.start = start;
-
2315 return true;
-
2316 }
-
2317
-
2318 virtual void invalidate()
-
2319 {
-
2320 if (positive_sign) positive_sign->invalidate();
-
2321 if (negative_sign) negative_sign->invalidate();
-
2322 if (special_sign) special_sign->invalidate();
-
2323 currency->invalidate();
-
2324 integer->invalidate();
-
2325 decimal_separator->invalidate();
-
2326 decimal->invalidate();
- -
2328 }
-
2329
-
2330 public:
-
2331 std::shared_ptr<basic_parser<T>> positive_sign;
-
2332 std::shared_ptr<basic_parser<T>> negative_sign;
-
2333 std::shared_ptr<basic_parser<T>> special_sign;
-
2334 std::shared_ptr<basic_parser<T>> currency;
-
2335 std::shared_ptr<basic_parser<T>> integer;
-
2336 std::shared_ptr<basic_parser<T>> decimal_separator;
-
2337 std::shared_ptr<basic_parser<T>> decimal;
-
2338 };
+
2209
+ + +
2212#ifdef _UNICODE
+ +
2214#else
+ +
2216#endif
+ +
2218
+
2222 template <class T>
+
+ +
2224 {
+
2225 public:
+ +
2227 _In_ const std::shared_ptr<basic_parser<T>>& _positive_sign,
+
2228 _In_ const std::shared_ptr<basic_parser<T>>& _negative_sign,
+
2229 _In_ const std::shared_ptr<basic_parser<T>>& _special_sign,
+
2230 _In_ const std::shared_ptr<basic_parser<T>>& _currency,
+
2231 _In_ const std::shared_ptr<basic_parser<T>>& _integer,
+
2232 _In_ const std::shared_ptr<basic_parser<T>>& _decimal_separator,
+
2233 _In_ const std::shared_ptr<basic_parser<T>>& _decimal,
+
2234 _In_ const std::locale& locale = std::locale()) :
+
2235 basic_parser<T>(locale),
+ + + + + + + +
2243 {}
+
2244
+
2245 virtual bool match(
+
2246 _In_reads_or_z_(end) const T* text,
+
2247 _In_ size_t start = 0,
+
2248 _In_ size_t end = (size_t)-1,
+
2249 _In_ int flags = match_default)
+
2250 {
+
2251 _Assume_(text || start >= end);
+
2252 this->interval.end = start;
+
2253
+
2254 if (positive_sign->match(text, this->interval.end, end, flags)) {
+
2255 this->interval.end = positive_sign->interval.end;
+
2256 if (negative_sign) negative_sign->invalidate();
+
2257 if (special_sign) special_sign->invalidate();
+
2258 }
+
2259 else if (negative_sign->match(text, this->interval.end, end, flags)) {
+
2260 this->interval.end = negative_sign->interval.end;
+
2261 if (positive_sign) positive_sign->invalidate();
+
2262 if (special_sign) special_sign->invalidate();
+
2263 }
+
2264 else if (special_sign->match(text, this->interval.end, end, flags)) {
+
2265 this->interval.end = special_sign->interval.end;
+
2266 if (positive_sign) positive_sign->invalidate();
+
2267 if (negative_sign) negative_sign->invalidate();
+
2268 }
+
2269 else {
+
2270 if (positive_sign) positive_sign->invalidate();
+
2271 if (negative_sign) negative_sign->invalidate();
+
2272 if (special_sign) special_sign->invalidate();
+
2273 }
+
2274
+
2275 if (currency->match(text, this->interval.end, end, flags))
+
2276 this->interval.end = currency->interval.end;
+
2277 else {
+
2278 if (positive_sign) positive_sign->invalidate();
+
2279 if (negative_sign) negative_sign->invalidate();
+
2280 if (special_sign) special_sign->invalidate();
+
2281 integer->invalidate();
+
2282 decimal_separator->invalidate();
+
2283 decimal->invalidate();
+
2284 this->interval.start = (this->interval.end = start) + 1;
+
2285 return false;
+
2286 }
+
2287
+
2288 if (integer->match(text, this->interval.end, end, flags))
+
2289 this->interval.end = integer->interval.end;
+
2290 if (decimal_separator->match(text, this->interval.end, end, flags) &&
+ +
2292 this->interval.end = decimal->interval.end;
+
2293 else {
+
2294 decimal_separator->invalidate();
+
2295 decimal->invalidate();
+
2296 }
+
2297
+
2298 if (integer->interval.empty() &&
+
2299 decimal->interval.empty())
+
2300 {
+
2301 // No integer part, no decimal part.
+
2302 if (positive_sign) positive_sign->invalidate();
+
2303 if (negative_sign) negative_sign->invalidate();
+
2304 if (special_sign) special_sign->invalidate();
+
2305 currency->invalidate();
+
2306 integer->invalidate();
+
2307 decimal_separator->invalidate();
+
2308 decimal->invalidate();
+
2309 this->interval.start = (this->interval.end = start) + 1;
+
2310 return false;
+
2311 }
+
2312
+
2313 this->interval.start = start;
+
2314 return true;
+
2315 }
+
2316
+
2317 virtual void invalidate()
+
2318 {
+
2319 if (positive_sign) positive_sign->invalidate();
+
2320 if (negative_sign) negative_sign->invalidate();
+
2321 if (special_sign) special_sign->invalidate();
+
2322 currency->invalidate();
+
2323 integer->invalidate();
+
2324 decimal_separator->invalidate();
+
2325 decimal->invalidate();
+ +
2327 }
+
2328
+
2329 public:
+
2330 std::shared_ptr<basic_parser<T>> positive_sign;
+
2331 std::shared_ptr<basic_parser<T>> negative_sign;
+
2332 std::shared_ptr<basic_parser<T>> special_sign;
+
2333 std::shared_ptr<basic_parser<T>> currency;
+
2334 std::shared_ptr<basic_parser<T>> integer;
+
2335 std::shared_ptr<basic_parser<T>> decimal_separator;
+
2336 std::shared_ptr<basic_parser<T>> decimal;
+
2337 };
-
2339
- - -
2342#ifdef _UNICODE
- -
2344#else
- -
2346#endif
- -
2348
-
2352 template <class T>
-
- -
2354 {
-
2355 public:
- -
2357 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
-
2358 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
-
2359 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
-
2360 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
-
2361 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
-
2362 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
-
2363 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
-
2364 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
-
2365 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
-
2366 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
-
2367 _In_ const std::shared_ptr<basic_parser<T>>& separator,
-
2368 _In_ const std::locale& locale = std::locale()) :
-
2369 basic_parser<T>(locale),
-
2370 m_digit_0(digit_0),
-
2371 m_digit_1(digit_1),
-
2372 m_digit_2(digit_2),
-
2373 m_digit_3(digit_3),
-
2374 m_digit_4(digit_4),
-
2375 m_digit_5(digit_5),
-
2376 m_digit_6(digit_6),
-
2377 m_digit_7(digit_7),
-
2378 m_digit_8(digit_8),
-
2379 m_digit_9(digit_9),
-
2380 m_separator(separator)
-
2381 {
-
2382 value.s_addr = 0;
-
2383 }
-
2384
-
2385 virtual bool match(
-
2386 _In_reads_or_z_(end) const T* text,
-
2387 _In_ size_t start = 0,
-
2388 _In_ size_t end = (size_t)-1,
-
2389 _In_ int flags = match_default)
-
2390 {
-
2391 _Assume_(text || start >= end);
-
2392 this->interval.end = start;
-
2393 value.s_addr = 0;
-
2394
-
2395 size_t i;
-
2396 for (i = 0; i < 4; i++) {
-
2397 if (i) {
-
2398 if (m_separator->match(text, this->interval.end, end, flags))
-
2399 this->interval.end = m_separator->interval.end;
-
2400 else
-
2401 goto error;
-
2402 }
-
2403
-
2404 components[i].start = this->interval.end;
-
2405 bool is_empty = true;
-
2406 size_t x;
-
2407 for (x = 0; this->interval.end < end && text[this->interval.end];) {
-
2408 size_t dig, digit_end;
-
2409 if (m_digit_0->match(text, this->interval.end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
-
2410 else if (m_digit_1->match(text, this->interval.end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
-
2411 else if (m_digit_2->match(text, this->interval.end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
-
2412 else if (m_digit_3->match(text, this->interval.end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
-
2413 else if (m_digit_4->match(text, this->interval.end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
-
2414 else if (m_digit_5->match(text, this->interval.end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
-
2415 else if (m_digit_6->match(text, this->interval.end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
-
2416 else if (m_digit_7->match(text, this->interval.end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
-
2417 else if (m_digit_8->match(text, this->interval.end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
-
2418 else if (m_digit_9->match(text, this->interval.end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
-
2419 else break;
-
2420 size_t x_n = x * 10 + dig;
-
2421 if (x_n <= 255) {
-
2422 x = x_n;
-
2423 this->interval.end = digit_end;
-
2424 is_empty = false;
-
2425 }
-
2426 else
-
2427 break;
-
2428 }
-
2429 if (is_empty)
-
2430 goto error;
-
2431 components[i].end = this->interval.end;
-
2432 value.s_addr = (value.s_addr << 8) | (uint8_t)x;
-
2433 }
-
2434 if (i < 4)
-
2435 goto error;
-
2436
-
2437 this->interval.start = start;
-
2438 return true;
-
2439
-
2440 error:
-
2441 components[0].start = 1;
-
2442 components[0].end = 0;
-
2443 components[1].start = 1;
-
2444 components[1].end = 0;
-
2445 components[2].start = 1;
-
2446 components[2].end = 0;
-
2447 components[3].start = 1;
-
2448 components[3].end = 0;
-
2449 value.s_addr = 0;
-
2450 this->interval.start = (this->interval.end = start) + 1;
-
2451 return false;
-
2452 }
-
2453
-
2454 virtual void invalidate()
-
2455 {
-
2456 components[0].start = 1;
-
2457 components[0].end = 0;
-
2458 components[1].start = 1;
-
2459 components[1].end = 0;
-
2460 components[2].start = 1;
-
2461 components[2].end = 0;
-
2462 components[3].start = 1;
-
2463 components[3].end = 0;
-
2464 value.s_addr = 0;
- -
2466 }
-
2467
-
2468 public:
- - -
2471
-
2472 protected:
-
2473 std::shared_ptr<basic_parser<T>>
-
2474 m_digit_0,
-
2475 m_digit_1,
-
2476 m_digit_2,
-
2477 m_digit_3,
-
2478 m_digit_4,
-
2479 m_digit_5,
-
2480 m_digit_6,
-
2481 m_digit_7,
-
2482 m_digit_8,
-
2483 m_digit_9;
-
2484 std::shared_ptr<basic_parser<T>> m_separator;
-
2485 };
+
2338
+ + +
2341#ifdef _UNICODE
+ +
2343#else
+ +
2345#endif
+ +
2347
+
2351 template <class T>
+
+ +
2353 {
+
2354 public:
+ +
2356 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
+
2357 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
+
2358 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
+
2359 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
+
2360 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
+
2361 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
+
2362 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
+
2363 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
+
2364 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
+
2365 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
+
2366 _In_ const std::shared_ptr<basic_parser<T>>& separator,
+
2367 _In_ const std::locale& locale = std::locale()) :
+
2368 basic_parser<T>(locale),
+
2369 m_digit_0(digit_0),
+
2370 m_digit_1(digit_1),
+
2371 m_digit_2(digit_2),
+
2372 m_digit_3(digit_3),
+
2373 m_digit_4(digit_4),
+
2374 m_digit_5(digit_5),
+
2375 m_digit_6(digit_6),
+
2376 m_digit_7(digit_7),
+
2377 m_digit_8(digit_8),
+
2378 m_digit_9(digit_9),
+
2379 m_separator(separator)
+
2380 {
+
2381 value.s_addr = 0;
+
2382 }
+
2383
+
2384 virtual bool match(
+
2385 _In_reads_or_z_(end) const T* text,
+
2386 _In_ size_t start = 0,
+
2387 _In_ size_t end = (size_t)-1,
+
2388 _In_ int flags = match_default)
+
2389 {
+
2390 _Assume_(text || start >= end);
+
2391 this->interval.end = start;
+
2392 value.s_addr = 0;
+
2393
+
2394 size_t i;
+
2395 for (i = 0; i < 4; i++) {
+
2396 if (i) {
+
2397 if (m_separator->match(text, this->interval.end, end, flags))
+
2398 this->interval.end = m_separator->interval.end;
+
2399 else
+
2400 goto error;
+
2401 }
+
2402
+
2403 components[i].start = this->interval.end;
+
2404 bool is_empty = true;
+
2405 size_t x;
+
2406 for (x = 0; this->interval.end < end && text[this->interval.end];) {
+
2407 size_t dig, digit_end;
+
2408 if (m_digit_0->match(text, this->interval.end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
+
2409 else if (m_digit_1->match(text, this->interval.end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
+
2410 else if (m_digit_2->match(text, this->interval.end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
+
2411 else if (m_digit_3->match(text, this->interval.end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
+
2412 else if (m_digit_4->match(text, this->interval.end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
+
2413 else if (m_digit_5->match(text, this->interval.end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
+
2414 else if (m_digit_6->match(text, this->interval.end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
+
2415 else if (m_digit_7->match(text, this->interval.end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
+
2416 else if (m_digit_8->match(text, this->interval.end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
+
2417 else if (m_digit_9->match(text, this->interval.end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
+
2418 else break;
+
2419 size_t x_n = x * 10 + dig;
+
2420 if (x_n <= 255) {
+
2421 x = x_n;
+
2422 this->interval.end = digit_end;
+
2423 is_empty = false;
+
2424 }
+
2425 else
+
2426 break;
+
2427 }
+
2428 if (is_empty)
+
2429 goto error;
+
2430 components[i].end = this->interval.end;
+
2431 value.s_addr = (value.s_addr << 8) | (uint8_t)x;
+
2432 }
+
2433 if (i < 4)
+
2434 goto error;
+
2435
+
2436 this->interval.start = start;
+
2437 return true;
+
2438
+
2439 error:
+
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 this->interval.start = (this->interval.end = start) + 1;
+
2450 return false;
+
2451 }
+
2452
+
2453 virtual void invalidate()
+
2454 {
+
2455 components[0].start = 1;
+
2456 components[0].end = 0;
+
2457 components[1].start = 1;
+
2458 components[1].end = 0;
+
2459 components[2].start = 1;
+
2460 components[2].end = 0;
+
2461 components[3].start = 1;
+
2462 components[3].end = 0;
+
2463 value.s_addr = 0;
+ +
2465 }
+
2466
+
2467 public:
+ + +
2470
+
2471 protected:
+
2472 std::shared_ptr<basic_parser<T>>
+
2473 m_digit_0,
+
2474 m_digit_1,
+
2475 m_digit_2,
+
2476 m_digit_3,
+
2477 m_digit_4,
+
2478 m_digit_5,
+
2479 m_digit_6,
+
2480 m_digit_7,
+
2481 m_digit_8,
+
2482 m_digit_9;
+
2483 std::shared_ptr<basic_parser<T>> m_separator;
+
2484 };
-
2486
- - -
2489#ifdef _UNICODE
- -
2491#else
- -
2493#endif
- -
2495
-
2499 template <class T>
-
- -
2501 {
-
2502 public:
-
2503 basic_ipv6_scope_id_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
-
2504
-
2505 virtual bool match(
-
2506 _In_reads_or_z_(end) const T* text,
-
2507 _In_ size_t start = 0,
-
2508 _In_ size_t end = (size_t)-1,
-
2509 _In_ int flags = match_default)
-
2510 {
-
2511 _Assume_(text || start >= end);
-
2512 if (start < end && text[start]) {
-
2513 if (text[start] == '-' ||
-
2514 text[start] == '_' ||
-
2515 text[start] == ':' ||
-
2516 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
-
2517 {
-
2518 this->interval.end = (this->interval.start = start) + 1;
-
2519 return true;
-
2520 }
-
2521 }
-
2522 this->interval.start = (this->interval.end = start) + 1;
-
2523 return false;
-
2524 }
-
2525 };
+
2485
+ + +
2488#ifdef _UNICODE
+ +
2490#else
+ +
2492#endif
+ +
2494
+
2498 template <class T>
+
+ +
2500 {
+
2501 public:
+
2502 basic_ipv6_scope_id_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
+
2503
+
2504 virtual bool match(
+
2505 _In_reads_or_z_(end) const T* text,
+
2506 _In_ size_t start = 0,
+
2507 _In_ size_t end = (size_t)-1,
+
2508 _In_ int flags = match_default)
+
2509 {
+
2510 _Assume_(text || start >= end);
+
2511 if (start < end && text[start]) {
+
2512 if (text[start] == '-' ||
+
2513 text[start] == '_' ||
+
2514 text[start] == ':' ||
+
2515 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
+
2516 {
+
2517 this->interval.end = (this->interval.start = start) + 1;
+
2518 return true;
+
2519 }
+
2520 }
+
2521 this->interval.start = (this->interval.end = start) + 1;
+
2522 return false;
+
2523 }
+
2524 };
-
2526
- - -
2529#ifdef _UNICODE
- -
2531#else
- -
2533#endif
-
2534
-
- -
2539 {
-
2540 public:
-
2541 sgml_ipv6_scope_id_char(_In_ const std::locale& locale = std::locale()) : sgml_parser(locale) {}
-
2542
-
2543 virtual bool match(
-
2544 _In_reads_or_z_(end) const char* text,
-
2545 _In_ size_t start = 0,
-
2546 _In_ size_t end = (size_t)-1,
-
2547 _In_ int flags = match_default)
-
2548 {
-
2549 _Assume_(text || start >= end);
-
2550 if (start < end && text[start]) {
-
2551 wchar_t buf[3];
-
2552 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
-
2553 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
2554 if (((chr[0] == L'-' ||
-
2555 chr[0] == L'_' ||
-
2556 chr[0] == L':') && chr[1] == 0) ||
-
2557 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
-
2558 {
-
2559 this->interval.start = start;
-
2560 return true;
-
2561 }
-
2562 }
-
2563 this->interval.start = (this->interval.end = start) + 1;
-
2564 return false;
-
2565 }
-
2566 };
+
2525
+ + +
2528#ifdef _UNICODE
+ +
2530#else
+ +
2532#endif
+
2533
+
+ +
2538 {
+
2539 public:
+
2540 sgml_ipv6_scope_id_char(_In_ const std::locale& locale = std::locale()) : sgml_parser(locale) {}
+
2541
+
2542 virtual bool match(
+
2543 _In_reads_or_z_(end) const char* text,
+
2544 _In_ size_t start = 0,
+
2545 _In_ size_t end = (size_t)-1,
+
2546 _In_ int flags = match_default)
+
2547 {
+
2548 _Assume_(text || start >= end);
+
2549 if (start < end && text[start]) {
+
2550 wchar_t buf[3];
+
2551 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
+
2552 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
2553 if (((chr[0] == L'-' ||
+
2554 chr[0] == L'_' ||
+
2555 chr[0] == L':') && chr[1] == 0) ||
+
2556 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
+
2557 {
+
2558 this->interval.start = start;
+
2559 return true;
+
2560 }
+
2561 }
+
2562 this->interval.start = (this->interval.end = start) + 1;
+
2563 return false;
+
2564 }
+
2565 };
-
2567
-
2571 template <class T>
-
- -
2573 {
-
2574 public:
- -
2576 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
-
2577 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
-
2578 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
-
2579 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
-
2580 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
-
2581 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
-
2582 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
-
2583 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
-
2584 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
-
2585 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
-
2586 _In_ const std::shared_ptr<basic_parser<T>>& digit_10,
-
2587 _In_ const std::shared_ptr<basic_parser<T>>& digit_11,
-
2588 _In_ const std::shared_ptr<basic_parser<T>>& digit_12,
-
2589 _In_ const std::shared_ptr<basic_parser<T>>& digit_13,
-
2590 _In_ const std::shared_ptr<basic_parser<T>>& digit_14,
-
2591 _In_ const std::shared_ptr<basic_parser<T>>& digit_15,
-
2592 _In_ const std::shared_ptr<basic_parser<T>>& separator,
-
2593 _In_ const std::shared_ptr<basic_parser<T>>& scope_id_separator = nullptr,
-
2594 _In_ const std::shared_ptr<basic_parser<T>>& _scope_id = nullptr,
-
2595 _In_ const std::locale& locale = std::locale()) :
-
2596 basic_parser<T>(locale),
-
2597 m_digit_0(digit_0),
-
2598 m_digit_1(digit_1),
-
2599 m_digit_2(digit_2),
-
2600 m_digit_3(digit_3),
-
2601 m_digit_4(digit_4),
-
2602 m_digit_5(digit_5),
-
2603 m_digit_6(digit_6),
-
2604 m_digit_7(digit_7),
-
2605 m_digit_8(digit_8),
-
2606 m_digit_9(digit_9),
-
2607 m_digit_10(digit_10),
-
2608 m_digit_11(digit_11),
-
2609 m_digit_12(digit_12),
-
2610 m_digit_13(digit_13),
-
2611 m_digit_14(digit_14),
-
2612 m_digit_15(digit_15),
-
2613 m_separator(separator),
-
2614 m_scope_id_separator(scope_id_separator),
- -
2616 {
-
2617 memset(&value, 0, sizeof(value));
-
2618 }
-
2619
-
2620 virtual bool match(
-
2621 _In_reads_or_z_(end) const T* text,
-
2622 _In_ size_t start = 0,
-
2623 _In_ size_t end = (size_t)-1,
-
2624 _In_ int flags = match_default)
-
2625 {
-
2626 _Assume_(text || start >= end);
-
2627 this->interval.end = start;
-
2628 memset(&value, 0, sizeof(value));
-
2629
-
2630 size_t i, compaction_i = (size_t)-1, compaction_start = start;
-
2631 for (i = 0; i < 8; i++) {
-
2632 bool is_empty = true;
-
2633
-
2634 if (m_separator->match(text, this->interval.end, end, flags)) {
-
2635 if (m_separator->match(text, m_separator->interval.end, end, flags)) {
-
2636 // :: found
-
2637 if (compaction_i == (size_t)-1) {
-
2638 // Zero compaction start
-
2639 compaction_i = i;
-
2640 compaction_start = m_separator->interval.start;
-
2641 this->interval.end = m_separator->interval.end;
-
2642 }
-
2643 else {
-
2644 // More than one zero compaction
-
2645 break;
-
2646 }
-
2647 }
-
2648 else if (i) {
-
2649 // Inner : found
-
2650 this->interval.end = m_separator->interval.end;
-
2651 }
-
2652 else {
-
2653 // Leading : found
-
2654 goto error;
-
2655 }
-
2656 }
-
2657 else if (i) {
-
2658 // : missing
-
2659 break;
-
2660 }
-
2661
-
2662 components[i].start = this->interval.end;
-
2663 size_t x;
-
2664 for (x = 0; this->interval.end < end && text[this->interval.end];) {
-
2665 size_t dig, digit_end;
-
2666 if (m_digit_0->match(text, this->interval.end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
-
2667 else if (m_digit_1->match(text, this->interval.end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
-
2668 else if (m_digit_2->match(text, this->interval.end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
-
2669 else if (m_digit_3->match(text, this->interval.end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
-
2670 else if (m_digit_4->match(text, this->interval.end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
-
2671 else if (m_digit_5->match(text, this->interval.end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
-
2672 else if (m_digit_6->match(text, this->interval.end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
-
2673 else if (m_digit_7->match(text, this->interval.end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
-
2674 else if (m_digit_8->match(text, this->interval.end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
-
2675 else if (m_digit_9->match(text, this->interval.end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
-
2676 else if (m_digit_10->match(text, this->interval.end, end, flags)) { dig = 10; digit_end = m_digit_10->interval.end; }
-
2677 else if (m_digit_11->match(text, this->interval.end, end, flags)) { dig = 11; digit_end = m_digit_11->interval.end; }
-
2678 else if (m_digit_12->match(text, this->interval.end, end, flags)) { dig = 12; digit_end = m_digit_12->interval.end; }
-
2679 else if (m_digit_13->match(text, this->interval.end, end, flags)) { dig = 13; digit_end = m_digit_13->interval.end; }
-
2680 else if (m_digit_14->match(text, this->interval.end, end, flags)) { dig = 14; digit_end = m_digit_14->interval.end; }
-
2681 else if (m_digit_15->match(text, this->interval.end, end, flags)) { dig = 15; digit_end = m_digit_15->interval.end; }
-
2682 else break;
-
2683 size_t x_n = x * 16 + dig;
-
2684 if (x_n <= 0xffff) {
-
2685 x = x_n;
-
2686 this->interval.end = digit_end;
-
2687 is_empty = false;
-
2688 }
-
2689 else
-
2690 break;
-
2691 }
-
2692 if (is_empty) {
-
2693 if (compaction_i != (size_t)-1) {
-
2694 // Zero compaction active: no sweat.
-
2695 break;
-
2696 }
-
2697 goto error;
-
2698 }
-
2699 components[i].end = this->interval.end;
-
2700 this->value.s6_words[i] = (uint16_t)x;
-
2701 }
-
2702
-
2703 if (compaction_i != (size_t)-1) {
-
2704 // Align components right due to zero compaction.
-
2705 size_t j, k;
-
2706 for (j = 8, k = i; k > compaction_i;) {
-
2707 this->value.s6_words[--j] = this->value.s6_words[--k];
- -
2709 }
-
2710 for (; j > compaction_i;) {
-
2711 this->value.s6_words[--j] = 0;
-
2712 components[j].start =
- -
2714 }
-
2715 }
-
2716 else if (i < 8)
-
2717 goto error;
-
2718
-
2719 if (m_scope_id_separator && m_scope_id_separator->match(text, this->interval.end, end, flags) &&
-
2720 scope_id && scope_id->match(text, m_scope_id_separator->interval.end, end, flags))
-
2721 this->interval.end = scope_id->interval.end;
-
2722 else if (scope_id)
-
2723 scope_id->invalidate();
-
2724
-
2725 this->interval.start = start;
-
2726 return true;
-
2727
-
2728 error:
-
2729 components[0].start = 1;
-
2730 components[0].end = 0;
-
2731 components[1].start = 1;
-
2732 components[1].end = 0;
-
2733 components[2].start = 1;
-
2734 components[2].end = 0;
-
2735 components[3].start = 1;
-
2736 components[3].end = 0;
-
2737 components[4].start = 1;
-
2738 components[4].end = 0;
-
2739 components[5].start = 1;
-
2740 components[5].end = 0;
-
2741 components[6].start = 1;
-
2742 components[6].end = 0;
-
2743 components[7].start = 1;
-
2744 components[7].end = 0;
-
2745 memset(&value, 0, sizeof(value));
-
2746 if (scope_id) scope_id->invalidate();
-
2747 this->interval.start = (this->interval.end = start) + 1;
-
2748 return false;
-
2749 }
-
2750
-
2751 virtual void invalidate()
-
2752 {
-
2753 components[0].start = 1;
-
2754 components[0].end = 0;
-
2755 components[1].start = 1;
-
2756 components[1].end = 0;
-
2757 components[2].start = 1;
-
2758 components[2].end = 0;
-
2759 components[3].start = 1;
-
2760 components[3].end = 0;
-
2761 components[4].start = 1;
-
2762 components[4].end = 0;
-
2763 components[5].start = 1;
-
2764 components[5].end = 0;
-
2765 components[6].start = 1;
-
2766 components[6].end = 0;
-
2767 components[7].start = 1;
-
2768 components[7].end = 0;
-
2769 memset(&value, 0, sizeof(value));
-
2770 if (scope_id) scope_id->invalidate();
- -
2772 }
-
2773
-
2774 public:
- - -
2777 std::shared_ptr<basic_parser<T>> scope_id;
-
2778
-
2779 protected:
-
2780 std::shared_ptr<basic_parser<T>>
-
2781 m_digit_0,
-
2782 m_digit_1,
-
2783 m_digit_2,
-
2784 m_digit_3,
-
2785 m_digit_4,
-
2786 m_digit_5,
-
2787 m_digit_6,
-
2788 m_digit_7,
-
2789 m_digit_8,
-
2790 m_digit_9,
-
2791 m_digit_10,
-
2792 m_digit_11,
-
2793 m_digit_12,
-
2794 m_digit_13,
-
2795 m_digit_14,
-
2796 m_digit_15;
-
2797 std::shared_ptr<basic_parser<T>> m_separator, m_scope_id_separator;
-
2798 };
+
2566
+
2570 template <class T>
+
+ +
2572 {
+
2573 public:
+ +
2575 _In_ const std::shared_ptr<basic_parser<T>>& digit_0,
+
2576 _In_ const std::shared_ptr<basic_parser<T>>& digit_1,
+
2577 _In_ const std::shared_ptr<basic_parser<T>>& digit_2,
+
2578 _In_ const std::shared_ptr<basic_parser<T>>& digit_3,
+
2579 _In_ const std::shared_ptr<basic_parser<T>>& digit_4,
+
2580 _In_ const std::shared_ptr<basic_parser<T>>& digit_5,
+
2581 _In_ const std::shared_ptr<basic_parser<T>>& digit_6,
+
2582 _In_ const std::shared_ptr<basic_parser<T>>& digit_7,
+
2583 _In_ const std::shared_ptr<basic_parser<T>>& digit_8,
+
2584 _In_ const std::shared_ptr<basic_parser<T>>& digit_9,
+
2585 _In_ const std::shared_ptr<basic_parser<T>>& digit_10,
+
2586 _In_ const std::shared_ptr<basic_parser<T>>& digit_11,
+
2587 _In_ const std::shared_ptr<basic_parser<T>>& digit_12,
+
2588 _In_ const std::shared_ptr<basic_parser<T>>& digit_13,
+
2589 _In_ const std::shared_ptr<basic_parser<T>>& digit_14,
+
2590 _In_ const std::shared_ptr<basic_parser<T>>& digit_15,
+
2591 _In_ const std::shared_ptr<basic_parser<T>>& separator,
+
2592 _In_ const std::shared_ptr<basic_parser<T>>& scope_id_separator = nullptr,
+
2593 _In_ const std::shared_ptr<basic_parser<T>>& _scope_id = nullptr,
+
2594 _In_ const std::locale& locale = std::locale()) :
+
2595 basic_parser<T>(locale),
+
2596 m_digit_0(digit_0),
+
2597 m_digit_1(digit_1),
+
2598 m_digit_2(digit_2),
+
2599 m_digit_3(digit_3),
+
2600 m_digit_4(digit_4),
+
2601 m_digit_5(digit_5),
+
2602 m_digit_6(digit_6),
+
2603 m_digit_7(digit_7),
+
2604 m_digit_8(digit_8),
+
2605 m_digit_9(digit_9),
+
2606 m_digit_10(digit_10),
+
2607 m_digit_11(digit_11),
+
2608 m_digit_12(digit_12),
+
2609 m_digit_13(digit_13),
+
2610 m_digit_14(digit_14),
+
2611 m_digit_15(digit_15),
+
2612 m_separator(separator),
+
2613 m_scope_id_separator(scope_id_separator),
+ +
2615 {
+
2616 memset(&value, 0, sizeof(value));
+
2617 }
+
2618
+
2619 virtual bool match(
+
2620 _In_reads_or_z_(end) const T* text,
+
2621 _In_ size_t start = 0,
+
2622 _In_ size_t end = (size_t)-1,
+
2623 _In_ int flags = match_default)
+
2624 {
+
2625 _Assume_(text || start >= end);
+
2626 this->interval.end = start;
+
2627 memset(&value, 0, sizeof(value));
+
2628
+
2629 size_t i, compaction_i = (size_t)-1, compaction_start = start;
+
2630 for (i = 0; i < 8; i++) {
+
2631 bool is_empty = true;
+
2632
+
2633 if (m_separator->match(text, this->interval.end, end, flags)) {
+
2634 if (m_separator->match(text, m_separator->interval.end, end, flags)) {
+
2635 // :: found
+
2636 if (compaction_i == (size_t)-1) {
+
2637 // Zero compaction start
+
2638 compaction_i = i;
+
2639 compaction_start = m_separator->interval.start;
+
2640 this->interval.end = m_separator->interval.end;
+
2641 }
+
2642 else {
+
2643 // More than one zero compaction
+
2644 break;
+
2645 }
+
2646 }
+
2647 else if (i) {
+
2648 // Inner : found
+
2649 this->interval.end = m_separator->interval.end;
+
2650 }
+
2651 else {
+
2652 // Leading : found
+
2653 goto error;
+
2654 }
+
2655 }
+
2656 else if (i) {
+
2657 // : missing
+
2658 break;
+
2659 }
+
2660
+
2661 components[i].start = this->interval.end;
+
2662 size_t x;
+
2663 for (x = 0; this->interval.end < end && text[this->interval.end];) {
+
2664 size_t dig, digit_end;
+
2665 if (m_digit_0->match(text, this->interval.end, end, flags)) { dig = 0; digit_end = m_digit_0->interval.end; }
+
2666 else if (m_digit_1->match(text, this->interval.end, end, flags)) { dig = 1; digit_end = m_digit_1->interval.end; }
+
2667 else if (m_digit_2->match(text, this->interval.end, end, flags)) { dig = 2; digit_end = m_digit_2->interval.end; }
+
2668 else if (m_digit_3->match(text, this->interval.end, end, flags)) { dig = 3; digit_end = m_digit_3->interval.end; }
+
2669 else if (m_digit_4->match(text, this->interval.end, end, flags)) { dig = 4; digit_end = m_digit_4->interval.end; }
+
2670 else if (m_digit_5->match(text, this->interval.end, end, flags)) { dig = 5; digit_end = m_digit_5->interval.end; }
+
2671 else if (m_digit_6->match(text, this->interval.end, end, flags)) { dig = 6; digit_end = m_digit_6->interval.end; }
+
2672 else if (m_digit_7->match(text, this->interval.end, end, flags)) { dig = 7; digit_end = m_digit_7->interval.end; }
+
2673 else if (m_digit_8->match(text, this->interval.end, end, flags)) { dig = 8; digit_end = m_digit_8->interval.end; }
+
2674 else if (m_digit_9->match(text, this->interval.end, end, flags)) { dig = 9; digit_end = m_digit_9->interval.end; }
+
2675 else if (m_digit_10->match(text, this->interval.end, end, flags)) { dig = 10; digit_end = m_digit_10->interval.end; }
+
2676 else if (m_digit_11->match(text, this->interval.end, end, flags)) { dig = 11; digit_end = m_digit_11->interval.end; }
+
2677 else if (m_digit_12->match(text, this->interval.end, end, flags)) { dig = 12; digit_end = m_digit_12->interval.end; }
+
2678 else if (m_digit_13->match(text, this->interval.end, end, flags)) { dig = 13; digit_end = m_digit_13->interval.end; }
+
2679 else if (m_digit_14->match(text, this->interval.end, end, flags)) { dig = 14; digit_end = m_digit_14->interval.end; }
+
2680 else if (m_digit_15->match(text, this->interval.end, end, flags)) { dig = 15; digit_end = m_digit_15->interval.end; }
+
2681 else break;
+
2682 size_t x_n = x * 16 + dig;
+
2683 if (x_n <= 0xffff) {
+
2684 x = x_n;
+
2685 this->interval.end = digit_end;
+
2686 is_empty = false;
+
2687 }
+
2688 else
+
2689 break;
+
2690 }
+
2691 if (is_empty) {
+
2692 if (compaction_i != (size_t)-1) {
+
2693 // Zero compaction active: no sweat.
+
2694 break;
+
2695 }
+
2696 goto error;
+
2697 }
+
2698 components[i].end = this->interval.end;
+
2699 this->value.s6_words[i] = (uint16_t)x;
+
2700 }
+
2701
+
2702 if (compaction_i != (size_t)-1) {
+
2703 // Align components right due to zero compaction.
+
2704 size_t j, k;
+
2705 for (j = 8, k = i; k > compaction_i;) {
+
2706 this->value.s6_words[--j] = this->value.s6_words[--k];
+ +
2708 }
+
2709 for (; j > compaction_i;) {
+
2710 this->value.s6_words[--j] = 0;
+
2711 components[j].start =
+ +
2713 }
+
2714 }
+
2715 else if (i < 8)
+
2716 goto error;
+
2717
+
2718 if (m_scope_id_separator && m_scope_id_separator->match(text, this->interval.end, end, flags) &&
+
2719 scope_id && scope_id->match(text, m_scope_id_separator->interval.end, end, flags))
+
2720 this->interval.end = scope_id->interval.end;
+
2721 else if (scope_id)
+
2722 scope_id->invalidate();
+
2723
+
2724 this->interval.start = start;
+
2725 return true;
+
2726
+
2727 error:
+
2728 components[0].start = 1;
+
2729 components[0].end = 0;
+
2730 components[1].start = 1;
+
2731 components[1].end = 0;
+
2732 components[2].start = 1;
+
2733 components[2].end = 0;
+
2734 components[3].start = 1;
+
2735 components[3].end = 0;
+
2736 components[4].start = 1;
+
2737 components[4].end = 0;
+
2738 components[5].start = 1;
+
2739 components[5].end = 0;
+
2740 components[6].start = 1;
+
2741 components[6].end = 0;
+
2742 components[7].start = 1;
+
2743 components[7].end = 0;
+
2744 memset(&value, 0, sizeof(value));
+
2745 if (scope_id) scope_id->invalidate();
+
2746 this->interval.start = (this->interval.end = start) + 1;
+
2747 return false;
+
2748 }
+
2749
+
2750 virtual void invalidate()
+
2751 {
+
2752 components[0].start = 1;
+
2753 components[0].end = 0;
+
2754 components[1].start = 1;
+
2755 components[1].end = 0;
+
2756 components[2].start = 1;
+
2757 components[2].end = 0;
+
2758 components[3].start = 1;
+
2759 components[3].end = 0;
+
2760 components[4].start = 1;
+
2761 components[4].end = 0;
+
2762 components[5].start = 1;
+
2763 components[5].end = 0;
+
2764 components[6].start = 1;
+
2765 components[6].end = 0;
+
2766 components[7].start = 1;
+
2767 components[7].end = 0;
+
2768 memset(&value, 0, sizeof(value));
+
2769 if (scope_id) scope_id->invalidate();
+ +
2771 }
+
2772
+
2773 public:
+ + +
2776 std::shared_ptr<basic_parser<T>> scope_id;
+
2777
+
2778 protected:
+
2779 std::shared_ptr<basic_parser<T>>
+
2780 m_digit_0,
+
2781 m_digit_1,
+
2782 m_digit_2,
+
2783 m_digit_3,
+
2784 m_digit_4,
+
2785 m_digit_5,
+
2786 m_digit_6,
+
2787 m_digit_7,
+
2788 m_digit_8,
+
2789 m_digit_9,
+
2790 m_digit_10,
+
2791 m_digit_11,
+
2792 m_digit_12,
+
2793 m_digit_13,
+
2794 m_digit_14,
+
2795 m_digit_15;
+
2796 std::shared_ptr<basic_parser<T>> m_separator, m_scope_id_separator;
+
2797 };
-
2799
- - -
2802#ifdef _UNICODE
- -
2804#else
- -
2806#endif
- -
2808
-
2812 template <class T>
-
- -
2814 {
-
2815 public:
- -
2817 _In_ bool allow_idn,
-
2818 _In_ const std::locale& locale = std::locale()) :
-
2819 basic_parser<T>(locale),
-
2820 m_allow_idn(allow_idn),
-
2821 allow_on_edge(true)
-
2822 {}
-
2823
-
2824 virtual bool match(
-
2825 _In_reads_or_z_(end) const T* text,
-
2826 _In_ size_t start = 0,
-
2827 _In_ size_t end = (size_t)-1,
-
2828 _In_ int flags = match_default)
-
2829 {
-
2830 _Assume_(text || start >= end);
-
2831 if (start < end && text[start]) {
-
2832 if (('A' <= text[start] && text[start] <= 'Z') ||
-
2833 ('a' <= text[start] && text[start] <= 'z') ||
-
2834 ('0' <= text[start] && text[start] <= '9'))
-
2835 allow_on_edge = true;
-
2836 else if (text[start] == '-')
-
2837 allow_on_edge = false;
-
2838 else if (m_allow_idn && std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
-
2839 allow_on_edge = true;
-
2840 else {
-
2841 this->interval.start = (this->interval.end = start) + 1;
-
2842 return false;
-
2843 }
-
2844 this->interval.end = (this->interval.start = start) + 1;
-
2845 return true;
-
2846 }
-
2847 this->interval.start = (this->interval.end = start) + 1;
-
2848 return false;
-
2849 }
-
2850
-
2851 public:
- -
2853
-
2854 protected:
-
2855 bool m_allow_idn;
-
2856 };
+
2798
+ + +
2801#ifdef _UNICODE
+ +
2803#else
+ +
2805#endif
+ +
2807
+
2811 template <class T>
+
+ +
2813 {
+
2814 public:
+ +
2816 _In_ bool allow_idn,
+
2817 _In_ const std::locale& locale = std::locale()) :
+
2818 basic_parser<T>(locale),
+
2819 m_allow_idn(allow_idn),
+
2820 allow_on_edge(true)
+
2821 {}
+
2822
+
2823 virtual bool match(
+
2824 _In_reads_or_z_(end) const T* text,
+
2825 _In_ size_t start = 0,
+
2826 _In_ size_t end = (size_t)-1,
+
2827 _In_ int flags = match_default)
+
2828 {
+
2829 _Assume_(text || start >= end);
+
2830 if (start < end && text[start]) {
+
2831 if (('A' <= text[start] && text[start] <= 'Z') ||
+
2832 ('a' <= text[start] && text[start] <= 'z') ||
+
2833 ('0' <= text[start] && text[start] <= '9'))
+
2834 allow_on_edge = true;
+
2835 else if (text[start] == '-')
+
2836 allow_on_edge = false;
+
2837 else if (m_allow_idn && std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
+
2838 allow_on_edge = true;
+
2839 else {
+
2840 this->interval.start = (this->interval.end = start) + 1;
+
2841 return false;
+
2842 }
+
2843 this->interval.end = (this->interval.start = start) + 1;
+
2844 return true;
+
2845 }
+
2846 this->interval.start = (this->interval.end = start) + 1;
+
2847 return false;
+
2848 }
+
2849
+
2850 public:
+ +
2852
+
2853 protected:
+
2854 bool m_allow_idn;
+
2855 };
-
2857
- - -
2860#ifdef _UNICODE
- -
2862#else
- -
2864#endif
-
2865
-
- -
2870 {
-
2871 public:
- -
2873 _In_ bool allow_idn,
-
2874 _In_ const std::locale& locale = std::locale()) :
- -
2876 {}
-
2877
-
2878 virtual bool match(
-
2879 _In_reads_or_z_(end) const char* text,
-
2880 _In_ size_t start = 0,
-
2881 _In_ size_t end = (size_t)-1,
-
2882 _In_ int flags = match_default)
-
2883 {
-
2884 _Assume_(text || start >= end);
-
2885 if (start < end && text[start]) {
-
2886 wchar_t buf[3];
-
2887 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
-
2888 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
2889 if ((('A' <= chr[0] && chr[0] <= 'Z') ||
-
2890 ('a' <= chr[0] && chr[0] <= 'z') ||
-
2891 ('0' <= chr[0] && chr[0] <= '9')) && chr[1] == 0)
-
2892 allow_on_edge = true;
-
2893 else if (chr[0] == '-' && chr[1] == 0)
-
2894 allow_on_edge = false;
-
2895 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)
-
2896 allow_on_edge = true;
-
2897 else {
-
2898 this->interval.start = (this->interval.end = start) + 1;
-
2899 return false;
-
2900 }
-
2901 this->interval.start = start;
-
2902 return true;
-
2903 }
-
2904 this->interval.start = (this->interval.end = start) + 1;
-
2905 return false;
-
2906 }
-
2907 };
+
2856
+ + +
2859#ifdef _UNICODE
+ +
2861#else
+ +
2863#endif
+
2864
+
+ +
2869 {
+
2870 public:
+ +
2872 _In_ bool allow_idn,
+
2873 _In_ const std::locale& locale = std::locale()) :
+ +
2875 {}
+
2876
+
2877 virtual bool match(
+
2878 _In_reads_or_z_(end) const char* text,
+
2879 _In_ size_t start = 0,
+
2880 _In_ size_t end = (size_t)-1,
+
2881 _In_ int flags = match_default)
+
2882 {
+
2883 _Assume_(text || start >= end);
+
2884 if (start < end && text[start]) {
+
2885 wchar_t buf[3];
+
2886 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
+
2887 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
2888 if ((('A' <= chr[0] && chr[0] <= 'Z') ||
+
2889 ('a' <= chr[0] && chr[0] <= 'z') ||
+
2890 ('0' <= chr[0] && chr[0] <= '9')) && chr[1] == 0)
+
2891 allow_on_edge = true;
+
2892 else if (chr[0] == '-' && chr[1] == 0)
+
2893 allow_on_edge = false;
+
2894 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)
+
2895 allow_on_edge = true;
+
2896 else {
+
2897 this->interval.start = (this->interval.end = start) + 1;
+
2898 return false;
+
2899 }
+
2900 this->interval.start = start;
+
2901 return true;
+
2902 }
+
2903 this->interval.start = (this->interval.end = start) + 1;
+
2904 return false;
+
2905 }
+
2906 };
-
2908
-
2912 template <class T>
-
- -
2914 {
-
2915 public:
- -
2917 _In_ bool allow_absolute,
-
2918 _In_ const std::shared_ptr<basic_dns_domain_char<T>>& domain_char,
-
2919 _In_ const std::shared_ptr<basic_parser<T>>& separator,
-
2920 _In_ const std::locale& locale = std::locale()) :
-
2921 basic_parser<T>(locale),
- -
2923 m_domain_char(domain_char),
-
2924 m_separator(separator)
-
2925 {}
-
2926
-
2927 virtual bool match(
-
2928 _In_reads_or_z_(end) const T* text,
-
2929 _In_ size_t start = 0,
-
2930 _In_ size_t end = (size_t)-1,
-
2931 _In_ int flags = match_default)
-
2932 {
-
2933 _Assume_(text || start >= end);
-
2934 size_t i = start, count;
-
2935 for (count = 0; i < end && text[i] && count < 127; count++) {
-
2936 if (m_domain_char->match(text, i, end, flags) &&
-
2937 m_domain_char->allow_on_edge)
-
2938 {
-
2939 // Domain start
-
2940 this->interval.end = i = m_domain_char->interval.end;
-
2941 while (i < end && text[i]) {
-
2942 if (m_domain_char->allow_on_edge &&
-
2943 m_separator->match(text, i, end, flags))
-
2944 {
-
2945 // Domain end
-
2946 if (m_allow_absolute)
-
2947 this->interval.end = i = m_separator->interval.end;
-
2948 else {
-
2949 this->interval.end = i;
-
2950 i = m_separator->interval.end;
-
2951 }
-
2952 break;
-
2953 }
-
2954 if (m_domain_char->match(text, i, end, flags)) {
-
2955 if (m_domain_char->allow_on_edge)
-
2956 this->interval.end = i = m_domain_char->interval.end;
-
2957 else
-
2958 i = m_domain_char->interval.end;
-
2959 }
-
2960 else {
-
2961 this->interval.start = start;
-
2962 return true;
-
2963 }
-
2964 }
-
2965 }
-
2966 else
-
2967 break;
-
2968 }
-
2969 if (count) {
-
2970 this->interval.start = start;
-
2971 return true;
-
2972 }
-
2973 this->interval.start = (this->interval.end = start) + 1;
-
2974 return false;
-
2975 }
-
2976
-
2977 protected:
- -
2979 std::shared_ptr<basic_dns_domain_char<T>> m_domain_char;
-
2980 std::shared_ptr<basic_parser<T>> m_separator;
-
2981 };
+
2907
+
2911 template <class T>
+
+ +
2913 {
+
2914 public:
+ +
2916 _In_ bool allow_absolute,
+
2917 _In_ const std::shared_ptr<basic_dns_domain_char<T>>& domain_char,
+
2918 _In_ const std::shared_ptr<basic_parser<T>>& separator,
+
2919 _In_ const std::locale& locale = std::locale()) :
+
2920 basic_parser<T>(locale),
+ +
2922 m_domain_char(domain_char),
+
2923 m_separator(separator)
+
2924 {}
+
2925
+
2926 virtual bool match(
+
2927 _In_reads_or_z_(end) const T* text,
+
2928 _In_ size_t start = 0,
+
2929 _In_ size_t end = (size_t)-1,
+
2930 _In_ int flags = match_default)
+
2931 {
+
2932 _Assume_(text || start >= end);
+
2933 size_t i = start, count;
+
2934 for (count = 0; i < end && text[i] && count < 127; count++) {
+
2935 if (m_domain_char->match(text, i, end, flags) &&
+
2936 m_domain_char->allow_on_edge)
+
2937 {
+
2938 // Domain start
+
2939 this->interval.end = i = m_domain_char->interval.end;
+
2940 while (i < end && text[i]) {
+
2941 if (m_domain_char->allow_on_edge &&
+
2942 m_separator->match(text, i, end, flags))
+
2943 {
+
2944 // Domain end
+
2945 if (m_allow_absolute)
+
2946 this->interval.end = i = m_separator->interval.end;
+
2947 else {
+
2948 this->interval.end = i;
+
2949 i = m_separator->interval.end;
+
2950 }
+
2951 break;
+
2952 }
+
2953 if (m_domain_char->match(text, i, end, flags)) {
+
2954 if (m_domain_char->allow_on_edge)
+
2955 this->interval.end = i = m_domain_char->interval.end;
+
2956 else
+
2957 i = m_domain_char->interval.end;
+
2958 }
+
2959 else {
+
2960 this->interval.start = start;
+
2961 return true;
+
2962 }
+
2963 }
+
2964 }
+
2965 else
+
2966 break;
+
2967 }
+
2968 if (count) {
+
2969 this->interval.start = start;
+
2970 return true;
+
2971 }
+
2972 this->interval.start = (this->interval.end = start) + 1;
+
2973 return false;
+
2974 }
+
2975
+
2976 protected:
+ +
2978 std::shared_ptr<basic_dns_domain_char<T>> m_domain_char;
+
2979 std::shared_ptr<basic_parser<T>> m_separator;
+
2980 };
-
2982
- - -
2985#ifdef _UNICODE
-
2986 using tdns_name = wdns_name;
-
2987#else
-
2988 using tdns_name = dns_name;
-
2989#endif
- -
2991
-
2995 template <class T>
-
- -
2997 {
-
2998 public:
-
2999 basic_url_username_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
-
3000
-
3001 virtual bool match(
-
3002 _In_reads_or_z_(end) const T* text,
-
3003 _In_ size_t start = 0,
-
3004 _In_ size_t end = (size_t)-1,
-
3005 _In_ int flags = match_default)
-
3006 {
-
3007 _Assume_(text || start >= end);
-
3008 if (start < end && text[start]) {
-
3009 if (text[start] == '-' ||
-
3010 text[start] == '.' ||
-
3011 text[start] == '_' ||
-
3012 text[start] == '~' ||
-
3013 text[start] == '%' ||
-
3014 text[start] == '!' ||
-
3015 text[start] == '$' ||
-
3016 text[start] == '&' ||
-
3017 text[start] == '\'' ||
-
3018 //text[start] == '(' ||
-
3019 //text[start] == ')' ||
-
3020 text[start] == '*' ||
-
3021 text[start] == '+' ||
-
3022 text[start] == ',' ||
-
3023 text[start] == ';' ||
-
3024 text[start] == '=' ||
-
3025 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
-
3026 {
-
3027 this->interval.end = (this->interval.start = start) + 1;
-
3028 return true;
-
3029 }
-
3030 }
-
3031 this->interval.start = (this->interval.end = start) + 1;
-
3032 return false;
-
3033 }
-
3034 };
+
2981
+ + +
2984#ifdef _UNICODE
+
2985 using tdns_name = wdns_name;
+
2986#else
+
2987 using tdns_name = dns_name;
+
2988#endif
+ +
2990
+
2994 template <class T>
+
+ +
2996 {
+
2997 public:
+
2998 basic_url_username_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
+
2999
+
3000 virtual bool match(
+
3001 _In_reads_or_z_(end) const T* text,
+
3002 _In_ size_t start = 0,
+
3003 _In_ size_t end = (size_t)-1,
+
3004 _In_ int flags = match_default)
+
3005 {
+
3006 _Assume_(text || start >= end);
+
3007 if (start < end && text[start]) {
+
3008 if (text[start] == '-' ||
+
3009 text[start] == '.' ||
+
3010 text[start] == '_' ||
+
3011 text[start] == '~' ||
+
3012 text[start] == '%' ||
+
3013 text[start] == '!' ||
+
3014 text[start] == '$' ||
+
3015 text[start] == '&' ||
+
3016 text[start] == '\'' ||
+
3017 //text[start] == '(' ||
+
3018 //text[start] == ')' ||
+
3019 text[start] == '*' ||
+
3020 text[start] == '+' ||
+
3021 text[start] == ',' ||
+
3022 text[start] == ';' ||
+
3023 text[start] == '=' ||
+
3024 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
+
3025 {
+
3026 this->interval.end = (this->interval.start = start) + 1;
+
3027 return true;
+
3028 }
+
3029 }
+
3030 this->interval.start = (this->interval.end = start) + 1;
+
3031 return false;
+
3032 }
+
3033 };
-
3035
- - -
3038#ifdef _UNICODE
- -
3040#else
- -
3042#endif
-
3043
-
- -
3048 {
-
3049 public:
-
3050 sgml_url_username_char(_In_ const std::locale& locale = std::locale()) : basic_url_username_char<char>(locale) {}
-
3051
-
3052 virtual bool match(
-
3053 _In_reads_or_z_(end) const char* text,
-
3054 _In_ size_t start = 0,
-
3055 _In_ size_t end = (size_t)-1,
-
3056 _In_ int flags = match_default)
-
3057 {
-
3058 _Assume_(text || start >= end);
-
3059 if (start < end && text[start]) {
-
3060 wchar_t buf[3];
-
3061 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
-
3062 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
3063 if (((chr[0] == L'-' ||
-
3064 chr[0] == L'.' ||
-
3065 chr[0] == L'_' ||
-
3066 chr[0] == L'~' ||
-
3067 chr[0] == L'%' ||
-
3068 chr[0] == L'!' ||
-
3069 chr[0] == L'$' ||
-
3070 chr[0] == L'&' ||
-
3071 chr[0] == L'\'' ||
-
3072 //chr[0] == L'(' ||
-
3073 //chr[0] == L')' ||
-
3074 chr[0] == L'*' ||
-
3075 chr[0] == L'+' ||
-
3076 chr[0] == L',' ||
-
3077 chr[0] == L';' ||
-
3078 chr[0] == L'=') && chr[1] == 0) ||
-
3079 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
-
3080 {
-
3081 this->interval.start = start;
-
3082 return true;
-
3083 }
-
3084 }
-
3085
-
3086 this->interval.start = (this->interval.end = start) + 1;
-
3087 return false;
-
3088 }
-
3089 };
+
3034
+ + +
3037#ifdef _UNICODE
+ +
3039#else
+ +
3041#endif
+
3042
+
+ +
3047 {
+
3048 public:
+
3049 sgml_url_username_char(_In_ const std::locale& locale = std::locale()) : basic_url_username_char<char>(locale) {}
+
3050
+
3051 virtual bool match(
+
3052 _In_reads_or_z_(end) const char* text,
+
3053 _In_ size_t start = 0,
+
3054 _In_ size_t end = (size_t)-1,
+
3055 _In_ int flags = match_default)
+
3056 {
+
3057 _Assume_(text || start >= end);
+
3058 if (start < end && text[start]) {
+
3059 wchar_t buf[3];
+
3060 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
+
3061 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
3062 if (((chr[0] == L'-' ||
+
3063 chr[0] == L'.' ||
+
3064 chr[0] == L'_' ||
+
3065 chr[0] == L'~' ||
+
3066 chr[0] == L'%' ||
+
3067 chr[0] == L'!' ||
+
3068 chr[0] == L'$' ||
+
3069 chr[0] == L'&' ||
+
3070 chr[0] == L'\'' ||
+
3071 //chr[0] == L'(' ||
+
3072 //chr[0] == L')' ||
+
3073 chr[0] == L'*' ||
+
3074 chr[0] == L'+' ||
+
3075 chr[0] == L',' ||
+
3076 chr[0] == L';' ||
+
3077 chr[0] == L'=') && chr[1] == 0) ||
+
3078 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
+
3079 {
+
3080 this->interval.start = start;
+
3081 return true;
+
3082 }
+
3083 }
+
3084
+
3085 this->interval.start = (this->interval.end = start) + 1;
+
3086 return false;
+
3087 }
+
3088 };
-
3090
-
3094 template <class T>
-
- -
3096 {
-
3097 public:
-
3098 basic_url_password_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
-
3099
-
3100 virtual bool match(
-
3101 _In_reads_or_z_(end) const T* text,
-
3102 _In_ size_t start = 0,
-
3103 _In_ size_t end = (size_t)-1,
-
3104 _In_ int flags = match_default)
-
3105 {
-
3106 _Assume_(text || start >= end);
-
3107 if (start < end && text[start]) {
-
3108 if (text[start] == '-' ||
-
3109 text[start] == '.' ||
-
3110 text[start] == '_' ||
-
3111 text[start] == '~' ||
-
3112 text[start] == '%' ||
-
3113 text[start] == '!' ||
-
3114 text[start] == '$' ||
-
3115 text[start] == '&' ||
-
3116 text[start] == '\'' ||
-
3117 text[start] == '(' ||
-
3118 text[start] == ')' ||
-
3119 text[start] == '*' ||
-
3120 text[start] == '+' ||
-
3121 text[start] == ',' ||
-
3122 text[start] == ';' ||
-
3123 text[start] == '=' ||
-
3124 text[start] == ':' ||
-
3125 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
-
3126 {
-
3127 this->interval.end = (this->interval.start = start) + 1;
-
3128 return true;
-
3129 }
-
3130 }
-
3131 this->interval.start = (this->interval.end = start) + 1;
-
3132 return false;
-
3133 }
-
3134 };
+
3089
+
3093 template <class T>
+
+ +
3095 {
+
3096 public:
+
3097 basic_url_password_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
+
3098
+
3099 virtual bool match(
+
3100 _In_reads_or_z_(end) const T* text,
+
3101 _In_ size_t start = 0,
+
3102 _In_ size_t end = (size_t)-1,
+
3103 _In_ int flags = match_default)
+
3104 {
+
3105 _Assume_(text || start >= end);
+
3106 if (start < end && text[start]) {
+
3107 if (text[start] == '-' ||
+
3108 text[start] == '.' ||
+
3109 text[start] == '_' ||
+
3110 text[start] == '~' ||
+
3111 text[start] == '%' ||
+
3112 text[start] == '!' ||
+
3113 text[start] == '$' ||
+
3114 text[start] == '&' ||
+
3115 text[start] == '\'' ||
+
3116 text[start] == '(' ||
+
3117 text[start] == ')' ||
+
3118 text[start] == '*' ||
+
3119 text[start] == '+' ||
+
3120 text[start] == ',' ||
+
3121 text[start] == ';' ||
+
3122 text[start] == '=' ||
+
3123 text[start] == ':' ||
+
3124 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
+
3125 {
+
3126 this->interval.end = (this->interval.start = start) + 1;
+
3127 return true;
+
3128 }
+
3129 }
+
3130 this->interval.start = (this->interval.end = start) + 1;
+
3131 return false;
+
3132 }
+
3133 };
-
3135
- - -
3138#ifdef _UNICODE
- -
3140#else
- -
3142#endif
-
3143
-
- -
3148 {
-
3149 public:
-
3150 sgml_url_password_char(_In_ const std::locale& locale = std::locale()) : basic_url_password_char<char>(locale) {}
-
3151
-
3152 virtual bool match(
-
3153 _In_reads_or_z_(end) const char* text,
-
3154 _In_ size_t start = 0,
-
3155 _In_ size_t end = (size_t)-1,
-
3156 _In_ int flags = match_default)
-
3157 {
-
3158 _Assume_(text || start >= end);
-
3159 if (start < end && text[start]) {
-
3160 wchar_t buf[3];
-
3161 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
-
3162 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
3163 if (((chr[0] == L'-' ||
-
3164 chr[0] == L'.' ||
-
3165 chr[0] == L'_' ||
-
3166 chr[0] == L'~' ||
-
3167 chr[0] == L'%' ||
-
3168 chr[0] == L'!' ||
-
3169 chr[0] == L'$' ||
-
3170 chr[0] == L'&' ||
-
3171 chr[0] == L'\'' ||
-
3172 chr[0] == L'(' ||
-
3173 chr[0] == L')' ||
-
3174 chr[0] == L'*' ||
-
3175 chr[0] == L'+' ||
-
3176 chr[0] == L',' ||
-
3177 chr[0] == L';' ||
-
3178 chr[0] == L'=' ||
-
3179 chr[0] == L':') && chr[1] == 0) ||
-
3180 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
-
3181 {
-
3182 this->interval.start = start;
-
3183 return true;
-
3184 }
-
3185 }
-
3186 this->interval.start = (this->interval.end = start) + 1;
-
3187 return false;
-
3188 }
-
3189 };
+
3134
+ + +
3137#ifdef _UNICODE
+ +
3139#else
+ +
3141#endif
+
3142
+
+ +
3147 {
+
3148 public:
+
3149 sgml_url_password_char(_In_ const std::locale& locale = std::locale()) : basic_url_password_char<char>(locale) {}
+
3150
+
3151 virtual bool match(
+
3152 _In_reads_or_z_(end) const char* text,
+
3153 _In_ size_t start = 0,
+
3154 _In_ size_t end = (size_t)-1,
+
3155 _In_ int flags = match_default)
+
3156 {
+
3157 _Assume_(text || start >= end);
+
3158 if (start < end && text[start]) {
+
3159 wchar_t buf[3];
+
3160 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
+
3161 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
3162 if (((chr[0] == L'-' ||
+
3163 chr[0] == L'.' ||
+
3164 chr[0] == L'_' ||
+
3165 chr[0] == L'~' ||
+
3166 chr[0] == L'%' ||
+
3167 chr[0] == L'!' ||
+
3168 chr[0] == L'$' ||
+
3169 chr[0] == L'&' ||
+
3170 chr[0] == L'\'' ||
+
3171 chr[0] == L'(' ||
+
3172 chr[0] == L')' ||
+
3173 chr[0] == L'*' ||
+
3174 chr[0] == L'+' ||
+
3175 chr[0] == L',' ||
+
3176 chr[0] == L';' ||
+
3177 chr[0] == L'=' ||
+
3178 chr[0] == L':') && chr[1] == 0) ||
+
3179 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
+
3180 {
+
3181 this->interval.start = start;
+
3182 return true;
+
3183 }
+
3184 }
+
3185 this->interval.start = (this->interval.end = start) + 1;
+
3186 return false;
+
3187 }
+
3188 };
-
3190
-
3194 template <class T>
-
- -
3196 {
-
3197 public:
-
3198 basic_url_path_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
-
3199
-
3200 virtual bool match(
-
3201 _In_reads_or_z_(end) const T* text,
-
3202 _In_ size_t start = 0,
-
3203 _In_ size_t end = (size_t)-1,
-
3204 _In_ int flags = match_default)
-
3205 {
-
3206 _Assume_(text || start >= end);
-
3207 if (start < end && text[start]) {
-
3208 if (text[start] == '/' ||
-
3209 text[start] == '-' ||
-
3210 text[start] == '.' ||
-
3211 text[start] == '_' ||
-
3212 text[start] == '~' ||
-
3213 text[start] == '%' ||
-
3214 text[start] == '!' ||
-
3215 text[start] == '$' ||
-
3216 text[start] == '&' ||
-
3217 text[start] == '\'' ||
-
3218 text[start] == '(' ||
-
3219 text[start] == ')' ||
-
3220 text[start] == '*' ||
-
3221 text[start] == '+' ||
-
3222 text[start] == ',' ||
-
3223 text[start] == ';' ||
-
3224 text[start] == '=' ||
-
3225 text[start] == ':' ||
-
3226 text[start] == '@' ||
-
3227 text[start] == '?' ||
-
3228 text[start] == '#' ||
-
3229 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
-
3230 {
-
3231 this->interval.end = (this->interval.start = start) + 1;
-
3232 return true;
-
3233 }
-
3234 }
-
3235 this->interval.start = (this->interval.end = start) + 1;
-
3236 return false;
-
3237 }
-
3238 };
+
3189
+
3193 template <class T>
+
+ +
3195 {
+
3196 public:
+
3197 basic_url_path_char(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
+
3198
+
3199 virtual bool match(
+
3200 _In_reads_or_z_(end) const T* text,
+
3201 _In_ size_t start = 0,
+
3202 _In_ size_t end = (size_t)-1,
+
3203 _In_ int flags = match_default)
+
3204 {
+
3205 _Assume_(text || start >= end);
+
3206 if (start < end && text[start]) {
+
3207 if (text[start] == '/' ||
+
3208 text[start] == '-' ||
+
3209 text[start] == '.' ||
+
3210 text[start] == '_' ||
+
3211 text[start] == '~' ||
+
3212 text[start] == '%' ||
+
3213 text[start] == '!' ||
+
3214 text[start] == '$' ||
+
3215 text[start] == '&' ||
+
3216 text[start] == '\'' ||
+
3217 text[start] == '(' ||
+
3218 text[start] == ')' ||
+
3219 text[start] == '*' ||
+
3220 text[start] == '+' ||
+
3221 text[start] == ',' ||
+
3222 text[start] == ';' ||
+
3223 text[start] == '=' ||
+
3224 text[start] == ':' ||
+
3225 text[start] == '@' ||
+
3226 text[start] == '?' ||
+
3227 text[start] == '#' ||
+
3228 std::use_facet<std::ctype<T>>(this->m_locale).is(std::ctype_base::alnum, text[start]))
+
3229 {
+
3230 this->interval.end = (this->interval.start = start) + 1;
+
3231 return true;
+
3232 }
+
3233 }
+
3234 this->interval.start = (this->interval.end = start) + 1;
+
3235 return false;
+
3236 }
+
3237 };
-
3239
- - -
3242#ifdef _UNICODE
- -
3244#else
- -
3246#endif
-
3247
-
- -
3252 {
-
3253 public:
-
3254 sgml_url_path_char(_In_ const std::locale& locale = std::locale()) : basic_url_path_char<char>(locale) {}
-
3255
-
3256 virtual bool match(
-
3257 _In_reads_or_z_(end) const char* text,
-
3258 _In_ size_t start = 0,
-
3259 _In_ size_t end = (size_t)-1,
-
3260 _In_ int flags = match_default)
-
3261 {
-
3262 _Assume_(text || start >= end);
-
3263 if (start < end && text[start]) {
-
3264 wchar_t buf[3];
-
3265 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
-
3266 const wchar_t* chr_end = chr + stdex::strlen(chr);
-
3267 if (((chr[0] == L'/' ||
-
3268 chr[0] == L'-' ||
-
3269 chr[0] == L'.' ||
-
3270 chr[0] == L'_' ||
-
3271 chr[0] == L'~' ||
-
3272 chr[0] == L'%' ||
-
3273 chr[0] == L'!' ||
-
3274 chr[0] == L'$' ||
-
3275 chr[0] == L'&' ||
-
3276 chr[0] == L'\'' ||
-
3277 chr[0] == L'(' ||
-
3278 chr[0] == L')' ||
-
3279 chr[0] == L'*' ||
-
3280 chr[0] == L'+' ||
-
3281 chr[0] == L',' ||
-
3282 chr[0] == L';' ||
-
3283 chr[0] == L'=' ||
-
3284 chr[0] == L':' ||
-
3285 chr[0] == L'@' ||
-
3286 chr[0] == L'?' ||
-
3287 chr[0] == L'#') && chr[1] == 0) ||
-
3288 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
-
3289 {
-
3290 this->interval.start = start;
-
3291 return true;
-
3292 }
-
3293 }
-
3294 this->interval.start = (this->interval.end = start) + 1;
-
3295 return false;
-
3296 }
-
3297 };
+
3238
+ + +
3241#ifdef _UNICODE
+ +
3243#else
+ +
3245#endif
+
3246
+
+ +
3251 {
+
3252 public:
+
3253 sgml_url_path_char(_In_ const std::locale& locale = std::locale()) : basic_url_path_char<char>(locale) {}
+
3254
+
3255 virtual bool match(
+
3256 _In_reads_or_z_(end) const char* text,
+
3257 _In_ size_t start = 0,
+
3258 _In_ size_t end = (size_t)-1,
+
3259 _In_ int flags = match_default)
+
3260 {
+
3261 _Assume_(text || start >= end);
+
3262 if (start < end && text[start]) {
+
3263 wchar_t buf[3];
+
3264 const wchar_t* chr = next_sgml_cp(text, start, end, this->interval.end, buf);
+
3265 const wchar_t* chr_end = chr + stdex::strlen(chr);
+
3266 if (((chr[0] == L'/' ||
+
3267 chr[0] == L'-' ||
+
3268 chr[0] == L'.' ||
+
3269 chr[0] == L'_' ||
+
3270 chr[0] == L'~' ||
+
3271 chr[0] == L'%' ||
+
3272 chr[0] == L'!' ||
+
3273 chr[0] == L'$' ||
+
3274 chr[0] == L'&' ||
+
3275 chr[0] == L'\'' ||
+
3276 chr[0] == L'(' ||
+
3277 chr[0] == L')' ||
+
3278 chr[0] == L'*' ||
+
3279 chr[0] == L'+' ||
+
3280 chr[0] == L',' ||
+
3281 chr[0] == L';' ||
+
3282 chr[0] == L'=' ||
+
3283 chr[0] == L':' ||
+
3284 chr[0] == L'@' ||
+
3285 chr[0] == L'?' ||
+
3286 chr[0] == L'#') && chr[1] == 0) ||
+
3287 std::use_facet<std::ctype<wchar_t>>(m_locale).scan_not(std::ctype_base::alnum, chr, chr_end) == chr_end)
+
3288 {
+
3289 this->interval.start = start;
+
3290 return true;
+
3291 }
+
3292 }
+
3293 this->interval.start = (this->interval.end = start) + 1;
+
3294 return false;
+
3295 }
+
3296 };
-
3298
-
3302 template <class T>
-
- -
3304 {
-
3305 public:
- -
3307 _In_ const std::shared_ptr<basic_parser<T>>& path_char,
-
3308 _In_ const std::shared_ptr<basic_parser<T>>& query_start,
-
3309 _In_ const std::shared_ptr<basic_parser<T>>& bookmark_start,
-
3310 _In_ const std::locale& locale = std::locale()) :
-
3311 basic_parser<T>(locale),
-
3312 m_path_char(path_char),
-
3313 m_query_start(query_start),
-
3314 m_bookmark_start(bookmark_start)
-
3315 {}
-
3316
-
3317 virtual bool match(
-
3318 _In_reads_or_z_(end) const T* text,
-
3319 _In_ size_t start = 0,
-
3320 _In_ size_t end = (size_t)-1,
-
3321 _In_ int flags = match_default)
-
3322 {
-
3323 _Assume_(text || start >= end);
-
3324
-
3325 this->interval.end = start;
-
3326 path.start = start;
-
3327 query.start = 1;
-
3328 query.end = 0;
-
3329 bookmark.start = 1;
-
3330 bookmark.end = 0;
-
3331
-
3332 for (;;) {
-
3333 if (this->interval.end >= end || !text[this->interval.end])
-
3334 break;
-
3335 if (m_query_start->match(text, this->interval.end, end, flags)) {
-
3336 path.end = this->interval.end;
-
3337 query.start = this->interval.end = m_query_start->interval.end;
-
3338 for (;;) {
-
3339 if (this->interval.end >= end || !text[this->interval.end]) {
-
3340 query.end = this->interval.end;
-
3341 break;
-
3342 }
-
3343 if (m_bookmark_start->match(text, this->interval.end, end, flags)) {
-
3344 query.end = this->interval.end;
-
3345 bookmark.start = this->interval.end = m_bookmark_start->interval.end;
-
3346 for (;;) {
-
3347 if (this->interval.end >= end || !text[this->interval.end]) {
-
3348 bookmark.end = this->interval.end;
-
3349 break;
-
3350 }
-
3351 if (m_path_char->match(text, this->interval.end, end, flags))
-
3352 this->interval.end = m_path_char->interval.end;
-
3353 else {
-
3354 bookmark.end = this->interval.end;
-
3355 break;
-
3356 }
-
3357 }
-
3358 this->interval.start = start;
-
3359 return true;
-
3360 }
-
3361 if (m_path_char->match(text, this->interval.end, end, flags))
-
3362 this->interval.end = m_path_char->interval.end;
-
3363 else {
-
3364 query.end = this->interval.end;
-
3365 break;
-
3366 }
-
3367 }
-
3368 this->interval.start = start;
-
3369 return true;
-
3370 }
-
3371 if (m_bookmark_start->match(text, this->interval.end, end, flags)) {
-
3372 path.end = this->interval.end;
-
3373 bookmark.start = this->interval.end = m_bookmark_start->interval.end;
-
3374 for (;;) {
-
3375 if (this->interval.end >= end || !text[this->interval.end]) {
-
3376 bookmark.end = this->interval.end;
-
3377 break;
-
3378 }
-
3379 if (m_path_char->match(text, this->interval.end, end, flags))
-
3380 this->interval.end = m_path_char->interval.end;
-
3381 else {
-
3382 bookmark.end = this->interval.end;
-
3383 break;
-
3384 }
-
3385 }
-
3386 this->interval.start = start;
-
3387 return true;
-
3388 }
-
3389 if (m_path_char->match(text, this->interval.end, end, flags))
-
3390 this->interval.end = m_path_char->interval.end;
-
3391 else
-
3392 break;
-
3393 }
-
3394
- -
3396 path.end = this->interval.end;
-
3397 this->interval.start = start;
-
3398 return true;
-
3399 }
-
3400
-
3401 path.start = 1;
-
3402 path.end = 0;
-
3403 bookmark.start = 1;
-
3404 bookmark.end = 0;
-
3405 this->interval.start = (this->interval.end = start) + 1;
-
3406 return false;
-
3407 }
-
3408
-
3409 virtual void invalidate()
-
3410 {
-
3411 path.start = 1;
-
3412 path.end = 0;
-
3413 query.start = 1;
-
3414 query.end = 0;
-
3415 bookmark.start = 1;
-
3416 bookmark.end = 0;
- -
3418 }
-
3419
-
3420 public:
- - -
3423 stdex::interval<size_t> bookmark;
-
3424
-
3425 protected:
-
3426 std::shared_ptr<basic_parser<T>> m_path_char;
-
3427 std::shared_ptr<basic_parser<T>> m_query_start;
-
3428 std::shared_ptr<basic_parser<T>> m_bookmark_start;
-
3429 };
+
3297
+
3301 template <class T>
+
+ +
3303 {
+
3304 public:
+ +
3306 _In_ const std::shared_ptr<basic_parser<T>>& path_char,
+
3307 _In_ const std::shared_ptr<basic_parser<T>>& query_start,
+
3308 _In_ const std::shared_ptr<basic_parser<T>>& bookmark_start,
+
3309 _In_ const std::locale& locale = std::locale()) :
+
3310 basic_parser<T>(locale),
+
3311 m_path_char(path_char),
+
3312 m_query_start(query_start),
+
3313 m_bookmark_start(bookmark_start)
+
3314 {}
+
3315
+
3316 virtual bool match(
+
3317 _In_reads_or_z_(end) const T* text,
+
3318 _In_ size_t start = 0,
+
3319 _In_ size_t end = (size_t)-1,
+
3320 _In_ int flags = match_default)
+
3321 {
+
3322 _Assume_(text || start >= end);
+
3323
+
3324 this->interval.end = start;
+
3325 path.start = start;
+
3326 query.start = 1;
+
3327 query.end = 0;
+
3328 bookmark.start = 1;
+
3329 bookmark.end = 0;
+
3330
+
3331 for (;;) {
+
3332 if (this->interval.end >= end || !text[this->interval.end])
+
3333 break;
+
3334 if (m_query_start->match(text, this->interval.end, end, flags)) {
+
3335 path.end = this->interval.end;
+
3336 query.start = this->interval.end = m_query_start->interval.end;
+
3337 for (;;) {
+
3338 if (this->interval.end >= end || !text[this->interval.end]) {
+
3339 query.end = this->interval.end;
+
3340 break;
+
3341 }
+
3342 if (m_bookmark_start->match(text, this->interval.end, end, flags)) {
+
3343 query.end = this->interval.end;
+
3344 bookmark.start = this->interval.end = m_bookmark_start->interval.end;
+
3345 for (;;) {
+
3346 if (this->interval.end >= end || !text[this->interval.end]) {
+
3347 bookmark.end = this->interval.end;
+
3348 break;
+
3349 }
+
3350 if (m_path_char->match(text, this->interval.end, end, flags))
+
3351 this->interval.end = m_path_char->interval.end;
+
3352 else {
+
3353 bookmark.end = this->interval.end;
+
3354 break;
+
3355 }
+
3356 }
+
3357 this->interval.start = start;
+
3358 return true;
+
3359 }
+
3360 if (m_path_char->match(text, this->interval.end, end, flags))
+
3361 this->interval.end = m_path_char->interval.end;
+
3362 else {
+
3363 query.end = this->interval.end;
+
3364 break;
+
3365 }
+
3366 }
+
3367 this->interval.start = start;
+
3368 return true;
+
3369 }
+
3370 if (m_bookmark_start->match(text, this->interval.end, end, flags)) {
+
3371 path.end = this->interval.end;
+
3372 bookmark.start = this->interval.end = m_bookmark_start->interval.end;
+
3373 for (;;) {
+
3374 if (this->interval.end >= end || !text[this->interval.end]) {
+
3375 bookmark.end = this->interval.end;
+
3376 break;
+
3377 }
+
3378 if (m_path_char->match(text, this->interval.end, end, flags))
+
3379 this->interval.end = m_path_char->interval.end;
+
3380 else {
+
3381 bookmark.end = this->interval.end;
+
3382 break;
+
3383 }
+
3384 }
+
3385 this->interval.start = start;
+
3386 return true;
+
3387 }
+
3388 if (m_path_char->match(text, this->interval.end, end, flags))
+
3389 this->interval.end = m_path_char->interval.end;
+
3390 else
+
3391 break;
+
3392 }
+
3393
+ +
3395 path.end = this->interval.end;
+
3396 this->interval.start = start;
+
3397 return true;
+
3398 }
+
3399
+
3400 path.start = 1;
+
3401 path.end = 0;
+
3402 bookmark.start = 1;
+
3403 bookmark.end = 0;
+
3404 this->interval.start = (this->interval.end = start) + 1;
+
3405 return false;
+
3406 }
+
3407
+
3408 virtual void invalidate()
+
3409 {
+
3410 path.start = 1;
+
3411 path.end = 0;
+
3412 query.start = 1;
+
3413 query.end = 0;
+
3414 bookmark.start = 1;
+
3415 bookmark.end = 0;
+ +
3417 }
+
3418
+
3419 public:
+ + +
3422 stdex::interval<size_t> bookmark;
+
3423
+
3424 protected:
+
3425 std::shared_ptr<basic_parser<T>> m_path_char;
+
3426 std::shared_ptr<basic_parser<T>> m_query_start;
+
3427 std::shared_ptr<basic_parser<T>> m_bookmark_start;
+
3428 };
-
3430
- - -
3433#ifdef _UNICODE
-
3434 using turl_path = wurl_path;
-
3435#else
-
3436 using turl_path = url_path;
-
3437#endif
- -
3439
-
3443 template <class T>
-
-
3444 class basic_url : public basic_parser<T>
-
3445 {
-
3446 public:
-
3447 basic_url(
-
3448 _In_ const std::shared_ptr<basic_parser<T>>& _http_scheme,
-
3449 _In_ const std::shared_ptr<basic_parser<T>>& _ftp_scheme,
-
3450 _In_ const std::shared_ptr<basic_parser<T>>& _mailto_scheme,
-
3451 _In_ const std::shared_ptr<basic_parser<T>>& _file_scheme,
-
3452 _In_ const std::shared_ptr<basic_parser<T>>& colon,
-
3453 _In_ const std::shared_ptr<basic_parser<T>>& slash,
-
3454 _In_ const std::shared_ptr<basic_parser<T>>& _username,
-
3455 _In_ const std::shared_ptr<basic_parser<T>>& _password,
-
3456 _In_ const std::shared_ptr<basic_parser<T>>& at,
-
3457 _In_ const std::shared_ptr<basic_parser<T>>& ip_lbracket,
-
3458 _In_ const std::shared_ptr<basic_parser<T>>& ip_rbracket,
-
3459 _In_ const std::shared_ptr<basic_parser<T>>& _ipv4_host,
-
3460 _In_ const std::shared_ptr<basic_parser<T>>& _ipv6_host,
-
3461 _In_ const std::shared_ptr<basic_parser<T>>& _dns_host,
-
3462 _In_ const std::shared_ptr<basic_parser<T>>& _port,
-
3463 _In_ const std::shared_ptr<basic_parser<T>>& _path,
-
3464 _In_ const std::locale& locale = std::locale()) :
-
3465 basic_parser<T>(locale),
-
3466 http_scheme(_http_scheme),
-
3467 ftp_scheme(_ftp_scheme),
-
3468 mailto_scheme(_mailto_scheme),
-
3469 file_scheme(_file_scheme),
-
3470 m_colon(colon),
-
3471 m_slash(slash),
-
3472 username(_username),
-
3473 password(_password),
-
3474 m_at(at),
-
3475 m_ip_lbracket(ip_lbracket),
-
3476 m_ip_rbracket(ip_rbracket),
-
3477 ipv4_host(_ipv4_host),
-
3478 ipv6_host(_ipv6_host),
-
3479 dns_host(_dns_host),
-
3480 port(_port),
-
3481 path(_path)
-
3482 {}
-
3483
-
3484 virtual bool match(
-
3485 _In_reads_or_z_(end) const T* text,
-
3486 _In_ size_t start = 0,
-
3487 _In_ size_t end = (size_t)-1,
-
3488 _In_ int flags = match_default)
-
3489 {
-
3490 _Assume_(text || start >= end);
-
3491
-
3492 this->interval.end = start;
-
3493
-
3494 if (http_scheme->match(text, this->interval.end, end, flags) &&
-
3495 m_colon->match(text, http_scheme->interval.end, end, flags) &&
-
3496 m_slash->match(text, m_colon->interval.end, end, flags) &&
-
3497 m_slash->match(text, m_slash->interval.end, end, flags))
-
3498 {
-
3499 // http://
-
3500 this->interval.end = m_slash->interval.end;
-
3501 ftp_scheme->invalidate();
-
3502 mailto_scheme->invalidate();
-
3503 file_scheme->invalidate();
-
3504 }
-
3505 else if (ftp_scheme->match(text, this->interval.end, end, flags) &&
-
3506 m_colon->match(text, ftp_scheme->interval.end, end, flags) &&
-
3507 m_slash->match(text, m_colon->interval.end, end, flags) &&
-
3508 m_slash->match(text, m_slash->interval.end, end, flags))
-
3509 {
-
3510 // ftp://
-
3511 this->interval.end = m_slash->interval.end;
-
3512 http_scheme->invalidate();
-
3513 mailto_scheme->invalidate();
-
3514 file_scheme->invalidate();
-
3515 }
-
3516 else if (mailto_scheme->match(text, this->interval.end, end, flags) &&
-
3517 m_colon->match(text, mailto_scheme->interval.end, end, flags))
-
3518 {
-
3519 // mailto:
-
3520 this->interval.end = m_colon->interval.end;
-
3521 http_scheme->invalidate();
-
3522 ftp_scheme->invalidate();
-
3523 file_scheme->invalidate();
-
3524 }
-
3525 else if (file_scheme->match(text, this->interval.end, end, flags) &&
-
3526 m_colon->match(text, file_scheme->interval.end, end, flags) &&
-
3527 m_slash->match(text, m_colon->interval.end, end, flags) &&
-
3528 m_slash->match(text, m_slash->interval.end, end, flags))
-
3529 {
-
3530 // file://
-
3531 this->interval.end = m_slash->interval.end;
-
3532 http_scheme->invalidate();
-
3533 ftp_scheme->invalidate();
-
3534 mailto_scheme->invalidate();
-
3535 }
-
3536 else {
-
3537 // Default to http:
-
3538 http_scheme->invalidate();
-
3539 ftp_scheme->invalidate();
-
3540 mailto_scheme->invalidate();
-
3541 file_scheme->invalidate();
-
3542 }
-
3543
-
3544 if (ftp_scheme->interval) {
-
3545 if (username->match(text, this->interval.end, end, flags)) {
-
3546 if (m_colon->match(text, username->interval.end, end, flags) &&
-
3547 password->match(text, m_colon->interval.end, end, flags) &&
-
3548 m_at->match(text, password->interval.end, end, flags))
-
3549 {
-
3550 // Username and password
-
3551 this->interval.end = m_at->interval.end;
-
3552 }
-
3553 else if (m_at->match(text, this->interval.end, end, flags)) {
-
3554 // Username only
-
3555 this->interval.end = m_at->interval.end;
-
3556 password->invalidate();
-
3557 }
-
3558 else {
-
3559 username->invalidate();
-
3560 password->invalidate();
-
3561 }
-
3562 }
-
3563 else {
-
3564 username->invalidate();
-
3565 password->invalidate();
-
3566 }
-
3567
-
3568 if (ipv4_host->match(text, this->interval.end, end, flags)) {
-
3569 // Host is IPv4
-
3570 this->interval.end = ipv4_host->interval.end;
-
3571 ipv6_host->invalidate();
-
3572 dns_host->invalidate();
-
3573 }
-
3574 else if (
-
3575 m_ip_lbracket->match(text, this->interval.end, end, flags) &&
-
3576 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
-
3577 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
-
3578 {
-
3579 // Host is IPv6
-
3580 this->interval.end = m_ip_rbracket->interval.end;
-
3581 ipv4_host->invalidate();
-
3582 dns_host->invalidate();
-
3583 }
-
3584 else if (dns_host->match(text, this->interval.end, end, flags)) {
-
3585 // Host is hostname
-
3586 this->interval.end = dns_host->interval.end;
-
3587 ipv4_host->invalidate();
-
3588 ipv6_host->invalidate();
-
3589 }
-
3590 else {
-
3591 invalidate();
-
3592 return false;
-
3593 }
-
3594
-
3595 if (m_colon->match(text, this->interval.end, end, flags) &&
-
3596 port->match(text, m_colon->interval.end, end, flags))
-
3597 {
-
3598 // Port
-
3599 this->interval.end = port->interval.end;
-
3600 }
-
3601 else
-
3602 port->invalidate();
-
3603
-
3604 if (path->match(text, this->interval.end, end, flags)) {
-
3605 // Path
-
3606 this->interval.end = path->interval.end;
-
3607 }
-
3608
-
3609 this->interval.start = start;
-
3610 return true;
-
3611 }
-
3612
-
3613 if (mailto_scheme->interval) {
-
3614 if (username->match(text, this->interval.end, end, flags) &&
-
3615 m_at->match(text, username->interval.end, end, flags))
-
3616 {
-
3617 // Username
-
3618 this->interval.end = m_at->interval.end;
-
3619 }
-
3620 else {
-
3621 invalidate();
-
3622 return false;
-
3623 }
-
3624
-
3625 if (m_ip_lbracket->match(text, this->interval.end, end, flags) &&
-
3626 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
-
3627 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
-
3628 {
-
3629 // Host is IPv4
-
3630 this->interval.end = m_ip_rbracket->interval.end;
-
3631 ipv6_host->invalidate();
-
3632 dns_host->invalidate();
-
3633 }
-
3634 else if (
-
3635 m_ip_lbracket->match(text, this->interval.end, end, flags) &&
-
3636 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
-
3637 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
-
3638 {
-
3639 // Host is IPv6
-
3640 this->interval.end = m_ip_rbracket->interval.end;
-
3641 ipv4_host->invalidate();
-
3642 dns_host->invalidate();
-
3643 }
-
3644 else if (dns_host->match(text, this->interval.end, end, flags)) {
-
3645 // Host is hostname
-
3646 this->interval.end = dns_host->interval.end;
-
3647 ipv4_host->invalidate();
-
3648 ipv6_host->invalidate();
-
3649 }
-
3650 else {
-
3651 invalidate();
-
3652 return false;
-
3653 }
-
3654
-
3655 password->invalidate();
-
3656 port->invalidate();
-
3657 path->invalidate();
-
3658 this->interval.start = start;
-
3659 return true;
-
3660 }
-
3661
-
3662 if (file_scheme->interval) {
-
3663 if (path->match(text, this->interval.end, end, flags)) {
-
3664 // Path
-
3665 this->interval.end = path->interval.end;
-
3666 }
-
3667
-
3668 username->invalidate();
-
3669 password->invalidate();
-
3670 ipv4_host->invalidate();
-
3671 ipv6_host->invalidate();
-
3672 dns_host->invalidate();
-
3673 port->invalidate();
-
3674 this->interval.start = start;
-
3675 return true;
-
3676 }
-
3677
-
3678 // "http://" found or defaulted to
-
3679
-
3680 // If "http://" explicit, test for username&password.
-
3681 if (http_scheme->interval &&
-
3682 username->match(text, this->interval.end, end, flags))
-
3683 {
-
3684 if (m_colon->match(text, username->interval.end, end, flags) &&
-
3685 password->match(text, m_colon->interval.end, end, flags) &&
-
3686 m_at->match(text, password->interval.end, end, flags))
-
3687 {
-
3688 // Username and password
-
3689 this->interval.end = m_at->interval.end;
-
3690 }
-
3691 else if (m_at->match(text, username->interval.end, end, flags)) {
-
3692 // Username only
-
3693 this->interval.end = m_at->interval.end;
-
3694 password->invalidate();
-
3695 }
-
3696 else {
-
3697 username->invalidate();
-
3698 password->invalidate();
-
3699 }
-
3700 }
-
3701 else {
-
3702 username->invalidate();
-
3703 password->invalidate();
-
3704 }
-
3705
-
3706 if (ipv4_host->match(text, this->interval.end, end, flags)) {
-
3707 // Host is IPv4
-
3708 this->interval.end = ipv4_host->interval.end;
-
3709 ipv6_host->invalidate();
-
3710 dns_host->invalidate();
-
3711 }
-
3712 else if (
-
3713 m_ip_lbracket->match(text, this->interval.end, end, flags) &&
-
3714 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
-
3715 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
-
3716 {
-
3717 // Host is IPv6
-
3718 this->interval.end = m_ip_rbracket->interval.end;
-
3719 ipv4_host->invalidate();
-
3720 dns_host->invalidate();
-
3721 }
-
3722 else if (dns_host->match(text, this->interval.end, end, flags)) {
-
3723 // Host is hostname
-
3724 this->interval.end = dns_host->interval.end;
-
3725 ipv4_host->invalidate();
-
3726 ipv6_host->invalidate();
-
3727 }
-
3728 else {
-
3729 invalidate();
-
3730 return false;
-
3731 }
-
3732
-
3733 if (m_colon->match(text, this->interval.end, end, flags) &&
-
3734 port->match(text, m_colon->interval.end, end, flags))
-
3735 {
-
3736 // Port
-
3737 this->interval.end = port->interval.end;
-
3738 }
-
3739 else
-
3740 port->invalidate();
-
3741
-
3742 if (path->match(text, this->interval.end, end, flags)) {
-
3743 // Path
-
3744 this->interval.end = path->interval.end;
-
3745 }
-
3746
-
3747 this->interval.start = start;
-
3748 return true;
-
3749 }
-
3750
-
3751 virtual void invalidate()
-
3752 {
-
3753 http_scheme->invalidate();
-
3754 ftp_scheme->invalidate();
-
3755 mailto_scheme->invalidate();
-
3756 file_scheme->invalidate();
-
3757 username->invalidate();
-
3758 password->invalidate();
-
3759 ipv4_host->invalidate();
-
3760 ipv6_host->invalidate();
-
3761 dns_host->invalidate();
-
3762 port->invalidate();
-
3763 path->invalidate();
- -
3765 }
-
3766
-
3767 public:
-
3768 std::shared_ptr<basic_parser<T>> http_scheme;
-
3769 std::shared_ptr<basic_parser<T>> ftp_scheme;
-
3770 std::shared_ptr<basic_parser<T>> mailto_scheme;
-
3771 std::shared_ptr<basic_parser<T>> file_scheme;
-
3772 std::shared_ptr<basic_parser<T>> username;
-
3773 std::shared_ptr<basic_parser<T>> password;
-
3774 std::shared_ptr<basic_parser<T>> ipv4_host;
-
3775 std::shared_ptr<basic_parser<T>> ipv6_host;
-
3776 std::shared_ptr<basic_parser<T>> dns_host;
-
3777 std::shared_ptr<basic_parser<T>> port;
-
3778 std::shared_ptr<basic_parser<T>> path;
-
3779
-
3780 protected:
-
3781 std::shared_ptr<basic_parser<T>> m_colon;
-
3782 std::shared_ptr<basic_parser<T>> m_slash;
-
3783 std::shared_ptr<basic_parser<T>> m_at;
-
3784 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
-
3785 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
-
3786 };
+
3429
+ + +
3432#ifdef _UNICODE
+
3433 using turl_path = wurl_path;
+
3434#else
+
3435 using turl_path = url_path;
+
3436#endif
+ +
3438
+
3442 template <class T>
+
+
3443 class basic_url : public basic_parser<T>
+
3444 {
+
3445 public:
+
3446 basic_url(
+
3447 _In_ const std::shared_ptr<basic_parser<T>>& _http_scheme,
+
3448 _In_ const std::shared_ptr<basic_parser<T>>& _ftp_scheme,
+
3449 _In_ const std::shared_ptr<basic_parser<T>>& _mailto_scheme,
+
3450 _In_ const std::shared_ptr<basic_parser<T>>& _file_scheme,
+
3451 _In_ const std::shared_ptr<basic_parser<T>>& colon,
+
3452 _In_ const std::shared_ptr<basic_parser<T>>& slash,
+
3453 _In_ const std::shared_ptr<basic_parser<T>>& _username,
+
3454 _In_ const std::shared_ptr<basic_parser<T>>& _password,
+
3455 _In_ const std::shared_ptr<basic_parser<T>>& at,
+
3456 _In_ const std::shared_ptr<basic_parser<T>>& ip_lbracket,
+
3457 _In_ const std::shared_ptr<basic_parser<T>>& ip_rbracket,
+
3458 _In_ const std::shared_ptr<basic_parser<T>>& _ipv4_host,
+
3459 _In_ const std::shared_ptr<basic_parser<T>>& _ipv6_host,
+
3460 _In_ const std::shared_ptr<basic_parser<T>>& _dns_host,
+
3461 _In_ const std::shared_ptr<basic_parser<T>>& _port,
+
3462 _In_ const std::shared_ptr<basic_parser<T>>& _path,
+
3463 _In_ const std::locale& locale = std::locale()) :
+
3464 basic_parser<T>(locale),
+
3465 http_scheme(_http_scheme),
+
3466 ftp_scheme(_ftp_scheme),
+
3467 mailto_scheme(_mailto_scheme),
+
3468 file_scheme(_file_scheme),
+
3469 m_colon(colon),
+
3470 m_slash(slash),
+
3471 username(_username),
+
3472 password(_password),
+
3473 m_at(at),
+
3474 m_ip_lbracket(ip_lbracket),
+
3475 m_ip_rbracket(ip_rbracket),
+
3476 ipv4_host(_ipv4_host),
+
3477 ipv6_host(_ipv6_host),
+
3478 dns_host(_dns_host),
+
3479 port(_port),
+
3480 path(_path)
+
3481 {}
+
3482
+
3483 virtual bool match(
+
3484 _In_reads_or_z_(end) const T* text,
+
3485 _In_ size_t start = 0,
+
3486 _In_ size_t end = (size_t)-1,
+
3487 _In_ int flags = match_default)
+
3488 {
+
3489 _Assume_(text || start >= end);
+
3490
+
3491 this->interval.end = start;
+
3492
+
3493 if (http_scheme->match(text, this->interval.end, end, flags) &&
+
3494 m_colon->match(text, http_scheme->interval.end, end, flags) &&
+
3495 m_slash->match(text, m_colon->interval.end, end, flags) &&
+
3496 m_slash->match(text, m_slash->interval.end, end, flags))
+
3497 {
+
3498 // http://
+
3499 this->interval.end = m_slash->interval.end;
+
3500 ftp_scheme->invalidate();
+
3501 mailto_scheme->invalidate();
+
3502 file_scheme->invalidate();
+
3503 }
+
3504 else if (ftp_scheme->match(text, this->interval.end, end, flags) &&
+
3505 m_colon->match(text, ftp_scheme->interval.end, end, flags) &&
+
3506 m_slash->match(text, m_colon->interval.end, end, flags) &&
+
3507 m_slash->match(text, m_slash->interval.end, end, flags))
+
3508 {
+
3509 // ftp://
+
3510 this->interval.end = m_slash->interval.end;
+
3511 http_scheme->invalidate();
+
3512 mailto_scheme->invalidate();
+
3513 file_scheme->invalidate();
+
3514 }
+
3515 else if (mailto_scheme->match(text, this->interval.end, end, flags) &&
+
3516 m_colon->match(text, mailto_scheme->interval.end, end, flags))
+
3517 {
+
3518 // mailto:
+
3519 this->interval.end = m_colon->interval.end;
+
3520 http_scheme->invalidate();
+
3521 ftp_scheme->invalidate();
+
3522 file_scheme->invalidate();
+
3523 }
+
3524 else if (file_scheme->match(text, this->interval.end, end, flags) &&
+
3525 m_colon->match(text, file_scheme->interval.end, end, flags) &&
+
3526 m_slash->match(text, m_colon->interval.end, end, flags) &&
+
3527 m_slash->match(text, m_slash->interval.end, end, flags))
+
3528 {
+
3529 // file://
+
3530 this->interval.end = m_slash->interval.end;
+
3531 http_scheme->invalidate();
+
3532 ftp_scheme->invalidate();
+
3533 mailto_scheme->invalidate();
+
3534 }
+
3535 else {
+
3536 // Default to http:
+
3537 http_scheme->invalidate();
+
3538 ftp_scheme->invalidate();
+
3539 mailto_scheme->invalidate();
+
3540 file_scheme->invalidate();
+
3541 }
+
3542
+
3543 if (ftp_scheme->interval) {
+
3544 if (username->match(text, this->interval.end, end, flags)) {
+
3545 if (m_colon->match(text, username->interval.end, end, flags) &&
+
3546 password->match(text, m_colon->interval.end, end, flags) &&
+
3547 m_at->match(text, password->interval.end, end, flags))
+
3548 {
+
3549 // Username and password
+
3550 this->interval.end = m_at->interval.end;
+
3551 }
+
3552 else if (m_at->match(text, this->interval.end, end, flags)) {
+
3553 // Username only
+
3554 this->interval.end = m_at->interval.end;
+
3555 password->invalidate();
+
3556 }
+
3557 else {
+
3558 username->invalidate();
+
3559 password->invalidate();
+
3560 }
+
3561 }
+
3562 else {
+
3563 username->invalidate();
+
3564 password->invalidate();
+
3565 }
+
3566
+
3567 if (ipv4_host->match(text, this->interval.end, end, flags)) {
+
3568 // Host is IPv4
+
3569 this->interval.end = ipv4_host->interval.end;
+
3570 ipv6_host->invalidate();
+
3571 dns_host->invalidate();
+
3572 }
+
3573 else if (
+
3574 m_ip_lbracket->match(text, this->interval.end, end, flags) &&
+
3575 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
+
3576 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
+
3577 {
+
3578 // Host is IPv6
+
3579 this->interval.end = m_ip_rbracket->interval.end;
+
3580 ipv4_host->invalidate();
+
3581 dns_host->invalidate();
+
3582 }
+
3583 else if (dns_host->match(text, this->interval.end, end, flags)) {
+
3584 // Host is hostname
+
3585 this->interval.end = dns_host->interval.end;
+
3586 ipv4_host->invalidate();
+
3587 ipv6_host->invalidate();
+
3588 }
+
3589 else {
+
3590 invalidate();
+
3591 return false;
+
3592 }
+
3593
+
3594 if (m_colon->match(text, this->interval.end, end, flags) &&
+
3595 port->match(text, m_colon->interval.end, end, flags))
+
3596 {
+
3597 // Port
+
3598 this->interval.end = port->interval.end;
+
3599 }
+
3600 else
+
3601 port->invalidate();
+
3602
+
3603 if (path->match(text, this->interval.end, end, flags)) {
+
3604 // Path
+
3605 this->interval.end = path->interval.end;
+
3606 }
+
3607
+
3608 this->interval.start = start;
+
3609 return true;
+
3610 }
+
3611
+
3612 if (mailto_scheme->interval) {
+
3613 if (username->match(text, this->interval.end, end, flags) &&
+
3614 m_at->match(text, username->interval.end, end, flags))
+
3615 {
+
3616 // Username
+
3617 this->interval.end = m_at->interval.end;
+
3618 }
+
3619 else {
+
3620 invalidate();
+
3621 return false;
+
3622 }
+
3623
+
3624 if (m_ip_lbracket->match(text, this->interval.end, end, flags) &&
+
3625 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
+
3626 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
+
3627 {
+
3628 // Host is IPv4
+
3629 this->interval.end = m_ip_rbracket->interval.end;
+
3630 ipv6_host->invalidate();
+
3631 dns_host->invalidate();
+
3632 }
+
3633 else if (
+
3634 m_ip_lbracket->match(text, this->interval.end, end, flags) &&
+
3635 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
+
3636 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
+
3637 {
+
3638 // Host is IPv6
+
3639 this->interval.end = m_ip_rbracket->interval.end;
+
3640 ipv4_host->invalidate();
+
3641 dns_host->invalidate();
+
3642 }
+
3643 else if (dns_host->match(text, this->interval.end, end, flags)) {
+
3644 // Host is hostname
+
3645 this->interval.end = dns_host->interval.end;
+
3646 ipv4_host->invalidate();
+
3647 ipv6_host->invalidate();
+
3648 }
+
3649 else {
+
3650 invalidate();
+
3651 return false;
+
3652 }
+
3653
+
3654 password->invalidate();
+
3655 port->invalidate();
+
3656 path->invalidate();
+
3657 this->interval.start = start;
+
3658 return true;
+
3659 }
+
3660
+
3661 if (file_scheme->interval) {
+
3662 if (path->match(text, this->interval.end, end, flags)) {
+
3663 // Path
+
3664 this->interval.end = path->interval.end;
+
3665 }
+
3666
+
3667 username->invalidate();
+
3668 password->invalidate();
+
3669 ipv4_host->invalidate();
+
3670 ipv6_host->invalidate();
+
3671 dns_host->invalidate();
+
3672 port->invalidate();
+
3673 this->interval.start = start;
+
3674 return true;
+
3675 }
+
3676
+
3677 // "http://" found or defaulted to
+
3678
+
3679 // If "http://" explicit, test for username&password.
+
3680 if (http_scheme->interval &&
+
3681 username->match(text, this->interval.end, end, flags))
+
3682 {
+
3683 if (m_colon->match(text, username->interval.end, end, flags) &&
+
3684 password->match(text, m_colon->interval.end, end, flags) &&
+
3685 m_at->match(text, password->interval.end, end, flags))
+
3686 {
+
3687 // Username and password
+
3688 this->interval.end = m_at->interval.end;
+
3689 }
+
3690 else if (m_at->match(text, username->interval.end, end, flags)) {
+
3691 // Username only
+
3692 this->interval.end = m_at->interval.end;
+
3693 password->invalidate();
+
3694 }
+
3695 else {
+
3696 username->invalidate();
+
3697 password->invalidate();
+
3698 }
+
3699 }
+
3700 else {
+
3701 username->invalidate();
+
3702 password->invalidate();
+
3703 }
+
3704
+
3705 if (ipv4_host->match(text, this->interval.end, end, flags)) {
+
3706 // Host is IPv4
+
3707 this->interval.end = ipv4_host->interval.end;
+
3708 ipv6_host->invalidate();
+
3709 dns_host->invalidate();
+
3710 }
+
3711 else if (
+
3712 m_ip_lbracket->match(text, this->interval.end, end, flags) &&
+
3713 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
+
3714 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
+
3715 {
+
3716 // Host is IPv6
+
3717 this->interval.end = m_ip_rbracket->interval.end;
+
3718 ipv4_host->invalidate();
+
3719 dns_host->invalidate();
+
3720 }
+
3721 else if (dns_host->match(text, this->interval.end, end, flags)) {
+
3722 // Host is hostname
+
3723 this->interval.end = dns_host->interval.end;
+
3724 ipv4_host->invalidate();
+
3725 ipv6_host->invalidate();
+
3726 }
+
3727 else {
+
3728 invalidate();
+
3729 return false;
+
3730 }
+
3731
+
3732 if (m_colon->match(text, this->interval.end, end, flags) &&
+
3733 port->match(text, m_colon->interval.end, end, flags))
+
3734 {
+
3735 // Port
+
3736 this->interval.end = port->interval.end;
+
3737 }
+
3738 else
+
3739 port->invalidate();
+
3740
+
3741 if (path->match(text, this->interval.end, end, flags)) {
+
3742 // Path
+
3743 this->interval.end = path->interval.end;
+
3744 }
+
3745
+
3746 this->interval.start = start;
+
3747 return true;
+
3748 }
+
3749
+
3750 virtual void invalidate()
+
3751 {
+
3752 http_scheme->invalidate();
+
3753 ftp_scheme->invalidate();
+
3754 mailto_scheme->invalidate();
+
3755 file_scheme->invalidate();
+
3756 username->invalidate();
+
3757 password->invalidate();
+
3758 ipv4_host->invalidate();
+
3759 ipv6_host->invalidate();
+
3760 dns_host->invalidate();
+
3761 port->invalidate();
+
3762 path->invalidate();
+ +
3764 }
+
3765
+
3766 public:
+
3767 std::shared_ptr<basic_parser<T>> http_scheme;
+
3768 std::shared_ptr<basic_parser<T>> ftp_scheme;
+
3769 std::shared_ptr<basic_parser<T>> mailto_scheme;
+
3770 std::shared_ptr<basic_parser<T>> file_scheme;
+
3771 std::shared_ptr<basic_parser<T>> username;
+
3772 std::shared_ptr<basic_parser<T>> password;
+
3773 std::shared_ptr<basic_parser<T>> ipv4_host;
+
3774 std::shared_ptr<basic_parser<T>> ipv6_host;
+
3775 std::shared_ptr<basic_parser<T>> dns_host;
+
3776 std::shared_ptr<basic_parser<T>> port;
+
3777 std::shared_ptr<basic_parser<T>> path;
+
3778
+
3779 protected:
+
3780 std::shared_ptr<basic_parser<T>> m_colon;
+
3781 std::shared_ptr<basic_parser<T>> m_slash;
+
3782 std::shared_ptr<basic_parser<T>> m_at;
+
3783 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
+
3784 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
+
3785 };
-
3787
-
3788 using url = basic_url<char>;
-
3789 using wurl = basic_url<wchar_t>;
-
3790#ifdef _UNICODE
-
3791 using turl = wurl;
-
3792#else
-
3793 using turl = url;
-
3794#endif
-
3795 using sgml_url = basic_url<char>;
-
3796
-
3800 template <class T>
-
- -
3802 {
-
3803 public:
- -
3805 _In_ const std::shared_ptr<basic_parser<T>>& _username,
-
3806 _In_ const std::shared_ptr<basic_parser<T>>& at,
-
3807 _In_ const std::shared_ptr<basic_parser<T>>& ip_lbracket,
-
3808 _In_ const std::shared_ptr<basic_parser<T>>& ip_rbracket,
-
3809 _In_ const std::shared_ptr<basic_parser<T>>& _ipv4_host,
-
3810 _In_ const std::shared_ptr<basic_parser<T>>& _ipv6_host,
-
3811 _In_ const std::shared_ptr<basic_parser<T>>& _dns_host,
-
3812 _In_ const std::locale& locale = std::locale()) :
-
3813 basic_parser<T>(locale),
-
3814 username(_username),
-
3815 m_at(at),
-
3816 m_ip_lbracket(ip_lbracket),
-
3817 m_ip_rbracket(ip_rbracket),
-
3818 ipv4_host(_ipv4_host),
-
3819 ipv6_host(_ipv6_host),
-
3820 dns_host(_dns_host)
-
3821 {}
-
3822
-
3823 virtual bool match(
-
3824 _In_reads_or_z_(end) const T* text,
-
3825 _In_ size_t start = 0,
-
3826 _In_ size_t end = (size_t)-1,
-
3827 _In_ int flags = match_default)
-
3828 {
-
3829 _Assume_(text || start >= end);
-
3830
-
3831 if (username->match(text, start, end, flags) &&
-
3832 m_at->match(text, username->interval.end, end, flags))
-
3833 {
-
3834 // Username@
-
3835 if (m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
-
3836 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
-
3837 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
-
3838 {
-
3839 // Host is IPv4
-
3840 this->interval.end = m_ip_rbracket->interval.end;
-
3841 ipv6_host->invalidate();
-
3842 dns_host->invalidate();
-
3843 }
-
3844 else if (
-
3845 m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
-
3846 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
-
3847 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
-
3848 {
-
3849 // Host is IPv6
-
3850 this->interval.end = m_ip_rbracket->interval.end;
-
3851 ipv4_host->invalidate();
-
3852 dns_host->invalidate();
-
3853 }
-
3854 else if (dns_host->match(text, m_at->interval.end, end, flags)) {
-
3855 // Host is hostname
-
3856 this->interval.end = dns_host->interval.end;
-
3857 ipv4_host->invalidate();
-
3858 ipv6_host->invalidate();
-
3859 }
-
3860 else
-
3861 goto error;
-
3862 this->interval.start = start;
-
3863 return true;
-
3864 }
-
3865
-
3866 error:
-
3867 username->invalidate();
-
3868 ipv4_host->invalidate();
-
3869 ipv6_host->invalidate();
-
3870 dns_host->invalidate();
-
3871 this->interval.start = (this->interval.end = start) + 1;
-
3872 return false;
-
3873 }
-
3874
-
3875 virtual void invalidate()
-
3876 {
-
3877 username->invalidate();
-
3878 ipv4_host->invalidate();
-
3879 ipv6_host->invalidate();
-
3880 dns_host->invalidate();
- -
3882 }
-
3883
-
3884 public:
-
3885 std::shared_ptr<basic_parser<T>> username;
-
3886 std::shared_ptr<basic_parser<T>> ipv4_host;
-
3887 std::shared_ptr<basic_parser<T>> ipv6_host;
-
3888 std::shared_ptr<basic_parser<T>> dns_host;
-
3889
-
3890 protected:
-
3891 std::shared_ptr<basic_parser<T>> m_at;
-
3892 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
-
3893 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
-
3894 };
+
3786
+
3787 using url = basic_url<char>;
+
3788 using wurl = basic_url<wchar_t>;
+
3789#ifdef _UNICODE
+
3790 using turl = wurl;
+
3791#else
+
3792 using turl = url;
+
3793#endif
+
3794 using sgml_url = basic_url<char>;
+
3795
+
3799 template <class T>
+
+ +
3801 {
+
3802 public:
+ +
3804 _In_ const std::shared_ptr<basic_parser<T>>& _username,
+
3805 _In_ const std::shared_ptr<basic_parser<T>>& at,
+
3806 _In_ const std::shared_ptr<basic_parser<T>>& ip_lbracket,
+
3807 _In_ const std::shared_ptr<basic_parser<T>>& ip_rbracket,
+
3808 _In_ const std::shared_ptr<basic_parser<T>>& _ipv4_host,
+
3809 _In_ const std::shared_ptr<basic_parser<T>>& _ipv6_host,
+
3810 _In_ const std::shared_ptr<basic_parser<T>>& _dns_host,
+
3811 _In_ const std::locale& locale = std::locale()) :
+
3812 basic_parser<T>(locale),
+
3813 username(_username),
+
3814 m_at(at),
+
3815 m_ip_lbracket(ip_lbracket),
+
3816 m_ip_rbracket(ip_rbracket),
+
3817 ipv4_host(_ipv4_host),
+
3818 ipv6_host(_ipv6_host),
+
3819 dns_host(_dns_host)
+
3820 {}
+
3821
+
3822 virtual bool match(
+
3823 _In_reads_or_z_(end) const T* text,
+
3824 _In_ size_t start = 0,
+
3825 _In_ size_t end = (size_t)-1,
+
3826 _In_ int flags = match_default)
+
3827 {
+
3828 _Assume_(text || start >= end);
+
3829
+
3830 if (username->match(text, start, end, flags) &&
+
3831 m_at->match(text, username->interval.end, end, flags))
+
3832 {
+
3833 // Username@
+
3834 if (m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
+
3835 ipv4_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
+
3836 m_ip_rbracket->match(text, ipv4_host->interval.end, end, flags))
+
3837 {
+
3838 // Host is IPv4
+
3839 this->interval.end = m_ip_rbracket->interval.end;
+
3840 ipv6_host->invalidate();
+
3841 dns_host->invalidate();
+
3842 }
+
3843 else if (
+
3844 m_ip_lbracket->match(text, m_at->interval.end, end, flags) &&
+
3845 ipv6_host->match(text, m_ip_lbracket->interval.end, end, flags) &&
+
3846 m_ip_rbracket->match(text, ipv6_host->interval.end, end, flags))
+
3847 {
+
3848 // Host is IPv6
+
3849 this->interval.end = m_ip_rbracket->interval.end;
+
3850 ipv4_host->invalidate();
+
3851 dns_host->invalidate();
+
3852 }
+
3853 else if (dns_host->match(text, m_at->interval.end, end, flags)) {
+
3854 // Host is hostname
+
3855 this->interval.end = dns_host->interval.end;
+
3856 ipv4_host->invalidate();
+
3857 ipv6_host->invalidate();
+
3858 }
+
3859 else
+
3860 goto error;
+
3861 this->interval.start = start;
+
3862 return true;
+
3863 }
+
3864
+
3865 error:
+
3866 username->invalidate();
+
3867 ipv4_host->invalidate();
+
3868 ipv6_host->invalidate();
+
3869 dns_host->invalidate();
+
3870 this->interval.start = (this->interval.end = start) + 1;
+
3871 return false;
+
3872 }
+
3873
+
3874 virtual void invalidate()
+
3875 {
+
3876 username->invalidate();
+
3877 ipv4_host->invalidate();
+
3878 ipv6_host->invalidate();
+
3879 dns_host->invalidate();
+ +
3881 }
+
3882
+
3883 public:
+
3884 std::shared_ptr<basic_parser<T>> username;
+
3885 std::shared_ptr<basic_parser<T>> ipv4_host;
+
3886 std::shared_ptr<basic_parser<T>> ipv6_host;
+
3887 std::shared_ptr<basic_parser<T>> dns_host;
+
3888
+
3889 protected:
+
3890 std::shared_ptr<basic_parser<T>> m_at;
+
3891 std::shared_ptr<basic_parser<T>> m_ip_lbracket;
+
3892 std::shared_ptr<basic_parser<T>> m_ip_rbracket;
+
3893 };
-
3895
- - -
3898#ifdef _UNICODE
- -
3900#else
- -
3902#endif
- -
3904
-
3908 template <class T>
-
- -
3910 {
-
3911 public:
- -
3913 _In_ const std::shared_ptr<basic_parser<T>>& _emoticon,
-
3914 _In_ const std::shared_ptr<basic_parser<T>>& _apex,
-
3915 _In_ const std::shared_ptr<basic_parser<T>>& _eyes,
-
3916 _In_ const std::shared_ptr<basic_parser<T>>& _nose,
-
3917 _In_ const std::shared_ptr<basic_set<T>>& _mouth,
-
3918 _In_ const std::locale& locale = std::locale()) :
-
3919 basic_parser<T>(locale),
- -
3921 apex(_apex),
-
3922 eyes(_eyes),
-
3923 nose(_nose),
-
3924 mouth(_mouth)
-
3925 {}
-
3926
-
3927 virtual bool match(
-
3928 _In_reads_or_z_(end) const T* text,
-
3929 _In_ size_t start = 0,
-
3930 _In_ size_t end = (size_t)-1,
-
3931 _In_ int flags = match_default)
-
3932 {
-
3933 _Assume_(text || start >= end);
-
3934
-
3935 if (emoticon && emoticon->match(text, start, end, flags)) {
-
3936 if (apex) apex->invalidate();
-
3937 eyes->invalidate();
-
3938 if (nose) nose->invalidate();
-
3939 mouth->invalidate();
-
3940 this->interval.start = start;
-
3941 this->interval.end = emoticon->interval.end;
-
3942 return true;
-
3943 }
-
3944
-
3945 this->interval.end = start;
-
3946
-
3947 if (apex && apex->match(text, this->interval.end, end, flags))
-
3948 this->interval.end = apex->interval.end;
-
3949
-
3950 if (eyes->match(text, this->interval.end, end, flags)) {
-
3951 if (nose && nose->match(text, eyes->interval.end, end, flags) &&
-
3952 mouth->match(text, nose->interval.end, end, flags))
-
3953 {
-
3954 size_t
- -
3956 hit_offset = mouth->hit_offset;
-
3957 // Mouth may repeat :-)))))))
-
3958 for (this->interval.end = mouth->interval.end; mouth->match(text, this->interval.end, end, flags) && mouth->hit_offset == hit_offset; this->interval.end = mouth->interval.end);
-
3959 mouth->interval.start = start_mouth;
-
3960 mouth->interval.end = this->interval.end;
-
3961 this->interval.start = start;
-
3962 return true;
-
3963 }
-
3964 if (mouth->match(text, eyes->interval.end, end, flags)) {
-
3965 size_t
- -
3967 hit_offset = mouth->hit_offset;
-
3968 // Mouth may repeat :-)))))))
-
3969 for (this->interval.end = mouth->interval.end; mouth->match(text, this->interval.end, end, flags) && mouth->hit_offset == hit_offset; this->interval.end = mouth->interval.end);
-
3970 if (nose) nose->invalidate();
-
3971 mouth->interval.start = start_mouth;
-
3972 mouth->interval.end = this->interval.end;
-
3973 this->interval.start = start;
-
3974 return true;
-
3975 }
-
3976 }
-
3977
-
3978 if (emoticon) emoticon->invalidate();
-
3979 if (apex) apex->invalidate();
-
3980 eyes->invalidate();
-
3981 if (nose) nose->invalidate();
-
3982 mouth->invalidate();
-
3983 this->interval.start = (this->interval.end = start) + 1;
-
3984 return false;
-
3985 }
-
3986
-
3987 virtual void invalidate()
-
3988 {
-
3989 if (emoticon) emoticon->invalidate();
-
3990 if (apex) apex->invalidate();
-
3991 eyes->invalidate();
-
3992 if (nose) nose->invalidate();
-
3993 mouth->invalidate();
- -
3995 }
-
3996
-
3997 public:
-
3998 std::shared_ptr<basic_parser<T>> emoticon;
-
3999 std::shared_ptr<basic_parser<T>> apex;
-
4000 std::shared_ptr<basic_parser<T>> eyes;
-
4001 std::shared_ptr<basic_parser<T>> nose;
-
4002 std::shared_ptr<basic_set<T>> mouth;
-
4003 };
+
3894
+ + +
3897#ifdef _UNICODE
+ +
3899#else
+ +
3901#endif
+ +
3903
+
3907 template <class T>
+
+ +
3909 {
+
3910 public:
+ +
3912 _In_ const std::shared_ptr<basic_parser<T>>& _emoticon,
+
3913 _In_ const std::shared_ptr<basic_parser<T>>& _apex,
+
3914 _In_ const std::shared_ptr<basic_parser<T>>& _eyes,
+
3915 _In_ const std::shared_ptr<basic_parser<T>>& _nose,
+
3916 _In_ const std::shared_ptr<basic_set<T>>& _mouth,
+
3917 _In_ const std::locale& locale = std::locale()) :
+
3918 basic_parser<T>(locale),
+ +
3920 apex(_apex),
+
3921 eyes(_eyes),
+
3922 nose(_nose),
+
3923 mouth(_mouth)
+
3924 {}
+
3925
+
3926 virtual bool match(
+
3927 _In_reads_or_z_(end) const T* text,
+
3928 _In_ size_t start = 0,
+
3929 _In_ size_t end = (size_t)-1,
+
3930 _In_ int flags = match_default)
+
3931 {
+
3932 _Assume_(text || start >= end);
+
3933
+
3934 if (emoticon && emoticon->match(text, start, end, flags)) {
+
3935 if (apex) apex->invalidate();
+
3936 eyes->invalidate();
+
3937 if (nose) nose->invalidate();
+
3938 mouth->invalidate();
+
3939 this->interval.start = start;
+
3940 this->interval.end = emoticon->interval.end;
+
3941 return true;
+
3942 }
+
3943
+
3944 this->interval.end = start;
+
3945
+
3946 if (apex && apex->match(text, this->interval.end, end, flags))
+
3947 this->interval.end = apex->interval.end;
+
3948
+
3949 if (eyes->match(text, this->interval.end, end, flags)) {
+
3950 if (nose && nose->match(text, eyes->interval.end, end, flags) &&
+
3951 mouth->match(text, nose->interval.end, end, flags))
+
3952 {
+
3953 size_t
+ +
3955 hit_offset = mouth->hit_offset;
+
3956 // Mouth may repeat :-)))))))
+
3957 for (this->interval.end = mouth->interval.end; mouth->match(text, this->interval.end, end, flags) && mouth->hit_offset == hit_offset; this->interval.end = mouth->interval.end);
+
3958 mouth->interval.start = start_mouth;
+
3959 mouth->interval.end = this->interval.end;
+
3960 this->interval.start = start;
+
3961 return true;
+
3962 }
+
3963 if (mouth->match(text, eyes->interval.end, end, flags)) {
+
3964 size_t
+ +
3966 hit_offset = mouth->hit_offset;
+
3967 // Mouth may repeat :-)))))))
+
3968 for (this->interval.end = mouth->interval.end; mouth->match(text, this->interval.end, end, flags) && mouth->hit_offset == hit_offset; this->interval.end = mouth->interval.end);
+
3969 if (nose) nose->invalidate();
+
3970 mouth->interval.start = start_mouth;
+
3971 mouth->interval.end = this->interval.end;
+
3972 this->interval.start = start;
+
3973 return true;
+
3974 }
+
3975 }
+
3976
+
3977 if (emoticon) emoticon->invalidate();
+
3978 if (apex) apex->invalidate();
+
3979 eyes->invalidate();
+
3980 if (nose) nose->invalidate();
+
3981 mouth->invalidate();
+
3982 this->interval.start = (this->interval.end = start) + 1;
+
3983 return false;
+
3984 }
+
3985
+
3986 virtual void invalidate()
+
3987 {
+
3988 if (emoticon) emoticon->invalidate();
+
3989 if (apex) apex->invalidate();
+
3990 eyes->invalidate();
+
3991 if (nose) nose->invalidate();
+
3992 mouth->invalidate();
+ +
3994 }
+
3995
+
3996 public:
+
3997 std::shared_ptr<basic_parser<T>> emoticon;
+
3998 std::shared_ptr<basic_parser<T>> apex;
+
3999 std::shared_ptr<basic_parser<T>> eyes;
+
4000 std::shared_ptr<basic_parser<T>> nose;
+
4001 std::shared_ptr<basic_set<T>> mouth;
+
4002 };
-
4004
- - -
4007#ifdef _UNICODE
-
4008 using temoticon = wemoticon;
-
4009#else
-
4010 using temoticon = emoticon;
-
4011#endif
- -
4013
-
4017 enum date_format_t {
-
4018 date_format_none = 0,
-
4019 date_format_dmy = 0x1,
-
4020 date_format_mdy = 0x2,
-
4021 date_format_ymd = 0x4,
-
4022 date_format_ym = 0x8,
-
4023 date_format_my = 0x10,
-
4024 date_format_dm = 0x20,
-
4025 date_format_md = 0x40,
-
4026 };
-
4027
-
4031 template <class T>
-
-
4032 class basic_date : public basic_parser<T>
-
4033 {
-
4034 public:
-
4035 basic_date(
-
4036 _In_ int format_mask,
-
4037 _In_ const std::shared_ptr<basic_integer<T>>& _day,
-
4038 _In_ const std::shared_ptr<basic_integer<T>>& _month,
-
4039 _In_ const std::shared_ptr<basic_integer<T>>& _year,
-
4040 _In_ const std::shared_ptr<basic_set<T>>& separator,
-
4041 _In_ const std::shared_ptr<basic_parser<T>>& space,
-
4042 _In_ const std::locale& locale = std::locale()) :
-
4043 basic_parser<T>(locale),
-
4044 format(date_format_none),
-
4045 m_format_mask(format_mask),
-
4046 day(_day),
-
4047 month(_month),
-
4048 year(_year),
-
4049 m_separator(separator),
-
4050 m_space(space)
-
4051 {}
-
4052
-
4053 virtual bool match(
-
4054 _In_reads_or_z_(end) const T* text,
-
4055 _In_ size_t start = 0,
-
4056 _In_ size_t end = (size_t)-1,
-
4057 _In_ int flags = match_default)
-
4058 {
-
4059 _Assume_(text || start >= end);
-
4060
-
4061 const int space_match_flags = flags & ~match_multiline; // Spaces in dates must never be broken in new line.
-
4062 if ((m_format_mask & date_format_dmy) == date_format_dmy) {
-
4063 if (day->match(text, start, end, flags)) {
-
4064 for (this->interval.end = day->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4065 if (m_separator->match(text, this->interval.end, end, flags)) {
-
4066 size_t hit_offset = m_separator->hit_offset;
-
4067 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4068 if (month->match(text, this->interval.end, end, flags)) {
-
4069 for (this->interval.end = month->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4070 if (m_separator->match(text, this->interval.end, end, flags) &&
-
4071 m_separator->hit_offset == hit_offset) // Both separators must match.
-
4072 {
-
4073 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4074 if (year->match(text, this->interval.end, end, flags) &&
-
4075 is_valid(day->value, month->value))
-
4076 {
-
4077 this->interval.start = start;
-
4078 this->interval.end = year->interval.end;
-
4079 format = date_format_dmy;
-
4080 return true;
-
4081 }
-
4082 }
-
4083 }
-
4084 }
-
4085 }
-
4086 }
-
4087
-
4088 if ((m_format_mask & date_format_mdy) == date_format_mdy) {
-
4089 if (month->match(text, start, end, flags)) {
-
4090 for (this->interval.end = month->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4091 if (m_separator->match(text, this->interval.end, end, flags)) {
-
4092 size_t hit_offset = m_separator->hit_offset;
-
4093 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4094 if (day->match(text, this->interval.end, end, flags)) {
-
4095 for (this->interval.end = day->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4096 if (m_separator->match(text, this->interval.end, end, flags) &&
-
4097 m_separator->hit_offset == hit_offset) // Both separators must match.
-
4098 {
-
4099 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4100 if (year->match(text, this->interval.end, end, flags) &&
-
4101 is_valid(day->value, month->value))
-
4102 {
-
4103 this->interval.start = start;
-
4104 this->interval.end = year->interval.end;
-
4105 format = date_format_mdy;
-
4106 return true;
-
4107 }
-
4108 }
-
4109 }
-
4110 }
-
4111 }
-
4112 }
-
4113
-
4114 if ((m_format_mask & date_format_ymd) == date_format_ymd) {
-
4115 if (year->match(text, start, end, flags)) {
-
4116 for (this->interval.end = year->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4117 if (m_separator->match(text, this->interval.end, end, flags)) {
-
4118 size_t hit_offset = m_separator->hit_offset;
-
4119 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4120 if (month->match(text, this->interval.end, end, flags)) {
-
4121 for (this->interval.end = month->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4122 if (m_separator->match(text, this->interval.end, end, flags) &&
-
4123 m_separator->hit_offset == hit_offset) // Both separators must match.
-
4124 {
-
4125 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4126 if (day->match(text, this->interval.end, end, flags) &&
-
4127 is_valid(day->value, month->value))
-
4128 {
-
4129 this->interval.start = start;
-
4130 this->interval.end = day->interval.end;
-
4131 format = date_format_ymd;
-
4132 return true;
-
4133 }
-
4134 }
-
4135 }
-
4136 }
-
4137 }
-
4138 }
-
4139
-
4140 if ((m_format_mask & date_format_ym) == date_format_ym) {
-
4141 if (year->match(text, start, end, flags)) {
-
4142 for (this->interval.end = year->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4143 if (m_separator->match(text, this->interval.end, end, flags)) {
-
4144 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4145 if (month->match(text, this->interval.end, end, flags) &&
-
4146 is_valid((size_t)-1, month->value))
-
4147 {
-
4148 if (day) day->invalidate();
-
4149 this->interval.start = start;
-
4150 this->interval.end = month->interval.end;
-
4151 format = date_format_ym;
-
4152 return true;
-
4153 }
-
4154 }
-
4155 }
-
4156 }
-
4157
-
4158 if ((m_format_mask & date_format_my) == date_format_my) {
-
4159 if (month->match(text, start, end, flags)) {
-
4160 for (this->interval.end = month->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4161 if (m_separator->match(text, this->interval.end, end, flags)) {
-
4162 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4163 if (year->match(text, this->interval.end, end, flags) &&
-
4164 is_valid((size_t)-1, month->value))
-
4165 {
-
4166 if (day) day->invalidate();
-
4167 this->interval.start = start;
-
4168 this->interval.end = year->interval.end;
-
4169 format = date_format_my;
-
4170 return true;
-
4171 }
-
4172 }
-
4173 }
-
4174 }
-
4175
-
4176 if ((m_format_mask & date_format_dm) == date_format_dm) {
-
4177 if (day->match(text, start, end, flags)) {
-
4178 for (this->interval.end = day->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4179 if (m_separator->match(text, this->interval.end, end, flags)) {
-
4180 size_t hit_offset = m_separator->hit_offset;
-
4181 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4182 if (month->match(text, this->interval.end, end, flags) &&
-
4183 is_valid(day->value, month->value))
-
4184 {
-
4185 if (year) year->invalidate();
-
4186 this->interval.start = start;
-
4187 for (this->interval.end = month->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4188 if (m_separator->match(text, this->interval.end, end, flags) &&
-
4189 m_separator->hit_offset == hit_offset) // Both separators must match.
-
4190 this->interval.end = m_separator->interval.end;
-
4191 else
-
4192 this->interval.end = month->interval.end;
-
4193 format = date_format_dm;
-
4194 return true;
-
4195 }
-
4196 }
-
4197 }
-
4198 }
-
4199
-
4200 if ((m_format_mask & date_format_md) == date_format_md) {
-
4201 if (month->match(text, start, end, flags)) {
-
4202 for (this->interval.end = month->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4203 if (m_separator->match(text, this->interval.end, end, flags)) {
-
4204 size_t hit_offset = m_separator->hit_offset;
-
4205 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4206 if (day->match(text, this->interval.end, end, flags) &&
-
4207 is_valid(day->value, month->value))
-
4208 {
-
4209 if (year) year->invalidate();
-
4210 this->interval.start = start;
-
4211 for (this->interval.end = day->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
-
4212 if (m_separator->match(text, this->interval.end, end, flags) &&
-
4213 m_separator->hit_offset == hit_offset) // Both separators must match.
-
4214 this->interval.end = m_separator->interval.end;
-
4215 else
-
4216 this->interval.end = day->interval.end;
-
4217 format = date_format_md;
-
4218 return true;
-
4219 }
-
4220 }
-
4221 }
-
4222 }
-
4223
-
4224 if (day) day->invalidate();
-
4225 if (month) month->invalidate();
-
4226 if (year) year->invalidate();
-
4227 format = date_format_none;
-
4228 this->interval.start = (this->interval.end = start) + 1;
-
4229 return false;
-
4230 }
-
4231
-
4232 virtual void invalidate()
-
4233 {
-
4234 if (day) day->invalidate();
-
4235 if (month) month->invalidate();
-
4236 if (year) year->invalidate();
-
4237 format = date_format_none;
- -
4239 }
-
4240
-
4241 protected:
-
4242 static inline bool is_valid(size_t day, size_t month)
-
4243 {
-
4244 if (month == (size_t)-1) {
-
4245 // Default to January. This allows validating day only, as January has all 31 days.
-
4246 month = 1;
-
4247 }
-
4248 if (day == (size_t)-1) {
-
4249 // Default to 1st day in month. This allows validating month only, as each month has 1st day.
-
4250 day = 1;
-
4251 }
-
4252
-
4253 switch (month) {
-
4254 case 1:
-
4255 case 3:
-
4256 case 5:
-
4257 case 7:
-
4258 case 8:
-
4259 case 10:
-
4260 case 12:
-
4261 return 1 <= day && day <= 31;
-
4262 case 2:
-
4263 return 1 <= day && day <= 29;
-
4264 case 4:
-
4265 case 6:
-
4266 case 9:
-
4267 case 11:
-
4268 return 1 <= day && day <= 30;
-
4269 default:
-
4270 return false;
-
4271 }
-
4272 }
-
4273
-
4274 public:
-
4275 date_format_t format;
-
4276 std::shared_ptr<basic_integer<T>> day;
-
4277 std::shared_ptr<basic_integer<T>> month;
-
4278 std::shared_ptr<basic_integer<T>> year;
-
4279
-
4280 protected:
-
4281 int m_format_mask;
-
4282 std::shared_ptr<basic_set<T>> m_separator;
-
4283 std::shared_ptr<basic_parser<T>> m_space;
-
4284 };
+
4003
+ + +
4006#ifdef _UNICODE
+
4007 using temoticon = wemoticon;
+
4008#else
+
4009 using temoticon = emoticon;
+
4010#endif
+ +
4012
+
4016 enum date_format_t {
+
4017 date_format_none = 0,
+
4018 date_format_dmy = 0x1,
+
4019 date_format_mdy = 0x2,
+
4020 date_format_ymd = 0x4,
+
4021 date_format_ym = 0x8,
+
4022 date_format_my = 0x10,
+
4023 date_format_dm = 0x20,
+
4024 date_format_md = 0x40,
+
4025 };
+
4026
+
4030 template <class T>
+
+
4031 class basic_date : public basic_parser<T>
+
4032 {
+
4033 public:
+
4034 basic_date(
+
4035 _In_ int format_mask,
+
4036 _In_ const std::shared_ptr<basic_integer<T>>& _day,
+
4037 _In_ const std::shared_ptr<basic_integer<T>>& _month,
+
4038 _In_ const std::shared_ptr<basic_integer<T>>& _year,
+
4039 _In_ const std::shared_ptr<basic_set<T>>& separator,
+
4040 _In_ const std::shared_ptr<basic_parser<T>>& space,
+
4041 _In_ const std::locale& locale = std::locale()) :
+
4042 basic_parser<T>(locale),
+
4043 format(date_format_none),
+
4044 m_format_mask(format_mask),
+
4045 day(_day),
+
4046 month(_month),
+
4047 year(_year),
+
4048 m_separator(separator),
+
4049 m_space(space)
+
4050 {}
+
4051
+
4052 virtual bool match(
+
4053 _In_reads_or_z_(end) const T* text,
+
4054 _In_ size_t start = 0,
+
4055 _In_ size_t end = (size_t)-1,
+
4056 _In_ int flags = match_default)
+
4057 {
+
4058 _Assume_(text || start >= end);
+
4059
+
4060 const int space_match_flags = flags & ~match_multiline; // Spaces in dates must never be broken in new line.
+
4061 if ((m_format_mask & date_format_dmy) == date_format_dmy) {
+
4062 if (day->match(text, start, end, flags)) {
+
4063 for (this->interval.end = day->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4064 if (m_separator->match(text, this->interval.end, end, flags)) {
+
4065 size_t hit_offset = m_separator->hit_offset;
+
4066 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4067 if (month->match(text, this->interval.end, end, flags)) {
+
4068 for (this->interval.end = month->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4069 if (m_separator->match(text, this->interval.end, end, flags) &&
+
4070 m_separator->hit_offset == hit_offset) // Both separators must match.
+
4071 {
+
4072 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4073 if (year->match(text, this->interval.end, end, flags) &&
+
4074 is_valid(day->value, month->value))
+
4075 {
+
4076 this->interval.start = start;
+
4077 this->interval.end = year->interval.end;
+
4078 format = date_format_dmy;
+
4079 return true;
+
4080 }
+
4081 }
+
4082 }
+
4083 }
+
4084 }
+
4085 }
+
4086
+
4087 if ((m_format_mask & date_format_mdy) == date_format_mdy) {
+
4088 if (month->match(text, start, end, flags)) {
+
4089 for (this->interval.end = month->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4090 if (m_separator->match(text, this->interval.end, end, flags)) {
+
4091 size_t hit_offset = m_separator->hit_offset;
+
4092 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4093 if (day->match(text, this->interval.end, end, flags)) {
+
4094 for (this->interval.end = day->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4095 if (m_separator->match(text, this->interval.end, end, flags) &&
+
4096 m_separator->hit_offset == hit_offset) // Both separators must match.
+
4097 {
+
4098 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4099 if (year->match(text, this->interval.end, end, flags) &&
+
4100 is_valid(day->value, month->value))
+
4101 {
+
4102 this->interval.start = start;
+
4103 this->interval.end = year->interval.end;
+
4104 format = date_format_mdy;
+
4105 return true;
+
4106 }
+
4107 }
+
4108 }
+
4109 }
+
4110 }
+
4111 }
+
4112
+
4113 if ((m_format_mask & date_format_ymd) == date_format_ymd) {
+
4114 if (year->match(text, start, end, flags)) {
+
4115 for (this->interval.end = year->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4116 if (m_separator->match(text, this->interval.end, end, flags)) {
+
4117 size_t hit_offset = m_separator->hit_offset;
+
4118 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4119 if (month->match(text, this->interval.end, end, flags)) {
+
4120 for (this->interval.end = month->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4121 if (m_separator->match(text, this->interval.end, end, flags) &&
+
4122 m_separator->hit_offset == hit_offset) // Both separators must match.
+
4123 {
+
4124 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4125 if (day->match(text, this->interval.end, end, flags) &&
+
4126 is_valid(day->value, month->value))
+
4127 {
+
4128 this->interval.start = start;
+
4129 this->interval.end = day->interval.end;
+
4130 format = date_format_ymd;
+
4131 return true;
+
4132 }
+
4133 }
+
4134 }
+
4135 }
+
4136 }
+
4137 }
+
4138
+
4139 if ((m_format_mask & date_format_ym) == date_format_ym) {
+
4140 if (year->match(text, start, end, flags)) {
+
4141 for (this->interval.end = year->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4142 if (m_separator->match(text, this->interval.end, end, flags)) {
+
4143 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4144 if (month->match(text, this->interval.end, end, flags) &&
+
4145 is_valid((size_t)-1, month->value))
+
4146 {
+
4147 if (day) day->invalidate();
+
4148 this->interval.start = start;
+
4149 this->interval.end = month->interval.end;
+
4150 format = date_format_ym;
+
4151 return true;
+
4152 }
+
4153 }
+
4154 }
+
4155 }
+
4156
+
4157 if ((m_format_mask & date_format_my) == date_format_my) {
+
4158 if (month->match(text, start, end, flags)) {
+
4159 for (this->interval.end = month->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4160 if (m_separator->match(text, this->interval.end, end, flags)) {
+
4161 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4162 if (year->match(text, this->interval.end, end, flags) &&
+
4163 is_valid((size_t)-1, month->value))
+
4164 {
+
4165 if (day) day->invalidate();
+
4166 this->interval.start = start;
+
4167 this->interval.end = year->interval.end;
+
4168 format = date_format_my;
+
4169 return true;
+
4170 }
+
4171 }
+
4172 }
+
4173 }
+
4174
+
4175 if ((m_format_mask & date_format_dm) == date_format_dm) {
+
4176 if (day->match(text, start, end, flags)) {
+
4177 for (this->interval.end = day->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4178 if (m_separator->match(text, this->interval.end, end, flags)) {
+
4179 size_t hit_offset = m_separator->hit_offset;
+
4180 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4181 if (month->match(text, this->interval.end, end, flags) &&
+
4182 is_valid(day->value, month->value))
+
4183 {
+
4184 if (year) year->invalidate();
+
4185 this->interval.start = start;
+
4186 for (this->interval.end = month->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4187 if (m_separator->match(text, this->interval.end, end, flags) &&
+
4188 m_separator->hit_offset == hit_offset) // Both separators must match.
+
4189 this->interval.end = m_separator->interval.end;
+
4190 else
+
4191 this->interval.end = month->interval.end;
+
4192 format = date_format_dm;
+
4193 return true;
+
4194 }
+
4195 }
+
4196 }
+
4197 }
+
4198
+
4199 if ((m_format_mask & date_format_md) == date_format_md) {
+
4200 if (month->match(text, start, end, flags)) {
+
4201 for (this->interval.end = month->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4202 if (m_separator->match(text, this->interval.end, end, flags)) {
+
4203 size_t hit_offset = m_separator->hit_offset;
+
4204 for (this->interval.end = m_separator->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4205 if (day->match(text, this->interval.end, end, flags) &&
+
4206 is_valid(day->value, month->value))
+
4207 {
+
4208 if (year) year->invalidate();
+
4209 this->interval.start = start;
+
4210 for (this->interval.end = day->interval.end; m_space->match(text, this->interval.end, end, space_match_flags); this->interval.end = m_space->interval.end);
+
4211 if (m_separator->match(text, this->interval.end, end, flags) &&
+
4212 m_separator->hit_offset == hit_offset) // Both separators must match.
+
4213 this->interval.end = m_separator->interval.end;
+
4214 else
+
4215 this->interval.end = day->interval.end;
+
4216 format = date_format_md;
+
4217 return true;
+
4218 }
+
4219 }
+
4220 }
+
4221 }
+
4222
+
4223 if (day) day->invalidate();
+
4224 if (month) month->invalidate();
+
4225 if (year) year->invalidate();
+
4226 format = date_format_none;
+
4227 this->interval.start = (this->interval.end = start) + 1;
+
4228 return false;
+
4229 }
+
4230
+
4231 virtual void invalidate()
+
4232 {
+
4233 if (day) day->invalidate();
+
4234 if (month) month->invalidate();
+
4235 if (year) year->invalidate();
+
4236 format = date_format_none;
+ +
4238 }
+
4239
+
4240 protected:
+
4241 static inline bool is_valid(size_t day, size_t month)
+
4242 {
+
4243 if (month == (size_t)-1) {
+
4244 // Default to January. This allows validating day only, as January has all 31 days.
+
4245 month = 1;
+
4246 }
+
4247 if (day == (size_t)-1) {
+
4248 // Default to 1st day in month. This allows validating month only, as each month has 1st day.
+
4249 day = 1;
+
4250 }
+
4251
+
4252 switch (month) {
+
4253 case 1:
+
4254 case 3:
+
4255 case 5:
+
4256 case 7:
+
4257 case 8:
+
4258 case 10:
+
4259 case 12:
+
4260 return 1 <= day && day <= 31;
+
4261 case 2:
+
4262 return 1 <= day && day <= 29;
+
4263 case 4:
+
4264 case 6:
+
4265 case 9:
+
4266 case 11:
+
4267 return 1 <= day && day <= 30;
+
4268 default:
+
4269 return false;
+
4270 }
+
4271 }
+
4272
+
4273 public:
+
4274 date_format_t format;
+
4275 std::shared_ptr<basic_integer<T>> day;
+
4276 std::shared_ptr<basic_integer<T>> month;
+
4277 std::shared_ptr<basic_integer<T>> year;
+
4278
+
4279 protected:
+
4280 int m_format_mask;
+
4281 std::shared_ptr<basic_set<T>> m_separator;
+
4282 std::shared_ptr<basic_parser<T>> m_space;
+
4283 };
-
4285
-
4286 using date = basic_date<char>;
-
4287 using wdate = basic_date<wchar_t>;
-
4288#ifdef _UNICODE
-
4289 using tdate = wdate;
-
4290#else
-
4291 using tdate = date;
-
4292#endif
- -
4294
-
4298 template <class T>
-
-
4299 class basic_time : public basic_parser<T>
-
4300 {
-
4301 public:
-
4302 basic_time(
-
4303 _In_ const std::shared_ptr<basic_integer10<T>>& _hour,
-
4304 _In_ const std::shared_ptr<basic_integer10<T>>& _minute,
-
4305 _In_ const std::shared_ptr<basic_integer10<T>>& _second,
-
4306 _In_ const std::shared_ptr<basic_integer10<T>>& _millisecond,
-
4307 _In_ const std::shared_ptr<basic_set<T>>& separator,
-
4308 _In_ const std::shared_ptr<basic_parser<T>>& millisecond_separator,
-
4309 _In_ const std::locale& locale = std::locale()) :
-
4310 basic_parser<T>(locale),
-
4311 hour(_hour),
-
4312 minute(_minute),
-
4313 second(_second),
-
4314 millisecond(_millisecond),
-
4315 m_separator(separator),
-
4316 m_millisecond_separator(millisecond_separator)
-
4317 {}
-
4318
-
4319 virtual bool match(
-
4320 _In_reads_or_z_(end) const T* text,
-
4321 _In_ size_t start = 0,
-
4322 _In_ size_t end = (size_t)-1,
-
4323 _In_ int flags = match_default)
-
4324 {
-
4325 _Assume_(text || start >= end);
-
4326
-
4327 if (hour->match(text, start, end, flags) &&
-
4328 m_separator->match(text, hour->interval.end, end, flags) &&
-
4329 minute->match(text, m_separator->interval.end, end, flags) &&
-
4330 minute->value < 60)
-
4331 {
-
4332 // hh::mm
-
4333 size_t hit_offset = m_separator->hit_offset;
-
4334 if (m_separator->match(text, minute->interval.end, end, flags) &&
-
4335 m_separator->hit_offset == hit_offset && // Both separators must match.
-
4336 second && second->match(text, m_separator->interval.end, end, flags) &&
-
4337 second->value < 60)
-
4338 {
-
4339 // hh::mm:ss
-
4340 if (m_millisecond_separator && m_millisecond_separator->match(text, second->interval.end, end, flags) &&
-
4341 millisecond && millisecond->match(text, m_millisecond_separator->interval.end, end, flags) &&
-
4342 millisecond->value < 1000)
-
4343 {
-
4344 // hh::mm:ss.mmmm
-
4345 this->interval.end = millisecond->interval.end;
-
4346 }
-
4347 else {
-
4348 if (millisecond) millisecond->invalidate();
-
4349 this->interval.end = second->interval.end;
-
4350 }
-
4351 }
-
4352 else {
-
4353 if (second) second->invalidate();
-
4354 if (millisecond) millisecond->invalidate();
-
4355 this->interval.end = minute->interval.end;
-
4356 }
-
4357 this->interval.start = start;
-
4358 return true;
-
4359 }
-
4360
-
4361 hour->invalidate();
-
4362 minute->invalidate();
-
4363 if (second) second->invalidate();
-
4364 if (millisecond) millisecond->invalidate();
-
4365 this->interval.start = (this->interval.end = start) + 1;
-
4366 return false;
-
4367 }
-
4368
-
4369 virtual void invalidate()
-
4370 {
-
4371 hour->invalidate();
-
4372 minute->invalidate();
-
4373 if (second) second->invalidate();
-
4374 if (millisecond) millisecond->invalidate();
- -
4376 }
-
4377
-
4378 public:
-
4379 std::shared_ptr<basic_integer10<T>> hour;
-
4380 std::shared_ptr<basic_integer10<T>> minute;
-
4381 std::shared_ptr<basic_integer10<T>> second;
-
4382 std::shared_ptr<basic_integer10<T>> millisecond;
-
4383
-
4384 protected:
-
4385 std::shared_ptr<basic_set<T>> m_separator;
-
4386 std::shared_ptr<basic_parser<T>> m_millisecond_separator;
-
4387 };
+
4284
+
4285 using date = basic_date<char>;
+
4286 using wdate = basic_date<wchar_t>;
+
4287#ifdef _UNICODE
+
4288 using tdate = wdate;
+
4289#else
+
4290 using tdate = date;
+
4291#endif
+ +
4293
+
4297 template <class T>
+
+
4298 class basic_time : public basic_parser<T>
+
4299 {
+
4300 public:
+
4301 basic_time(
+
4302 _In_ const std::shared_ptr<basic_integer10<T>>& _hour,
+
4303 _In_ const std::shared_ptr<basic_integer10<T>>& _minute,
+
4304 _In_ const std::shared_ptr<basic_integer10<T>>& _second,
+
4305 _In_ const std::shared_ptr<basic_integer10<T>>& _millisecond,
+
4306 _In_ const std::shared_ptr<basic_set<T>>& separator,
+
4307 _In_ const std::shared_ptr<basic_parser<T>>& millisecond_separator,
+
4308 _In_ const std::locale& locale = std::locale()) :
+
4309 basic_parser<T>(locale),
+
4310 hour(_hour),
+
4311 minute(_minute),
+
4312 second(_second),
+
4313 millisecond(_millisecond),
+
4314 m_separator(separator),
+
4315 m_millisecond_separator(millisecond_separator)
+
4316 {}
+
4317
+
4318 virtual bool match(
+
4319 _In_reads_or_z_(end) const T* text,
+
4320 _In_ size_t start = 0,
+
4321 _In_ size_t end = (size_t)-1,
+
4322 _In_ int flags = match_default)
+
4323 {
+
4324 _Assume_(text || start >= end);
+
4325
+
4326 if (hour->match(text, start, end, flags) &&
+
4327 m_separator->match(text, hour->interval.end, end, flags) &&
+
4328 minute->match(text, m_separator->interval.end, end, flags) &&
+
4329 minute->value < 60)
+
4330 {
+
4331 // hh::mm
+
4332 size_t hit_offset = m_separator->hit_offset;
+
4333 if (m_separator->match(text, minute->interval.end, end, flags) &&
+
4334 m_separator->hit_offset == hit_offset && // Both separators must match.
+
4335 second && second->match(text, m_separator->interval.end, end, flags) &&
+
4336 second->value < 60)
+
4337 {
+
4338 // hh::mm:ss
+
4339 if (m_millisecond_separator && m_millisecond_separator->match(text, second->interval.end, end, flags) &&
+
4340 millisecond && millisecond->match(text, m_millisecond_separator->interval.end, end, flags) &&
+
4341 millisecond->value < 1000)
+
4342 {
+
4343 // hh::mm:ss.mmmm
+
4344 this->interval.end = millisecond->interval.end;
+
4345 }
+
4346 else {
+
4347 if (millisecond) millisecond->invalidate();
+
4348 this->interval.end = second->interval.end;
+
4349 }
+
4350 }
+
4351 else {
+
4352 if (second) second->invalidate();
+
4353 if (millisecond) millisecond->invalidate();
+
4354 this->interval.end = minute->interval.end;
+
4355 }
+
4356 this->interval.start = start;
+
4357 return true;
+
4358 }
+
4359
+
4360 hour->invalidate();
+
4361 minute->invalidate();
+
4362 if (second) second->invalidate();
+
4363 if (millisecond) millisecond->invalidate();
+
4364 this->interval.start = (this->interval.end = start) + 1;
+
4365 return false;
+
4366 }
+
4367
+
4368 virtual void invalidate()
+
4369 {
+
4370 hour->invalidate();
+
4371 minute->invalidate();
+
4372 if (second) second->invalidate();
+
4373 if (millisecond) millisecond->invalidate();
+ +
4375 }
+
4376
+
4377 public:
+
4378 std::shared_ptr<basic_integer10<T>> hour;
+
4379 std::shared_ptr<basic_integer10<T>> minute;
+
4380 std::shared_ptr<basic_integer10<T>> second;
+
4381 std::shared_ptr<basic_integer10<T>> millisecond;
+
4382
+
4383 protected:
+
4384 std::shared_ptr<basic_set<T>> m_separator;
+
4385 std::shared_ptr<basic_parser<T>> m_millisecond_separator;
+
4386 };
-
4388
-
4389 using time = basic_time<char>;
-
4390 using wtime = basic_time<wchar_t>;
-
4391#ifdef _UNICODE
-
4392 using ttime = wtime;
-
4393#else
-
4394 using ttime = time;
-
4395#endif
- -
4397
-
4401 template <class T>
-
-
4402 class basic_angle : public basic_parser<T>
-
4403 {
-
4404 public:
- -
4406 _In_ const std::shared_ptr<basic_integer10<T>>& _degree,
-
4407 _In_ const std::shared_ptr<basic_parser<T>>& _degree_separator,
-
4408 _In_ const std::shared_ptr<basic_integer10<T>>& _minute,
-
4409 _In_ const std::shared_ptr<basic_parser<T>>& _minute_separator,
-
4410 _In_ const std::shared_ptr<basic_integer10<T>>& _second,
-
4411 _In_ const std::shared_ptr<basic_parser<T>>& _second_separator,
-
4412 _In_ const std::shared_ptr<basic_parser<T>>& _decimal,
-
4413 _In_ const std::locale& locale = std::locale()) :
-
4414 basic_parser<T>(locale),
-
4415 degree(_degree),
-
4416 degree_separator(_degree_separator),
-
4417 minute(_minute),
-
4418 minute_separator(_minute_separator),
-
4419 second(_second),
-
4420 second_separator(_second_separator),
-
4421 decimal(_decimal)
-
4422 {}
-
4423
-
4424 virtual bool match(
-
4425 _In_reads_or_z_(end) const T* text,
-
4426 _In_ size_t start = 0,
-
4427 _In_ size_t end = (size_t)-1,
-
4428 _In_ int flags = match_default)
-
4429 {
-
4430 _Assume_(text || start >= end);
-
4431
-
4432 this->interval.end = start;
-
4433
-
4434 if (degree->match(text, this->interval.end, end, flags) &&
-
4435 degree_separator->match(text, degree->interval.end, end, flags))
-
4436 {
-
4437 // Degrees
-
4438 this->interval.end = degree_separator->interval.end;
-
4439 }
-
4440 else {
-
4441 degree->invalidate();
-
4442 degree_separator->invalidate();
-
4443 }
-
4444
-
4445 if (minute->match(text, this->interval.end, end, flags) &&
-
4446 minute->value < 60 &&
-
4447 minute_separator->match(text, minute->interval.end, end, flags))
-
4448 {
-
4449 // Minutes
-
4450 this->interval.end = minute_separator->interval.end;
-
4451 }
-
4452 else {
-
4453 minute->invalidate();
-
4454 minute_separator->invalidate();
-
4455 }
-
4456
-
4457 if (second && second->match(text, this->interval.end, end, flags) &&
-
4458 second->value < 60)
-
4459 {
-
4460 // Seconds
-
4461 this->interval.end = second->interval.end;
-
4462 if (second_separator && second_separator->match(text, this->interval.end, end, flags))
-
4463 this->interval.end = second_separator->interval.end;
-
4464 else
-
4465 if (second_separator) second_separator->invalidate();
-
4466 }
-
4467 else {
-
4468 if (second) second->invalidate();
-
4469 if (second_separator) second_separator->invalidate();
-
4470 }
-
4471
-
4472 if (degree->interval.start < degree->interval.end ||
-
4473 minute->interval.start < minute->interval.end ||
-
4474 (second && second->interval.start < second->interval.end))
-
4475 {
-
4476 if (decimal && decimal->match(text, this->interval.end, end, flags)) {
-
4477 // Decimals
-
4478 this->interval.end = decimal->interval.end;
-
4479 }
-
4480 else if (decimal)
-
4481 decimal->invalidate();
-
4482 this->interval.start = start;
-
4483 return true;
-
4484 }
-
4485 if (decimal) decimal->invalidate();
-
4486 this->interval.start = (this->interval.end = start) + 1;
-
4487 return false;
-
4488 }
-
4489
-
4490 virtual void invalidate()
-
4491 {
-
4492 degree->invalidate();
-
4493 degree_separator->invalidate();
-
4494 minute->invalidate();
-
4495 minute_separator->invalidate();
-
4496 if (second) second->invalidate();
-
4497 if (second_separator) second_separator->invalidate();
-
4498 if (decimal) decimal->invalidate();
- -
4500 }
-
4501
-
4502 public:
-
4503 std::shared_ptr<basic_integer10<T>> degree;
-
4504 std::shared_ptr<basic_parser<T>> degree_separator;
-
4505 std::shared_ptr<basic_integer10<T>> minute;
-
4506 std::shared_ptr<basic_parser<T>> minute_separator;
-
4507 std::shared_ptr<basic_integer10<T>> second;
-
4508 std::shared_ptr<basic_parser<T>> second_separator;
-
4509 std::shared_ptr<basic_parser<T>> decimal;
-
4510 };
+
4387
+
4388 using time = basic_time<char>;
+
4389 using wtime = basic_time<wchar_t>;
+
4390#ifdef _UNICODE
+
4391 using ttime = wtime;
+
4392#else
+
4393 using ttime = time;
+
4394#endif
+ +
4396
+
4400 template <class T>
+
+
4401 class basic_angle : public basic_parser<T>
+
4402 {
+
4403 public:
+ +
4405 _In_ const std::shared_ptr<basic_integer10<T>>& _degree,
+
4406 _In_ const std::shared_ptr<basic_parser<T>>& _degree_separator,
+
4407 _In_ const std::shared_ptr<basic_integer10<T>>& _minute,
+
4408 _In_ const std::shared_ptr<basic_parser<T>>& _minute_separator,
+
4409 _In_ const std::shared_ptr<basic_integer10<T>>& _second,
+
4410 _In_ const std::shared_ptr<basic_parser<T>>& _second_separator,
+
4411 _In_ const std::shared_ptr<basic_parser<T>>& _decimal,
+
4412 _In_ const std::locale& locale = std::locale()) :
+
4413 basic_parser<T>(locale),
+
4414 degree(_degree),
+
4415 degree_separator(_degree_separator),
+
4416 minute(_minute),
+
4417 minute_separator(_minute_separator),
+
4418 second(_second),
+
4419 second_separator(_second_separator),
+
4420 decimal(_decimal)
+
4421 {}
+
4422
+
4423 virtual bool match(
+
4424 _In_reads_or_z_(end) const T* text,
+
4425 _In_ size_t start = 0,
+
4426 _In_ size_t end = (size_t)-1,
+
4427 _In_ int flags = match_default)
+
4428 {
+
4429 _Assume_(text || start >= end);
+
4430
+
4431 this->interval.end = start;
+
4432
+
4433 if (degree->match(text, this->interval.end, end, flags) &&
+
4434 degree_separator->match(text, degree->interval.end, end, flags))
+
4435 {
+
4436 // Degrees
+
4437 this->interval.end = degree_separator->interval.end;
+
4438 }
+
4439 else {
+
4440 degree->invalidate();
+
4441 degree_separator->invalidate();
+
4442 }
+
4443
+
4444 if (minute->match(text, this->interval.end, end, flags) &&
+
4445 minute->value < 60 &&
+
4446 minute_separator->match(text, minute->interval.end, end, flags))
+
4447 {
+
4448 // Minutes
+
4449 this->interval.end = minute_separator->interval.end;
+
4450 }
+
4451 else {
+
4452 minute->invalidate();
+
4453 minute_separator->invalidate();
+
4454 }
+
4455
+
4456 if (second && second->match(text, this->interval.end, end, flags) &&
+
4457 second->value < 60)
+
4458 {
+
4459 // Seconds
+
4460 this->interval.end = second->interval.end;
+
4461 if (second_separator && second_separator->match(text, this->interval.end, end, flags))
+
4462 this->interval.end = second_separator->interval.end;
+
4463 else
+
4464 if (second_separator) second_separator->invalidate();
+
4465 }
+
4466 else {
+
4467 if (second) second->invalidate();
+
4468 if (second_separator) second_separator->invalidate();
+
4469 }
+
4470
+
4471 if (degree->interval.start < degree->interval.end ||
+
4472 minute->interval.start < minute->interval.end ||
+
4473 (second && second->interval.start < second->interval.end))
+
4474 {
+
4475 if (decimal && decimal->match(text, this->interval.end, end, flags)) {
+
4476 // Decimals
+
4477 this->interval.end = decimal->interval.end;
+
4478 }
+
4479 else if (decimal)
+
4480 decimal->invalidate();
+
4481 this->interval.start = start;
+
4482 return true;
+
4483 }
+
4484 if (decimal) decimal->invalidate();
+
4485 this->interval.start = (this->interval.end = start) + 1;
+
4486 return false;
+
4487 }
+
4488
+
4489 virtual void invalidate()
+
4490 {
+
4491 degree->invalidate();
+
4492 degree_separator->invalidate();
+
4493 minute->invalidate();
+
4494 minute_separator->invalidate();
+
4495 if (second) second->invalidate();
+
4496 if (second_separator) second_separator->invalidate();
+
4497 if (decimal) decimal->invalidate();
+ +
4499 }
+
4500
+
4501 public:
+
4502 std::shared_ptr<basic_integer10<T>> degree;
+
4503 std::shared_ptr<basic_parser<T>> degree_separator;
+
4504 std::shared_ptr<basic_integer10<T>> minute;
+
4505 std::shared_ptr<basic_parser<T>> minute_separator;
+
4506 std::shared_ptr<basic_integer10<T>> second;
+
4507 std::shared_ptr<basic_parser<T>> second_separator;
+
4508 std::shared_ptr<basic_parser<T>> decimal;
+
4509 };
-
4511
-
4512 using angle = basic_angle<char>;
- -
4514#ifdef _UNICODE
-
4515 using RRegElKot = wangle;
-
4516#else
-
4517 using RRegElKot = angle;
-
4518#endif
- -
4520
-
4524 template <class T>
-
- -
4526 {
-
4527 public:
- -
4529 _In_ const std::shared_ptr<basic_parser<T>>& digit,
-
4530 _In_ const std::shared_ptr<basic_parser<T>>& plus_sign,
-
4531 _In_ const std::shared_ptr<basic_set<T>>& lparenthesis,
-
4532 _In_ const std::shared_ptr<basic_set<T>>& rparenthesis,
-
4533 _In_ const std::shared_ptr<basic_parser<T>>& separator,
-
4534 _In_ const std::shared_ptr<basic_parser<T>>& space,
-
4535 _In_ const std::locale& locale = std::locale()) :
-
4536 basic_parser<T>(locale),
-
4537 m_digit(digit),
-
4538 m_plus_sign(plus_sign),
-
4539 m_lparenthesis(lparenthesis),
-
4540 m_rparenthesis(rparenthesis),
-
4541 m_separator(separator),
-
4542 m_space(space)
-
4543 {}
-
4544
-
4545 virtual bool match(
-
4546 _In_reads_or_z_(end) const T* text,
-
4547 _In_ size_t start = 0,
-
4548 _In_ size_t end = (size_t)-1,
-
4549 _In_ int flags = match_default)
-
4550 {
-
4551 _Assume_(text || start >= end);
-
4552
-
4553 size_t safe_digit_end = start, safe_value_size = 0;
-
4554 bool has_digits = false, after_digit = false, in_parentheses = false, after_parentheses = false;
-
4555 const int space_match_flags = flags & ~match_multiline; // Spaces in phone numbers must never be broken in new line.
-
4556
-
4557 this->interval.end = start;
-
4558 value.clear();
-
4559 m_lparenthesis->invalidate();
-
4560 m_rparenthesis->invalidate();
-
4561
-
4562 if (m_plus_sign && m_plus_sign->match(text, this->interval.end, end, flags)) {
-
4563 value.append(text + m_plus_sign->interval.start, text + m_plus_sign->interval.end);
-
4564 safe_value_size = value.size();
-
4565 this->interval.end = m_plus_sign->interval.end;
-
4566 }
-
4567
-
4568 for (;;) {
-
4569 _Assume_(text || this->interval.end >= end);
-
4570 if (this->interval.end >= end || !text[this->interval.end])
-
4571 break;
-
4572 if (m_digit->match(text, this->interval.end, end, flags)) {
-
4573 // Digit
-
4574 value.append(text + m_digit->interval.start, text + m_digit->interval.end);
-
4575 this->interval.end = m_digit->interval.end;
-
4576 if (!in_parentheses) {
-
4577 safe_digit_end = this->interval.end;
-
4578 safe_value_size = value.size();
-
4579 has_digits = true;
-
4580 }
-
4581 after_digit = true;
-
4582 after_parentheses = false;
-
4583 }
-
4584 else if (
-
4585 m_lparenthesis && !m_lparenthesis->interval && // No left parenthesis yet
-
4586 m_rparenthesis && !m_rparenthesis->interval && // Right parenthesis after left
-
4587 m_lparenthesis->match(text, this->interval.end, end, flags))
-
4588 {
-
4589 // Left parenthesis
-
4590 value.append(text + m_lparenthesis->interval.start, m_lparenthesis->interval.size());
-
4591 this->interval.end = m_lparenthesis->interval.end;
-
4592 in_parentheses = true;
-
4593 after_digit = false;
-
4594 after_parentheses = false;
-
4595 }
-
4596 else if (
-
4597 in_parentheses && // After left parenthesis
-
4598 m_rparenthesis && !m_rparenthesis->interval && // No right parenthesis yet
-
4599 m_rparenthesis->match(text, this->interval.end, end, flags) &&
-
4600 m_lparenthesis->hit_offset == m_rparenthesis->hit_offset) // Left and right parentheses must match
-
4601 {
-
4602 // Right parenthesis
-
4603 value.append(text + m_rparenthesis->interval.start, text + m_rparenthesis->interval.end);
-
4604 this->interval.end = m_rparenthesis->interval.end;
-
4605 safe_digit_end = this->interval.end;
-
4606 safe_value_size = value.size();
-
4607 in_parentheses = false;
-
4608 after_digit = false;
-
4609 after_parentheses = true;
-
4610 }
-
4611 else if (
-
4612 after_digit &&
-
4613 !in_parentheses && // No separators inside parentheses
-
4614 !after_parentheses && // No separators following right parenthesis
-
4615 m_separator && m_separator->match(text, this->interval.end, end, flags))
-
4616 {
-
4617 // Separator
-
4618 this->interval.end = m_separator->interval.end;
-
4619 after_digit = false;
-
4620 after_parentheses = false;
-
4621 }
-
4622 else if (
- -
4624 m_space && m_space->match(text, this->interval.end, end, space_match_flags))
-
4625 {
-
4626 // Space
-
4627 this->interval.end = m_space->interval.end;
-
4628 after_digit = false;
-
4629 after_parentheses = false;
-
4630 }
-
4631 else
-
4632 break;
-
4633 }
-
4634 if (has_digits) {
-
4635 value.erase(safe_value_size);
-
4636 this->interval.start = start;
-
4637 this->interval.end = safe_digit_end;
-
4638 return true;
-
4639 }
-
4640 value.clear();
-
4641 this->interval.start = (this->interval.end = start) + 1;
-
4642 return false;
-
4643 }
-
4644
-
4645 virtual void invalidate()
-
4646 {
-
4647 value.clear();
- -
4649 }
-
4650
-
4651 public:
-
4652 std::basic_string<T> value;
-
4653
-
4654 protected:
-
4655 std::shared_ptr<basic_parser<T>> m_digit;
-
4656 std::shared_ptr<basic_parser<T>> m_plus_sign;
-
4657 std::shared_ptr<basic_set<T>> m_lparenthesis;
-
4658 std::shared_ptr<basic_set<T>> m_rparenthesis;
-
4659 std::shared_ptr<basic_parser<T>> m_separator;
-
4660 std::shared_ptr<basic_parser<T>> m_space;
-
4661 };
+
4510
+
4511 using angle = basic_angle<char>;
+ +
4513#ifdef _UNICODE
+
4514 using RRegElKot = wangle;
+
4515#else
+
4516 using RRegElKot = angle;
+
4517#endif
+ +
4519
+
4523 template <class T>
+
+ +
4525 {
+
4526 public:
+ +
4528 _In_ const std::shared_ptr<basic_parser<T>>& digit,
+
4529 _In_ const std::shared_ptr<basic_parser<T>>& plus_sign,
+
4530 _In_ const std::shared_ptr<basic_set<T>>& lparenthesis,
+
4531 _In_ const std::shared_ptr<basic_set<T>>& rparenthesis,
+
4532 _In_ const std::shared_ptr<basic_parser<T>>& separator,
+
4533 _In_ const std::shared_ptr<basic_parser<T>>& space,
+
4534 _In_ const std::locale& locale = std::locale()) :
+
4535 basic_parser<T>(locale),
+
4536 m_digit(digit),
+
4537 m_plus_sign(plus_sign),
+
4538 m_lparenthesis(lparenthesis),
+
4539 m_rparenthesis(rparenthesis),
+
4540 m_separator(separator),
+
4541 m_space(space)
+
4542 {}
+
4543
+
4544 virtual bool match(
+
4545 _In_reads_or_z_(end) const T* text,
+
4546 _In_ size_t start = 0,
+
4547 _In_ size_t end = (size_t)-1,
+
4548 _In_ int flags = match_default)
+
4549 {
+
4550 _Assume_(text || start >= end);
+
4551
+
4552 size_t safe_digit_end = start, safe_value_size = 0;
+
4553 bool has_digits = false, after_digit = false, in_parentheses = false, after_parentheses = false;
+
4554 const int space_match_flags = flags & ~match_multiline; // Spaces in phone numbers must never be broken in new line.
+
4555
+
4556 this->interval.end = start;
+
4557 value.clear();
+
4558 m_lparenthesis->invalidate();
+
4559 m_rparenthesis->invalidate();
+
4560
+
4561 if (m_plus_sign && m_plus_sign->match(text, this->interval.end, end, flags)) {
+
4562 value.append(text + m_plus_sign->interval.start, text + m_plus_sign->interval.end);
+
4563 safe_value_size = value.size();
+
4564 this->interval.end = m_plus_sign->interval.end;
+
4565 }
+
4566
+
4567 for (;;) {
+
4568 _Assume_(text || this->interval.end >= end);
+
4569 if (this->interval.end >= end || !text[this->interval.end])
+
4570 break;
+
4571 if (m_digit->match(text, this->interval.end, end, flags)) {
+
4572 // Digit
+
4573 value.append(text + m_digit->interval.start, text + m_digit->interval.end);
+
4574 this->interval.end = m_digit->interval.end;
+
4575 if (!in_parentheses) {
+
4576 safe_digit_end = this->interval.end;
+
4577 safe_value_size = value.size();
+
4578 has_digits = true;
+
4579 }
+
4580 after_digit = true;
+
4581 after_parentheses = false;
+
4582 }
+
4583 else if (
+
4584 m_lparenthesis && !m_lparenthesis->interval && // No left parenthesis yet
+
4585 m_rparenthesis && !m_rparenthesis->interval && // Right parenthesis after left
+
4586 m_lparenthesis->match(text, this->interval.end, end, flags))
+
4587 {
+
4588 // Left parenthesis
+
4589 value.append(text + m_lparenthesis->interval.start, m_lparenthesis->interval.size());
+
4590 this->interval.end = m_lparenthesis->interval.end;
+
4591 in_parentheses = true;
+
4592 after_digit = false;
+
4593 after_parentheses = false;
+
4594 }
+
4595 else if (
+
4596 in_parentheses && // After left parenthesis
+
4597 m_rparenthesis && !m_rparenthesis->interval && // No right parenthesis yet
+
4598 m_rparenthesis->match(text, this->interval.end, end, flags) &&
+
4599 m_lparenthesis->hit_offset == m_rparenthesis->hit_offset) // Left and right parentheses must match
+
4600 {
+
4601 // Right parenthesis
+
4602 value.append(text + m_rparenthesis->interval.start, text + m_rparenthesis->interval.end);
+
4603 this->interval.end = m_rparenthesis->interval.end;
+
4604 safe_digit_end = this->interval.end;
+
4605 safe_value_size = value.size();
+
4606 in_parentheses = false;
+
4607 after_digit = false;
+
4608 after_parentheses = true;
+
4609 }
+
4610 else if (
+
4611 after_digit &&
+
4612 !in_parentheses && // No separators inside parentheses
+
4613 !after_parentheses && // No separators following right parenthesis
+
4614 m_separator && m_separator->match(text, this->interval.end, end, flags))
+
4615 {
+
4616 // Separator
+
4617 this->interval.end = m_separator->interval.end;
+
4618 after_digit = false;
+
4619 after_parentheses = false;
+
4620 }
+
4621 else if (
+ +
4623 m_space && m_space->match(text, this->interval.end, end, space_match_flags))
+
4624 {
+
4625 // Space
+
4626 this->interval.end = m_space->interval.end;
+
4627 after_digit = false;
+
4628 after_parentheses = false;
+
4629 }
+
4630 else
+
4631 break;
+
4632 }
+
4633 if (has_digits) {
+
4634 value.erase(safe_value_size);
+
4635 this->interval.start = start;
+
4636 this->interval.end = safe_digit_end;
+
4637 return true;
+
4638 }
+
4639 value.clear();
+
4640 this->interval.start = (this->interval.end = start) + 1;
+
4641 return false;
+
4642 }
+
4643
+
4644 virtual void invalidate()
+
4645 {
+
4646 value.clear();
+ +
4648 }
+
4649
+
4650 public:
+
4651 std::basic_string<T> value;
+
4652
+
4653 protected:
+
4654 std::shared_ptr<basic_parser<T>> m_digit;
+
4655 std::shared_ptr<basic_parser<T>> m_plus_sign;
+
4656 std::shared_ptr<basic_set<T>> m_lparenthesis;
+
4657 std::shared_ptr<basic_set<T>> m_rparenthesis;
+
4658 std::shared_ptr<basic_parser<T>> m_separator;
+
4659 std::shared_ptr<basic_parser<T>> m_space;
+
4660 };
-
4662
- - -
4665#ifdef _UNICODE
- -
4667#else
- -
4669#endif
- -
4671
-
4677 template <class T>
-
-
4678 class basic_iban : public basic_parser<T>
-
4679 {
-
4680 public:
-
4681 basic_iban(
-
4682 _In_ const std::shared_ptr<basic_parser<T>>& space,
-
4683 _In_ const std::locale& locale = std::locale()) :
-
4684 basic_parser<T>(locale),
-
4685 m_space(space)
-
4686 {
-
4687 this->country[0] = 0;
-
4688 this->check_digits[0] = 0;
-
4689 this->bban[0] = 0;
-
4690 this->is_valid = false;
-
4691 }
-
4692
-
4693 virtual bool match(
-
4694 _In_reads_or_z_(end) const T* text,
-
4695 _In_ size_t start = 0,
-
4696 _In_ size_t end = (size_t)-1,
-
4697 _In_ int flags = match_default)
-
4698 {
-
4699 _Assume_(text || start >= end);
-
4700 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
-
4701 const bool case_insensitive = flags & match_case_insensitive ? true : false;
-
4702 struct country_t {
-
4703 T country[2];
-
4704 T check_digits[2];
-
4705 size_t length;
-
4706 };
-
4707 static const country_t s_countries[] = {
-
4708 { { 'A', 'D' }, {}, 24 }, // Andorra
-
4709 { { 'A', 'E' }, {}, 23 }, // United Arab Emirates
-
4710 { { 'A', 'L' }, {}, 28 }, // Albania
-
4711 { { 'A', 'O' }, {}, 25 }, // Angola
-
4712 { { 'A', 'T' }, {}, 20 }, // Austria
-
4713 { { 'A', 'Z' }, {}, 28 }, // Azerbaijan
-
4714 { { 'B', 'A' }, { '3', '9' }, 20}, // Bosnia and Herzegovina
-
4715 { { 'B', 'E' }, {}, 16 }, // Belgium
-
4716 { { 'B', 'F' }, {}, 28 }, // Burkina Faso
-
4717 { { 'B', 'G' }, {}, 22 }, // Bulgaria
-
4718 { { 'B', 'H' }, {}, 22 }, // Bahrain
-
4719 { { 'B', 'I' }, {}, 27 }, // Burundi
-
4720 { { 'B', 'J' }, {}, 28 }, // Benin
-
4721 { { 'B', 'R' }, {}, 29 }, // Brazil
-
4722 { { 'B', 'Y' }, {}, 28 }, // Belarus
-
4723 { { 'C', 'F' }, {}, 27 }, // Central African Republic
-
4724 { { 'C', 'G' }, {}, 27 }, // Congo, Republic of the
-
4725 { { 'C', 'H' }, {}, 21 }, // Switzerland
-
4726 { { 'C', 'I' }, {}, 28 }, // Côte d'Ivoire
-
4727 { { 'C', 'M' }, {}, 27 }, // Cameroon
-
4728 { { 'C', 'R' }, {}, 22 }, // Costa Rica
-
4729 { { 'C', 'V' }, {}, 25 }, // Cabo Verde
-
4730 { { 'C', 'Y' }, {}, 28 }, // Cyprus
-
4731 { { 'C', 'Z' }, {}, 24 }, // Czech Republic
-
4732 { { 'D', 'E' }, {}, 22 }, // Germany
-
4733 { { 'D', 'J' }, {}, 27 }, // Djibouti
-
4734 { { 'D', 'K' }, {}, 18 }, // Denmark
-
4735 { { 'D', 'O' }, {}, 28 }, // Dominican Republic
-
4736 { { 'D', 'Z' }, {}, 26 }, // Algeria
-
4737 { { 'E', 'E' }, {}, 20 }, // Estonia
-
4738 { { 'E', 'G' }, {}, 29 }, // Egypt
-
4739 { { 'E', 'S' }, {}, 24 }, // Spain
-
4740 { { 'F', 'I' }, {}, 18 }, // Finland
-
4741 { { 'F', 'O' }, {}, 18 }, // Faroe Islands
-
4742 { { 'F', 'R' }, {}, 27 }, // France
-
4743 { { 'G', 'A' }, {}, 27 }, // Gabon
-
4744 { { 'G', 'B' }, {}, 22 }, // United Kingdom
-
4745 { { 'G', 'E' }, {}, 22 }, // Georgia
-
4746 { { 'G', 'I' }, {}, 23 }, // Gibraltar
-
4747 { { 'G', 'L' }, {}, 18 }, // Greenland
-
4748 { { 'G', 'Q' }, {}, 27 }, // Equatorial Guinea
-
4749 { { 'G', 'R' }, {}, 27 }, // Greece
-
4750 { { 'G', 'T' }, {}, 28 }, // Guatemala
-
4751 { { 'G', 'W' }, {}, 25 }, // Guinea-Bissau
-
4752 { { 'H', 'N' }, {}, 28 }, // Honduras
-
4753 { { 'H', 'R' }, {}, 21 }, // Croatia
-
4754 { { 'H', 'U' }, {}, 28 }, // Hungary
-
4755 { { 'I', 'E' }, {}, 22 }, // Ireland
-
4756 { { 'I', 'L' }, {}, 23 }, // Israel
-
4757 { { 'I', 'Q' }, {}, 23 }, // Iraq
-
4758 { { 'I', 'R' }, {}, 26 }, // Iran
-
4759 { { 'I', 'S' }, {}, 26 }, // Iceland
-
4760 { { 'I', 'T' }, {}, 27 }, // Italy
-
4761 { { 'J', 'O' }, {}, 30 }, // Jordan
-
4762 { { 'K', 'M' }, {}, 27 }, // Comoros
-
4763 { { 'K', 'W' }, {}, 30 }, // Kuwait
-
4764 { { 'K', 'Z' }, {}, 20 }, // Kazakhstan
-
4765 { { 'L', 'B' }, {}, 28 }, // Lebanon
-
4766 { { 'L', 'C' }, {}, 32 }, // Saint Lucia
-
4767 { { 'L', 'I' }, {}, 21 }, // Liechtenstein
-
4768 { { 'L', 'T' }, {}, 20 }, // Lithuania
-
4769 { { 'L', 'U' }, {}, 20 }, // Luxembourg
-
4770 { { 'L', 'V' }, {}, 21 }, // Latvia
-
4771 { { 'L', 'Y' }, {}, 25 }, // Libya
-
4772 { { 'M', 'A' }, {}, 28 }, // Morocco
-
4773 { { 'M', 'C' }, {}, 27 }, // Monaco
-
4774 { { 'M', 'D' }, {}, 24 }, // Moldova
-
4775 { { 'M', 'E' }, { '2', '5' }, 22 }, // Montenegro
-
4776 { { 'M', 'G' }, {}, 27 }, // Madagascar
-
4777 { { 'M', 'K' }, { '0', '7' }, 19 }, // North Macedonia
-
4778 { { 'M', 'L' }, {}, 28 }, // Mali
-
4779 { { 'M', 'R' }, { '1', '3' }, 27}, // Mauritania
-
4780 { { 'M', 'T' }, {}, 31 }, // Malta
-
4781 { { 'M', 'U' }, {}, 30 }, // Mauritius
-
4782 { { 'M', 'Z' }, {}, 25 }, // Mozambique
-
4783 { { 'N', 'E' }, {}, 28 }, // Niger
-
4784 { { 'N', 'I' }, {}, 32 }, // Nicaragua
-
4785 { { 'N', 'L' }, {}, 18 }, // Netherlands
-
4786 { { 'N', 'O' }, {}, 15 }, // Norway
-
4787 { { 'P', 'K' }, {}, 24 }, // Pakistan
-
4788 { { 'P', 'L' }, {}, 28 }, // Poland
-
4789 { { 'P', 'S' }, {}, 29 }, // Palestinian territories
-
4790 { { 'P', 'T' }, { '5', '0' }, 25 }, // Portugal
-
4791 { { 'Q', 'A' }, {}, 29 }, // Qatar
-
4792 { { 'R', 'O' }, {}, 24 }, // Romania
-
4793 { { 'R', 'S' }, { '3', '5' }, 22 }, // Serbia
-
4794 { { 'R', 'U' }, {}, 33 }, // Russia
-
4795 { { 'S', 'A' }, {}, 24 }, // Saudi Arabia
-
4796 { { 'S', 'C' }, {}, 31 }, // Seychelles
-
4797 { { 'S', 'D' }, {}, 18 }, // Sudan
-
4798 { { 'S', 'E' }, {}, 24 }, // Sweden
-
4799 { { 'S', 'I' }, { '5', '6' }, 19 }, // Slovenia
-
4800 { { 'S', 'K' }, {}, 24 }, // Slovakia
-
4801 { { 'S', 'M' }, {}, 27 }, // San Marino
-
4802 { { 'S', 'N' }, {}, 28 }, // Senegal
-
4803 { { 'S', 'T' }, {}, 25 }, // São Tomé and Príncipe
-
4804 { { 'S', 'V' }, {}, 28 }, // El Salvador
-
4805 { { 'T', 'D' }, {}, 27 }, // Chad
-
4806 { { 'T', 'G' }, {}, 28 }, // Togo
-
4807 { { 'T', 'L' }, { '3', '8' }, 23}, // East Timor
-
4808 { { 'T', 'N' }, { '5', '9' }, 24 }, // Tunisia
-
4809 { { 'T', 'R' }, {}, 26 }, // Turkey
-
4810 { { 'U', 'A' }, {}, 29 }, // Ukraine
-
4811 { { 'V', 'A' }, {}, 22 }, // Vatican City
-
4812 { { 'V', 'G' }, {}, 24 }, // Virgin Islands, British
-
4813 { { 'X', 'K' }, {}, 20 }, // Kosovo
-
4814 };
-
4815 const country_t* country_desc = nullptr;
-
4816 size_t n, available, next, bban_length;
- -
4818
-
4819 this->interval.end = start;
-
4820 for (size_t i = 0; i < 2; ++i, ++this->interval.end) {
-
4821 if (this->interval.end >= end || !text[this->interval.end])
-
4822 goto error; // incomplete country code
-
4823 T chr = case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end];
-
4824 if (chr < 'A' || 'Z' < chr)
-
4825 goto error; // invalid country code
-
4826 this->country[i] = chr;
-
4827 }
-
4828 for (size_t l = 0, r = _countof(s_countries);;) {
-
4829 if (l >= r)
-
4830 goto error; // unknown country
-
4831 size_t m = (l + r) / 2;
-
4832 const country_t& c = s_countries[m];
-
4833 if (c.country[0] < this->country[0] || (c.country[0] == this->country[0] && c.country[1] < this->country[1]))
-
4834 l = m + 1;
-
4835 else if (this->country[0] < c.country[0] || (this->country[0] == c.country[0] && this->country[1] < c.country[1]))
-
4836 r = m;
-
4837 else {
-
4838 country_desc = &c;
-
4839 break;
-
4840 }
-
4841 }
-
4842 this->country[2] = 0;
-
4843
-
4844 for (size_t i = 0; i < 2; ++i, ++this->interval.end) {
-
4845 if (this->interval.end >= end || text[this->interval.end] < '0' || '9' < text[this->interval.end])
-
4846 goto error; // incomplete or invalid check digits
-
4847 this->check_digits[i] = text[this->interval.end];
-
4848 }
-
4849 this->check_digits[2] = 0;
-
4850
-
4851 if ((country_desc->check_digits[0] && this->check_digits[0] != country_desc->check_digits[0]) ||
-
4852 (country_desc->check_digits[1] && this->check_digits[1] != country_desc->check_digits[1]))
-
4853 goto error; // unexpected check digits
-
4854
-
4855 bban_length = country_desc->length - 4;
-
4856 for (n = 0; n < bban_length;) {
-
4857 if (this->interval.end >= end || !text[this->interval.end])
-
4858 goto error; // bban too short
-
4859 if (m_space && m_space->match(text, this->interval.end, end, flags)) {
-
4860 this->interval.end = m_space->interval.end;
-
4861 continue;
-
4862 }
-
4863 T chr = case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end];
-
4864 if (('0' <= chr && chr <= '9') || ('A' <= chr && chr <= 'Z')) {
-
4865 this->bban[n++] = chr;
-
4866 this->interval.end++;
-
4867 }
-
4868 else
-
4869 goto error; // invalid bban
-
4870 }
-
4871 this->bban[n] = 0;
-
4872
-
4873 // Normalize IBAN.
-
4874 T normalized[69];
-
4875 available = 0;
-
4876 for (size_t i = 0; ; ++i) {
-
4877 if (!this->bban[i]) {
-
4878 for (i = 0; i < 2; ++i) {
-
4879 if ('A' <= this->country[i] && this->country[i] <= 'J') {
-
4880 normalized[available++] = '1';
-
4881 normalized[available++] = '0' + this->country[i] - 'A';
-
4882 }
-
4883 else if ('K' <= this->country[i] && this->country[i] <= 'T') {
-
4884 normalized[available++] = '2';
-
4885 normalized[available++] = '0' + this->country[i] - 'K';
-
4886 }
-
4887 else if ('U' <= this->country[i] && this->country[i] <= 'Z') {
-
4888 normalized[available++] = '3';
-
4889 normalized[available++] = '0' + this->country[i] - 'U';
-
4890 }
-
4891 }
-
4892 normalized[available++] = this->check_digits[0];
-
4893 normalized[available++] = this->check_digits[1];
-
4894 normalized[available] = 0;
-
4895 break;
-
4896 }
-
4897 if ('0' <= this->bban[i] && this->bban[i] <= '9')
-
4898 normalized[available++] = this->bban[i];
-
4899 else if ('A' <= this->bban[i] && this->bban[i] <= 'J') {
-
4900 normalized[available++] = '1';
-
4901 normalized[available++] = '0' + this->bban[i] - 'A';
-
4902 }
-
4903 else if ('K' <= this->bban[i] && this->bban[i] <= 'T') {
-
4904 normalized[available++] = '2';
-
4905 normalized[available++] = '0' + this->bban[i] - 'K';
-
4906 }
-
4907 else if ('U' <= this->bban[i] && this->bban[i] <= 'Z') {
-
4908 normalized[available++] = '3';
-
4909 normalized[available++] = '0' + this->bban[i] - 'U';
-
4910 }
-
4911 }
-
4912
-
4913 // Calculate modulo 97.
-
4914 nominator = stdex::strtou32(normalized, 9, &next, 10);
-
4915 for (;;) {
-
4916 nominator %= 97;
-
4917 if (!normalized[next]) {
-
4918 this->is_valid = nominator == 1;
-
4919 break;
-
4920 }
-
4921 size_t digit_count = nominator == 0 ? 0 : nominator < 10 ? 1 : 2;
-
4922 for (; digit_count < 9 && normalized[next]; ++next, ++digit_count)
-
4923 nominator = nominator * 10 + (normalized[next] - '0');
-
4924 }
-
4925
-
4926 this->interval.start = start;
-
4927 return true;
-
4928
-
4929 error:
-
4930 this->country[0] = 0;
-
4931 this->check_digits[0] = 0;
-
4932 this->bban[0] = 0;
-
4933 this->is_valid = false;
-
4934 this->interval.start = (this->interval.end = start) + 1;
-
4935 return false;
-
4936 }
-
4937
-
4938 virtual void invalidate()
-
4939 {
-
4940 this->country[0] = 0;
-
4941 this->check_digits[0] = 0;
-
4942 this->bban[0] = 0;
-
4943 this->is_valid = false;
- -
4945 }
-
4946
-
4947 public:
-
4948 T country[3];
- -
4950 T bban[31];
- -
4952
-
4953 protected:
-
4954 std::shared_ptr<basic_parser<T>> m_space;
-
4955 };
+
4661
+ + +
4664#ifdef _UNICODE
+ +
4666#else
+ +
4668#endif
+ +
4670
+
4676 template <class T>
+
+
4677 class basic_iban : public basic_parser<T>
+
4678 {
+
4679 public:
+
4680 basic_iban(
+
4681 _In_ const std::shared_ptr<basic_parser<T>>& space,
+
4682 _In_ const std::locale& locale = std::locale()) :
+
4683 basic_parser<T>(locale),
+
4684 m_space(space)
+
4685 {
+
4686 this->country[0] = 0;
+
4687 this->check_digits[0] = 0;
+
4688 this->bban[0] = 0;
+
4689 this->is_valid = false;
+
4690 }
+
4691
+
4692 virtual bool match(
+
4693 _In_reads_or_z_(end) const T* text,
+
4694 _In_ size_t start = 0,
+
4695 _In_ size_t end = (size_t)-1,
+
4696 _In_ int flags = match_default)
+
4697 {
+
4698 _Assume_(text || start >= end);
+
4699 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
+
4700 const bool case_insensitive = flags & match_case_insensitive ? true : false;
+
4701 struct country_t {
+
4702 T country[2];
+
4703 T check_digits[2];
+
4704 size_t length;
+
4705 };
+
4706 static const country_t s_countries[] = {
+
4707 { { 'A', 'D' }, {}, 24 }, // Andorra
+
4708 { { 'A', 'E' }, {}, 23 }, // United Arab Emirates
+
4709 { { 'A', 'L' }, {}, 28 }, // Albania
+
4710 { { 'A', 'O' }, {}, 25 }, // Angola
+
4711 { { 'A', 'T' }, {}, 20 }, // Austria
+
4712 { { 'A', 'Z' }, {}, 28 }, // Azerbaijan
+
4713 { { 'B', 'A' }, { '3', '9' }, 20}, // Bosnia and Herzegovina
+
4714 { { 'B', 'E' }, {}, 16 }, // Belgium
+
4715 { { 'B', 'F' }, {}, 28 }, // Burkina Faso
+
4716 { { 'B', 'G' }, {}, 22 }, // Bulgaria
+
4717 { { 'B', 'H' }, {}, 22 }, // Bahrain
+
4718 { { 'B', 'I' }, {}, 27 }, // Burundi
+
4719 { { 'B', 'J' }, {}, 28 }, // Benin
+
4720 { { 'B', 'R' }, {}, 29 }, // Brazil
+
4721 { { 'B', 'Y' }, {}, 28 }, // Belarus
+
4722 { { 'C', 'F' }, {}, 27 }, // Central African Republic
+
4723 { { 'C', 'G' }, {}, 27 }, // Congo, Republic of the
+
4724 { { 'C', 'H' }, {}, 21 }, // Switzerland
+
4725 { { 'C', 'I' }, {}, 28 }, // Côte d'Ivoire
+
4726 { { 'C', 'M' }, {}, 27 }, // Cameroon
+
4727 { { 'C', 'R' }, {}, 22 }, // Costa Rica
+
4728 { { 'C', 'V' }, {}, 25 }, // Cabo Verde
+
4729 { { 'C', 'Y' }, {}, 28 }, // Cyprus
+
4730 { { 'C', 'Z' }, {}, 24 }, // Czech Republic
+
4731 { { 'D', 'E' }, {}, 22 }, // Germany
+
4732 { { 'D', 'J' }, {}, 27 }, // Djibouti
+
4733 { { 'D', 'K' }, {}, 18 }, // Denmark
+
4734 { { 'D', 'O' }, {}, 28 }, // Dominican Republic
+
4735 { { 'D', 'Z' }, {}, 26 }, // Algeria
+
4736 { { 'E', 'E' }, {}, 20 }, // Estonia
+
4737 { { 'E', 'G' }, {}, 29 }, // Egypt
+
4738 { { 'E', 'S' }, {}, 24 }, // Spain
+
4739 { { 'F', 'I' }, {}, 18 }, // Finland
+
4740 { { 'F', 'O' }, {}, 18 }, // Faroe Islands
+
4741 { { 'F', 'R' }, {}, 27 }, // France
+
4742 { { 'G', 'A' }, {}, 27 }, // Gabon
+
4743 { { 'G', 'B' }, {}, 22 }, // United Kingdom
+
4744 { { 'G', 'E' }, {}, 22 }, // Georgia
+
4745 { { 'G', 'I' }, {}, 23 }, // Gibraltar
+
4746 { { 'G', 'L' }, {}, 18 }, // Greenland
+
4747 { { 'G', 'Q' }, {}, 27 }, // Equatorial Guinea
+
4748 { { 'G', 'R' }, {}, 27 }, // Greece
+
4749 { { 'G', 'T' }, {}, 28 }, // Guatemala
+
4750 { { 'G', 'W' }, {}, 25 }, // Guinea-Bissau
+
4751 { { 'H', 'N' }, {}, 28 }, // Honduras
+
4752 { { 'H', 'R' }, {}, 21 }, // Croatia
+
4753 { { 'H', 'U' }, {}, 28 }, // Hungary
+
4754 { { 'I', 'E' }, {}, 22 }, // Ireland
+
4755 { { 'I', 'L' }, {}, 23 }, // Israel
+
4756 { { 'I', 'Q' }, {}, 23 }, // Iraq
+
4757 { { 'I', 'R' }, {}, 26 }, // Iran
+
4758 { { 'I', 'S' }, {}, 26 }, // Iceland
+
4759 { { 'I', 'T' }, {}, 27 }, // Italy
+
4760 { { 'J', 'O' }, {}, 30 }, // Jordan
+
4761 { { 'K', 'M' }, {}, 27 }, // Comoros
+
4762 { { 'K', 'W' }, {}, 30 }, // Kuwait
+
4763 { { 'K', 'Z' }, {}, 20 }, // Kazakhstan
+
4764 { { 'L', 'B' }, {}, 28 }, // Lebanon
+
4765 { { 'L', 'C' }, {}, 32 }, // Saint Lucia
+
4766 { { 'L', 'I' }, {}, 21 }, // Liechtenstein
+
4767 { { 'L', 'T' }, {}, 20 }, // Lithuania
+
4768 { { 'L', 'U' }, {}, 20 }, // Luxembourg
+
4769 { { 'L', 'V' }, {}, 21 }, // Latvia
+
4770 { { 'L', 'Y' }, {}, 25 }, // Libya
+
4771 { { 'M', 'A' }, {}, 28 }, // Morocco
+
4772 { { 'M', 'C' }, {}, 27 }, // Monaco
+
4773 { { 'M', 'D' }, {}, 24 }, // Moldova
+
4774 { { 'M', 'E' }, { '2', '5' }, 22 }, // Montenegro
+
4775 { { 'M', 'G' }, {}, 27 }, // Madagascar
+
4776 { { 'M', 'K' }, { '0', '7' }, 19 }, // North Macedonia
+
4777 { { 'M', 'L' }, {}, 28 }, // Mali
+
4778 { { 'M', 'R' }, { '1', '3' }, 27}, // Mauritania
+
4779 { { 'M', 'T' }, {}, 31 }, // Malta
+
4780 { { 'M', 'U' }, {}, 30 }, // Mauritius
+
4781 { { 'M', 'Z' }, {}, 25 }, // Mozambique
+
4782 { { 'N', 'E' }, {}, 28 }, // Niger
+
4783 { { 'N', 'I' }, {}, 32 }, // Nicaragua
+
4784 { { 'N', 'L' }, {}, 18 }, // Netherlands
+
4785 { { 'N', 'O' }, {}, 15 }, // Norway
+
4786 { { 'P', 'K' }, {}, 24 }, // Pakistan
+
4787 { { 'P', 'L' }, {}, 28 }, // Poland
+
4788 { { 'P', 'S' }, {}, 29 }, // Palestinian territories
+
4789 { { 'P', 'T' }, { '5', '0' }, 25 }, // Portugal
+
4790 { { 'Q', 'A' }, {}, 29 }, // Qatar
+
4791 { { 'R', 'O' }, {}, 24 }, // Romania
+
4792 { { 'R', 'S' }, { '3', '5' }, 22 }, // Serbia
+
4793 { { 'R', 'U' }, {}, 33 }, // Russia
+
4794 { { 'S', 'A' }, {}, 24 }, // Saudi Arabia
+
4795 { { 'S', 'C' }, {}, 31 }, // Seychelles
+
4796 { { 'S', 'D' }, {}, 18 }, // Sudan
+
4797 { { 'S', 'E' }, {}, 24 }, // Sweden
+
4798 { { 'S', 'I' }, { '5', '6' }, 19 }, // Slovenia
+
4799 { { 'S', 'K' }, {}, 24 }, // Slovakia
+
4800 { { 'S', 'M' }, {}, 27 }, // San Marino
+
4801 { { 'S', 'N' }, {}, 28 }, // Senegal
+
4802 { { 'S', 'T' }, {}, 25 }, // São Tomé and Príncipe
+
4803 { { 'S', 'V' }, {}, 28 }, // El Salvador
+
4804 { { 'T', 'D' }, {}, 27 }, // Chad
+
4805 { { 'T', 'G' }, {}, 28 }, // Togo
+
4806 { { 'T', 'L' }, { '3', '8' }, 23}, // East Timor
+
4807 { { 'T', 'N' }, { '5', '9' }, 24 }, // Tunisia
+
4808 { { 'T', 'R' }, {}, 26 }, // Turkey
+
4809 { { 'U', 'A' }, {}, 29 }, // Ukraine
+
4810 { { 'V', 'A' }, {}, 22 }, // Vatican City
+
4811 { { 'V', 'G' }, {}, 24 }, // Virgin Islands, British
+
4812 { { 'X', 'K' }, {}, 20 }, // Kosovo
+
4813 };
+
4814 const country_t* country_desc = nullptr;
+
4815 size_t n, available, next, bban_length;
+ +
4817
+
4818 this->interval.end = start;
+
4819 for (size_t i = 0; i < 2; ++i, ++this->interval.end) {
+
4820 if (this->interval.end >= end || !text[this->interval.end])
+
4821 goto error; // incomplete country code
+
4822 T chr = case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end];
+
4823 if (chr < 'A' || 'Z' < chr)
+
4824 goto error; // invalid country code
+
4825 this->country[i] = chr;
+
4826 }
+
4827 for (size_t l = 0, r = _countof(s_countries);;) {
+
4828 if (l >= r)
+
4829 goto error; // unknown country
+
4830 size_t m = (l + r) / 2;
+
4831 const country_t& c = s_countries[m];
+
4832 if (c.country[0] < this->country[0] || (c.country[0] == this->country[0] && c.country[1] < this->country[1]))
+
4833 l = m + 1;
+
4834 else if (this->country[0] < c.country[0] || (this->country[0] == c.country[0] && this->country[1] < c.country[1]))
+
4835 r = m;
+
4836 else {
+
4837 country_desc = &c;
+
4838 break;
+
4839 }
+
4840 }
+
4841 this->country[2] = 0;
+
4842
+
4843 for (size_t i = 0; i < 2; ++i, ++this->interval.end) {
+
4844 if (this->interval.end >= end || text[this->interval.end] < '0' || '9' < text[this->interval.end])
+
4845 goto error; // incomplete or invalid check digits
+
4846 this->check_digits[i] = text[this->interval.end];
+
4847 }
+
4848 this->check_digits[2] = 0;
+
4849
+
4850 if ((country_desc->check_digits[0] && this->check_digits[0] != country_desc->check_digits[0]) ||
+
4851 (country_desc->check_digits[1] && this->check_digits[1] != country_desc->check_digits[1]))
+
4852 goto error; // unexpected check digits
+
4853
+
4854 bban_length = country_desc->length - 4;
+
4855 for (n = 0; n < bban_length;) {
+
4856 if (this->interval.end >= end || !text[this->interval.end])
+
4857 goto error; // bban too short
+
4858 if (m_space && m_space->match(text, this->interval.end, end, flags)) {
+
4859 this->interval.end = m_space->interval.end;
+
4860 continue;
+
4861 }
+
4862 T chr = case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end];
+
4863 if (('0' <= chr && chr <= '9') || ('A' <= chr && chr <= 'Z')) {
+
4864 this->bban[n++] = chr;
+
4865 this->interval.end++;
+
4866 }
+
4867 else
+
4868 goto error; // invalid bban
+
4869 }
+
4870 this->bban[n] = 0;
+
4871
+
4872 // Normalize IBAN.
+
4873 T normalized[69];
+
4874 available = 0;
+
4875 for (size_t i = 0; ; ++i) {
+
4876 if (!this->bban[i]) {
+
4877 for (i = 0; i < 2; ++i) {
+
4878 if ('A' <= this->country[i] && this->country[i] <= 'J') {
+
4879 normalized[available++] = '1';
+
4880 normalized[available++] = '0' + this->country[i] - 'A';
+
4881 }
+
4882 else if ('K' <= this->country[i] && this->country[i] <= 'T') {
+
4883 normalized[available++] = '2';
+
4884 normalized[available++] = '0' + this->country[i] - 'K';
+
4885 }
+
4886 else if ('U' <= this->country[i] && this->country[i] <= 'Z') {
+
4887 normalized[available++] = '3';
+
4888 normalized[available++] = '0' + this->country[i] - 'U';
+
4889 }
+
4890 }
+
4891 normalized[available++] = this->check_digits[0];
+
4892 normalized[available++] = this->check_digits[1];
+
4893 normalized[available] = 0;
+
4894 break;
+
4895 }
+
4896 if ('0' <= this->bban[i] && this->bban[i] <= '9')
+
4897 normalized[available++] = this->bban[i];
+
4898 else if ('A' <= this->bban[i] && this->bban[i] <= 'J') {
+
4899 normalized[available++] = '1';
+
4900 normalized[available++] = '0' + this->bban[i] - 'A';
+
4901 }
+
4902 else if ('K' <= this->bban[i] && this->bban[i] <= 'T') {
+
4903 normalized[available++] = '2';
+
4904 normalized[available++] = '0' + this->bban[i] - 'K';
+
4905 }
+
4906 else if ('U' <= this->bban[i] && this->bban[i] <= 'Z') {
+
4907 normalized[available++] = '3';
+
4908 normalized[available++] = '0' + this->bban[i] - 'U';
+
4909 }
+
4910 }
+
4911
+
4912 // Calculate modulo 97.
+
4913 nominator = stdex::strtou32(normalized, 9, &next, 10);
+
4914 for (;;) {
+
4915 nominator %= 97;
+
4916 if (!normalized[next]) {
+
4917 this->is_valid = nominator == 1;
+
4918 break;
+
4919 }
+
4920 size_t digit_count = nominator == 0 ? 0 : nominator < 10 ? 1 : 2;
+
4921 for (; digit_count < 9 && normalized[next]; ++next, ++digit_count)
+
4922 nominator = nominator * 10 + (normalized[next] - '0');
+
4923 }
+
4924
+
4925 this->interval.start = start;
+
4926 return true;
+
4927
+
4928 error:
+
4929 this->country[0] = 0;
+
4930 this->check_digits[0] = 0;
+
4931 this->bban[0] = 0;
+
4932 this->is_valid = false;
+
4933 this->interval.start = (this->interval.end = start) + 1;
+
4934 return false;
+
4935 }
+
4936
+
4937 virtual void invalidate()
+
4938 {
+
4939 this->country[0] = 0;
+
4940 this->check_digits[0] = 0;
+
4941 this->bban[0] = 0;
+
4942 this->is_valid = false;
+ +
4944 }
+
4945
+
4946 public:
+
4947 T country[3];
+ +
4949 T bban[31];
+ +
4951
+
4952 protected:
+
4953 std::shared_ptr<basic_parser<T>> m_space;
+
4954 };
-
4956
-
4957 using iban = basic_iban<char>;
-
4958 using wiban = basic_iban<wchar_t>;
-
4959#ifdef _UNICODE
-
4960 using tiban = wiban;
-
4961#else
-
4962 using tiban = iban;
-
4963#endif
- -
4965
-
4971 template <class T>
-
- -
4973 {
-
4974 public:
- -
4976 _In_ const std::shared_ptr<basic_parser<T>>& space,
-
4977 _In_ const std::locale& locale = std::locale()) :
-
4978 basic_parser<T>(locale),
-
4979 m_space(space)
-
4980 {
-
4981 this->check_digits[0] = 0;
-
4982 this->reference[0] = 0;
-
4983 this->is_valid = false;
-
4984 }
-
4985
-
4986 virtual bool match(
-
4987 _In_reads_or_z_(end) const T* text,
-
4988 _In_ size_t start = 0,
-
4989 _In_ size_t end = (size_t)-1,
-
4990 _In_ int flags = match_default)
-
4991 {
-
4992 _Assume_(text || start >= end);
-
4993 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
-
4994 const bool case_insensitive = flags & match_case_insensitive ? true : false;
-
4995 size_t n, available, next;
- -
4997
-
4998 this->interval.end = start;
-
4999 if (this->interval.end + 1 >= end ||
-
5000 (case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end]) != 'R' ||
-
5001 (case_insensitive ? ctype.toupper(text[this->interval.end + 1]) : text[this->interval.end + 1]) != 'F')
-
5002 goto error; // incomplete or wrong reference ID
-
5003 this->interval.end += 2;
-
5004
-
5005 for (size_t i = 0; i < 2; ++i, ++this->interval.end) {
-
5006 if (this->interval.end >= end || text[this->interval.end] < '0' || '9' < text[this->interval.end])
-
5007 goto error; // incomplete or invalid check digits
-
5008 this->check_digits[i] = text[this->interval.end];
-
5009 }
-
5010 this->check_digits[2] = 0;
-
5011
-
5012 for (n = 0;;) {
-
5013 if (m_space && m_space->match(text, this->interval.end, end, flags))
-
5014 this->interval.end = m_space->interval.end;
-
5015 for (size_t j = 0; j < 4; ++j) {
-
5016 if (this->interval.end >= end || !text[this->interval.end])
-
5017 goto out;
-
5018 T chr = case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end];
-
5019 if (('0' <= chr && chr <= '9') || ('A' <= chr && chr <= 'Z')) {
-
5020 if (n >= _countof(reference) - 1)
-
5021 goto error; // reference overflow
-
5022 this->reference[n++] = chr;
-
5023 this->interval.end++;
-
5024 }
-
5025 else
-
5026 goto out;
-
5027 }
-
5028 }
-
5029 out:
-
5030 if (!n)
-
5031 goto error; // reference too short
-
5032 this->reference[_countof(this->reference) - 1] = 0;
-
5033 for (size_t i = n, j = _countof(this->reference) - 1; i;)
-
5034 this->reference[--j] = this->reference[--i];
-
5035 for (size_t j = _countof(this->reference) - 1 - n; j;)
-
5036 this->reference[--j] = '0';
-
5037
-
5038 // Normalize creditor reference.
-
5039 T normalized[47];
-
5040 available = 0;
-
5041 for (size_t i = 0; ; ++i) {
-
5042 if (!this->reference[i]) {
-
5043 normalized[available++] = '2'; // R
-
5044 normalized[available++] = '7';
-
5045 normalized[available++] = '1'; // F
-
5046 normalized[available++] = '5';
-
5047 normalized[available++] = this->check_digits[0];
-
5048 normalized[available++] = this->check_digits[1];
-
5049 normalized[available] = 0;
-
5050 break;
-
5051 }
-
5052 if ('0' <= this->reference[i] && this->reference[i] <= '9')
-
5053 normalized[available++] = this->reference[i];
-
5054 else if ('A' <= this->reference[i] && this->reference[i] <= 'J') {
-
5055 normalized[available++] = '1';
-
5056 normalized[available++] = '0' + this->reference[i] - 'A';
-
5057 }
-
5058 else if ('K' <= this->reference[i] && this->reference[i] <= 'T') {
-
5059 normalized[available++] = '2';
-
5060 normalized[available++] = '0' + this->reference[i] - 'K';
-
5061 }
-
5062 else if ('U' <= this->reference[i] && this->reference[i] <= 'Z') {
-
5063 normalized[available++] = '3';
-
5064 normalized[available++] = '0' + this->reference[i] - 'U';
-
5065 }
-
5066 }
-
5067
-
5068 // Calculate modulo 97.
-
5069 nominator = stdex::strtou32(normalized, 9, &next, 10);
-
5070 for (;;) {
-
5071 nominator %= 97;
-
5072 if (!normalized[next]) {
-
5073 this->is_valid = nominator == 1;
-
5074 break;
-
5075 }
-
5076 size_t digit_count = nominator == 0 ? 0 : nominator < 10 ? 1 : 2;
-
5077 for (; digit_count < 9 && normalized[next]; ++next, ++digit_count)
-
5078 nominator = nominator * 10 + (normalized[next] - '0');
-
5079 }
-
5080
-
5081 this->interval.start = start;
-
5082 return true;
-
5083
-
5084 error:
-
5085 this->check_digits[0] = 0;
-
5086 this->reference[0] = 0;
-
5087 this->is_valid = false;
-
5088 this->interval.start = (this->interval.end = start) + 1;
-
5089 return false;
-
5090 }
-
5091
-
5092 virtual void invalidate()
-
5093 {
-
5094 this->check_digits[0] = 0;
-
5095 this->reference[0] = 0;
-
5096 this->is_valid = false;
- -
5098 }
-
5099
-
5100 public:
- - - -
5104
-
5105 protected:
-
5106 std::shared_ptr<basic_parser<T>> m_space;
-
5107 };
+
4955
+
4956 using iban = basic_iban<char>;
+
4957 using wiban = basic_iban<wchar_t>;
+
4958#ifdef _UNICODE
+
4959 using tiban = wiban;
+
4960#else
+
4961 using tiban = iban;
+
4962#endif
+ +
4964
+
4970 template <class T>
+
+ +
4972 {
+
4973 public:
+ +
4975 _In_ const std::shared_ptr<basic_parser<T>>& space,
+
4976 _In_ const std::locale& locale = std::locale()) :
+
4977 basic_parser<T>(locale),
+
4978 m_space(space)
+
4979 {
+
4980 this->check_digits[0] = 0;
+
4981 this->reference[0] = 0;
+
4982 this->is_valid = false;
+
4983 }
+
4984
+
4985 virtual bool match(
+
4986 _In_reads_or_z_(end) const T* text,
+
4987 _In_ size_t start = 0,
+
4988 _In_ size_t end = (size_t)-1,
+
4989 _In_ int flags = match_default)
+
4990 {
+
4991 _Assume_(text || start >= end);
+
4992 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
+
4993 const bool case_insensitive = flags & match_case_insensitive ? true : false;
+
4994 size_t n, available, next;
+ +
4996
+
4997 this->interval.end = start;
+
4998 if (this->interval.end + 1 >= end ||
+
4999 (case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end]) != 'R' ||
+
5000 (case_insensitive ? ctype.toupper(text[this->interval.end + 1]) : text[this->interval.end + 1]) != 'F')
+
5001 goto error; // incomplete or wrong reference ID
+
5002 this->interval.end += 2;
+
5003
+
5004 for (size_t i = 0; i < 2; ++i, ++this->interval.end) {
+
5005 if (this->interval.end >= end || text[this->interval.end] < '0' || '9' < text[this->interval.end])
+
5006 goto error; // incomplete or invalid check digits
+
5007 this->check_digits[i] = text[this->interval.end];
+
5008 }
+
5009 this->check_digits[2] = 0;
+
5010
+
5011 for (n = 0;;) {
+
5012 if (m_space && m_space->match(text, this->interval.end, end, flags))
+
5013 this->interval.end = m_space->interval.end;
+
5014 for (size_t j = 0; j < 4; ++j) {
+
5015 if (this->interval.end >= end || !text[this->interval.end])
+
5016 goto out;
+
5017 T chr = case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end];
+
5018 if (('0' <= chr && chr <= '9') || ('A' <= chr && chr <= 'Z')) {
+
5019 if (n >= _countof(reference) - 1)
+
5020 goto error; // reference overflow
+
5021 this->reference[n++] = chr;
+
5022 this->interval.end++;
+
5023 }
+
5024 else
+
5025 goto out;
+
5026 }
+
5027 }
+
5028 out:
+
5029 if (!n)
+
5030 goto error; // reference too short
+
5031 this->reference[_countof(this->reference) - 1] = 0;
+
5032 for (size_t i = n, j = _countof(this->reference) - 1; i;)
+
5033 this->reference[--j] = this->reference[--i];
+
5034 for (size_t j = _countof(this->reference) - 1 - n; j;)
+
5035 this->reference[--j] = '0';
+
5036
+
5037 // Normalize creditor reference.
+
5038 T normalized[47];
+
5039 available = 0;
+
5040 for (size_t i = 0; ; ++i) {
+
5041 if (!this->reference[i]) {
+
5042 normalized[available++] = '2'; // R
+
5043 normalized[available++] = '7';
+
5044 normalized[available++] = '1'; // F
+
5045 normalized[available++] = '5';
+
5046 normalized[available++] = this->check_digits[0];
+
5047 normalized[available++] = this->check_digits[1];
+
5048 normalized[available] = 0;
+
5049 break;
+
5050 }
+
5051 if ('0' <= this->reference[i] && this->reference[i] <= '9')
+
5052 normalized[available++] = this->reference[i];
+
5053 else if ('A' <= this->reference[i] && this->reference[i] <= 'J') {
+
5054 normalized[available++] = '1';
+
5055 normalized[available++] = '0' + this->reference[i] - 'A';
+
5056 }
+
5057 else if ('K' <= this->reference[i] && this->reference[i] <= 'T') {
+
5058 normalized[available++] = '2';
+
5059 normalized[available++] = '0' + this->reference[i] - 'K';
+
5060 }
+
5061 else if ('U' <= this->reference[i] && this->reference[i] <= 'Z') {
+
5062 normalized[available++] = '3';
+
5063 normalized[available++] = '0' + this->reference[i] - 'U';
+
5064 }
+
5065 }
+
5066
+
5067 // Calculate modulo 97.
+
5068 nominator = stdex::strtou32(normalized, 9, &next, 10);
+
5069 for (;;) {
+
5070 nominator %= 97;
+
5071 if (!normalized[next]) {
+
5072 this->is_valid = nominator == 1;
+
5073 break;
+
5074 }
+
5075 size_t digit_count = nominator == 0 ? 0 : nominator < 10 ? 1 : 2;
+
5076 for (; digit_count < 9 && normalized[next]; ++next, ++digit_count)
+
5077 nominator = nominator * 10 + (normalized[next] - '0');
+
5078 }
+
5079
+
5080 this->interval.start = start;
+
5081 return true;
+
5082
+
5083 error:
+
5084 this->check_digits[0] = 0;
+
5085 this->reference[0] = 0;
+
5086 this->is_valid = false;
+
5087 this->interval.start = (this->interval.end = start) + 1;
+
5088 return false;
+
5089 }
+
5090
+
5091 virtual void invalidate()
+
5092 {
+
5093 this->check_digits[0] = 0;
+
5094 this->reference[0] = 0;
+
5095 this->is_valid = false;
+ +
5097 }
+
5098
+
5099 public:
+ + + +
5103
+
5104 protected:
+
5105 std::shared_ptr<basic_parser<T>> m_space;
+
5106 };
-
5108
- - -
5111#ifdef _UNICODE
- -
5113#else
- -
5115#endif
- -
5117
-
5123 template <class T>
-
- -
5125 {
-
5126 public:
-
5127 basic_si_reference_part(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
-
5128
-
5129 virtual bool match(
-
5130 _In_reads_or_z_(end) const T* text,
-
5131 _In_ size_t start = 0,
-
5132 _In_ size_t end = (size_t)-1,
-
5133 _In_ int flags = match_default)
-
5134 {
-
5135 _Assume_(text || start >= end);
-
5136 this->interval.end = start;
-
5137 for (;;) {
-
5138 if (this->interval.end >= end || !text[this->interval.end])
-
5139 break;
-
5140 if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9')
-
5141 this->interval.end++;
-
5142 else
-
5143 break;
-
5144 }
- -
5146 this->interval.start = start;
-
5147 return true;
-
5148 }
-
5149 this->interval.start = (this->interval.end = start) + 1;
-
5150 return false;
-
5151 }
-
5152 };
+
5107
+ + +
5110#ifdef _UNICODE
+ +
5112#else
+ +
5114#endif
+ +
5116
+
5122 template <class T>
+
+ +
5124 {
+
5125 public:
+
5126 basic_si_reference_part(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
+
5127
+
5128 virtual bool match(
+
5129 _In_reads_or_z_(end) const T* text,
+
5130 _In_ size_t start = 0,
+
5131 _In_ size_t end = (size_t)-1,
+
5132 _In_ int flags = match_default)
+
5133 {
+
5134 _Assume_(text || start >= end);
+
5135 this->interval.end = start;
+
5136 for (;;) {
+
5137 if (this->interval.end >= end || !text[this->interval.end])
+
5138 break;
+
5139 if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9')
+
5140 this->interval.end++;
+
5141 else
+
5142 break;
+
5143 }
+ +
5145 this->interval.start = start;
+
5146 return true;
+
5147 }
+
5148 this->interval.start = (this->interval.end = start) + 1;
+
5149 return false;
+
5150 }
+
5151 };
-
5153
- - -
5156#ifdef _UNICODE
- -
5158#else
- -
5160#endif
- -
5162
-
5168 template <class T>
-
- -
5170 {
-
5171 public:
-
5172 basic_si_reference_delimiter(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
-
5173
-
5174 virtual bool match(
-
5175 _In_reads_or_z_(end) const T* text,
-
5176 _In_ size_t start = 0,
-
5177 _In_ size_t end = (size_t)-1,
-
5178 _In_ int flags = match_default)
-
5179 {
-
5180 _Assume_(text || start >= end);
-
5181 if (start < end && text[start] == '-') {
-
5182 this->interval.end = (this->interval.start = start) + 1;
-
5183 return true;
-
5184 }
-
5185 this->interval.start = (this->interval.end = start) + 1;
-
5186 return false;
-
5187 }
-
5188 };
+
5152
+ + +
5155#ifdef _UNICODE
+ +
5157#else
+ +
5159#endif
+ +
5161
+
5167 template <class T>
+
+ +
5169 {
+
5170 public:
+
5171 basic_si_reference_delimiter(_In_ const std::locale& locale = std::locale()) : basic_parser<T>(locale) {}
+
5172
+
5173 virtual bool match(
+
5174 _In_reads_or_z_(end) const T* text,
+
5175 _In_ size_t start = 0,
+
5176 _In_ size_t end = (size_t)-1,
+
5177 _In_ int flags = match_default)
+
5178 {
+
5179 _Assume_(text || start >= end);
+
5180 if (start < end && text[start] == '-') {
+
5181 this->interval.end = (this->interval.start = start) + 1;
+
5182 return true;
+
5183 }
+
5184 this->interval.start = (this->interval.end = start) + 1;
+
5185 return false;
+
5186 }
+
5187 };
-
5189
- - -
5192#ifdef _UNICODE
- -
5194#else
- -
5196#endif
- -
5198
-
5206 template <class T>
-
- -
5208 {
-
5209 public:
- -
5211 _In_ const std::shared_ptr<basic_parser<T>>& space,
-
5212 _In_ const std::locale& locale = std::locale()) :
-
5213 basic_parser<T>(locale),
-
5214 part1(locale),
-
5215 part2(locale),
-
5216 part3(locale),
-
5217 is_valid(false),
-
5218 m_space(space),
-
5219 m_delimiter(locale)
-
5220 {
-
5221 this->model[0] = 0;
-
5222 }
-
5223
-
5224 virtual bool match(
-
5225 _In_reads_or_z_(end) const T* text,
-
5226 _In_ size_t start = 0,
-
5227 _In_ size_t end = (size_t)-1,
-
5228 _In_ int flags = match_default)
-
5229 {
-
5230 _Assume_(text || start >= end);
-
5231 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
-
5232 const bool case_insensitive = flags & match_case_insensitive ? true : false;
-
5233
-
5234 this->interval.end = start;
-
5235 if (this->interval.end + 1 >= end ||
-
5236 (case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end]) != 'S' ||
-
5237 (case_insensitive ? ctype.toupper(text[this->interval.end + 1]) : text[this->interval.end + 1]) != 'I')
-
5238 goto error; // incomplete or wrong reference ID
-
5239 this->interval.end += 2;
-
5240
-
5241 for (size_t i = 0; i < 2; ++i, ++this->interval.end) {
-
5242 if (this->interval.end >= end || text[this->interval.end] < '0' || '9' < text[this->interval.end])
-
5243 goto error; // incomplete or invalid model
-
5244 this->model[i] = text[this->interval.end];
-
5245 }
-
5246 this->model[2] = 0;
-
5247
-
5248 this->part1.invalidate();
-
5249 this->part2.invalidate();
-
5250 this->part3.invalidate();
-
5251 if (this->model[0] == '9' && this->model[1] == '9') {
-
5252 is_valid = true;
-
5253 this->interval.start = start;
-
5254 return true;
-
5255 }
-
5256
-
5257 if (m_space && m_space->match(text, this->interval.end, end, flags))
-
5258 this->interval.end = m_space->interval.end;
-
5259
-
5260 this->part1.match(text, this->interval.end, end, flags) &&
-
5261 this->m_delimiter.match(text, this->part1.interval.end, end, flags) &&
-
5262 this->part2.match(text, this->m_delimiter.interval.end, end, flags) &&
-
5263 this->m_delimiter.match(text, this->part2.interval.end, end, flags) &&
-
5264 this->part3.match(text, this->m_delimiter.interval.end, end, flags);
-
5265
-
5266 this->interval.start = start;
-
5267 if (this->part3.interval)
-
5268 this->interval.end = this->part3.interval.end;
-
5269 else if (this->part2.interval)
-
5270 this->interval.end = this->part2.interval.end;
-
5271 else if (this->part1.interval)
-
5272 this->interval.end = this->part1.interval.end;
-
5273 else
-
5274 this->interval.end = start + 4;
-
5275
-
5276 if (this->model[0] == '0' && this->model[1] == '0')
-
5277 is_valid =
-
5278 this->part3.interval ?
-
5279 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
-
5280 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 :
-
5281 this->part2.interval ?
-
5282 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
-
5283 this->part1.interval.size() + this->part2.interval.size() <= 20 :
-
5284 this->part1.interval ?
-
5285 this->part1.interval.size() <= 12 :
-
5286 false;
-
5287 else if (this->model[0] == '0' && this->model[1] == '1')
-
5288 is_valid =
-
5289 this->part3.interval ?
-
5290 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
-
5291 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
-
5292 check11(
-
5293 text + this->part1.interval.start, this->part1.interval.size(),
-
5294 text + this->part2.interval.start, this->part2.interval.size(),
-
5295 text + this->part3.interval.start, this->part3.interval.size()) :
-
5296 this->part2.interval ?
-
5297 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
-
5298 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
-
5299 check11(
-
5300 text + this->part1.interval.start, this->part1.interval.size(),
-
5301 text + this->part2.interval.start, this->part2.interval.size()) :
-
5302 this->part1.interval ?
-
5303 this->part1.interval.size() <= 12 &&
-
5304 check11(text + this->part1.interval.start, this->part1.interval.size()) :
-
5305 false;
-
5306 else if (this->model[0] == '0' && this->model[1] == '2')
-
5307 is_valid =
-
5308 this->part3.interval ?
-
5309 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
-
5310 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
-
5311 check11(text + this->part2.interval.start, this->part2.interval.size()) &&
-
5312 check11(text + this->part3.interval.start, this->part3.interval.size()) :
-
5313 false;
-
5314 else if (this->model[0] == '0' && this->model[1] == '3')
-
5315 is_valid =
-
5316 this->part3.interval ?
-
5317 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
-
5318 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
-
5319 check11(text + this->part1.interval.start, this->part1.interval.size()) &&
-
5320 check11(text + this->part2.interval.start, this->part2.interval.size()) &&
-
5321 check11(text + this->part3.interval.start, this->part3.interval.size()) :
-
5322 false;
-
5323 else if (this->model[0] == '0' && this->model[1] == '4')
-
5324 is_valid =
-
5325 this->part3.interval ?
-
5326 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
-
5327 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
-
5328 check11(text + this->part1.interval.start, this->part1.interval.size()) &&
-
5329 check11(text + this->part3.interval.start, this->part3.interval.size()) :
-
5330 false;
-
5331 else if ((this->model[0] == '0' || this->model[0] == '5') && this->model[1] == '5')
-
5332 is_valid =
-
5333 this->part3.interval ?
-
5334 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
-
5335 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
-
5336 check11(text + this->part1.interval.start, this->part1.interval.size()) :
-
5337 this->part2.interval ?
-
5338 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
-
5339 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
-
5340 check11(text + this->part1.interval.start, this->part1.interval.size()) :
-
5341 this->part1.interval ?
-
5342 this->part1.interval.size() <= 12 &&
-
5343 check11(text + this->part1.interval.start, this->part1.interval.size()) :
-
5344 false;
-
5345 else if (this->model[0] == '0' && this->model[1] == '6')
-
5346 is_valid =
-
5347 this->part3.interval ?
-
5348 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
-
5349 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
-
5350 check11(
-
5351 text + this->part2.interval.start, this->part2.interval.size(),
-
5352 text + this->part3.interval.start, this->part3.interval.size()) :
-
5353 this->part2.interval ?
-
5354 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
-
5355 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
-
5356 check11(text + this->part2.interval.start, this->part2.interval.size()) :
-
5357 false;
-
5358 else if (this->model[0] == '0' && this->model[1] == '7')
-
5359 is_valid =
-
5360 this->part3.interval ?
-
5361 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
-
5362 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
-
5363 check11(text + this->part2.interval.start, this->part2.interval.size()) :
-
5364 this->part2.interval ?
-
5365 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
-
5366 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
-
5367 check11(text + this->part2.interval.start, this->part2.interval.size()) :
-
5368 false;
-
5369 else if (this->model[0] == '0' && this->model[1] == '8')
-
5370 is_valid =
-
5371 this->part3.interval ?
-
5372 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
-
5373 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
-
5374 check11(
-
5375 text + this->part1.interval.start, this->part1.interval.size(),
-
5376 text + this->part2.interval.start, this->part2.interval.size()) &&
-
5377 check11(text + this->part3.interval.start, this->part3.interval.size()) :
-
5378 false;
-
5379 else if (this->model[0] == '0' && this->model[1] == '9')
-
5380 is_valid =
-
5381 this->part3.interval ?
-
5382 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
-
5383 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
-
5384 check11(
-
5385 text + this->part1.interval.start, this->part1.interval.size(),
-
5386 text + this->part2.interval.start, this->part2.interval.size()) :
-
5387 this->part2.interval ?
-
5388 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
-
5389 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
-
5390 check11(
-
5391 text + this->part1.interval.start, this->part1.interval.size(),
-
5392 text + this->part2.interval.start, this->part2.interval.size()) :
-
5393 this->part1.interval ?
-
5394 this->part1.interval.size() <= 12 &&
-
5395 check11(text + this->part1.interval.start, this->part1.interval.size()) :
-
5396 false;
-
5397 else if (this->model[0] == '1' && this->model[1] == '0')
-
5398 is_valid =
-
5399 this->part3.interval ?
-
5400 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
-
5401 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
-
5402 check11(text + this->part1.interval.start, this->part1.interval.size()) &&
-
5403 check11(
-
5404 text + this->part2.interval.start, this->part2.interval.size(),
-
5405 text + this->part3.interval.start, this->part3.interval.size()) :
-
5406 this->part2.interval ?
-
5407 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
-
5408 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
-
5409 check11(text + this->part1.interval.start, this->part1.interval.size()) &&
-
5410 check11(text + this->part2.interval.start, this->part2.interval.size()) :
-
5411 false;
-
5412 else if (
-
5413 (this->model[0] == '1' && (this->model[1] == '1' || this->model[1] == '8' || this->model[1] == '9')) ||
-
5414 ((this->model[0] == '2' || this->model[0] == '3') && this->model[1] == '8') ||
-
5415 (this->model[0] == '4' && (this->model[1] == '0' || this->model[1] == '1' || this->model[1] == '8' || this->model[1] == '9')) ||
-
5416 (this->model[0] == '5' && (this->model[1] == '1' || this->model[1] == '8')))
-
5417 is_valid =
-
5418 this->part3.interval ?
-
5419 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
-
5420 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
-
5421 check11(text + this->part1.interval.start, this->part1.interval.size()) &&
-
5422 check11(text + this->part2.interval.start, this->part2.interval.size()) :
-
5423 this->part2.interval ?
-
5424 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
-
5425 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
-
5426 check11(text + this->part1.interval.start, this->part1.interval.size()) &&
-
5427 check11(text + this->part2.interval.start, this->part2.interval.size()) :
-
5428 false;
-
5429 else if (this->model[0] == '1' && this->model[1] == '2')
-
5430 is_valid =
-
5431 this->part3.interval ? false :
-
5432 this->part2.interval ? false :
-
5433 this->part1.interval ?
-
5434 this->part1.interval.size() <= 13 &&
-
5435 check11(text + this->part1.interval.start, this->part1.interval.size()) :
-
5436 false;
-
5437 else if ((this->model[0] == '2' || this->model[0] == '3') && this->model[1] == '1')
-
5438 is_valid =
-
5439 this->part3.interval ? false :
-
5440 this->part2.interval ?
-
5441 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
-
5442 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
-
5443 check11(text + this->part1.interval.start, this->part1.interval.size()) :
-
5444 false;
-
5445 else
-
5446 is_valid = true; // Assume models we don't handle as valid
-
5447 return true;
-
5448
-
5449 error:
-
5450 this->model[0] = 0;
-
5451 this->part1.interval.start = (this->part1.interval.end = start) + 1;
-
5452 this->part2.interval.start = (this->part2.interval.end = start) + 1;
-
5453 this->part3.interval.start = (this->part3.interval.end = start) + 1;
-
5454 this->is_valid = false;
-
5455 this->interval.start = (this->interval.end = start) + 1;
-
5456 return false;
-
5457 }
-
5458
-
5459 virtual void invalidate()
-
5460 {
-
5461 this->model[0] = 0;
-
5462 this->part1.invalidate();
-
5463 this->part2.invalidate();
-
5464 this->part3.invalidate();
-
5465 this->is_valid = false;
- -
5467 }
-
5468
-
5469 protected:
-
5470 static bool check11(
-
5471 _In_count_(num_part1) const T* part1, _In_ size_t num_part1)
-
5472 {
-
5473 _Assume_(part1 && num_part1 >= 1);
-
5474 uint32_t nominator = 0, ponder = 2;
-
5475 for (size_t i = num_part1 - 1; i--; ++ponder)
-
5476 nominator += (part1[i] - '0') * ponder;
-
5477 uint8_t control = 11 - static_cast<uint8_t>(nominator % 11);
-
5478 if (control >= 10)
-
5479 control = 0;
-
5480 return control == part1[num_part1 - 1] - '0';
-
5481 }
-
5482
-
5483 static bool check11(
-
5484 _In_count_(num_part1) const T* part1, _In_ size_t num_part1,
-
5485 _In_count_(num_part2) const T* part2, _In_ size_t num_part2)
-
5486 {
-
5487 _Assume_(part1 || !num_part1);
-
5488 _Assume_(part2 && num_part2 >= 1);
-
5489 uint32_t nominator = 0, ponder = 2;
-
5490 for (size_t i = num_part2 - 1; i--; ++ponder)
-
5491 nominator += (part2[i] - '0') * ponder;
-
5492 for (size_t i = num_part1; i--; ++ponder)
-
5493 nominator += (part1[i] - '0') * ponder;
-
5494 uint8_t control = 11 - static_cast<uint8_t>(nominator % 11);
-
5495 if (control == 10)
-
5496 control = 0;
-
5497 return control == part2[num_part2 - 1] - '0';
-
5498 }
-
5499
-
5500 static bool check11(
-
5501 _In_count_(num_part1) const T* part1, _In_ size_t num_part1,
-
5502 _In_count_(num_part2) const T* part2, _In_ size_t num_part2,
-
5503 _In_count_(num_part3) const T* part3, _In_ size_t num_part3)
-
5504 {
-
5505 _Assume_(part1 || !num_part1);
-
5506 _Assume_(part2 || !num_part2);
-
5507 _Assume_(part3 && num_part3 >= 1);
-
5508 uint32_t nominator = 0, ponder = 2;
-
5509 for (size_t i = num_part3 - 1; i--; ++ponder)
-
5510 nominator += (part3[i] - '0') * ponder;
-
5511 for (size_t i = num_part2; i--; ++ponder)
-
5512 nominator += (part2[i] - '0') * ponder;
-
5513 for (size_t i = num_part1; i--; ++ponder)
-
5514 nominator += (part1[i] - '0') * ponder;
-
5515 uint8_t control = 11 - static_cast<uint8_t>(nominator % 11);
-
5516 if (control == 10)
-
5517 control = 0;
-
5518 return control == part2[num_part3 - 1] - '0';
-
5519 }
-
5520
-
5521 public:
-
5522 T model[3];
- - - - -
5527
-
5528 protected:
-
5529 std::shared_ptr<basic_parser<T>> m_space;
- -
5531 };
+
5188
+ + +
5191#ifdef _UNICODE
+ +
5193#else
+ +
5195#endif
+ +
5197
+
5205 template <class T>
+
+ +
5207 {
+
5208 public:
+ +
5210 _In_ const std::shared_ptr<basic_parser<T>>& space,
+
5211 _In_ const std::locale& locale = std::locale()) :
+
5212 basic_parser<T>(locale),
+
5213 part1(locale),
+
5214 part2(locale),
+
5215 part3(locale),
+
5216 is_valid(false),
+
5217 m_space(space),
+
5218 m_delimiter(locale)
+
5219 {
+
5220 this->model[0] = 0;
+
5221 }
+
5222
+
5223 virtual bool match(
+
5224 _In_reads_or_z_(end) const T* text,
+
5225 _In_ size_t start = 0,
+
5226 _In_ size_t end = (size_t)-1,
+
5227 _In_ int flags = match_default)
+
5228 {
+
5229 _Assume_(text || start >= end);
+
5230 const auto& ctype = std::use_facet<std::ctype<T>>(this->m_locale);
+
5231 const bool case_insensitive = flags & match_case_insensitive ? true : false;
+
5232
+
5233 this->interval.end = start;
+
5234 if (this->interval.end + 1 >= end ||
+
5235 (case_insensitive ? ctype.toupper(text[this->interval.end]) : text[this->interval.end]) != 'S' ||
+
5236 (case_insensitive ? ctype.toupper(text[this->interval.end + 1]) : text[this->interval.end + 1]) != 'I')
+
5237 goto error; // incomplete or wrong reference ID
+
5238 this->interval.end += 2;
+
5239
+
5240 for (size_t i = 0; i < 2; ++i, ++this->interval.end) {
+
5241 if (this->interval.end >= end || text[this->interval.end] < '0' || '9' < text[this->interval.end])
+
5242 goto error; // incomplete or invalid model
+
5243 this->model[i] = text[this->interval.end];
+
5244 }
+
5245 this->model[2] = 0;
+
5246
+
5247 this->part1.invalidate();
+
5248 this->part2.invalidate();
+
5249 this->part3.invalidate();
+
5250 if (this->model[0] == '9' && this->model[1] == '9') {
+
5251 is_valid = true;
+
5252 this->interval.start = start;
+
5253 return true;
+
5254 }
+
5255
+
5256 if (m_space && m_space->match(text, this->interval.end, end, flags))
+
5257 this->interval.end = m_space->interval.end;
+
5258
+
5259 this->part1.match(text, this->interval.end, end, flags) &&
+
5260 this->m_delimiter.match(text, this->part1.interval.end, end, flags) &&
+
5261 this->part2.match(text, this->m_delimiter.interval.end, end, flags) &&
+
5262 this->m_delimiter.match(text, this->part2.interval.end, end, flags) &&
+
5263 this->part3.match(text, this->m_delimiter.interval.end, end, flags);
+
5264
+
5265 this->interval.start = start;
+
5266 if (this->part3.interval)
+
5267 this->interval.end = this->part3.interval.end;
+
5268 else if (this->part2.interval)
+
5269 this->interval.end = this->part2.interval.end;
+
5270 else if (this->part1.interval)
+
5271 this->interval.end = this->part1.interval.end;
+
5272 else
+
5273 this->interval.end = start + 4;
+
5274
+
5275 if (this->model[0] == '0' && this->model[1] == '0')
+
5276 is_valid =
+
5277 this->part3.interval ?
+
5278 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
+
5279 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 :
+
5280 this->part2.interval ?
+
5281 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
+
5282 this->part1.interval.size() + this->part2.interval.size() <= 20 :
+
5283 this->part1.interval ?
+
5284 this->part1.interval.size() <= 12 :
+
5285 false;
+
5286 else if (this->model[0] == '0' && this->model[1] == '1')
+
5287 is_valid =
+
5288 this->part3.interval ?
+
5289 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
+
5290 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
+
5291 check11(
+
5292 text + this->part1.interval.start, this->part1.interval.size(),
+
5293 text + this->part2.interval.start, this->part2.interval.size(),
+
5294 text + this->part3.interval.start, this->part3.interval.size()) :
+
5295 this->part2.interval ?
+
5296 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
+
5297 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
+
5298 check11(
+
5299 text + this->part1.interval.start, this->part1.interval.size(),
+
5300 text + this->part2.interval.start, this->part2.interval.size()) :
+
5301 this->part1.interval ?
+
5302 this->part1.interval.size() <= 12 &&
+
5303 check11(text + this->part1.interval.start, this->part1.interval.size()) :
+
5304 false;
+
5305 else if (this->model[0] == '0' && this->model[1] == '2')
+
5306 is_valid =
+
5307 this->part3.interval ?
+
5308 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
+
5309 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
+
5310 check11(text + this->part2.interval.start, this->part2.interval.size()) &&
+
5311 check11(text + this->part3.interval.start, this->part3.interval.size()) :
+
5312 false;
+
5313 else if (this->model[0] == '0' && this->model[1] == '3')
+
5314 is_valid =
+
5315 this->part3.interval ?
+
5316 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
+
5317 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
+
5318 check11(text + this->part1.interval.start, this->part1.interval.size()) &&
+
5319 check11(text + this->part2.interval.start, this->part2.interval.size()) &&
+
5320 check11(text + this->part3.interval.start, this->part3.interval.size()) :
+
5321 false;
+
5322 else if (this->model[0] == '0' && this->model[1] == '4')
+
5323 is_valid =
+
5324 this->part3.interval ?
+
5325 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
+
5326 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
+
5327 check11(text + this->part1.interval.start, this->part1.interval.size()) &&
+
5328 check11(text + this->part3.interval.start, this->part3.interval.size()) :
+
5329 false;
+
5330 else if ((this->model[0] == '0' || this->model[0] == '5') && this->model[1] == '5')
+
5331 is_valid =
+
5332 this->part3.interval ?
+
5333 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
+
5334 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
+
5335 check11(text + this->part1.interval.start, this->part1.interval.size()) :
+
5336 this->part2.interval ?
+
5337 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
+
5338 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
+
5339 check11(text + this->part1.interval.start, this->part1.interval.size()) :
+
5340 this->part1.interval ?
+
5341 this->part1.interval.size() <= 12 &&
+
5342 check11(text + this->part1.interval.start, this->part1.interval.size()) :
+
5343 false;
+
5344 else if (this->model[0] == '0' && this->model[1] == '6')
+
5345 is_valid =
+
5346 this->part3.interval ?
+
5347 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
+
5348 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
+
5349 check11(
+
5350 text + this->part2.interval.start, this->part2.interval.size(),
+
5351 text + this->part3.interval.start, this->part3.interval.size()) :
+
5352 this->part2.interval ?
+
5353 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
+
5354 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
+
5355 check11(text + this->part2.interval.start, this->part2.interval.size()) :
+
5356 false;
+
5357 else if (this->model[0] == '0' && this->model[1] == '7')
+
5358 is_valid =
+
5359 this->part3.interval ?
+
5360 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
+
5361 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
+
5362 check11(text + this->part2.interval.start, this->part2.interval.size()) :
+
5363 this->part2.interval ?
+
5364 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
+
5365 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
+
5366 check11(text + this->part2.interval.start, this->part2.interval.size()) :
+
5367 false;
+
5368 else if (this->model[0] == '0' && this->model[1] == '8')
+
5369 is_valid =
+
5370 this->part3.interval ?
+
5371 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
+
5372 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
+
5373 check11(
+
5374 text + this->part1.interval.start, this->part1.interval.size(),
+
5375 text + this->part2.interval.start, this->part2.interval.size()) &&
+
5376 check11(text + this->part3.interval.start, this->part3.interval.size()) :
+
5377 false;
+
5378 else if (this->model[0] == '0' && this->model[1] == '9')
+
5379 is_valid =
+
5380 this->part3.interval ?
+
5381 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
+
5382 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
+
5383 check11(
+
5384 text + this->part1.interval.start, this->part1.interval.size(),
+
5385 text + this->part2.interval.start, this->part2.interval.size()) :
+
5386 this->part2.interval ?
+
5387 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
+
5388 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
+
5389 check11(
+
5390 text + this->part1.interval.start, this->part1.interval.size(),
+
5391 text + this->part2.interval.start, this->part2.interval.size()) :
+
5392 this->part1.interval ?
+
5393 this->part1.interval.size() <= 12 &&
+
5394 check11(text + this->part1.interval.start, this->part1.interval.size()) :
+
5395 false;
+
5396 else if (this->model[0] == '1' && this->model[1] == '0')
+
5397 is_valid =
+
5398 this->part3.interval ?
+
5399 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
+
5400 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
+
5401 check11(text + this->part1.interval.start, this->part1.interval.size()) &&
+
5402 check11(
+
5403 text + this->part2.interval.start, this->part2.interval.size(),
+
5404 text + this->part3.interval.start, this->part3.interval.size()) :
+
5405 this->part2.interval ?
+
5406 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
+
5407 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
+
5408 check11(text + this->part1.interval.start, this->part1.interval.size()) &&
+
5409 check11(text + this->part2.interval.start, this->part2.interval.size()) :
+
5410 false;
+
5411 else if (
+
5412 (this->model[0] == '1' && (this->model[1] == '1' || this->model[1] == '8' || this->model[1] == '9')) ||
+
5413 ((this->model[0] == '2' || this->model[0] == '3') && this->model[1] == '8') ||
+
5414 (this->model[0] == '4' && (this->model[1] == '0' || this->model[1] == '1' || this->model[1] == '8' || this->model[1] == '9')) ||
+
5415 (this->model[0] == '5' && (this->model[1] == '1' || this->model[1] == '8')))
+
5416 is_valid =
+
5417 this->part3.interval ?
+
5418 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 && this->part3.interval.size() <= 12 &&
+
5419 this->part1.interval.size() + this->part2.interval.size() + this->part3.interval.size() <= 20 &&
+
5420 check11(text + this->part1.interval.start, this->part1.interval.size()) &&
+
5421 check11(text + this->part2.interval.start, this->part2.interval.size()) :
+
5422 this->part2.interval ?
+
5423 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
+
5424 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
+
5425 check11(text + this->part1.interval.start, this->part1.interval.size()) &&
+
5426 check11(text + this->part2.interval.start, this->part2.interval.size()) :
+
5427 false;
+
5428 else if (this->model[0] == '1' && this->model[1] == '2')
+
5429 is_valid =
+
5430 this->part3.interval ? false :
+
5431 this->part2.interval ? false :
+
5432 this->part1.interval ?
+
5433 this->part1.interval.size() <= 13 &&
+
5434 check11(text + this->part1.interval.start, this->part1.interval.size()) :
+
5435 false;
+
5436 else if ((this->model[0] == '2' || this->model[0] == '3') && this->model[1] == '1')
+
5437 is_valid =
+
5438 this->part3.interval ? false :
+
5439 this->part2.interval ?
+
5440 this->part1.interval.size() <= 12 && this->part2.interval.size() <= 12 &&
+
5441 this->part1.interval.size() + this->part2.interval.size() <= 20 &&
+
5442 check11(text + this->part1.interval.start, this->part1.interval.size()) :
+
5443 false;
+
5444 else
+
5445 is_valid = true; // Assume models we don't handle as valid
+
5446 return true;
+
5447
+
5448 error:
+
5449 this->model[0] = 0;
+
5450 this->part1.interval.start = (this->part1.interval.end = start) + 1;
+
5451 this->part2.interval.start = (this->part2.interval.end = start) + 1;
+
5452 this->part3.interval.start = (this->part3.interval.end = start) + 1;
+
5453 this->is_valid = false;
+
5454 this->interval.start = (this->interval.end = start) + 1;
+
5455 return false;
+
5456 }
+
5457
+
5458 virtual void invalidate()
+
5459 {
+
5460 this->model[0] = 0;
+
5461 this->part1.invalidate();
+
5462 this->part2.invalidate();
+
5463 this->part3.invalidate();
+
5464 this->is_valid = false;
+ +
5466 }
+
5467
+
5468 protected:
+
5469 static bool check11(
+
5470 _In_count_(num_part1) const T* part1, _In_ size_t num_part1)
+
5471 {
+
5472 _Assume_(part1 && num_part1 >= 1);
+
5473 uint32_t nominator = 0, ponder = 2;
+
5474 for (size_t i = num_part1 - 1; i--; ++ponder)
+
5475 nominator += (part1[i] - '0') * ponder;
+
5476 uint8_t control = 11 - static_cast<uint8_t>(nominator % 11);
+
5477 if (control >= 10)
+
5478 control = 0;
+
5479 return control == part1[num_part1 - 1] - '0';
+
5480 }
+
5481
+
5482 static bool check11(
+
5483 _In_count_(num_part1) const T* part1, _In_ size_t num_part1,
+
5484 _In_count_(num_part2) const T* part2, _In_ size_t num_part2)
+
5485 {
+
5486 _Assume_(part1 || !num_part1);
+
5487 _Assume_(part2 && num_part2 >= 1);
+
5488 uint32_t nominator = 0, ponder = 2;
+
5489 for (size_t i = num_part2 - 1; i--; ++ponder)
+
5490 nominator += (part2[i] - '0') * ponder;
+
5491 for (size_t i = num_part1; i--; ++ponder)
+
5492 nominator += (part1[i] - '0') * ponder;
+
5493 uint8_t control = 11 - static_cast<uint8_t>(nominator % 11);
+
5494 if (control == 10)
+
5495 control = 0;
+
5496 return control == part2[num_part2 - 1] - '0';
+
5497 }
+
5498
+
5499 static bool check11(
+
5500 _In_count_(num_part1) const T* part1, _In_ size_t num_part1,
+
5501 _In_count_(num_part2) const T* part2, _In_ size_t num_part2,
+
5502 _In_count_(num_part3) const T* part3, _In_ size_t num_part3)
+
5503 {
+
5504 _Assume_(part1 || !num_part1);
+
5505 _Assume_(part2 || !num_part2);
+
5506 _Assume_(part3 && num_part3 >= 1);
+
5507 uint32_t nominator = 0, ponder = 2;
+
5508 for (size_t i = num_part3 - 1; i--; ++ponder)
+
5509 nominator += (part3[i] - '0') * ponder;
+
5510 for (size_t i = num_part2; i--; ++ponder)
+
5511 nominator += (part2[i] - '0') * ponder;
+
5512 for (size_t i = num_part1; i--; ++ponder)
+
5513 nominator += (part1[i] - '0') * ponder;
+
5514 uint8_t control = 11 - static_cast<uint8_t>(nominator % 11);
+
5515 if (control == 10)
+
5516 control = 0;
+
5517 return control == part2[num_part3 - 1] - '0';
+
5518 }
+
5519
+
5520 public:
+
5521 T model[3];
+ + + + +
5526
+
5527 protected:
+
5528 std::shared_ptr<basic_parser<T>> m_space;
+ +
5530 };
-
5532
- - -
5535#ifdef _UNICODE
- -
5537#else
- -
5539#endif
- -
5541
-
5545 template <class T>
-
- -
5547 {
-
5548 public:
- -
5550 _In_ const std::shared_ptr<basic_parser<T>>& element,
-
5551 _In_ const std::shared_ptr<basic_parser<T>>& digit,
-
5552 _In_ const std::shared_ptr<basic_parser<T>>& sign,
-
5553 _In_ const std::locale& locale = std::locale()) :
-
5554 basic_parser<T>(locale),
-
5555 m_element(element),
-
5556 m_digit(digit),
-
5557 m_sign(sign),
-
5558 has_digits(false),
-
5559 has_charge(false)
-
5560 {}
-
5561
-
5562 virtual bool match(
-
5563 _In_reads_or_z_(end) const T* text,
-
5564 _In_ size_t start = 0,
-
5565 _In_ size_t end = (size_t)-1,
-
5566 _In_ int flags = match_default)
-
5567 {
-
5568 _Assume_(text || start >= end);
-
5569
-
5570 has_digits = false;
-
5571 has_charge = false;
-
5572 this->interval.end = start;
-
5573
-
5574 const int element_match_flags = flags & ~match_case_insensitive; // Chemical elements are always case-sensitive.
-
5575 for (;;) {
-
5576 if (m_element->match(text, this->interval.end, end, element_match_flags)) {
-
5577 this->interval.end = m_element->interval.end;
-
5578 while (m_digit->match(text, this->interval.end, end, flags)) {
-
5579 this->interval.end = m_digit->interval.end;
-
5580 has_digits = true;
-
5581 }
-
5582 }
-
5583 else if (start < this->interval.end) {
-
5584 if (m_sign->match(text, this->interval.end, end, flags)) {
-
5585 this->interval.end = m_sign->interval.end;
-
5586 has_charge = true;
-
5587 }
-
5588 this->interval.start = start;
-
5589 return true;
-
5590 }
-
5591 else {
-
5592 this->interval.start = (this->interval.end = start) + 1;
-
5593 return false;
-
5594 }
-
5595 }
-
5596 }
-
5597
-
5598 virtual void invalidate()
-
5599 {
-
5600 has_digits = false;
-
5601 has_charge = false;
- -
5603 }
-
5604
-
5605 public:
-
5606 bool has_digits;
-
5607 bool has_charge;
-
5608
-
5609 protected:
-
5610 std::shared_ptr<basic_parser<T>> m_element;
-
5611 std::shared_ptr<basic_parser<T>> m_digit;
-
5612 std::shared_ptr<basic_parser<T>> m_sign;
-
5613 };
+
5531
+ + +
5534#ifdef _UNICODE
+ +
5536#else
+ +
5538#endif
+ +
5540
+
5544 template <class T>
+
+ +
5546 {
+
5547 public:
+ +
5549 _In_ const std::shared_ptr<basic_parser<T>>& element,
+
5550 _In_ const std::shared_ptr<basic_parser<T>>& digit,
+
5551 _In_ const std::shared_ptr<basic_parser<T>>& sign,
+
5552 _In_ const std::locale& locale = std::locale()) :
+
5553 basic_parser<T>(locale),
+
5554 m_element(element),
+
5555 m_digit(digit),
+
5556 m_sign(sign),
+
5557 has_digits(false),
+
5558 has_charge(false)
+
5559 {}
+
5560
+
5561 virtual bool match(
+
5562 _In_reads_or_z_(end) const T* text,
+
5563 _In_ size_t start = 0,
+
5564 _In_ size_t end = (size_t)-1,
+
5565 _In_ int flags = match_default)
+
5566 {
+
5567 _Assume_(text || start >= end);
+
5568
+
5569 has_digits = false;
+
5570 has_charge = false;
+
5571 this->interval.end = start;
+
5572
+
5573 const int element_match_flags = flags & ~match_case_insensitive; // Chemical elements are always case-sensitive.
+
5574 for (;;) {
+
5575 if (m_element->match(text, this->interval.end, end, element_match_flags)) {
+
5576 this->interval.end = m_element->interval.end;
+
5577 while (m_digit->match(text, this->interval.end, end, flags)) {
+
5578 this->interval.end = m_digit->interval.end;
+
5579 has_digits = true;
+
5580 }
+
5581 }
+
5582 else if (start < this->interval.end) {
+
5583 if (m_sign->match(text, this->interval.end, end, flags)) {
+
5584 this->interval.end = m_sign->interval.end;
+
5585 has_charge = true;
+
5586 }
+
5587 this->interval.start = start;
+
5588 return true;
+
5589 }
+
5590 else {
+
5591 this->interval.start = (this->interval.end = start) + 1;
+
5592 return false;
+
5593 }
+
5594 }
+
5595 }
+
5596
+
5597 virtual void invalidate()
+
5598 {
+
5599 has_digits = false;
+
5600 has_charge = false;
+ +
5602 }
+
5603
+
5604 public:
+
5605 bool has_digits;
+
5606 bool has_charge;
+
5607
+
5608 protected:
+
5609 std::shared_ptr<basic_parser<T>> m_element;
+
5610 std::shared_ptr<basic_parser<T>> m_digit;
+
5611 std::shared_ptr<basic_parser<T>> m_sign;
+
5612 };
-
5614
- - -
5617#ifdef _UNICODE
- -
5619#else
- -
5621#endif
- -
5623
-
- -
5628 {
-
5629 public:
-
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 _Assume_(text || start >= end);
-
5637 this->interval.end = start;
-
5638
-
5639 _Assume_(text || this->interval.end >= end);
-
5640 if (this->interval.end < end && text[this->interval.end]) {
-
5641 if (text[this->interval.end] == '\r') {
-
5642 this->interval.end++;
-
5643 if (this->interval.end < end && text[this->interval.end] == '\n') {
-
5644 this->interval.start = start;
-
5645 this->interval.end++;
-
5646 return true;
-
5647 }
-
5648 }
-
5649 else if (text[this->interval.end] == '\n') {
-
5650 this->interval.start = start;
-
5651 this->interval.end++;
-
5652 return true;
-
5653 }
-
5654 }
-
5655 this->interval.start = (this->interval.end = start) + 1;
-
5656 return false;
-
5657 }
-
5658 };
+
5613
+ + +
5616#ifdef _UNICODE
+ +
5618#else
+ +
5620#endif
+ +
5622
+
+ +
5627 {
+
5628 public:
+
5629 virtual bool match(
+
5630 _In_reads_or_z_(end) const char* text,
+
5631 _In_ size_t start = 0,
+
5632 _In_ size_t end = (size_t)-1,
+
5633 _In_ int flags = match_default)
+
5634 {
+
5635 _Assume_(text || start >= end);
+
5636 this->interval.end = start;
+
5637
+
5638 _Assume_(text || this->interval.end >= end);
+
5639 if (this->interval.end < end && text[this->interval.end]) {
+
5640 if (text[this->interval.end] == '\r') {
+
5641 this->interval.end++;
+
5642 if (this->interval.end < end && text[this->interval.end] == '\n') {
+
5643 this->interval.start = start;
+
5644 this->interval.end++;
+
5645 return true;
+
5646 }
+
5647 }
+
5648 else if (text[this->interval.end] == '\n') {
+
5649 this->interval.start = start;
+
5650 this->interval.end++;
+
5651 return true;
+
5652 }
+
5653 }
+
5654 this->interval.start = (this->interval.end = start) + 1;
+
5655 return false;
+
5656 }
+
5657 };
-
5659
-
-
5663 class http_space : public parser
-
5664 {
-
5665 public:
-
5666 virtual bool match(
-
5667 _In_reads_or_z_(end) const char* text,
-
5668 _In_ size_t start = 0,
-
5669 _In_ size_t end = (size_t)-1,
-
5670 _In_ int flags = match_default)
-
5671 {
-
5672 _Assume_(text || start >= end);
-
5673 this->interval.end = start;
-
5674 if (m_line_break.match(text, this->interval.end, end, flags)) {
-
5675 this->interval.end = m_line_break.interval.end;
-
5676 if (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) {
-
5677 this->interval.start = start;
-
5678 this->interval.end++;
-
5679 while (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) this->interval.end++;
-
5680 return true;
-
5681 }
-
5682 }
-
5683 else if (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) {
-
5684 this->interval.start = start;
-
5685 this->interval.end++;
-
5686 while (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) this->interval.end++;
-
5687 return true;
-
5688 }
-
5689 this->interval.start = (this->interval.end = start) + 1;
-
5690 return false;
-
5691 }
-
5692
-
5693 protected:
-
5694 http_line_break m_line_break;
-
5695 };
+
5658
+
+
5662 class http_space : public parser
+
5663 {
+
5664 public:
+
5665 virtual bool match(
+
5666 _In_reads_or_z_(end) const char* text,
+
5667 _In_ size_t start = 0,
+
5668 _In_ size_t end = (size_t)-1,
+
5669 _In_ int flags = match_default)
+
5670 {
+
5671 _Assume_(text || start >= end);
+
5672 this->interval.end = start;
+
5673 if (m_line_break.match(text, this->interval.end, end, flags)) {
+
5674 this->interval.end = m_line_break.interval.end;
+
5675 if (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) {
+
5676 this->interval.start = start;
+
5677 this->interval.end++;
+
5678 while (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) this->interval.end++;
+
5679 return true;
+
5680 }
+
5681 }
+
5682 else if (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) {
+
5683 this->interval.start = start;
+
5684 this->interval.end++;
+
5685 while (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) this->interval.end++;
+
5686 return true;
+
5687 }
+
5688 this->interval.start = (this->interval.end = start) + 1;
+
5689 return false;
+
5690 }
+
5691
+
5692 protected:
+
5693 http_line_break m_line_break;
+
5694 };
-
5696
-
-
5700 class http_text_char : public parser
-
5701 {
-
5702 public:
-
5703 virtual bool match(
-
5704 _In_reads_or_z_(end) const char* text,
-
5705 _In_ size_t start = 0,
-
5706 _In_ size_t end = (size_t)-1,
-
5707 _In_ int flags = match_default)
-
5708 {
-
5709 _Assume_(text || start >= end);
-
5710 this->interval.end = start;
-
5711
-
5712 _Assume_(text || this->interval.end >= end);
-
5713 if (m_space.match(text, this->interval.end, end, flags)) {
-
5714 this->interval.start = start;
-
5715 this->interval.end = m_space.interval.end;
-
5716 return true;
-
5717 }
-
5718 else if (this->interval.end < end && text[this->interval.end] && text[this->interval.end] >= 0x20) {
-
5719 this->interval.start = start;
-
5720 this->interval.end++;
-
5721 return true;
-
5722 }
-
5723 this->interval.start = (this->interval.end = start) + 1;
-
5724 return false;
-
5725 }
-
5726
-
5727 protected:
-
5728 http_space m_space;
-
5729 };
+
5695
+
+
5699 class http_text_char : public parser
+
5700 {
+
5701 public:
+
5702 virtual bool match(
+
5703 _In_reads_or_z_(end) const char* text,
+
5704 _In_ size_t start = 0,
+
5705 _In_ size_t end = (size_t)-1,
+
5706 _In_ int flags = match_default)
+
5707 {
+
5708 _Assume_(text || start >= end);
+
5709 this->interval.end = start;
+
5710
+
5711 _Assume_(text || this->interval.end >= end);
+
5712 if (m_space.match(text, this->interval.end, end, flags)) {
+
5713 this->interval.start = start;
+
5714 this->interval.end = m_space.interval.end;
+
5715 return true;
+
5716 }
+
5717 else if (this->interval.end < end && text[this->interval.end] && text[this->interval.end] >= 0x20) {
+
5718 this->interval.start = start;
+
5719 this->interval.end++;
+
5720 return true;
+
5721 }
+
5722 this->interval.start = (this->interval.end = start) + 1;
+
5723 return false;
+
5724 }
+
5725
+
5726 protected:
+
5727 http_space m_space;
+
5728 };
-
5730
-
-
5734 class http_token : public parser
-
5735 {
-
5736 public:
-
5737 virtual bool match(
-
5738 _In_reads_or_z_(end) const char* text,
-
5739 _In_ size_t start = 0,
-
5740 _In_ size_t end = (size_t)-1,
-
5741 _In_ int flags = match_default)
-
5742 {
-
5743 _Assume_(text || start >= end);
-
5744 this->interval.end = start;
-
5745 for (;;) {
-
5746 if (this->interval.end < end && text[this->interval.end]) {
-
5747 if ((unsigned int)text[this->interval.end] < 0x20 ||
-
5748 (unsigned int)text[this->interval.end] == 0x7f ||
-
5749 text[this->interval.end] == '(' ||
-
5750 text[this->interval.end] == ')' ||
-
5751 text[this->interval.end] == '<' ||
-
5752 text[this->interval.end] == '>' ||
-
5753 text[this->interval.end] == '@' ||
-
5754 text[this->interval.end] == ',' ||
-
5755 text[this->interval.end] == ';' ||
-
5756 text[this->interval.end] == ':' ||
-
5757 text[this->interval.end] == '\\' ||
-
5758 text[this->interval.end] == '\"' ||
-
5759 text[this->interval.end] == '/' ||
-
5760 text[this->interval.end] == '[' ||
-
5761 text[this->interval.end] == ']' ||
-
5762 text[this->interval.end] == '?' ||
-
5763 text[this->interval.end] == '=' ||
-
5764 text[this->interval.end] == '{' ||
-
5765 text[this->interval.end] == '}' ||
-
5766 isspace(text[this->interval.end]))
-
5767 break;
-
5768 else
-
5769 this->interval.end++;
-
5770 }
-
5771 else
-
5772 break;
-
5773 }
- -
5775 this->interval.start = start;
-
5776 return true;
-
5777 }
-
5778 else {
-
5779 this->interval.start = (this->interval.end = start) + 1;
-
5780 return false;
-
5781 }
-
5782 }
-
5783 };
+
5729
+
+
5733 class http_token : public parser
+
5734 {
+
5735 public:
+
5736 virtual bool match(
+
5737 _In_reads_or_z_(end) const char* text,
+
5738 _In_ size_t start = 0,
+
5739 _In_ size_t end = (size_t)-1,
+
5740 _In_ int flags = match_default)
+
5741 {
+
5742 _Assume_(text || start >= end);
+
5743 this->interval.end = start;
+
5744 for (;;) {
+
5745 if (this->interval.end < end && text[this->interval.end]) {
+
5746 if ((unsigned int)text[this->interval.end] < 0x20 ||
+
5747 (unsigned int)text[this->interval.end] == 0x7f ||
+
5748 text[this->interval.end] == '(' ||
+
5749 text[this->interval.end] == ')' ||
+
5750 text[this->interval.end] == '<' ||
+
5751 text[this->interval.end] == '>' ||
+
5752 text[this->interval.end] == '@' ||
+
5753 text[this->interval.end] == ',' ||
+
5754 text[this->interval.end] == ';' ||
+
5755 text[this->interval.end] == ':' ||
+
5756 text[this->interval.end] == '\\' ||
+
5757 text[this->interval.end] == '\"' ||
+
5758 text[this->interval.end] == '/' ||
+
5759 text[this->interval.end] == '[' ||
+
5760 text[this->interval.end] == ']' ||
+
5761 text[this->interval.end] == '?' ||
+
5762 text[this->interval.end] == '=' ||
+
5763 text[this->interval.end] == '{' ||
+
5764 text[this->interval.end] == '}' ||
+
5765 isspace(text[this->interval.end]))
+
5766 break;
+
5767 else
+
5768 this->interval.end++;
+
5769 }
+
5770 else
+
5771 break;
+
5772 }
+ +
5774 this->interval.start = start;
+
5775 return true;
+
5776 }
+
5777 else {
+
5778 this->interval.start = (this->interval.end = start) + 1;
+
5779 return false;
+
5780 }
+
5781 }
+
5782 };
-
5784
-
- -
5789 {
-
5790 public:
-
5791 virtual bool match(
-
5792 _In_reads_or_z_(end) const char* text,
-
5793 _In_ size_t start = 0,
-
5794 _In_ size_t end = (size_t)-1,
-
5795 _In_ int flags = match_default)
-
5796 {
-
5797 _Assume_(text || start >= end);
-
5798 this->interval.end = start;
-
5799 if (this->interval.end < end && text[this->interval.end] != '"')
-
5800 goto error;
-
5801 this->interval.end++;
-
5802 content.start = this->interval.end;
-
5803 for (;;) {
-
5804 _Assume_(text || this->interval.end >= end);
-
5805 if (this->interval.end < end && text[this->interval.end]) {
-
5806 if (text[this->interval.end] == '"') {
-
5807 content.end = this->interval.end;
-
5808 this->interval.end++;
-
5809 break;
-
5810 }
-
5811 else if (text[this->interval.end] == '\\') {
-
5812 this->interval.end++;
-
5813 if (this->interval.end < end && text[this->interval.end]) {
-
5814 this->interval.end++;
-
5815 }
-
5816 else
-
5817 goto error;
-
5818 }
-
5819 else if (m_chr.match(text, this->interval.end, end, flags))
-
5820 this->interval.end++;
-
5821 else
-
5822 goto error;
-
5823 }
-
5824 else
-
5825 goto error;
-
5826 }
-
5827 this->interval.start = start;
-
5828 return true;
-
5829
-
5830 error:
-
5831 content.start = 1;
-
5832 content.end = 0;
-
5833 this->interval.start = (this->interval.end = start) + 1;
-
5834 return false;
-
5835 }
-
5836
-
5837 virtual void invalidate()
-
5838 {
-
5839 content.start = 1;
-
5840 content.end = 0;
-
5841 parser::invalidate();
-
5842 }
-
5843
-
5844 public:
- -
5846
-
5847 protected:
-
5848 http_text_char m_chr;
-
5849 };
+
5783
+
+ +
5788 {
+
5789 public:
+
5790 virtual bool match(
+
5791 _In_reads_or_z_(end) const char* text,
+
5792 _In_ size_t start = 0,
+
5793 _In_ size_t end = (size_t)-1,
+
5794 _In_ int flags = match_default)
+
5795 {
+
5796 _Assume_(text || start >= end);
+
5797 this->interval.end = start;
+
5798 if (this->interval.end < end && text[this->interval.end] != '"')
+
5799 goto error;
+
5800 this->interval.end++;
+
5801 content.start = this->interval.end;
+
5802 for (;;) {
+
5803 _Assume_(text || this->interval.end >= end);
+
5804 if (this->interval.end < end && text[this->interval.end]) {
+
5805 if (text[this->interval.end] == '"') {
+
5806 content.end = this->interval.end;
+
5807 this->interval.end++;
+
5808 break;
+
5809 }
+
5810 else if (text[this->interval.end] == '\\') {
+
5811 this->interval.end++;
+
5812 if (this->interval.end < end && text[this->interval.end]) {
+
5813 this->interval.end++;
+
5814 }
+
5815 else
+
5816 goto error;
+
5817 }
+
5818 else if (m_chr.match(text, this->interval.end, end, flags))
+
5819 this->interval.end++;
+
5820 else
+
5821 goto error;
+
5822 }
+
5823 else
+
5824 goto error;
+
5825 }
+
5826 this->interval.start = start;
+
5827 return true;
+
5828
+
5829 error:
+
5830 content.start = 1;
+
5831 content.end = 0;
+
5832 this->interval.start = (this->interval.end = start) + 1;
+
5833 return false;
+
5834 }
+
5835
+
5836 virtual void invalidate()
+
5837 {
+
5838 content.start = 1;
+
5839 content.end = 0;
+
5840 parser::invalidate();
+
5841 }
+
5842
+
5843 public:
+ +
5845
+
5846 protected:
+
5847 http_text_char m_chr;
+
5848 };
-
5850
-
-
5854 class http_value : public parser
-
5855 {
-
5856 public:
-
5857 virtual bool match(
-
5858 _In_reads_or_z_(end) const char* text,
-
5859 _In_ size_t start = 0,
-
5860 _In_ size_t end = (size_t)-1,
-
5861 _In_ int flags = match_default)
-
5862 {
-
5863 _Assume_(text || start >= end);
-
5864 this->interval.end = start;
-
5865 if (string.match(text, this->interval.end, end, flags)) {
-
5866 token.invalidate();
-
5867 this->interval.end = string.interval.end;
-
5868 this->interval.start = start;
-
5869 return true;
-
5870 }
-
5871 else if (token.match(text, this->interval.end, end, flags)) {
-
5872 string.invalidate();
-
5873 this->interval.end = token.interval.end;
-
5874 this->interval.start = start;
-
5875 return true;
-
5876 }
-
5877 else {
-
5878 this->interval.start = (this->interval.end = start) + 1;
-
5879 return false;
-
5880 }
-
5881 }
-
5882
-
5883 virtual void invalidate()
-
5884 {
-
5885 string.invalidate();
-
5886 token.invalidate();
-
5887 parser::invalidate();
-
5888 }
-
5889
-
5890 public:
- - -
5893 };
+
5849
+
+
5853 class http_value : public parser
+
5854 {
+
5855 public:
+
5856 virtual bool match(
+
5857 _In_reads_or_z_(end) const char* text,
+
5858 _In_ size_t start = 0,
+
5859 _In_ size_t end = (size_t)-1,
+
5860 _In_ int flags = match_default)
+
5861 {
+
5862 _Assume_(text || start >= end);
+
5863 this->interval.end = start;
+
5864 if (string.match(text, this->interval.end, end, flags)) {
+
5865 token.invalidate();
+
5866 this->interval.end = string.interval.end;
+
5867 this->interval.start = start;
+
5868 return true;
+
5869 }
+
5870 else if (token.match(text, this->interval.end, end, flags)) {
+
5871 string.invalidate();
+
5872 this->interval.end = token.interval.end;
+
5873 this->interval.start = start;
+
5874 return true;
+
5875 }
+
5876 else {
+
5877 this->interval.start = (this->interval.end = start) + 1;
+
5878 return false;
+
5879 }
+
5880 }
+
5881
+
5882 virtual void invalidate()
+
5883 {
+
5884 string.invalidate();
+
5885 token.invalidate();
+
5886 parser::invalidate();
+
5887 }
+
5888
+
5889 public:
+ + +
5892 };
-
5894
-
-
5898 class http_parameter : public parser
-
5899 {
-
5900 public:
-
5901 virtual bool match(
-
5902 _In_reads_or_z_(end) const char* text,
-
5903 _In_ size_t start = 0,
-
5904 _In_ size_t end = (size_t)-1,
-
5905 _In_ int flags = match_default)
-
5906 {
-
5907 _Assume_(text || start >= end);
-
5908 this->interval.end = start;
-
5909 if (name.match(text, this->interval.end, end, flags))
-
5910 this->interval.end = name.interval.end;
-
5911 else
-
5912 goto error;
-
5913 while (m_space.match(text, this->interval.end, end, flags))
-
5914 this->interval.end = m_space.interval.end;
-
5915 _Assume_(text || this->interval.end >= end);
-
5916 if (this->interval.end < end && text[this->interval.end] == '=')
-
5917 this->interval.end++;
-
5918 else
-
5919 while (m_space.match(text, this->interval.end, end, flags))
-
5920 this->interval.end = m_space.interval.end;
-
5921 if (value.match(text, this->interval.end, end, flags))
-
5922 this->interval.end = value.interval.end;
-
5923 else
-
5924 goto error;
-
5925 this->interval.start = start;
-
5926 return true;
-
5927
-
5928 error:
-
5929 name.invalidate();
-
5930 value.invalidate();
-
5931 this->interval.start = (this->interval.end = start) + 1;
-
5932 return false;
-
5933 }
-
5934
-
5935 virtual void invalidate()
-
5936 {
-
5937 name.invalidate();
-
5938 value.invalidate();
-
5939 parser::invalidate();
-
5940 }
-
5941
-
5942 public:
- - -
5945
-
5946 protected:
-
5947 http_space m_space;
-
5948 };
+
5893
+
+
5897 class http_parameter : public parser
+
5898 {
+
5899 public:
+
5900 virtual bool match(
+
5901 _In_reads_or_z_(end) const char* text,
+
5902 _In_ size_t start = 0,
+
5903 _In_ size_t end = (size_t)-1,
+
5904 _In_ int flags = match_default)
+
5905 {
+
5906 _Assume_(text || start >= end);
+
5907 this->interval.end = start;
+
5908 if (name.match(text, this->interval.end, end, flags))
+
5909 this->interval.end = name.interval.end;
+
5910 else
+
5911 goto error;
+
5912 while (m_space.match(text, this->interval.end, end, flags))
+
5913 this->interval.end = m_space.interval.end;
+
5914 _Assume_(text || this->interval.end >= end);
+
5915 if (this->interval.end < end && text[this->interval.end] == '=')
+
5916 this->interval.end++;
+
5917 else
+
5918 while (m_space.match(text, this->interval.end, end, flags))
+
5919 this->interval.end = m_space.interval.end;
+
5920 if (value.match(text, this->interval.end, end, flags))
+
5921 this->interval.end = value.interval.end;
+
5922 else
+
5923 goto error;
+
5924 this->interval.start = start;
+
5925 return true;
+
5926
+
5927 error:
+
5928 name.invalidate();
+
5929 value.invalidate();
+
5930 this->interval.start = (this->interval.end = start) + 1;
+
5931 return false;
+
5932 }
+
5933
+
5934 virtual void invalidate()
+
5935 {
+
5936 name.invalidate();
+
5937 value.invalidate();
+
5938 parser::invalidate();
+
5939 }
+
5940
+
5941 public:
+ + +
5944
+
5945 protected:
+
5946 http_space m_space;
+
5947 };
-
5949
-
-
5953 class http_any_type : public parser
-
5954 {
-
5955 public:
-
5956 virtual bool match(
-
5957 _In_reads_or_z_(end) const char* text,
-
5958 _In_ size_t start = 0,
-
5959 _In_ size_t end = (size_t)-1,
-
5960 _In_ int flags = match_default)
-
5961 {
-
5962 _Assume_(text || start >= end);
-
5963 if (start + 2 < end &&
-
5964 text[start] == '*' &&
-
5965 text[start + 1] == '/' &&
-
5966 text[start + 2] == '*')
-
5967 {
-
5968 this->interval.end = (this->interval.start = start) + 3;
-
5969 return true;
-
5970 }
-
5971 else if (start < end && text[start] == '*') {
-
5972 this->interval.end = (this->interval.start = start) + 1;
-
5973 return true;
-
5974 }
-
5975 else {
-
5976 this->interval.start = (this->interval.end = start) + 1;
-
5977 return false;
-
5978 }
-
5979 }
-
5980 };
+
5948
+
+
5952 class http_any_type : public parser
+
5953 {
+
5954 public:
+
5955 virtual bool match(
+
5956 _In_reads_or_z_(end) const char* text,
+
5957 _In_ size_t start = 0,
+
5958 _In_ size_t end = (size_t)-1,
+
5959 _In_ int flags = match_default)
+
5960 {
+
5961 _Assume_(text || start >= end);
+
5962 if (start + 2 < end &&
+
5963 text[start] == '*' &&
+
5964 text[start + 1] == '/' &&
+
5965 text[start + 2] == '*')
+
5966 {
+
5967 this->interval.end = (this->interval.start = start) + 3;
+
5968 return true;
+
5969 }
+
5970 else if (start < end && text[start] == '*') {
+
5971 this->interval.end = (this->interval.start = start) + 1;
+
5972 return true;
+
5973 }
+
5974 else {
+
5975 this->interval.start = (this->interval.end = start) + 1;
+
5976 return false;
+
5977 }
+
5978 }
+
5979 };
-
5981
-
- -
5986 {
-
5987 public:
-
5988 virtual bool match(
-
5989 _In_reads_or_z_(end) const char* text,
-
5990 _In_ size_t start = 0,
-
5991 _In_ size_t end = (size_t)-1,
-
5992 _In_ int flags = match_default)
-
5993 {
-
5994 _Assume_(text || start >= end);
-
5995 this->interval.end = start;
-
5996 if (type.match(text, this->interval.end, end, flags))
-
5997 this->interval.end = type.interval.end;
-
5998 else
-
5999 goto error;
-
6000 while (m_space.match(text, this->interval.end, end, flags))
-
6001 this->interval.end = m_space.interval.end;
-
6002 if (this->interval.end < end && text[this->interval.end] == '/')
-
6003 this->interval.end++;
-
6004 else
-
6005 goto error;
-
6006 while (m_space.match(text, this->interval.end, end, flags))
-
6007 this->interval.end = m_space.interval.end;
-
6008 if (subtype.match(text, this->interval.end, end, flags))
-
6009 this->interval.end = subtype.interval.end;
-
6010 else
-
6011 goto error;
-
6012 this->interval.start = start;
-
6013 return true;
-
6014
-
6015 error:
-
6016 type.invalidate();
-
6017 subtype.invalidate();
-
6018 this->interval.start = (this->interval.end = start) + 1;
-
6019 return false;
-
6020 }
-
6021
-
6022 virtual void invalidate()
-
6023 {
-
6024 type.invalidate();
-
6025 subtype.invalidate();
-
6026 parser::invalidate();
-
6027 }
-
6028
-
6029 public:
-
6030 http_token type;
-
6031 http_token subtype;
-
6032
-
6033 protected:
-
6034 http_space m_space;
-
6035 };
+
5980
+
+ +
5985 {
+
5986 public:
+
5987 virtual bool match(
+
5988 _In_reads_or_z_(end) const char* text,
+
5989 _In_ size_t start = 0,
+
5990 _In_ size_t end = (size_t)-1,
+
5991 _In_ int flags = match_default)
+
5992 {
+
5993 _Assume_(text || start >= end);
+
5994 this->interval.end = start;
+
5995 if (type.match(text, this->interval.end, end, flags))
+
5996 this->interval.end = type.interval.end;
+
5997 else
+
5998 goto error;
+
5999 while (m_space.match(text, this->interval.end, end, flags))
+
6000 this->interval.end = m_space.interval.end;
+
6001 if (this->interval.end < end && text[this->interval.end] == '/')
+
6002 this->interval.end++;
+
6003 else
+
6004 goto error;
+
6005 while (m_space.match(text, this->interval.end, end, flags))
+
6006 this->interval.end = m_space.interval.end;
+
6007 if (subtype.match(text, this->interval.end, end, flags))
+
6008 this->interval.end = subtype.interval.end;
+
6009 else
+
6010 goto error;
+
6011 this->interval.start = start;
+
6012 return true;
+
6013
+
6014 error:
+
6015 type.invalidate();
+
6016 subtype.invalidate();
+
6017 this->interval.start = (this->interval.end = start) + 1;
+
6018 return false;
+
6019 }
+
6020
+
6021 virtual void invalidate()
+
6022 {
+
6023 type.invalidate();
+
6024 subtype.invalidate();
+
6025 parser::invalidate();
+
6026 }
+
6027
+
6028 public:
+
6029 http_token type;
+
6030 http_token subtype;
+
6031
+
6032 protected:
+
6033 http_space m_space;
+
6034 };
-
6036
-
- -
6041 {
-
6042 public:
-
6043 virtual bool match(
-
6044 _In_reads_or_z_(end) const char* text,
-
6045 _In_ size_t start = 0,
-
6046 _In_ size_t end = (size_t)-1,
-
6047 _In_ int flags = match_default)
-
6048 {
-
6049 _Assume_(text || start >= end);
-
6050 if (!http_media_range::match(text, start, end, flags))
-
6051 goto error;
-
6052 params.clear();
-
6053 for (;;) {
-
6054 if (this->interval.end < end && text[this->interval.end]) {
-
6055 if (m_space.match(text, this->interval.end, end, flags))
-
6056 this->interval.end = m_space.interval.end;
-
6057 else if (text[this->interval.end] == ';') {
-
6058 this->interval.end++;
-
6059 while (m_space.match(text, this->interval.end, end, flags))
-
6060 this->interval.end = m_space.interval.end;
- -
6062 if (param.match(text, this->interval.end, end, flags)) {
-
6063 this->interval.end = param.interval.end;
-
6064 params.push_back(std::move(param));
-
6065 }
-
6066 else
-
6067 break;
-
6068 }
-
6069 else
-
6070 break;
-
6071 }
-
6072 else
-
6073 break;
-
6074 }
-
6075 this->interval.end = params.empty() ? subtype.interval.end : params.back().interval.end;
-
6076 return true;
-
6077
-
6078 error:
-
6079 http_media_range::invalidate();
-
6080 params.clear();
-
6081 this->interval.start = (this->interval.end = start) + 1;
-
6082 return false;
-
6083 }
-
6084
-
6085 virtual void invalidate()
-
6086 {
-
6087 params.clear();
-
6088 http_media_range::invalidate();
-
6089 }
-
6090
-
6091 public:
-
6092 std::list<http_parameter> params;
-
6093 };
+
6035
+
+ +
6040 {
+
6041 public:
+
6042 virtual bool match(
+
6043 _In_reads_or_z_(end) const char* text,
+
6044 _In_ size_t start = 0,
+
6045 _In_ size_t end = (size_t)-1,
+
6046 _In_ int flags = match_default)
+
6047 {
+
6048 _Assume_(text || start >= end);
+
6049 if (!http_media_range::match(text, start, end, flags))
+
6050 goto error;
+
6051 params.clear();
+
6052 for (;;) {
+
6053 if (this->interval.end < end && text[this->interval.end]) {
+
6054 if (m_space.match(text, this->interval.end, end, flags))
+
6055 this->interval.end = m_space.interval.end;
+
6056 else if (text[this->interval.end] == ';') {
+
6057 this->interval.end++;
+
6058 while (m_space.match(text, this->interval.end, end, flags))
+
6059 this->interval.end = m_space.interval.end;
+ +
6061 if (param.match(text, this->interval.end, end, flags)) {
+
6062 this->interval.end = param.interval.end;
+
6063 params.push_back(std::move(param));
+
6064 }
+
6065 else
+
6066 break;
+
6067 }
+
6068 else
+
6069 break;
+
6070 }
+
6071 else
+
6072 break;
+
6073 }
+
6074 this->interval.end = params.empty() ? subtype.interval.end : params.back().interval.end;
+
6075 return true;
+
6076
+
6077 error:
+
6078 http_media_range::invalidate();
+
6079 params.clear();
+
6080 this->interval.start = (this->interval.end = start) + 1;
+
6081 return false;
+
6082 }
+
6083
+
6084 virtual void invalidate()
+
6085 {
+
6086 params.clear();
+
6087 http_media_range::invalidate();
+
6088 }
+
6089
+
6090 public:
+
6091 std::list<http_parameter> params;
+
6092 };
-
6094
-
- -
6099 {
-
6100 public:
-
6101 virtual bool match(
-
6102 _In_reads_or_z_(end) const char* text,
-
6103 _In_ size_t start = 0,
-
6104 _In_ size_t end = (size_t)-1,
-
6105 _In_ int flags = match_default)
-
6106 {
-
6107 _Assume_(text || start >= end);
-
6108 this->interval.end = start;
-
6109 for (;;) {
-
6110 if (this->interval.end < end && text[this->interval.end]) {
-
6111 if ((unsigned int)text[this->interval.end] < 0x20 ||
-
6112 (unsigned int)text[this->interval.end] == 0x7f ||
-
6113 text[this->interval.end] == ':' ||
-
6114 text[this->interval.end] == '/' ||
-
6115 isspace(text[this->interval.end]))
-
6116 break;
-
6117 else
-
6118 this->interval.end++;
-
6119 }
-
6120 else
-
6121 break;
-
6122 }
- -
6124 this->interval.start = start;
-
6125 return true;
-
6126 }
-
6127 this->interval.start = (this->interval.end = start) + 1;
-
6128 return false;
-
6129 }
-
6130 };
+
6093
+
+ +
6098 {
+
6099 public:
+
6100 virtual bool match(
+
6101 _In_reads_or_z_(end) const char* text,
+
6102 _In_ size_t start = 0,
+
6103 _In_ size_t end = (size_t)-1,
+
6104 _In_ int flags = match_default)
+
6105 {
+
6106 _Assume_(text || start >= end);
+
6107 this->interval.end = start;
+
6108 for (;;) {
+
6109 if (this->interval.end < end && text[this->interval.end]) {
+
6110 if ((unsigned int)text[this->interval.end] < 0x20 ||
+
6111 (unsigned int)text[this->interval.end] == 0x7f ||
+
6112 text[this->interval.end] == ':' ||
+
6113 text[this->interval.end] == '/' ||
+
6114 isspace(text[this->interval.end]))
+
6115 break;
+
6116 else
+
6117 this->interval.end++;
+
6118 }
+
6119 else
+
6120 break;
+
6121 }
+ +
6123 this->interval.start = start;
+
6124 return true;
+
6125 }
+
6126 this->interval.start = (this->interval.end = start) + 1;
+
6127 return false;
+
6128 }
+
6129 };
-
6131
-
-
6135 class http_url_port : public parser
-
6136 {
-
6137 public:
-
6138 http_url_port(_In_ const std::locale& locale = std::locale()) :
-
6139 parser(locale),
-
6140 value(0)
-
6141 {}
-
6142
-
6143 virtual bool match(
-
6144 _In_reads_or_z_(end) const char* text,
-
6145 _In_ size_t start = 0,
-
6146 _In_ size_t end = (size_t)-1,
-
6147 _In_ int flags = match_default)
-
6148 {
-
6149 _Assume_(text || start >= end);
-
6150 value = 0;
-
6151 this->interval.end = start;
-
6152 for (;;) {
-
6153 if (this->interval.end < end && text[this->interval.end]) {
-
6154 if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9') {
-
6155 size_t _value = (size_t)value * 10 + text[this->interval.end] - '0';
-
6156 if (_value > (uint16_t)-1) {
-
6157 value = 0;
-
6158 this->interval.start = (this->interval.end = start) + 1;
-
6159 return false;
-
6160 }
-
6161 value = (uint16_t)_value;
-
6162 this->interval.end++;
-
6163 }
-
6164 else
-
6165 break;
-
6166 }
-
6167 else
-
6168 break;
-
6169 }
- -
6171 this->interval.start = start;
-
6172 return true;
-
6173 }
-
6174 this->interval.start = (this->interval.end = start) + 1;
-
6175 return false;
-
6176 }
-
6177
-
6178 virtual void invalidate()
-
6179 {
-
6180 value = 0;
-
6181 parser::invalidate();
-
6182 }
-
6183
-
6184 public:
-
6185 uint16_t value;
-
6186 };
+
6130
+
+
6134 class http_url_port : public parser
+
6135 {
+
6136 public:
+
6137 http_url_port(_In_ const std::locale& locale = std::locale()) :
+
6138 parser(locale),
+
6139 value(0)
+
6140 {}
+
6141
+
6142 virtual bool match(
+
6143 _In_reads_or_z_(end) const char* text,
+
6144 _In_ size_t start = 0,
+
6145 _In_ size_t end = (size_t)-1,
+
6146 _In_ int flags = match_default)
+
6147 {
+
6148 _Assume_(text || start >= end);
+
6149 value = 0;
+
6150 this->interval.end = start;
+
6151 for (;;) {
+
6152 if (this->interval.end < end && text[this->interval.end]) {
+
6153 if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9') {
+
6154 size_t _value = (size_t)value * 10 + text[this->interval.end] - '0';
+
6155 if (_value > (uint16_t)-1) {
+
6156 value = 0;
+
6157 this->interval.start = (this->interval.end = start) + 1;
+
6158 return false;
+
6159 }
+
6160 value = (uint16_t)_value;
+
6161 this->interval.end++;
+
6162 }
+
6163 else
+
6164 break;
+
6165 }
+
6166 else
+
6167 break;
+
6168 }
+ +
6170 this->interval.start = start;
+
6171 return true;
+
6172 }
+
6173 this->interval.start = (this->interval.end = start) + 1;
+
6174 return false;
+
6175 }
+
6176
+
6177 virtual void invalidate()
+
6178 {
+
6179 value = 0;
+
6180 parser::invalidate();
+
6181 }
+
6182
+
6183 public:
+
6184 uint16_t value;
+
6185 };
-
6187
-
- -
6192 {
-
6193 public:
-
6194 virtual bool match(
-
6195 _In_reads_or_z_(end) const char* text,
-
6196 _In_ size_t start = 0,
-
6197 _In_ size_t end = (size_t)-1,
-
6198 _In_ int flags = match_default)
-
6199 {
-
6200 _Assume_(text || start >= end);
-
6201 this->interval.end = start;
-
6202 for (;;) {
-
6203 if (this->interval.end < end && text[this->interval.end]) {
-
6204 if ((unsigned int)text[this->interval.end] < 0x20 ||
-
6205 (unsigned int)text[this->interval.end] == 0x7f ||
-
6206 text[this->interval.end] == '?' ||
-
6207 text[this->interval.end] == '/' ||
-
6208 isspace(text[this->interval.end]))
-
6209 break;
-
6210 else
-
6211 this->interval.end++;
-
6212 }
-
6213 else
-
6214 break;
-
6215 }
-
6216 this->interval.start = start;
-
6217 return true;
-
6218 }
-
6219 };
+
6186
+
+ +
6191 {
+
6192 public:
+
6193 virtual bool match(
+
6194 _In_reads_or_z_(end) const char* text,
+
6195 _In_ size_t start = 0,
+
6196 _In_ size_t end = (size_t)-1,
+
6197 _In_ int flags = match_default)
+
6198 {
+
6199 _Assume_(text || start >= end);
+
6200 this->interval.end = start;
+
6201 for (;;) {
+
6202 if (this->interval.end < end && text[this->interval.end]) {
+
6203 if ((unsigned int)text[this->interval.end] < 0x20 ||
+
6204 (unsigned int)text[this->interval.end] == 0x7f ||
+
6205 text[this->interval.end] == '?' ||
+
6206 text[this->interval.end] == '/' ||
+
6207 isspace(text[this->interval.end]))
+
6208 break;
+
6209 else
+
6210 this->interval.end++;
+
6211 }
+
6212 else
+
6213 break;
+
6214 }
+
6215 this->interval.start = start;
+
6216 return true;
+
6217 }
+
6218 };
-
6220
-
-
6224 class http_url_path : public parser
-
6225 {
-
6226 public:
-
6227 virtual bool match(
-
6228 _In_reads_or_z_(end) const char* text,
-
6229 _In_ size_t start = 0,
-
6230 _In_ size_t end = (size_t)-1,
-
6231 _In_ int flags = match_default)
-
6232 {
-
6233 _Assume_(text || start >= end);
- -
6235 this->interval.end = start;
-
6236 segments.clear();
-
6237 _Assume_(text || this->interval.end >= end);
-
6238 if (this->interval.end < end && text[this->interval.end] != '/')
-
6239 goto error;
-
6240 this->interval.end++;
-
6241 s.match(text, this->interval.end, end, flags);
-
6242 segments.push_back(s);
-
6243 this->interval.end = s.interval.end;
-
6244 for (;;) {
-
6245 if (this->interval.end < end && text[this->interval.end]) {
-
6246 if (text[this->interval.end] == '/') {
-
6247 this->interval.end++;
-
6248 s.match(text, this->interval.end, end, flags);
-
6249 segments.push_back(s);
-
6250 this->interval.end = s.interval.end;
-
6251 }
-
6252 else
-
6253 break;
-
6254 }
-
6255 else
-
6256 break;
-
6257 }
-
6258 this->interval.start = start;
-
6259 return true;
-
6260
-
6261 error:
-
6262 segments.clear();
-
6263 this->interval.start = (this->interval.end = start) + 1;
-
6264 return false;
-
6265 }
-
6266
-
6267 virtual void invalidate()
-
6268 {
-
6269 segments.clear();
-
6270 parser::invalidate();
-
6271 }
-
6272
-
6273 public:
-
6274 std::vector<http_url_path_segment> segments;
-
6275 };
+
6219
+
+
6223 class http_url_path : public parser
+
6224 {
+
6225 public:
+
6226 virtual bool match(
+
6227 _In_reads_or_z_(end) const char* text,
+
6228 _In_ size_t start = 0,
+
6229 _In_ size_t end = (size_t)-1,
+
6230 _In_ int flags = match_default)
+
6231 {
+
6232 _Assume_(text || start >= end);
+ +
6234 this->interval.end = start;
+
6235 segments.clear();
+
6236 _Assume_(text || this->interval.end >= end);
+
6237 if (this->interval.end < end && text[this->interval.end] != '/')
+
6238 goto error;
+
6239 this->interval.end++;
+
6240 s.match(text, this->interval.end, end, flags);
+
6241 segments.push_back(s);
+
6242 this->interval.end = s.interval.end;
+
6243 for (;;) {
+
6244 if (this->interval.end < end && text[this->interval.end]) {
+
6245 if (text[this->interval.end] == '/') {
+
6246 this->interval.end++;
+
6247 s.match(text, this->interval.end, end, flags);
+
6248 segments.push_back(s);
+
6249 this->interval.end = s.interval.end;
+
6250 }
+
6251 else
+
6252 break;
+
6253 }
+
6254 else
+
6255 break;
+
6256 }
+
6257 this->interval.start = start;
+
6258 return true;
+
6259
+
6260 error:
+
6261 segments.clear();
+
6262 this->interval.start = (this->interval.end = start) + 1;
+
6263 return false;
+
6264 }
+
6265
+
6266 virtual void invalidate()
+
6267 {
+
6268 segments.clear();
+
6269 parser::invalidate();
+
6270 }
+
6271
+
6272 public:
+
6273 std::vector<http_url_path_segment> segments;
+
6274 };
-
6276
-
- -
6281 {
-
6282 public:
-
6283 virtual bool match(
-
6284 _In_reads_or_z_(end) const char* text,
-
6285 _In_ size_t start = 0,
-
6286 _In_ size_t end = (size_t)-1,
-
6287 _In_ int flags = match_default)
-
6288 {
-
6289 _Assume_(text || start >= end);
-
6290 this->interval.end = start;
-
6291 name.start = this->interval.end;
-
6292 for (;;) {
-
6293 if (this->interval.end < end && text[this->interval.end]) {
-
6294 if ((unsigned int)text[this->interval.end] < 0x20 ||
-
6295 (unsigned int)text[this->interval.end] == 0x7f ||
-
6296 text[this->interval.end] == '&' ||
-
6297 text[this->interval.end] == '=' ||
-
6298 isspace(text[this->interval.end]))
-
6299 break;
-
6300 else
-
6301 this->interval.end++;
-
6302 }
-
6303 else
-
6304 break;
-
6305 }
- -
6307 name.end = this->interval.end;
-
6308 else
-
6309 goto error;
-
6310 if (text[this->interval.end] == '=') {
-
6311 this->interval.end++;
-
6312 value.start = this->interval.end;
-
6313 for (;;) {
-
6314 if (this->interval.end < end && text[this->interval.end]) {
-
6315 if ((unsigned int)text[this->interval.end] < 0x20 ||
-
6316 (unsigned int)text[this->interval.end] == 0x7f ||
-
6317 text[this->interval.end] == '&' ||
-
6318 isspace(text[this->interval.end]))
-
6319 break;
-
6320 else
-
6321 this->interval.end++;
-
6322 }
-
6323 else
-
6324 break;
-
6325 }
-
6326 value.end = this->interval.end;
-
6327 }
-
6328 else {
-
6329 value.start = 1;
-
6330 value.end = 0;
-
6331 }
-
6332 this->interval.start = start;
-
6333 return true;
-
6334
-
6335 error:
-
6336 name.start = 1;
-
6337 name.end = 0;
-
6338 value.start = 1;
-
6339 value.end = 0;
-
6340 this->interval.start = (this->interval.end = start) + 1;
-
6341 return false;
-
6342 }
-
6343
-
6344 virtual void invalidate()
-
6345 {
-
6346 name.start = 1;
-
6347 name.end = 0;
-
6348 value.start = 1;
-
6349 value.end = 0;
-
6350 parser::invalidate();
-
6351 }
-
6352
-
6353 public:
- - -
6356 };
+
6275
+
+ +
6280 {
+
6281 public:
+
6282 virtual bool match(
+
6283 _In_reads_or_z_(end) const char* text,
+
6284 _In_ size_t start = 0,
+
6285 _In_ size_t end = (size_t)-1,
+
6286 _In_ int flags = match_default)
+
6287 {
+
6288 _Assume_(text || start >= end);
+
6289 this->interval.end = start;
+
6290 name.start = this->interval.end;
+
6291 for (;;) {
+
6292 if (this->interval.end < end && text[this->interval.end]) {
+
6293 if ((unsigned int)text[this->interval.end] < 0x20 ||
+
6294 (unsigned int)text[this->interval.end] == 0x7f ||
+
6295 text[this->interval.end] == '&' ||
+
6296 text[this->interval.end] == '=' ||
+
6297 isspace(text[this->interval.end]))
+
6298 break;
+
6299 else
+
6300 this->interval.end++;
+
6301 }
+
6302 else
+
6303 break;
+
6304 }
+ +
6306 name.end = this->interval.end;
+
6307 else
+
6308 goto error;
+
6309 if (text[this->interval.end] == '=') {
+
6310 this->interval.end++;
+
6311 value.start = this->interval.end;
+
6312 for (;;) {
+
6313 if (this->interval.end < end && text[this->interval.end]) {
+
6314 if ((unsigned int)text[this->interval.end] < 0x20 ||
+
6315 (unsigned int)text[this->interval.end] == 0x7f ||
+
6316 text[this->interval.end] == '&' ||
+
6317 isspace(text[this->interval.end]))
+
6318 break;
+
6319 else
+
6320 this->interval.end++;
+
6321 }
+
6322 else
+
6323 break;
+
6324 }
+
6325 value.end = this->interval.end;
+
6326 }
+
6327 else {
+
6328 value.start = 1;
+
6329 value.end = 0;
+
6330 }
+
6331 this->interval.start = start;
+
6332 return true;
+
6333
+
6334 error:
+
6335 name.start = 1;
+
6336 name.end = 0;
+
6337 value.start = 1;
+
6338 value.end = 0;
+
6339 this->interval.start = (this->interval.end = start) + 1;
+
6340 return false;
+
6341 }
+
6342
+
6343 virtual void invalidate()
+
6344 {
+
6345 name.start = 1;
+
6346 name.end = 0;
+
6347 value.start = 1;
+
6348 value.end = 0;
+
6349 parser::invalidate();
+
6350 }
+
6351
+
6352 public:
+ + +
6355 };
-
6357
-
-
6361 class http_url : public parser
-
6362 {
-
6363 public:
-
6364 http_url(_In_ const std::locale& locale = std::locale()) :
-
6365 parser(locale),
-
6366 port(locale)
-
6367 {}
-
6368
-
6369 virtual bool match(
-
6370 _In_reads_or_z_(end) const char* text,
-
6371 _In_ size_t start = 0,
-
6372 _In_ size_t end = (size_t)-1,
-
6373 _In_ int flags = match_default)
-
6374 {
-
6375 _Assume_(text || start >= end);
-
6376 this->interval.end = start;
-
6377
-
6378 if (this->interval.end + 7 <= end && stdex::strnicmp(text + this->interval.end, 7, "http://", (size_t)-1, m_locale) == 0) {
-
6379 this->interval.end += 7;
-
6380 if (server.match(text, this->interval.end, end, flags))
-
6381 this->interval.end = server.interval.end;
-
6382 else
-
6383 goto error;
-
6384 if (this->interval.end < end && text[this->interval.end] == ':') {
-
6385 this->interval.end++;
-
6386 if (port.match(text, this->interval.end, end, flags))
-
6387 this->interval.end = port.interval.end;
-
6388 }
-
6389 else {
-
6390 port.invalidate();
-
6391 port.value = 80;
-
6392 }
-
6393 }
-
6394 else {
-
6395 server.invalidate();
-
6396 port.invalidate();
-
6397 port.value = 80;
-
6398 }
-
6399
-
6400 if (path.match(text, this->interval.end, end, flags))
-
6401 this->interval.end = path.interval.end;
-
6402 else
-
6403 goto error;
-
6404
-
6405 params.clear();
-
6406
-
6407 if (this->interval.end < end && text[this->interval.end] == '?') {
-
6408 this->interval.end++;
-
6409 for (;;) {
-
6410 if (this->interval.end < end && text[this->interval.end]) {
-
6411 if ((unsigned int)text[this->interval.end] < 0x20 ||
-
6412 (unsigned int)text[this->interval.end] == 0x7f ||
-
6413 isspace(text[this->interval.end]))
-
6414 break;
-
6415 else if (text[this->interval.end] == '&')
-
6416 this->interval.end++;
-
6417 else {
- -
6419 if (param.match(text, this->interval.end, end, flags)) {
-
6420 this->interval.end = param.interval.end;
-
6421 params.push_back(std::move(param));
-
6422 }
-
6423 else
-
6424 break;
-
6425 }
-
6426 }
-
6427 else
-
6428 break;
-
6429 }
-
6430 }
-
6431
-
6432 this->interval.start = start;
-
6433 return true;
-
6434
-
6435 error:
-
6436 server.invalidate();
-
6437 port.invalidate();
-
6438 path.invalidate();
-
6439 params.clear();
-
6440 this->interval.start = (this->interval.end = start) + 1;
-
6441 return false;
-
6442 }
-
6443
-
6444 virtual void invalidate()
-
6445 {
-
6446 server.invalidate();
-
6447 port.invalidate();
-
6448 path.invalidate();
-
6449 params.clear();
-
6450 parser::invalidate();
-
6451 }
-
6452
-
6453 public:
-
6454 http_url_server server;
-
6455 http_url_port port;
-
6456 http_url_path path;
-
6457 std::list<http_url_parameter> params;
-
6458 };
+
6356
+
+
6360 class http_url : public parser
+
6361 {
+
6362 public:
+
6363 http_url(_In_ const std::locale& locale = std::locale()) :
+
6364 parser(locale),
+
6365 port(locale)
+
6366 {}
+
6367
+
6368 virtual bool match(
+
6369 _In_reads_or_z_(end) const char* text,
+
6370 _In_ size_t start = 0,
+
6371 _In_ size_t end = (size_t)-1,
+
6372 _In_ int flags = match_default)
+
6373 {
+
6374 _Assume_(text || start >= end);
+
6375 this->interval.end = start;
+
6376
+
6377 if (this->interval.end + 7 <= end && stdex::strnicmp(text + this->interval.end, 7, "http://", (size_t)-1, m_locale) == 0) {
+
6378 this->interval.end += 7;
+
6379 if (server.match(text, this->interval.end, end, flags))
+
6380 this->interval.end = server.interval.end;
+
6381 else
+
6382 goto error;
+
6383 if (this->interval.end < end && text[this->interval.end] == ':') {
+
6384 this->interval.end++;
+
6385 if (port.match(text, this->interval.end, end, flags))
+
6386 this->interval.end = port.interval.end;
+
6387 }
+
6388 else {
+
6389 port.invalidate();
+
6390 port.value = 80;
+
6391 }
+
6392 }
+
6393 else {
+
6394 server.invalidate();
+
6395 port.invalidate();
+
6396 port.value = 80;
+
6397 }
+
6398
+
6399 if (path.match(text, this->interval.end, end, flags))
+
6400 this->interval.end = path.interval.end;
+
6401 else
+
6402 goto error;
+
6403
+
6404 params.clear();
+
6405
+
6406 if (this->interval.end < end && text[this->interval.end] == '?') {
+
6407 this->interval.end++;
+
6408 for (;;) {
+
6409 if (this->interval.end < end && text[this->interval.end]) {
+
6410 if ((unsigned int)text[this->interval.end] < 0x20 ||
+
6411 (unsigned int)text[this->interval.end] == 0x7f ||
+
6412 isspace(text[this->interval.end]))
+
6413 break;
+
6414 else if (text[this->interval.end] == '&')
+
6415 this->interval.end++;
+
6416 else {
+ +
6418 if (param.match(text, this->interval.end, end, flags)) {
+
6419 this->interval.end = param.interval.end;
+
6420 params.push_back(std::move(param));
+
6421 }
+
6422 else
+
6423 break;
+
6424 }
+
6425 }
+
6426 else
+
6427 break;
+
6428 }
+
6429 }
+
6430
+
6431 this->interval.start = start;
+
6432 return true;
+
6433
+
6434 error:
+
6435 server.invalidate();
+
6436 port.invalidate();
+
6437 path.invalidate();
+
6438 params.clear();
+
6439 this->interval.start = (this->interval.end = start) + 1;
+
6440 return false;
+
6441 }
+
6442
+
6443 virtual void invalidate()
+
6444 {
+
6445 server.invalidate();
+
6446 port.invalidate();
+
6447 path.invalidate();
+
6448 params.clear();
+
6449 parser::invalidate();
+
6450 }
+
6451
+
6452 public:
+
6453 http_url_server server;
+
6454 http_url_port port;
+
6455 http_url_path path;
+
6456 std::list<http_url_parameter> params;
+
6457 };
-
6459
-
-
6463 class http_language : public parser
-
6464 {
-
6465 public:
-
6466 virtual bool match(
-
6467 _In_reads_or_z_(end) const char* text,
-
6468 _In_ size_t start = 0,
-
6469 _In_ size_t end = (size_t)-1,
-
6470 _In_ int flags = match_default)
-
6471 {
-
6472 _Assume_(text || start >= end);
-
6473 this->interval.end = start;
-
6474 components.clear();
-
6475 for (;;) {
-
6476 if (this->interval.end < end && text[this->interval.end]) {
- -
6478 k.end = this->interval.end;
-
6479 for (;;) {
-
6480 if (k.end < end && text[k.end]) {
-
6481 if (isalpha(text[k.end]))
-
6482 k.end++;
-
6483 else
-
6484 break;
-
6485 }
-
6486 else
-
6487 break;
-
6488 }
-
6489 if (this->interval.end < k.end) {
-
6490 k.start = this->interval.end;
-
6491 this->interval.end = k.end;
-
6492 components.push_back(k);
-
6493 }
-
6494 else
-
6495 break;
-
6496 if (this->interval.end < end && text[this->interval.end] == '-')
-
6497 this->interval.end++;
-
6498 else
-
6499 break;
-
6500 }
-
6501 else
-
6502 break;
-
6503 }
-
6504 if (!components.empty()) {
-
6505 this->interval.start = start;
-
6506 this->interval.end = components.back().end;
-
6507 return true;
-
6508 }
-
6509 this->interval.start = (this->interval.end = start) + 1;
-
6510 return false;
-
6511 }
-
6512
-
6513 virtual void invalidate()
-
6514 {
-
6515 components.clear();
-
6516 parser::invalidate();
-
6517 }
-
6518
-
6519 public:
-
6520 std::vector<stdex::interval<size_t>> components;
-
6521 };
+
6458
+
+
6462 class http_language : public parser
+
6463 {
+
6464 public:
+
6465 virtual bool match(
+
6466 _In_reads_or_z_(end) const char* text,
+
6467 _In_ size_t start = 0,
+
6468 _In_ size_t end = (size_t)-1,
+
6469 _In_ int flags = match_default)
+
6470 {
+
6471 _Assume_(text || start >= end);
+
6472 this->interval.end = start;
+
6473 components.clear();
+
6474 for (;;) {
+
6475 if (this->interval.end < end && text[this->interval.end]) {
+ +
6477 k.end = this->interval.end;
+
6478 for (;;) {
+
6479 if (k.end < end && text[k.end]) {
+
6480 if (isalpha(text[k.end]))
+
6481 k.end++;
+
6482 else
+
6483 break;
+
6484 }
+
6485 else
+
6486 break;
+
6487 }
+
6488 if (this->interval.end < k.end) {
+
6489 k.start = this->interval.end;
+
6490 this->interval.end = k.end;
+
6491 components.push_back(k);
+
6492 }
+
6493 else
+
6494 break;
+
6495 if (this->interval.end < end && text[this->interval.end] == '-')
+
6496 this->interval.end++;
+
6497 else
+
6498 break;
+
6499 }
+
6500 else
+
6501 break;
+
6502 }
+
6503 if (!components.empty()) {
+
6504 this->interval.start = start;
+
6505 this->interval.end = components.back().end;
+
6506 return true;
+
6507 }
+
6508 this->interval.start = (this->interval.end = start) + 1;
+
6509 return false;
+
6510 }
+
6511
+
6512 virtual void invalidate()
+
6513 {
+
6514 components.clear();
+
6515 parser::invalidate();
+
6516 }
+
6517
+
6518 public:
+
6519 std::vector<stdex::interval<size_t>> components;
+
6520 };
-
6522
-
-
6526 class http_weight : public parser
-
6527 {
-
6528 public:
-
6529 http_weight(_In_ const std::locale& locale = std::locale()) :
-
6530 parser(locale),
-
6531 value(1.0f)
-
6532 {}
-
6533
-
6534 virtual bool match(
-
6535 _In_reads_or_z_(end) const char* text,
-
6536 _In_ size_t start = 0,
-
6537 _In_ size_t end = (size_t)-1,
-
6538 _In_ int flags = match_default)
-
6539 {
-
6540 _Assume_(text || start >= end);
-
6541 size_t celi_del = 0, decimalni_del = 0, decimalni_del_n = 1;
-
6542 this->interval.end = start;
-
6543 for (;;) {
-
6544 if (this->interval.end < end && text[this->interval.end]) {
-
6545 if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9') {
-
6546 celi_del = celi_del * 10 + text[this->interval.end] - '0';
-
6547 this->interval.end++;
-
6548 }
-
6549 else if (text[this->interval.end] == '.') {
-
6550 this->interval.end++;
-
6551 for (;;) {
-
6552 if (this->interval.end < end && text[this->interval.end]) {
-
6553 if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9') {
-
6554 decimalni_del = decimalni_del * 10 + text[this->interval.end] - '0';
-
6555 decimalni_del_n *= 10;
-
6556 this->interval.end++;
-
6557 }
-
6558 else
-
6559 break;
-
6560 }
-
6561 else
-
6562 break;
-
6563 }
-
6564 break;
-
6565 }
-
6566 else
-
6567 break;
-
6568 }
-
6569 else
-
6570 break;
-
6571 }
- - -
6574 this->interval.start = start;
-
6575 return true;
-
6576 }
-
6577 value = 1.0f;
-
6578 this->interval.start = (this->interval.end = start) + 1;
-
6579 return false;
-
6580 }
-
6581
-
6582 virtual void invalidate()
-
6583 {
-
6584 value = 1.0f;
-
6585 parser::invalidate();
-
6586 }
-
6587
-
6588 public:
-
6589 float value;
-
6590 };
+
6521
+
+
6525 class http_weight : public parser
+
6526 {
+
6527 public:
+
6528 http_weight(_In_ const std::locale& locale = std::locale()) :
+
6529 parser(locale),
+
6530 value(1.0f)
+
6531 {}
+
6532
+
6533 virtual bool match(
+
6534 _In_reads_or_z_(end) const char* text,
+
6535 _In_ size_t start = 0,
+
6536 _In_ size_t end = (size_t)-1,
+
6537 _In_ int flags = match_default)
+
6538 {
+
6539 _Assume_(text || start >= end);
+
6540 size_t celi_del = 0, decimalni_del = 0, decimalni_del_n = 1;
+
6541 this->interval.end = start;
+
6542 for (;;) {
+
6543 if (this->interval.end < end && text[this->interval.end]) {
+
6544 if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9') {
+
6545 celi_del = celi_del * 10 + text[this->interval.end] - '0';
+
6546 this->interval.end++;
+
6547 }
+
6548 else if (text[this->interval.end] == '.') {
+
6549 this->interval.end++;
+
6550 for (;;) {
+
6551 if (this->interval.end < end && text[this->interval.end]) {
+
6552 if ('0' <= text[this->interval.end] && text[this->interval.end] <= '9') {
+
6553 decimalni_del = decimalni_del * 10 + text[this->interval.end] - '0';
+
6554 decimalni_del_n *= 10;
+
6555 this->interval.end++;
+
6556 }
+
6557 else
+
6558 break;
+
6559 }
+
6560 else
+
6561 break;
+
6562 }
+
6563 break;
+
6564 }
+
6565 else
+
6566 break;
+
6567 }
+
6568 else
+
6569 break;
+
6570 }
+ + +
6573 this->interval.start = start;
+
6574 return true;
+
6575 }
+
6576 value = 1.0f;
+
6577 this->interval.start = (this->interval.end = start) + 1;
+
6578 return false;
+
6579 }
+
6580
+
6581 virtual void invalidate()
+
6582 {
+
6583 value = 1.0f;
+
6584 parser::invalidate();
+
6585 }
+
6586
+
6587 public:
+
6588 float value;
+
6589 };
-
6591
-
-
6595 class http_asterisk : public parser
-
6596 {
-
6597 public:
-
6598 virtual bool match(
-
6599 _In_reads_or_z_(end) const char* text,
-
6600 _In_ size_t start = 0,
-
6601 _In_ size_t end = (size_t)-1,
-
6602 _In_ int flags = match_default)
-
6603 {
-
6604 _Assume_(text || end <= start);
-
6605 if (start < end && text[start] == '*') {
-
6606 this->interval.end = (this->interval.start = start) + 1;
-
6607 return true;
-
6608 }
-
6609 this->interval.start = (this->interval.end = start) + 1;
-
6610 return false;
-
6611 }
-
6612 };
+
6590
+
+
6594 class http_asterisk : public parser
+
6595 {
+
6596 public:
+
6597 virtual bool match(
+
6598 _In_reads_or_z_(end) const char* text,
+
6599 _In_ size_t start = 0,
+
6600 _In_ size_t end = (size_t)-1,
+
6601 _In_ int flags = match_default)
+
6602 {
+
6603 _Assume_(text || end <= start);
+
6604 if (start < end && text[start] == '*') {
+
6605 this->interval.end = (this->interval.start = start) + 1;
+
6606 return true;
+
6607 }
+
6608 this->interval.start = (this->interval.end = start) + 1;
+
6609 return false;
+
6610 }
+
6611 };
-
6613
-
6617 template <class T, class T_asterisk = http_asterisk>
-
- -
6619 {
-
6620 public:
-
6621 http_weighted_value(_In_ const std::locale& locale = std::locale()) :
-
6622 parser(locale),
-
6623 factor(locale)
-
6624 {}
-
6625
-
6626 virtual bool match(
-
6627 _In_reads_or_z_(end) const char* text,
-
6628 _In_ size_t start = 0,
-
6629 _In_ size_t end = (size_t)-1,
-
6630 _In_ int flags = match_default)
-
6631 {
-
6632 _Assume_(text || start >= end);
-
6633 size_t konec_vrednosti;
-
6634 this->interval.end = start;
-
6635 if (asterisk.match(text, this->interval.end, end, flags)) {
-
6636 this->interval.end = konec_vrednosti = asterisk.interval.end;
-
6637 value.invalidate();
-
6638 }
-
6639 else if (value.match(text, this->interval.end, end, flags)) {
-
6640 this->interval.end = konec_vrednosti = value.interval.end;
-
6641 asterisk.invalidate();
-
6642 }
-
6643 else {
-
6644 asterisk.invalidate();
-
6645 value.invalidate();
-
6646 this->interval.start = (this->interval.end = start) + 1;
-
6647 return false;
-
6648 }
-
6649
-
6650 while (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) this->interval.end++;
-
6651 if (this->interval.end < end && text[this->interval.end] == ';') {
-
6652 this->interval.end++;
-
6653 while (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) this->interval.end++;
-
6654 if (this->interval.end < end && (text[this->interval.end] == 'q' || text[this->interval.end] == 'Q')) {
-
6655 this->interval.end++;
-
6656 while (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) this->interval.end++;
-
6657 if (this->interval.end < end && text[this->interval.end] == '=') {
-
6658 this->interval.end++;
-
6659 while (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) this->interval.end++;
-
6660 if (factor.match(text, this->interval.end, end, flags))
-
6661 this->interval.end = factor.interval.end;
-
6662 }
-
6663 }
-
6664 }
-
6665 if (!factor.interval) {
-
6666 factor.invalidate();
- -
6668 }
-
6669 this->interval.start = start;
-
6670 return true;
-
6671 }
-
6672
-
6673 virtual void invalidate()
-
6674 {
-
6675 asterisk.invalidate();
-
6676 value.invalidate();
-
6677 factor.invalidate();
-
6678 parser::invalidate();
-
6679 }
-
6680
-
6681 public:
-
6682 T_asterisk asterisk;
-
6683 T value;
-
6684 http_weight factor;
-
6685 };
+
6612
+
6616 template <class T, class T_asterisk = http_asterisk>
+
+ +
6618 {
+
6619 public:
+
6620 http_weighted_value(_In_ const std::locale& locale = std::locale()) :
+
6621 parser(locale),
+
6622 factor(locale)
+
6623 {}
+
6624
+
6625 virtual bool match(
+
6626 _In_reads_or_z_(end) const char* text,
+
6627 _In_ size_t start = 0,
+
6628 _In_ size_t end = (size_t)-1,
+
6629 _In_ int flags = match_default)
+
6630 {
+
6631 _Assume_(text || start >= end);
+
6632 size_t konec_vrednosti;
+
6633 this->interval.end = start;
+
6634 if (asterisk.match(text, this->interval.end, end, flags)) {
+
6635 this->interval.end = konec_vrednosti = asterisk.interval.end;
+
6636 value.invalidate();
+
6637 }
+
6638 else if (value.match(text, this->interval.end, end, flags)) {
+
6639 this->interval.end = konec_vrednosti = value.interval.end;
+
6640 asterisk.invalidate();
+
6641 }
+
6642 else {
+
6643 asterisk.invalidate();
+
6644 value.invalidate();
+
6645 this->interval.start = (this->interval.end = start) + 1;
+
6646 return false;
+
6647 }
+
6648
+
6649 while (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) this->interval.end++;
+
6650 if (this->interval.end < end && text[this->interval.end] == ';') {
+
6651 this->interval.end++;
+
6652 while (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) this->interval.end++;
+
6653 if (this->interval.end < end && (text[this->interval.end] == 'q' || text[this->interval.end] == 'Q')) {
+
6654 this->interval.end++;
+
6655 while (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) this->interval.end++;
+
6656 if (this->interval.end < end && text[this->interval.end] == '=') {
+
6657 this->interval.end++;
+
6658 while (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])) this->interval.end++;
+
6659 if (factor.match(text, this->interval.end, end, flags))
+
6660 this->interval.end = factor.interval.end;
+
6661 }
+
6662 }
+
6663 }
+
6664 if (!factor.interval) {
+
6665 factor.invalidate();
+ +
6667 }
+
6668 this->interval.start = start;
+
6669 return true;
+
6670 }
+
6671
+
6672 virtual void invalidate()
+
6673 {
+
6674 asterisk.invalidate();
+
6675 value.invalidate();
+
6676 factor.invalidate();
+
6677 parser::invalidate();
+
6678 }
+
6679
+
6680 public:
+
6681 T_asterisk asterisk;
+
6682 T value;
+
6683 http_weight factor;
+
6684 };
-
6686
-
- -
6691 {
-
6692 public:
-
6693 virtual bool match(
-
6694 _In_reads_or_z_(end) const char* text,
-
6695 _In_ size_t start = 0,
-
6696 _In_ size_t end = (size_t)-1,
-
6697 _In_ int flags = match_default)
-
6698 {
-
6699 _Assume_(text || start >= end);
-
6700 this->interval.end = start;
-
6701 if (this->interval.end < end && text[this->interval.end] == '$')
-
6702 this->interval.end++;
-
6703 else
-
6704 goto error;
-
6705 if (name.match(text, this->interval.end, end, flags))
-
6706 this->interval.end = name.interval.end;
-
6707 else
-
6708 goto error;
-
6709 while (m_space.match(text, this->interval.end, end, flags))
-
6710 this->interval.end = m_space.interval.end;
-
6711 if (this->interval.end < end && text[this->interval.end] == '=')
-
6712 this->interval.end++;
-
6713 else
-
6714 goto error;
-
6715 while (m_space.match(text, this->interval.end, end, flags))
-
6716 this->interval.end = m_space.interval.end;
-
6717 if (value.match(text, this->interval.end, end, flags))
-
6718 this->interval.end = value.interval.end;
-
6719 else
-
6720 goto error;
-
6721 this->interval.start = start;
-
6722 return true;
-
6723
-
6724 error:
-
6725 name.invalidate();
-
6726 value.invalidate();
-
6727 this->interval.start = (this->interval.end = start) + 1;
-
6728 return false;
-
6729 }
-
6730
-
6731 virtual void invalidate()
-
6732 {
-
6733 name.invalidate();
-
6734 value.invalidate();
-
6735 parser::invalidate();
-
6736 }
-
6737
-
6738 public:
-
6739 http_token name;
-
6740 http_value value;
-
6741
-
6742 protected:
-
6743 http_space m_space;
-
6744 };
+
6685
+
+ +
6690 {
+
6691 public:
+
6692 virtual bool match(
+
6693 _In_reads_or_z_(end) const char* text,
+
6694 _In_ size_t start = 0,
+
6695 _In_ size_t end = (size_t)-1,
+
6696 _In_ int flags = match_default)
+
6697 {
+
6698 _Assume_(text || start >= end);
+
6699 this->interval.end = start;
+
6700 if (this->interval.end < end && text[this->interval.end] == '$')
+
6701 this->interval.end++;
+
6702 else
+
6703 goto error;
+
6704 if (name.match(text, this->interval.end, end, flags))
+
6705 this->interval.end = name.interval.end;
+
6706 else
+
6707 goto error;
+
6708 while (m_space.match(text, this->interval.end, end, flags))
+
6709 this->interval.end = m_space.interval.end;
+
6710 if (this->interval.end < end && text[this->interval.end] == '=')
+
6711 this->interval.end++;
+
6712 else
+
6713 goto error;
+
6714 while (m_space.match(text, this->interval.end, end, flags))
+
6715 this->interval.end = m_space.interval.end;
+
6716 if (value.match(text, this->interval.end, end, flags))
+
6717 this->interval.end = value.interval.end;
+
6718 else
+
6719 goto error;
+
6720 this->interval.start = start;
+
6721 return true;
+
6722
+
6723 error:
+
6724 name.invalidate();
+
6725 value.invalidate();
+
6726 this->interval.start = (this->interval.end = start) + 1;
+
6727 return false;
+
6728 }
+
6729
+
6730 virtual void invalidate()
+
6731 {
+
6732 name.invalidate();
+
6733 value.invalidate();
+
6734 parser::invalidate();
+
6735 }
+
6736
+
6737 public:
+
6738 http_token name;
+
6739 http_value value;
+
6740
+
6741 protected:
+
6742 http_space m_space;
+
6743 };
-
6745
-
-
6749 class http_cookie : public parser
-
6750 {
-
6751 public:
-
6752 virtual bool match(
-
6753 _In_reads_or_z_(end) const char* text,
-
6754 _In_ size_t start = 0,
-
6755 _In_ size_t end = (size_t)-1,
-
6756 _In_ int flags = match_default)
-
6757 {
-
6758 _Assume_(text || start >= end);
-
6759 this->interval.end = start;
-
6760 if (name.match(text, this->interval.end, end, flags))
-
6761 this->interval.end = name.interval.end;
-
6762 else
-
6763 goto error;
-
6764 while (m_space.match(text, this->interval.end, end, flags))
-
6765 this->interval.end = m_space.interval.end;
-
6766 if (this->interval.end < end && text[this->interval.end] == '=')
-
6767 this->interval.end++;
-
6768 else
-
6769 goto error;
-
6770 while (m_space.match(text, this->interval.end, end, flags))
-
6771 this->interval.end = m_space.interval.end;
-
6772 if (value.match(text, this->interval.end, end, flags))
-
6773 this->interval.end = value.interval.end;
-
6774 else
-
6775 goto error;
-
6776 params.clear();
-
6777 for (;;) {
-
6778 if (this->interval.end < end && text[this->interval.end]) {
-
6779 if (m_space.match(text, this->interval.end, end, flags))
-
6780 this->interval.end = m_space.interval.end;
-
6781 else if (text[this->interval.end] == ';') {
-
6782 this->interval.end++;
-
6783 while (m_space.match(text, this->interval.end, end, flags))
-
6784 this->interval.end = m_space.interval.end;
- -
6786 if (param.match(text, this->interval.end, end, flags)) {
-
6787 this->interval.end = param.interval.end;
-
6788 params.push_back(std::move(param));
-
6789 }
-
6790 else
-
6791 break;
-
6792 }
-
6793 else
-
6794 break;
-
6795 }
-
6796 else
-
6797 break;
-
6798 }
-
6799 this->interval.start = start;
-
6800 this->interval.end = params.empty() ? value.interval.end : params.back().interval.end;
-
6801 return true;
-
6802
-
6803 error:
-
6804 name.invalidate();
-
6805 value.invalidate();
-
6806 params.clear();
-
6807 this->interval.start = (this->interval.end = start) + 1;
-
6808 return false;
-
6809 }
-
6810
-
6811 virtual void invalidate()
-
6812 {
-
6813 name.invalidate();
-
6814 value.invalidate();
-
6815 params.clear();
-
6816 parser::invalidate();
-
6817 }
-
6818
-
6819 public:
- - -
6822 std::list<http_cookie_parameter> params;
-
6823
-
6824 protected:
-
6825 http_space m_space;
-
6826 };
+
6744
+
+
6748 class http_cookie : public parser
+
6749 {
+
6750 public:
+
6751 virtual bool match(
+
6752 _In_reads_or_z_(end) const char* text,
+
6753 _In_ size_t start = 0,
+
6754 _In_ size_t end = (size_t)-1,
+
6755 _In_ int flags = match_default)
+
6756 {
+
6757 _Assume_(text || start >= end);
+
6758 this->interval.end = start;
+
6759 if (name.match(text, this->interval.end, end, flags))
+
6760 this->interval.end = name.interval.end;
+
6761 else
+
6762 goto error;
+
6763 while (m_space.match(text, this->interval.end, end, flags))
+
6764 this->interval.end = m_space.interval.end;
+
6765 if (this->interval.end < end && text[this->interval.end] == '=')
+
6766 this->interval.end++;
+
6767 else
+
6768 goto error;
+
6769 while (m_space.match(text, this->interval.end, end, flags))
+
6770 this->interval.end = m_space.interval.end;
+
6771 if (value.match(text, this->interval.end, end, flags))
+
6772 this->interval.end = value.interval.end;
+
6773 else
+
6774 goto error;
+
6775 params.clear();
+
6776 for (;;) {
+
6777 if (this->interval.end < end && text[this->interval.end]) {
+
6778 if (m_space.match(text, this->interval.end, end, flags))
+
6779 this->interval.end = m_space.interval.end;
+
6780 else if (text[this->interval.end] == ';') {
+
6781 this->interval.end++;
+
6782 while (m_space.match(text, this->interval.end, end, flags))
+
6783 this->interval.end = m_space.interval.end;
+ +
6785 if (param.match(text, this->interval.end, end, flags)) {
+
6786 this->interval.end = param.interval.end;
+
6787 params.push_back(std::move(param));
+
6788 }
+
6789 else
+
6790 break;
+
6791 }
+
6792 else
+
6793 break;
+
6794 }
+
6795 else
+
6796 break;
+
6797 }
+
6798 this->interval.start = start;
+
6799 this->interval.end = params.empty() ? value.interval.end : params.back().interval.end;
+
6800 return true;
+
6801
+
6802 error:
+
6803 name.invalidate();
+
6804 value.invalidate();
+
6805 params.clear();
+
6806 this->interval.start = (this->interval.end = start) + 1;
+
6807 return false;
+
6808 }
+
6809
+
6810 virtual void invalidate()
+
6811 {
+
6812 name.invalidate();
+
6813 value.invalidate();
+
6814 params.clear();
+
6815 parser::invalidate();
+
6816 }
+
6817
+
6818 public:
+ + +
6821 std::list<http_cookie_parameter> params;
+
6822
+
6823 protected:
+
6824 http_space m_space;
+
6825 };
-
6827
-
-
6831 class http_agent : public parser
-
6832 {
-
6833 public:
-
6834 virtual bool match(
-
6835 _In_reads_or_z_(end) const char* text,
-
6836 _In_ size_t start = 0,
-
6837 _In_ size_t end = (size_t)-1,
-
6838 _In_ int flags = match_default)
-
6839 {
-
6840 _Assume_(text || start >= end);
-
6841 this->interval.end = start;
-
6842 type.start = this->interval.end;
-
6843 for (;;) {
-
6844 if (this->interval.end < end && text[this->interval.end]) {
-
6845 if (text[this->interval.end] == '/') {
-
6846 type.end = this->interval.end;
-
6847 this->interval.end++;
-
6848 version.start = this->interval.end;
-
6849 for (;;) {
-
6850 if (this->interval.end < end && text[this->interval.end]) {
-
6851 if (isspace(text[this->interval.end])) {
-
6852 version.end = this->interval.end;
-
6853 break;
-
6854 }
-
6855 else
-
6856 this->interval.end++;
-
6857 }
-
6858 else {
-
6859 version.end = this->interval.end;
-
6860 break;
-
6861 }
-
6862 }
-
6863 break;
-
6864 }
-
6865 else if (isspace(text[this->interval.end])) {
-
6866 type.end = this->interval.end;
-
6867 break;
-
6868 }
-
6869 else
-
6870 this->interval.end++;
-
6871 }
-
6872 else {
-
6873 type.end = this->interval.end;
-
6874 break;
-
6875 }
-
6876 }
- -
6878 this->interval.start = start;
-
6879 return true;
-
6880 }
-
6881 type.start = 1;
-
6882 type.end = 0;
-
6883 version.start = 1;
-
6884 version.end = 0;
-
6885 this->interval.start = 1;
-
6886 this->interval.end = 0;
-
6887 return false;
-
6888 }
-
6889
-
6890 virtual void invalidate()
-
6891 {
-
6892 type.start = 1;
-
6893 type.end = 0;
-
6894 version.start = 1;
-
6895 version.end = 0;
-
6896 parser::invalidate();
-
6897 }
-
6898
-
6899 public:
- - -
6902 };
+
6826
+
+
6830 class http_agent : public parser
+
6831 {
+
6832 public:
+
6833 virtual bool match(
+
6834 _In_reads_or_z_(end) const char* text,
+
6835 _In_ size_t start = 0,
+
6836 _In_ size_t end = (size_t)-1,
+
6837 _In_ int flags = match_default)
+
6838 {
+
6839 _Assume_(text || start >= end);
+
6840 this->interval.end = start;
+
6841 type.start = this->interval.end;
+
6842 for (;;) {
+
6843 if (this->interval.end < end && text[this->interval.end]) {
+
6844 if (text[this->interval.end] == '/') {
+
6845 type.end = this->interval.end;
+
6846 this->interval.end++;
+
6847 version.start = this->interval.end;
+
6848 for (;;) {
+
6849 if (this->interval.end < end && text[this->interval.end]) {
+
6850 if (isspace(text[this->interval.end])) {
+
6851 version.end = this->interval.end;
+
6852 break;
+
6853 }
+
6854 else
+
6855 this->interval.end++;
+
6856 }
+
6857 else {
+
6858 version.end = this->interval.end;
+
6859 break;
+
6860 }
+
6861 }
+
6862 break;
+
6863 }
+
6864 else if (isspace(text[this->interval.end])) {
+
6865 type.end = this->interval.end;
+
6866 break;
+
6867 }
+
6868 else
+
6869 this->interval.end++;
+
6870 }
+
6871 else {
+
6872 type.end = this->interval.end;
+
6873 break;
+
6874 }
+
6875 }
+ +
6877 this->interval.start = start;
+
6878 return true;
+
6879 }
+
6880 type.start = 1;
+
6881 type.end = 0;
+
6882 version.start = 1;
+
6883 version.end = 0;
+
6884 this->interval.start = 1;
+
6885 this->interval.end = 0;
+
6886 return false;
+
6887 }
+
6888
+
6889 virtual void invalidate()
+
6890 {
+
6891 type.start = 1;
+
6892 type.end = 0;
+
6893 version.start = 1;
+
6894 version.end = 0;
+
6895 parser::invalidate();
+
6896 }
+
6897
+
6898 public:
+ + +
6901 };
-
6903
-
-
6907 class http_protocol : public parser
-
6908 {
-
6909 public:
-
6910 http_protocol(_In_ const std::locale& locale = std::locale()) :
-
6911 parser(locale),
-
6912 version(0x009)
-
6913 {}
-
6914
-
6915 virtual bool match(
-
6916 _In_reads_or_z_(end) const char* text,
-
6917 _In_ size_t start = 0,
-
6918 _In_ size_t end = (size_t)-1,
-
6919 _In_ int flags = match_default)
-
6920 {
-
6921 _Assume_(text || start >= end);
-
6922 this->interval.end = start;
-
6923 type.start = this->interval.end;
-
6924 for (;;) {
-
6925 if (this->interval.end < end && text[this->interval.end]) {
-
6926 if (text[this->interval.end] == '/') {
-
6927 type.end = this->interval.end;
-
6928 this->interval.end++;
-
6929 break;
-
6930 }
-
6931 else if (isspace(text[this->interval.end]))
-
6932 goto error;
-
6933 else
-
6934 this->interval.end++;
-
6935 }
-
6936 else {
-
6937 type.end = this->interval.end;
-
6938 goto error;
-
6939 }
-
6940 }
-
6941 version_maj.start = this->interval.end;
-
6942 for (;;) {
-
6943 if (this->interval.end < end && text[this->interval.end]) {
-
6944 if (text[this->interval.end] == '.') {
-
6945 version_maj.end = this->interval.end;
-
6946 this->interval.end++;
-
6947 version_min.start = this->interval.end;
-
6948 for (;;) {
-
6949 if (this->interval.end < end && text[this->interval.end]) {
-
6950 if (isspace(text[this->interval.end])) {
-
6951 version_min.end = this->interval.end;
-
6952 version =
-
6953 (uint16_t)strtoui(text + version_maj.start, version_maj.size(), nullptr, 10) * 0x100 +
-
6954 (uint16_t)strtoui(text + version_min.start, version_min.size(), nullptr, 10);
-
6955 break;
-
6956 }
-
6957 else
-
6958 this->interval.end++;
-
6959 }
-
6960 else
-
6961 goto error;
-
6962 }
-
6963 break;
-
6964 }
-
6965 else if (isspace(text[this->interval.end])) {
-
6966 version_maj.end = this->interval.end;
-
6967 version_min.start = 1;
-
6968 version_min.end = 0;
-
6969 version = (uint16_t)strtoui(text + version_maj.start, version_maj.size(), nullptr, 10) * 0x100;
-
6970 break;
-
6971 }
-
6972 else
-
6973 this->interval.end++;
-
6974 }
-
6975 else
-
6976 goto error;
-
6977 }
-
6978 this->interval.start = start;
-
6979 return true;
-
6980
-
6981 error:
-
6982 type.start = 1;
-
6983 type.end = 0;
-
6984 version_maj.start = 1;
-
6985 version_maj.end = 0;
-
6986 version_min.start = 1;
-
6987 version_min.end = 0;
-
6988 version = 0x009;
-
6989 this->interval.start = 1;
-
6990 this->interval.end = 0;
-
6991 return false;
-
6992 }
-
6993
-
6994 virtual void invalidate()
-
6995 {
-
6996 type.start = 1;
-
6997 type.end = 0;
-
6998 version_maj.start = 1;
-
6999 version_maj.end = 0;
-
7000 version_min.start = 1;
-
7001 version_min.end = 0;
-
7002 version = 0x009;
-
7003 parser::invalidate();
-
7004 }
-
7005
-
7006 public:
- -
7008 stdex::interval<size_t> version_maj;
-
7009 stdex::interval<size_t> version_min;
- -
7011 };
+
6902
+
+
6906 class http_protocol : public parser
+
6907 {
+
6908 public:
+
6909 http_protocol(_In_ const std::locale& locale = std::locale()) :
+
6910 parser(locale),
+
6911 version(0x009)
+
6912 {}
+
6913
+
6914 virtual bool match(
+
6915 _In_reads_or_z_(end) const char* text,
+
6916 _In_ size_t start = 0,
+
6917 _In_ size_t end = (size_t)-1,
+
6918 _In_ int flags = match_default)
+
6919 {
+
6920 _Assume_(text || start >= end);
+
6921 this->interval.end = start;
+
6922 type.start = this->interval.end;
+
6923 for (;;) {
+
6924 if (this->interval.end < end && text[this->interval.end]) {
+
6925 if (text[this->interval.end] == '/') {
+
6926 type.end = this->interval.end;
+
6927 this->interval.end++;
+
6928 break;
+
6929 }
+
6930 else if (isspace(text[this->interval.end]))
+
6931 goto error;
+
6932 else
+
6933 this->interval.end++;
+
6934 }
+
6935 else {
+
6936 type.end = this->interval.end;
+
6937 goto error;
+
6938 }
+
6939 }
+
6940 version_maj.start = this->interval.end;
+
6941 for (;;) {
+
6942 if (this->interval.end < end && text[this->interval.end]) {
+
6943 if (text[this->interval.end] == '.') {
+
6944 version_maj.end = this->interval.end;
+
6945 this->interval.end++;
+
6946 version_min.start = this->interval.end;
+
6947 for (;;) {
+
6948 if (this->interval.end < end && text[this->interval.end]) {
+
6949 if (isspace(text[this->interval.end])) {
+
6950 version_min.end = this->interval.end;
+
6951 version =
+
6952 (uint16_t)strtoui(text + version_maj.start, version_maj.size(), nullptr, 10) * 0x100 +
+
6953 (uint16_t)strtoui(text + version_min.start, version_min.size(), nullptr, 10);
+
6954 break;
+
6955 }
+
6956 else
+
6957 this->interval.end++;
+
6958 }
+
6959 else
+
6960 goto error;
+
6961 }
+
6962 break;
+
6963 }
+
6964 else if (isspace(text[this->interval.end])) {
+
6965 version_maj.end = this->interval.end;
+
6966 version_min.start = 1;
+
6967 version_min.end = 0;
+
6968 version = (uint16_t)strtoui(text + version_maj.start, version_maj.size(), nullptr, 10) * 0x100;
+
6969 break;
+
6970 }
+
6971 else
+
6972 this->interval.end++;
+
6973 }
+
6974 else
+
6975 goto error;
+
6976 }
+
6977 this->interval.start = start;
+
6978 return true;
+
6979
+
6980 error:
+
6981 type.start = 1;
+
6982 type.end = 0;
+
6983 version_maj.start = 1;
+
6984 version_maj.end = 0;
+
6985 version_min.start = 1;
+
6986 version_min.end = 0;
+
6987 version = 0x009;
+
6988 this->interval.start = 1;
+
6989 this->interval.end = 0;
+
6990 return false;
+
6991 }
+
6992
+
6993 virtual void invalidate()
+
6994 {
+
6995 type.start = 1;
+
6996 type.end = 0;
+
6997 version_maj.start = 1;
+
6998 version_maj.end = 0;
+
6999 version_min.start = 1;
+
7000 version_min.end = 0;
+
7001 version = 0x009;
+
7002 parser::invalidate();
+
7003 }
+
7004
+
7005 public:
+ +
7007 stdex::interval<size_t> version_maj;
+
7008 stdex::interval<size_t> version_min;
+ +
7010 };
-
7012
-
-
7016 class http_request : public parser
-
7017 {
-
7018 public:
-
7019 http_request(_In_ const std::locale& locale = std::locale()) :
-
7020 parser(locale),
-
7021 url(locale),
-
7022 protocol(locale)
-
7023 {}
-
7024
-
7025 virtual bool match(
-
7026 _In_reads_or_z_(end) const char* text,
-
7027 _In_ size_t start = 0,
-
7028 _In_ size_t end = (size_t)-1,
-
7029 _In_ int flags = match_default)
-
7030 {
-
7031 _Assume_(text || start >= end);
-
7032 this->interval.end = start;
-
7033
-
7034 for (;;) {
-
7035 if (m_line_break.match(text, this->interval.end, end, flags))
-
7036 goto error;
-
7037 else if (this->interval.end < end && text[this->interval.end]) {
-
7038 if (isspace(text[this->interval.end]))
-
7039 this->interval.end++;
-
7040 else
-
7041 break;
-
7042 }
-
7043 else
-
7044 goto error;
-
7045 }
-
7046 verb.start = this->interval.end;
-
7047 for (;;) {
-
7048 if (m_line_break.match(text, this->interval.end, end, flags))
-
7049 goto error;
-
7050 else if (this->interval.end < end && text[this->interval.end]) {
-
7051 if (isspace(text[this->interval.end])) {
-
7052 verb.end = this->interval.end;
-
7053 this->interval.end++;
-
7054 break;
-
7055 }
-
7056 else
-
7057 this->interval.end++;
-
7058 }
-
7059 else
-
7060 goto error;
-
7061 }
-
7062
-
7063 for (;;) {
-
7064 if (m_line_break.match(text, this->interval.end, end, flags))
-
7065 goto error;
-
7066 else if (this->interval.end < end && text[this->interval.end]) {
-
7067 if (isspace(text[this->interval.end]))
-
7068 this->interval.end++;
-
7069 else
-
7070 break;
-
7071 }
-
7072 else
-
7073 goto error;
-
7074 }
-
7075 if (url.match(text, this->interval.end, end, flags))
-
7076 this->interval.end = url.interval.end;
-
7077 else
-
7078 goto error;
-
7079
-
7080 protocol.invalidate();
-
7081 for (;;) {
-
7082 if (m_line_break.match(text, this->interval.end, end, flags)) {
-
7083 this->interval.end = m_line_break.interval.end;
-
7084 goto end;
-
7085 }
-
7086 else if (this->interval.end < end && text[this->interval.end]) {
-
7087 if (isspace(text[this->interval.end]))
-
7088 this->interval.end++;
-
7089 else
-
7090 break;
-
7091 }
-
7092 else
-
7093 goto end;
-
7094 }
-
7095 for (;;) {
-
7096 if (m_line_break.match(text, this->interval.end, end, flags)) {
-
7097 this->interval.end = m_line_break.interval.end;
-
7098 goto end;
-
7099 }
-
7100 else if (protocol.match(text, this->interval.end, end, flags)) {
-
7101 this->interval.end = protocol.interval.end;
-
7102 break;
-
7103 }
-
7104 else
-
7105 goto end;
-
7106 }
-
7107
-
7108 for (;;) {
-
7109 if (m_line_break.match(text, this->interval.end, end, flags)) {
-
7110 this->interval.end = m_line_break.interval.end;
-
7111 break;
-
7112 }
-
7113 else if (this->interval.end < end && text[this->interval.end])
-
7114 this->interval.end++;
-
7115 else
-
7116 goto end;
-
7117 }
-
7118
-
7119 end:
-
7120 this->interval.start = start;
-
7121 return true;
-
7122
-
7123 error:
-
7124 verb.start = 1;
-
7125 verb.end = 0;
-
7126 url.invalidate();
-
7127 protocol.invalidate();
-
7128 this->interval.start = 1;
-
7129 this->interval.end = 0;
-
7130 return false;
-
7131 }
-
7132
-
7133 virtual void invalidate()
-
7134 {
-
7135 verb.start = 1;
-
7136 verb.end = 0;
-
7137 url.invalidate();
-
7138 protocol.invalidate();
-
7139 parser::invalidate();
-
7140 }
-
7141
-
7142 public:
- -
7144 http_url url;
-
7145 http_protocol protocol;
-
7146
-
7147 protected:
-
7148 http_line_break m_line_break;
-
7149 };
+
7011
+
+
7015 class http_request : public parser
+
7016 {
+
7017 public:
+
7018 http_request(_In_ const std::locale& locale = std::locale()) :
+
7019 parser(locale),
+
7020 url(locale),
+
7021 protocol(locale)
+
7022 {}
+
7023
+
7024 virtual bool match(
+
7025 _In_reads_or_z_(end) const char* text,
+
7026 _In_ size_t start = 0,
+
7027 _In_ size_t end = (size_t)-1,
+
7028 _In_ int flags = match_default)
+
7029 {
+
7030 _Assume_(text || start >= end);
+
7031 this->interval.end = start;
+
7032
+
7033 for (;;) {
+
7034 if (m_line_break.match(text, this->interval.end, end, flags))
+
7035 goto error;
+
7036 else if (this->interval.end < end && text[this->interval.end]) {
+
7037 if (isspace(text[this->interval.end]))
+
7038 this->interval.end++;
+
7039 else
+
7040 break;
+
7041 }
+
7042 else
+
7043 goto error;
+
7044 }
+
7045 verb.start = this->interval.end;
+
7046 for (;;) {
+
7047 if (m_line_break.match(text, this->interval.end, end, flags))
+
7048 goto error;
+
7049 else if (this->interval.end < end && text[this->interval.end]) {
+
7050 if (isspace(text[this->interval.end])) {
+
7051 verb.end = this->interval.end;
+
7052 this->interval.end++;
+
7053 break;
+
7054 }
+
7055 else
+
7056 this->interval.end++;
+
7057 }
+
7058 else
+
7059 goto error;
+
7060 }
+
7061
+
7062 for (;;) {
+
7063 if (m_line_break.match(text, this->interval.end, end, flags))
+
7064 goto error;
+
7065 else if (this->interval.end < end && text[this->interval.end]) {
+
7066 if (isspace(text[this->interval.end]))
+
7067 this->interval.end++;
+
7068 else
+
7069 break;
+
7070 }
+
7071 else
+
7072 goto error;
+
7073 }
+
7074 if (url.match(text, this->interval.end, end, flags))
+
7075 this->interval.end = url.interval.end;
+
7076 else
+
7077 goto error;
+
7078
+
7079 protocol.invalidate();
+
7080 for (;;) {
+
7081 if (m_line_break.match(text, this->interval.end, end, flags)) {
+
7082 this->interval.end = m_line_break.interval.end;
+
7083 goto end;
+
7084 }
+
7085 else if (this->interval.end < end && text[this->interval.end]) {
+
7086 if (isspace(text[this->interval.end]))
+
7087 this->interval.end++;
+
7088 else
+
7089 break;
+
7090 }
+
7091 else
+
7092 goto end;
+
7093 }
+
7094 for (;;) {
+
7095 if (m_line_break.match(text, this->interval.end, end, flags)) {
+
7096 this->interval.end = m_line_break.interval.end;
+
7097 goto end;
+
7098 }
+
7099 else if (protocol.match(text, this->interval.end, end, flags)) {
+
7100 this->interval.end = protocol.interval.end;
+
7101 break;
+
7102 }
+
7103 else
+
7104 goto end;
+
7105 }
+
7106
+
7107 for (;;) {
+
7108 if (m_line_break.match(text, this->interval.end, end, flags)) {
+
7109 this->interval.end = m_line_break.interval.end;
+
7110 break;
+
7111 }
+
7112 else if (this->interval.end < end && text[this->interval.end])
+
7113 this->interval.end++;
+
7114 else
+
7115 goto end;
+
7116 }
+
7117
+
7118 end:
+
7119 this->interval.start = start;
+
7120 return true;
+
7121
+
7122 error:
+
7123 verb.start = 1;
+
7124 verb.end = 0;
+
7125 url.invalidate();
+
7126 protocol.invalidate();
+
7127 this->interval.start = 1;
+
7128 this->interval.end = 0;
+
7129 return false;
+
7130 }
+
7131
+
7132 virtual void invalidate()
+
7133 {
+
7134 verb.start = 1;
+
7135 verb.end = 0;
+
7136 url.invalidate();
+
7137 protocol.invalidate();
+
7138 parser::invalidate();
+
7139 }
+
7140
+
7141 public:
+ +
7143 http_url url;
+
7144 http_protocol protocol;
+
7145
+
7146 protected:
+
7147 http_line_break m_line_break;
+
7148 };
-
7150
-
-
7154 class http_header : public parser
-
7155 {
-
7156 public:
-
7157 virtual bool match(
-
7158 _In_reads_or_z_(end) const char* text,
-
7159 _In_ size_t start = 0,
-
7160 _In_ size_t end = (size_t)-1,
-
7161 _In_ int flags = match_default)
-
7162 {
-
7163 _Assume_(text || start >= end);
-
7164 this->interval.end = start;
-
7165
-
7166 if (m_line_break.match(text, this->interval.end, end, flags) ||
-
7167 (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])))
-
7168 goto error;
-
7169 name.start = this->interval.end;
-
7170 for (;;) {
-
7171 if (m_line_break.match(text, this->interval.end, end, flags))
-
7172 goto error;
-
7173 else if (this->interval.end < end && text[this->interval.end]) {
-
7174 if (isspace(text[this->interval.end])) {
-
7175 name.end = this->interval.end;
-
7176 this->interval.end++;
-
7177 for (;;) {
-
7178 if (m_line_break.match(text, this->interval.end, end, flags))
-
7179 goto error;
-
7180 else if (this->interval.end < end && text[this->interval.end]) {
-
7181 if (isspace(text[this->interval.end]))
-
7182 this->interval.end++;
-
7183 else
-
7184 break;
-
7185 }
-
7186 else
-
7187 goto error;
-
7188 }
-
7189 if (this->interval.end < end && text[this->interval.end] == ':') {
-
7190 this->interval.end++;
-
7191 break;
-
7192 }
-
7193 else
-
7194 goto error;
-
7195 break;
-
7196 }
-
7197 else if (text[this->interval.end] == ':') {
-
7198 name.end = this->interval.end;
-
7199 this->interval.end++;
-
7200 break;
-
7201 }
-
7202 else
-
7203 this->interval.end++;
-
7204 }
-
7205 else
-
7206 goto error;
-
7207 }
-
7208 value.start = (size_t)-1;
-
7209 value.end = 0;
-
7210 for (;;) {
-
7211 if (m_line_break.match(text, this->interval.end, end, flags)) {
-
7212 this->interval.end = m_line_break.interval.end;
-
7213 if (!m_line_break.match(text, this->interval.end, end, flags) &&
-
7214 this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end]))
-
7215 this->interval.end++;
-
7216 else
-
7217 break;
-
7218 }
-
7219 else if (this->interval.end < end && text[this->interval.end]) {
-
7220 if (isspace(text[this->interval.end]))
-
7221 this->interval.end++;
-
7222 else {
-
7223 if (value.start == (size_t)-1) value.start = this->interval.end;
-
7224 value.end = ++this->interval.end;
-
7225 }
-
7226 }
-
7227 else
-
7228 break;
-
7229 }
-
7230 this->interval.start = start;
-
7231 return true;
-
7232
-
7233 error:
-
7234 name.start = 1;
-
7235 name.end = 0;
-
7236 value.start = 1;
-
7237 value.end = 0;
-
7238 this->interval.start = 1;
-
7239 this->interval.end = 0;
-
7240 return false;
-
7241 }
-
7242
-
7243 virtual void invalidate()
-
7244 {
-
7245 name.start = 1;
-
7246 name.end = 0;
-
7247 value.start = 1;
-
7248 value.end = 0;
-
7249 parser::invalidate();
-
7250 }
-
7251
-
7252 public:
- - -
7255
-
7256 protected:
-
7257 http_line_break m_line_break;
-
7258 };
+
7149
+
+
7153 class http_header : public parser
+
7154 {
+
7155 public:
+
7156 virtual bool match(
+
7157 _In_reads_or_z_(end) const char* text,
+
7158 _In_ size_t start = 0,
+
7159 _In_ size_t end = (size_t)-1,
+
7160 _In_ int flags = match_default)
+
7161 {
+
7162 _Assume_(text || start >= end);
+
7163 this->interval.end = start;
+
7164
+
7165 if (m_line_break.match(text, this->interval.end, end, flags) ||
+
7166 (this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end])))
+
7167 goto error;
+
7168 name.start = this->interval.end;
+
7169 for (;;) {
+
7170 if (m_line_break.match(text, this->interval.end, end, flags))
+
7171 goto error;
+
7172 else if (this->interval.end < end && text[this->interval.end]) {
+
7173 if (isspace(text[this->interval.end])) {
+
7174 name.end = this->interval.end;
+
7175 this->interval.end++;
+
7176 for (;;) {
+
7177 if (m_line_break.match(text, this->interval.end, end, flags))
+
7178 goto error;
+
7179 else if (this->interval.end < end && text[this->interval.end]) {
+
7180 if (isspace(text[this->interval.end]))
+
7181 this->interval.end++;
+
7182 else
+
7183 break;
+
7184 }
+
7185 else
+
7186 goto error;
+
7187 }
+
7188 if (this->interval.end < end && text[this->interval.end] == ':') {
+
7189 this->interval.end++;
+
7190 break;
+
7191 }
+
7192 else
+
7193 goto error;
+
7194 break;
+
7195 }
+
7196 else if (text[this->interval.end] == ':') {
+
7197 name.end = this->interval.end;
+
7198 this->interval.end++;
+
7199 break;
+
7200 }
+
7201 else
+
7202 this->interval.end++;
+
7203 }
+
7204 else
+
7205 goto error;
+
7206 }
+
7207 value.start = (size_t)-1;
+
7208 value.end = 0;
+
7209 for (;;) {
+
7210 if (m_line_break.match(text, this->interval.end, end, flags)) {
+
7211 this->interval.end = m_line_break.interval.end;
+
7212 if (!m_line_break.match(text, this->interval.end, end, flags) &&
+
7213 this->interval.end < end && text[this->interval.end] && isspace(text[this->interval.end]))
+
7214 this->interval.end++;
+
7215 else
+
7216 break;
+
7217 }
+
7218 else if (this->interval.end < end && text[this->interval.end]) {
+
7219 if (isspace(text[this->interval.end]))
+
7220 this->interval.end++;
+
7221 else {
+
7222 if (value.start == (size_t)-1) value.start = this->interval.end;
+
7223 value.end = ++this->interval.end;
+
7224 }
+
7225 }
+
7226 else
+
7227 break;
+
7228 }
+
7229 this->interval.start = start;
+
7230 return true;
+
7231
+
7232 error:
+
7233 name.start = 1;
+
7234 name.end = 0;
+
7235 value.start = 1;
+
7236 value.end = 0;
+
7237 this->interval.start = 1;
+
7238 this->interval.end = 0;
+
7239 return false;
+
7240 }
+
7241
+
7242 virtual void invalidate()
+
7243 {
+
7244 name.start = 1;
+
7245 name.end = 0;
+
7246 value.start = 1;
+
7247 value.end = 0;
+
7248 parser::invalidate();
+
7249 }
+
7250
+
7251 public:
+ + +
7254
+
7255 protected:
+
7256 http_line_break m_line_break;
+
7257 };
-
7259
-
7263 template <class _Key, class T>
-
-
7264 class http_value_collection : public T
-
7265 {
-
7266 public:
-
7267 void insert(
-
7268 _In_reads_or_z_(end) const char* text,
-
7269 _In_ size_t start = 0,
-
7270 _In_ size_t end = (size_t)-1,
-
7271 _In_ int flags = match_default)
-
7272 {
-
7273 while (start < end) {
-
7274 while (start < end && text[start] && isspace(text[start])) start++;
-
7275 if (start < end && text[start] == ',') {
-
7276 start++;
-
7277 while (start < end&& text[start] && isspace(text[start])) start++;
-
7278 }
-
7279 _Key el;
-
7280 if (el.match(text, start, end, flags)) {
-
7281 start = el.interval.end;
-
7282 T::insert(std::move(el));
-
7283 }
-
7284 else
-
7285 break;
-
7286 }
-
7287 }
-
7288 };
+
7258
+
7262 template <class _Key, class T>
+
+
7263 class http_value_collection : public T
+
7264 {
+
7265 public:
+
7266 void insert(
+
7267 _In_reads_or_z_(end) const char* text,
+
7268 _In_ size_t start = 0,
+
7269 _In_ size_t end = (size_t)-1,
+
7270 _In_ int flags = match_default)
+
7271 {
+
7272 while (start < end) {
+
7273 while (start < end && text[start] && isspace(text[start])) start++;
+
7274 if (start < end && text[start] == ',') {
+
7275 start++;
+
7276 while (start < end&& text[start] && isspace(text[start])) start++;
+
7277 }
+
7278 _Key el;
+
7279 if (el.match(text, start, end, flags)) {
+
7280 start = el.interval.end;
+
7281 T::insert(std::move(el));
+
7282 }
+
7283 else
+
7284 break;
+
7285 }
+
7286 }
+
7287 };
-
7289
-
7290 template <class T>
-
- -
7292 constexpr bool operator()(const T& a, const T& b) const noexcept
-
7293 {
-
7294 return a.factor.value > b.factor.value;
-
7295 }
-
7296 };
+
7288
+
7289 template <class T>
+
+ +
7291 constexpr bool operator()(const T& a, const T& b) const noexcept
+
7292 {
+
7293 return a.factor.value > b.factor.value;
+
7294 }
+
7295 };
-
7297
-
7301 template <class T, class _Alloc = std::allocator<T>>
- -
7303
-
7307 template <class T>
-
- -
7309 {
-
7310 public:
- -
7312 _In_ const std::shared_ptr<basic_parser<T>>& quote,
-
7313 _In_ const std::shared_ptr<basic_parser<T>>& chr,
-
7314 _In_ const std::shared_ptr<basic_parser<T>>& escape,
-
7315 _In_ const std::shared_ptr<basic_parser<T>>& sol,
-
7316 _In_ const std::shared_ptr<basic_parser<T>>& bs,
-
7317 _In_ const std::shared_ptr<basic_parser<T>>& ff,
-
7318 _In_ const std::shared_ptr<basic_parser<T>>& lf,
-
7319 _In_ const std::shared_ptr<basic_parser<T>>& cr,
-
7320 _In_ const std::shared_ptr<basic_parser<T>>& htab,
-
7321 _In_ const std::shared_ptr<basic_parser<T>>& uni,
-
7322 _In_ const std::shared_ptr<basic_integer16<T>>& hex,
-
7323 _In_ const std::locale& locale = std::locale()) :
-
7324 basic_parser<T>(locale),
-
7325 m_quote(quote),
-
7326 m_chr(chr),
-
7327 m_escape(escape),
-
7328 m_sol(sol),
-
7329 m_bs(bs),
-
7330 m_ff(ff),
-
7331 m_lf(lf),
-
7332 m_cr(cr),
-
7333 m_htab(htab),
-
7334 m_uni(uni),
-
7335 m_hex(hex)
-
7336 {}
-
7337
-
7338 virtual bool match(
-
7339 _In_reads_or_z_(end) const T* text,
-
7340 _In_ size_t start = 0,
-
7341 _In_ size_t end = (size_t)-1,
-
7342 _In_ int flags = match_default)
-
7343 {
-
7344 _Assume_(text || start >= end);
-
7345 this->interval.end = start;
-
7346 if (m_quote->match(text, this->interval.end, end, flags)) {
-
7347 this->interval.end = m_quote->interval.end;
-
7348 value.clear();
-
7349 for (;;) {
-
7350 if (m_quote->match(text, this->interval.end, end, flags)) {
-
7351 this->interval.start = start;
-
7352 this->interval.end = m_quote->interval.end;
-
7353 return true;
-
7354 }
-
7355 if (m_escape->match(text, this->interval.end, end, flags)) {
-
7356 if (m_quote->match(text, m_escape->interval.end, end, flags)) {
-
7357 value += '"'; this->interval.end = m_quote->interval.end;
-
7358 continue;
-
7359 }
-
7360 if (m_sol->match(text, m_escape->interval.end, end, flags)) {
-
7361 value += '/'; this->interval.end = m_sol->interval.end;
-
7362 continue;
-
7363 }
-
7364 if (m_bs->match(text, m_escape->interval.end, end, flags)) {
-
7365 value += '\b'; this->interval.end = m_bs->interval.end;
-
7366 continue;
-
7367 }
-
7368 if (m_ff->match(text, m_escape->interval.end, end, flags)) {
-
7369 value += '\f'; this->interval.end = m_ff->interval.end;
-
7370 continue;
-
7371 }
-
7372 if (m_lf->match(text, m_escape->interval.end, end, flags)) {
-
7373 value += '\n'; this->interval.end = m_lf->interval.end;
-
7374 continue;
-
7375 }
-
7376 if (m_cr->match(text, m_escape->interval.end, end, flags)) {
-
7377 value += '\r'; this->interval.end = m_cr->interval.end;
-
7378 continue;
-
7379 }
-
7380 if (m_htab->match(text, m_escape->interval.end, end, flags)) {
-
7381 value += '\t'; this->interval.end = m_htab->interval.end;
-
7382 continue;
-
7383 }
-
7384 if (
-
7385 m_uni->match(text, m_escape->interval.end, end, flags) &&
-
7386 m_hex->match(text, m_uni->interval.end, std::min(m_uni->interval.end + 4, end), flags | match_case_insensitive) &&
-
7387 m_hex->interval.size() == 4 /* JSON requests 4-digit Unicode sequneces: \u.... */)
-
7388 {
-
7389 _Assume_(m_hex->value <= 0xffff);
-
7390 if (sizeof(T) == 1) {
-
7391 if (m_hex->value > 0x7ff) {
-
7392 value += (T)(0xe0 | ((m_hex->value >> 12) & 0x0f));
-
7393 value += (T)(0x80 | ((m_hex->value >> 6) & 0x3f));
-
7394 value += (T)(0x80 | (m_hex->value & 0x3f));
-
7395 }
-
7396 else if (m_hex->value > 0x7f) {
-
7397 value += (T)(0xc0 | ((m_hex->value >> 6) & 0x1f));
-
7398 value += (T)(0x80 | (m_hex->value & 0x3f));
-
7399 }
-
7400 else
-
7401 value += (T)(m_hex->value & 0x7f);
-
7402 }
-
7403 else
-
7404 value += (T)m_hex->value;
-
7405 this->interval.end = m_hex->interval.end;
-
7406 continue;
-
7407 }
-
7408 if (m_escape->match(text, m_escape->interval.end, end, flags)) {
-
7409 value += '\\'; this->interval.end = m_escape->interval.end;
-
7410 continue;
-
7411 }
-
7412 }
-
7413 if (m_chr->match(text, this->interval.end, end, flags)) {
-
7414 value.Prilepi(text + m_chr->interval.start, m_chr->interval.size());
-
7415 this->interval.end = m_chr->interval.end;
-
7416 continue;
-
7417 }
-
7418 break;
-
7419 }
-
7420 }
-
7421 value.clear();
-
7422 this->interval.start = (this->interval.end = start) + 1;
-
7423 return false;
-
7424 }
-
7425
-
7426 virtual void invalidate()
-
7427 {
-
7428 value.clear();
- -
7430 }
-
7431
-
7432 public:
-
7433 std::basic_string<T> value;
-
7434
-
7435 protected:
-
7436 std::shared_ptr<basic_parser<T>> m_quote;
-
7437 std::shared_ptr<basic_parser<T>> m_chr;
-
7438 std::shared_ptr<basic_parser<T>> m_escape;
-
7439 std::shared_ptr<basic_parser<T>> m_sol;
-
7440 std::shared_ptr<basic_parser<T>> m_bs;
-
7441 std::shared_ptr<basic_parser<T>> m_ff;
-
7442 std::shared_ptr<basic_parser<T>> m_lf;
-
7443 std::shared_ptr<basic_parser<T>> m_cr;
-
7444 std::shared_ptr<basic_parser<T>> m_htab;
-
7445 std::shared_ptr<basic_parser<T>> m_uni;
-
7446 std::shared_ptr<basic_integer16<T>> m_hex;
-
7447 };
+
7296
+
7300 template <class T, class _Alloc = std::allocator<T>>
+ +
7302
+
7306 template <class T>
+
+ +
7308 {
+
7309 public:
+ +
7311 _In_ const std::shared_ptr<basic_parser<T>>& quote,
+
7312 _In_ const std::shared_ptr<basic_parser<T>>& chr,
+
7313 _In_ const std::shared_ptr<basic_parser<T>>& escape,
+
7314 _In_ const std::shared_ptr<basic_parser<T>>& sol,
+
7315 _In_ const std::shared_ptr<basic_parser<T>>& bs,
+
7316 _In_ const std::shared_ptr<basic_parser<T>>& ff,
+
7317 _In_ const std::shared_ptr<basic_parser<T>>& lf,
+
7318 _In_ const std::shared_ptr<basic_parser<T>>& cr,
+
7319 _In_ const std::shared_ptr<basic_parser<T>>& htab,
+
7320 _In_ const std::shared_ptr<basic_parser<T>>& uni,
+
7321 _In_ const std::shared_ptr<basic_integer16<T>>& hex,
+
7322 _In_ const std::locale& locale = std::locale()) :
+
7323 basic_parser<T>(locale),
+
7324 m_quote(quote),
+
7325 m_chr(chr),
+
7326 m_escape(escape),
+
7327 m_sol(sol),
+
7328 m_bs(bs),
+
7329 m_ff(ff),
+
7330 m_lf(lf),
+
7331 m_cr(cr),
+
7332 m_htab(htab),
+
7333 m_uni(uni),
+
7334 m_hex(hex)
+
7335 {}
+
7336
+
7337 virtual bool match(
+
7338 _In_reads_or_z_(end) const T* text,
+
7339 _In_ size_t start = 0,
+
7340 _In_ size_t end = (size_t)-1,
+
7341 _In_ int flags = match_default)
+
7342 {
+
7343 _Assume_(text || start >= end);
+
7344 this->interval.end = start;
+
7345 if (m_quote->match(text, this->interval.end, end, flags)) {
+
7346 this->interval.end = m_quote->interval.end;
+
7347 value.clear();
+
7348 for (;;) {
+
7349 if (m_quote->match(text, this->interval.end, end, flags)) {
+
7350 this->interval.start = start;
+
7351 this->interval.end = m_quote->interval.end;
+
7352 return true;
+
7353 }
+
7354 if (m_escape->match(text, this->interval.end, end, flags)) {
+
7355 if (m_quote->match(text, m_escape->interval.end, end, flags)) {
+
7356 value += '"'; this->interval.end = m_quote->interval.end;
+
7357 continue;
+
7358 }
+
7359 if (m_sol->match(text, m_escape->interval.end, end, flags)) {
+
7360 value += '/'; this->interval.end = m_sol->interval.end;
+
7361 continue;
+
7362 }
+
7363 if (m_bs->match(text, m_escape->interval.end, end, flags)) {
+
7364 value += '\b'; this->interval.end = m_bs->interval.end;
+
7365 continue;
+
7366 }
+
7367 if (m_ff->match(text, m_escape->interval.end, end, flags)) {
+
7368 value += '\f'; this->interval.end = m_ff->interval.end;
+
7369 continue;
+
7370 }
+
7371 if (m_lf->match(text, m_escape->interval.end, end, flags)) {
+
7372 value += '\n'; this->interval.end = m_lf->interval.end;
+
7373 continue;
+
7374 }
+
7375 if (m_cr->match(text, m_escape->interval.end, end, flags)) {
+
7376 value += '\r'; this->interval.end = m_cr->interval.end;
+
7377 continue;
+
7378 }
+
7379 if (m_htab->match(text, m_escape->interval.end, end, flags)) {
+
7380 value += '\t'; this->interval.end = m_htab->interval.end;
+
7381 continue;
+
7382 }
+
7383 if (
+
7384 m_uni->match(text, m_escape->interval.end, end, flags) &&
+
7385 m_hex->match(text, m_uni->interval.end, std::min(m_uni->interval.end + 4, end), flags | match_case_insensitive) &&
+
7386 m_hex->interval.size() == 4 /* JSON requests 4-digit Unicode sequneces: \u.... */)
+
7387 {
+
7388 _Assume_(m_hex->value <= 0xffff);
+
7389 if (sizeof(T) == 1) {
+
7390 if (m_hex->value > 0x7ff) {
+
7391 value += (T)(0xe0 | ((m_hex->value >> 12) & 0x0f));
+
7392 value += (T)(0x80 | ((m_hex->value >> 6) & 0x3f));
+
7393 value += (T)(0x80 | (m_hex->value & 0x3f));
+
7394 }
+
7395 else if (m_hex->value > 0x7f) {
+
7396 value += (T)(0xc0 | ((m_hex->value >> 6) & 0x1f));
+
7397 value += (T)(0x80 | (m_hex->value & 0x3f));
+
7398 }
+
7399 else
+
7400 value += (T)(m_hex->value & 0x7f);
+
7401 }
+
7402 else
+
7403 value += (T)m_hex->value;
+
7404 this->interval.end = m_hex->interval.end;
+
7405 continue;
+
7406 }
+
7407 if (m_escape->match(text, m_escape->interval.end, end, flags)) {
+
7408 value += '\\'; this->interval.end = m_escape->interval.end;
+
7409 continue;
+
7410 }
+
7411 }
+
7412 if (m_chr->match(text, this->interval.end, end, flags)) {
+
7413 value.Prilepi(text + m_chr->interval.start, m_chr->interval.size());
+
7414 this->interval.end = m_chr->interval.end;
+
7415 continue;
+
7416 }
+
7417 break;
+
7418 }
+
7419 }
+
7420 value.clear();
+
7421 this->interval.start = (this->interval.end = start) + 1;
+
7422 return false;
+
7423 }
+
7424
+
7425 virtual void invalidate()
+
7426 {
+
7427 value.clear();
+ +
7429 }
+
7430
+
7431 public:
+
7432 std::basic_string<T> value;
+
7433
+
7434 protected:
+
7435 std::shared_ptr<basic_parser<T>> m_quote;
+
7436 std::shared_ptr<basic_parser<T>> m_chr;
+
7437 std::shared_ptr<basic_parser<T>> m_escape;
+
7438 std::shared_ptr<basic_parser<T>> m_sol;
+
7439 std::shared_ptr<basic_parser<T>> m_bs;
+
7440 std::shared_ptr<basic_parser<T>> m_ff;
+
7441 std::shared_ptr<basic_parser<T>> m_lf;
+
7442 std::shared_ptr<basic_parser<T>> m_cr;
+
7443 std::shared_ptr<basic_parser<T>> m_htab;
+
7444 std::shared_ptr<basic_parser<T>> m_uni;
+
7445 std::shared_ptr<basic_integer16<T>> m_hex;
+
7446 };
-
7448
- - -
7451#ifdef _UNICODE
-
7452 using tjson_string = wjson_string;
-
7453#else
-
7454 using tjson_string = json_string;
-
7455#endif
-
7456 }
-
7457}
-
7458
-
7459#undef ENUM_FLAG_OPERATOR
-
7460#undef ENUM_FLAGS
-
7461
-
7462#ifdef _MSC_VER
-
7463#pragma warning(pop)
-
7464#endif
-
Test for angle in d°mm'ss.dddd form.
Definition parser.hpp:4403
-
Test for any code unit.
Definition parser.hpp:229
-
Test for beginning of line.
Definition parser.hpp:623
-
Test for any.
Definition parser.hpp:1065
-
Test for chemical formula.
Definition parser.hpp:5547
-
Test for Creditor Reference.
Definition parser.hpp:4973
-
T reference[22]
Normalized national reference number.
Definition parser.hpp:5102
-
T check_digits[3]
Two check digits.
Definition parser.hpp:5101
-
bool is_valid
Is reference valid per ISO 7064.
Definition parser.hpp:5103
-
Test for any code unit from a given string of code units.
Definition parser.hpp:728
-
Test for specific code unit.
Definition parser.hpp:299
-
Test for date.
Definition parser.hpp:4033
-
Test for valid DNS domain character.
Definition parser.hpp:2814
-
bool allow_on_edge
Is character allowed at the beginning or an end of a DNS domain?
Definition parser.hpp:2852
-
Test for DNS domain/hostname.
Definition parser.hpp:2914
-
bool m_allow_absolute
May DNS names end with a dot (absolute name)?
Definition parser.hpp:2978
-
Test for e-mail address.
Definition parser.hpp:3802
-
Test for emoticon.
Definition parser.hpp:3910
-
std::shared_ptr< basic_parser< T > > apex
apex/eyebrows/halo (e.g. O, 0)
Definition parser.hpp:3999
-
std::shared_ptr< basic_parser< T > > eyes
eyes (e.g. :, ;, >, |, B)
Definition parser.hpp:4000
-
std::shared_ptr< basic_set< T > > mouth
mouth (e.g. ), ), (, (, |, P, D, p, d)
Definition parser.hpp:4002
-
std::shared_ptr< basic_parser< T > > nose
nose (e.g. -, o)
Definition parser.hpp:4001
-
std::shared_ptr< basic_parser< T > > emoticon
emoticon as a whole (e.g. 😀, 🤔, 😶)
Definition parser.hpp:3998
-
Test for end of line.
Definition parser.hpp:661
-
Test for fraction.
Definition parser.hpp:1694
-
Test for International Bank Account Number.
Definition parser.hpp:4679
-
T bban[31]
Normalized Basic Bank Account Number.
Definition parser.hpp:4950
-
T country[3]
ISO 3166-1 alpha-2 country code.
Definition parser.hpp:4948
-
T check_digits[3]
Two check digits.
Definition parser.hpp:4949
-
bool is_valid
Is IBAN valid per ISO 7064.
Definition parser.hpp:4951
-
Test for decimal integer.
Definition parser.hpp:1303
-
Test for decimal integer possibly containing thousand separators.
Definition parser.hpp:1388
-
bool has_separators
Did integer have any separators?
Definition parser.hpp:1448
-
size_t digit_count
Total number of digits in integer.
Definition parser.hpp:1447
-
Test for hexadecimal integer.
Definition parser.hpp:1469
-
Base class for integer testing.
Definition parser.hpp:1281
-
size_t value
Calculated value of the numeral.
Definition parser.hpp:1295
-
Test for IPv4 address.
Definition parser.hpp:2354
-
stdex::interval< size_t > components[4]
Individual component intervals.
Definition parser.hpp:2469
-
struct in_addr value
IPv4 address value.
Definition parser.hpp:2470
-
Test for IPv6 address.
Definition parser.hpp:2573
-
std::shared_ptr< basic_parser< T > > scope_id
Scope ID (e.g. NIC index with link-local addresses)
Definition parser.hpp:2777
-
stdex::interval< size_t > components[8]
Individual component intervals.
Definition parser.hpp:2775
-
struct in6_addr value
IPv6 address value.
Definition parser.hpp:2776
-
Test for valid IPv6 address scope ID character.
Definition parser.hpp:2501
-
Test for repeating.
Definition parser.hpp:918
-
bool m_greedy
try to match as long sequence as possible
Definition parser.hpp:957
-
std::shared_ptr< basic_parser< T > > m_el
repeating element
Definition parser.hpp:954
-
size_t m_min_iterations
minimum number of iterations
Definition parser.hpp:955
-
size_t m_max_iterations
maximum number of iterations
Definition parser.hpp:956
-
Test for JSON string.
Definition parser.hpp:7309
-
Test for mixed numeral.
Definition parser.hpp:1930
-
std::shared_ptr< basic_parser< T > > fraction
fraction
Definition parser.hpp:2036
-
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2034
-
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2033
-
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2032
-
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2035
-
Test for monetary numeral.
Definition parser.hpp:2225
-
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2331
-
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2336
-
std::shared_ptr< basic_parser< T > > currency
Currency part.
Definition parser.hpp:2334
-
std::shared_ptr< basic_parser< T > > decimal
Decimal part.
Definition parser.hpp:2337
-
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2335
-
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2332
-
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2333
-
"No-op" match
Definition parser.hpp:197
-
Base template for all parsers.
Definition parser.hpp:78
-
interval< size_t > interval
Region of the last match.
Definition parser.hpp:177
-
Test for permutation.
Definition parser.hpp:1205
-
Test for phone number.
Definition parser.hpp:4526
-
std::basic_string< T > value
Normalized phone number.
Definition parser.hpp:4652
-
Test for any punctuation code unit.
Definition parser.hpp:471
-
Test for Roman numeral.
Definition parser.hpp:1578
-
Test for scientific numeral.
Definition parser.hpp:2056
-
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2200
-
std::shared_ptr< basic_parser< T > > exponent_symbol
Exponent symbol (e.g. 'e')
Definition parser.hpp:2204
-
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2198
-
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2199
-
double value
Calculated value of the numeral.
Definition parser.hpp:2208
-
std::shared_ptr< basic_parser< T > > negative_exp_sign
Negative exponent sign (e.g. '-')
Definition parser.hpp:2206
-
std::shared_ptr< basic_integer< T > > decimal
Decimal part.
Definition parser.hpp:2203
-
std::shared_ptr< basic_parser< T > > positive_exp_sign
Positive exponent sign (e.g. '+')
Definition parser.hpp:2205
-
std::shared_ptr< basic_integer< T > > exponent
Exponent part.
Definition parser.hpp:2207
-
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2202
-
std::shared_ptr< basic_integer< T > > integer
Integer part.
Definition parser.hpp:2201
-
Test for match score.
Definition parser.hpp:1757
-
Test for sequence.
Definition parser.hpp:1014
-
Definition parser.hpp:696
-
Test for SI Reference delimiter.
Definition parser.hpp:5170
-
Test for SI Reference part.
Definition parser.hpp:5125
-
Test for SI Reference.
Definition parser.hpp:5208
-
basic_si_reference_part< T > part3
Reference data part 3 (P3)
Definition parser.hpp:5525
-
basic_si_reference_part< T > part1
Reference data part 1 (P1)
Definition parser.hpp:5523
-
bool is_valid
Is reference valid.
Definition parser.hpp:5526
-
T model[3]
Reference model.
Definition parser.hpp:5522
-
basic_si_reference_part< T > part2
Reference data part 2 (P2)
Definition parser.hpp:5524
-
Test for signed numeral.
Definition parser.hpp:1844
-
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:1912
-
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:1911
-
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:1910
-
std::shared_ptr< basic_parser< T > > number
Number.
Definition parser.hpp:1913
-
Test for any space code unit.
Definition parser.hpp:392
-
Test for any space or punctuation code unit.
Definition parser.hpp:545
-
Test for any string.
Definition parser.hpp:1133
-
Test for given string.
Definition parser.hpp:823
-
Test for time.
Definition parser.hpp:4300
-
Test for valid URL password character.
Definition parser.hpp:3096
-
Test for valid URL path character.
Definition parser.hpp:3196
-
Test for URL path.
Definition parser.hpp:3304
-
Test for valid URL username character.
Definition parser.hpp:2997
-
Test for URL.
Definition parser.hpp:3445
-
Test for HTTP agent.
Definition parser.hpp:6832
-
Test for HTTP any type.
Definition parser.hpp:5954
-
Test for HTTP asterisk.
Definition parser.hpp:6596
- - - - - -
Test for HTTP header.
Definition parser.hpp:7155
-
Test for HTTP language (RFC1766)
Definition parser.hpp:6464
-
Test for HTTP line break (RFC2616: CRLF | LF)
Definition parser.hpp:5628
-
Test for HTTP media range (RFC2616: media-range)
Definition parser.hpp:5986
-
Test for HTTP media type (RFC2616: media-type)
Definition parser.hpp:6041
-
Test for HTTP parameter (RFC2616: parameter)
Definition parser.hpp:5899
-
http_token name
Parameter name.
Definition parser.hpp:5943
-
http_value value
Parameter value.
Definition parser.hpp:5944
-
Test for HTTP protocol.
Definition parser.hpp:6908
-
uint16_t version
HTTP protocol version: 0x100 = 1.0, 0x101 = 1.1...
Definition parser.hpp:7010
-
Test for HTTP quoted string (RFC2616: quoted-string)
Definition parser.hpp:5789
-
stdex::interval< size_t > content
String content (without quotes)
Definition parser.hpp:5845
-
Test for HTTP request.
Definition parser.hpp:7017
-
Test for HTTP space (RFC2616: LWS)
Definition parser.hpp:5664
-
Test for HTTP text character (RFC2616: TEXT)
Definition parser.hpp:5701
-
Test for HTTP token (RFC2616: token - tolerates non-ASCII)
Definition parser.hpp:5735
-
Test for HTTP URL parameter.
Definition parser.hpp:6281
-
Test for HTTP URL path segment.
Definition parser.hpp:6192
-
Test for HTTP URL path segment.
Definition parser.hpp:6225
-
std::vector< http_url_path_segment > segments
Path segments.
Definition parser.hpp:6274
-
Test for HTTP URL port.
Definition parser.hpp:6136
-
Test for HTTP URL server.
Definition parser.hpp:6099
-
Test for HTTP URL.
Definition parser.hpp:6362
-
Collection of HTTP values.
Definition parser.hpp:7265
-
Test for HTTP value (RFC2616: value)
Definition parser.hpp:5855
-
http_quoted_string string
Value when matched as quoted string.
Definition parser.hpp:5891
-
http_token token
Value when matched as token.
Definition parser.hpp:5892
-
Test for HTTP weight factor.
Definition parser.hpp:6527
-
float value
Calculated value of the weight factor.
Definition parser.hpp:6589
-
Test for HTTP weighted value.
Definition parser.hpp:6619
-
Base template for collection-holding parsers.
Definition parser.hpp:974
-
Test for any SGML code point.
Definition parser.hpp:261
-
Test for any SGML code point from a given string of SGML code points.
Definition parser.hpp:780
-
Test for specific SGML code point.
Definition parser.hpp:348
-
Test for valid DNS domain SGML character.
Definition parser.hpp:2870
-
Test for valid IPv6 address scope ID SGML character.
Definition parser.hpp:2539
-
Test for any SGML punctuation code point.
Definition parser.hpp:512
-
Test for any SGML space code point.
Definition parser.hpp:435
-
Test for any SGML space or punctuation code point.
Definition parser.hpp:588
-
Test for SGML given string.
Definition parser.hpp:870
-
Test for valid URL password SGML character.
Definition parser.hpp:3148
-
Test for valid URL path SGML character.
Definition parser.hpp:3252
-
Test for valid URL username SGML character.
Definition parser.hpp:3048
+
7447
+ + +
7450#ifdef _UNICODE
+
7451 using tjson_string = wjson_string;
+
7452#else
+
7453 using tjson_string = json_string;
+
7454#endif
+
7455 }
+
7456}
+
7457
+
7458#undef ENUM_FLAG_OPERATOR
+
7459#undef ENUM_FLAGS
+
7460
+
7461#ifdef _MSC_VER
+
7462#pragma warning(pop)
+
7463#endif
+
Test for angle in d°mm'ss.dddd form.
Definition parser.hpp:4402
+
Test for any code unit.
Definition parser.hpp:228
+
Test for beginning of line.
Definition parser.hpp:622
+
Test for any.
Definition parser.hpp:1064
+
Test for chemical formula.
Definition parser.hpp:5546
+
Test for Creditor Reference.
Definition parser.hpp:4972
+
T reference[22]
Normalized national reference number.
Definition parser.hpp:5101
+
T check_digits[3]
Two check digits.
Definition parser.hpp:5100
+
bool is_valid
Is reference valid per ISO 7064.
Definition parser.hpp:5102
+
Test for any code unit from a given string of code units.
Definition parser.hpp:727
+
Test for specific code unit.
Definition parser.hpp:298
+
Test for date.
Definition parser.hpp:4032
+
Test for valid DNS domain character.
Definition parser.hpp:2813
+
bool allow_on_edge
Is character allowed at the beginning or an end of a DNS domain?
Definition parser.hpp:2851
+
Test for DNS domain/hostname.
Definition parser.hpp:2913
+
bool m_allow_absolute
May DNS names end with a dot (absolute name)?
Definition parser.hpp:2977
+
Test for e-mail address.
Definition parser.hpp:3801
+
Test for emoticon.
Definition parser.hpp:3909
+
std::shared_ptr< basic_parser< T > > apex
apex/eyebrows/halo (e.g. O, 0)
Definition parser.hpp:3998
+
std::shared_ptr< basic_parser< T > > eyes
eyes (e.g. :, ;, >, |, B)
Definition parser.hpp:3999
+
std::shared_ptr< basic_set< T > > mouth
mouth (e.g. ), ), (, (, |, P, D, p, d)
Definition parser.hpp:4001
+
std::shared_ptr< basic_parser< T > > nose
nose (e.g. -, o)
Definition parser.hpp:4000
+
std::shared_ptr< basic_parser< T > > emoticon
emoticon as a whole (e.g. 😀, 🤔, 😶)
Definition parser.hpp:3997
+
Test for end of line.
Definition parser.hpp:660
+
Test for fraction.
Definition parser.hpp:1693
+
Test for International Bank Account Number.
Definition parser.hpp:4678
+
T bban[31]
Normalized Basic Bank Account Number.
Definition parser.hpp:4949
+
T country[3]
ISO 3166-1 alpha-2 country code.
Definition parser.hpp:4947
+
T check_digits[3]
Two check digits.
Definition parser.hpp:4948
+
bool is_valid
Is IBAN valid per ISO 7064.
Definition parser.hpp:4950
+
Test for decimal integer.
Definition parser.hpp:1302
+
Test for decimal integer possibly containing thousand separators.
Definition parser.hpp:1387
+
bool has_separators
Did integer have any separators?
Definition parser.hpp:1447
+
size_t digit_count
Total number of digits in integer.
Definition parser.hpp:1446
+
Test for hexadecimal integer.
Definition parser.hpp:1468
+
Base class for integer testing.
Definition parser.hpp:1280
+
size_t value
Calculated value of the numeral.
Definition parser.hpp:1294
+
Test for IPv4 address.
Definition parser.hpp:2353
+
stdex::interval< size_t > components[4]
Individual component intervals.
Definition parser.hpp:2468
+
struct in_addr value
IPv4 address value.
Definition parser.hpp:2469
+
Test for IPv6 address.
Definition parser.hpp:2572
+
std::shared_ptr< basic_parser< T > > scope_id
Scope ID (e.g. NIC index with link-local addresses)
Definition parser.hpp:2776
+
stdex::interval< size_t > components[8]
Individual component intervals.
Definition parser.hpp:2774
+
struct in6_addr value
IPv6 address value.
Definition parser.hpp:2775
+
Test for valid IPv6 address scope ID character.
Definition parser.hpp:2500
+
Test for repeating.
Definition parser.hpp:917
+
bool m_greedy
try to match as long sequence as possible
Definition parser.hpp:956
+
std::shared_ptr< basic_parser< T > > m_el
repeating element
Definition parser.hpp:953
+
size_t m_min_iterations
minimum number of iterations
Definition parser.hpp:954
+
size_t m_max_iterations
maximum number of iterations
Definition parser.hpp:955
+
Test for JSON string.
Definition parser.hpp:7308
+
Test for mixed numeral.
Definition parser.hpp:1929
+
std::shared_ptr< basic_parser< T > > fraction
fraction
Definition parser.hpp:2035
+
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2033
+
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2032
+
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2031
+
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2034
+
Test for monetary numeral.
Definition parser.hpp:2224
+
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2330
+
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2335
+
std::shared_ptr< basic_parser< T > > currency
Currency part.
Definition parser.hpp:2333
+
std::shared_ptr< basic_parser< T > > decimal
Decimal part.
Definition parser.hpp:2336
+
std::shared_ptr< basic_parser< T > > integer
Integer part.
Definition parser.hpp:2334
+
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2331
+
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2332
+
"No-op" match
Definition parser.hpp:196
+
Base template for all parsers.
Definition parser.hpp:77
+
interval< size_t > interval
Region of the last match.
Definition parser.hpp:176
+
Test for permutation.
Definition parser.hpp:1204
+
Test for phone number.
Definition parser.hpp:4525
+
std::basic_string< T > value
Normalized phone number.
Definition parser.hpp:4651
+
Test for any punctuation code unit.
Definition parser.hpp:470
+
Test for Roman numeral.
Definition parser.hpp:1577
+
Test for scientific numeral.
Definition parser.hpp:2055
+
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:2199
+
std::shared_ptr< basic_parser< T > > exponent_symbol
Exponent symbol (e.g. 'e')
Definition parser.hpp:2203
+
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:2197
+
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:2198
+
double value
Calculated value of the numeral.
Definition parser.hpp:2207
+
std::shared_ptr< basic_parser< T > > negative_exp_sign
Negative exponent sign (e.g. '-')
Definition parser.hpp:2205
+
std::shared_ptr< basic_integer< T > > decimal
Decimal part.
Definition parser.hpp:2202
+
std::shared_ptr< basic_parser< T > > positive_exp_sign
Positive exponent sign (e.g. '+')
Definition parser.hpp:2204
+
std::shared_ptr< basic_integer< T > > exponent
Exponent part.
Definition parser.hpp:2206
+
std::shared_ptr< basic_parser< T > > decimal_separator
Decimal separator.
Definition parser.hpp:2201
+
std::shared_ptr< basic_integer< T > > integer
Integer part.
Definition parser.hpp:2200
+
Test for match score.
Definition parser.hpp:1756
+
Test for sequence.
Definition parser.hpp:1013
+
Definition parser.hpp:695
+
Test for SI Reference delimiter.
Definition parser.hpp:5169
+
Test for SI Reference part.
Definition parser.hpp:5124
+
Test for SI Reference.
Definition parser.hpp:5207
+
basic_si_reference_part< T > part3
Reference data part 3 (P3)
Definition parser.hpp:5524
+
basic_si_reference_part< T > part1
Reference data part 1 (P1)
Definition parser.hpp:5522
+
bool is_valid
Is reference valid.
Definition parser.hpp:5525
+
T model[3]
Reference model.
Definition parser.hpp:5521
+
basic_si_reference_part< T > part2
Reference data part 2 (P2)
Definition parser.hpp:5523
+
Test for signed numeral.
Definition parser.hpp:1843
+
std::shared_ptr< basic_parser< T > > special_sign
Special sign (e.g. plus-minus '±')
Definition parser.hpp:1911
+
std::shared_ptr< basic_parser< T > > negative_sign
Negative sign.
Definition parser.hpp:1910
+
std::shared_ptr< basic_parser< T > > positive_sign
Positive sign.
Definition parser.hpp:1909
+
std::shared_ptr< basic_parser< T > > number
Number.
Definition parser.hpp:1912
+
Test for any space code unit.
Definition parser.hpp:391
+
Test for any space or punctuation code unit.
Definition parser.hpp:544
+
Test for any string.
Definition parser.hpp:1132
+
Test for given string.
Definition parser.hpp:822
+
Test for time.
Definition parser.hpp:4299
+
Test for valid URL password character.
Definition parser.hpp:3095
+
Test for valid URL path character.
Definition parser.hpp:3195
+
Test for URL path.
Definition parser.hpp:3303
+
Test for valid URL username character.
Definition parser.hpp:2996
+
Test for URL.
Definition parser.hpp:3444
+
Test for HTTP agent.
Definition parser.hpp:6831
+
Test for HTTP any type.
Definition parser.hpp:5953
+
Test for HTTP asterisk.
Definition parser.hpp:6595
+ + + + + +
Test for HTTP header.
Definition parser.hpp:7154
+
Test for HTTP language (RFC1766)
Definition parser.hpp:6463
+
Test for HTTP line break (RFC2616: CRLF | LF)
Definition parser.hpp:5627
+
Test for HTTP media range (RFC2616: media-range)
Definition parser.hpp:5985
+
Test for HTTP media type (RFC2616: media-type)
Definition parser.hpp:6040
+
Test for HTTP parameter (RFC2616: parameter)
Definition parser.hpp:5898
+
http_token name
Parameter name.
Definition parser.hpp:5942
+
http_value value
Parameter value.
Definition parser.hpp:5943
+
Test for HTTP protocol.
Definition parser.hpp:6907
+
uint16_t version
HTTP protocol version: 0x100 = 1.0, 0x101 = 1.1...
Definition parser.hpp:7009
+
Test for HTTP quoted string (RFC2616: quoted-string)
Definition parser.hpp:5788
+
stdex::interval< size_t > content
String content (without quotes)
Definition parser.hpp:5844
+
Test for HTTP request.
Definition parser.hpp:7016
+
Test for HTTP space (RFC2616: LWS)
Definition parser.hpp:5663
+
Test for HTTP text character (RFC2616: TEXT)
Definition parser.hpp:5700
+
Test for HTTP token (RFC2616: token - tolerates non-ASCII)
Definition parser.hpp:5734
+
Test for HTTP URL parameter.
Definition parser.hpp:6280
+
Test for HTTP URL path segment.
Definition parser.hpp:6191
+
Test for HTTP URL path segment.
Definition parser.hpp:6224
+
std::vector< http_url_path_segment > segments
Path segments.
Definition parser.hpp:6273
+
Test for HTTP URL port.
Definition parser.hpp:6135
+
Test for HTTP URL server.
Definition parser.hpp:6098
+
Test for HTTP URL.
Definition parser.hpp:6361
+
Collection of HTTP values.
Definition parser.hpp:7264
+
Test for HTTP value (RFC2616: value)
Definition parser.hpp:5854
+
http_quoted_string string
Value when matched as quoted string.
Definition parser.hpp:5890
+
http_token token
Value when matched as token.
Definition parser.hpp:5891
+
Test for HTTP weight factor.
Definition parser.hpp:6526
+
float value
Calculated value of the weight factor.
Definition parser.hpp:6588
+
Test for HTTP weighted value.
Definition parser.hpp:6618
+
Base template for collection-holding parsers.
Definition parser.hpp:973
+
Test for any SGML code point.
Definition parser.hpp:260
+
Test for any SGML code point from a given string of SGML code points.
Definition parser.hpp:779
+
Test for specific SGML code point.
Definition parser.hpp:347
+
Test for valid DNS domain SGML character.
Definition parser.hpp:2869
+
Test for valid IPv6 address scope ID SGML character.
Definition parser.hpp:2538
+
Test for any SGML punctuation code point.
Definition parser.hpp:511
+
Test for any SGML space code point.
Definition parser.hpp:434
+
Test for any SGML space or punctuation code point.
Definition parser.hpp:587
+
Test for SGML given string.
Definition parser.hpp:869
+
Test for valid URL password SGML character.
Definition parser.hpp:3147
+
Test for valid URL path SGML character.
Definition parser.hpp:3251
+
Test for valid URL username SGML character.
Definition parser.hpp:3047
Numerical interval.
Definition interval.hpp:18
T size() const
Returns interval size.
Definition interval.hpp:47
T end
interval end
Definition interval.hpp:20
interval() noexcept
Constructs an invalid interval.
Definition interval.hpp:25
T start
interval start
Definition interval.hpp:19
-
Definition parser.hpp:7291
+
Definition parser.hpp:7290
diff --git a/pch_8hpp_source.html b/pch_8hpp_source.html index 952ecb79f..0202a0cb6 100644 --- a/pch_8hpp_source.html +++ b/pch_8hpp_source.html @@ -117,7 +117,7 @@ $(document).ready(function() { init_codefold(0); });
diff --git a/progress_8hpp_source.html b/progress_8hpp_source.html index ef76e957e..68b40355e 100644 --- a/progress_8hpp_source.html +++ b/progress_8hpp_source.html @@ -331,7 +331,7 @@ $(document).ready(function() { init_codefold(0); });
diff --git a/ring_8cpp_source.html b/ring_8cpp_source.html index 748c4c438..695749ed3 100644 --- a/ring_8cpp_source.html +++ b/ring_8cpp_source.html @@ -144,7 +144,7 @@ $(document).ready(function() { init_codefold(0); });
diff --git a/ring_8hpp_source.html b/ring_8hpp_source.html index fc95f60fa..e8e509db3 100644 --- a/ring_8hpp_source.html +++ b/ring_8hpp_source.html @@ -223,7 +223,7 @@ $(document).ready(function() { init_codefold(0); });
diff --git a/sgml_8cpp_source.html b/sgml_8cpp_source.html index 02bc30050..2b40472f3 100644 --- a/sgml_8cpp_source.html +++ b/sgml_8cpp_source.html @@ -153,7 +153,7 @@ $(document).ready(function() { init_codefold(0); });
diff --git a/sgml_8hpp_source.html b/sgml_8hpp_source.html index 488639076..5601d3815 100644 --- a/sgml_8hpp_source.html +++ b/sgml_8hpp_source.html @@ -772,7 +772,7 @@ $(document).ready(function() { init_codefold(0); });
diff --git a/sgml__unicode_8hpp_source.html b/sgml__unicode_8hpp_source.html index 215ae64ef..e684a00b5 100644 --- a/sgml__unicode_8hpp_source.html +++ b/sgml__unicode_8hpp_source.html @@ -3175,7 +3175,7 @@ $(document).ready(function() { init_codefold(0); });
diff --git a/stream_8cpp_source.html b/stream_8cpp_source.html index 08a1e72f5..5cd077696 100644 --- a/stream_8cpp_source.html +++ b/stream_8cpp_source.html @@ -257,7 +257,7 @@ $(document).ready(function() { init_codefold(0); });
diff --git a/stream_8hpp_source.html b/stream_8hpp_source.html index a0f8d04a3..cdc10668e 100644 --- a/stream_8hpp_source.html +++ b/stream_8hpp_source.html @@ -95,11 +95,11 @@ $(document).ready(function() { init_codefold(0); });
11#include "math.hpp"
12#include "ring.hpp"
13#include "string.hpp"
-
14#include "system.hpp"
-
15#include "unicode.hpp"
-
16#include <stdint.h>
-
17#include <stdlib.h>
-
18#if defined(_WIN32)
+
14#include "unicode.hpp"
+
15#include <stdint.h>
+
16#include <stdlib.h>
+
17#if defined(_WIN32)
+
18#include <windows.h>
19#include <asptlb.h>
20#include <objidl.h>
21#include <WinSock2.h>
@@ -4009,7 +4009,7 @@ $(document).ready(function() { init_codefold(0); });
4186 }
4187}
-
Encoding converter context.
Definition unicode.hpp:65
+
Encoding converter context.
Definition unicode.hpp:64
Provides read-ahead stream capability.
Definition stream.hpp:1255
virtual size_t read(_Out_writes_bytes_to_opt_(length, return) void *data, size_t length)
Reads block of data from the stream.
Definition stream.hpp:1269
Provides write-back stream capability.
Definition stream.hpp:1322
@@ -4212,8 +4212,8 @@ $(document).ready(function() { init_codefold(0); });
virtual size_t write(_In_reads_bytes_opt_(length) const void *data, size_t length)
Writes block of data to the stream.
Definition stream.hpp:1647
virtual size_t read(_Out_writes_bytes_to_opt_(length, return) void *data, size_t length)
Reads block of data from the stream.
Definition stream.hpp:1618
fpos_t read_offset
Number of bytes to skip on read.
Definition stream.hpp:1685
-
Operating system object (file, pipe, anything with an OS handle etc.)
Definition system.hpp:106
-
virtual void close()
Closes object.
Definition system.hpp:147
+
Operating system object (file, pipe, anything with an OS handle etc.)
Definition system.hpp:91
+
virtual void close()
Closes object.
Definition system.hpp:132
Numerical interval.
Definition interval.hpp:18
bool contains(T x) const
Is value in interval?
Definition interval.hpp:70
T size() const
Returns interval size.
Definition interval.hpp:47
@@ -4224,7 +4224,7 @@ $(document).ready(function() { init_codefold(0); });
diff --git a/string_8hpp_source.html b/string_8hpp_source.html index c8173615c..fd0fb0037 100644 --- a/string_8hpp_source.html +++ b/string_8hpp_source.html @@ -97,1165 +97,1166 @@ $(document).ready(function() { init_codefold(0); });
13#include <stdint.h>
14#include <stdio.h>
15#include <time.h>
-
16#ifdef __APPLE__
-
17#include <xlocale.h>
-
18#endif
-
19#ifdef _WIN32
-
20#include <rpcdce.h>
-
21#else
-
22#include <uuid/uuid.h>
-
23#endif
-
24#include <algorithm>
-
25#include <locale>
-
26#include <memory>
-
27#include <stdexcept>
-
28
-
29namespace stdex
-
30{
-
31#ifdef _WIN32
-
32 using locale_t = _locale_t;
-
33
-
34 inline locale_t create_locale(_In_ int category, _In_z_ const char* locale) { return _create_locale(category, locale); }
-
35 inline locale_t create_locale(_In_ int category, _In_z_ const wchar_t* locale) { return _wcreate_locale(category, locale); }
-
36 inline void free_locale(_In_opt_ locale_t locale) { _free_locale(locale); }
-
37#else
-
38 using locale_t = ::locale_t;
-
39
-
40 inline locale_t create_locale(_In_ int category, _In_z_ const char* locale)
-
41 {
-
42 int mask = 0;
-
43 switch (category) {
-
44 case LC_ALL : mask = LC_ALL_MASK ; break;
-
45 case LC_COLLATE : mask = LC_COLLATE_MASK ; break;
-
46 case LC_CTYPE : mask = LC_CTYPE_MASK ; break;
-
47 case LC_MESSAGES: mask = LC_MESSAGES_MASK; break;
-
48 case LC_MONETARY: mask = LC_MONETARY_MASK; break;
-
49 case LC_NUMERIC : mask = LC_NUMERIC_MASK ; break;
-
50 case LC_TIME : mask = LC_TIME_MASK ; break;
-
51 }
-
52 return newlocale(mask, locale, LC_GLOBAL_LOCALE);
-
53 }
-
54
-
55 inline void free_locale(_In_opt_ locale_t locale) { freelocale(locale); }
-
56#endif
-
57
-
- -
62 {
-
-
66 void operator()(_In_ locale_t locale) const
-
67 {
-
68 free_locale(locale);
-
69 }
+
16#if defined(_WIN32)
+
17#include <windows.h>
+
18#include <rpc.h>
+
19#elif defined(__APPLE__)
+
20#include <uuid/uuid.h>
+
21#include <xlocale.h>
+
22#else
+
23#include <xlocale.h>
+
24#endif
+
25#include <algorithm>
+
26#include <locale>
+
27#include <memory>
+
28#include <stdexcept>
+
29
+
30namespace stdex
+
31{
+
32#ifdef _WIN32
+
33 using locale_t = _locale_t;
+
34
+
35 inline locale_t create_locale(_In_ int category, _In_z_ const char* locale) { return _create_locale(category, locale); }
+
36 inline locale_t create_locale(_In_ int category, _In_z_ const wchar_t* locale) { return _wcreate_locale(category, locale); }
+
37 inline void free_locale(_In_opt_ locale_t locale) { _free_locale(locale); }
+
38#else
+
39 using locale_t = ::locale_t;
+
40
+
41 inline locale_t create_locale(_In_ int category, _In_z_ const char* locale)
+
42 {
+
43 int mask = 0;
+
44 switch (category) {
+
45 case LC_ALL : mask = LC_ALL_MASK ; break;
+
46 case LC_COLLATE : mask = LC_COLLATE_MASK ; break;
+
47 case LC_CTYPE : mask = LC_CTYPE_MASK ; break;
+
48 case LC_MESSAGES: mask = LC_MESSAGES_MASK; break;
+
49 case LC_MONETARY: mask = LC_MONETARY_MASK; break;
+
50 case LC_NUMERIC : mask = LC_NUMERIC_MASK ; break;
+
51 case LC_TIME : mask = LC_TIME_MASK ; break;
+
52 }
+
53 return newlocale(mask, locale, LC_GLOBAL_LOCALE);
+
54 }
+
55
+
56 inline void free_locale(_In_opt_ locale_t locale) { freelocale(locale); }
+
57#endif
+
58
+
+ +
63 {
+
+
67 void operator()(_In_ locale_t locale) const
+
68 {
+
69 free_locale(locale);
+
70 }
-
70 };
+
71 };
-
71
-
75#if defined(_WIN32)
-
76 using locale = std::unique_ptr<__crt_locale_pointers, free_locale_delete>;
-
77#elif defined(__APPLE__)
-
78 using locale = std::unique_ptr<struct _xlocale, free_locale_delete>;
-
79#else
-
80 using locale = std::unique_ptr<struct __locale_struct, free_locale_delete>;
-
81#endif
-
82
-
86 const locale locale_C(create_locale(LC_ALL, "C"));
-
87
-
91#ifdef _WIN32
-
92 typedef wchar_t utf16_t;
-
93#else
-
94 typedef char16_t utf16_t;
-
95#endif
-
96
-
102 inline bool is_high_surrogate(_In_ utf16_t chr)
-
103 {
-
104 return 0xd800 < chr && chr < 0xdc00;
-
105 }
-
106
-
112 inline bool is_low_surrogate(_In_ utf16_t chr)
-
113 {
-
114 return 0xdc00 < chr && chr < 0xe000;
-
115 }
-
116
-
122 inline bool is_surrogate_pair(_In_reads_(2) const utf16_t* str)
-
123 {
-
124 return is_high_surrogate(str[0]) && is_low_surrogate(str[1]);
-
125 }
-
126
-
132 inline char32_t surrogate_pair_to_ucs4(_In_reads_(2) const utf16_t* str)
-
133 {
-
134 _Assume_(is_surrogate_pair(str));
-
135 return
-
136 ((char32_t)(str[0] - 0xd800) << 10) +
-
137 (char32_t)(str[1] - 0xdc00) +
-
138 0x10000;
-
139 }
-
140
-
146 inline void ucs4_to_surrogate_pair(_Out_writes_(2) utf16_t* str, _In_ char32_t chr)
-
147 {
-
148 _Assume_(chr >= 0x10000);
-
149 chr -= 0x10000;
-
150 str[0] = 0xd800 + (char32_t)((chr >> 10) & 0x3ff);
-
151 str[1] = 0xdc00 + (char32_t)(chr & 0x3ff);
-
152 }
-
153
-
159 inline bool iscombining(_In_ char32_t chr)
-
160 {
-
161 return
-
162 (0x0300 <= chr && chr < 0x0370) ||
-
163 (0x1dc0 <= chr && chr < 0x1e00) ||
-
164 (0x20d0 <= chr && chr < 0x2100) ||
-
165 (0xfe20 <= chr && chr < 0xfe30);
-
166 }
-
167
-
173 template <class T>
-
174 inline size_t islbreak(_In_ T chr)
-
175 {
-
176 return chr == '\n' || chr == '\r';
-
177 }
-
178
-
185 template <class T>
-
186 inline size_t islbreak(_In_reads_or_z_opt_(count) const T* chr, _In_ size_t count)
-
187 {
-
188 _Assume_(chr || !count);
-
189 if (count >= 2 && ((chr[0] == '\r' && chr[1] == '\n') || (chr[0] == '\n' && chr[1] == '\r')))
-
190 return 2;
-
191 if (count > 1 && (chr[0] == '\n' || chr[0] == '\r'))
-
192 return 1;
-
193 return 0;
-
194 }
-
195
-
202 inline size_t glyphlen(_In_reads_or_z_opt_(count) const wchar_t* glyph, _In_ size_t count)
-
203 {
-
204 _Assume_(glyph || !count);
-
205 if (count) {
-
206#ifdef _WIN32
-
207 size_t i = count < 2 || !is_surrogate_pair(glyph) ? 1 : 2;
-
208#else
-
209 size_t i = 1;
-
210#endif
-
211 for (; i < count && iscombining(glyph[i]); ++i);
-
212 return i;
-
213 }
-
214 return 0;
-
215 }
-
216
-
224 template <class T>
-
225 inline size_t strlen(_In_z_ const T* str)
-
226 {
-
227 _Assume_(str);
-
228 size_t i;
-
229 for (i = 0; str[i]; ++i);
-
230 return i;
-
231 }
-
232
-
241 template <class T>
-
242 inline size_t strnlen(_In_reads_or_z_opt_(count) const T* str, _In_ size_t count)
-
243 {
-
244 _Assume_(str || !count);
-
245 size_t i;
-
246 for (i = 0; i < count && str[i]; ++i);
-
247 return i;
-
248 }
-
249
-
250 constexpr auto npos{ static_cast<size_t>(-1) };
-
251
-
260 template <class T>
-
261 inline size_t strchr(_In_z_ const T* str, _In_ T chr)
-
262 {
-
263 _Assume_(str);
-
264 for (size_t i = 0; str[i]; ++i)
-
265 if (str[i] == chr) return i;
-
266 return npos;
-
267 }
-
268
-
278 template <class T>
-
279 inline size_t strnchr(
-
280 _In_reads_or_z_opt_(count) const T* str,
-
281 _In_ size_t count,
-
282 _In_ T chr)
-
283 {
-
284 _Assume_(str || !count);
-
285 for (size_t i = 0; i < count && str[i]; ++i)
-
286 if (str[i] == chr) return i;
-
287 return npos;
-
288 }
-
289
-
299 template <class T>
-
300 inline size_t strrnchr(
-
301 _In_reads_or_z_opt_(count) const T* str,
-
302 _In_ size_t count,
-
303 _In_ T chr)
-
304 {
-
305 _Assume_(str || !count);
-
306 size_t z = npos;
-
307 for (size_t i = 0; i < count && str[i]; ++i)
-
308 if (str[i] == chr) z = i;
-
309 return z;
-
310 }
-
311
-
321 template <class T>
-
322 inline size_t strnichr(
-
323 _In_reads_or_z_opt_(count) const T* str,
-
324 _In_ size_t count,
-
325 _In_ T chr,
-
326 _In_ const std::locale& locale)
-
327 {
-
328 _Assume_(str || !count);
-
329 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
-
330 chr = ctype.tolower(chr);
-
331 for (size_t i = 0; i < count && str[i]; ++i)
-
332 if (ctype.tolower(str[i]) == chr) return i;
-
333 return npos;
-
334 }
-
335
-
345 template <class T>
-
346 inline size_t strrnichr(
-
347 _In_reads_or_z_opt_(count) const T* str,
-
348 _In_ size_t count,
-
349 _In_ T chr,
-
350 _In_ const std::locale& locale)
-
351 {
-
352 _Assume_(str || !count);
-
353 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
-
354 chr = ctype.tolower(chr);
-
355 size_t z = npos;
-
356 for (size_t i = 0; i < count && str[i]; ++i)
-
357 if (ctype.tolower(str[i]) == chr) z = i;
-
358 return z;
-
359 }
-
360
-
369 template <class T1, class T2>
-
370 inline int strcmp(const T1* str1, const T2* str2)
-
371 {
-
372 _Assume_(str1 && str2);
-
373 T1 a; T2 b;
-
374 for (size_t i = 0; (a = str1[i]) | (b = str2[i]); ++i) {
-
375 if (a > b) return +1;
-
376 if (a < b) return -1;
-
377 }
-
378 return 0;
-
379 }
-
380
-
391 template <class T1, class T2>
-
392 inline int strncmp(
-
393 _In_reads_or_z_opt_(count1) const T1* str1, _In_ size_t count1,
-
394 _In_reads_or_z_opt_(count2) const T2* str2, _In_ size_t count2)
-
395 {
-
396 _Assume_(str1 || !count1);
-
397 _Assume_(str2 || !count2);
-
398 size_t i; T1 a; T2 b;
-
399 for (i = 0; i < count1 && i < count2 && ((a = str1[i]) | (b = str2[i])); ++i) {
-
400 if (a > b) return +1;
-
401 if (a < b) return -1;
-
402 }
-
403 if (i < count1 && str1[i]) return +1;
-
404 if (i < count2 && str2[i]) return -1;
-
405 return 0;
-
406 }
-
407
-
417 template <class T1, class T2>
-
418 inline int strncmp(_In_reads_or_z_opt_(count) const T1* str1, _In_reads_or_z_opt_(count) const T2* str2, _In_ size_t count)
-
419 {
-
420 _Assume_((str1 && str2) || !count);
-
421 size_t i; T1 a; T2 b;
-
422 for (i = 0; i < count && ((a = str1[i]) | (b = str2[i])); ++i) {
-
423 if (a > b) return +1;
-
424 if (a < b) return -1;
-
425 }
-
426 if (i < count && str1[i]) return +1;
-
427 if (i < count && str2[i]) return -1;
-
428 return 0;
-
429 }
-
430
-
441 template <class T>
-
442 inline int strncoll(
-
443 _In_reads_or_z_opt_(count1) const T* str1, _In_ size_t count1,
-
444 _In_reads_or_z_opt_(count2) const T* str2, _In_ size_t count2,
-
445 _In_ const std::locale& locale)
-
446 {
-
447 _Assume_(str1 || !count1);
-
448 _Assume_(str2 || !count2);
-
449 auto& collate = std::use_facet<std::collate<T>>(locale);
-
450 return collate.compare(str1, str1 + count1, str2, str2 + count2);
-
451 }
-
452
-
461 template <class T1, class T2>
-
462 inline int stricmp(_In_z_ const T1* str1, _In_z_ const T2* str2, _In_ const std::locale& locale)
-
463 {
-
464 _Assume_(str1);
-
465 _Assume_(str2);
-
466 size_t i; T1 a; T2 b;
-
467 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
-
468 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
-
469 for (i = 0; (a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i])); i++) {
-
470 if (a > b) return +1;
-
471 if (a < b) return -1;
-
472 }
-
473 if (str1[i]) return +1;
-
474 if (str2[i]) return -1;
-
475 return 0;
-
476 }
-
477
-
487 template <class T1, class T2>
-
488 inline int strnicmp(_In_reads_or_z_opt_(count) const T1* str1, _In_reads_or_z_opt_(count) const T2* str2, _In_ size_t count, _In_ const std::locale& locale)
-
489 {
-
490 _Assume_(str1 || !count);
-
491 _Assume_(str2 || !count);
-
492 size_t i; T1 a; T2 b;
-
493 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
-
494 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
-
495 for (i = 0; i < count && ((a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i]))); i++) {
-
496 if (a > b) return +1;
-
497 if (a < b) return -1;
-
498 }
-
499 if (i < count && str1[i]) return +1;
-
500 if (i < count && str2[i]) return -1;
-
501 return 0;
-
502 }
-
503
-
514 template <class T1, class T2>
-
515 inline int strnicmp(
-
516 _In_reads_or_z_opt_(count1) const T1* str1, _In_ size_t count1,
-
517 _In_reads_or_z_opt_(count2) const T2* str2, _In_ size_t count2,
-
518 _In_ const std::locale& locale)
-
519 {
-
520 _Assume_(str1 || !count1);
-
521 _Assume_(str2 || !count2);
-
522 size_t i; T1 a; T2 b;
-
523 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
-
524 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
-
525 for (i = 0; i < count1 && i < count2 && ((a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i]))); i++) {
-
526 if (a > b) return +1;
-
527 if (a < b) return -1;
-
528 }
-
529 if (i < count1 && str1[i]) return +1;
-
530 if (i < count2 && str2[i]) return -1;
-
531 return 0;
-
532 }
-
533
-
542 template <class T1, class T2>
-
543 inline size_t strstr(
-
544 _In_z_ const T1* str,
-
545 _In_z_ const T2* sample)
-
546 {
-
547 _Assume_(str);
-
548 _Assume_(sample);
-
549 for (size_t offset = 0;; ++offset) {
-
550 for (size_t i = offset, j = 0;; ++i, ++j) {
-
551 if (!sample[j])
-
552 return offset;
-
553 if (!str[i])
-
554 return npos;
-
555 if (str[i] != sample[j])
-
556 break;
-
557 }
-
558 }
-
559 }
-
560
-
570 template <class T1, class T2>
-
571 inline size_t strnstr(
-
572 _In_reads_or_z_opt_(count) const T1* str,
-
573 _In_ size_t count,
-
574 _In_z_ const T2* sample)
-
575 {
-
576 _Assume_(str || !count);
-
577 _Assume_(sample);
-
578 for (size_t offset = 0;; ++offset) {
-
579 for (size_t i = offset, j = 0;; ++i, ++j) {
-
580 if (!sample[j])
-
581 return offset;
-
582 if (i >= count || !str[i])
-
583 return npos;
-
584 if (str[i] != sample[j])
-
585 break;
-
586 }
-
587 }
-
588 }
-
589
-
598 template <class T1, class T2>
-
599 inline size_t stristr(
-
600 _In_z_ const T1* str,
-
601 _In_z_ const T2* sample,
-
602 _In_ const std::locale& locale)
-
603 {
-
604 _Assume_(str);
-
605 _Assume_(sample);
-
606 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
-
607 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
-
608 for (size_t offset = 0;; ++offset) {
-
609 for (size_t i = offset, j = 0;; ++i, ++j) {
-
610 if (!sample[j])
-
611 return offset;
-
612 if (!str[i])
-
613 return npos;
-
614 if (ctype1.tolower(str[i]) != ctype2.tolower(sample[j]))
-
615 break;
-
616 }
-
617 }
-
618 }
-
619
-
629 template <class T1, class T2>
-
630 inline size_t strnistr(
-
631 _In_reads_or_z_opt_(count) const T1* str,
-
632 _In_ size_t count,
-
633 _In_z_ const T2* sample,
-
634 _In_ const std::locale& locale)
-
635 {
-
636 _Assume_(str || !count);
-
637 _Assume_(sample);
-
638 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
-
639 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
-
640 for (size_t offset = 0;; ++offset) {
-
641 for (size_t i = offset, j = 0;; ++i, ++j) {
-
642 if (!sample[j])
-
643 return offset;
-
644 if (i >= count || !str[i])
-
645 return npos;
-
646 if (ctype1.tolower(str[i]) != ctype2.tolower(sample[j]))
-
647 break;
-
648 }
-
649 }
-
650 }
-
651
-
660 template <class T1, class T2>
-
661 inline size_t strcpy(
-
662 _Out_writes_z_(_String_length_(src) + 1) T1* dst,
-
663 _In_z_ const T2* src)
-
664 {
-
665 _Assume_(dst && src);
-
666 for (size_t i = 0; ; ++i) {
-
667 if ((dst[i] = src[i]) == 0)
-
668 return i;
-
669 }
-
670 }
-
671
-
681 template <class T1, class T2>
-
682 inline size_t strncpy(
-
683 _Out_writes_(count) _Post_maybez_ T1* dst,
-
684 _In_reads_or_z_opt_(count) const T2* src, _In_ size_t count)
-
685 {
-
686 _Assume_(dst && src || !count);
-
687 for (size_t i = 0; ; ++i) {
-
688 if (i >= count)
-
689 return i;
-
690 if ((dst[i] = src[i]) == 0)
-
691 return i;
-
692 }
-
693 }
-
694
-
705 template <class T1, class T2>
-
706 inline size_t strncpy(
-
707 _Out_writes_(count_dst) _Post_maybez_ T1* dst, _In_ size_t count_dst,
-
708 _In_reads_or_z_opt_(count_src) const T2* src, _In_ size_t count_src)
-
709 {
-
710 _Assume_(dst || !count_dst);
-
711 _Assume_(src || !count_src);
-
712 for (size_t i = 0; ; ++i)
-
713 {
-
714 if (i >= count_dst)
-
715 return i;
-
716 if (i >= count_src) {
-
717 dst[i] = 0;
-
718 return i;
-
719 }
-
720 if ((dst[i] = src[i]) == 0)
-
721 return i;
-
722 }
-
723 }
-
724
-
733 template <class T1, class T2>
-
734 inline size_t strcat(
-
735 _In_z_ _Out_writes_z_(_String_length_(dst) + _String_length_(src) + 1) T1* dst,
-
736 _In_z_ const T2* src)
-
737 {
-
738 _Assume_(dst && src);
-
739 for (size_t i = 0, j = stdex::strlen<T1>(dst); ; ++i, ++j) {
-
740 if ((dst[j] = src[i]) == 0)
-
741 return j;
-
742 }
-
743 }
-
744
-
754 template <class T1, class T2>
-
755 inline size_t strncat(
-
756 _Out_writes_(count) _Post_maybez_ T1* dst,
-
757 _In_reads_or_z_opt_(count) const T2* src, _In_ size_t count)
-
758 {
-
759 _Assume_(dst && src || !count);
-
760 for (size_t i = 0, j = stdex::strlen<T1>(dst); ; ++i, ++j) {
-
761 if (i >= count)
-
762 return j;
-
763 if ((dst[j] = src[i]) == 0)
-
764 return j;
-
765 }
-
766 }
-
767
-
778 template <class T1, class T2>
-
779 inline size_t strncat(
-
780 _Out_writes_(count_dst) _Post_maybez_ T1* dst, _In_ size_t count_dst,
-
781 _In_reads_or_z_opt_(count_src) const T2* src, _In_ size_t count_src)
-
782 {
-
783 _Assume_(dst || !count_dst);
-
784 _Assume_(src || !count_src);
-
785 for (size_t i = 0, j = stdex::strnlen<T1>(dst, count_dst); ; ++i, ++j)
-
786 {
-
787 if (j >= count_dst)
-
788 return j;
-
789 if (i >= count_src) {
-
790 dst[j] = 0;
-
791 return j;
-
792 }
-
793 if ((dst[j] = src[i]) == 0)
-
794 return j;
-
795 }
-
796 }
-
797
-
808 template <class T>
-
809 inline _Check_return_ _Ret_maybenull_z_ T* strdup(_In_opt_z_ const T* str)
-
810 {
-
811 if (!str) _Unlikely_
-
812 return nullptr;
-
813 size_t count = strlen(str) + 1;
-
814 T* dst = new T[count];
-
815 strncpy(dst, count, str, SIZE_MAX);
-
816 return dst;
-
817 }
-
818
-
830 template <class T>
-
831 inline _Ret_z_ T* strndup(
-
832 _In_reads_or_z_opt_(count) const T* str,
-
833 _In_ size_t count)
-
834 {
-
835 T* dst = new T[count];
-
836 strncpy(dst, count, str, SIZE_MAX);
-
837 return dst;
-
838 }
-
839
-
849 template <class T>
-
850 inline size_t crlf2nl(_Out_writes_z_(strlen(src)) T* dst, _In_z_ const T* src)
-
851 {
-
852 _Assume_(dst);
-
853 _Assume_(src);
-
854 size_t i, j;
-
855 for (i = j = 0; src[j];) {
-
856 if (src[j] != '\r' || src[j + 1] != '\n')
-
857 dst[i++] = src[j++];
-
858 else {
-
859 dst[i++] = '\n';
-
860 j += 2;
-
861 }
-
862 }
-
863 dst[i] = 0;
-
864 return i;
-
865 }
-
866
-
873 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
-
874 inline void crlf2nl(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &dst, _In_z_ const _Elem* src)
-
875 {
-
876 _Assume_(src);
-
877 _Assume_(src != dst.c_str());
-
878 dst.clear();
-
879 dst.reserve(strlen(src));
-
880 for (size_t j = 0; src[j];) {
-
881 if (src[j] != '\r' || src[j + 1] != '\n')
-
882 dst += src[j++];
-
883 else {
-
884 dst += '\n';
-
885 j += 2;
-
886 }
-
887 }
-
888 }
-
889
-
895 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
-
896 inline void crlf2nl(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str)
-
897 {
-
898 size_t i, j, n;
-
899 for (i = j = 0, n = str.size(); j < n;) {
-
900 if (str[j] != '\r' || str[j + 1] != '\n')
-
901 str[i++] = str[j++];
-
902 else {
-
903 str[i++] = '\n';
-
904 j += 2;
-
905 }
-
906 }
-
907 str.resize(i);
-
908 }
-
909
-
911 template <class T, class T_bin>
-
912 inline T_bin strtoint(
-
913 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
-
914 _Out_opt_ size_t* end,
-
915 _In_ int radix,
-
916 _Out_ uint8_t& flags)
-
917 {
-
918 _Assume_(str || !count);
-
919 _Assume_(radix == 0 || 2 <= radix && radix <= 36);
-
920
-
921 size_t i = 0;
-
922 T_bin value = 0, digit,
-
923 max_ui = (T_bin)-1,
-
924 max_ui_pre1, max_ui_pre2;
-
925
-
926 flags = 0;
-
927
-
928 // Skip leading spaces.
-
929 for (;; ++i) {
-
930 if (i >= count || !str[i]) goto error;
-
931 if (!isspace(str[i])) break;
-
932 }
-
933
-
934 // Read the sign.
-
935 if (str[i] == '+') {
-
936 flags &= ~0x01;
-
937 ++i;
-
938 if (i >= count || !str[i]) goto error;
-
939 }
-
940 else if (str[i] == '-') {
-
941 flags |= 0x01;
-
942 ++i;
-
943 if (i >= count || !str[i]) goto error;
-
944 }
-
945
-
946 if (radix == 16) {
-
947 // On hexadecimal, allow leading 0x.
-
948 if (str[i] == '0' && i + 1 < count && (str[i + 1] == 'x' || str[i + 1] == 'X')) {
-
949 i += 2;
-
950 if (i >= count || !str[i]) goto error;
-
951 }
-
952 }
-
953 else if (!radix) {
-
954 // Autodetect radix.
-
955 if (str[i] == '0') {
-
956 ++i;
-
957 if (i >= count || !str[i]) goto error;
-
958 if (str[i] == 'x' || str[i] == 'X') {
-
959 radix = 16;
-
960 ++i;
-
961 if (i >= count || !str[i]) goto error;
-
962 }
-
963 else
-
964 radix = 8;
-
965 }
-
966 else
-
967 radix = 10;
-
968 }
-
969
-
970 // We have the radix.
-
971 max_ui_pre1 = max_ui / (T_bin)radix;
-
972 max_ui_pre2 = max_ui % (T_bin)radix;
-
973 for (;;) {
-
974 if ('0' <= str[i] && str[i] <= '9')
-
975 digit = (T_bin)str[i] - '0';
-
976 else if ('A' <= str[i] && str[i] <= 'Z')
-
977 digit = (T_bin)str[i] - 'A' + '\x0a';
-
978 else if ('a' <= str[i] && str[i] <= 'z')
-
979 digit = (T_bin)str[i] - 'a' + '\x0a';
-
980 else
-
981 goto error;
-
982 if (digit >= (T_bin)radix)
-
983 goto error;
-
984
-
985 if (value < max_ui_pre1 || // Multiplication nor addition will not overflow.
-
986 (value == max_ui_pre1 && digit <= max_ui_pre2)) // Small digits will not overflow.
-
987 value = value * (T_bin)radix + digit;
-
988 else {
-
989 // Overflow!
-
990 flags |= 0x02;
-
991 }
-
992
-
993 ++i;
-
994 if (i >= count || !str[i])
-
995 goto error;
-
996 }
-
997
-
998 error:
-
999 if (end) *end = i;
-
1000 return value;
-
1001 }
-
1003
-
1014 template <class T, class T_bin>
-
1015 T_bin strtoint(
-
1016 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
-
1017 _Out_opt_ size_t* end,
-
1018 _In_ int radix)
-
1019 {
-
1020 uint8_t flags;
-
1021 T_bin value;
-
1022
-
1023 switch (sizeof(T_bin)) {
-
1024 case 1:
-
1025 value = (T_bin)strtoint<T, uint8_t>(str, count, end, radix, flags);
-
1026 if ((flags & 0x01) && (value & 0x80)) {
-
1027 // Sign bit is 1 => overflow.
-
1028 flags |= 0x02;
-
1029 }
-
1030 return (flags & 0x02) ?
-
1031 (flags & 0x01) ? (T_bin)0x80 : (T_bin)0x7f :
-
1032 (flags & 0x01) ? -value : value;
-
1033
-
1034 case 2:
-
1035 value = (T_bin)strtoint<T, uint16_t>(str, count, end, radix, flags);
-
1036 if ((flags & 0x01) && (value & 0x8000)) {
-
1037 // Sign bit is 1 => overflow.
-
1038 flags |= 0x02;
-
1039 }
-
1040 return (flags & 0x02) ?
-
1041 (flags & 0x01) ? (T_bin)0x8000 : (T_bin)0x7fff :
-
1042 (flags & 0x01) ? -value : value;
-
1043
-
1044 case 4:
-
1045 value = (T_bin)strtoint<T, uint32_t>(str, count, end, radix, flags);
-
1046 if ((flags & 0x01) && (value & 0x80000000)) {
-
1047 // Sign bit is 1 => overflow.
-
1048 flags |= 0x02;
-
1049 }
-
1050 return (flags & 0x02) ?
-
1051 (flags & 0x01) ? (T_bin)0x80000000 : (T_bin)0x7fffffff :
-
1052 (flags & 0x01) ? -value : value;
-
1053
-
1054 case 8:
-
1055 value = (T_bin)strtoint<T, uint64_t>(str, count, end, radix, flags);
-
1056 if ((flags & 0x01) && (value & 0x8000000000000000)) {
-
1057 // Sign bit is 1 => overflow.
-
1058 flags |= 0x02;
-
1059 }
-
1060 return (flags & 0x02) ?
-
1061 (flags & 0x01) ? (T_bin)0x8000000000000000 : (T_bin)0x7fffffffffffffff :
-
1062 (flags & 0x01) ? -value : value;
-
1063
-
1064 default:
-
1065 throw std::invalid_argument("Unsupported bit length");
-
1066 }
-
1067 }
-
1068
-
1079 template <class T, class T_bin>
-
1080 inline T_bin strtouint(
-
1081 _In_reads_or_z_opt_(count) const T* str,
-
1082 _In_ size_t count,
-
1083 _Out_opt_ size_t* end,
-
1084 _In_ int radix)
-
1085 {
-
1086 uint8_t flags;
-
1087 T_bin value;
-
1088
-
1089 switch (sizeof(T_bin)) {
-
1090 case 1: value = (T_bin)strtoint<T, uint8_t>(str, count, end, radix, flags); break;
-
1091 case 2: value = (T_bin)strtoint<T, uint16_t>(str, count, end, radix, flags); break;
-
1092 case 4: value = (T_bin)strtoint<T, uint32_t>(str, count, end, radix, flags); break;
-
1093 case 8: value = (T_bin)strtoint<T, uint64_t>(str, count, end, radix, flags); break;
-
1094 default: throw std::invalid_argument("Unsupported bit length");
-
1095 }
-
1096
-
1097 return (flags & 0x02) ?
-
1098 (flags & 0x01) ? (T_bin)0 : (T_bin)-1 :
-
1099 (flags & 0x01) ? ~value : value;
-
1100 }
-
1101
-
1112 template <class T>
-
1113 inline int32_t strto32(
-
1114 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
-
1115 _Out_opt_ size_t* end,
-
1116 _In_ int radix)
-
1117 {
-
1118 return strtoint<T, int32_t>(str, count, end, radix);
-
1119 }
-
1120
-
1131 template <class T>
-
1132 inline int64_t strto64(
-
1133 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
-
1134 _Out_opt_ size_t* end,
-
1135 _In_ int radix)
-
1136 {
-
1137 return strtoint<T, int64_t>(str, count, end, radix);
-
1138 }
-
1139
-
1151 template <class T>
-
1152 inline intptr_t strtoi(
-
1153 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
-
1154 _Out_opt_ size_t* end,
-
1155 _In_ int radix)
-
1156 {
-
1157#if defined(_WIN64) || defined(__LP64__)
-
1158 return (intptr_t)strto64(str, count, end, radix);
-
1159#else
-
1160 return (intptr_t)strto32(str, count, end, radix);
-
1161#endif
-
1162 }
-
1163
-
1174 template <class T>
-
1175 inline uint32_t strtou32(
-
1176 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
-
1177 _Out_opt_ size_t* end,
-
1178 _In_ int radix)
-
1179 {
-
1180 return strtouint<T, uint32_t>(str, count, end, radix);
-
1181 }
-
1182
-
1193 template <class T>
-
1194 inline uint64_t strtou64(
-
1195 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
-
1196 _Out_opt_ size_t* end,
-
1197 _In_ int radix)
-
1198 {
-
1199 return strtouint<T, uint64_t>(str, count, end, radix);
-
1200 }
-
1201
-
1213 template <class T>
-
1214 inline size_t strtoui(
-
1215 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
-
1216 _Out_opt_ size_t* end,
-
1217 _In_ int radix)
-
1218 {
-
1219#if defined(_WIN64) || defined(__LP64__)
-
1220 return (size_t)strtou64(str, count, end, radix);
-
1221#else
-
1222 return (size_t)strtou32(str, count, end, radix);
-
1223#endif
-
1224 }
-
1225
-
1227 inline int vsnprintf(_Out_z_cap_(capacity) char *str, _In_ size_t capacity, _In_z_ _Printf_format_string_params_(2) const char *format, _In_opt_ locale_t locale, _In_ va_list arg)
-
1228 {
-
1229 int r;
-
1230#ifdef _WIN32
-
1231 // Don't use _vsnprintf_s(). It terminates the string even if we want to print to the edge of the buffer.
-
1232#pragma warning(suppress: 4996)
-
1233 r = _vsnprintf_l(str, capacity, format, locale, arg);
-
1234#else
-
1235 r = ::vsnprintf(str, capacity, format, arg);
-
1236#endif
-
1237 if (r == -1 && strnlen(str, capacity) == capacity) {
-
1238 // Buffer overrun. Estimate buffer size for the next iteration.
-
1239 capacity += std::max<size_t>(capacity / 8, 0x80);
-
1240 if (capacity > INT_MAX)
-
1241 throw std::invalid_argument("string too big");
-
1242 return (int)capacity;
-
1243 }
-
1244 return r;
-
1245 }
-
1246
-
1247 inline int vsnprintf(_Out_z_cap_(capacity) wchar_t *str, _In_ size_t capacity, _In_z_ _Printf_format_string_params_(2) const wchar_t *format, _In_opt_ locale_t locale, _In_ va_list arg)
-
1248 {
-
1249 int r;
-
1250#ifdef _WIN32
-
1251 // Don't use _vsnwprintf_s(). It terminates the string even if we want to print to the edge of the buffer.
-
1252#pragma warning(suppress: 4996)
-
1253 r = _vsnwprintf_l(str, capacity, format, locale, arg);
-
1254#else
-
1255 r = vswprintf(str, capacity, format, arg);
-
1256#endif
-
1257 if (r == -1 && strnlen(str, capacity) == capacity) {
-
1258 // Buffer overrun. Estimate buffer size for the next iteration.
-
1259 capacity += std::max<size_t>(capacity / 8, 0x80);
-
1260 if (capacity > INT_MAX)
-
1261 throw std::invalid_argument("string too big");
-
1262 return (int)capacity;
-
1263 }
-
1264 return r;
-
1265 }
-
1267
-
1276 template<class _Elem, class _Traits, class _Ax>
-
1277 inline void vappendf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_params_(2) const _Elem *format, _In_opt_ locale_t locale, _In_ va_list arg)
-
1278 {
-
1279 _Elem buf[1024/sizeof(_Elem)];
-
1280
-
1281 // Try with stack buffer first.
-
1282 int count = vsnprintf(buf, _countof(buf) - 1, format, locale, arg);
-
1283 if (count >= 0) {
-
1284 // Copy from stack.
-
1285 str.append(buf, count);
-
1286 } else {
-
1287 for (size_t capacity = 2*1024/sizeof(_Elem);; capacity *= 2) {
-
1288 // Allocate on heap and retry.
-
1289 auto buf_dyn = std::make_unique<_Elem[]>(capacity);
-
1290 count = vsnprintf(buf_dyn.get(), capacity - 1, format, locale, arg);
-
1291 if (count >= 0) {
-
1292 str.append(buf_dyn.get(), count);
-
1293 break;
-
1294 }
-
1295 }
-
1296 }
-
1297 }
-
1298
-
1306 template<class _Elem, class _Traits, class _Ax>
-
1307 inline void appendf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_params_(2) const _Elem *format, _In_opt_ locale_t locale, ...)
-
1308 {
-
1309 va_list arg;
-
1310 va_start(arg, locale);
-
1311 vappendf(str, format, locale, arg);
-
1312 va_end(arg);
-
1313 }
-
1314
-
1323 template<class _Elem, class _Traits, class _Ax>
-
1324 inline void vsprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_params_(2) const _Elem *format, _In_opt_ locale_t locale, _In_ va_list arg)
-
1325 {
-
1326 str.clear();
-
1327 vappendf(str, format, locale, arg);
-
1328 }
-
1329
-
1337 template<class _Elem, class _Traits, class _Ax>
-
1338 inline void sprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_params_(2) const _Elem *format, _In_opt_ locale_t locale, ...)
-
1339 {
-
1340 va_list arg;
-
1341 va_start(arg, locale);
-
1342 vsprintf(str, format, locale, arg);
-
1343 va_end(arg);
-
1344 }
-
1345
-
1355 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
-
1356 inline std::basic_string<_Elem, _Traits, _Ax> vsprintf(_In_z_ _Printf_format_string_params_(2) const _Elem *format, _In_opt_ locale_t locale, _In_ va_list arg)
-
1357 {
-
1358 std::basic_string<_Elem, _Traits, _Ax> str;
-
1359 vappendf(str, format, locale, arg);
-
1360 return str;
-
1361 }
-
1362
-
1371 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
-
1372 inline std::basic_string<_Elem, _Traits, _Ax> sprintf(_In_z_ _Printf_format_string_params_(2) const _Elem *format, _In_opt_ locale_t locale, ...)
-
1373 {
-
1374 va_list arg;
-
1375 va_start(arg, locale);
-
1376 auto str = vsprintf(format, locale, arg);
-
1377 va_end(arg);
-
1378 return str;
-
1379 }
-
1380
-
1382 inline size_t strftime(_Out_z_cap_(capacity) char *str, _In_ size_t capacity, _In_z_ _Printf_format_string_ const char *format, _In_ const struct tm* time, _In_opt_ locale_t locale)
-
1383 {
-
1384#ifdef _WIN32
-
1385 return _strftime_l(str, capacity, format, time, locale);
-
1386#else
-
1387 return strftime_l(str, capacity, format, time, locale);
-
1388#endif
-
1389 }
-
1390
-
1391 inline size_t strftime(_Out_z_cap_(capacity) wchar_t *str, _In_ size_t capacity, _In_z_ _Printf_format_string_ const wchar_t *format, _In_ const struct tm* time, _In_opt_ locale_t locale)
-
1392 {
-
1393#ifdef _WIN32
-
1394 return _wcsftime_l(str, capacity, format, time, locale);
-
1395#else
-
1396 return wcsftime_l(str, capacity, format, time, locale);
-
1397#endif
-
1398 }
-
1400
-
1409 template<class _Elem, class _Traits, class _Ax>
-
1410 inline void strcatftime(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, _In_ const struct tm* time, _In_opt_ locale_t locale)
-
1411 {
-
1412 _Elem buf[1024/sizeof(_Elem)];
-
1413
-
1414 // Try with stack buffer first.
-
1415 size_t count = strftime(buf, _countof(buf), format, time, locale);
-
1416 if (count) {
-
1417 // Copy from stack.
-
1418 str.append(buf, count);
-
1419 } else {
-
1420 for (size_t capacity = 2*1024/sizeof(_Elem);; capacity *= 2) {
-
1421 // Allocate on heap and retry.
-
1422 auto buf_dyn = std::make_unique<_Elem[]>(capacity);
-
1423 count = strftime(buf_dyn.get(), capacity, format, time, locale);
-
1424 if (count) {
-
1425 str.append(buf_dyn.get(), count);
-
1426 break;
-
1427 }
-
1428 }
-
1429 }
-
1430 }
-
1431
-
1440 template<class _Elem, class _Traits, class _Ax>
-
1441 inline void strftime(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, _In_ const struct tm* time, _In_opt_ locale_t locale)
-
1442 {
-
1443 str.clear();
-
1444 strcatftime(str, format, time, locale);
-
1445 }
-
1446
-
1457 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
-
1458 inline std::basic_string<_Elem, _Traits, _Ax> strftime(_In_z_ _Printf_format_string_ const _Elem *format, _In_ const struct tm* time, _In_opt_ locale_t locale)
-
1459 {
-
1460 std::basic_string<_Elem, _Traits, _Ax> str;
-
1461 strcatftime(str, format, time, locale);
-
1462 return str;
-
1463 }
-
1464
-
1471 inline void uuidtostr(_Out_writes_z_(39) char str[39], _In_ const uuid_t& id)
-
1472 {
-
1473 _Assume_(str);
-
1474 _snprintf_s_l(str, 39, _TRUNCATE, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", NULL,
-
1475#ifdef _WIN32
-
1476 id.Data1,
-
1477 static_cast<unsigned int>(id.Data2),
-
1478 static_cast<unsigned int>(id.Data3),
-
1479 static_cast<unsigned int>(id.Data4[0]), static_cast<unsigned int>(id.Data4[1]),
-
1480 static_cast<unsigned int>(id.Data4[2]), static_cast<unsigned int>(id.Data4[3]), static_cast<unsigned int>(id.Data4[4]), static_cast<unsigned int>(id.Data4[5]), static_cast<unsigned int>(id.Data4[6]), static_cast<unsigned int>(id.Data4[7]));
-
1481#else
-
1482 *reinterpret_cast<const uint32_t*>(&id[0]),
-
1483 static_cast<unsigned int>(*reinterpret_cast<const uint16_t*>(&id[4])),
-
1484 static_cast<unsigned int>(*reinterpret_cast<const uint16_t*>(&id[6])),
-
1485 static_cast<unsigned int>(id[8]), static_cast<unsigned int>(id[9]),
-
1486 static_cast<unsigned int>(id[10])), static_cast<unsigned int>(id[11]), static_cast<unsigned int>(id[12]), static_cast<unsigned int>(id)), static_cast<unsigned int>(id[14]), static_cast<unsigned int>(id[15]));
-
1487#endif
-
1488 }
-
1489
-
1496 inline void uuidtostr(_Out_writes_z_(39) wchar_t str[39], _In_ const uuid_t& id)
-
1497 {
-
1498 _Assume_(str);
-
1499 _snwprintf_s_l(str, 39, _TRUNCATE, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", NULL,
-
1500#ifdef _WIN32
-
1501 id.Data1,
-
1502 static_cast<unsigned int>(id.Data2),
-
1503 static_cast<unsigned int>(id.Data3),
-
1504 static_cast<unsigned int>(id.Data4[0]), static_cast<unsigned int>(id.Data4[1]),
-
1505 static_cast<unsigned int>(id.Data4[2]), static_cast<unsigned int>(id.Data4[3]), static_cast<unsigned int>(id.Data4[4]), static_cast<unsigned int>(id.Data4[5]), static_cast<unsigned int>(id.Data4[6]), static_cast<unsigned int>(id.Data4[7]));
-
1506#else
-
1507 *reinterpret_cast<const uint32_t*>(&id[0]),
-
1508 static_cast<unsigned int>(*reinterpret_cast<const uint16_t*>(&id[4])),
-
1509 static_cast<unsigned int>(*reinterpret_cast<const uint16_t*>(&id[6])),
-
1510 static_cast<unsigned int>(id[8]), static_cast<unsigned int>(id[9]),
-
1511 static_cast<unsigned int>(id[10])), static_cast<unsigned int>(id[11]), static_cast<unsigned int>(id[12]), static_cast<unsigned int>(id)), static_cast<unsigned int>(id[14]), static_cast<unsigned int>(id[15]));
-
1512#endif
-
1513 }
-
1514
-
1522 template<class T>
-
1523 inline void strlwr(_Inout_z_ T* str, _In_ const std::locale& locale)
-
1524 {
-
1525 _Assume_(str);
-
1526 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
-
1527 for (size_t i = 0; str[i]; ++i)
-
1528 str[i] = ctype.tolower(str[i]);
-
1529 }
-
1530
-
1539 template<class T>
-
1540 inline void strlwr(_Inout_updates_z_(count) T* str, _In_ size_t count, _In_ const std::locale& locale)
-
1541 {
-
1542 _Assume_(str || !count);
-
1543 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
-
1544 for (size_t i = 0; i < count && str[i]; ++i)
-
1545 str[i] = ctype.tolower(str[i]);
-
1546 }
-
1547
-
1555 template<class T>
-
1556 inline void strupr(_Inout_z_ T* str, _In_ const std::locale& locale)
-
1557 {
-
1558 _Assume_(str);
-
1559 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
-
1560 for (size_t i = 0; str[i]; ++i)
-
1561 str[i] = ctype.toupper(str[i]);
-
1562 }
-
1563
-
1572 template<class T>
-
1573 inline void strupr(_Inout_updates_z_(count) T* str, _In_ size_t count, _In_ const std::locale& locale)
-
1574 {
-
1575 _Assume_(str || !count);
-
1576 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
-
1577 for (size_t i = 0; i < count && str[i]; ++i)
-
1578 str[i] = ctype.toupper(str[i]);
-
1579 }
-
1580
-
1588 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
-
1589 inline void strupr(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_ const std::locale& locale)
-
1590 {
-
1591 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
-
1592 for (size_t i = 0; i < str.size(); ++i)
-
1593 str[i] = ctype.toupper(str[i]);
-
1594 }
-
1595
-
1604 template<class T>
-
1605 inline size_t ltrim(
-
1606 _Inout_z_count_(count) T* str, _In_ size_t count,
-
1607 _In_ const std::locale& locale)
-
1608 {
-
1609 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
-
1610 for (size_t i = 0;; ++i) {
-
1611 if (i >= count) {
-
1612 if (count) str[0] = 0;
-
1613 return 0;
-
1614 }
-
1615 if (!str[i]) {
-
1616 str[0] = 0;
-
1617 return 0;
-
1618 }
-
1619 if (!ctype.is(ctype.space, str[i])) {
-
1620 if (!i)
-
1621 return strnlen(str, count);
-
1622 size_t n = count != SIZE_MAX ? strncpy(str, str + i, count - i) : strcpy(str, str + i);
-
1623 str[n] = 0;
-
1624 return n;
-
1625 }
-
1626 }
-
1627 }
-
1628
-
1634 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
-
1635 inline void ltrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &s, _In_ const std::locale& locale)
-
1636 {
-
1637 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
-
1638 s.erase(
-
1639 s.begin(),
-
1640 std::find_if(
-
1641 s.begin(),
-
1642 s.end(),
-
1643 [&](_Elem ch) { return !ctype.is(ctype.space, ch); }));
-
1644 }
-
1645
-
1654 template<class T>
-
1655 inline size_t rtrim(
-
1656 _Inout_z_count_(count) T* str, _In_ size_t count,
-
1657 _In_ const std::locale& locale)
-
1658 {
-
1659 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
-
1660 for (size_t i = 0, j = 0;;) {
-
1661 if (i >= count || !str[i]) {
-
1662 if (j < count) str[j] = 0;
-
1663 return j;
-
1664 }
-
1665 if (!ctype.is(ctype.space, str[i]))
-
1666 j = ++i;
-
1667 else
-
1668 ++i;
-
1669 }
-
1670 }
-
1671
-
1677 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
-
1678 static inline void rtrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &s, _In_ const std::locale& locale)
-
1679 {
-
1680 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
-
1681 s.erase(
-
1682 std::find_if(
-
1683 s.rbegin(),
-
1684 s.rend(),
-
1685 [&](_Elem ch) { return !ctype.is(ctype.space, ch); }).base(),
-
1686 s.end());
-
1687 }
-
1688
-
1697 template<class T>
-
1698 inline size_t trim(
-
1699 _Inout_z_count_(count) T* str, _In_ size_t count,
-
1700 _In_ const std::locale& locale)
-
1701 {
-
1702 return ltrim(str, rtrim(str, count, locale), locale);
-
1703 }
-
1704
-
1710 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
-
1711 static inline void trim(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &s, _In_ const std::locale& locale)
-
1712 {
-
1713 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
-
1714 s.erase(
-
1715 s.begin(),
-
1716 std::find_if(
-
1717 s.begin(),
-
1718 s.end(),
-
1719 [&](_Elem ch) { return !ctype.is(ctype.space, ch); }));
-
1720 s.erase(
-
1721 std::find_if(
-
1722 s.rbegin(),
-
1723 s.rend(),
-
1724 [&](_Elem ch) { return !ctype.is(ctype.space, ch); }).base(),
-
1725 s.end());
-
1726 }
-
1727}
-
Deleter for unique_ptr using free_locale.
Definition string.hpp:62
-
void operator()(locale_t locale) const
Delete a pointer.
Definition string.hpp:66
+
72
+
76#if defined(_WIN32)
+
77 using locale = std::unique_ptr<__crt_locale_pointers, free_locale_delete>;
+
78#elif defined(__APPLE__)
+
79 using locale = std::unique_ptr<struct _xlocale, free_locale_delete>;
+
80#else
+
81 using locale = std::unique_ptr<struct __locale_struct, free_locale_delete>;
+
82#endif
+
83
+
87 const locale locale_C(create_locale(LC_ALL, "C"));
+
88
+
92#ifdef _WIN32
+
93 typedef wchar_t utf16_t;
+
94#else
+
95 typedef char16_t utf16_t;
+
96#endif
+
97
+
103 inline bool is_high_surrogate(_In_ utf16_t chr)
+
104 {
+
105 return 0xd800 < chr && chr < 0xdc00;
+
106 }
+
107
+
113 inline bool is_low_surrogate(_In_ utf16_t chr)
+
114 {
+
115 return 0xdc00 < chr && chr < 0xe000;
+
116 }
+
117
+
123 inline bool is_surrogate_pair(_In_reads_(2) const utf16_t* str)
+
124 {
+
125 return is_high_surrogate(str[0]) && is_low_surrogate(str[1]);
+
126 }
+
127
+
133 inline char32_t surrogate_pair_to_ucs4(_In_reads_(2) const utf16_t* str)
+
134 {
+
135 _Assume_(is_surrogate_pair(str));
+
136 return
+
137 ((char32_t)(str[0] - 0xd800) << 10) +
+
138 (char32_t)(str[1] - 0xdc00) +
+
139 0x10000;
+
140 }
+
141
+
147 inline void ucs4_to_surrogate_pair(_Out_writes_(2) utf16_t* str, _In_ char32_t chr)
+
148 {
+
149 _Assume_(chr >= 0x10000);
+
150 chr -= 0x10000;
+
151 str[0] = 0xd800 + (char32_t)((chr >> 10) & 0x3ff);
+
152 str[1] = 0xdc00 + (char32_t)(chr & 0x3ff);
+
153 }
+
154
+
160 inline bool iscombining(_In_ char32_t chr)
+
161 {
+
162 return
+
163 (0x0300 <= chr && chr < 0x0370) ||
+
164 (0x1dc0 <= chr && chr < 0x1e00) ||
+
165 (0x20d0 <= chr && chr < 0x2100) ||
+
166 (0xfe20 <= chr && chr < 0xfe30);
+
167 }
+
168
+
174 template <class T>
+
175 inline size_t islbreak(_In_ T chr)
+
176 {
+
177 return chr == '\n' || chr == '\r';
+
178 }
+
179
+
186 template <class T>
+
187 inline size_t islbreak(_In_reads_or_z_opt_(count) const T* chr, _In_ size_t count)
+
188 {
+
189 _Assume_(chr || !count);
+
190 if (count >= 2 && ((chr[0] == '\r' && chr[1] == '\n') || (chr[0] == '\n' && chr[1] == '\r')))
+
191 return 2;
+
192 if (count > 1 && (chr[0] == '\n' || chr[0] == '\r'))
+
193 return 1;
+
194 return 0;
+
195 }
+
196
+
203 inline size_t glyphlen(_In_reads_or_z_opt_(count) const wchar_t* glyph, _In_ size_t count)
+
204 {
+
205 _Assume_(glyph || !count);
+
206 if (count) {
+
207#ifdef _WIN32
+
208 size_t i = count < 2 || !is_surrogate_pair(glyph) ? 1 : 2;
+
209#else
+
210 size_t i = 1;
+
211#endif
+
212 for (; i < count && iscombining(glyph[i]); ++i);
+
213 return i;
+
214 }
+
215 return 0;
+
216 }
+
217
+
225 template <class T>
+
226 inline size_t strlen(_In_z_ const T* str)
+
227 {
+
228 _Assume_(str);
+
229 size_t i;
+
230 for (i = 0; str[i]; ++i);
+
231 return i;
+
232 }
+
233
+
242 template <class T>
+
243 inline size_t strnlen(_In_reads_or_z_opt_(count) const T* str, _In_ size_t count)
+
244 {
+
245 _Assume_(str || !count);
+
246 size_t i;
+
247 for (i = 0; i < count && str[i]; ++i);
+
248 return i;
+
249 }
+
250
+
251 constexpr auto npos{ static_cast<size_t>(-1) };
+
252
+
261 template <class T>
+
262 inline size_t strchr(_In_z_ const T* str, _In_ T chr)
+
263 {
+
264 _Assume_(str);
+
265 for (size_t i = 0; str[i]; ++i)
+
266 if (str[i] == chr) return i;
+
267 return npos;
+
268 }
+
269
+
279 template <class T>
+
280 inline size_t strnchr(
+
281 _In_reads_or_z_opt_(count) const T* str,
+
282 _In_ size_t count,
+
283 _In_ T chr)
+
284 {
+
285 _Assume_(str || !count);
+
286 for (size_t i = 0; i < count && str[i]; ++i)
+
287 if (str[i] == chr) return i;
+
288 return npos;
+
289 }
+
290
+
300 template <class T>
+
301 inline size_t strrnchr(
+
302 _In_reads_or_z_opt_(count) const T* str,
+
303 _In_ size_t count,
+
304 _In_ T chr)
+
305 {
+
306 _Assume_(str || !count);
+
307 size_t z = npos;
+
308 for (size_t i = 0; i < count && str[i]; ++i)
+
309 if (str[i] == chr) z = i;
+
310 return z;
+
311 }
+
312
+
322 template <class T>
+
323 inline size_t strnichr(
+
324 _In_reads_or_z_opt_(count) const T* str,
+
325 _In_ size_t count,
+
326 _In_ T chr,
+
327 _In_ const std::locale& locale)
+
328 {
+
329 _Assume_(str || !count);
+
330 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
+
331 chr = ctype.tolower(chr);
+
332 for (size_t i = 0; i < count && str[i]; ++i)
+
333 if (ctype.tolower(str[i]) == chr) return i;
+
334 return npos;
+
335 }
+
336
+
346 template <class T>
+
347 inline size_t strrnichr(
+
348 _In_reads_or_z_opt_(count) const T* str,
+
349 _In_ size_t count,
+
350 _In_ T chr,
+
351 _In_ const std::locale& locale)
+
352 {
+
353 _Assume_(str || !count);
+
354 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
+
355 chr = ctype.tolower(chr);
+
356 size_t z = npos;
+
357 for (size_t i = 0; i < count && str[i]; ++i)
+
358 if (ctype.tolower(str[i]) == chr) z = i;
+
359 return z;
+
360 }
+
361
+
370 template <class T1, class T2>
+
371 inline int strcmp(const T1* str1, const T2* str2)
+
372 {
+
373 _Assume_(str1 && str2);
+
374 T1 a; T2 b;
+
375 for (size_t i = 0; (a = str1[i]) | (b = str2[i]); ++i) {
+
376 if (a > b) return +1;
+
377 if (a < b) return -1;
+
378 }
+
379 return 0;
+
380 }
+
381
+
392 template <class T1, class T2>
+
393 inline int strncmp(
+
394 _In_reads_or_z_opt_(count1) const T1* str1, _In_ size_t count1,
+
395 _In_reads_or_z_opt_(count2) const T2* str2, _In_ size_t count2)
+
396 {
+
397 _Assume_(str1 || !count1);
+
398 _Assume_(str2 || !count2);
+
399 size_t i; T1 a; T2 b;
+
400 for (i = 0; i < count1 && i < count2 && ((a = str1[i]) | (b = str2[i])); ++i) {
+
401 if (a > b) return +1;
+
402 if (a < b) return -1;
+
403 }
+
404 if (i < count1 && str1[i]) return +1;
+
405 if (i < count2 && str2[i]) return -1;
+
406 return 0;
+
407 }
+
408
+
418 template <class T1, class T2>
+
419 inline int strncmp(_In_reads_or_z_opt_(count) const T1* str1, _In_reads_or_z_opt_(count) const T2* str2, _In_ size_t count)
+
420 {
+
421 _Assume_((str1 && str2) || !count);
+
422 size_t i; T1 a; T2 b;
+
423 for (i = 0; i < count && ((a = str1[i]) | (b = str2[i])); ++i) {
+
424 if (a > b) return +1;
+
425 if (a < b) return -1;
+
426 }
+
427 if (i < count && str1[i]) return +1;
+
428 if (i < count && str2[i]) return -1;
+
429 return 0;
+
430 }
+
431
+
442 template <class T>
+
443 inline int strncoll(
+
444 _In_reads_or_z_opt_(count1) const T* str1, _In_ size_t count1,
+
445 _In_reads_or_z_opt_(count2) const T* str2, _In_ size_t count2,
+
446 _In_ const std::locale& locale)
+
447 {
+
448 _Assume_(str1 || !count1);
+
449 _Assume_(str2 || !count2);
+
450 auto& collate = std::use_facet<std::collate<T>>(locale);
+
451 return collate.compare(str1, str1 + count1, str2, str2 + count2);
+
452 }
+
453
+
462 template <class T1, class T2>
+
463 inline int stricmp(_In_z_ const T1* str1, _In_z_ const T2* str2, _In_ const std::locale& locale)
+
464 {
+
465 _Assume_(str1);
+
466 _Assume_(str2);
+
467 size_t i; T1 a; T2 b;
+
468 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
+
469 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
+
470 for (i = 0; (a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i])); i++) {
+
471 if (a > b) return +1;
+
472 if (a < b) return -1;
+
473 }
+
474 if (str1[i]) return +1;
+
475 if (str2[i]) return -1;
+
476 return 0;
+
477 }
+
478
+
488 template <class T1, class T2>
+
489 inline int strnicmp(_In_reads_or_z_opt_(count) const T1* str1, _In_reads_or_z_opt_(count) const T2* str2, _In_ size_t count, _In_ const std::locale& locale)
+
490 {
+
491 _Assume_(str1 || !count);
+
492 _Assume_(str2 || !count);
+
493 size_t i; T1 a; T2 b;
+
494 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
+
495 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
+
496 for (i = 0; i < count && ((a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i]))); i++) {
+
497 if (a > b) return +1;
+
498 if (a < b) return -1;
+
499 }
+
500 if (i < count && str1[i]) return +1;
+
501 if (i < count && str2[i]) return -1;
+
502 return 0;
+
503 }
+
504
+
515 template <class T1, class T2>
+
516 inline int strnicmp(
+
517 _In_reads_or_z_opt_(count1) const T1* str1, _In_ size_t count1,
+
518 _In_reads_or_z_opt_(count2) const T2* str2, _In_ size_t count2,
+
519 _In_ const std::locale& locale)
+
520 {
+
521 _Assume_(str1 || !count1);
+
522 _Assume_(str2 || !count2);
+
523 size_t i; T1 a; T2 b;
+
524 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
+
525 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
+
526 for (i = 0; i < count1 && i < count2 && ((a = ctype1.tolower(str1[i])) | (b = ctype2.tolower(str2[i]))); i++) {
+
527 if (a > b) return +1;
+
528 if (a < b) return -1;
+
529 }
+
530 if (i < count1 && str1[i]) return +1;
+
531 if (i < count2 && str2[i]) return -1;
+
532 return 0;
+
533 }
+
534
+
543 template <class T1, class T2>
+
544 inline size_t strstr(
+
545 _In_z_ const T1* str,
+
546 _In_z_ const T2* sample)
+
547 {
+
548 _Assume_(str);
+
549 _Assume_(sample);
+
550 for (size_t offset = 0;; ++offset) {
+
551 for (size_t i = offset, j = 0;; ++i, ++j) {
+
552 if (!sample[j])
+
553 return offset;
+
554 if (!str[i])
+
555 return npos;
+
556 if (str[i] != sample[j])
+
557 break;
+
558 }
+
559 }
+
560 }
+
561
+
571 template <class T1, class T2>
+
572 inline size_t strnstr(
+
573 _In_reads_or_z_opt_(count) const T1* str,
+
574 _In_ size_t count,
+
575 _In_z_ const T2* sample)
+
576 {
+
577 _Assume_(str || !count);
+
578 _Assume_(sample);
+
579 for (size_t offset = 0;; ++offset) {
+
580 for (size_t i = offset, j = 0;; ++i, ++j) {
+
581 if (!sample[j])
+
582 return offset;
+
583 if (i >= count || !str[i])
+
584 return npos;
+
585 if (str[i] != sample[j])
+
586 break;
+
587 }
+
588 }
+
589 }
+
590
+
599 template <class T1, class T2>
+
600 inline size_t stristr(
+
601 _In_z_ const T1* str,
+
602 _In_z_ const T2* sample,
+
603 _In_ const std::locale& locale)
+
604 {
+
605 _Assume_(str);
+
606 _Assume_(sample);
+
607 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
+
608 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
+
609 for (size_t offset = 0;; ++offset) {
+
610 for (size_t i = offset, j = 0;; ++i, ++j) {
+
611 if (!sample[j])
+
612 return offset;
+
613 if (!str[i])
+
614 return npos;
+
615 if (ctype1.tolower(str[i]) != ctype2.tolower(sample[j]))
+
616 break;
+
617 }
+
618 }
+
619 }
+
620
+
630 template <class T1, class T2>
+
631 inline size_t strnistr(
+
632 _In_reads_or_z_opt_(count) const T1* str,
+
633 _In_ size_t count,
+
634 _In_z_ const T2* sample,
+
635 _In_ const std::locale& locale)
+
636 {
+
637 _Assume_(str || !count);
+
638 _Assume_(sample);
+
639 const auto& ctype1 = std::use_facet<std::ctype<T1>>(locale);
+
640 const auto& ctype2 = std::use_facet<std::ctype<T2>>(locale);
+
641 for (size_t offset = 0;; ++offset) {
+
642 for (size_t i = offset, j = 0;; ++i, ++j) {
+
643 if (!sample[j])
+
644 return offset;
+
645 if (i >= count || !str[i])
+
646 return npos;
+
647 if (ctype1.tolower(str[i]) != ctype2.tolower(sample[j]))
+
648 break;
+
649 }
+
650 }
+
651 }
+
652
+
661 template <class T1, class T2>
+
662 inline size_t strcpy(
+
663 _Out_writes_z_(_String_length_(src) + 1) T1* dst,
+
664 _In_z_ const T2* src)
+
665 {
+
666 _Assume_(dst && src);
+
667 for (size_t i = 0; ; ++i) {
+
668 if ((dst[i] = src[i]) == 0)
+
669 return i;
+
670 }
+
671 }
+
672
+
682 template <class T1, class T2>
+
683 inline size_t strncpy(
+
684 _Out_writes_(count) _Post_maybez_ T1* dst,
+
685 _In_reads_or_z_opt_(count) const T2* src, _In_ size_t count)
+
686 {
+
687 _Assume_(dst && src || !count);
+
688 for (size_t i = 0; ; ++i) {
+
689 if (i >= count)
+
690 return i;
+
691 if ((dst[i] = src[i]) == 0)
+
692 return i;
+
693 }
+
694 }
+
695
+
706 template <class T1, class T2>
+
707 inline size_t strncpy(
+
708 _Out_writes_(count_dst) _Post_maybez_ T1* dst, _In_ size_t count_dst,
+
709 _In_reads_or_z_opt_(count_src) const T2* src, _In_ size_t count_src)
+
710 {
+
711 _Assume_(dst || !count_dst);
+
712 _Assume_(src || !count_src);
+
713 for (size_t i = 0; ; ++i)
+
714 {
+
715 if (i >= count_dst)
+
716 return i;
+
717 if (i >= count_src) {
+
718 dst[i] = 0;
+
719 return i;
+
720 }
+
721 if ((dst[i] = src[i]) == 0)
+
722 return i;
+
723 }
+
724 }
+
725
+
734 template <class T1, class T2>
+
735 inline size_t strcat(
+
736 _In_z_ _Out_writes_z_(_String_length_(dst) + _String_length_(src) + 1) T1* dst,
+
737 _In_z_ const T2* src)
+
738 {
+
739 _Assume_(dst && src);
+
740 for (size_t i = 0, j = stdex::strlen<T1>(dst); ; ++i, ++j) {
+
741 if ((dst[j] = src[i]) == 0)
+
742 return j;
+
743 }
+
744 }
+
745
+
755 template <class T1, class T2>
+
756 inline size_t strncat(
+
757 _Out_writes_(count) _Post_maybez_ T1* dst,
+
758 _In_reads_or_z_opt_(count) const T2* src, _In_ size_t count)
+
759 {
+
760 _Assume_(dst && src || !count);
+
761 for (size_t i = 0, j = stdex::strlen<T1>(dst); ; ++i, ++j) {
+
762 if (i >= count)
+
763 return j;
+
764 if ((dst[j] = src[i]) == 0)
+
765 return j;
+
766 }
+
767 }
+
768
+
779 template <class T1, class T2>
+
780 inline size_t strncat(
+
781 _Out_writes_(count_dst) _Post_maybez_ T1* dst, _In_ size_t count_dst,
+
782 _In_reads_or_z_opt_(count_src) const T2* src, _In_ size_t count_src)
+
783 {
+
784 _Assume_(dst || !count_dst);
+
785 _Assume_(src || !count_src);
+
786 for (size_t i = 0, j = stdex::strnlen<T1>(dst, count_dst); ; ++i, ++j)
+
787 {
+
788 if (j >= count_dst)
+
789 return j;
+
790 if (i >= count_src) {
+
791 dst[j] = 0;
+
792 return j;
+
793 }
+
794 if ((dst[j] = src[i]) == 0)
+
795 return j;
+
796 }
+
797 }
+
798
+
809 template <class T>
+
810 inline _Check_return_ _Ret_maybenull_z_ T* strdup(_In_opt_z_ const T* str)
+
811 {
+
812 if (!str) _Unlikely_
+
813 return nullptr;
+
814 size_t count = strlen(str) + 1;
+
815 T* dst = new T[count];
+
816 strncpy(dst, count, str, SIZE_MAX);
+
817 return dst;
+
818 }
+
819
+
831 template <class T>
+
832 inline _Ret_z_ T* strndup(
+
833 _In_reads_or_z_opt_(count) const T* str,
+
834 _In_ size_t count)
+
835 {
+
836 T* dst = new T[count];
+
837 strncpy(dst, count, str, SIZE_MAX);
+
838 return dst;
+
839 }
+
840
+
850 template <class T>
+
851 inline size_t crlf2nl(_Out_writes_z_(strlen(src)) T* dst, _In_z_ const T* src)
+
852 {
+
853 _Assume_(dst);
+
854 _Assume_(src);
+
855 size_t i, j;
+
856 for (i = j = 0; src[j];) {
+
857 if (src[j] != '\r' || src[j + 1] != '\n')
+
858 dst[i++] = src[j++];
+
859 else {
+
860 dst[i++] = '\n';
+
861 j += 2;
+
862 }
+
863 }
+
864 dst[i] = 0;
+
865 return i;
+
866 }
+
867
+
874 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
+
875 inline void crlf2nl(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &dst, _In_z_ const _Elem* src)
+
876 {
+
877 _Assume_(src);
+
878 _Assume_(src != dst.c_str());
+
879 dst.clear();
+
880 dst.reserve(strlen(src));
+
881 for (size_t j = 0; src[j];) {
+
882 if (src[j] != '\r' || src[j + 1] != '\n')
+
883 dst += src[j++];
+
884 else {
+
885 dst += '\n';
+
886 j += 2;
+
887 }
+
888 }
+
889 }
+
890
+
896 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
+
897 inline void crlf2nl(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str)
+
898 {
+
899 size_t i, j, n;
+
900 for (i = j = 0, n = str.size(); j < n;) {
+
901 if (str[j] != '\r' || str[j + 1] != '\n')
+
902 str[i++] = str[j++];
+
903 else {
+
904 str[i++] = '\n';
+
905 j += 2;
+
906 }
+
907 }
+
908 str.resize(i);
+
909 }
+
910
+
912 template <class T, class T_bin>
+
913 inline T_bin strtoint(
+
914 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
+
915 _Out_opt_ size_t* end,
+
916 _In_ int radix,
+
917 _Out_ uint8_t& flags)
+
918 {
+
919 _Assume_(str || !count);
+
920 _Assume_(radix == 0 || 2 <= radix && radix <= 36);
+
921
+
922 size_t i = 0;
+
923 T_bin value = 0, digit,
+
924 max_ui = (T_bin)-1,
+
925 max_ui_pre1, max_ui_pre2;
+
926
+
927 flags = 0;
+
928
+
929 // Skip leading spaces.
+
930 for (;; ++i) {
+
931 if (i >= count || !str[i]) goto error;
+
932 if (!isspace(str[i])) break;
+
933 }
+
934
+
935 // Read the sign.
+
936 if (str[i] == '+') {
+
937 flags &= ~0x01;
+
938 ++i;
+
939 if (i >= count || !str[i]) goto error;
+
940 }
+
941 else if (str[i] == '-') {
+
942 flags |= 0x01;
+
943 ++i;
+
944 if (i >= count || !str[i]) goto error;
+
945 }
+
946
+
947 if (radix == 16) {
+
948 // On hexadecimal, allow leading 0x.
+
949 if (str[i] == '0' && i + 1 < count && (str[i + 1] == 'x' || str[i + 1] == 'X')) {
+
950 i += 2;
+
951 if (i >= count || !str[i]) goto error;
+
952 }
+
953 }
+
954 else if (!radix) {
+
955 // Autodetect radix.
+
956 if (str[i] == '0') {
+
957 ++i;
+
958 if (i >= count || !str[i]) goto error;
+
959 if (str[i] == 'x' || str[i] == 'X') {
+
960 radix = 16;
+
961 ++i;
+
962 if (i >= count || !str[i]) goto error;
+
963 }
+
964 else
+
965 radix = 8;
+
966 }
+
967 else
+
968 radix = 10;
+
969 }
+
970
+
971 // We have the radix.
+
972 max_ui_pre1 = max_ui / (T_bin)radix;
+
973 max_ui_pre2 = max_ui % (T_bin)radix;
+
974 for (;;) {
+
975 if ('0' <= str[i] && str[i] <= '9')
+
976 digit = (T_bin)str[i] - '0';
+
977 else if ('A' <= str[i] && str[i] <= 'Z')
+
978 digit = (T_bin)str[i] - 'A' + '\x0a';
+
979 else if ('a' <= str[i] && str[i] <= 'z')
+
980 digit = (T_bin)str[i] - 'a' + '\x0a';
+
981 else
+
982 goto error;
+
983 if (digit >= (T_bin)radix)
+
984 goto error;
+
985
+
986 if (value < max_ui_pre1 || // Multiplication nor addition will not overflow.
+
987 (value == max_ui_pre1 && digit <= max_ui_pre2)) // Small digits will not overflow.
+
988 value = value * (T_bin)radix + digit;
+
989 else {
+
990 // Overflow!
+
991 flags |= 0x02;
+
992 }
+
993
+
994 ++i;
+
995 if (i >= count || !str[i])
+
996 goto error;
+
997 }
+
998
+
999 error:
+
1000 if (end) *end = i;
+
1001 return value;
+
1002 }
+
1004
+
1015 template <class T, class T_bin>
+
1016 T_bin strtoint(
+
1017 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
+
1018 _Out_opt_ size_t* end,
+
1019 _In_ int radix)
+
1020 {
+
1021 uint8_t flags;
+
1022 T_bin value;
+
1023
+
1024 switch (sizeof(T_bin)) {
+
1025 case 1:
+
1026 value = (T_bin)strtoint<T, uint8_t>(str, count, end, radix, flags);
+
1027 if ((flags & 0x01) && (value & 0x80)) {
+
1028 // Sign bit is 1 => overflow.
+
1029 flags |= 0x02;
+
1030 }
+
1031 return (flags & 0x02) ?
+
1032 (flags & 0x01) ? (T_bin)0x80 : (T_bin)0x7f :
+
1033 (flags & 0x01) ? -value : value;
+
1034
+
1035 case 2:
+
1036 value = (T_bin)strtoint<T, uint16_t>(str, count, end, radix, flags);
+
1037 if ((flags & 0x01) && (value & 0x8000)) {
+
1038 // Sign bit is 1 => overflow.
+
1039 flags |= 0x02;
+
1040 }
+
1041 return (flags & 0x02) ?
+
1042 (flags & 0x01) ? (T_bin)0x8000 : (T_bin)0x7fff :
+
1043 (flags & 0x01) ? -value : value;
+
1044
+
1045 case 4:
+
1046 value = (T_bin)strtoint<T, uint32_t>(str, count, end, radix, flags);
+
1047 if ((flags & 0x01) && (value & 0x80000000)) {
+
1048 // Sign bit is 1 => overflow.
+
1049 flags |= 0x02;
+
1050 }
+
1051 return (flags & 0x02) ?
+
1052 (flags & 0x01) ? (T_bin)0x80000000 : (T_bin)0x7fffffff :
+
1053 (flags & 0x01) ? -value : value;
+
1054
+
1055 case 8:
+
1056 value = (T_bin)strtoint<T, uint64_t>(str, count, end, radix, flags);
+
1057 if ((flags & 0x01) && (value & 0x8000000000000000)) {
+
1058 // Sign bit is 1 => overflow.
+
1059 flags |= 0x02;
+
1060 }
+
1061 return (flags & 0x02) ?
+
1062 (flags & 0x01) ? (T_bin)0x8000000000000000 : (T_bin)0x7fffffffffffffff :
+
1063 (flags & 0x01) ? -value : value;
+
1064
+
1065 default:
+
1066 throw std::invalid_argument("Unsupported bit length");
+
1067 }
+
1068 }
+
1069
+
1080 template <class T, class T_bin>
+
1081 inline T_bin strtouint(
+
1082 _In_reads_or_z_opt_(count) const T* str,
+
1083 _In_ size_t count,
+
1084 _Out_opt_ size_t* end,
+
1085 _In_ int radix)
+
1086 {
+
1087 uint8_t flags;
+
1088 T_bin value;
+
1089
+
1090 switch (sizeof(T_bin)) {
+
1091 case 1: value = (T_bin)strtoint<T, uint8_t>(str, count, end, radix, flags); break;
+
1092 case 2: value = (T_bin)strtoint<T, uint16_t>(str, count, end, radix, flags); break;
+
1093 case 4: value = (T_bin)strtoint<T, uint32_t>(str, count, end, radix, flags); break;
+
1094 case 8: value = (T_bin)strtoint<T, uint64_t>(str, count, end, radix, flags); break;
+
1095 default: throw std::invalid_argument("Unsupported bit length");
+
1096 }
+
1097
+
1098 return (flags & 0x02) ?
+
1099 (flags & 0x01) ? (T_bin)0 : (T_bin)-1 :
+
1100 (flags & 0x01) ? ~value : value;
+
1101 }
+
1102
+
1113 template <class T>
+
1114 inline int32_t strto32(
+
1115 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
+
1116 _Out_opt_ size_t* end,
+
1117 _In_ int radix)
+
1118 {
+
1119 return strtoint<T, int32_t>(str, count, end, radix);
+
1120 }
+
1121
+
1132 template <class T>
+
1133 inline int64_t strto64(
+
1134 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
+
1135 _Out_opt_ size_t* end,
+
1136 _In_ int radix)
+
1137 {
+
1138 return strtoint<T, int64_t>(str, count, end, radix);
+
1139 }
+
1140
+
1152 template <class T>
+
1153 inline intptr_t strtoi(
+
1154 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
+
1155 _Out_opt_ size_t* end,
+
1156 _In_ int radix)
+
1157 {
+
1158#if defined(_WIN64) || defined(__LP64__)
+
1159 return (intptr_t)strto64(str, count, end, radix);
+
1160#else
+
1161 return (intptr_t)strto32(str, count, end, radix);
+
1162#endif
+
1163 }
+
1164
+
1175 template <class T>
+
1176 inline uint32_t strtou32(
+
1177 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
+
1178 _Out_opt_ size_t* end,
+
1179 _In_ int radix)
+
1180 {
+
1181 return strtouint<T, uint32_t>(str, count, end, radix);
+
1182 }
+
1183
+
1194 template <class T>
+
1195 inline uint64_t strtou64(
+
1196 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
+
1197 _Out_opt_ size_t* end,
+
1198 _In_ int radix)
+
1199 {
+
1200 return strtouint<T, uint64_t>(str, count, end, radix);
+
1201 }
+
1202
+
1214 template <class T>
+
1215 inline size_t strtoui(
+
1216 _In_reads_or_z_opt_(count) const T* str, _In_ size_t count,
+
1217 _Out_opt_ size_t* end,
+
1218 _In_ int radix)
+
1219 {
+
1220#if defined(_WIN64) || defined(__LP64__)
+
1221 return (size_t)strtou64(str, count, end, radix);
+
1222#else
+
1223 return (size_t)strtou32(str, count, end, radix);
+
1224#endif
+
1225 }
+
1226
+
1228 inline int vsnprintf(_Out_z_cap_(capacity) char *str, _In_ size_t capacity, _In_z_ _Printf_format_string_params_(2) const char *format, _In_opt_ locale_t locale, _In_ va_list arg)
+
1229 {
+
1230 int r;
+
1231#ifdef _WIN32
+
1232 // Don't use _vsnprintf_s(). It terminates the string even if we want to print to the edge of the buffer.
+
1233#pragma warning(suppress: 4996)
+
1234 r = _vsnprintf_l(str, capacity, format, locale, arg);
+
1235#else
+
1236 r = ::vsnprintf(str, capacity, format, arg);
+
1237#endif
+
1238 if (r == -1 && strnlen(str, capacity) == capacity) {
+
1239 // Buffer overrun. Estimate buffer size for the next iteration.
+
1240 capacity += std::max<size_t>(capacity / 8, 0x80);
+
1241 if (capacity > INT_MAX)
+
1242 throw std::invalid_argument("string too big");
+
1243 return (int)capacity;
+
1244 }
+
1245 return r;
+
1246 }
+
1247
+
1248 inline int vsnprintf(_Out_z_cap_(capacity) wchar_t *str, _In_ size_t capacity, _In_z_ _Printf_format_string_params_(2) const wchar_t *format, _In_opt_ locale_t locale, _In_ va_list arg)
+
1249 {
+
1250 int r;
+
1251#ifdef _WIN32
+
1252 // Don't use _vsnwprintf_s(). It terminates the string even if we want to print to the edge of the buffer.
+
1253#pragma warning(suppress: 4996)
+
1254 r = _vsnwprintf_l(str, capacity, format, locale, arg);
+
1255#else
+
1256 r = vswprintf(str, capacity, format, arg);
+
1257#endif
+
1258 if (r == -1 && strnlen(str, capacity) == capacity) {
+
1259 // Buffer overrun. Estimate buffer size for the next iteration.
+
1260 capacity += std::max<size_t>(capacity / 8, 0x80);
+
1261 if (capacity > INT_MAX)
+
1262 throw std::invalid_argument("string too big");
+
1263 return (int)capacity;
+
1264 }
+
1265 return r;
+
1266 }
+
1268
+
1277 template<class _Elem, class _Traits, class _Ax>
+
1278 inline void vappendf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_params_(2) const _Elem *format, _In_opt_ locale_t locale, _In_ va_list arg)
+
1279 {
+
1280 _Elem buf[1024/sizeof(_Elem)];
+
1281
+
1282 // Try with stack buffer first.
+
1283 int count = vsnprintf(buf, _countof(buf) - 1, format, locale, arg);
+
1284 if (count >= 0) {
+
1285 // Copy from stack.
+
1286 str.append(buf, count);
+
1287 } else {
+
1288 for (size_t capacity = 2*1024/sizeof(_Elem);; capacity *= 2) {
+
1289 // Allocate on heap and retry.
+
1290 auto buf_dyn = std::make_unique<_Elem[]>(capacity);
+
1291 count = vsnprintf(buf_dyn.get(), capacity - 1, format, locale, arg);
+
1292 if (count >= 0) {
+
1293 str.append(buf_dyn.get(), count);
+
1294 break;
+
1295 }
+
1296 }
+
1297 }
+
1298 }
+
1299
+
1307 template<class _Elem, class _Traits, class _Ax>
+
1308 inline void appendf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_params_(2) const _Elem *format, _In_opt_ locale_t locale, ...)
+
1309 {
+
1310 va_list arg;
+
1311 va_start(arg, locale);
+
1312 vappendf(str, format, locale, arg);
+
1313 va_end(arg);
+
1314 }
+
1315
+
1324 template<class _Elem, class _Traits, class _Ax>
+
1325 inline void vsprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_params_(2) const _Elem *format, _In_opt_ locale_t locale, _In_ va_list arg)
+
1326 {
+
1327 str.clear();
+
1328 vappendf(str, format, locale, arg);
+
1329 }
+
1330
+
1338 template<class _Elem, class _Traits, class _Ax>
+
1339 inline void sprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_params_(2) const _Elem *format, _In_opt_ locale_t locale, ...)
+
1340 {
+
1341 va_list arg;
+
1342 va_start(arg, locale);
+
1343 vsprintf(str, format, locale, arg);
+
1344 va_end(arg);
+
1345 }
+
1346
+
1356 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
+
1357 inline std::basic_string<_Elem, _Traits, _Ax> vsprintf(_In_z_ _Printf_format_string_params_(2) const _Elem *format, _In_opt_ locale_t locale, _In_ va_list arg)
+
1358 {
+
1359 std::basic_string<_Elem, _Traits, _Ax> str;
+
1360 vappendf(str, format, locale, arg);
+
1361 return str;
+
1362 }
+
1363
+
1372 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
+
1373 inline std::basic_string<_Elem, _Traits, _Ax> sprintf(_In_z_ _Printf_format_string_params_(2) const _Elem *format, _In_opt_ locale_t locale, ...)
+
1374 {
+
1375 va_list arg;
+
1376 va_start(arg, locale);
+
1377 auto str = vsprintf(format, locale, arg);
+
1378 va_end(arg);
+
1379 return str;
+
1380 }
+
1381
+
1383 inline size_t strftime(_Out_z_cap_(capacity) char *str, _In_ size_t capacity, _In_z_ _Printf_format_string_ const char *format, _In_ const struct tm* time, _In_opt_ locale_t locale)
+
1384 {
+
1385#ifdef _WIN32
+
1386 return _strftime_l(str, capacity, format, time, locale);
+
1387#else
+
1388 return strftime_l(str, capacity, format, time, locale);
+
1389#endif
+
1390 }
+
1391
+
1392 inline size_t strftime(_Out_z_cap_(capacity) wchar_t *str, _In_ size_t capacity, _In_z_ _Printf_format_string_ const wchar_t *format, _In_ const struct tm* time, _In_opt_ locale_t locale)
+
1393 {
+
1394#ifdef _WIN32
+
1395 return _wcsftime_l(str, capacity, format, time, locale);
+
1396#else
+
1397 return wcsftime_l(str, capacity, format, time, locale);
+
1398#endif
+
1399 }
+
1401
+
1410 template<class _Elem, class _Traits, class _Ax>
+
1411 inline void strcatftime(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, _In_ const struct tm* time, _In_opt_ locale_t locale)
+
1412 {
+
1413 _Elem buf[1024/sizeof(_Elem)];
+
1414
+
1415 // Try with stack buffer first.
+
1416 size_t count = strftime(buf, _countof(buf), format, time, locale);
+
1417 if (count) {
+
1418 // Copy from stack.
+
1419 str.append(buf, count);
+
1420 } else {
+
1421 for (size_t capacity = 2*1024/sizeof(_Elem);; capacity *= 2) {
+
1422 // Allocate on heap and retry.
+
1423 auto buf_dyn = std::make_unique<_Elem[]>(capacity);
+
1424 count = strftime(buf_dyn.get(), capacity, format, time, locale);
+
1425 if (count) {
+
1426 str.append(buf_dyn.get(), count);
+
1427 break;
+
1428 }
+
1429 }
+
1430 }
+
1431 }
+
1432
+
1441 template<class _Elem, class _Traits, class _Ax>
+
1442 inline void strftime(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &str, _In_z_ _Printf_format_string_ const _Elem *format, _In_ const struct tm* time, _In_opt_ locale_t locale)
+
1443 {
+
1444 str.clear();
+
1445 strcatftime(str, format, time, locale);
+
1446 }
+
1447
+
1458 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
+
1459 inline std::basic_string<_Elem, _Traits, _Ax> strftime(_In_z_ _Printf_format_string_ const _Elem *format, _In_ const struct tm* time, _In_opt_ locale_t locale)
+
1460 {
+
1461 std::basic_string<_Elem, _Traits, _Ax> str;
+
1462 strcatftime(str, format, time, locale);
+
1463 return str;
+
1464 }
+
1465
+
1472 inline void uuidtostr(_Out_writes_z_(39) char str[39], _In_ const uuid_t& id)
+
1473 {
+
1474 _Assume_(str);
+
1475 _snprintf_s_l(str, 39, _TRUNCATE, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", NULL,
+
1476#ifdef _WIN32
+
1477 id.Data1,
+
1478 static_cast<unsigned int>(id.Data2),
+
1479 static_cast<unsigned int>(id.Data3),
+
1480 static_cast<unsigned int>(id.Data4[0]), static_cast<unsigned int>(id.Data4[1]),
+
1481 static_cast<unsigned int>(id.Data4[2]), static_cast<unsigned int>(id.Data4[3]), static_cast<unsigned int>(id.Data4[4]), static_cast<unsigned int>(id.Data4[5]), static_cast<unsigned int>(id.Data4[6]), static_cast<unsigned int>(id.Data4[7]));
+
1482#else
+
1483 *reinterpret_cast<const uint32_t*>(&id[0]),
+
1484 static_cast<unsigned int>(*reinterpret_cast<const uint16_t*>(&id[4])),
+
1485 static_cast<unsigned int>(*reinterpret_cast<const uint16_t*>(&id[6])),
+
1486 static_cast<unsigned int>(id[8]), static_cast<unsigned int>(id[9]),
+
1487 static_cast<unsigned int>(id[10])), static_cast<unsigned int>(id[11]), static_cast<unsigned int>(id[12]), static_cast<unsigned int>(id)), static_cast<unsigned int>(id[14]), static_cast<unsigned int>(id[15]));
+
1488#endif
+
1489 }
+
1490
+
1497 inline void uuidtostr(_Out_writes_z_(39) wchar_t str[39], _In_ const uuid_t& id)
+
1498 {
+
1499 _Assume_(str);
+
1500 _snwprintf_s_l(str, 39, _TRUNCATE, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", NULL,
+
1501#ifdef _WIN32
+
1502 id.Data1,
+
1503 static_cast<unsigned int>(id.Data2),
+
1504 static_cast<unsigned int>(id.Data3),
+
1505 static_cast<unsigned int>(id.Data4[0]), static_cast<unsigned int>(id.Data4[1]),
+
1506 static_cast<unsigned int>(id.Data4[2]), static_cast<unsigned int>(id.Data4[3]), static_cast<unsigned int>(id.Data4[4]), static_cast<unsigned int>(id.Data4[5]), static_cast<unsigned int>(id.Data4[6]), static_cast<unsigned int>(id.Data4[7]));
+
1507#else
+
1508 *reinterpret_cast<const uint32_t*>(&id[0]),
+
1509 static_cast<unsigned int>(*reinterpret_cast<const uint16_t*>(&id[4])),
+
1510 static_cast<unsigned int>(*reinterpret_cast<const uint16_t*>(&id[6])),
+
1511 static_cast<unsigned int>(id[8]), static_cast<unsigned int>(id[9]),
+
1512 static_cast<unsigned int>(id[10])), static_cast<unsigned int>(id[11]), static_cast<unsigned int>(id[12]), static_cast<unsigned int>(id)), static_cast<unsigned int>(id[14]), static_cast<unsigned int>(id[15]));
+
1513#endif
+
1514 }
+
1515
+
1523 template<class T>
+
1524 inline void strlwr(_Inout_z_ T* str, _In_ const std::locale& locale)
+
1525 {
+
1526 _Assume_(str);
+
1527 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
+
1528 for (size_t i = 0; str[i]; ++i)
+
1529 str[i] = ctype.tolower(str[i]);
+
1530 }
+
1531
+
1540 template<class T>
+
1541 inline void strlwr(_Inout_updates_z_(count) T* str, _In_ size_t count, _In_ const std::locale& locale)
+
1542 {
+
1543 _Assume_(str || !count);
+
1544 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
+
1545 for (size_t i = 0; i < count && str[i]; ++i)
+
1546 str[i] = ctype.tolower(str[i]);
+
1547 }
+
1548
+
1556 template<class T>
+
1557 inline void strupr(_Inout_z_ T* str, _In_ const std::locale& locale)
+
1558 {
+
1559 _Assume_(str);
+
1560 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
+
1561 for (size_t i = 0; str[i]; ++i)
+
1562 str[i] = ctype.toupper(str[i]);
+
1563 }
+
1564
+
1573 template<class T>
+
1574 inline void strupr(_Inout_updates_z_(count) T* str, _In_ size_t count, _In_ const std::locale& locale)
+
1575 {
+
1576 _Assume_(str || !count);
+
1577 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
+
1578 for (size_t i = 0; i < count && str[i]; ++i)
+
1579 str[i] = ctype.toupper(str[i]);
+
1580 }
+
1581
+
1589 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
+
1590 inline void strupr(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_ const std::locale& locale)
+
1591 {
+
1592 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
+
1593 for (size_t i = 0; i < str.size(); ++i)
+
1594 str[i] = ctype.toupper(str[i]);
+
1595 }
+
1596
+
1605 template<class T>
+
1606 inline size_t ltrim(
+
1607 _Inout_z_count_(count) T* str, _In_ size_t count,
+
1608 _In_ const std::locale& locale)
+
1609 {
+
1610 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
+
1611 for (size_t i = 0;; ++i) {
+
1612 if (i >= count) {
+
1613 if (count) str[0] = 0;
+
1614 return 0;
+
1615 }
+
1616 if (!str[i]) {
+
1617 str[0] = 0;
+
1618 return 0;
+
1619 }
+
1620 if (!ctype.is(ctype.space, str[i])) {
+
1621 if (!i)
+
1622 return strnlen(str, count);
+
1623 size_t n = count != SIZE_MAX ? strncpy(str, str + i, count - i) : strcpy(str, str + i);
+
1624 str[n] = 0;
+
1625 return n;
+
1626 }
+
1627 }
+
1628 }
+
1629
+
1635 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
+
1636 inline void ltrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &s, _In_ const std::locale& locale)
+
1637 {
+
1638 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
+
1639 s.erase(
+
1640 s.begin(),
+
1641 std::find_if(
+
1642 s.begin(),
+
1643 s.end(),
+
1644 [&](_Elem ch) { return !ctype.is(ctype.space, ch); }));
+
1645 }
+
1646
+
1655 template<class T>
+
1656 inline size_t rtrim(
+
1657 _Inout_z_count_(count) T* str, _In_ size_t count,
+
1658 _In_ const std::locale& locale)
+
1659 {
+
1660 const auto& ctype = std::use_facet<std::ctype<T>>(locale);
+
1661 for (size_t i = 0, j = 0;;) {
+
1662 if (i >= count || !str[i]) {
+
1663 if (j < count) str[j] = 0;
+
1664 return j;
+
1665 }
+
1666 if (!ctype.is(ctype.space, str[i]))
+
1667 j = ++i;
+
1668 else
+
1669 ++i;
+
1670 }
+
1671 }
+
1672
+
1678 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
+
1679 static inline void rtrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &s, _In_ const std::locale& locale)
+
1680 {
+
1681 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
+
1682 s.erase(
+
1683 std::find_if(
+
1684 s.rbegin(),
+
1685 s.rend(),
+
1686 [&](_Elem ch) { return !ctype.is(ctype.space, ch); }).base(),
+
1687 s.end());
+
1688 }
+
1689
+
1698 template<class T>
+
1699 inline size_t trim(
+
1700 _Inout_z_count_(count) T* str, _In_ size_t count,
+
1701 _In_ const std::locale& locale)
+
1702 {
+
1703 return ltrim(str, rtrim(str, count, locale), locale);
+
1704 }
+
1705
+
1711 template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
+
1712 static inline void trim(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &s, _In_ const std::locale& locale)
+
1713 {
+
1714 const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
+
1715 s.erase(
+
1716 s.begin(),
+
1717 std::find_if(
+
1718 s.begin(),
+
1719 s.end(),
+
1720 [&](_Elem ch) { return !ctype.is(ctype.space, ch); }));
+
1721 s.erase(
+
1722 std::find_if(
+
1723 s.rbegin(),
+
1724 s.rend(),
+
1725 [&](_Elem ch) { return !ctype.is(ctype.space, ch); }).base(),
+
1726 s.end());
+
1727 }
+
1728}
+
Deleter for unique_ptr using free_locale.
Definition string.hpp:63
+
void operator()(locale_t locale) const
Delete a pointer.
Definition string.hpp:67
diff --git a/structstdex_1_1chrono_1_1aosn__date-members.html b/structstdex_1_1chrono_1_1aosn__date-members.html index 50ea9abd3..a5a2593b7 100644 --- a/structstdex_1_1chrono_1_1aosn__date-members.html +++ b/structstdex_1_1chrono_1_1aosn__date-members.html @@ -96,7 +96,7 @@ $(function() {
diff --git a/structstdex_1_1chrono_1_1aosn__date.html b/structstdex_1_1chrono_1_1aosn__date.html index ab649b06a..689718e9c 100644 --- a/structstdex_1_1chrono_1_1aosn__date.html +++ b/structstdex_1_1chrono_1_1aosn__date.html @@ -152,7 +152,7 @@ static constexpr bool is_s
diff --git a/structstdex_1_1chrono_1_1aosn__timestamp-members.html b/structstdex_1_1chrono_1_1aosn__timestamp-members.html index f740f14eb..ed6ea756f 100644 --- a/structstdex_1_1chrono_1_1aosn__timestamp-members.html +++ b/structstdex_1_1chrono_1_1aosn__timestamp-members.html @@ -110,7 +110,7 @@ $(function() {
diff --git a/structstdex_1_1chrono_1_1aosn__timestamp.html b/structstdex_1_1chrono_1_1aosn__timestamp.html index 1dc2dbebf..8e5482540 100644 --- a/structstdex_1_1chrono_1_1aosn__timestamp.html +++ b/structstdex_1_1chrono_1_1aosn__timestamp.html @@ -197,7 +197,7 @@ static constexpr rep one_w
diff --git a/structstdex_1_1free__locale__delete-members.html b/structstdex_1_1free__locale__delete-members.html index 4a9018668..8abc00e47 100644 --- a/structstdex_1_1free__locale__delete-members.html +++ b/structstdex_1_1free__locale__delete-members.html @@ -84,7 +84,7 @@ $(function() {
diff --git a/structstdex_1_1free__locale__delete.html b/structstdex_1_1free__locale__delete.html index e3565f749..ab72d55f3 100644 --- a/structstdex_1_1free__locale__delete.html +++ b/structstdex_1_1free__locale__delete.html @@ -101,7 +101,7 @@ void operator() (local
diff --git a/structstdex_1_1interval-members.html b/structstdex_1_1interval-members.html index 614235332..7fe210e5b 100644 --- a/structstdex_1_1interval-members.html +++ b/structstdex_1_1interval-members.html @@ -102,7 +102,7 @@ $(function() {
diff --git a/structstdex_1_1interval.html b/structstdex_1_1interval.html index 043801ffe..960b90769 100644 --- a/structstdex_1_1interval.html +++ b/structstdex_1_1interval.html @@ -718,7 +718,7 @@ template<class T >
diff --git a/structstdex_1_1mapping-members.html b/structstdex_1_1mapping-members.html index d2b66bd98..349553cb9 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 c7483c6f9..ecf9a2ba8 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 f996d4f2d..3342aa23e 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 c69da0436..4a5768865 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 99c0f7bae..c42457889 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 6e215a3ed..ab0668d81 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 37de12d69..7bc6c4cca 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 030840bfe..7a7067ebc 100644 --- a/structstdex_1_1parser_1_1http__factor__more.html +++ b/structstdex_1_1parser_1_1http__factor__more.html @@ -93,7 +93,7 @@ Public Member Functions
diff --git a/structstdex_1_1stream_1_1buffer_1_1buffer__t-members.html b/structstdex_1_1stream_1_1buffer_1_1buffer__t-members.html index 10c6a7338..5c886d05e 100644 --- a/structstdex_1_1stream_1_1buffer_1_1buffer__t-members.html +++ b/structstdex_1_1stream_1_1buffer_1_1buffer__t-members.html @@ -89,7 +89,7 @@ $(function() {
diff --git a/structstdex_1_1stream_1_1buffer_1_1buffer__t.html b/structstdex_1_1stream_1_1buffer_1_1buffer__t.html index be3b201b1..2b9e360a3 100644 --- a/structstdex_1_1stream_1_1buffer_1_1buffer__t.html +++ b/structstdex_1_1stream_1_1buffer_1_1buffer__t.html @@ -109,7 +109,7 @@ size_t capacity diff --git a/structstdex_1_1stream_1_1fifo_1_1node__t-members.html b/structstdex_1_1stream_1_1fifo_1_1node__t-members.html index 0a407af67..b8a82f4f7 100644 --- a/structstdex_1_1stream_1_1fifo_1_1node__t-members.html +++ b/structstdex_1_1stream_1_1fifo_1_1node__t-members.html @@ -86,7 +86,7 @@ $(function() {
diff --git a/structstdex_1_1stream_1_1fifo_1_1node__t.html b/structstdex_1_1stream_1_1fifo_1_1node__t.html index 6820f0da8..a90e17ca6 100644 --- a/structstdex_1_1stream_1_1fifo_1_1node__t.html +++ b/structstdex_1_1stream_1_1fifo_1_1node__t.html @@ -99,7 +99,7 @@ uint8_t data [0]<
diff --git a/structstdex_1_1sys__info__t-members.html b/structstdex_1_1sys__info__t-members.html index ddf7ea465..830ba88b3 100644 --- a/structstdex_1_1sys__info__t-members.html +++ b/structstdex_1_1sys__info__t-members.html @@ -89,7 +89,7 @@ $(function() {
diff --git a/structstdex_1_1sys__info__t.html b/structstdex_1_1sys__info__t.html index 725b3e225..e8a2b2a63 100644 --- a/structstdex_1_1sys__info__t.html +++ b/structstdex_1_1sys__info__t.html @@ -137,7 +137,7 @@ struct utsname m_utsn<
diff --git a/system_8hpp_source.html b/system_8hpp_source.html index a96cf807a..fa6901fea 100644 --- a/system_8hpp_source.html +++ b/system_8hpp_source.html @@ -89,396 +89,381 @@ $(document).ready(function() { init_codefold(0); });
5
6#pragma once
7
-
8#ifdef _WIN32
-
9#ifndef NOMINMAX
-
10#define NOMINMAX // Collides with std::min/max
-
11#endif
-
12#include <windows.h>
-
13#include <intrin.h>
-
14#include <intsafe.h>
-
15#include <oaidl.h>
-
16#include <tchar.h>
-
17#else
-
18#define _LARGEFILE64_SOURCE
-
19#include <grp.h>
-
20#include <pwd.h>
-
21#include <string.h>
-
22#include <sys/types.h>
-
23#include <unistd.h>
-
24#endif
-
25#include "compat.hpp"
-
26#include <regex>
-
27#include <stdexcept>
-
28#include <string>
-
29
-
30// In case somebody #included <windows.h> before us and didn't #define NOMINMAX
-
31#ifdef _WIN32
-
32#ifdef min
-
33#undef min
-
34#endif
-
35#ifdef max
-
36#undef max
-
37#endif
-
38#endif
-
39
-
40#if defined(_WIN32)
-
41#define PATH_SEPARATOR '\\'
-
42#define PATH_SEPARATOR_STR "\\"
-
43#else
-
44#define PATH_SEPARATOR '/'
-
45#define PATH_SEPARATOR_STR "/"
-
46#endif
-
47
-
48namespace stdex
-
49{
-
53#if defined(_WIN32)
-
54 using sys_handle = HANDLE;
-
55 const sys_handle invalid_handle = INVALID_HANDLE_VALUE;
-
56#else
-
57 using sys_handle = int;
-
58 const sys_handle invalid_handle = (sys_handle)-1;
-
59#endif
-
60
-
64#if defined(_WIN32)
-
65 inline DWORD sys_error() { return GetLastError(); }
-
66#else
-
67 inline int sys_error() { return errno; }
-
68#endif
-
69
-
73#if defined(_WIN32)
-
74 using schar_t = TCHAR;
-
75#else
-
76 using schar_t = char;
-
77#define _T(x) x
-
78#endif
-
79
-
84 using sys_char = schar_t;
-
85
-
89 using sstring = std::basic_string<stdex::schar_t>;
-
90
-
95 using sys_string = sstring;
+
8#include "compat.hpp"
+
9#ifdef _WIN32
+
10#include <windows.h>
+
11#include <oaidl.h>
+
12#include <tchar.h>
+
13#else
+
14#define _LARGEFILE64_SOURCE
+
15#include <grp.h>
+
16#include <pwd.h>
+
17#include <string.h>
+
18#include <sys/types.h>
+
19#include <unistd.h>
+
20#endif
+
21#include <regex>
+
22#include <stdexcept>
+
23#include <string>
+
24
+
25#if defined(_WIN32)
+
26#define PATH_SEPARATOR '\\'
+
27#define PATH_SEPARATOR_STR "\\"
+
28#else
+
29#define PATH_SEPARATOR '/'
+
30#define PATH_SEPARATOR_STR "/"
+
31#endif
+
32
+
33namespace stdex
+
34{
+
38#if defined(_WIN32)
+
39 using sys_handle = HANDLE;
+
40 const sys_handle invalid_handle = INVALID_HANDLE_VALUE;
+
41#else
+
42 using sys_handle = int;
+
43 const sys_handle invalid_handle = (sys_handle)-1;
+
44#endif
+
45
+
49#if defined(_WIN32)
+
50 inline DWORD sys_error() { return GetLastError(); }
+
51#else
+
52 inline int sys_error() { return errno; }
+
53#endif
+
54
+
58#if defined(_WIN32)
+
59 using schar_t = TCHAR;
+
60#else
+
61 using schar_t = char;
+
62#define _T(x) x
+
63#endif
+
64
+
69 using sys_char = schar_t;
+
70
+
74 using sstring = std::basic_string<stdex::schar_t>;
+
75
+
80 using sys_string = sstring;
+
81
+
85 using sregex = std::basic_regex<stdex::schar_t>;
+
86
+
+ +
91 {
+
92 public:
+
93 sys_object(_In_opt_ sys_handle h = invalid_handle) : m_h(h) {}
+
94
+
95 sys_object(_In_ const sys_object& other) : m_h(other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle) {}
96
-
100 using sregex = std::basic_regex<stdex::schar_t>;
-
101
-
- -
106 {
-
107 public:
-
108 sys_object(_In_opt_ sys_handle h = invalid_handle) : m_h(h) {}
-
109
-
110 sys_object(_In_ const sys_object& other) : m_h(other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle) {}
+
97 sys_object& operator =(_In_ const sys_object& other)
+
98 {
+
99 if (this != std::addressof(other)) {
+
100 if (m_h != invalid_handle)
+
101 close(m_h);
+
102 m_h = other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle;
+
103 }
+
104 return *this;
+
105 }
+
106
+
107 sys_object(_Inout_ sys_object&& other) noexcept : m_h(other.m_h)
+
108 {
+
109 other.m_h = invalid_handle;
+
110 }
111
-
112 sys_object& operator =(_In_ const sys_object& other)
+
112 sys_object& operator =(_Inout_ sys_object&& other) noexcept
113 {
114 if (this != std::addressof(other)) {
115 if (m_h != invalid_handle)
116 close(m_h);
-
117 m_h = other.m_h != invalid_handle ? duplicate(other.m_h, false) : invalid_handle;
-
118 }
-
119 return *this;
-
120 }
-
121
-
122 sys_object(_Inout_ sys_object&& other) noexcept : m_h(other.m_h)
-
123 {
-
124 other.m_h = invalid_handle;
-
125 }
-
126
-
127 sys_object& operator =(_Inout_ sys_object&& other) noexcept
-
128 {
-
129 if (this != std::addressof(other)) {
-
130 if (m_h != invalid_handle)
-
131 close(m_h);
-
132 m_h = other.m_h;
-
133 other.m_h = invalid_handle;
-
134 }
-
135 return *this;
-
136 }
-
137
-
138 virtual ~sys_object() noexcept(false)
-
139 {
-
140 if (m_h != invalid_handle)
-
141 close(m_h);
-
142 }
-
143
-
-
147 virtual void close()
-
148 {
-
149 if (m_h != invalid_handle) {
-
150 close(m_h);
-
151 m_h = invalid_handle;
-
152 }
-
153 }
+
117 m_h = other.m_h;
+
118 other.m_h = invalid_handle;
+
119 }
+
120 return *this;
+
121 }
+
122
+
123 virtual ~sys_object() noexcept(false)
+
124 {
+
125 if (m_h != invalid_handle)
+
126 close(m_h);
+
127 }
+
128
+
+
132 virtual void close()
+
133 {
+
134 if (m_h != invalid_handle) {
+
135 close(m_h);
+
136 m_h = invalid_handle;
+
137 }
+
138 }
-
154
-
158 inline operator bool() const noexcept { return m_h != invalid_handle; }
-
159
-
163 inline sys_handle get() const noexcept { return m_h; }
-
164
-
165 protected:
-
-
169 static void close(_In_ sys_handle h)
-
170 {
-
171#ifdef _WIN32
-
172 if (CloseHandle(h) || GetLastError() == ERROR_INVALID_HANDLE)
-
173 return;
-
174 throw std::system_error(GetLastError(), std::system_category(), "CloseHandle failed");
-
175#else
-
176 if (::close(h) >= 0 || errno == EBADF)
-
177 return;
-
178 throw std::system_error(errno, std::system_category(), "close failed");
-
179#endif
-
180 }
+
139
+
143 inline operator bool() const noexcept { return m_h != invalid_handle; }
+
144
+
148 inline sys_handle get() const noexcept { return m_h; }
+
149
+
150 protected:
+
+
154 static void close(_In_ sys_handle h)
+
155 {
+
156#ifdef _WIN32
+
157 if (CloseHandle(h) || GetLastError() == ERROR_INVALID_HANDLE)
+
158 return;
+
159 throw std::system_error(GetLastError(), std::system_category(), "CloseHandle failed");
+
160#else
+
161 if (::close(h) >= 0 || errno == EBADF)
+
162 return;
+
163 throw std::system_error(errno, std::system_category(), "close failed");
+
164#endif
+
165 }
-
181
-
-
185 static sys_handle duplicate(_In_ sys_handle h, _In_ bool inherit)
-
186 {
-
187 sys_handle h_new;
-
188#ifdef _WIN32
-
189 HANDLE process = GetCurrentProcess();
-
190 if (DuplicateHandle(process, h, process, &h_new, 0, inherit, DUPLICATE_SAME_ACCESS))
-
191 return h_new;
-
192 throw std::system_error(GetLastError(), std::system_category(), "DuplicateHandle failed");
-
193#else
-
194 _Unreferenced_(inherit);
-
195 if ((h_new = dup(h)) >= 0)
-
196 return h_new;
-
197 throw std::system_error(errno, std::system_category(), "dup failed");
-
198#endif
-
199 }
+
166
+
+
170 static sys_handle duplicate(_In_ sys_handle h, _In_ bool inherit)
+
171 {
+
172 sys_handle h_new;
+
173#ifdef _WIN32
+
174 HANDLE process = GetCurrentProcess();
+
175 if (DuplicateHandle(process, h, process, &h_new, 0, inherit, DUPLICATE_SAME_ACCESS))
+
176 return h_new;
+
177 throw std::system_error(GetLastError(), std::system_category(), "DuplicateHandle failed");
+
178#else
+
179 _Unreferenced_(inherit);
+
180 if ((h_new = dup(h)) >= 0)
+
181 return h_new;
+
182 throw std::system_error(errno, std::system_category(), "dup failed");
+
183#endif
+
184 }
-
200
-
201 protected:
-
202 sys_handle m_h;
-
203 };
+
185
+
186 protected:
+
187 sys_handle m_h;
+
188 };
-
204
-
205#ifdef _WIN32
-
206 template <class T>
-
207 class safearray_accessor
-
208 {
-
209 public:
-
210 safearray_accessor(_In_ LPSAFEARRAY sa) : m_sa(sa)
-
211 {
-
212 HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void HUGEP**>(&m_data));
-
213 if (FAILED(hr))
-
214 throw std::system_error(hr, std::system_category(), "SafeArrayAccessData failed");
-
215 }
-
216
-
217 ~safearray_accessor()
-
218 {
-
219 SafeArrayUnaccessData(m_sa);
-
220 }
-
221
-
222 T* data() const { return m_data; }
-
223
-
224 protected:
-
225 LPSAFEARRAY m_sa;
-
226 T* m_data;
-
227 };
-
228
-
232 struct SafeArrayDestroy_delete
-
233 {
-
237 void operator()(_In_ LPSAFEARRAY sa) const
-
238 {
-
239 SafeArrayDestroy(sa);
-
240 }
-
241 };
+
189
+
190#ifdef _WIN32
+
191 template <class T>
+
192 class safearray_accessor
+
193 {
+
194 public:
+
195 safearray_accessor(_In_ LPSAFEARRAY sa) : m_sa(sa)
+
196 {
+
197 HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void HUGEP**>(&m_data));
+
198 if (FAILED(hr))
+
199 throw std::system_error(hr, std::system_category(), "SafeArrayAccessData failed");
+
200 }
+
201
+
202 ~safearray_accessor()
+
203 {
+
204 SafeArrayUnaccessData(m_sa);
+
205 }
+
206
+
207 T* data() const { return m_data; }
+
208
+
209 protected:
+
210 LPSAFEARRAY m_sa;
+
211 T* m_data;
+
212 };
+
213
+
217 struct SafeArrayDestroy_delete
+
218 {
+
222 void operator()(_In_ LPSAFEARRAY sa) const
+
223 {
+
224 SafeArrayDestroy(sa);
+
225 }
+
226 };
+
227
+
231 struct SysFreeString_delete
+
232 {
+
236 void operator()(_In_ BSTR sa) const
+
237 {
+
238 SysFreeString(sa);
+
239 }
+
240 };
+
241#endif
242
-
246 struct SysFreeString_delete
-
247 {
-
251 void operator()(_In_ BSTR sa) const
-
252 {
-
253 SysFreeString(sa);
-
254 }
-
255 };
-
256#endif
-
257
-
261#ifdef _WIN32
-
262 typedef uint16_t platform_id;
-
263#else
-
264 typedef const char* platform_id;
-
265
-
266 inline bool operator ==(_In_ const platform_id a, _In_ const platform_id b) { return a == b; }
-
267 inline bool operator !=(_In_ const platform_id a, _In_ const platform_id b) { return a != b; }
-
268 inline bool operator <(_In_ const platform_id a, _In_ const platform_id b) { return a == IMAGE_FILE_MACHINE_UNKNOWN && b != IMAGE_FILE_MACHINE_UNKNOWN || a != IMAGE_FILE_MACHINE_UNKNOWN && b != IMAGE_FILE_MACHINE_UNKNOWN && strcmp(a, b) < 0; }
-
269 inline bool operator <=(_In_ const platform_id a, _In_ const platform_id b) { return a == IMAGE_FILE_MACHINE_UNKNOWN || a != IMAGE_FILE_MACHINE_UNKNOWN && b != IMAGE_FILE_MACHINE_UNKNOWN && strcmp(a, b) <= 0; }
-
270 inline bool operator >(_In_ const platform_id a, _In_ const platform_id b) { return a != IMAGE_FILE_MACHINE_UNKNOWN && b == IMAGE_FILE_MACHINE_UNKNOWN || a != IMAGE_FILE_MACHINE_UNKNOWN && b != IMAGE_FILE_MACHINE_UNKNOWN && strcmp(a, b) > 0; }
-
271 inline bool operator >=(_In_ const platform_id a, _In_ const platform_id b) { return b == IMAGE_FILE_MACHINE_UNKNOWN || a != IMAGE_FILE_MACHINE_UNKNOWN && b != IMAGE_FILE_MACHINE_UNKNOWN && strcmp(a, b) >= 0; }
-
272#endif
-
273}
-
274
-
275#ifndef _WIN32
-
276constexpr stdex::platform_id IMAGE_FILE_MACHINE_UNKNOWN = nullptr;
-
277constexpr stdex::platform_id IMAGE_FILE_MACHINE_I386 = "i386";
-
278constexpr stdex::platform_id IMAGE_FILE_MACHINE_AMD64 = "x86_64";
-
279constexpr stdex::platform_id IMAGE_FILE_MACHINE_ARMNT = "arm";
-
280constexpr stdex::platform_id IMAGE_FILE_MACHINE_ARM64 = "aarch64";
-
281#endif
-
282
-
283namespace stdex
-
284{
-
-
288 const struct sys_info_t
-
289 {
-
293#if _M_IX86
-
294 static constexpr platform_id process_platform = IMAGE_FILE_MACHINE_I386;
-
295#elif _M_X64 // _M_ARM64EC is introducing as x64
-
296 static constexpr platform_id process_platform = IMAGE_FILE_MACHINE_AMD64;
-
297#elif _M_ARM
-
298 static constexpr platform_id process_platform = IMAGE_FILE_MACHINE_ARMNT;
-
299#elif _M_ARM64
-
300 static constexpr platform_id process_platform = IMAGE_FILE_MACHINE_ARM64;
-
301#elif __i386__
-
302 static constexpr platform_id process_platform = "i386";
-
303#elif __x86_64__
-
304 static constexpr platform_id process_platform = "x86_64";
-
305#elif __aarch64__
-
306 static constexpr platform_id process_platform = "aarch64";
-
307#else
-
308 #error Unknown platform
-
309#endif
-
310
-
314 platform_id os_platform;
-
315
-
316#ifdef _WIN32
-
320 bool wow64;
-
321#endif
+
246#ifdef _WIN32
+
247 typedef uint16_t platform_id;
+
248#else
+
249 typedef const char* platform_id;
+
250
+
251 inline bool operator ==(_In_ const platform_id a, _In_ const platform_id b) { return a == b; }
+
252 inline bool operator !=(_In_ const platform_id a, _In_ const platform_id b) { return a != b; }
+
253 inline bool operator <(_In_ const platform_id a, _In_ const platform_id b) { return a == IMAGE_FILE_MACHINE_UNKNOWN && b != IMAGE_FILE_MACHINE_UNKNOWN || a != IMAGE_FILE_MACHINE_UNKNOWN && b != IMAGE_FILE_MACHINE_UNKNOWN && strcmp(a, b) < 0; }
+
254 inline bool operator <=(_In_ const platform_id a, _In_ const platform_id b) { return a == IMAGE_FILE_MACHINE_UNKNOWN || a != IMAGE_FILE_MACHINE_UNKNOWN && b != IMAGE_FILE_MACHINE_UNKNOWN && strcmp(a, b) <= 0; }
+
255 inline bool operator >(_In_ const platform_id a, _In_ const platform_id b) { return a != IMAGE_FILE_MACHINE_UNKNOWN && b == IMAGE_FILE_MACHINE_UNKNOWN || a != IMAGE_FILE_MACHINE_UNKNOWN && b != IMAGE_FILE_MACHINE_UNKNOWN && strcmp(a, b) > 0; }
+
256 inline bool operator >=(_In_ const platform_id a, _In_ const platform_id b) { return b == IMAGE_FILE_MACHINE_UNKNOWN || a != IMAGE_FILE_MACHINE_UNKNOWN && b != IMAGE_FILE_MACHINE_UNKNOWN && strcmp(a, b) >= 0; }
+
257#endif
+
258}
+
259
+
260#ifndef _WIN32
+
261constexpr stdex::platform_id IMAGE_FILE_MACHINE_UNKNOWN = nullptr;
+
262constexpr stdex::platform_id IMAGE_FILE_MACHINE_I386 = "i386";
+
263constexpr stdex::platform_id IMAGE_FILE_MACHINE_AMD64 = "x86_64";
+
264constexpr stdex::platform_id IMAGE_FILE_MACHINE_ARMNT = "arm";
+
265constexpr stdex::platform_id IMAGE_FILE_MACHINE_ARM64 = "aarch64";
+
266#endif
+
267
+
268namespace stdex
+
269{
+
+
273 const struct sys_info_t
+
274 {
+
278#if _M_IX86
+
279 static constexpr platform_id process_platform = IMAGE_FILE_MACHINE_I386;
+
280#elif _M_X64 // _M_ARM64EC is introducing as x64
+
281 static constexpr platform_id process_platform = IMAGE_FILE_MACHINE_AMD64;
+
282#elif _M_ARM
+
283 static constexpr platform_id process_platform = IMAGE_FILE_MACHINE_ARMNT;
+
284#elif _M_ARM64
+
285 static constexpr platform_id process_platform = IMAGE_FILE_MACHINE_ARM64;
+
286#elif __i386__
+
287 static constexpr platform_id process_platform = "i386";
+
288#elif __x86_64__
+
289 static constexpr platform_id process_platform = "x86_64";
+
290#elif __aarch64__
+
291 static constexpr platform_id process_platform = "aarch64";
+
292#else
+
293 #error Unknown platform
+
294#endif
+
295
+
299 platform_id os_platform;
+
300
+
301#ifdef _WIN32
+
305 bool wow64;
+
306#endif
+
307
+ +
312
+
316 bool admin;
+
317
+
322
- -
327
-
331 bool admin;
-
332
- -
337
-
338 sys_info_t() :
-
339 os_platform(IMAGE_FILE_MACHINE_UNKNOWN),
-
340 wow64(false),
- -
342 admin(false),
-
343 elevated(false)
-
344 {
-
345#ifdef _WIN32
-
346 HMODULE kernel32_handle;
-
347 kernel32_handle = LoadLibrary(_T("kernel32.dll"));
-
348 _Assume_(kernel32_handle);
-
349 BOOL(WINAPI * IsWow64Process2)(HANDLE hProcess, USHORT * pProcessMachine, USHORT * pNativeMachine);
-
350 *reinterpret_cast<FARPROC*>(&IsWow64Process2) = GetProcAddress(kernel32_handle, "IsWow64Process2");
-
351 HANDLE process = GetCurrentProcess();
-
352 USHORT process_machine;
-
353#ifndef _WIN64
-
354 BOOL Wow64Process;
-
355#endif
-
356 if (IsWow64Process2 && IsWow64Process2(process, &process_machine, &os_platform)) {
-
357 wow64 = process_machine != IMAGE_FILE_MACHINE_UNKNOWN;
-
358 }
-
359#ifdef _WIN64
-
360 else {
-
361 os_platform = process_platform;
-
362 wow64 = false;
-
363 }
-
364#else
-
365 else if (IsWow64Process(process, &Wow64Process)) {
-
366 if (Wow64Process) {
-
367 os_platform = IMAGE_FILE_MACHINE_AMD64;
-
368 wow64 = true;
-
369 }
-
370 else {
-
371 os_platform = process_platform;
-
372 wow64 = false;
-
373 }
-
374 }
-
375#endif
-
376 FreeLibrary(kernel32_handle);
-
377#else
-
378 memset(&m_utsn, 0, sizeof(m_utsn));
-
379 if (uname(&m_utsn) != -1)
-
380 os_platform = reinterpret_cast<platform_id>(m_utsn.machine);
-
381#endif
-
382
-
383#ifdef _WIN32
-
384 HWINSTA hWinSta = GetProcessWindowStation();
-
385 if (hWinSta) {
-
386 TCHAR sName[MAX_PATH];
-
387 if (GetUserObjectInformation(hWinSta, UOI_NAME, sName, sizeof(sName), NULL)) {
-
388 sName[_countof(sName) - 1] = 0;
-
389 // Only "WinSta0" is interactive (Source: KB171890)
-
390 interactive_process = _tcsicmp(sName, _T("WinSta0")) == 0;
-
391 }
-
392 }
-
393#else
-
394 // TODO: Research interactive process vs service/agent/daemon on this platform.
-
395#endif
-
396
-
397#if defined(_WIN32)
-
398 {
-
399 HANDLE token_h;
-
400 if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token_h)) {
-
401 sys_object token(token_h);
-
402
-
403 TOKEN_ELEVATION elevation;
-
404 DWORD size = sizeof(TOKEN_ELEVATION);
-
405 if (GetTokenInformation(token_h, TokenElevation, &elevation, sizeof(elevation), &size))
-
406 elevated = elevation.TokenIsElevated;
-
407
-
408 GetTokenInformation(token.get(), TokenGroups, NULL, 0, &size);
-
409 std::unique_ptr<TOKEN_GROUPS> groups((TOKEN_GROUPS*)new uint8_t[size]);
-
410 if (GetTokenInformation(token.get(), TokenGroups, (LPVOID)groups.get(), size, &size)) {
-
411 SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
-
412 PSID sid_admins_h = NULL;
-
413 if (AllocateAndInitializeSid(&authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid_admins_h)) {
-
414 struct SID_delete { void operator()(_In_ PSID p) const { FreeSid(p); } };
-
415 std::unique_ptr<void, SID_delete> sid_admins(sid_admins_h);
-
416 for (DWORD i = 0; i < groups->GroupCount; ++i)
-
417 if (EqualSid(sid_admins.get(), groups->Groups[i].Sid)) {
-
418 admin = true;
-
419 break;
-
420 }
-
421 }
-
422 }
-
423 }
-
424 }
-
425#elif defined(__APPLE__)
-
426 {
-
427 gid_t gids[NGROUPS + 1]; // A user cannot be member in more than NGROUPS groups, not counting the default group (hence the + 1)
-
428 for (int i = 0, n = getgroups(_countof(gids), gids); i < n; ++i) {
-
429 struct group* group = getgrgid(gids[i]);
-
430 if (!group) continue;
-
431 if (strcmp(group->gr_name, "admin") == 0) {
-
432 admin = true;
-
433 break;
-
434 }
-
435 }
-
436 }
-
437
-
438 elevated = geteuid() == 0;
-
439#else
-
440 // TODO: Set admin.
-
441 elevated = geteuid() == 0;
-
442#endif
-
443 }
-
444
-
445 protected:
-
446#ifndef _WIN32
-
447 struct utsname m_utsn;
-
448#endif
-
449 } sys_info;
+
323 sys_info_t() :
+
324 os_platform(IMAGE_FILE_MACHINE_UNKNOWN),
+
325 wow64(false),
+ +
327 admin(false),
+
328 elevated(false)
+
329 {
+
330#ifdef _WIN32
+
331 HMODULE kernel32_handle;
+
332 kernel32_handle = LoadLibrary(_T("kernel32.dll"));
+
333 _Assume_(kernel32_handle);
+
334 BOOL(WINAPI * IsWow64Process2)(HANDLE hProcess, USHORT * pProcessMachine, USHORT * pNativeMachine);
+
335 *reinterpret_cast<FARPROC*>(&IsWow64Process2) = GetProcAddress(kernel32_handle, "IsWow64Process2");
+
336 HANDLE process = GetCurrentProcess();
+
337 USHORT process_machine;
+
338#ifndef _WIN64
+
339 BOOL Wow64Process;
+
340#endif
+
341 if (IsWow64Process2 && IsWow64Process2(process, &process_machine, &os_platform)) {
+
342 wow64 = process_machine != IMAGE_FILE_MACHINE_UNKNOWN;
+
343 }
+
344#ifdef _WIN64
+
345 else {
+
346 os_platform = process_platform;
+
347 wow64 = false;
+
348 }
+
349#else
+
350 else if (IsWow64Process(process, &Wow64Process)) {
+
351 if (Wow64Process) {
+
352 os_platform = IMAGE_FILE_MACHINE_AMD64;
+
353 wow64 = true;
+
354 }
+
355 else {
+
356 os_platform = process_platform;
+
357 wow64 = false;
+
358 }
+
359 }
+
360#endif
+
361 FreeLibrary(kernel32_handle);
+
362#else
+
363 memset(&m_utsn, 0, sizeof(m_utsn));
+
364 if (uname(&m_utsn) != -1)
+
365 os_platform = reinterpret_cast<platform_id>(m_utsn.machine);
+
366#endif
+
367
+
368#ifdef _WIN32
+
369 HWINSTA hWinSta = GetProcessWindowStation();
+
370 if (hWinSta) {
+
371 TCHAR sName[MAX_PATH];
+
372 if (GetUserObjectInformation(hWinSta, UOI_NAME, sName, sizeof(sName), NULL)) {
+
373 sName[_countof(sName) - 1] = 0;
+
374 // Only "WinSta0" is interactive (Source: KB171890)
+
375 interactive_process = _tcsicmp(sName, _T("WinSta0")) == 0;
+
376 }
+
377 }
+
378#else
+
379 // TODO: Research interactive process vs service/agent/daemon on this platform.
+
380#endif
+
381
+
382#if defined(_WIN32)
+
383 {
+
384 HANDLE token_h;
+
385 if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token_h)) {
+
386 sys_object token(token_h);
+
387
+
388 TOKEN_ELEVATION elevation;
+
389 DWORD size = sizeof(TOKEN_ELEVATION);
+
390 if (GetTokenInformation(token_h, TokenElevation, &elevation, sizeof(elevation), &size))
+
391 elevated = elevation.TokenIsElevated;
+
392
+
393 GetTokenInformation(token.get(), TokenGroups, NULL, 0, &size);
+
394 std::unique_ptr<TOKEN_GROUPS> groups((TOKEN_GROUPS*)new uint8_t[size]);
+
395 if (GetTokenInformation(token.get(), TokenGroups, (LPVOID)groups.get(), size, &size)) {
+
396 SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
+
397 PSID sid_admins_h = NULL;
+
398 if (AllocateAndInitializeSid(&authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid_admins_h)) {
+
399 struct SID_delete { void operator()(_In_ PSID p) const { FreeSid(p); } };
+
400 std::unique_ptr<void, SID_delete> sid_admins(sid_admins_h);
+
401 for (DWORD i = 0; i < groups->GroupCount; ++i)
+
402 if (EqualSid(sid_admins.get(), groups->Groups[i].Sid)) {
+
403 admin = true;
+
404 break;
+
405 }
+
406 }
+
407 }
+
408 }
+
409 }
+
410#elif defined(__APPLE__)
+
411 {
+
412 gid_t gids[NGROUPS + 1]; // A user cannot be member in more than NGROUPS groups, not counting the default group (hence the + 1)
+
413 for (int i = 0, n = getgroups(_countof(gids), gids); i < n; ++i) {
+
414 struct group* group = getgrgid(gids[i]);
+
415 if (!group) continue;
+
416 if (strcmp(group->gr_name, "admin") == 0) {
+
417 admin = true;
+
418 break;
+
419 }
+
420 }
+
421 }
+
422
+
423 elevated = geteuid() == 0;
+
424#else
+
425 // TODO: Set admin.
+
426 elevated = geteuid() == 0;
+
427#endif
+
428 }
+
429
+
430 protected:
+
431#ifndef _WIN32
+
432 struct utsname m_utsn;
+
433#endif
+
434 } sys_info;
-
450}
-
Operating system object (file, pipe, anything with an OS handle etc.)
Definition system.hpp:106
-
sys_handle get() const noexcept
Returns object handle.
Definition system.hpp:163
-
virtual void close()
Closes object.
Definition system.hpp:147
-
static sys_handle duplicate(sys_handle h, bool inherit)
Duplicates given object.
Definition system.hpp:185
-
static void close(sys_handle h)
Closes object.
Definition system.hpp:169
-
System information.
Definition system.hpp:289
-
bool admin
Is member of local group Administrators (Windows) or member of group wheel/sudoers (others)?
Definition system.hpp:331
-
bool elevated
Is elevated process (Windows) or running as root (others)?
Definition system.hpp:336
-
platform_id os_platform
The platform this process was compiled for.
Definition system.hpp:314
-
bool interactive_process
Is interactive process?
Definition system.hpp:326
+
435}
+
Operating system object (file, pipe, anything with an OS handle etc.)
Definition system.hpp:91
+
sys_handle get() const noexcept
Returns object handle.
Definition system.hpp:148
+
virtual void close()
Closes object.
Definition system.hpp:132
+
static sys_handle duplicate(sys_handle h, bool inherit)
Duplicates given object.
Definition system.hpp:170
+
static void close(sys_handle h)
Closes object.
Definition system.hpp:154
+
System information.
Definition system.hpp:274
+
bool admin
Is member of local group Administrators (Windows) or member of group wheel/sudoers (others)?
Definition system.hpp:316
+
bool elevated
Is elevated process (Windows) or running as root (others)?
Definition system.hpp:321
+
platform_id os_platform
The platform this process was compiled for.
Definition system.hpp:299
+
bool interactive_process
Is interactive process?
Definition system.hpp:311
diff --git a/unicode_8cpp_source.html b/unicode_8cpp_source.html index 97c34c2a8..b2acc2d97 100644 --- a/unicode_8cpp_source.html +++ b/unicode_8cpp_source.html @@ -177,11 +177,11 @@ $(document).ready(function() { init_codefold(0); });
93#ifndef _WIN32
94#pragma GCC diagnostic pop
95#endif
-
Encoding converter context.
Definition unicode.hpp:65
+
Encoding converter context.
Definition unicode.hpp:64
diff --git a/unicode_8hpp_source.html b/unicode_8hpp_source.html index 43e913e65..2b8eb5a21 100644 --- a/unicode_8hpp_source.html +++ b/unicode_8hpp_source.html @@ -92,605 +92,604 @@ $(document).ready(function() { init_codefold(0); });
8#include "compat.hpp"
9#include "endian.hpp"
10#include "math.hpp"
-
11#include "system.hpp"
-
12#include <stdint.h>
-
13#ifndef _WIN32
-
14#include <iconv.h>
-
15#include <langinfo.h>
-
16#endif
-
17#include <map>
-
18#include <memory>
-
19#include <string>
-
20
-
21namespace stdex
-
22{
-
23 enum class charset_id : uint16_t {
-
24#ifdef _WIN32
-
25 system = CP_ACP,
-
26 oem = CP_OEMCP,
-
27 utf7 = CP_UTF7,
-
28 utf8 = CP_UTF8,
-
29 utf16 = 1200 /*CP_WINUNICODE*/,
-
30 utf32 = 12000,
-
31 windows1250 = 1250,
-
32 windows1251 = 1251,
-
33 windows1252 = 1252,
-
34#else
-
35 system = 0,
-
36 utf7,
-
37 utf8,
-
38 utf16,
-
39 utf32,
-
40 windows1250,
-
41 windows1251,
-
42 windows1252,
-
43
-
44 _max
-
45#endif
-
46 };
-
47
-
48#ifdef _WIN32
-
49 constexpr charset_id wchar_t_charset = charset_id::utf16;
-
50#ifdef _UNICODE
-
51 constexpr charset_id system_charset = charset_id::utf16;
-
52#else
-
53 constexpr charset_id system_charset = charset_id::system;
-
54#endif
-
55#else
-
56 constexpr charset_id wchar_t_charset = charset_id::utf32;
-
57 constexpr charset_id system_charset = charset_id::system;
-
58#endif
-
59
-
63 template <typename T_from, typename T_to>
-
- -
65 {
-
66 protected:
-
67 charset_id m_from, m_to;
-
68
-
69 public:
-
70 charset_encoder(_In_ charset_id from, _In_ charset_id to) :
-
71 m_from(from),
-
72 m_to(to)
-
73 {
-
74#ifdef _WIN32
-
75 m_from_wincp = to_encoding(from);
-
76 m_to_wincp = to_encoding(to);
-
77#else
-
78 m_handle = iconv_open(to_encoding(to), to_encoding(from));
-
79 if (m_handle == (iconv_t)-1)
-
80 throw std::system_error(errno, std::system_category(), "iconv_open failed");
-
81#endif
-
82 }
-
83
-
84#ifndef _WIN32
- -
86 {
-
87 iconv_close(m_handle);
-
88 }
-
89#endif
-
90
-
91 inline charset_id from_encoding() const { return m_from; }
-
92 inline charset_id to_encoding() const { return m_to; }
-
93
-
101 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
-
-
102 void strcat(
-
103 _Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to> &dst,
-
104 _In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src)
-
105 {
-
106 _Assume_(src || !count_src);
-
107 count_src = stdex::strnlen(src, count_src);
-
108 if (!count_src) _Unlikely_
-
109 return;
-
110
-
111#ifdef _WIN32
-
112 constexpr DWORD dwFlagsMBWC = MB_PRECOMPOSED;
-
113 constexpr DWORD dwFlagsWCMB = 0;
-
114 constexpr LPCCH lpDefaultChar = NULL;
-
115
-
116 _Assume_(src);
-
117 if (m_from_wincp == m_to_wincp) _Unlikely_{
-
118 dst.append(reinterpret_cast<const T_to*>(src), count_src);
-
119 return;
-
120 }
-
121
-
122#pragma warning(suppress: 4127)
-
123 if _Constexpr_ (sizeof(T_from) == sizeof(char) && sizeof(T_to) == sizeof(wchar_t)) {
-
124 _Assume_(count_src < INT_MAX || count_src == SIZE_MAX);
-
125
-
126 // Try to convert to stack buffer first.
-
127 WCHAR szStackBuffer[1024 / sizeof(WCHAR)];
-
128#pragma warning(suppress: 6387) // Testing indicates src may be NULL when count_src is also 0. Is SAL of the lpMultiByteStr parameter wrong?
-
129 int cch = MultiByteToWideChar(static_cast<UINT>(m_from_wincp), dwFlagsMBWC, reinterpret_cast<LPCCH>(src), static_cast<int>(count_src), szStackBuffer, _countof(szStackBuffer));
-
130 if (cch) {
-
131 // Append from stack.
-
132 dst.append(reinterpret_cast<const T_to*>(szStackBuffer), count_src != SIZE_MAX ? wcsnlen(szStackBuffer, cch) : static_cast<size_t>(cch) - 1);
-
133 return;
-
134 }
-
135 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
-
136 // Query the required output size. Allocate buffer. Then convert again.
-
137 cch = MultiByteToWideChar(static_cast<UINT>(m_from_wincp), dwFlagsMBWC, reinterpret_cast<LPCCH>(src), static_cast<int>(count_src), NULL, 0);
-
138 std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]);
-
139 cch = MultiByteToWideChar(static_cast<UINT>(m_from_wincp), dwFlagsMBWC, reinterpret_cast<LPCCH>(src), static_cast<int>(count_src), szBuffer.get(), cch);
-
140 dst.append(reinterpret_cast<const T_to*>(szBuffer.get()), count_src != SIZE_MAX ? wcsnlen(szBuffer.get(), cch) : static_cast<size_t>(cch) - 1);
-
141 return;
-
142 }
-
143 throw std::system_error(GetLastError(), std::system_category(), "MultiByteToWideChar failed");
-
144 }
-
145
-
146#pragma warning(suppress: 4127)
-
147 if _Constexpr_ (sizeof(T_from) == sizeof(wchar_t) && sizeof(T_to) == sizeof(char)) {
-
148 _Assume_(count_src < INT_MAX || count_src == SIZE_MAX);
-
149
-
150 // Try to convert to stack buffer first.
-
151 CHAR szStackBuffer[1024 / sizeof(CHAR)];
-
152#pragma warning(suppress: 6387) // Testing indicates src may be NULL when count_src is also 0. Is SAL of the lpWideCharStr parameter wrong?
-
153 int cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, reinterpret_cast<LPCWCH>(src), static_cast<int>(count_src), szStackBuffer, _countof(szStackBuffer), lpDefaultChar, NULL);
-
154 if (cch) {
-
155 // Copy from stack. Be careful not to include zero terminator.
-
156 dst.append(reinterpret_cast<const T_to*>(szStackBuffer), count_src != SIZE_MAX ? strnlen(szStackBuffer, cch) : static_cast<size_t>(cch) - 1);
-
157 return;
-
158 }
-
159 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
-
160 // Query the required output size. Allocate buffer. Then convert again.
-
161 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, reinterpret_cast<LPCWCH>(src), static_cast<int>(count_src), NULL, 0, lpDefaultChar, NULL);
-
162 std::unique_ptr<CHAR[]> szBuffer(new CHAR[cch]);
-
163 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, reinterpret_cast<LPCWCH>(src), static_cast<int>(count_src), szBuffer.get(), cch, lpDefaultChar, NULL);
-
164 dst.append(reinterpret_cast<const T_to*>(szBuffer.get()), count_src != SIZE_MAX ? strnlen(szBuffer.get(), cch) : static_cast<size_t>(cch) - 1);
-
165 return;
-
166 }
-
167 throw std::system_error(GetLastError(), std::system_category(), "WideCharToMultiByte failed");
-
168 }
-
169
-
170#pragma warning(suppress: 4127)
-
171 if _Constexpr_ (sizeof(T_from) == sizeof(char) && sizeof(T_to) == sizeof(char)) {
-
172 _Assume_(count_src < INT_MAX || count_src == SIZE_MAX);
-
173
-
174 // Try to convert to stack buffer first.
-
175 WCHAR szStackBufferMBWC[512 / sizeof(WCHAR)];
-
176#pragma warning(suppress: 6387) // Testing indicates src may be NULL when count_src is also 0. Is SAL of the lpMultiByteStr parameter wrong?
-
177 int cch = MultiByteToWideChar(static_cast<UINT>(m_from_wincp), dwFlagsMBWC, reinterpret_cast<LPCCH>(src), static_cast<int>(count_src), szStackBufferMBWC, _countof(szStackBufferMBWC));
-
178 if (cch) {
-
179 // Append from stack.
-
180 size_t count_inter = count_src != SIZE_MAX ? wcsnlen(szStackBufferMBWC, cch) : static_cast<size_t>(cch) - 1;
-
181 _Assume_(count_inter < INT_MAX);
-
182
-
183 // Try to convert to stack buffer first.
-
184 CHAR szStackBufferWCMB[512 / sizeof(CHAR)];
-
185#pragma warning(suppress: 6387) // Testing indicates szStackBufferMBWC may be NULL when count_inter is also 0. Is SAL of the lpWideCharStr parameter wrong?
-
186 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, szStackBufferMBWC, static_cast<int>(count_inter), szStackBufferWCMB, _countof(szStackBufferWCMB), lpDefaultChar, NULL);
-
187 if (cch) {
-
188 // Copy from stack. Be careful not to include zero terminator.
-
189 dst.append(reinterpret_cast<const T_to*>(szStackBufferWCMB), strnlen(szStackBufferWCMB, cch));
-
190 return;
-
191 }
-
192 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
-
193 // Query the required output size. Allocate buffer. Then convert again.
-
194 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, szStackBufferMBWC, static_cast<int>(count_inter), NULL, 0, lpDefaultChar, NULL);
-
195 std::unique_ptr<CHAR[]> szBufferWCMB(new CHAR[cch]);
-
196 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, szStackBufferMBWC, static_cast<int>(count_inter), szBufferWCMB.get(), cch, lpDefaultChar, NULL);
-
197 dst.append(reinterpret_cast<const T_to*>(szBufferWCMB.get()), strnlen(szBufferWCMB.get(), cch));
-
198 return;
-
199 }
-
200 throw std::system_error(GetLastError(), std::system_category(), "WideCharToMultiByte failed");
-
201 }
-
202 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
-
203 // Query the required output size. Allocate buffer. Then convert again.
-
204 cch = MultiByteToWideChar(static_cast<UINT>(m_from_wincp), dwFlagsMBWC, reinterpret_cast<LPCCH>(src), static_cast<int>(count_src), NULL, 0);
-
205 std::unique_ptr<WCHAR[]> szBufferMBWC(new WCHAR[cch]);
-
206 cch = MultiByteToWideChar(static_cast<UINT>(m_from_wincp), dwFlagsMBWC, reinterpret_cast<LPCCH>(src), static_cast<int>(count_src), szBufferMBWC.get(), cch);
-
207 size_t count_inter = count_src != SIZE_MAX ? wcsnlen(szBufferMBWC.get(), cch) : static_cast<size_t>(cch) - 1;
-
208
-
209 // Query the required output size. Allocate buffer. Then convert again.
-
210 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, szBufferMBWC.get(), static_cast<int>(count_inter), NULL, 0, lpDefaultChar, NULL);
-
211 std::unique_ptr<CHAR[]> szBufferWCMB(new CHAR[cch]);
-
212 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, szBufferMBWC.get(), static_cast<int>(count_inter), szBufferWCMB.get(), cch, lpDefaultChar, NULL);
-
213 dst.append(reinterpret_cast<const T_to*>(szBufferWCMB.get()), strnlen(szBufferWCMB.get(), cch));
-
214 return;
-
215 }
-
216 throw std::system_error(GetLastError(), std::system_category(), "MultiByteToWideChar failed");
-
217 }
-
218#else
-
219 dst.reserve(dst.size() + count_src);
-
220 T_to buf[1024 / sizeof(T_to)];
-
221 size_t src_size = stdex::mul(sizeof(T_from), count_src);
-
222 for (;;) {
-
223 T_to* output = &buf[0];
-
224 size_t output_size = sizeof(buf);
-
225 errno = 0;
-
226 iconv(m_handle, const_cast<char**>(reinterpret_cast<const char**>(&src)), &src_size, reinterpret_cast<char**>(&output), &output_size);
-
227 dst.append(buf, reinterpret_cast<T_to*>(reinterpret_cast<char*>(buf) + sizeof(buf) - output_size));
-
228 if (!errno)
-
229 break;
-
230 if (errno == E2BIG)
-
231 continue;
-
232 throw std::system_error(errno, std::system_category(), "iconv failed");
-
233 }
-
234#endif
-
235 }
+
11#include <stdint.h>
+
12#ifndef _WIN32
+
13#include <iconv.h>
+
14#include <langinfo.h>
+
15#endif
+
16#include <map>
+
17#include <memory>
+
18#include <string>
+
19
+
20namespace stdex
+
21{
+
22 enum class charset_id : uint16_t {
+
23#ifdef _WIN32
+
24 system = CP_ACP,
+
25 oem = CP_OEMCP,
+
26 utf7 = CP_UTF7,
+
27 utf8 = CP_UTF8,
+
28 utf16 = 1200 /*CP_WINUNICODE*/,
+
29 utf32 = 12000,
+
30 windows1250 = 1250,
+
31 windows1251 = 1251,
+
32 windows1252 = 1252,
+
33#else
+
34 system = 0,
+
35 utf7,
+
36 utf8,
+
37 utf16,
+
38 utf32,
+
39 windows1250,
+
40 windows1251,
+
41 windows1252,
+
42
+
43 _max
+
44#endif
+
45 };
+
46
+
47#ifdef _WIN32
+
48 constexpr charset_id wchar_t_charset = charset_id::utf16;
+
49#ifdef _UNICODE
+
50 constexpr charset_id system_charset = charset_id::utf16;
+
51#else
+
52 constexpr charset_id system_charset = charset_id::system;
+
53#endif
+
54#else
+
55 constexpr charset_id wchar_t_charset = charset_id::utf32;
+
56 constexpr charset_id system_charset = charset_id::system;
+
57#endif
+
58
+
62 template <typename T_from, typename T_to>
+
+ +
64 {
+
65 protected:
+
66 charset_id m_from, m_to;
+
67
+
68 public:
+
69 charset_encoder(_In_ charset_id from, _In_ charset_id to) :
+
70 m_from(from),
+
71 m_to(to)
+
72 {
+
73#ifdef _WIN32
+
74 m_from_wincp = to_encoding(from);
+
75 m_to_wincp = to_encoding(to);
+
76#else
+
77 m_handle = iconv_open(to_encoding(to), to_encoding(from));
+
78 if (m_handle == (iconv_t)-1)
+
79 throw std::system_error(errno, std::system_category(), "iconv_open failed");
+
80#endif
+
81 }
+
82
+
83#ifndef _WIN32
+ +
85 {
+
86 iconv_close(m_handle);
+
87 }
+
88#endif
+
89
+
90 inline charset_id from_encoding() const { return m_from; }
+
91 inline charset_id to_encoding() const { return m_to; }
+
92
+
100 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
+
+
101 void strcat(
+
102 _Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to> &dst,
+
103 _In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src)
+
104 {
+
105 _Assume_(src || !count_src);
+
106 count_src = stdex::strnlen(src, count_src);
+
107 if (!count_src) _Unlikely_
+
108 return;
+
109
+
110#ifdef _WIN32
+
111 constexpr DWORD dwFlagsMBWC = MB_PRECOMPOSED;
+
112 constexpr DWORD dwFlagsWCMB = 0;
+
113 constexpr LPCCH lpDefaultChar = NULL;
+
114
+
115 _Assume_(src);
+
116 if (m_from_wincp == m_to_wincp) _Unlikely_{
+
117 dst.append(reinterpret_cast<const T_to*>(src), count_src);
+
118 return;
+
119 }
+
120
+
121#pragma warning(suppress: 4127)
+
122 if _Constexpr_ (sizeof(T_from) == sizeof(char) && sizeof(T_to) == sizeof(wchar_t)) {
+
123 _Assume_(count_src < INT_MAX || count_src == SIZE_MAX);
+
124
+
125 // Try to convert to stack buffer first.
+
126 WCHAR szStackBuffer[1024 / sizeof(WCHAR)];
+
127#pragma warning(suppress: 6387) // Testing indicates src may be NULL when count_src is also 0. Is SAL of the lpMultiByteStr parameter wrong?
+
128 int cch = MultiByteToWideChar(static_cast<UINT>(m_from_wincp), dwFlagsMBWC, reinterpret_cast<LPCCH>(src), static_cast<int>(count_src), szStackBuffer, _countof(szStackBuffer));
+
129 if (cch) {
+
130 // Append from stack.
+
131 dst.append(reinterpret_cast<const T_to*>(szStackBuffer), count_src != SIZE_MAX ? wcsnlen(szStackBuffer, cch) : static_cast<size_t>(cch) - 1);
+
132 return;
+
133 }
+
134 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+
135 // Query the required output size. Allocate buffer. Then convert again.
+
136 cch = MultiByteToWideChar(static_cast<UINT>(m_from_wincp), dwFlagsMBWC, reinterpret_cast<LPCCH>(src), static_cast<int>(count_src), NULL, 0);
+
137 std::unique_ptr<WCHAR[]> szBuffer(new WCHAR[cch]);
+
138 cch = MultiByteToWideChar(static_cast<UINT>(m_from_wincp), dwFlagsMBWC, reinterpret_cast<LPCCH>(src), static_cast<int>(count_src), szBuffer.get(), cch);
+
139 dst.append(reinterpret_cast<const T_to*>(szBuffer.get()), count_src != SIZE_MAX ? wcsnlen(szBuffer.get(), cch) : static_cast<size_t>(cch) - 1);
+
140 return;
+
141 }
+
142 throw std::system_error(GetLastError(), std::system_category(), "MultiByteToWideChar failed");
+
143 }
+
144
+
145#pragma warning(suppress: 4127)
+
146 if _Constexpr_ (sizeof(T_from) == sizeof(wchar_t) && sizeof(T_to) == sizeof(char)) {
+
147 _Assume_(count_src < INT_MAX || count_src == SIZE_MAX);
+
148
+
149 // Try to convert to stack buffer first.
+
150 CHAR szStackBuffer[1024 / sizeof(CHAR)];
+
151#pragma warning(suppress: 6387) // Testing indicates src may be NULL when count_src is also 0. Is SAL of the lpWideCharStr parameter wrong?
+
152 int cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, reinterpret_cast<LPCWCH>(src), static_cast<int>(count_src), szStackBuffer, _countof(szStackBuffer), lpDefaultChar, NULL);
+
153 if (cch) {
+
154 // Copy from stack. Be careful not to include zero terminator.
+
155 dst.append(reinterpret_cast<const T_to*>(szStackBuffer), count_src != SIZE_MAX ? strnlen(szStackBuffer, cch) : static_cast<size_t>(cch) - 1);
+
156 return;
+
157 }
+
158 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+
159 // Query the required output size. Allocate buffer. Then convert again.
+
160 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, reinterpret_cast<LPCWCH>(src), static_cast<int>(count_src), NULL, 0, lpDefaultChar, NULL);
+
161 std::unique_ptr<CHAR[]> szBuffer(new CHAR[cch]);
+
162 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, reinterpret_cast<LPCWCH>(src), static_cast<int>(count_src), szBuffer.get(), cch, lpDefaultChar, NULL);
+
163 dst.append(reinterpret_cast<const T_to*>(szBuffer.get()), count_src != SIZE_MAX ? strnlen(szBuffer.get(), cch) : static_cast<size_t>(cch) - 1);
+
164 return;
+
165 }
+
166 throw std::system_error(GetLastError(), std::system_category(), "WideCharToMultiByte failed");
+
167 }
+
168
+
169#pragma warning(suppress: 4127)
+
170 if _Constexpr_ (sizeof(T_from) == sizeof(char) && sizeof(T_to) == sizeof(char)) {
+
171 _Assume_(count_src < INT_MAX || count_src == SIZE_MAX);
+
172
+
173 // Try to convert to stack buffer first.
+
174 WCHAR szStackBufferMBWC[512 / sizeof(WCHAR)];
+
175#pragma warning(suppress: 6387) // Testing indicates src may be NULL when count_src is also 0. Is SAL of the lpMultiByteStr parameter wrong?
+
176 int cch = MultiByteToWideChar(static_cast<UINT>(m_from_wincp), dwFlagsMBWC, reinterpret_cast<LPCCH>(src), static_cast<int>(count_src), szStackBufferMBWC, _countof(szStackBufferMBWC));
+
177 if (cch) {
+
178 // Append from stack.
+
179 size_t count_inter = count_src != SIZE_MAX ? wcsnlen(szStackBufferMBWC, cch) : static_cast<size_t>(cch) - 1;
+
180 _Assume_(count_inter < INT_MAX);
+
181
+
182 // Try to convert to stack buffer first.
+
183 CHAR szStackBufferWCMB[512 / sizeof(CHAR)];
+
184#pragma warning(suppress: 6387) // Testing indicates szStackBufferMBWC may be NULL when count_inter is also 0. Is SAL of the lpWideCharStr parameter wrong?
+
185 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, szStackBufferMBWC, static_cast<int>(count_inter), szStackBufferWCMB, _countof(szStackBufferWCMB), lpDefaultChar, NULL);
+
186 if (cch) {
+
187 // Copy from stack. Be careful not to include zero terminator.
+
188 dst.append(reinterpret_cast<const T_to*>(szStackBufferWCMB), strnlen(szStackBufferWCMB, cch));
+
189 return;
+
190 }
+
191 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+
192 // Query the required output size. Allocate buffer. Then convert again.
+
193 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, szStackBufferMBWC, static_cast<int>(count_inter), NULL, 0, lpDefaultChar, NULL);
+
194 std::unique_ptr<CHAR[]> szBufferWCMB(new CHAR[cch]);
+
195 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, szStackBufferMBWC, static_cast<int>(count_inter), szBufferWCMB.get(), cch, lpDefaultChar, NULL);
+
196 dst.append(reinterpret_cast<const T_to*>(szBufferWCMB.get()), strnlen(szBufferWCMB.get(), cch));
+
197 return;
+
198 }
+
199 throw std::system_error(GetLastError(), std::system_category(), "WideCharToMultiByte failed");
+
200 }
+
201 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+
202 // Query the required output size. Allocate buffer. Then convert again.
+
203 cch = MultiByteToWideChar(static_cast<UINT>(m_from_wincp), dwFlagsMBWC, reinterpret_cast<LPCCH>(src), static_cast<int>(count_src), NULL, 0);
+
204 std::unique_ptr<WCHAR[]> szBufferMBWC(new WCHAR[cch]);
+
205 cch = MultiByteToWideChar(static_cast<UINT>(m_from_wincp), dwFlagsMBWC, reinterpret_cast<LPCCH>(src), static_cast<int>(count_src), szBufferMBWC.get(), cch);
+
206 size_t count_inter = count_src != SIZE_MAX ? wcsnlen(szBufferMBWC.get(), cch) : static_cast<size_t>(cch) - 1;
+
207
+
208 // Query the required output size. Allocate buffer. Then convert again.
+
209 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, szBufferMBWC.get(), static_cast<int>(count_inter), NULL, 0, lpDefaultChar, NULL);
+
210 std::unique_ptr<CHAR[]> szBufferWCMB(new CHAR[cch]);
+
211 cch = WideCharToMultiByte(static_cast<UINT>(m_to_wincp), dwFlagsWCMB, szBufferMBWC.get(), static_cast<int>(count_inter), szBufferWCMB.get(), cch, lpDefaultChar, NULL);
+
212 dst.append(reinterpret_cast<const T_to*>(szBufferWCMB.get()), strnlen(szBufferWCMB.get(), cch));
+
213 return;
+
214 }
+
215 throw std::system_error(GetLastError(), std::system_category(), "MultiByteToWideChar failed");
+
216 }
+
217#else
+
218 dst.reserve(dst.size() + count_src);
+
219 T_to buf[1024 / sizeof(T_to)];
+
220 size_t src_size = stdex::mul(sizeof(T_from), count_src);
+
221 for (;;) {
+
222 T_to* output = &buf[0];
+
223 size_t output_size = sizeof(buf);
+
224 errno = 0;
+
225 iconv(m_handle, const_cast<char**>(reinterpret_cast<const char**>(&src)), &src_size, reinterpret_cast<char**>(&output), &output_size);
+
226 dst.append(buf, reinterpret_cast<T_to*>(reinterpret_cast<char*>(buf) + sizeof(buf) - output_size));
+
227 if (!errno)
+
228 break;
+
229 if (errno == E2BIG)
+
230 continue;
+
231 throw std::system_error(errno, std::system_category(), "iconv failed");
+
232 }
+
233#endif
+
234 }
-
236
-
243 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
-
-
244 inline void strcat(
-
245 _Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
-
246 _In_z_ const T_from* src)
-
247 {
-
248 strcat(dst, src, SIZE_MAX);
-
249 }
+
235
+
242 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
+
+
243 inline void strcat(
+
244 _Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
+
245 _In_z_ const T_from* src)
+
246 {
+
247 strcat(dst, src, SIZE_MAX);
+
248 }
-
250
-
257 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>, class _Traits_from = std::char_traits<T_from>, class _Alloc_from = std::allocator<T_from>>
-
-
258 inline void strcat(
-
259 _Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
-
260 _In_ const std::basic_string<T_from, _Traits_from, _Alloc_from>& src)
-
261 {
-
262 strcat(dst, src.data(), src.size());
-
263 }
+
249
+
256 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>, class _Traits_from = std::char_traits<T_from>, class _Alloc_from = std::allocator<T_from>>
+
+
257 inline void strcat(
+
258 _Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
+
259 _In_ const std::basic_string<T_from, _Traits_from, _Alloc_from>& src)
+
260 {
+
261 strcat(dst, src.data(), src.size());
+
262 }
-
264
-
272 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
-
-
273 inline void strcpy(
-
274 _Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
-
275 _In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src)
-
276 {
-
277 dst.clear();
-
278 strcat(dst, src, count_src);
-
279 }
+
263
+
271 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
+
+
272 inline void strcpy(
+
273 _Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
+
274 _In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src)
+
275 {
+
276 dst.clear();
+
277 strcat(dst, src, count_src);
+
278 }
-
280
-
287 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
-
-
288 inline void strcpy(
-
289 _Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
-
290 _In_z_ const T_from* src)
-
291 {
-
292 strcpy(dst, src, SIZE_MAX);
-
293 }
+
279
+
286 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
+
+
287 inline void strcpy(
+
288 _Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
+
289 _In_z_ const T_from* src)
+
290 {
+
291 strcpy(dst, src, SIZE_MAX);
+
292 }
-
294
-
301 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>, class _Traits_from = std::char_traits<T_from>, class _Alloc_from = std::allocator<T_from>>
-
-
302 inline void strcpy(
-
303 _Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
-
304 _In_ const std::basic_string<T_from, _Traits_from, _Alloc_from>& src)
-
305 {
-
306 strcpy(dst, src.data(), src.size());
-
307 }
+
293
+
300 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>, class _Traits_from = std::char_traits<T_from>, class _Alloc_from = std::allocator<T_from>>
+
+
301 inline void strcpy(
+
302 _Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
+
303 _In_ const std::basic_string<T_from, _Traits_from, _Alloc_from>& src)
+
304 {
+
305 strcpy(dst, src.data(), src.size());
+
306 }
-
308
-
315 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
-
-
316 inline std::basic_string<T_to, _Traits_to, _Alloc_to> convert(_In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src)
-
317 {
-
318 std::basic_string<T_to, _Traits_to, _Alloc_to> dst;
-
319 strcat(dst, src, count_src);
-
320 return dst;
-
321 }
+
307
+
314 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
+
+
315 inline std::basic_string<T_to, _Traits_to, _Alloc_to> convert(_In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src)
+
316 {
+
317 std::basic_string<T_to, _Traits_to, _Alloc_to> dst;
+
318 strcat(dst, src, count_src);
+
319 return dst;
+
320 }
-
322
-
328 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
-
-
329 inline std::basic_string<T_to, _Traits_to, _Alloc_to> convert(_In_z_ const T_from* src)
-
330 {
-
331 return convert(src, SIZE_MAX);
-
332 }
+
321
+
327 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
+
+
328 inline std::basic_string<T_to, _Traits_to, _Alloc_to> convert(_In_z_ const T_from* src)
+
329 {
+
330 return convert(src, SIZE_MAX);
+
331 }
-
333
-
339 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>, class _Traits_from = std::char_traits<T_from>, class _Alloc_from = std::allocator<T_from>>
-
-
340 inline std::basic_string<T_to, _Traits_to, _Alloc_to> convert(_In_ const std::basic_string<T_from, _Traits_from, _Alloc_from>& src)
-
341 {
-
342 return convert(src.data(), src.size());
-
343 }
+
332
+
338 template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>, class _Traits_from = std::char_traits<T_from>, class _Alloc_from = std::allocator<T_from>>
+
+
339 inline std::basic_string<T_to, _Traits_to, _Alloc_to> convert(_In_ const std::basic_string<T_from, _Traits_from, _Alloc_from>& src)
+
340 {
+
341 return convert(src.data(), src.size());
+
342 }
-
344
-
345 inline void clear()
-
346 {
-
347#ifndef _WIN32
-
348 iconv(m_handle, NULL, NULL, NULL, NULL);
-
349#endif
-
350 }
-
351
-
352 static charset_id system_charset()
-
353 {
-
354#ifdef _WIN32
-
355 return static_cast<charset_id>(GetACP());
-
356#else
-
357 static const std::map<const char*, charset_id> charsets = {
-
358 { "UNICODE-1-1-UTF-7", charset_id::utf7 },
-
359 { "UTF-7", charset_id::utf7 },
-
360 { "CSUNICODE11UTF7", charset_id::utf7 },
-
361
-
362 { "UTF-8", charset_id::utf8 },
-
363 { "UTF8", charset_id::utf8 },
-
364
-
365 { "UTF-16", charset_id::utf16 },
-
366#if BYTE_ORDER == BIG_ENDIAN
-
367 { "UTF-16BE", charset_id::utf16 },
-
368#else
-
369 { "UTF-16LE", charset_id::utf16 },
-
370#endif
-
371
-
372 { "UTF-32", charset_id::utf32 },
-
373#if BYTE_ORDER == BIG_ENDIAN
-
374 { "UTF-32BE", charset_id::utf32 },
-
375#else
-
376 { "UTF-32LE", charset_id::utf32 },
-
377#endif
-
378
-
379 { "CP1250", charset_id::windows1250 },
-
380 { "MS-EE", charset_id::windows1250 },
-
381 { "WINDOWS-1250", charset_id::windows1250 },
-
382
-
383 { "CP1251", charset_id::windows1251 },
-
384 { "MS-CYRL", charset_id::windows1251 },
-
385 { "WINDOWS-1251", charset_id::windows1251 },
-
386
-
387 { "CP1252", charset_id::windows1252 },
-
388 { "MS-ANSI", charset_id::windows1252 },
-
389 { "WINDOWS-1252", charset_id::windows1252 },
-
390 };
-
391 const char* lctype = nl_langinfo(CODESET);
-
392 if (auto el = charsets.find(lctype); el != charsets.end())
-
393 return el->second;
-
394 return charset_id::system;
-
395#endif
-
396 }
-
397
-
398#ifdef _WIN32
-
399 protected:
-
400 static UINT to_encoding(_In_ charset_id charset)
-
401 {
-
402 return
-
403 charset == charset_id::system ? GetACP() :
-
404 charset == charset_id::oem ? GetOEMCP() :
-
405 static_cast<UINT>(charset);
-
406 }
-
407
-
408 protected:
-
409 UINT m_from_wincp, m_to_wincp;
-
410#else
-
411 protected:
-
412 static const char* to_encoding(_In_ charset_id charset)
-
413 {
-
414 static const char* const encodings[static_cast<std::underlying_type_t<charset_id>>(charset_id::_max)] = {
-
415 "", // system
-
416 "UTF-7", // utf7
-
417 "UTF-8", // utf8
-
418#if BYTE_ORDER == BIG_ENDIAN
-
419 "UTF-16BE", // utf16
-
420 "UTF-32BE", // utf32
-
421#else
-
422 "UTF-16LE", // utf16
-
423 "UTF-32LE", // utf32
-
424#endif
-
425 "CP1250", // windows1250
-
426 "CP1251", // windows1251
-
427 "CP1252", // windows1252
-
428 };
-
429 return
-
430 charset == charset_id::system ? nl_langinfo(CODESET) :
-
431 encodings[static_cast<std::underlying_type_t<charset_id>>(charset)];
-
432 }
-
433
-
434 protected:
-
435 iconv_t m_handle;
-
436#endif
-
437 };
+
343
+
344 inline void clear()
+
345 {
+
346#ifndef _WIN32
+
347 iconv(m_handle, NULL, NULL, NULL, NULL);
+
348#endif
+
349 }
+
350
+
351 static charset_id system_charset()
+
352 {
+
353#ifdef _WIN32
+
354 return static_cast<charset_id>(GetACP());
+
355#else
+
356 static const std::map<const char*, charset_id> charsets = {
+
357 { "UNICODE-1-1-UTF-7", charset_id::utf7 },
+
358 { "UTF-7", charset_id::utf7 },
+
359 { "CSUNICODE11UTF7", charset_id::utf7 },
+
360
+
361 { "UTF-8", charset_id::utf8 },
+
362 { "UTF8", charset_id::utf8 },
+
363
+
364 { "UTF-16", charset_id::utf16 },
+
365#if BYTE_ORDER == BIG_ENDIAN
+
366 { "UTF-16BE", charset_id::utf16 },
+
367#else
+
368 { "UTF-16LE", charset_id::utf16 },
+
369#endif
+
370
+
371 { "UTF-32", charset_id::utf32 },
+
372#if BYTE_ORDER == BIG_ENDIAN
+
373 { "UTF-32BE", charset_id::utf32 },
+
374#else
+
375 { "UTF-32LE", charset_id::utf32 },
+
376#endif
+
377
+
378 { "CP1250", charset_id::windows1250 },
+
379 { "MS-EE", charset_id::windows1250 },
+
380 { "WINDOWS-1250", charset_id::windows1250 },
+
381
+
382 { "CP1251", charset_id::windows1251 },
+
383 { "MS-CYRL", charset_id::windows1251 },
+
384 { "WINDOWS-1251", charset_id::windows1251 },
+
385
+
386 { "CP1252", charset_id::windows1252 },
+
387 { "MS-ANSI", charset_id::windows1252 },
+
388 { "WINDOWS-1252", charset_id::windows1252 },
+
389 };
+
390 const char* lctype = nl_langinfo(CODESET);
+
391 if (auto el = charsets.find(lctype); el != charsets.end())
+
392 return el->second;
+
393 return charset_id::system;
+
394#endif
+
395 }
+
396
+
397#ifdef _WIN32
+
398 protected:
+
399 static UINT to_encoding(_In_ charset_id charset)
+
400 {
+
401 return
+
402 charset == charset_id::system ? GetACP() :
+
403 charset == charset_id::oem ? GetOEMCP() :
+
404 static_cast<UINT>(charset);
+
405 }
+
406
+
407 protected:
+
408 UINT m_from_wincp, m_to_wincp;
+
409#else
+
410 protected:
+
411 static const char* to_encoding(_In_ charset_id charset)
+
412 {
+
413 static const char* const encodings[static_cast<std::underlying_type_t<charset_id>>(charset_id::_max)] = {
+
414 "", // system
+
415 "UTF-7", // utf7
+
416 "UTF-8", // utf8
+
417#if BYTE_ORDER == BIG_ENDIAN
+
418 "UTF-16BE", // utf16
+
419 "UTF-32BE", // utf32
+
420#else
+
421 "UTF-16LE", // utf16
+
422 "UTF-32LE", // utf32
+
423#endif
+
424 "CP1250", // windows1250
+
425 "CP1251", // windows1251
+
426 "CP1252", // windows1252
+
427 };
+
428 return
+
429 charset == charset_id::system ? nl_langinfo(CODESET) :
+
430 encodings[static_cast<std::underlying_type_t<charset_id>>(charset)];
+
431 }
+
432
+
433 protected:
+
434 iconv_t m_handle;
+
435#endif
+
436 };
-
438
-
449#ifndef _WIN32
-
450 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
451#endif
-
452 inline void strcat(
-
453 _Inout_ std::wstring& dst,
-
454 _In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
-
455 _In_ charset_id charset = charset_id::system)
-
456 {
-
457 charset_encoder<char, wchar_t>(charset, wchar_t_charset).strcat(dst, src, count_src);
-
458 }
-
459
-
460 _Deprecated_("Use stdex::strcat")
-
461 inline void str2wstr(
-
462 _Inout_ std::wstring& dst,
-
463 _In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
-
464 _In_ charset_id charset = charset_id::system)
-
465 {
-
466 strcat(dst, src, count_src, charset);
-
467 }
-
468
-
478#ifndef _WIN32
-
479 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
480#endif
-
481 inline void strcat(
-
482 _Inout_ std::wstring& dst,
-
483 _In_ const std::string& src,
-
484 _In_ charset_id charset = charset_id::system)
-
485 {
-
486 strcat(dst, src.data(), src.size(), charset);
-
487 }
-
488
-
489 _Deprecated_("Use stdex::strcat")
-
490 inline void str2wstr(
-
491 _Inout_ std::wstring& dst,
-
492 _In_ const std::string& src,
-
493 _In_ charset_id charset = charset_id::system)
-
494 {
-
495 strcat(dst, src, charset);
-
496 }
-
497
-
508#ifndef _WIN32
-
509 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
510#endif
-
511 inline void strcpy(
-
512 _Inout_ std::wstring& dst,
-
513 _In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
-
514 _In_ charset_id charset = charset_id::system)
-
515 {
-
516 dst.clear();
-
517 strcat(dst, src, count_src, charset);
-
518 }
-
519
-
529#ifndef _WIN32
-
530 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
531#endif
-
532 inline void strcpy(
-
533 _Inout_ std::wstring& dst,
-
534 _In_ const std::string& src,
-
535 _In_ charset_id charset = charset_id::system)
-
536 {
-
537 strcpy(dst, src.data(), src.size(), charset);
-
538 }
-
539
-
550#ifndef _WIN32
-
551 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
552#endif
-
553 inline std::wstring str2wstr(
-
554 _In_z_ const char* src,
-
555 _In_ charset_id charset = charset_id::system)
-
556 {
-
557 std::wstring dst;
-
558 strcat(dst, src, SIZE_MAX, charset);
-
559 return dst;
-
560 }
-
561
-
573#ifndef _WIN32
-
574 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
575#endif
-
576 inline std::wstring str2wstr(
-
577 _In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
-
578 _In_ charset_id charset = charset_id::system)
-
579 {
-
580 std::wstring dst;
-
581 strcat(dst, src, count_src, charset);
-
582 return dst;
-
583 }
-
584
-
595#ifndef _WIN32
-
596 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
597#endif
-
598 inline std::wstring str2wstr(
-
599 _In_ const std::string& src,
-
600 _In_ charset_id charset = charset_id::system)
-
601 {
-
602 return str2wstr(src.c_str(), src.size(), charset);
-
603 }
-
604
-
615#ifndef _WIN32
-
616 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
617#endif
-
618 inline void strcat(
-
619 _Inout_ std::string& dst,
-
620 _In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
-
621 _In_ charset_id charset = charset_id::system)
-
622 {
-
623 charset_encoder<wchar_t, char>(wchar_t_charset, charset).strcat(dst, src, count_src);
-
624 }
-
625
-
626 _Deprecated_("Use stdex::strcat")
-
627 inline void wstr2str(
-
628 _Inout_ std::string& dst,
-
629 _In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
-
630 _In_ charset_id charset = charset_id::system)
-
631 {
-
632 strcat(dst, src, count_src, charset);
-
633 }
-
634
-
644#ifndef _WIN32
-
645 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
646#endif
-
647 inline void strcat(
-
648 _Inout_ std::string& dst,
-
649 _In_ const std::wstring& src,
-
650 _In_ charset_id charset = charset_id::system)
-
651 {
-
652 strcat(dst, src.c_str(), src.size(), charset);
-
653 }
-
654
-
655 _Deprecated_("Use stdex::strcat")
-
656 inline void wstr2str(
-
657 _Inout_ std::string& dst,
-
658 _In_ const std::wstring& src,
-
659 _In_ charset_id charset = charset_id::system)
-
660 {
-
661 strcat(dst, src, charset);
-
662 }
-
663
-
674#ifndef _WIN32
-
675 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
676#endif
-
677 inline void strcpy(
-
678 _Inout_ std::string& dst,
-
679 _In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
-
680 _In_ charset_id charset = charset_id::system)
-
681 {
-
682 dst.clear();
-
683 strcat(dst, src, count_src, charset);
-
684 }
-
685
-
695#ifndef _WIN32
-
696 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
697#endif
-
698 inline void strcpy(
-
699 _Inout_ std::string& dst,
-
700 _In_ const std::wstring& src,
-
701 _In_ charset_id charset = charset_id::system)
-
702 {
-
703 strcpy(dst, src.data(), src.size(), charset);
-
704 }
-
705
-
716#ifndef _WIN32
-
717 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
718#endif
-
719 inline std::string wstr2str(
-
720 _In_z_ const wchar_t* src,
-
721 _In_ charset_id charset = charset_id::system)
-
722 {
-
723 std::string dst;
-
724 strcat(dst, src, SIZE_MAX, charset);
-
725 return dst;
-
726 }
-
727
-
739#ifndef _WIN32
-
740 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
741#endif
-
742 inline std::string wstr2str(
-
743 _In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
-
744 _In_ charset_id charset = charset_id::system)
-
745 {
-
746 std::string dst;
-
747 strcat(dst, src, count_src, charset);
-
748 return dst;
-
749 }
-
750
-
761#ifndef _WIN32
-
762 _Deprecated_("For better performance, consider a reusable charset_encoder")
-
763#endif
-
764 inline std::string wstr2str(
-
765 _In_ const std::wstring& src,
-
766 _In_ charset_id charset = charset_id::system)
-
767 {
-
768 return wstr2str(src.c_str(), src.size(), charset);
-
769 }
-
770}
-
Encoding converter context.
Definition unicode.hpp:65
-
void strcpy(std::basic_string< T_to, _Traits_to, _Alloc_to > &dst, const std::basic_string< T_from, _Traits_from, _Alloc_from > &src)
Convert string.
Definition unicode.hpp:302
-
std::basic_string< T_to, _Traits_to, _Alloc_to > convert(const std::basic_string< T_from, _Traits_from, _Alloc_from > &src)
Return converted string.
Definition unicode.hpp:340
-
std::basic_string< T_to, _Traits_to, _Alloc_to > convert(const T_from *src)
Return converted string.
Definition unicode.hpp:329
-
void strcat(std::basic_string< T_to, _Traits_to, _Alloc_to > &dst, const std::basic_string< T_from, _Traits_from, _Alloc_from > &src)
Convert string and append to string.
Definition unicode.hpp:258
-
void strcpy(std::basic_string< T_to, _Traits_to, _Alloc_to > &dst, const T_from *src)
Convert string.
Definition unicode.hpp:288
-
void strcat(std::basic_string< T_to, _Traits_to, _Alloc_to > &dst, _In_reads_or_z_opt_(count_src) const T_from *src, size_t count_src)
Convert string and append to string.
Definition unicode.hpp:102
-
void strcat(std::basic_string< T_to, _Traits_to, _Alloc_to > &dst, const T_from *src)
Convert string and append to string.
Definition unicode.hpp:244
-
void strcpy(std::basic_string< T_to, _Traits_to, _Alloc_to > &dst, _In_reads_or_z_opt_(count_src) const T_from *src, size_t count_src)
Convert string.
Definition unicode.hpp:273
-
std::basic_string< T_to, _Traits_to, _Alloc_to > convert(_In_reads_or_z_opt_(count_src) const T_from *src, size_t count_src)
Return converted string.
Definition unicode.hpp:316
+
437
+
448#ifndef _WIN32
+
449 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
450#endif
+
451 inline void strcat(
+
452 _Inout_ std::wstring& dst,
+
453 _In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
+
454 _In_ charset_id charset = charset_id::system)
+
455 {
+
456 charset_encoder<char, wchar_t>(charset, wchar_t_charset).strcat(dst, src, count_src);
+
457 }
+
458
+
459 _Deprecated_("Use stdex::strcat")
+
460 inline void str2wstr(
+
461 _Inout_ std::wstring& dst,
+
462 _In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
+
463 _In_ charset_id charset = charset_id::system)
+
464 {
+
465 strcat(dst, src, count_src, charset);
+
466 }
+
467
+
477#ifndef _WIN32
+
478 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
479#endif
+
480 inline void strcat(
+
481 _Inout_ std::wstring& dst,
+
482 _In_ const std::string& src,
+
483 _In_ charset_id charset = charset_id::system)
+
484 {
+
485 strcat(dst, src.data(), src.size(), charset);
+
486 }
+
487
+
488 _Deprecated_("Use stdex::strcat")
+
489 inline void str2wstr(
+
490 _Inout_ std::wstring& dst,
+
491 _In_ const std::string& src,
+
492 _In_ charset_id charset = charset_id::system)
+
493 {
+
494 strcat(dst, src, charset);
+
495 }
+
496
+
507#ifndef _WIN32
+
508 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
509#endif
+
510 inline void strcpy(
+
511 _Inout_ std::wstring& dst,
+
512 _In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
+
513 _In_ charset_id charset = charset_id::system)
+
514 {
+
515 dst.clear();
+
516 strcat(dst, src, count_src, charset);
+
517 }
+
518
+
528#ifndef _WIN32
+
529 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
530#endif
+
531 inline void strcpy(
+
532 _Inout_ std::wstring& dst,
+
533 _In_ const std::string& src,
+
534 _In_ charset_id charset = charset_id::system)
+
535 {
+
536 strcpy(dst, src.data(), src.size(), charset);
+
537 }
+
538
+
549#ifndef _WIN32
+
550 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
551#endif
+
552 inline std::wstring str2wstr(
+
553 _In_z_ const char* src,
+
554 _In_ charset_id charset = charset_id::system)
+
555 {
+
556 std::wstring dst;
+
557 strcat(dst, src, SIZE_MAX, charset);
+
558 return dst;
+
559 }
+
560
+
572#ifndef _WIN32
+
573 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
574#endif
+
575 inline std::wstring str2wstr(
+
576 _In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
+
577 _In_ charset_id charset = charset_id::system)
+
578 {
+
579 std::wstring dst;
+
580 strcat(dst, src, count_src, charset);
+
581 return dst;
+
582 }
+
583
+
594#ifndef _WIN32
+
595 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
596#endif
+
597 inline std::wstring str2wstr(
+
598 _In_ const std::string& src,
+
599 _In_ charset_id charset = charset_id::system)
+
600 {
+
601 return str2wstr(src.c_str(), src.size(), charset);
+
602 }
+
603
+
614#ifndef _WIN32
+
615 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
616#endif
+
617 inline void strcat(
+
618 _Inout_ std::string& dst,
+
619 _In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
+
620 _In_ charset_id charset = charset_id::system)
+
621 {
+
622 charset_encoder<wchar_t, char>(wchar_t_charset, charset).strcat(dst, src, count_src);
+
623 }
+
624
+
625 _Deprecated_("Use stdex::strcat")
+
626 inline void wstr2str(
+
627 _Inout_ std::string& dst,
+
628 _In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
+
629 _In_ charset_id charset = charset_id::system)
+
630 {
+
631 strcat(dst, src, count_src, charset);
+
632 }
+
633
+
643#ifndef _WIN32
+
644 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
645#endif
+
646 inline void strcat(
+
647 _Inout_ std::string& dst,
+
648 _In_ const std::wstring& src,
+
649 _In_ charset_id charset = charset_id::system)
+
650 {
+
651 strcat(dst, src.c_str(), src.size(), charset);
+
652 }
+
653
+
654 _Deprecated_("Use stdex::strcat")
+
655 inline void wstr2str(
+
656 _Inout_ std::string& dst,
+
657 _In_ const std::wstring& src,
+
658 _In_ charset_id charset = charset_id::system)
+
659 {
+
660 strcat(dst, src, charset);
+
661 }
+
662
+
673#ifndef _WIN32
+
674 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
675#endif
+
676 inline void strcpy(
+
677 _Inout_ std::string& dst,
+
678 _In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
+
679 _In_ charset_id charset = charset_id::system)
+
680 {
+
681 dst.clear();
+
682 strcat(dst, src, count_src, charset);
+
683 }
+
684
+
694#ifndef _WIN32
+
695 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
696#endif
+
697 inline void strcpy(
+
698 _Inout_ std::string& dst,
+
699 _In_ const std::wstring& src,
+
700 _In_ charset_id charset = charset_id::system)
+
701 {
+
702 strcpy(dst, src.data(), src.size(), charset);
+
703 }
+
704
+
715#ifndef _WIN32
+
716 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
717#endif
+
718 inline std::string wstr2str(
+
719 _In_z_ const wchar_t* src,
+
720 _In_ charset_id charset = charset_id::system)
+
721 {
+
722 std::string dst;
+
723 strcat(dst, src, SIZE_MAX, charset);
+
724 return dst;
+
725 }
+
726
+
738#ifndef _WIN32
+
739 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
740#endif
+
741 inline std::string wstr2str(
+
742 _In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
+
743 _In_ charset_id charset = charset_id::system)
+
744 {
+
745 std::string dst;
+
746 strcat(dst, src, count_src, charset);
+
747 return dst;
+
748 }
+
749
+
760#ifndef _WIN32
+
761 _Deprecated_("For better performance, consider a reusable charset_encoder")
+
762#endif
+
763 inline std::string wstr2str(
+
764 _In_ const std::wstring& src,
+
765 _In_ charset_id charset = charset_id::system)
+
766 {
+
767 return wstr2str(src.c_str(), src.size(), charset);
+
768 }
+
769}
+
Encoding converter context.
Definition unicode.hpp:64
+
void strcpy(std::basic_string< T_to, _Traits_to, _Alloc_to > &dst, const std::basic_string< T_from, _Traits_from, _Alloc_from > &src)
Convert string.
Definition unicode.hpp:301
+
std::basic_string< T_to, _Traits_to, _Alloc_to > convert(const std::basic_string< T_from, _Traits_from, _Alloc_from > &src)
Return converted string.
Definition unicode.hpp:339
+
std::basic_string< T_to, _Traits_to, _Alloc_to > convert(const T_from *src)
Return converted string.
Definition unicode.hpp:328
+
void strcat(std::basic_string< T_to, _Traits_to, _Alloc_to > &dst, const std::basic_string< T_from, _Traits_from, _Alloc_from > &src)
Convert string and append to string.
Definition unicode.hpp:257
+
void strcpy(std::basic_string< T_to, _Traits_to, _Alloc_to > &dst, const T_from *src)
Convert string.
Definition unicode.hpp:287
+
void strcat(std::basic_string< T_to, _Traits_to, _Alloc_to > &dst, _In_reads_or_z_opt_(count_src) const T_from *src, size_t count_src)
Convert string and append to string.
Definition unicode.hpp:101
+
void strcat(std::basic_string< T_to, _Traits_to, _Alloc_to > &dst, const T_from *src)
Convert string and append to string.
Definition unicode.hpp:243
+
void strcpy(std::basic_string< T_to, _Traits_to, _Alloc_to > &dst, _In_reads_or_z_opt_(count_src) const T_from *src, size_t count_src)
Convert string.
Definition unicode.hpp:272
+
std::basic_string< T_to, _Traits_to, _Alloc_to > convert(_In_reads_or_z_opt_(count_src) const T_from *src, size_t count_src)
Return converted string.
Definition unicode.hpp:315
diff --git a/unionstdex_1_1md2__t-members.html b/unionstdex_1_1md2__t-members.html index b761bc27f..95c86e18e 100644 --- a/unionstdex_1_1md2__t-members.html +++ b/unionstdex_1_1md2__t-members.html @@ -89,7 +89,7 @@ $(function() {
diff --git a/unionstdex_1_1md2__t.html b/unionstdex_1_1md2__t.html index a1c326db2..1ff8b83f8 100644 --- a/unionstdex_1_1md2__t.html +++ b/unionstdex_1_1md2__t.html @@ -123,7 +123,7 @@ Friends
diff --git a/unionstdex_1_1sha256__t-members.html b/unionstdex_1_1sha256__t-members.html index e64d85d99..fbb2290ba 100644 --- a/unionstdex_1_1sha256__t-members.html +++ b/unionstdex_1_1sha256__t-members.html @@ -89,7 +89,7 @@ $(function() {
diff --git a/unionstdex_1_1sha256__t.html b/unionstdex_1_1sha256__t.html index 3efb778d0..cbbf4643a 100644 --- a/unionstdex_1_1sha256__t.html +++ b/unionstdex_1_1sha256__t.html @@ -123,7 +123,7 @@ Friends
diff --git a/unionstdex_1_1sha__t-members.html b/unionstdex_1_1sha__t-members.html index 3bc6016a9..97b173301 100644 --- a/unionstdex_1_1sha__t-members.html +++ b/unionstdex_1_1sha__t-members.html @@ -89,7 +89,7 @@ $(function() {
diff --git a/unionstdex_1_1sha__t.html b/unionstdex_1_1sha__t.html index 3b8426145..3f864f60c 100644 --- a/unionstdex_1_1sha__t.html +++ b/unionstdex_1_1sha__t.html @@ -123,7 +123,7 @@ Friends
diff --git a/vector__queue_8hpp_source.html b/vector__queue_8hpp_source.html index eabe3ac65..eca444e6a 100644 --- a/vector__queue_8hpp_source.html +++ b/vector__queue_8hpp_source.html @@ -451,7 +451,7 @@ $(document).ready(function() { init_codefold(0); });
diff --git a/watchdog_8cpp_source.html b/watchdog_8cpp_source.html index 3afb8da41..642c7cccc 100644 --- a/watchdog_8cpp_source.html +++ b/watchdog_8cpp_source.html @@ -118,7 +118,7 @@ $(document).ready(function() { init_codefold(0); });
diff --git a/watchdog_8hpp_source.html b/watchdog_8hpp_source.html index bc6e03aef..9cf18ee4b 100644 --- a/watchdog_8hpp_source.html +++ b/watchdog_8hpp_source.html @@ -176,7 +176,7 @@ $(document).ready(function() { init_codefold(0); });