hrev54962 adds 1 changeset to branch 'master'
old head: 02ccdc6fa15523ba65c224f605c3c06476b27b4b
new head: c1e6e51a05d569622330492ffcaa50494d31737c
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=c1e6e51a05d5+%5E02ccdc6fa155
----------------------------------------------------------------------------
c1e6e51a05d5: libroot: implement timegm calling the ICU backend
Change-Id: Ib4de4288e061670acbc2edea3671cee029305d33
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3748
Reviewed-by: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
[ Jérôme Duval <jerome.duval@xxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev54962
Commit: c1e6e51a05d569622330492ffcaa50494d31737c
URL: https://git.haiku-os.org/haiku/commit/?id=c1e6e51a05d5
Author: Jérôme Duval <jerome.duval@xxxxxxxxx>
Date: Sun Feb 21 11:10:47 2021 UTC
----------------------------------------------------------------------------
7 files changed, 82 insertions(+), 22 deletions(-)
.../private/libroot/locale/ICULocaleBackend.h | 2 +
.../private/libroot/locale/ICUTimeConversion.h | 6 +++
headers/private/libroot/locale/LocaleBackend.h | 2 +
.../libroot/add-ons/icu/ICULocaleBackend.cpp | 9 ++++
.../libroot/add-ons/icu/ICUTimeConversion.cpp | 50 +++++++++++++-------
src/system/libroot/posix/time/localtime.cpp | 29 +++++++++++-
.../libroot/posix/time/localtime_fading_out.c | 6 +--
----------------------------------------------------------------------------
diff --git a/headers/private/libroot/locale/ICULocaleBackend.h
b/headers/private/libroot/locale/ICULocaleBackend.h
index 72e3ef96b6..1d5f5f4807 100644
--- a/headers/private/libroot/locale/ICULocaleBackend.h
+++ b/headers/private/libroot/locale/ICULocaleBackend.h
@@ -73,6 +73,8 @@ public:
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 c7b2b38315..8fb9b4f862 100644
--- a/headers/private/libroot/locale/ICUTimeConversion.h
+++ b/headers/private/libroot/locale/ICUTimeConversion.h
@@ -34,11 +34,17 @@ public:
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 670253c4b7..eb4fc8e8eb 100644
--- a/headers/private/libroot/locale/LocaleBackend.h
+++ b/headers/private/libroot/locale/LocaleBackend.h
@@ -157,6 +157,8 @@ public:
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 3f226f29a6..a1c45b705a 100644
--- a/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
+++ b/src/system/libroot/add-ons/icu/ICULocaleBackend.cpp
@@ -353,6 +353,15 @@ ICULocaleBackend::Mktime(struct tm* inOutTm, time_t&
timeOut)
}
+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 1a2d749e2b..5951b6c50b 100644
--- a/src/system/libroot/add-ons/icu/ICUTimeConversion.cpp
+++ b/src/system/libroot/add-ons/icu/ICUTimeConversion.cpp
@@ -166,25 +166,15 @@ ICUTimeConversion::Gmtime(const time_t* inTime, struct
tm* tmOut)
status_t
ICUTimeConversion::Mktime(struct tm* inOutTm, time_t& timeOut)
{
- if (fTimeZone == NULL)
- return B_NO_INIT;
-
- 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);
+ return _Mktime(fTimeZone, inOutTm, timeOut);
+}
- 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 @@ ICUTimeConversion::_FillTmValues(const TimeZone*
icuTimeZone,
}
+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 cc4a2b49e2..739712fb81 100644
--- a/src/system/libroot/posix/time/localtime.cpp
+++ b/src/system/libroot/posix/time/localtime.cpp
@@ -33,10 +33,11 @@ long timezone = 0;
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 @@ mktime(struct tm* inTm)
// 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 081254a401..5d0a690f94 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 @@ static int tmcomp P((const struct tm * atmp,
*/
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 @@ __mktime_fallback(struct tm* tmp)
}
-
time_t
-timegm(tmp)
-struct tm * const tmp;
+__timegm_fallback(struct tm* const tmp)
{
tmp->tm_isdst = 0;
return time1(tmp, gmtsub, 0L);