* Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de.
* Distributed under the terms of the MIT License.
*/
#include "LocaleBackend.h"
#include <dlfcn.h>
#include <pthread.h>
#include <string.h>
#include <ThreadLocale.h>
namespace BPrivate {
namespace Libroot {
LocaleBackend* gGlobalLocaleBackend = NULL;
LocaleDataBridge gGlobalLocaleDataBridge = LocaleDataBridge(true);
static void* sImageHandle = NULL;
typedef LocaleBackend* (*create_instance_t)();
typedef void (*destroy_instance_t)(LocaleBackend*);
static create_instance_t sCreateInstanceFunc = NULL;
static destroy_instance_t sDestroyInstanceFunc = NULL;
static pthread_once_t sBackendInitOnce = PTHREAD_ONCE_INIT;
static pthread_once_t sFunctionsInitOnce = PTHREAD_ONCE_INIT;
static void
LoadFunctions()
{
sImageHandle = dlopen("libroot-addon-icu.so", RTLD_LAZY);
if (sImageHandle == NULL)
return;
sCreateInstanceFunc = (create_instance_t)dlsym(sImageHandle, "CreateInstance");
sDestroyInstanceFunc = (destroy_instance_t)dlsym(sImageHandle, "DestroyInstance");
if ((sCreateInstanceFunc == NULL) || (sDestroyInstanceFunc == NULL)) {
dlclose(sImageHandle);
return;
}
}
static void
LoadBackend()
{
LocaleBackend::CreateBackend(gGlobalLocaleBackend);
if (gGlobalLocaleBackend != NULL) {
gGlobalLocaleBackend->Initialize(&gGlobalLocaleDataBridge);
}
}
LocaleBackend::LocaleBackend()
{
}
LocaleBackend::~LocaleBackend()
{
}
status_t
LocaleBackend::LoadBackend()
{
if (gGlobalLocaleBackend == NULL) {
pthread_once(&sBackendInitOnce, &BPrivate::Libroot::LoadBackend);
}
return gGlobalLocaleBackend != NULL ? B_OK : B_ERROR;
}
status_t
LocaleBackend::CreateBackend(LocaleBackend*& backendOut)
{
if (sCreateInstanceFunc == NULL) {
pthread_once(&sFunctionsInitOnce, &BPrivate::Libroot::LoadFunctions);
}
if (sCreateInstanceFunc != NULL) {
backendOut = sCreateInstanceFunc();
return backendOut != NULL ? B_OK : B_NO_MEMORY;
}
backendOut = NULL;
return B_MISSING_LIBRARY;
}
void
LocaleBackend::DestroyBackend(LocaleBackend* instance)
{
if (sDestroyInstanceFunc != NULL) {
sDestroyInstanceFunc(instance);
}
}
LocaleBackendData* GetCurrentLocaleInfo()
{
return GetCurrentThreadLocale()->threadLocaleInfo;
}
void
SetCurrentLocaleInfo(LocaleBackendData* newLocale)
{
GetCurrentThreadLocale()->threadLocaleInfo = newLocale;
}
LocaleBackend* GetCurrentLocaleBackend()
{
LocaleBackendData* info = GetCurrentThreadLocale()->threadLocaleInfo;
if (info != NULL && info->backend != NULL) {
return info->backend;
}
return gGlobalLocaleBackend;
}
}
}