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