[haiku-commits] Change in haiku[master]: libroot: implement timegm calling the ICU backend

  • From: Gerrit <review@xxxxxxxxxxxxxxxxxxx>
  • To: waddlesplash <waddlesplash@xxxxxxxxx>, haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 21 Feb 2021 11:17:53 +0000

From Jérôme Duval <jerome.duval@xxxxxxxxx>:

Jérôme Duval has uploaded this change for review. ( 
https://review.haiku-os.org/c/haiku/+/3748 ;)


Change subject: libroot: implement timegm calling the ICU backend
......................................................................

libroot: implement timegm calling the ICU backend
---
M headers/private/libroot/locale/ICULocaleBackend.h
M headers/private/libroot/locale/ICUTimeConversion.h
M headers/private/libroot/locale/LocaleBackend.h
M src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
M src/system/libroot/add-ons/icu/ICUTimeConversion.cpp
M src/system/libroot/posix/time/localtime.cpp
M src/system/libroot/posix/time/localtime_fading_out.c
7 files changed, 82 insertions(+), 22 deletions(-)



  git pull ssh://git.haiku-os.org:22/haiku refs/changes/48/3748/1

diff --git a/headers/private/libroot/locale/ICULocaleBackend.h 
b/headers/private/libroot/locale/ICULocaleBackend.h
index 72e3ef9..1d5f5f4 100644
--- a/headers/private/libroot/locale/ICULocaleBackend.h
+++ b/headers/private/libroot/locale/ICULocaleBackend.h
@@ -73,6 +73,8 @@

        virtual status_t                        Mktime(struct tm* inOutTm, 
time_t& timeOut);

+       virtual status_t                        Timegm(struct tm* inOutTm, 
time_t& timeOut);
+
 private:
                        const char*                     _QueryLocale(int 
category);
                        const char*                     _SetPosixLocale(int 
category);
diff --git a/headers/private/libroot/locale/ICUTimeConversion.h 
b/headers/private/libroot/locale/ICUTimeConversion.h
index c7b2b38..8fb9b4f 100644
--- a/headers/private/libroot/locale/ICUTimeConversion.h
+++ b/headers/private/libroot/locale/ICUTimeConversion.h
@@ -34,11 +34,17 @@

                        status_t                        Mktime(struct tm* 
inOutTm, time_t& timeOut);

+                       status_t                        Timegm(struct tm* 
inOutTm, time_t& timeOut);
+
 private:
                        status_t                        _FillTmValues(const 
U_NAMESPACE_QUALIFIER
                                                                                
TimeZone* icuTimeZone,
                                                                        const 
time_t* inTime, struct tm* tmOut);

+                       status_t                        _Mktime(const 
U_NAMESPACE_QUALIFIER
+                                                                               
TimeZone* icuTimeZone,
+                                                                       struct 
tm* inOutTm, time_t& timeOut);
+
                        const ICUTimeData&      fTimeData;

                        TimeConversionDataBridge*       fDataBridge;
diff --git a/headers/private/libroot/locale/LocaleBackend.h 
b/headers/private/libroot/locale/LocaleBackend.h
index 670253c..eb4fc8e 100644
--- a/headers/private/libroot/locale/LocaleBackend.h
+++ b/headers/private/libroot/locale/LocaleBackend.h
@@ -157,6 +157,8 @@
                                                                        struct 
tm* tmOut) = 0;
        virtual status_t                        Mktime(struct tm* inOutTm, 
time_t& timeOut) = 0;

+       virtual status_t                        Timegm(struct tm* inOutTm, 
time_t& timeOut) = 0;
+
        virtual void                            Initialize(LocaleDataBridge* 
dataBridge) = 0;

        static  status_t                        LoadBackend();
diff --git a/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp 
b/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
index 3f226f2..a1c45b7 100644
--- a/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
+++ b/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
@@ -353,6 +353,15 @@
 }


+status_t
+ICULocaleBackend::Timegm(struct tm* inOutTm, time_t& timeOut)
+{
+       ErrnoMaintainer errnoMaintainer;
+
+       return fTimeConversion.Timegm(inOutTm, timeOut);
+}
+
+
 const char*
 ICULocaleBackend::_QueryLocale(int category)
 {
diff --git a/src/system/libroot/add-ons/icu/ICUTimeConversion.cpp 
b/src/system/libroot/add-ons/icu/ICUTimeConversion.cpp
index 1a2d749..5951b6c 100644
--- a/src/system/libroot/add-ons/icu/ICUTimeConversion.cpp
+++ b/src/system/libroot/add-ons/icu/ICUTimeConversion.cpp
@@ -166,25 +166,15 @@
 status_t
 ICUTimeConversion::Mktime(struct tm* inOutTm, time_t& timeOut)
 {
-       if (fTimeZone == NULL)
-               return B_NO_INIT;
+       return _Mktime(fTimeZone, inOutTm, timeOut);
+}

-       UErrorCode icuStatus = U_ZERO_ERROR;
-       GregorianCalendar calendar(*fTimeZone, fTimeData.ICULocale(),
-               icuStatus);
-       if (!U_SUCCESS(icuStatus))
-               return B_ERROR;

-       calendar.setLenient(TRUE);
-       calendar.set(inOutTm->tm_year + 1900, inOutTm->tm_mon, inOutTm->tm_mday,
-               inOutTm->tm_hour, inOutTm->tm_min, inOutTm->tm_sec);
-
-       UDate timeInMillis = calendar.getTime(icuStatus);
-       if (!U_SUCCESS(icuStatus))
-               return B_ERROR;
-       timeOut = (time_t)((int64_t)timeInMillis / 1000);
-
-       return _FillTmValues(fTimeZone, &timeOut, inOutTm);
+status_t
+ICUTimeConversion::Timegm(struct tm* inOutTm, time_t& timeOut)
+{
+       const TimeZone* icuTimeZone = TimeZone::getGMT();
+       return _Mktime(icuTimeZone, inOutTm, timeOut);
 }


@@ -238,5 +228,31 @@
 }


+status_t
+ICUTimeConversion::_Mktime(const TimeZone* icuTimeZone,
+       struct tm* inOutTm, time_t& timeOut)
+{
+       if (icuTimeZone == NULL)
+               return B_NO_INIT;
+
+       UErrorCode icuStatus = U_ZERO_ERROR;
+       GregorianCalendar calendar(*icuTimeZone, fTimeData.ICULocale(),
+               icuStatus);
+       if (!U_SUCCESS(icuStatus))
+               return B_ERROR;
+
+       calendar.setLenient(TRUE);
+       calendar.set(inOutTm->tm_year + 1900, inOutTm->tm_mon, inOutTm->tm_mday,
+               inOutTm->tm_hour, inOutTm->tm_min, inOutTm->tm_sec);
+
+       UDate timeInMillis = calendar.getTime(icuStatus);
+       if (!U_SUCCESS(icuStatus))
+               return B_ERROR;
+       timeOut = (time_t)((int64_t)timeInMillis / 1000);
+
+       return _FillTmValues(icuTimeZone, &timeOut, inOutTm);
+}
+
+
 }      // namespace Libroot
 }      // namespace BPrivate
diff --git a/src/system/libroot/posix/time/localtime.cpp 
b/src/system/libroot/posix/time/localtime.cpp
index cc4a2b4..739712f 100644
--- a/src/system/libroot/posix/time/localtime.cpp
+++ b/src/system/libroot/posix/time/localtime.cpp
@@ -33,10 +33,11 @@
 int daylight = 0;


-// These two functions are used as a fallback when the locale backend could not
+// These three functions are used as a fallback when the locale backend could 
not
 // be loaded. They are implemented in localtime_fading_out.c.
 extern "C" struct tm* __gmtime_r_fallback(const time_t* timep, struct tm* tmp);
 extern "C" time_t __mktime_fallback(struct tm* tmp);
+extern "C" time_t __timegm_fallback(struct tm* tmp);


 extern "C" void
@@ -143,3 +144,29 @@
        // implementation.
        return __mktime_fallback(inTm);
 }
+
+
+extern "C" time_t
+timegm(struct tm* inTm)
+{
+       if (inTm == NULL) {
+               __set_errno(EINVAL);
+               return -1;
+       }
+       tzset();
+       if (gLocaleBackend != NULL) {
+               time_t timeOut;
+               status_t status = gLocaleBackend->Timegm(inTm, timeOut);
+
+               if (status != B_OK) {
+                       __set_errno(EOVERFLOW);
+                       return -1;
+               }
+
+               return timeOut;
+       }
+
+       // without a locale backend, we fall back to using a basic timegm
+       // implementation.
+       return __timegm_fallback(inTm);
+}
diff --git a/src/system/libroot/posix/time/localtime_fading_out.c 
b/src/system/libroot/posix/time/localtime_fading_out.c
index 081254a..5d0a690 100644
--- a/src/system/libroot/posix/time/localtime_fading_out.c
+++ b/src/system/libroot/posix/time/localtime_fading_out.c
@@ -169,7 +169,7 @@
 */
 struct tm* __gmtime_r_fallback(const time_t* timep, struct tm* tmp);
 time_t __mktime_fallback(struct tm* tmp);
-time_t timegm(struct tm* const tmp);
+time_t __timegm_fallback(struct tm* const tmp);

 static struct state    lclmem;
 static struct state    gmtmem;
@@ -831,10 +831,8 @@
 }


-
 time_t
-timegm(tmp)
-struct tm * const      tmp;
+__timegm_fallback(struct tm* const tmp)
 {
        tmp->tm_isdst = 0;
        return time1(tmp, gmtsub, 0L);

--
To view, visit https://review.haiku-os.org/c/haiku/+/3748
To unsubscribe, or for help writing mail filters, visit 
https://review.haiku-os.org/settings

Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: Ib4de4288e061670acbc2edea3671cee029305d33
Gerrit-Change-Number: 3748
Gerrit-PatchSet: 1
Gerrit-Owner: Jérôme Duval <jerome.duval@xxxxxxxxx>
Gerrit-MessageType: newchange

Other related posts:

  • » [haiku-commits] Change in haiku[master]: libroot: implement timegm calling the ICU backend - Gerrit