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 LocaleBackend::CreateBackend(gGlobalLocaleBackend); 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 status_t 85 LocaleBackend::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 101 void 102 LocaleBackend::DestroyBackend(LocaleBackend* instance) 103 { 104 if (sDestroyInstanceFunc != NULL) { 105 sDestroyInstanceFunc(instance); 106 } 107 } 108 109 110 LocaleBackendData* GetCurrentLocaleInfo() 111 { 112 return GetCurrentThreadLocale()->threadLocaleInfo; 113 } 114 115 116 void 117 SetCurrentLocaleInfo(LocaleBackendData* newLocale) 118 { 119 GetCurrentThreadLocale()->threadLocaleInfo = newLocale; 120 } 121 122 123 LocaleBackend* 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