1/* 2 * Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "LocaleBackend.h" 8 9#include <dlfcn.h> 10#include <pthread.h> 11#include <string.h> 12 13#include <ThreadLocale.h> 14 15 16namespace BPrivate { 17namespace Libroot { 18 19 20LocaleBackend* gGlobalLocaleBackend = NULL; 21LocaleDataBridge gGlobalLocaleDataBridge = LocaleDataBridge(true); 22 23 24static void* sImageHandle = NULL; 25typedef LocaleBackend* (*create_instance_t)(); 26typedef void (*destroy_instance_t)(LocaleBackend*); 27static create_instance_t sCreateInstanceFunc = NULL; 28static destroy_instance_t sDestroyInstanceFunc = NULL; 29 30 31static pthread_once_t sBackendInitOnce = PTHREAD_ONCE_INIT; 32static pthread_once_t sFunctionsInitOnce = PTHREAD_ONCE_INIT; 33 34 35static void 36LoadFunctions() 37{ 38 sImageHandle = dlopen("libroot-addon-icu.so", RTLD_LAZY); 39 if (sImageHandle == NULL) 40 return; 41 42 sCreateInstanceFunc = (create_instance_t)dlsym(sImageHandle, "CreateInstance"); 43 sDestroyInstanceFunc = (destroy_instance_t)dlsym(sImageHandle, "DestroyInstance"); 44 45 if ((sCreateInstanceFunc == NULL) || (sDestroyInstanceFunc == NULL)) { 46 dlclose(sImageHandle); 47 return; 48 } 49} 50 51 52static void 53LoadBackend() 54{ 55 LocaleBackend::CreateBackend(gGlobalLocaleBackend); 56 if (gGlobalLocaleBackend != NULL) { 57 gGlobalLocaleBackend->Initialize(&gGlobalLocaleDataBridge); 58 } 59} 60 61 62 63LocaleBackend::LocaleBackend() 64{ 65} 66 67 68LocaleBackend::~LocaleBackend() 69{ 70} 71 72 73status_t 74LocaleBackend::LoadBackend() 75{ 76 if (gGlobalLocaleBackend == NULL) { 77 pthread_once(&sBackendInitOnce, &BPrivate::Libroot::LoadBackend); 78 } 79 80 return gGlobalLocaleBackend != NULL ? B_OK : B_ERROR; 81} 82 83 84status_t 85LocaleBackend::CreateBackend(LocaleBackend*& backendOut) 86{ 87 if (sCreateInstanceFunc == NULL) { 88 pthread_once(&sFunctionsInitOnce, &BPrivate::Libroot::LoadFunctions); 89 } 90 91 if (sCreateInstanceFunc != NULL) { 92 backendOut = sCreateInstanceFunc(); 93 return backendOut != NULL ? B_OK : B_NO_MEMORY; 94 } 95 96 backendOut = NULL; 97 return B_MISSING_LIBRARY; 98} 99 100 101void 102LocaleBackend::DestroyBackend(LocaleBackend* instance) 103{ 104 if (sDestroyInstanceFunc != NULL) { 105 sDestroyInstanceFunc(instance); 106 } 107} 108 109 110LocaleBackendData* GetCurrentLocaleInfo() 111{ 112 return GetCurrentThreadLocale()->threadLocaleInfo; 113} 114 115 116void 117SetCurrentLocaleInfo(LocaleBackendData* newLocale) 118{ 119 GetCurrentThreadLocale()->threadLocaleInfo = newLocale; 120} 121 122 123LocaleBackend* GetCurrentLocaleBackend() 124{ 125 LocaleBackendData* info = GetCurrentThreadLocale()->threadLocaleInfo; 126 if (info != NULL && info->backend != NULL) { 127 return info->backend; 128 } 129 return gGlobalLocaleBackend; 130} 131 132} // namespace Libroot 133} // namespace BPrivate 134