|
9 | 9 | #include "types.hpp"
|
10 | 10 |
|
11 | 11 | // + standard includes
|
12 |
| -#include <regex> |
13 | 12 | #include <sstream>
|
14 | 13 |
|
15 | 14 | // *****************************************************************************
|
@@ -895,39 +894,83 @@ int TimeValue::read(const std::string& buf) {
|
895 | 894 | // https://web.archive.org/web/20171020084445/https://www.loc.gov/standards/datetime/ISO_DIS%208601-1.pdf
|
896 | 895 | // Not supported formats:
|
897 | 896 | // 4.2.2.4 Representations with decimal fraction: 232050,5
|
898 |
| - static const std::regex re(R"(^(2[0-3]|[01][0-9]):?([0-5][0-9])?:?([0-5][0-9])?$)"); |
899 |
| - static const std::regex reExt( |
900 |
| - R"(^(2[0-3]|[01][0-9]):?([0-5][0-9]):?([0-5][0-9])(Z|[+-](?:2[0-3]|[01][0-9])(?::?(?:[0-5][0-9]))?)$)"); |
901 |
| - |
902 |
| - if (std::smatch sm; std::regex_match(buf, sm, re) || std::regex_match(buf, sm, reExt)) { |
903 |
| - time_.hour = sm.length(1) ? std::stoi(sm[1].str()) : 0; |
904 |
| - time_.minute = sm.length(2) ? std::stoi(sm[2].str()) : 0; |
905 |
| - time_.second = sm.length(3) ? std::stoi(sm[3].str()) : 0; |
906 |
| - if (sm.size() > 4) { |
907 |
| - std::string str = sm[4].str(); |
908 |
| - const auto strSize = str.size(); |
909 |
| - auto posColon = str.find(':'); |
910 |
| - |
911 |
| - if (posColon == std::string::npos) { |
912 |
| - // Extended format |
913 |
| - time_.tzHour = std::stoi(str.substr(0, 3)); |
914 |
| - if (strSize > 3) { |
915 |
| - int minute = std::stoi(str.substr(3)); |
916 |
| - time_.tzMinute = time_.tzHour < 0 ? -minute : minute; |
917 |
| - } |
918 |
| - } else { |
919 |
| - // Basic format |
920 |
| - time_.tzHour = std::stoi(str.substr(0, posColon)); |
921 |
| - int minute = std::stoi(str.substr(posColon + 1)); |
| 897 | + auto printWarning = [] { |
| 898 | +#ifndef SUPPRESS_WARNINGS |
| 899 | + EXV_WARNING << Error(ErrorCode::kerUnsupportedTimeFormat) << "\n"; |
| 900 | +#endif |
| 901 | + return 1; |
| 902 | + }; |
| 903 | + |
| 904 | + if (buf.size() < 2) |
| 905 | + return printWarning(); |
| 906 | + |
| 907 | + for (auto c : buf) |
| 908 | + if (c != ':' && c != '+' && c != '-' && c != 'Z' && !std::isdigit(c)) |
| 909 | + return printWarning(); |
| 910 | + |
| 911 | + size_t mpos; |
| 912 | + size_t spos; |
| 913 | + if (buf.find(':') != std::string::npos) { |
| 914 | + mpos = 3; |
| 915 | + spos = 6; |
| 916 | + } else { |
| 917 | + mpos = 2; |
| 918 | + spos = 4; |
| 919 | + } |
| 920 | + |
| 921 | + auto hi = std::stoi(buf.substr(0, 2)); |
| 922 | + if (hi > 23) |
| 923 | + return printWarning(); |
| 924 | + time_.hour = hi; |
| 925 | + if (buf.size() > 3) { |
| 926 | + auto mi = std::stoi(buf.substr(mpos, 2)); |
| 927 | + if (mi > 59) |
| 928 | + return printWarning(); |
| 929 | + time_.minute = std::stoi(buf.substr(mpos, 2)); |
| 930 | + } else { |
| 931 | + time_.minute = 0; |
| 932 | + } |
| 933 | + if (buf.size() > 5) { |
| 934 | + auto si = std::stoi(buf.substr(spos, 2)); |
| 935 | + if (si > 60) |
| 936 | + return printWarning(); |
| 937 | + time_.second = std::stoi(buf.substr(spos, 2)); |
| 938 | + } else { |
| 939 | + time_.second = 0; |
| 940 | + } |
| 941 | + |
| 942 | + auto fpos = buf.find('+'); |
| 943 | + if (fpos == std::string::npos) |
| 944 | + fpos = buf.find('-'); |
| 945 | + |
| 946 | + if (fpos != std::string::npos) { |
| 947 | + auto format = buf.substr(fpos, buf.size()); |
| 948 | + auto posColon = format.find(':'); |
| 949 | + if (posColon == std::string::npos) { |
| 950 | + // Extended format |
| 951 | + auto tzhi = std::stoi(format.substr(0, 3)); |
| 952 | + if (tzhi > 23) |
| 953 | + return printWarning(); |
| 954 | + time_.tzHour = tzhi; |
| 955 | + if (format.size() > 3) { |
| 956 | + int minute = std::stoi(format.substr(3)); |
| 957 | + if (minute > 59) |
| 958 | + return printWarning(); |
922 | 959 | time_.tzMinute = time_.tzHour < 0 ? -minute : minute;
|
923 | 960 | }
|
| 961 | + } else { |
| 962 | + // Basic format |
| 963 | + auto tzhi = std::stoi(format.substr(0, posColon)); |
| 964 | + if (tzhi > 23) |
| 965 | + return printWarning(); |
| 966 | + time_.tzHour = tzhi; |
| 967 | + int minute = std::stoi(format.substr(posColon + 1)); |
| 968 | + if (minute > 59) |
| 969 | + return printWarning(); |
| 970 | + time_.tzMinute = time_.tzHour < 0 ? -minute : minute; |
924 | 971 | }
|
925 |
| - return 0; |
926 | 972 | }
|
927 |
| -#ifndef SUPPRESS_WARNINGS |
928 |
| - EXV_WARNING << Error(ErrorCode::kerUnsupportedTimeFormat) << "\n"; |
929 |
| -#endif |
930 |
| - return 1; |
| 973 | + return 0; |
931 | 974 | }
|
932 | 975 |
|
933 | 976 | /// \todo not used internally. At least we should test it
|
|
0 commit comments