diff options
Diffstat (limited to '')
-rw-r--r-- | src/ptimec.hh | 263 |
1 files changed, 218 insertions, 45 deletions
diff --git a/src/ptimec.hh b/src/ptimec.hh index 9db6b0c..527b33d 100644 --- a/src/ptimec.hh +++ b/src/ptimec.hh @@ -202,11 +202,6 @@ ftime_a(char* dst, off_t& off_inout, ssize_t len, const struct exttm& tm) } inline void -ftime_Z(char* dst, off_t& off_inout, ssize_t len, const struct exttm& tm) -{ -} - -inline void ftime_b(char* dst, off_t& off_inout, ssize_t len, const struct exttm& tm) { switch (tm.et_tm.tm_mon) { @@ -287,10 +282,13 @@ ptime_S(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) } dst->et_tm.tm_sec = (str[off_inout] - '0') * 10 + (str[off_inout + 1] - '0'); + if (dst->et_tm.tm_sec < 0 || dst->et_tm.tm_sec >= 60) { + return false; + } dst->et_flags |= ETF_SECOND_SET; }); - return (dst->et_tm.tm_sec >= 0 && dst->et_tm.tm_sec <= 59); + return true; } inline void @@ -323,7 +321,7 @@ ptime_s(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) secs2tm(epoch, &dst->et_tm); dst->et_flags = ETF_DAY_SET | ETF_MONTH_SET | ETF_YEAR_SET | ETF_HOUR_SET | ETF_MINUTE_SET | ETF_SECOND_SET | ETF_MACHINE_ORIENTED - | ETF_EPOCH_TIME; + | ETF_EPOCH_TIME | ETF_ZONE_SET; return (epoch > 0); } @@ -381,7 +379,7 @@ ptime_q(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) secs2tm(epoch, &dst->et_tm); dst->et_flags = ETF_DAY_SET | ETF_MONTH_SET | ETF_YEAR_SET | ETF_HOUR_SET | ETF_MINUTE_SET | ETF_SECOND_SET | ETF_MACHINE_ORIENTED - | ETF_EPOCH_TIME; + | ETF_EPOCH_TIME | ETF_ZONE_SET; return (epoch > 0); } @@ -398,20 +396,42 @@ ftime_q(char* dst, off_t& off_inout, ssize_t len, const struct exttm& tm) inline bool ptime_L(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) { + auto avail = len - off_inout; int ms = 0; - PTIME_CONSUME(3, { - char c0 = str[off_inout]; - char c1 = str[off_inout + 1]; - char c2 = str[off_inout + 2]; - if (!isdigit(c0) || !isdigit(c1) || !isdigit(c2)) { - return false; - } - ms = ((str[off_inout] - '0') * 100 + (str[off_inout + 1] - '0') * 10 - + (str[off_inout + 2] - '0')); - }); + if (avail >= 3 && isdigit(str[off_inout + 2])) { + PTIME_CONSUME(3, { + char c0 = str[off_inout]; + char c1 = str[off_inout + 1]; + char c2 = str[off_inout + 2]; + if (!isdigit(c0) || !isdigit(c1) || !isdigit(c2)) { + return false; + } + ms = ((str[off_inout] - '0') * 100 + (str[off_inout + 1] - '0') * 10 + + (str[off_inout + 2] - '0')); + }); + } else if (avail >= 2 && isdigit(str[off_inout + 1])) { + PTIME_CONSUME(2, { + char c0 = str[off_inout]; + char c1 = str[off_inout + 1]; + if (!isdigit(c0) || !isdigit(c1)) { + return false; + } + ms = ((str[off_inout] - '0') * 100 + + (str[off_inout + 1] - '0') * 10); + }); + } else { + PTIME_CONSUME(1, { + char c0 = str[off_inout]; + if (!isdigit(c0)) { + return false; + } + ms = (str[off_inout] - '0') * 100; + }); + } if ((ms >= 0 && ms <= 999)) { + dst->et_flags |= ETF_MILLIS_SET; dst->et_nsec = ms * 1000000; return true; } @@ -457,8 +477,14 @@ ptime_H(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) if (str[off_inout + 1] > '9') { return false; } - dst->et_tm.tm_hour - = (str[off_inout] - '0') * 10 + (str[off_inout + 1] - '0'); + if (isdigit(str[off_inout])) { + dst->et_tm.tm_hour = (str[off_inout] - '0') * 10; + } else if (str[off_inout] == ' ') { + dst->et_tm.tm_hour = 0; + } else { + return false; + } + dst->et_tm.tm_hour += (str[off_inout + 1] - '0'); dst->et_flags |= ETF_HOUR_SET; }); @@ -493,8 +519,9 @@ ptime_i(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) secs2tm(epoch, &dst->et_tm); dst->et_flags = ETF_DAY_SET | ETF_MONTH_SET | ETF_YEAR_SET | ETF_HOUR_SET - | ETF_MINUTE_SET | ETF_SECOND_SET | ETF_MACHINE_ORIENTED - | ETF_EPOCH_TIME; + | ETF_MINUTE_SET | ETF_SECOND_SET | ETF_MILLIS_SET + | ETF_MACHINE_ORIENTED | ETF_EPOCH_TIME | ETF_ZONE_SET + | ETF_SUB_NOT_IN_FORMAT; return (epoch_ms > 0); } @@ -530,8 +557,9 @@ ptime_6(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) secs2tm(epoch, &dst->et_tm); dst->et_flags = ETF_DAY_SET | ETF_MONTH_SET | ETF_YEAR_SET | ETF_HOUR_SET - | ETF_MINUTE_SET | ETF_SECOND_SET | ETF_MACHINE_ORIENTED - | ETF_EPOCH_TIME; + | ETF_MINUTE_SET | ETF_SECOND_SET | ETF_MICROS_SET + | ETF_MACHINE_ORIENTED | ETF_EPOCH_TIME | ETF_ZONE_SET + | ETF_SUB_NOT_IN_FORMAT | ETF_Z_FOR_UTC; return (epoch_us > 0); } @@ -553,8 +581,14 @@ ptime_I(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) if (str[off_inout + 1] > '9') { return false; } - dst->et_tm.tm_hour - = (str[off_inout] - '0') * 10 + (str[off_inout + 1] - '0'); + if (isdigit(str[off_inout])) { + dst->et_tm.tm_hour = (str[off_inout] - '0') * 10; + } else if (str[off_inout] == ' ') { + dst->et_tm.tm_hour = 0; + } else { + return false; + } + dst->et_tm.tm_hour += (str[off_inout + 1] - '0'); if (dst->et_tm.tm_hour < 1 || dst->et_tm.tm_hour > 12) { return false; @@ -725,7 +759,7 @@ ptime_l(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) dst->et_tm.tm_hour = 0; - if ((off_inout + 1) > len) { + if ((off_inout + 1) >= len) { return false; } @@ -734,7 +768,7 @@ ptime_l(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) off_inout += 1; } - if ((off_inout + 1) > len) { + if ((off_inout + 1) >= len) { off_inout = orig_off; return false; } @@ -747,7 +781,13 @@ ptime_l(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) dst->et_tm.tm_hour = str[off_inout] - '0'; off_inout += 1; + if (!consumed_space && (off_inout + 1) >= len) { + off_inout = orig_off; + return false; + } + if (consumed_space || str[off_inout] < '0' || str[off_inout] > '9') { + dst->et_flags |= ETF_HOUR_SET; return true; } @@ -756,11 +796,10 @@ ptime_l(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) off_inout += 1; if (dst->et_tm.tm_hour >= 0 && dst->et_tm.tm_hour <= 23) { + dst->et_flags |= ETF_HOUR_SET; return true; } - dst->et_flags |= ETF_HOUR_SET; - off_inout = orig_off; return false; } @@ -880,8 +919,71 @@ ftime_y(char* dst, off_t& off_inout, ssize_t len, const struct exttm& tm) } inline bool +ptime_Z_upto(struct exttm* dst, + const char* str, + off_t& off_inout, + ssize_t len, + char term) +{ + auto avail = len - off_inout; + + if (avail >= 3 && str[off_inout + 0] == 'U' && str[off_inout + 1] == 'T' + && str[off_inout + 2] == 'C') + { + PTIME_CONSUME(3, { dst->et_flags |= ETF_ZONE_SET | ETF_Z_IS_UTC; }); + dst->et_gmtoff = 0; + return true; + } + if (avail >= 3 && str[off_inout + 0] == 'G' && str[off_inout + 1] == 'M' + && str[off_inout + 2] == 'T') + { + PTIME_CONSUME(3, { dst->et_flags |= ETF_ZONE_SET | ETF_Z_IS_GMT; }); + dst->et_gmtoff = 0; + return true; + } + + return ptime_upto(term, str, off_inout, len); +} + +inline bool +ptime_Z_upto_end(struct exttm* dst, + const char* str, + off_t& off_inout, + ssize_t len) +{ + auto avail = len - off_inout; + + if (avail >= 3 && str[off_inout + 0] == 'U' && str[off_inout + 1] == 'T' + && str[off_inout + 2] == 'C') + { + PTIME_CONSUME(3, { dst->et_flags |= ETF_ZONE_SET | ETF_Z_IS_UTC; }); + dst->et_gmtoff = 0; + return true; + } + if (avail >= 3 && str[off_inout + 0] == 'G' && str[off_inout + 1] == 'M' + && str[off_inout + 2] == 'T') + { + PTIME_CONSUME(3, { dst->et_flags |= ETF_ZONE_SET | ETF_Z_IS_GMT; }); + dst->et_gmtoff = 0; + return true; + } + + return ptime_upto_end(str, off_inout, len); +} + +inline bool ptime_z(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) { + if (off_inout + 1 <= len && str[off_inout] == 'Z') { + off_inout += 1; + dst->et_flags |= ETF_ZONE_SET | ETF_Z_FOR_UTC; +#ifdef HAVE_STRUCT_TM_TM_ZONE + dst->et_tm.tm_gmtoff = 0; +#endif + dst->et_gmtoff = 0; + return true; + } + int consume_amount = 5; if ((off_inout + 6) <= len && str[off_inout + 3] == ':') { @@ -907,6 +1009,10 @@ ptime_z(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) mins = ((str[off_inout + skip_colon + 3] - '0') * 10 + (str[off_inout + skip_colon + 4] - '0') * 1) * 60; + if (skip_colon) { + dst->et_flags |= ETF_Z_COLON; + } + dst->et_flags |= ETF_ZONE_SET; dst->et_gmtoff = sign * (hours + mins); #ifdef HAVE_STRUCT_TM_TM_ZONE dst->et_tm.tm_gmtoff = sign * (hours + mins); @@ -919,6 +1025,15 @@ ptime_z(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) inline void ftime_z(char* dst, off_t& off_inout, ssize_t len, const struct exttm& tm) { + if (!(tm.et_flags & ETF_ZONE_SET)) { + return; + } + + if (tm.et_gmtoff == 0 && tm.et_flags & ETF_Z_FOR_UTC) { + PTIME_APPEND('Z'); + return; + } + long gmtoff = std::abs(tm.et_gmtoff) / 60; if (tm.et_gmtoff < 0) { @@ -932,27 +1047,82 @@ ftime_z(char* dst, off_t& off_inout, ssize_t len, const struct exttm& tm) PTIME_APPEND('0' + ((hours / 10) % 10)); PTIME_APPEND('0' + ((hours / 1) % 10)); + if (tm.et_flags & ETF_Z_COLON) { + PTIME_APPEND(':'); + } PTIME_APPEND('0' + ((mins / 10) % 10)); PTIME_APPEND('0' + ((mins / 1) % 10)); } +inline void +ftime_Z(char* dst, off_t& off_inout, ssize_t len, const struct exttm& tm) +{ + if (tm.et_flags & ETF_Z_IS_UTC) { + PTIME_APPEND('U'); + PTIME_APPEND('T'); + PTIME_APPEND('C'); + } else if (tm.et_flags & ETF_Z_IS_GMT) { + PTIME_APPEND('G'); + PTIME_APPEND('M'); + PTIME_APPEND('T'); + } else if (tm.et_flags & ETF_ZONE_SET) { + ftime_z(dst, off_inout, len, tm); + } +} + inline bool ptime_f(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) { - PTIME_CONSUME(6, { - for (int lpc = 0; lpc < 6; lpc++) { - if (str[off_inout + lpc] < '0' || str[off_inout + lpc] > '9') { - return false; + auto avail = len - off_inout; + + if (avail >= 6 && isdigit(str[off_inout + 4]) + && isdigit(str[off_inout + 5])) + { + PTIME_CONSUME(6, { + for (int lpc = 0; lpc < 6; lpc++) { + if (str[off_inout + lpc] < '0' || str[off_inout + lpc] > '9') { + return false; + } } - } - dst->et_nsec = ((str[off_inout + 0] - '0') * 100000 - + (str[off_inout + 1] - '0') * 10000 - + (str[off_inout + 2] - '0') * 1000 - + (str[off_inout + 3] - '0') * 100 - + (str[off_inout + 4] - '0') * 10 - + (str[off_inout + 5] - '0') * 1) - * 1000; - }); + dst->et_flags |= ETF_MICROS_SET; + dst->et_nsec = ((str[off_inout + 0] - '0') * 100000 + + (str[off_inout + 1] - '0') * 10000 + + (str[off_inout + 2] - '0') * 1000 + + (str[off_inout + 3] - '0') * 100 + + (str[off_inout + 4] - '0') * 10 + + (str[off_inout + 5] - '0') * 1) + * 1000; + }); + } else if (avail >= 5 && isdigit(str[off_inout + 4])) { + PTIME_CONSUME(5, { + for (int lpc = 0; lpc < 5; lpc++) { + if (str[off_inout + lpc] < '0' || str[off_inout + lpc] > '9') { + return false; + } + } + dst->et_flags |= ETF_MICROS_SET; + dst->et_nsec = ((str[off_inout + 0] - '0') * 100000 + + (str[off_inout + 1] - '0') * 10000 + + (str[off_inout + 2] - '0') * 1000 + + (str[off_inout + 3] - '0') * 100 + + (str[off_inout + 4] - '0') * 10) + * 1000; + }); + } else { + PTIME_CONSUME(4, { + for (int lpc = 0; lpc < 4; lpc++) { + if (str[off_inout + lpc] < '0' || str[off_inout + lpc] > '9') { + return false; + } + } + dst->et_flags |= ETF_MICROS_SET; + dst->et_nsec = ((str[off_inout + 0] - '0') * 100000 + + (str[off_inout + 1] - '0') * 10000 + + (str[off_inout + 2] - '0') * 1000 + + (str[off_inout + 3] - '0') * 100) + * 1000; + }); + } return true; } @@ -979,6 +1149,7 @@ ptime_N(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) return false; } } + dst->et_flags |= ETF_NANOS_SET; dst->et_nsec = ((str[off_inout + 0] - '0') * 100000000 + (str[off_inout + 1] - '0') * 10000000 + (str[off_inout + 2] - '0') * 1000000 @@ -1082,8 +1253,8 @@ ptime_at(struct exttm* dst, const char* str, off_t& off_inout, ssize_t len) } dst->et_flags |= ETF_DAY_SET | ETF_MONTH_SET | ETF_YEAR_SET | ETF_HOUR_SET - | ETF_MINUTE_SET | ETF_SECOND_SET | ETF_MACHINE_ORIENTED - | ETF_EPOCH_TIME; + | ETF_MINUTE_SET | ETF_SECOND_SET | ETF_NANOS_SET | ETF_MACHINE_ORIENTED + | ETF_EPOCH_TIME | ETF_ZONE_SET; return true; } @@ -1116,4 +1287,6 @@ extern struct ptime_fmt PTIMEC_FORMATS[]; extern const char* PTIMEC_FORMAT_STR[]; +extern size_t PTIMEC_DEFAULT_FMT_INDEX; + #endif |