From fb48534e0a6cd8490bc476cfcad4a8a027a7bf33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Kubern=C3=A1t?= Date: Mon, 21 Oct 2024 13:04:25 +0200 Subject: [PATCH] Move DateTime out of RpcValue --- .../include/shv/chainpack/rpcvalue.h | 132 +++++++++--------- libshvchainpack/src/rpcvalue.cpp | 56 ++++---- 2 files changed, 95 insertions(+), 93 deletions(-) diff --git a/libshvchainpack/include/shv/chainpack/rpcvalue.h b/libshvchainpack/include/shv/chainpack/rpcvalue.h index 985f4069f..0af11054f 100644 --- a/libshvchainpack/include/shv/chainpack/rpcvalue.h +++ b/libshvchainpack/include/shv/chainpack/rpcvalue.h @@ -77,10 +77,70 @@ class CowPtr class RpcList; +class SHVCHAINPACK_DECL_EXPORT RpcDateTime +{ +public: + enum class MsecPolicy {Auto = 0, Always, Never}; + static constexpr bool IncludeTimeZone = true; +public: + RpcDateTime(); + int64_t msecsSinceEpoch() const; + int utcOffsetMin() const; + bool isZero() const; + + static RpcDateTime now(); + static RpcDateTime fromLocalString(const std::string &local_date_time_str); + static RpcDateTime fromUtcString(const std::string &utc_date_time_str, size_t *plen = nullptr); + static RpcDateTime fromMSecsSinceEpoch(int64_t msecs, int utc_offset_min = 0); + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + void setMsecsSinceEpoch(int64_t msecs); + void setUtcOffsetMin(int utc_offset_min); +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + + std::string toLocalString() const; + std::string toIsoString() const; + std::string toIsoString(MsecPolicy msec_policy, bool include_tz) const; + + struct SHVCHAINPACK_DECL_EXPORT Parts + { + int year = 0; + int month = 0; // 1-12 + int day = 0; // 1-31 + int hour = 0; // 0-23 + int min = 0; // 0-59 + int sec = 0; // 0-59 + int msec = 0; // 0-999 + + Parts(); + Parts(int y, int m, int d, int h = 0, int mn = 0, int s = 0, int ms = 0); + + bool isValid() const; + bool operator==(const Parts &o) const; + }; + Parts toParts() const; + static RpcDateTime fromParts(const Parts &parts); + + bool operator ==(const RpcDateTime &o) const; + bool operator <(const RpcDateTime &o) const; + bool operator >=(const RpcDateTime &o) const; + bool operator >(const RpcDateTime &o) const; + bool operator <=(const RpcDateTime &o) const; +private: + struct MsTz { + int64_t tz: 7, msec: 57; + }; + MsTz m_dtm = {0, 0}; +}; + class SHVCHAINPACK_DECL_EXPORT RpcValue { public: - using List = RpcList; enum class Type { Invalid, @@ -105,6 +165,8 @@ class SHVCHAINPACK_DECL_EXPORT RpcValue using UInt = unsigned; //uint64_t; using Double = double; using Bool = bool; + using List = RpcList; + using DateTime = RpcDateTime; class SHVCHAINPACK_DECL_EXPORT Decimal { static constexpr int Base = 10; @@ -131,66 +193,6 @@ class SHVCHAINPACK_DECL_EXPORT RpcValue std::string toString() const; bool operator==(const Decimal&) const = default; }; - class SHVCHAINPACK_DECL_EXPORT DateTime - { - public: - enum class MsecPolicy {Auto = 0, Always, Never}; - static constexpr bool IncludeTimeZone = true; - public: - DateTime(); - int64_t msecsSinceEpoch() const; - int utcOffsetMin() const; - bool isZero() const; - - static DateTime now(); - static DateTime fromLocalString(const std::string &local_date_time_str); - static DateTime fromUtcString(const std::string &utc_date_time_str, size_t *plen = nullptr); - static DateTime fromMSecsSinceEpoch(int64_t msecs, int utc_offset_min = 0); - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - void setMsecsSinceEpoch(int64_t msecs); - void setUtcOffsetMin(int utc_offset_min); -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - - std::string toLocalString() const; - std::string toIsoString() const; - std::string toIsoString(MsecPolicy msec_policy, bool include_tz) const; - - struct SHVCHAINPACK_DECL_EXPORT Parts - { - int year = 0; - int month = 0; // 1-12 - int day = 0; // 1-31 - int hour = 0; // 0-23 - int min = 0; // 0-59 - int sec = 0; // 0-59 - int msec = 0; // 0-999 - - Parts(); - Parts(int y, int m, int d, int h = 0, int mn = 0, int s = 0, int ms = 0); - - bool isValid() const; - bool operator==(const Parts &o) const; - }; - Parts toParts() const; - static DateTime fromParts(const Parts &parts); - - bool operator ==(const DateTime &o) const; - bool operator <(const DateTime &o) const; - bool operator >=(const DateTime &o) const; - bool operator >(const DateTime &o) const; - bool operator <=(const DateTime &o) const; - private: - struct MsTz { - int64_t tz: 7, msec: 57; - }; - MsTz m_dtm = {0, 0}; - }; using String = std::string; using Blob = std::vector; @@ -285,7 +287,7 @@ class SHVCHAINPACK_DECL_EXPORT RpcValue RpcValue(unsigned long long value); // UInt RpcValue(double value); // Double RpcValue(const Decimal& value); // Decimal - RpcValue(const DateTime &value); + RpcValue(const RpcDateTime &value); RpcValue(const uint8_t *value, size_t size); RpcValue(const RpcValue::Blob &value); // String @@ -357,7 +359,7 @@ class SHVCHAINPACK_DECL_EXPORT RpcValue int64_t toInt64() const; uint64_t toUInt64() const; bool toBool() const; - DateTime toDateTime() const; + RpcDateTime toDateTime() const; RpcValue::String toString() const; const RpcValue::String &asString() const; @@ -381,7 +383,7 @@ class SHVCHAINPACK_DECL_EXPORT RpcValue return toUInt(); else if constexpr (std::is_same()) return asString(); - else if constexpr (std::is_same()) + else if constexpr (std::is_same()) return toDateTime(); else if constexpr (std::is_same()) return toDecimal(); @@ -401,7 +403,7 @@ class SHVCHAINPACK_DECL_EXPORT RpcValue return isUInt(); else if constexpr (std::is_same()) return isString(); - else if constexpr (std::is_same()) + else if constexpr (std::is_same()) return isDateTime(); else if constexpr (std::is_same()) return isDecimal(); diff --git a/libshvchainpack/src/rpcvalue.cpp b/libshvchainpack/src/rpcvalue.cpp index bc0cb08dc..6c6aa2c66 100644 --- a/libshvchainpack/src/rpcvalue.cpp +++ b/libshvchainpack/src/rpcvalue.cpp @@ -939,27 +939,27 @@ long long parse_ISO_DateTime(const std::string &s, std::tm &tm, int &msec, int64 } } -RpcValue::DateTime::DateTime() +RpcDateTime::RpcDateTime() : m_dtm{0, 0} { } -int64_t RpcValue::DateTime::msecsSinceEpoch() const +int64_t RpcDateTime::msecsSinceEpoch() const { return m_dtm.msec; } -int RpcValue::DateTime::utcOffsetMin() const +int RpcDateTime::utcOffsetMin() const { return m_dtm.tz * 15; } -bool RpcValue::DateTime::isZero() const +bool RpcDateTime::isZero() const { return msecsSinceEpoch() == 0; } -RpcValue::DateTime RpcValue::DateTime::now() +RpcDateTime RpcDateTime::now() { std::chrono::time_point p1 = std::chrono::system_clock::now(); int64_t msecs = std::chrono::duration_cast(p1.time_since_epoch()).count(); @@ -972,7 +972,7 @@ RpcValue::DateTime RpcValue::DateTime::fromLocalString(const std::string &local_ int msec; int64_t epoch_msec; int utc_offset; - DateTime ret; + RpcDateTime ret; if(!parse_ISO_DateTime(local_date_time_str, tm, msec, epoch_msec, utc_offset)) { nError() << "Invalid date time string:" << local_date_time_str; return ret; @@ -992,18 +992,18 @@ RpcValue::DateTime RpcValue::DateTime::fromLocalString(const std::string &local_ return ret; } -RpcValue::DateTime RpcValue::DateTime::fromUtcString(const std::string &utc_date_time_str, size_t *plen) +RpcDateTime RpcDateTime::fromUtcString(const std::string &utc_date_time_str, size_t *plen) { if(utc_date_time_str.empty()) { if(plen) *plen = 0; - return DateTime(); + return RpcDateTime(); } std::tm tm; int msec; int64_t epoch_msec; int utc_offset; - DateTime ret; + RpcDateTime ret; auto len = parse_ISO_DateTime(utc_date_time_str, tm, msec, epoch_msec, utc_offset); if(len == 0) { nInfo() << "Invalid date time string:" << utc_date_time_str; @@ -1020,15 +1020,15 @@ RpcValue::DateTime RpcValue::DateTime::fromUtcString(const std::string &utc_date return ret; } -RpcValue::DateTime RpcValue::DateTime::fromMSecsSinceEpoch(int64_t msecs, int utc_offset_min) +RpcDateTime RpcDateTime::fromMSecsSinceEpoch(int64_t msecs, int utc_offset_min) { - DateTime ret; + RpcDateTime ret; ret.setMsecsSinceEpoch(msecs); ret.setUtcOffsetMin(utc_offset_min); return ret; } -void RpcValue::DateTime::setMsecsSinceEpoch(int64_t msecs) +void RpcDateTime::setMsecsSinceEpoch(int64_t msecs) { #ifdef __GNUC__ #pragma GCC diagnostic push @@ -1040,7 +1040,7 @@ void RpcValue::DateTime::setMsecsSinceEpoch(int64_t msecs) #endif } -void RpcValue::DateTime::setUtcOffsetMin(int utc_offset_min) +void RpcDateTime::setUtcOffsetMin(int utc_offset_min) { #ifdef __GNUC__ #pragma GCC diagnostic push @@ -1052,7 +1052,7 @@ void RpcValue::DateTime::setUtcOffsetMin(int utc_offset_min) #endif } -std::string RpcValue::DateTime::toLocalString() const +std::string RpcDateTime::toLocalString() const { std::time_t tim = m_dtm.msec / 1000 + m_dtm.tz * 15 * 60; std::tm *tm = std::localtime(&tim); @@ -1069,12 +1069,12 @@ std::string RpcValue::DateTime::toLocalString() const return ret; } -std::string RpcValue::DateTime::toIsoString() const +std::string RpcDateTime::toIsoString() const { return toIsoString(MsecPolicy::Auto, IncludeTimeZone); } -std::string RpcValue::DateTime::toIsoString(RpcValue::DateTime::MsecPolicy msec_policy, bool include_tz) const +std::string RpcDateTime::toIsoString(RpcDateTime::MsecPolicy msec_policy, bool include_tz) const { ccpcp_pack_context ctx; std::array buff; @@ -1083,14 +1083,14 @@ std::string RpcValue::DateTime::toIsoString(RpcValue::DateTime::MsecPolicy msec_ return std::string(buff.data(), ctx.current); } -RpcValue::DateTime::Parts::Parts() = default; +RpcDateTime::Parts::Parts() = default; -RpcValue::DateTime::Parts::Parts(int y, int m, int d, int h, int mn, int s, int ms) +RpcDateTime::Parts::Parts(int y, int m, int d, int h, int mn, int s, int ms) : year(y), month(m), day(d), hour(h), min(mn), sec(s), msec(ms) { } -bool RpcValue::DateTime::Parts::isValid() const +bool RpcDateTime::Parts::isValid() const { return year >= 1970 @@ -1102,7 +1102,7 @@ bool RpcValue::DateTime::Parts::isValid() const && msec >= 0 && msec <= 999; } -bool RpcValue::DateTime::Parts::operator==(const Parts &o) const +bool RpcDateTime::Parts::operator==(const Parts &o) const { return year == o.year @@ -1114,14 +1114,14 @@ bool RpcValue::DateTime::Parts::operator==(const Parts &o) const && msec == o.msec; } -RpcValue::DateTime::Parts RpcValue::DateTime::toParts() const +RpcDateTime::Parts RpcDateTime::toParts() const { struct tm tm; ccpon_gmtime(msecsSinceEpoch() / 1000 + utcOffsetMin() * 60, &tm); return Parts {tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, static_cast(msecsSinceEpoch() % 1000)}; } -RpcValue::DateTime RpcValue::DateTime::fromParts(const Parts &parts) +RpcDateTime RpcDateTime::fromParts(const Parts &parts) { if (parts.isValid()) { struct tm tm; @@ -1132,32 +1132,32 @@ RpcValue::DateTime RpcValue::DateTime::fromParts(const Parts &parts) tm.tm_min = parts.min; tm.tm_sec = parts.sec; auto msec = ccpon_timegm(&tm) * 1000 + parts.msec; - return DateTime::fromMSecsSinceEpoch(msec); + return RpcDateTime::fromMSecsSinceEpoch(msec); } return {}; } -bool RpcValue::DateTime::operator==(const DateTime &o) const +bool RpcDateTime::operator==(const RpcDateTime &o) const { return (m_dtm.msec == o.m_dtm.msec); } -bool RpcValue::DateTime::operator<(const DateTime &o) const +bool RpcDateTime::operator<(const RpcDateTime &o) const { return m_dtm.msec < o.m_dtm.msec; } -bool RpcValue::DateTime::operator>=(const DateTime &o) const +bool RpcDateTime::operator>=(const RpcDateTime &o) const { return !(*this < o); } -bool RpcValue::DateTime::operator>(const DateTime &o) const +bool RpcDateTime::operator>(const RpcDateTime &o) const { return m_dtm.msec > o.m_dtm.msec; } -bool RpcValue::DateTime::operator<=(const DateTime &o) const +bool RpcDateTime::operator<=(const RpcDateTime &o) const { return !(*this > o); }