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 16 namespace BPrivate { 17 namespace Libroot { 18 19 20 LocaleBackend* gGlobalLocaleBackend = NULL; 21 LocaleDataBridge gGlobalLocaleDataBridge = LocaleDataBridge(true); 22 23 24 static void* sImageHandle = NULL; 25 typedef LocaleBackend* (*create_instance_t)(); 26 typedef void (*destroy_instance_t)(LocaleBackend*); 27 static create_instance_t sCreateInstanceFunc = NULL; 28 static destroy_instance_t sDestroyInstanceFunc = NULL; 29 30 31 static pthread_once_t sBackendInitOnce = PTHREAD_ONCE_INIT; 32 static pthread_once_t sFunctionsInitOnce = PTHREAD_ONCE_INIT; 33 34 35 static void 36 LoadFunctions() 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 52 static void 53 LoadBackend() 54 { 55 gGlobalLocaleBackend = LocaleBackend::CreateBackend(); 56 if (gGlobalLocaleBackend != NULL) { 57 gGlobalLocaleBackend->Initialize(&gGlobalLocaleDataBridge); 58 } 59 } 60 61 62 63 LocaleBackend::LocaleBackend() 64 { 65 } 66 67 68 LocaleBackend::~LocaleBackend() 69 { 70 } 71 72 73 status_t 74 LocaleBackend::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 84 LocaleBackend* 85 LocaleBackend::CreateBackend() 86 { 87 if (sCreateInstanceFunc == NULL) { 88 pthread_once(&sFunctionsInitOnce, &BPrivate::Libroot::LoadFunctions); 89 } 90 91 if (sCreateInstanceFunc != NULL) { 92 LocaleBackend* backend = sCreateInstanceFunc(); 93 return backend; 94 } 95 96 return NULL; 97 } 98 99 100 void 101 LocaleBackend::DestroyBackend(LocaleBackend* instance) 102 { 103 if (sDestroyInstanceFunc != NULL) { 104 sDestroyInstanceFunc(instance); 105 } 106 } 107 108 109 LocaleBackendData* GetCurrentLocaleInfo() 110 { 111 return GetCurrentThreadLocale()->threadLocaleInfo; 112 } 113 114 115 void 116 SetCurrentLocaleInfo(LocaleBackendData* newLocale) 117 { 118 GetCurrentThreadLocale()->threadLocaleInfo = newLocale; 119 } 120 121 122 LocaleBackend* GetCurrentLocaleBackend() 123 { 124 LocaleBackendData* info = GetCurrentThreadLocale()->threadLocaleInfo; 125 if (info != NULL && info->backend != NULL) { 126 return info->backend; 127 } 128 return gGlobalLocaleBackend; 129 } 130 131 } // namespace Libroot 132 } // namespace BPrivate 133