* introduced stubbed TimeBackend to libroot, which will contain implementations

of localtime(), gmtime() and mktime()
* implemented tzset() to read the required info from libroot_timezone_info

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37935 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe 2010-08-05 21:50:26 +00:00
parent 85b54438f7
commit 562ccb03cc
8 changed files with 307 additions and 1 deletions

View File

@ -0,0 +1,32 @@
/*
* Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _ICU_TIME_BACKEND_H
#define _ICU_TIME_BACKEND_H
#include <TimeBackend.h>
namespace BPrivate {
class ICUTimeBackend : public TimeBackend {
public:
ICUTimeBackend();
virtual ~ICUTimeBackend();
virtual const status_t TZSet();
virtual void Initialize(TimeDataBridge* dataBridge);
private:
TimeDataBridge fDataBridge;
};
} // namespace BPrivate
#endif // _ICU_TIME_BACKEND_H

View File

@ -0,0 +1,43 @@
/*
* Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _TIME_BACKEND_H
#define _TIME_BACKEND_H
#include <SupportDefs.h>
namespace BPrivate {
struct TimeDataBridge {
int* addrOfDaylight;
long* addrOfTimezone;
char** addrOfTZName;
TimeDataBridge();
};
class TimeBackend {
public:
TimeBackend();
virtual ~TimeBackend();
virtual const status_t TZSet() = 0;
virtual void Initialize(TimeDataBridge* dataBridge) = 0;
static status_t LoadBackend();
};
extern TimeBackend* gTimeBackend;
} // namespace BPrivate
#endif // _TIME_BACKEND_H

View File

@ -0,0 +1,85 @@
/*
* Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de.
* Distributed under the terms of the MIT License.
*/
#include "ICUTimeBackend.h"
#include <new>
#include <string.h>
#include <unicode/timezone.h>
#include <ErrnoMaintainer.h>
namespace BPrivate {
extern "C" TimeBackend*
CreateInstance()
{
return new(std::nothrow) ICUTimeBackend();
}
ICUTimeBackend::ICUTimeBackend()
{
}
ICUTimeBackend::~ICUTimeBackend()
{
}
void
ICUTimeBackend::Initialize(TimeDataBridge* dataBridge)
{
fDataBridge = dataBridge;
}
void
ICUTimeBackend::TZSet(void)
{
ErrnoMaintainer errnoMaintainer;
TimeZone* icuTimeZone;
if (zoneCode == NULL || zoneCode[0] == '\0')
icuTimeZone = TimeZone::createDefault();
else
icuTimeZone = TimeZone::createTimeZone(zoneCode);
UnicodeString unicodeString;
icuTimeZone->getID(unicodeString);
BStringByteSink converter(&fCode);
unicodeString.toUTF8(converter);
unicodeString.remove();
icuTimeZone->getDisplayName(unicodeString);
converter.SetTo(&fName);
unicodeString.toUTF8(converter);
int32_t rawOffset;
int32_t dstOffset;
UDate nowMillis = 1000 * (double)time(NULL);
UErrorCode error = U_ZERO_ERROR;
icuTimeZone->getOffset(nowMillis, FALSE, rawOffset, dstOffset, error);
if (!U_SUCCESS(error)) {
fOffsetFromGMT = 0;
fInitStatus = B_ERROR;
} else {
fOffsetFromGMT = (rawOffset + dstOffset) / 1000;
// we want seconds, not ms (which ICU gives us)
fInitStatus = B_OK;
}
delete icuTimeZone;
}
} // namespace BPrivate

View File

@ -13,7 +13,8 @@ MergeObject posix_time.o :
clock.c
ctime.c
difftime.c
localtime.c
localtime_fading_out.c
localtime.cpp
nanosleep.c
stime.c
strftime.c

View File

@ -0,0 +1,63 @@
/*
* Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de.
* Distributed under the terms of the MIT License.
*/
#include "TimeBackend.h"
#include <dlfcn.h>
#include <pthread.h>
namespace BPrivate {
TimeBackend* gTimeBackend = NULL;
static TimeDataBridge sTimeDataBridge;
static pthread_once_t sBackendInitOnce = PTHREAD_ONCE_INIT;
static void
LoadBackend()
{
void* imageHandle = dlopen("libroot-addon-icu.so", RTLD_LAZY);
if (imageHandle == NULL)
return;
typedef TimeBackend* (*symbolType)();
symbolType createInstanceFunc
= (symbolType)dlsym(imageHandle, "CreateInstance");
if (createInstanceFunc == NULL)
return;
gTimeBackend = createInstanceFunc();
}
TimeBackend::TimeBackend()
{
}
TimeBackend::~TimeBackend()
{
}
status_t
TimeBackend::LoadBackend()
{
if (gTimeBackend == NULL) {
pthread_once(&sBackendInitOnce, &BPrivate::LoadBackend);
if (gTimeBackend != NULL)
gTimeBackend->Initialize(&sTimeDataBridge);
}
return gTimeBackend != NULL ? B_OK : B_ERROR;
}
} // namespace BPrivate

View File

@ -0,0 +1,22 @@
/*
* Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de.
* Distributed under the terms of the MIT License.
*/
#include "TimeBackend.h"
namespace BPrivate {
TimeDataBridge::TimeDataBridge()
:
addrOfDaylight(&daylight),
addrOfTimezone(&timezone),
addrOfTZName(tzname)
{
}
} // namespace BPrivate

View File

@ -0,0 +1,54 @@
/*
* Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de.
* Distributed under the terms of the MIT License.
*/
#include <stdio.h>
#include <string.h>
#include <localtime.h>
#include <FindDirectory.h>
#include <StorageDefs.h>
char* tzname[2] = { "???", "???" };
long timezone = 0;
int daylight = 0;
namespace BPrivate {
static time_zone_info tzInfo;
extern "C" void
tzset(void)
{
char path[B_PATH_NAME_LENGTH];
if (find_directory(B_COMMON_SETTINGS_DIRECTORY, -1, false, path,
sizeof(path)) < 0)
return;
strlcat(path, "/", sizeof(path));
strlcat(path, skPosixTimeZoneInfoFile, sizeof(path));
FILE* tzInfoFile = fopen(path, "r");
if (tzInfoFile == NULL)
return;
size_t numRead = fread(&tzInfo, sizeof(tzInfo), 1, tzInfoFile);
fclose(tzInfoFile);
if (numRead != 1)
return;
tzname[0] = tzInfo.short_std_name;
tzname[1] = tzInfo.short_dst_name;
timezone = tzInfo.offset_from_gmt;
daylight = tzInfo.uses_daylight_saving;
}
} // namespace BPrivate

View File

@ -202,10 +202,12 @@ static char lcl_TZname[TZ_STRLEN_MAX + 1];
static int lcl_is_set;
static int gmt_is_set;
#if 0
char * tzname[2] = {
wildabbr,
wildabbr
};
#endif
/*
** Section 4.12.3 of X3.159-1989 requires that
@ -217,10 +219,12 @@ char * tzname[2] = {
static struct tm tm;
#if 0
#ifdef USG_COMPAT
time_t timezone = 0;
int daylight = 0;
#endif /* defined USG_COMPAT */
#endif
#ifdef ALTZONE
time_t altzone = 0;
@ -1164,6 +1168,7 @@ tzsetwall P((void))
#include <StorageDefs.h>
#include <syscalls.h>
#if 0
void
tzset P((void))
{
@ -1212,6 +1217,7 @@ tzset P((void))
(void) gmtload(lclptr);
settzname();
}
#endif
/*
** The easy way to behave "as if no library function calls" localtime