2 * Copyright 2010-2011, Oliver Tappe, zooey@hirschkaefer.de.
3 * Distributed under the terms of the MIT License.
7 #include "ICULocaleBackend.h"
16 #include <ErrnoMaintainer.h>
23 extern "C" LocaleBackend
*
26 return new(std::nothrow
) ICULocaleBackend();
30 ICULocaleBackend::ICULocaleBackend()
32 fThreadLocalStorageKey(_CreateThreadLocalStorageKey()),
33 fCollateData(fThreadLocalStorageKey
),
34 fCtypeData(fThreadLocalStorageKey
),
35 fMessagesData(fThreadLocalStorageKey
),
36 fMonetaryData(fThreadLocalStorageKey
, fLocaleConv
),
37 fNumericData(fThreadLocalStorageKey
, fLocaleConv
),
38 fTimeData(fThreadLocalStorageKey
, fLCTimeInfo
, fMessagesData
),
39 fTimeConversion(fTimeData
)
44 ICULocaleBackend::~ICULocaleBackend()
46 pthread_key_delete(fThreadLocalStorageKey
);
51 ICULocaleBackend::Initialize(LocaleDataBridge
* dataBridge
)
53 ErrnoMaintainer errnoMaintainer
;
55 fCtypeData
.Initialize(&dataBridge
->ctypeDataBridge
);
56 fMessagesData
.Initialize(&dataBridge
->messagesDataBridge
);
57 fMonetaryData
.Initialize(&dataBridge
->monetaryDataBridge
);
58 fNumericData
.Initialize(&dataBridge
->numericDataBridge
);
59 fTimeData
.Initialize(&dataBridge
->timeDataBridge
);
60 fTimeConversion
.Initialize(&dataBridge
->timeConversionDataBridge
);
62 fPosixLanginfo
= dataBridge
->posixLanginfo
;
64 _SetPosixLocale(LC_ALL
);
69 ICULocaleBackend::SetLocale(int category
, const char* posixLocaleName
)
71 ErrnoMaintainer errnoMaintainer
;
73 if (posixLocaleName
== NULL
)
74 return _QueryLocale(category
);
76 if (strcasecmp(posixLocaleName
, "POSIX") == 0
77 || strcasecmp(posixLocaleName
, "C") == 0)
78 return _SetPosixLocale(category
);
80 Locale locale
= Locale::createCanonical(posixLocaleName
);
83 if (fCollateData
.SetTo(locale
, posixLocaleName
) != B_OK
84 || fCtypeData
.SetTo(locale
, posixLocaleName
) != B_OK
85 || fMessagesData
.SetTo(locale
, posixLocaleName
) != B_OK
86 || fMonetaryData
.SetTo(locale
, posixLocaleName
) != B_OK
87 || fNumericData
.SetTo(locale
, posixLocaleName
) != B_OK
88 || fTimeData
.SetTo(locale
, posixLocaleName
) != B_OK
)
92 if (fCollateData
.SetTo(locale
, posixLocaleName
) != B_OK
)
96 if (fCtypeData
.SetTo(locale
, posixLocaleName
) != B_OK
)
100 if (fMessagesData
.SetTo(locale
, posixLocaleName
) != B_OK
)
104 if (fMonetaryData
.SetTo(locale
, posixLocaleName
) != B_OK
)
108 if (fNumericData
.SetTo(locale
, posixLocaleName
) != B_OK
)
112 if (fTimeData
.SetTo(locale
, posixLocaleName
) != B_OK
)
116 // unsupported category
120 return posixLocaleName
;
125 ICULocaleBackend::LocaleConv()
131 const struct lc_time_t
*
132 ICULocaleBackend::LCTimeInfo()
139 ICULocaleBackend::IsWCType(wint_t wc
, wctype_t charClass
)
141 ErrnoMaintainer errnoMaintainer
;
143 return fCtypeData
.IsWCType(wc
, charClass
);
148 ICULocaleBackend::ToWCTrans(wint_t wc
, wctrans_t transition
, wint_t& result
)
150 ErrnoMaintainer errnoMaintainer
;
152 return fCtypeData
.ToWCTrans(wc
, transition
, result
);
157 ICULocaleBackend::MultibyteToWchar(wchar_t* wcOut
, const char* mb
,
158 size_t mbLength
, mbstate_t* mbState
, size_t& lengthOut
)
160 ErrnoMaintainer errnoMaintainer
;
162 return fCtypeData
.MultibyteToWchar(wcOut
, mb
, mbLength
, mbState
, lengthOut
);
167 ICULocaleBackend::MultibyteStringToWchar(wchar_t* wcDest
, size_t wcDestLength
,
168 const char** mbSource
, size_t mbSourceLength
, mbstate_t* mbState
,
171 ErrnoMaintainer errnoMaintainer
;
173 return fCtypeData
.MultibyteStringToWchar(wcDest
, wcDestLength
, mbSource
,
174 mbSourceLength
, mbState
, lengthOut
);
179 ICULocaleBackend::WcharToMultibyte(char* mbOut
, wchar_t wc
, mbstate_t* mbState
,
182 ErrnoMaintainer errnoMaintainer
;
184 return fCtypeData
.WcharToMultibyte(mbOut
, wc
, mbState
, lengthOut
);
189 ICULocaleBackend::WcharStringToMultibyte(char* mbDest
, size_t mbDestLength
,
190 const wchar_t** wcSource
, size_t wcSourceLength
, mbstate_t* mbState
,
193 ErrnoMaintainer errnoMaintainer
;
195 return fCtypeData
.WcharStringToMultibyte(mbDest
, mbDestLength
, wcSource
,
196 wcSourceLength
, mbState
, lengthOut
);
201 ICULocaleBackend::GetLanginfo(int index
)
203 ErrnoMaintainer errnoMaintainer
;
207 return fCtypeData
.GetLanginfo(index
);
253 return fTimeData
.GetLanginfo(index
);
260 return fPosixLanginfo
[index
];
264 return fNumericData
.GetLanginfo(index
);
268 return fMessagesData
.GetLanginfo(index
);
271 return fMonetaryData
.GetLanginfo(index
);
280 ICULocaleBackend::Strcoll(const char* a
, const char* b
, int& result
)
282 ErrnoMaintainer errnoMaintainer
;
284 return fCollateData
.Strcoll(a
, b
, result
);
289 ICULocaleBackend::Strxfrm(char* out
, const char* in
, size_t size
,
292 ErrnoMaintainer errnoMaintainer
;
294 return fCollateData
.Strxfrm(out
, in
, size
, outSize
);
299 ICULocaleBackend::Wcscoll(const wchar_t* a
, const wchar_t* b
, int& result
)
301 ErrnoMaintainer errnoMaintainer
;
303 return fCollateData
.Wcscoll(a
, b
, result
);
308 ICULocaleBackend::Wcsxfrm(wchar_t* out
, const wchar_t* in
, size_t size
,
311 ErrnoMaintainer errnoMaintainer
;
313 return fCollateData
.Wcsxfrm(out
, in
, size
, outSize
);
318 ICULocaleBackend::TZSet(const char* timeZoneID
, const char* tz
)
320 ErrnoMaintainer errnoMaintainer
;
322 return fTimeConversion
.TZSet(timeZoneID
, tz
);
327 ICULocaleBackend::Localtime(const time_t* inTime
, struct tm
* tmOut
)
329 ErrnoMaintainer errnoMaintainer
;
331 return fTimeConversion
.Localtime(inTime
, tmOut
);
336 ICULocaleBackend::Gmtime(const time_t* inTime
, struct tm
* tmOut
)
338 ErrnoMaintainer errnoMaintainer
;
340 return fTimeConversion
.Gmtime(inTime
, tmOut
);
345 ICULocaleBackend::Mktime(struct tm
* inOutTm
, time_t& timeOut
)
347 ErrnoMaintainer errnoMaintainer
;
349 return fTimeConversion
.Mktime(inOutTm
, timeOut
);
354 ICULocaleBackend::_QueryLocale(int category
)
359 // if all categories have the same locale, return that
360 const char* locale
= fCollateData
.PosixLocaleName();
361 if (strcmp(locale
, fCtypeData
.PosixLocaleName()) == 0
362 && strcmp(locale
, fMessagesData
.PosixLocaleName()) == 0
363 && strcmp(locale
, fMonetaryData
.PosixLocaleName()) == 0
364 && strcmp(locale
, fNumericData
.PosixLocaleName()) == 0
365 && strcmp(locale
, fTimeData
.PosixLocaleName()) == 0)
368 // build a string with all info (at least glibc does it, too)
369 snprintf(fLocaleDescription
, sizeof(fLocaleDescription
),
370 "LC_COLLATE=%s;LC_CTYPE=%s;LC_MESSAGES=%s;LC_MONETARY=%s;"
371 "LC_NUMERIC=%s;LC_TIME=%s",
372 fCollateData
.PosixLocaleName(), fCtypeData
.PosixLocaleName(),
373 fMessagesData
.PosixLocaleName(),
374 fMonetaryData
.PosixLocaleName(), fNumericData
.PosixLocaleName(),
375 fTimeData
.PosixLocaleName());
376 return fLocaleDescription
;
379 return fCollateData
.PosixLocaleName();
381 return fCtypeData
.PosixLocaleName();
383 return fMessagesData
.PosixLocaleName();
385 return fMonetaryData
.PosixLocaleName();
387 return fNumericData
.PosixLocaleName();
389 return fTimeData
.PosixLocaleName();
391 // unsupported category
398 ICULocaleBackend::_SetPosixLocale(int category
)
402 if (fCollateData
.SetToPosix() != B_OK
403 || fCtypeData
.SetToPosix() != B_OK
404 || fMessagesData
.SetToPosix() != B_OK
405 || fMonetaryData
.SetToPosix() != B_OK
406 || fNumericData
.SetToPosix() != B_OK
407 || fTimeData
.SetToPosix() != B_OK
)
411 if (fCollateData
.SetToPosix() != B_OK
)
415 if (fCtypeData
.SetToPosix() != B_OK
)
419 if (fMessagesData
.SetToPosix() != B_OK
)
423 if (fMonetaryData
.SetToPosix() != B_OK
)
427 if (fNumericData
.SetToPosix() != B_OK
)
431 if (fTimeData
.SetToPosix() != B_OK
)
435 // unsupported category
444 ICULocaleBackend::_CreateThreadLocalStorageKey()
448 pthread_key_create(&key
, ICULocaleBackend::_DestroyThreadLocalStorageValue
);
455 ICULocaleBackend::_DestroyThreadLocalStorageValue(void* value
)
457 ICUThreadLocalStorageValue
* tlsValue
458 = static_cast<ICUThreadLocalStorageValue
*>(value
);
464 } // namespace Libroot
465 } // namespace BPrivate