xref: /haiku/headers/private/libroot/locale/LocaleBackend.h (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
1 /*
2  * Copyright 2010-2011, Oliver Tappe, zooey@hirschkaefer.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _LOCALE_BACKEND_H
6 #define _LOCALE_BACKEND_H
7 
8 
9 #include <SupportDefs.h>
10 
11 #include <locale.h>
12 #include <time.h>
13 #include <wctype.h>
14 
15 
16 struct lc_time_t;
17 struct locale_data;		// glibc
18 
19 
20 namespace BPrivate {
21 namespace Libroot {
22 
23 
24 struct LocaleCtypeDataBridge {
25 private:
26 	const unsigned short*		localClassInfoTable;
27 	const int*					localToLowerTable;
28 	const int*					localToUpperTable;
29 
30 public:
31 	const unsigned short**		addrOfClassInfoTable;
32 	const int**					addrOfToLowerTable;
33 	const int**					addrOfToUpperTable;
34 
35 	const unsigned short* const	posixClassInfo;
36 	const int* const			posixToLowerMap;
37 	const int* const			posixToUpperMap;
38 
39 	bool						isGlobal;
40 
41 	LocaleCtypeDataBridge(bool isGlobal);
42 
43 	void setMbCurMax(unsigned short mbCurMax);
44 	void ApplyToCurrentThread();
45 };
46 
47 
48 struct LocaleMessagesDataBridge {
49 	const char** const 	posixLanginfo;
50 
51 	LocaleMessagesDataBridge();
52 };
53 
54 
55 struct LocaleMonetaryDataBridge {
56 	const struct lconv* const posixLocaleConv;
57 
58 	LocaleMonetaryDataBridge();
59 };
60 
61 
62 struct LocaleNumericDataBridge {
63 private:
64 	// struct used by glibc to store numeric locale data
65 	struct GlibcNumericLocale {
66 		const char* name;
67 		const char* filedata;
68 		off_t filesize;
69 		int mmaped;
70 		unsigned int usage_count;
71 		int use_translit;
72 		const char *options;
73 		unsigned int nstrings;
74 		union locale_data_value
75 		{
76 			const uint32_t* wstr;
77 			const char* string;
78 			unsigned int word;
79 		}
80 		values[6];
81 	};
82 	locale_data* originalGlibcLocale;
83 	GlibcNumericLocale  		glibcNumericLocaleData;
84 
85 public:
86 	const struct lconv* const 	posixLocaleConv;
87 	GlibcNumericLocale*  		glibcNumericLocale;
88 	bool						isGlobal;
89 
90 	LocaleNumericDataBridge(bool isGlobal);
91 	~LocaleNumericDataBridge();
92 
93 	void ApplyToCurrentThread();
94 };
95 
96 
97 struct LocaleTimeDataBridge {
98 	const struct lc_time_t* const posixLCTimeInfo;
99 
100 	LocaleTimeDataBridge();
101 };
102 
103 
104 struct TimeConversionDataBridge {
105 	static const int32 		kTZNameLength = 64;
106 
107 private:
108 	int						localDaylight;
109 	long					localTimezone;
110 	char*					localTZName[2];
111 	char					localTZName0[kTZNameLength];
112 	char					localTZName1[kTZNameLength];
113 
114 public:
115 	int*					addrOfDaylight;
116 	long*					addrOfTimezone;
117 	char**					addrOfTZName;
118 	bool					isGlobal;
119 
120 	TimeConversionDataBridge(bool isGlobal);
121 };
122 
123 
124 struct LocaleDataBridge {
125 	LocaleCtypeDataBridge		ctypeDataBridge;
126 	LocaleMessagesDataBridge	messagesDataBridge;
127 	LocaleMonetaryDataBridge	monetaryDataBridge;
128 	LocaleNumericDataBridge		numericDataBridge;
129 	LocaleTimeDataBridge		timeDataBridge;
130 	TimeConversionDataBridge	timeConversionDataBridge;
131 	const char** const			posixLanginfo;
132 	bool						isGlobal;
133 
134 	LocaleDataBridge(bool isGlobal);
135 
136 	void ApplyToCurrentThread();
137 };
138 
139 
140 class LocaleBackend {
141 public:
142 								LocaleBackend();
143 	virtual						~LocaleBackend();
144 
145 	virtual	const char*			SetLocale(int category, const char* locale) = 0;
146 	virtual	const struct lconv*	LocaleConv() = 0;
147 	virtual	const struct lc_time_t*	LCTimeInfo() = 0;
148 
149 	virtual	int					IsWCType(wint_t wc, wctype_t charClass) = 0;
150 	virtual	status_t			ToWCTrans(wint_t wc, wctrans_t transition,
151 									wint_t& result) = 0;
152 
153 	virtual status_t			MultibyteToWchar(wchar_t* wcOut, const char* mb,
154 									size_t mbLength, mbstate_t* mbState,
155 									size_t& lengthOut) = 0;
156 	virtual status_t			MultibyteStringToWchar(wchar_t* wcDest,
157 									size_t wcDestLength, const char** mbSource,
158 									size_t mbSourceLength, mbstate_t* mbState,
159 									size_t& lengthOut) = 0;
160 	virtual status_t			WcharToMultibyte(char* mbOut, wchar_t wc,
161 									mbstate_t* mbState, size_t& lengthOut) = 0;
162 	virtual status_t			WcharStringToMultibyte(char* mbDest,
163 									size_t mbDestLength,
164 									const wchar_t** wcSource,
165 									size_t wcSourceLength, mbstate_t* mbState,
166 									size_t& lengthOut) = 0;
167 
168 	virtual	const char*			GetLanginfo(int index) = 0;
169 
170 	virtual	status_t			Strcoll(const char* a, const char* b,
171 									int& out) = 0;
172 	virtual status_t			Strxfrm(char* out, const char* in,
173 									size_t outSize, size_t& requiredSize) = 0;
174 	virtual	status_t			Wcscoll(const wchar_t* a, const wchar_t* b,
175 									int& out) = 0;
176 	virtual status_t			Wcsxfrm(wchar_t* out, const wchar_t* in,
177 									size_t outSize, size_t& requiredSize) = 0;
178 
179 	virtual status_t			TZSet(const char* timeZoneID,
180 									const char* tz) = 0;
181 	virtual	status_t			Localtime(const time_t* inTime,
182 									struct tm* tmOut) = 0;
183 	virtual	status_t			Gmtime(const time_t* inTime,
184 									struct tm* tmOut) = 0;
185 	virtual status_t			Mktime(struct tm* inOutTm, time_t& timeOut) = 0;
186 
187 	virtual status_t			Timegm(struct tm* inOutTm, time_t& timeOut) = 0;
188 
189 	virtual void				Initialize(LocaleDataBridge* dataBridge) = 0;
190 
191 	static	status_t			LoadBackend();
192 	static  status_t			CreateBackend(LocaleBackend*& backendOut);
193 	static  void				DestroyBackend(LocaleBackend* instance);
194 };
195 
196 
197 // The real struct behind locale_t
198 struct LocaleBackendData {
199 	int magic;
200 	LocaleBackend* backend;
201 	LocaleDataBridge* databridge;
202 };
203 
204 
205 LocaleBackendData* GetCurrentLocaleInfo();
206 void SetCurrentLocaleInfo(LocaleBackendData* newLocale);
207 LocaleBackend* GetCurrentLocaleBackend();
208 extern LocaleBackend* gGlobalLocaleBackend;
209 extern LocaleDataBridge gGlobalLocaleDataBridge;
210 
211 }	// namespace Libroot
212 }	// namespace BPrivate
213 
214 
215 #endif	// _LOCALE_BACKEND_H
216