xref: /haiku/src/system/libroot/posix/locale/LocaleBackend.cpp (revision 4a55cc230cf7566cadcbb23b1928eefff8aea9a2)
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