Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <osl/nlsupport.h>
21 : #include <osl/diagnose.h>
22 : #include <osl/process.h>
23 :
24 : #if defined(LINUX) || defined(SOLARIS) || defined(NETBSD) || \
25 : defined(FREEBSD) || defined(MACOSX) || defined(IOS) || defined(OPENBSD) || \
26 : defined(DRAGONFLY)
27 : #include <pthread.h>
28 : #if !defined(MACOSX) && !defined(IOS)
29 : #include <locale.h>
30 : #include <langinfo.h>
31 : #else
32 : #include <osl/module.h>
33 : #include <osl/thread.h>
34 : #endif /* !MACOSX && !IOS */
35 : #endif /* LINUX || SOLARIS || NETBSD || MACOSX || IOS */
36 :
37 : #include <string.h>
38 :
39 : /*****************************************************************************
40 : typedefs
41 : *****************************************************************************/
42 :
43 :
44 : typedef struct {
45 : const char *key;
46 : const rtl_TextEncoding value;
47 : } _pair;
48 :
49 :
50 : /*****************************************************************************
51 : compare function for binary search
52 : *****************************************************************************/
53 :
54 : static int
55 8729 : _pair_compare (const char *key, const _pair *pair)
56 : {
57 8729 : int result = rtl_str_compareIgnoreAsciiCase( key, pair->key );
58 8729 : return result;
59 : }
60 :
61 : /*****************************************************************************
62 : binary search on encoding tables
63 : *****************************************************************************/
64 :
65 : static const _pair*
66 1247 : _pair_search (const char *key, const _pair *base, unsigned int member )
67 : {
68 1247 : unsigned int lower = 0;
69 1247 : unsigned int upper = member;
70 : unsigned int current;
71 : int comparison;
72 :
73 : /* check for validity of input */
74 1247 : if ( (key == NULL) || (base == NULL) || (member == 0) )
75 0 : return NULL;
76 :
77 : /* binary search */
78 9976 : while ( lower < upper )
79 : {
80 8729 : current = (lower + upper) / 2;
81 8729 : comparison = _pair_compare( key, base + current );
82 8729 : if (comparison < 0)
83 1372 : upper = current;
84 7357 : else if (comparison > 0)
85 6110 : lower = current + 1;
86 : else
87 1247 : return base + current;
88 : }
89 :
90 0 : return NULL;
91 : }
92 :
93 :
94 : /*****************************************************************************
95 : convert rtl_Locale to locale string
96 : *****************************************************************************/
97 :
98 1247 : static char * _compose_locale( rtl_Locale * pLocale, char * buffer, size_t n )
99 : {
100 : /* check if a valid locale is specified */
101 2494 : if( pLocale && pLocale->Language &&
102 1272 : (pLocale->Language->length == 2 || pLocale->Language->length == 3) )
103 : {
104 1222 : size_t offset = 0;
105 :
106 : /* convert language code to ascii */
107 : {
108 1222 : rtl_String *pLanguage = NULL;
109 :
110 2444 : rtl_uString2String( &pLanguage,
111 2444 : pLocale->Language->buffer, pLocale->Language->length,
112 : RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS );
113 :
114 1222 : if( SAL_INT_CAST(sal_uInt32, pLanguage->length) < n )
115 : {
116 1222 : strcpy( buffer, pLanguage->buffer );
117 1222 : offset = pLanguage->length;
118 : }
119 :
120 1222 : rtl_string_release( pLanguage );
121 : }
122 :
123 : /* convert country code to ascii */
124 1222 : if( pLocale->Country && (pLocale->Country->length == 2) )
125 : {
126 1222 : rtl_String *pCountry = NULL;
127 :
128 2444 : rtl_uString2String( &pCountry,
129 2444 : pLocale->Country->buffer, pLocale->Country->length,
130 : RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS );
131 :
132 1222 : if( offset + pCountry->length + 1 < n )
133 : {
134 1222 : strcpy( buffer + offset++, "_" );
135 1222 : strcpy( buffer + offset, pCountry->buffer );
136 1222 : offset += pCountry->length;
137 : }
138 :
139 1222 : rtl_string_release( pCountry );
140 : }
141 :
142 : /* convert variant to ascii - check if there is enough space for the variant string */
143 2444 : if( pLocale->Variant && pLocale->Variant->length &&
144 1222 : ( SAL_INT_CAST(sal_uInt32, pLocale->Variant->length) < n - 6 ) )
145 : {
146 1222 : rtl_String *pVariant = NULL;
147 :
148 2444 : rtl_uString2String( &pVariant,
149 2444 : pLocale->Variant->buffer, pLocale->Variant->length,
150 : RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS );
151 :
152 1222 : if( offset + pVariant->length + 1 < n )
153 : {
154 1222 : strcpy( buffer + offset, pVariant->buffer );
155 1222 : offset += pVariant->length;
156 : }
157 :
158 1222 : rtl_string_release( pVariant );
159 : }
160 :
161 1222 : return buffer;
162 : }
163 :
164 25 : return NULL;
165 : }
166 :
167 : /*****************************************************************************
168 : convert locale string to rtl_Locale
169 : *****************************************************************************/
170 :
171 1247 : static rtl_Locale * _parse_locale( const char * locale )
172 : {
173 : static sal_Unicode c_locale[2] = { (sal_Unicode) 'C', 0 };
174 :
175 : /* check if locale contains a valid string */
176 1247 : if( locale )
177 : {
178 1247 : size_t len = strlen( locale );
179 :
180 1247 : if( len >= 2 )
181 : {
182 1222 : rtl_uString * pLanguage = NULL;
183 1222 : rtl_uString * pCountry = NULL;
184 1222 : rtl_uString * pVariant = NULL;
185 :
186 1222 : size_t offset = 2;
187 :
188 : rtl_Locale * ret;
189 :
190 : /* language is a two or three letter code */
191 1222 : if( (len > 3 && '_' == locale[3]) || (len == 3 && '_' != locale[2]) )
192 0 : offset = 3;
193 :
194 : /* convert language code to unicode */
195 1222 : rtl_string2UString( &pLanguage, locale, offset, RTL_TEXTENCODING_ASCII_US, OSTRING_TO_OUSTRING_CVTFLAGS );
196 : OSL_ASSERT(pLanguage != NULL);
197 :
198 : /* convert country code to unicode */
199 1222 : if( len >= offset+3 && '_' == locale[offset] )
200 : {
201 1222 : rtl_string2UString( &pCountry, locale + offset + 1, 2, RTL_TEXTENCODING_ASCII_US, OSTRING_TO_OUSTRING_CVTFLAGS );
202 : OSL_ASSERT(pCountry != NULL);
203 1222 : offset += 3;
204 : }
205 :
206 : /* convert variant code to unicode - do not rely on "." as delimiter */
207 1222 : if( len > offset ) {
208 1222 : rtl_string2UString( &pVariant, locale + offset, len - offset, RTL_TEXTENCODING_ASCII_US, OSTRING_TO_OUSTRING_CVTFLAGS );
209 : OSL_ASSERT(pVariant != NULL);
210 : }
211 :
212 1222 : ret = rtl_locale_register( pLanguage->buffer, pCountry ? pCountry->buffer : c_locale + 1, pVariant ? pVariant->buffer : c_locale + 1 );
213 :
214 1222 : if (pVariant) rtl_uString_release(pVariant);
215 1222 : if (pCountry) rtl_uString_release(pCountry);
216 1222 : if (pLanguage) rtl_uString_release(pLanguage);
217 :
218 1222 : return ret;
219 : }
220 : else
221 25 : return rtl_locale_register( c_locale, c_locale + 1, c_locale + 1 );
222 : }
223 :
224 0 : return NULL;
225 : }
226 :
227 : #if defined(LINUX) || defined(SOLARIS) || defined(NETBSD) || \
228 : defined(FREEBSD) || defined(OPENBSD) || defined(DRAGONFLY)
229 :
230 : /*
231 : * This implementation of osl_getTextEncodingFromLocale maps
232 : * from nl_langinfo(CODESET) to rtl_textencoding defines.
233 : * nl_langinfo() is supported only on Linux, Solaris,
234 : * >= NetBSD 1.6 and >= FreeBSD 4.4
235 : *
236 : * This routine is SLOW because of the setlocale call, so
237 : * grab the result and cache it.
238 : *
239 : * XXX this code has the usual mt problems aligned with setlocale() XXX
240 : */
241 :
242 : #ifdef LINUX
243 : #if !defined(CODESET)
244 : #define CODESET _NL_CTYPE_CODESET_NAME
245 : #endif
246 : #endif
247 :
248 : /*
249 : * _nl_language_list[] is an array list of supported encodings. Because
250 : * we are using a binary search, the list has to be in ascending order.
251 : * We are comparing the encodings case insensitiv, so the list has
252 : * to be completly upper- , or lowercase.
253 : */
254 :
255 : #if defined(SOLARIS)
256 :
257 : /* The values in the below list can be obtained with a script like
258 : * #!/bin/sh
259 : * for i in `locale -a`; do
260 : * LC_ALL=$i locale -k code_set_name
261 : * done
262 : */
263 : const _pair _nl_language_list[] = {
264 : { "5601", RTL_TEXTENCODING_EUC_KR }, /* ko_KR.EUC */
265 : { "646", RTL_TEXTENCODING_ISO_8859_1 }, /* fake: ASCII_US */
266 : { "ANSI-1251", RTL_TEXTENCODING_MS_1251 }, /* ru_RU.ANSI1251 */
267 : { "BIG5", RTL_TEXTENCODING_BIG5 }, /* zh_CN.BIG5 */
268 : { "BIG5-HKSCS", RTL_TEXTENCODING_BIG5_HKSCS }, /* zh_CN.BIG5HK */
269 : { "CNS11643", RTL_TEXTENCODING_EUC_TW }, /* zh_TW.EUC */
270 : { "EUCJP", RTL_TEXTENCODING_EUC_JP }, /* ja_JP.eucjp */
271 : { "GB18030", RTL_TEXTENCODING_GB_18030 }, /* zh_CN.GB18030 */
272 : { "GB2312", RTL_TEXTENCODING_GB_2312 }, /* zh_CN */
273 : { "GBK", RTL_TEXTENCODING_GBK }, /* zh_CN.GBK */
274 : { "ISO8859-1", RTL_TEXTENCODING_ISO_8859_1 },
275 : { "ISO8859-10", RTL_TEXTENCODING_ISO_8859_10 },
276 : { "ISO8859-13", RTL_TEXTENCODING_ISO_8859_13 }, /* lt_LT lv_LV */
277 : { "ISO8859-14", RTL_TEXTENCODING_ISO_8859_14 },
278 : { "ISO8859-15", RTL_TEXTENCODING_ISO_8859_15 },
279 : { "ISO8859-2", RTL_TEXTENCODING_ISO_8859_2 },
280 : { "ISO8859-3", RTL_TEXTENCODING_ISO_8859_3 },
281 : { "ISO8859-4", RTL_TEXTENCODING_ISO_8859_4 },
282 : { "ISO8859-5", RTL_TEXTENCODING_ISO_8859_5 },
283 : { "ISO8859-6", RTL_TEXTENCODING_ISO_8859_6 },
284 : { "ISO8859-7", RTL_TEXTENCODING_ISO_8859_7 },
285 : { "ISO8859-8", RTL_TEXTENCODING_ISO_8859_8 },
286 : { "ISO8859-9", RTL_TEXTENCODING_ISO_8859_9 },
287 : { "KOI8-R", RTL_TEXTENCODING_KOI8_R },
288 : { "KOI8-U", RTL_TEXTENCODING_KOI8_U },
289 : { "PCK", RTL_TEXTENCODING_MS_932 },
290 : { "SUN_EU_GREEK", RTL_TEXTENCODING_ISO_8859_7 }, /* 8859-7 + Euro */
291 : { "TIS620.2533", RTL_TEXTENCODING_MS_874 }, /* th_TH.TIS620 */
292 : { "UTF-8", RTL_TEXTENCODING_UTF8 }
293 : };
294 :
295 : /* XXX MS-874 is an extension to tis620, so this is not
296 : * really equivalent */
297 :
298 : #elif defined(LINUX)
299 :
300 : const _pair _nl_language_list[] = {
301 : { "ANSI_X3.110-1983", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-99 NAPLPS */
302 : { "ANSI_X3.4-1968", RTL_TEXTENCODING_ISO_8859_1 }, /* fake: ASCII_US */
303 : { "ASMO_449", RTL_TEXTENCODING_DONTKNOW }, /* ISO_9036 ARABIC7 */
304 : { "BALTIC", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-179 */
305 : { "BIG5", RTL_TEXTENCODING_BIG5 }, /* locale: zh_TW */
306 : { "BIG5-HKSCS", RTL_TEXTENCODING_BIG5_HKSCS }, /* locale: zh_CN.BIG5HK */
307 : { "BIG5HKSCS", RTL_TEXTENCODING_BIG5_HKSCS }, /* deprecated */
308 : { "BS_4730", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-4 ISO646-GB */
309 : { "BS_VIEWDATA", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-47 */
310 : { "CP1250", RTL_TEXTENCODING_MS_1250 }, /* MS-EE */
311 : { "CP1251", RTL_TEXTENCODING_MS_1251 }, /* MS-CYRL */
312 : { "CP1252", RTL_TEXTENCODING_MS_1252 }, /* MS-ANSI */
313 : { "CP1253", RTL_TEXTENCODING_MS_1253 }, /* MS-GREEK */
314 : { "CP1254", RTL_TEXTENCODING_MS_1254 }, /* MS-TURK */
315 : { "CP1255", RTL_TEXTENCODING_MS_1255 }, /* MS-HEBR */
316 : { "CP1256", RTL_TEXTENCODING_MS_1256 }, /* MS-ARAB */
317 : { "CP1257", RTL_TEXTENCODING_MS_1257 }, /* WINBALTRIM */
318 : { "CSA_Z243.4-1985-1", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-121 */
319 : { "CSA_Z243.4-1985-2", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-122 CSA7-2 */
320 : { "CSA_Z243.4-1985-GR", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-123 */
321 : { "CSN_369103", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-139 */
322 : { "CWI", RTL_TEXTENCODING_DONTKNOW }, /* CWI-2 CP-HU */
323 : { "DEC-MCS", RTL_TEXTENCODING_DONTKNOW }, /* DEC */
324 : { "DIN_66003", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-21 */
325 : { "DS_2089", RTL_TEXTENCODING_DONTKNOW }, /* DS2089 ISO646-DK */
326 : { "EBCDIC-AT-DE", RTL_TEXTENCODING_DONTKNOW },
327 : { "EBCDIC-AT-DE-A", RTL_TEXTENCODING_DONTKNOW },
328 : { "EBCDIC-CA-FR", RTL_TEXTENCODING_DONTKNOW },
329 : { "EBCDIC-DK-NO", RTL_TEXTENCODING_DONTKNOW },
330 : { "EBCDIC-DK-NO-A", RTL_TEXTENCODING_DONTKNOW },
331 : { "EBCDIC-ES", RTL_TEXTENCODING_DONTKNOW },
332 : { "EBCDIC-ES-A", RTL_TEXTENCODING_DONTKNOW },
333 : { "EBCDIC-ES-S", RTL_TEXTENCODING_DONTKNOW },
334 : { "EBCDIC-FI-SE", RTL_TEXTENCODING_DONTKNOW },
335 : { "EBCDIC-FI-SE-A", RTL_TEXTENCODING_DONTKNOW },
336 : { "EBCDIC-FR", RTL_TEXTENCODING_DONTKNOW },
337 : { "EBCDIC-IS-FRISS", RTL_TEXTENCODING_DONTKNOW }, /* FRISS */
338 : { "EBCDIC-IT", RTL_TEXTENCODING_DONTKNOW },
339 : { "EBCDIC-PT", RTL_TEXTENCODING_DONTKNOW },
340 : { "EBCDIC-UK", RTL_TEXTENCODING_DONTKNOW },
341 : { "EBCDIC-US", RTL_TEXTENCODING_DONTKNOW },
342 : { "ECMA-CYRILLIC", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-111 */
343 : { "ES", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-17 */
344 : { "ES2", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-85 */
345 : { "EUC-JP", RTL_TEXTENCODING_EUC_JP }, /* locale: ja_JP.eucjp */
346 : { "EUC-KR", RTL_TEXTENCODING_EUC_KR }, /* locale: ko_KR.euckr */
347 : { "EUC-TW", RTL_TEXTENCODING_EUC_TW }, /* locale: zh_TW.euctw */
348 : { "GB18030", RTL_TEXTENCODING_GB_18030 }, /* locale: zh_CN.gb18030 */
349 : { "GB2312", RTL_TEXTENCODING_GB_2312 }, /* locale: zh_CN */
350 : { "GB_1988-80", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-57 */
351 : { "GBK", RTL_TEXTENCODING_GBK }, /* locale: zh_CN.GBK */
352 : { "GOST_19768-74", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-153 */
353 : { "GREEK-CCITT", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-150 */
354 : { "GREEK7", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-88 */
355 : { "GREEK7-OLD", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-18 */
356 : { "HP-ROMAN8", RTL_TEXTENCODING_DONTKNOW }, /* ROMAN8 R8 */
357 : { "IBM037", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-[US|CA|WT] */
358 : { "IBM038", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-INT CP038 */
359 : { "IBM1004", RTL_TEXTENCODING_DONTKNOW }, /* CP1004 OS2LATIN1 */
360 : { "IBM1026", RTL_TEXTENCODING_DONTKNOW }, /* CP1026 1026 */
361 : { "IBM1047", RTL_TEXTENCODING_DONTKNOW }, /* CP1047 1047 */
362 : { "IBM256", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-INT1 */
363 : { "IBM273", RTL_TEXTENCODING_DONTKNOW }, /* CP273 */
364 : { "IBM274", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-BE CP274 */
365 : { "IBM275", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-BR CP275 */
366 : { "IBM277", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-CP-[DK|NO] */
367 : { "IBM278", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-CP-[FISE]*/
368 : { "IBM280", RTL_TEXTENCODING_DONTKNOW }, /* CP280 EBCDIC-CP-IT*/
369 : { "IBM281", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-JP-E CP281 */
370 : { "IBM284", RTL_TEXTENCODING_DONTKNOW }, /* CP284 EBCDIC-CP-ES */
371 : { "IBM285", RTL_TEXTENCODING_DONTKNOW }, /* CP285 EBCDIC-CP-GB */
372 : { "IBM290", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-JP-KANA */
373 : { "IBM297", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-CP-FR */
374 : { "IBM420", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-CP-AR1 */
375 : { "IBM423", RTL_TEXTENCODING_DONTKNOW }, /* CP423 EBCDIC-CP-GR */
376 : { "IBM424", RTL_TEXTENCODING_DONTKNOW }, /* CP424 EBCDIC-CP-HE */
377 : { "IBM437", RTL_TEXTENCODING_IBM_437 }, /* CP437 437 */
378 : { "IBM500", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-CP-[BE|CH] */
379 : { "IBM850", RTL_TEXTENCODING_IBM_850 }, /* CP850 850 */
380 : { "IBM851", RTL_TEXTENCODING_DONTKNOW }, /* CP851 851 */
381 : { "IBM852", RTL_TEXTENCODING_IBM_852 }, /* CP852 852 */
382 : { "IBM855", RTL_TEXTENCODING_IBM_855 }, /* CP855 855 */
383 : { "IBM857", RTL_TEXTENCODING_IBM_857 }, /* CP857 857 */
384 : { "IBM860", RTL_TEXTENCODING_IBM_860 }, /* CP860 860 */
385 : { "IBM861", RTL_TEXTENCODING_IBM_861 }, /* CP861 861 CP-IS */
386 : { "IBM862", RTL_TEXTENCODING_IBM_862 }, /* CP862 862 */
387 : { "IBM863", RTL_TEXTENCODING_IBM_863 }, /* CP863 863 */
388 : { "IBM864", RTL_TEXTENCODING_IBM_864 }, /* CP864 */
389 : { "IBM865", RTL_TEXTENCODING_IBM_865 }, /* CP865 865 */
390 : { "IBM866", RTL_TEXTENCODING_IBM_866 }, /* CP866 866 */
391 : { "IBM868", RTL_TEXTENCODING_DONTKNOW }, /* CP868 CP-AR */
392 : { "IBM869", RTL_TEXTENCODING_IBM_869 }, /* CP869 869 CP-GR */
393 : { "IBM870", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-[ROECE|YU] */
394 : { "IBM871", RTL_TEXTENCODING_DONTKNOW }, /* CP871 EBCDIC-CP-IS */
395 : { "IBM875", RTL_TEXTENCODING_DONTKNOW }, /* CP875 EBCDIC-GREEK */
396 : { "IBM880", RTL_TEXTENCODING_DONTKNOW }, /* EBCDIC-CYRILLIC */
397 : { "IBM891", RTL_TEXTENCODING_DONTKNOW }, /* CP891 */
398 : { "IBM903", RTL_TEXTENCODING_DONTKNOW }, /* CP903 */
399 : { "IBM904", RTL_TEXTENCODING_DONTKNOW }, /* CP904 904 */
400 : { "IBM905", RTL_TEXTENCODING_DONTKNOW }, /* CP905 EBCDIC-CP-TR */
401 : { "IBM918", RTL_TEXTENCODING_DONTKNOW }, /* CP918 EBCDIC-AR2 */
402 : { "IEC_P27-1", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-143 */
403 : { "INIS", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-49 */
404 : { "INIS-8", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-50 */
405 : { "INIS-CYRILLIC", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-51 */
406 : { "INVARIANT", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-170 */
407 : { "ISO-8859-1", RTL_TEXTENCODING_ISO_8859_1 }, /* ISO-IR-100 CP819 */
408 : { "ISO-8859-10", RTL_TEXTENCODING_ISO_8859_10 }, /* ISO-IR-157 LATIN6 */
409 : { "ISO-8859-13", RTL_TEXTENCODING_ISO_8859_13 }, /* ISO-IR-179 LATIN7 */
410 : { "ISO-8859-14", RTL_TEXTENCODING_ISO_8859_14 }, /* LATIN8 L8 */
411 : { "ISO-8859-15", RTL_TEXTENCODING_ISO_8859_15 },
412 : { "ISO-8859-2", RTL_TEXTENCODING_ISO_8859_2 }, /* LATIN2 L2 */
413 : { "ISO-8859-3", RTL_TEXTENCODING_ISO_8859_3 }, /* LATIN3 L3 */
414 : { "ISO-8859-4", RTL_TEXTENCODING_ISO_8859_4 }, /* LATIN4 L4 */
415 : { "ISO-8859-5", RTL_TEXTENCODING_ISO_8859_5 }, /* CYRILLIC */
416 : { "ISO-8859-6", RTL_TEXTENCODING_ISO_8859_6 }, /* ECMA-114 ARABIC */
417 : { "ISO-8859-7", RTL_TEXTENCODING_ISO_8859_7 }, /* ECMA-118 GREEK8 */
418 : { "ISO-8859-8", RTL_TEXTENCODING_ISO_8859_8 }, /* ISO_8859-8 HEBREW */
419 : { "ISO-8859-9", RTL_TEXTENCODING_ISO_8859_9 }, /* ISO_8859-9 LATIN5 */
420 : { "ISO-IR-90", RTL_TEXTENCODING_DONTKNOW }, /* ISO_6937-2:1983 */
421 : { "ISO_10367-BOX", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-155 */
422 : { "ISO_2033-1983", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-98 E13B */
423 : { "ISO_5427", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-37 KOI-7 */
424 : { "ISO_5427-EXT", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-54 */
425 : { "ISO_5428", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-55 */
426 : { "ISO_646.BASIC", RTL_TEXTENCODING_ASCII_US }, /* REF */
427 : { "ISO_646.IRV", RTL_TEXTENCODING_ASCII_US }, /* ISO-IR-2 IRV */
428 : { "ISO_646.IRV:1983", RTL_TEXTENCODING_ISO_8859_1 }, /* fake: ASCII_US, used for "C" locale*/
429 : { "ISO_6937", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-156 ISO6937*/
430 : { "ISO_6937-2-25", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-152 */
431 : { "ISO_6937-2-ADD", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-142 */
432 : { "ISO_8859-SUPP", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-154 */
433 : { "IT", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-15 */
434 : { "JIS_C6220-1969-JP", RTL_TEXTENCODING_DONTKNOW }, /* KATAKANA X0201-7 */
435 : { "JIS_C6220-1969-RO", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-14 */
436 : { "JIS_C6229-1984-A", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-91 */
437 : { "JIS_C6229-1984-B", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-92 */
438 : { "JIS_C6229-1984-B-ADD", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-93 */
439 : { "JIS_C6229-1984-HAND", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-94 */
440 : { "JIS_C6229-1984-HAND-ADD", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-95 */
441 : { "JIS_C6229-1984-KANA", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-96 */
442 : { "JIS_X0201", RTL_TEXTENCODING_DONTKNOW }, /* X0201 */
443 : { "JUS_I.B1.002", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-141 */
444 : { "JUS_I.B1.003-MAC", RTL_TEXTENCODING_DONTKNOW }, /* MACEDONIAN */
445 : { "JUS_I.B1.003-SERB", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-146 SERBIAN */
446 : { "KOI-8", RTL_TEXTENCODING_DONTKNOW },
447 : { "KOI8-R", RTL_TEXTENCODING_KOI8_R },
448 : { "KOI8-U", RTL_TEXTENCODING_KOI8_U },
449 : { "KSC5636", RTL_TEXTENCODING_DONTKNOW }, /* ISO646-KR */
450 : { "LATIN-GREEK", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-19 */
451 : { "LATIN-GREEK-1", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-27 */
452 : { "MAC-IS", RTL_TEXTENCODING_APPLE_ROMAN },
453 : { "MAC-UK", RTL_TEXTENCODING_APPLE_ROMAN },
454 : { "MACINTOSH", RTL_TEXTENCODING_APPLE_ROMAN }, /* MAC */
455 : { "MSZ_7795.3", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-86 */
456 : { "NATS-DANO", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-9-1 */
457 : { "NATS-DANO-ADD", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-9-2 */
458 : { "NATS-SEFI", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-8-1 */
459 : { "NATS-SEFI-ADD", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-8-2 */
460 : { "NC_NC00-10", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-151 */
461 : { "NEXTSTEP", RTL_TEXTENCODING_DONTKNOW }, /* NEXT */
462 : { "NF_Z_62-010", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-69 */
463 : { "NF_Z_62-010_(1973)", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-25 */
464 : { "NS_4551-1", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-60 */
465 : { "NS_4551-2", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-61 */
466 : { "PT", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-16 */
467 : { "PT2", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-84 */
468 : { "SAMI", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-158 */
469 : { "SEN_850200_B", RTL_TEXTENCODING_DONTKNOW }, /* ISO646-[FI|SE] */
470 : { "SEN_850200_C", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-11 */
471 : { "T.101-G2", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-128 */
472 : { "T.61-7BIT", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-102 */
473 : { "T.61-8BIT", RTL_TEXTENCODING_DONTKNOW }, /* T.61 ISO-IR-103 */
474 : { "TIS-620", RTL_TEXTENCODING_MS_874 }, /* locale: th_TH */
475 : { "UTF-8", RTL_TEXTENCODING_UTF8 }, /* ISO-10646/UTF-8 */
476 : { "VIDEOTEX-SUPPL", RTL_TEXTENCODING_DONTKNOW }, /* ISO-IR-70 */
477 : { "WIN-SAMI-2", RTL_TEXTENCODING_DONTKNOW } /* WS2 */
478 : };
479 :
480 : #elif defined(FREEBSD) || defined(DRAGONFLY)
481 :
482 : const _pair _nl_language_list[] = {
483 : { "ASCII", RTL_TEXTENCODING_ASCII_US }, /* US-ASCII */
484 : { "BIG5", RTL_TEXTENCODING_BIG5 }, /* China - Traditional Chinese */
485 : { "CP1251", RTL_TEXTENCODING_MS_1251 }, /* MS-CYRL */
486 : { "CP866", RTL_TEXTENCODING_IBM_866 }, /* CP866 866 */
487 : { "EUCCN", RTL_TEXTENCODING_EUC_CN }, /* China - Simplified Chinese */
488 : { "EUCJP", RTL_TEXTENCODING_EUC_JP }, /* Japan */
489 : { "EUCKR", RTL_TEXTENCODING_EUC_KR }, /* Korea */
490 : { "ISO8859-1", RTL_TEXTENCODING_ISO_8859_1 }, /* Western */
491 : { "ISO8859-15", RTL_TEXTENCODING_ISO_8859_15 }, /* Western Updated (w/Euro sign) */
492 : { "ISO8859-2", RTL_TEXTENCODING_ISO_8859_2 }, /* Central European */
493 : { "ISO8859-4", RTL_TEXTENCODING_ISO_8859_4 }, /* LATIN4 L4 */
494 : { "ISO8859-5", RTL_TEXTENCODING_ISO_8859_5 }, /* Cyrillic */
495 : { "ISO8859-7", RTL_TEXTENCODING_ISO_8859_7 }, /* Greek */
496 : { "ISO8859-9", RTL_TEXTENCODING_ISO_8859_9 }, /* Turkish */
497 : { "KOI8-R", RTL_TEXTENCODING_KOI8_R }, /* KOI8-R */
498 : { "KOI8-U", RTL_TEXTENCODING_KOI8_U }, /* KOI8-U */
499 : { "SJIS", RTL_TEXTENCODING_SHIFT_JIS }, /* Japan */
500 : { "US-ASCII", RTL_TEXTENCODING_ASCII_US }, /* US-ASCII */
501 : { "UTF-8", RTL_TEXTENCODING_UTF8 } /* ISO-10646/UTF-8 */
502 : };
503 :
504 : #elif defined(NETBSD)
505 :
506 : const _pair _nl_language_list[] = {
507 : { "ASCII", RTL_TEXTENCODING_ASCII_US }, /* US-ASCII */
508 : { "BIG5", RTL_TEXTENCODING_BIG5 }, /* China - Traditional Chinese */
509 : { "Big5", RTL_TEXTENCODING_BIG5 }, /* China - Traditional Chinese */
510 : { "Big5-HKSCS", RTL_TEXTENCODING_BIG5_HKSCS }, /* locale: zh_CN.BIG5HK */
511 : { "Big5HKSCS", RTL_TEXTENCODING_BIG5_HKSCS }, /* deprecated */
512 : { "CP1251", RTL_TEXTENCODING_MS_1251 }, /* MS-CYRL */
513 : { "CP866", RTL_TEXTENCODING_IBM_866 }, /* CP866 866 */
514 : { "CTEXT", RTL_TEXTENCODING_ASCII_US }, /* US-ASCII */
515 : { "eucCN", RTL_TEXTENCODING_EUC_CN }, /* China - Simplified Chinese */
516 : { "eucJP", RTL_TEXTENCODING_EUC_JP }, /* Japan */
517 : { "eucKR", RTL_TEXTENCODING_EUC_KR }, /* Korea */
518 : { "eucTW", RTL_TEXTENCODING_EUC_TW }, /* China - Traditional Chinese */
519 : { "GB18030", RTL_TEXTENCODING_GB_18030 }, /* locale: zh_CN.gb18030 */
520 : { "GB2312", RTL_TEXTENCODING_GB_2312 }, /* locale: zh_CN */
521 : { "ISO-2022-JP", RTL_TEXTENCODING_DONTKNOW }, /* */
522 : { "ISO-2022-JP-2", RTL_TEXTENCODING_DONTKNOW }, /* */
523 : { "ISO8859-1", RTL_TEXTENCODING_ISO_8859_1 }, /* Western */
524 : { "ISO8859-13", RTL_TEXTENCODING_ISO_8859_13 }, /* ISO-IR-179 LATIN7 */
525 : { "ISO8859-15", RTL_TEXTENCODING_ISO_8859_15 }, /* Western Updated (w/Euro sign) */
526 : { "ISO8859-2", RTL_TEXTENCODING_ISO_8859_2 }, /* Central European */
527 : { "ISO8859-4", RTL_TEXTENCODING_ISO_8859_4 }, /* LATIN4 L4 */
528 : { "ISO8859-5", RTL_TEXTENCODING_ISO_8859_5 }, /* Cyrillic */
529 : { "ISO8859-7", RTL_TEXTENCODING_ISO_8859_7 }, /* Greek */
530 : { "ISO8859-9", RTL_TEXTENCODING_ISO_8859_9 }, /* Turkish */
531 : { "KOI8-R", RTL_TEXTENCODING_KOI8_R }, /* KOI8-R */
532 : { "KOI8-U", RTL_TEXTENCODING_KOI8_U }, /* KOI8-U */
533 : { "PT154", RTL_TEXTENCODING_PT154 }, /* */
534 : { "SJIS", RTL_TEXTENCODING_SHIFT_JIS }, /* Japan */
535 : { "US-ASCII", RTL_TEXTENCODING_ASCII_US }, /* US-ASCII */
536 : { "UTF-8", RTL_TEXTENCODING_UTF8 } /* ISO-10646/UTF-8 */
537 : };
538 :
539 : #elif defined(OPENBSD)
540 :
541 : const _pair _nl_language_list[] = {
542 : { "ASCII", RTL_TEXTENCODING_ASCII_US }, /* US-ASCII */
543 : { "BIG5", RTL_TEXTENCODING_BIG5 }, /* China - Traditional Chinese */
544 : { "CP1251", RTL_TEXTENCODING_MS_1251 }, /* MS-CYRL */
545 : { "CP866", RTL_TEXTENCODING_IBM_866 }, /* CP866 866 */
546 : { "EUCCN", RTL_TEXTENCODING_EUC_CN }, /* China - Simplified Chinese */
547 : { "EUCJP", RTL_TEXTENCODING_EUC_JP }, /* Japan */
548 : { "EUCKR", RTL_TEXTENCODING_EUC_KR }, /* Korea */
549 : { "ISO8859-1", RTL_TEXTENCODING_ISO_8859_1 }, /* Western */
550 : { "ISO8859-15", RTL_TEXTENCODING_ISO_8859_15 }, /* Western Updated (w/Euro sign) */
551 : { "ISO8859-2", RTL_TEXTENCODING_ISO_8859_2 }, /* Central European */
552 : { "ISO8859-4", RTL_TEXTENCODING_ISO_8859_4 }, /* LATIN4 L4 */
553 : { "ISO8859-5", RTL_TEXTENCODING_ISO_8859_5 }, /* Cyrillic */
554 : { "ISO8859-7", RTL_TEXTENCODING_ISO_8859_7 }, /* Greek */
555 : { "ISO8859-9", RTL_TEXTENCODING_ISO_8859_9 }, /* Turkish */
556 : { "KOI8-R", RTL_TEXTENCODING_KOI8_R }, /* KOI8-R */
557 : { "KOI8-U", RTL_TEXTENCODING_KOI8_U }, /* KOI8-U */
558 : { "SJIS", RTL_TEXTENCODING_SHIFT_JIS }, /* Japan */
559 : { "US-ASCII", RTL_TEXTENCODING_ASCII_US }, /* US-ASCII */
560 : { "UTF-8", RTL_TEXTENCODING_UTF8 } /* ISO-10646/UTF-8 */
561 : };
562 :
563 : #endif /* ifdef SOLARIS LINUX FREEBSD NETBSD OPENBSD */
564 :
565 : static pthread_mutex_t aLocalMutex = PTHREAD_MUTEX_INITIALIZER;
566 :
567 : /*****************************************************************************
568 : return the text encoding corresponding to the given locale
569 : *****************************************************************************/
570 :
571 1247 : rtl_TextEncoding osl_getTextEncodingFromLocale( rtl_Locale * pLocale )
572 : {
573 1247 : const _pair *language=0;
574 :
575 1247 : char locale_buf[64] = "";
576 : char codeset_buf[64];
577 :
578 1247 : char *ctype_locale = 0;
579 1247 : char *codeset = 0;
580 :
581 : /* default to process locale if pLocale == NULL */
582 1247 : if( NULL == pLocale )
583 1247 : osl_getProcessLocale( &pLocale );
584 :
585 : /* convert rtl_Locale to locale string */
586 1247 : _compose_locale( pLocale, locale_buf, 64 );
587 :
588 : /* basic thread safeness */
589 1247 : pthread_mutex_lock( &aLocalMutex );
590 :
591 : /* remember the charset as indicated by the LC_CTYPE locale */
592 1247 : ctype_locale = setlocale( LC_CTYPE, NULL );
593 :
594 : /* set the desired LC_CTYPE locale */
595 1247 : if( NULL == setlocale( LC_CTYPE, locale_buf ) )
596 : {
597 0 : pthread_mutex_unlock(&aLocalMutex);
598 0 : return RTL_TEXTENCODING_DONTKNOW;
599 : }
600 :
601 : /* get the charset as indicated by the LC_CTYPE locale */
602 : #if defined(NETBSD) && !defined(CODESET)
603 : codeset = NULL;
604 : #else
605 1247 : codeset = nl_langinfo( CODESET );
606 : #endif
607 :
608 1247 : if ( codeset != NULL )
609 : {
610 : /* get codeset into mt save memory */
611 1247 : strncpy( codeset_buf, codeset, sizeof(codeset_buf) );
612 1247 : codeset_buf[sizeof(codeset_buf) - 1] = 0;
613 1247 : codeset = codeset_buf;
614 : }
615 :
616 : /* restore the original value of locale */
617 1247 : if ( ctype_locale != NULL )
618 1247 : setlocale( LC_CTYPE, ctype_locale );
619 :
620 1247 : pthread_mutex_unlock( &aLocalMutex );
621 :
622 : /* search the codeset in our language list */
623 1247 : if ( codeset != NULL )
624 : {
625 1247 : language = _pair_search (codeset, _nl_language_list, SAL_N_ELEMENTS( _nl_language_list ) );
626 : }
627 :
628 : OSL_ASSERT( language && ( RTL_TEXTENCODING_DONTKNOW != language->value ) );
629 :
630 : /* a matching item in our list provides a mapping from codeset to
631 : * rtl-codeset */
632 1247 : if ( language != NULL )
633 1247 : return language->value;
634 :
635 0 : return RTL_TEXTENCODING_DONTKNOW;
636 : }
637 :
638 : /*****************************************************************************
639 : return the current process locale
640 : *****************************************************************************/
641 :
642 1247 : void _imp_getProcessLocale( rtl_Locale ** ppLocale )
643 : {
644 : char * locale;
645 :
646 : /* basic thread safeness */
647 1247 : pthread_mutex_lock( &aLocalMutex );
648 :
649 : /* set the locale defined by the env vars */
650 1247 : locale = setlocale( LC_CTYPE, "" );
651 :
652 : /* fallback to the current locale */
653 1247 : if( NULL == locale )
654 0 : locale = setlocale( LC_CTYPE, NULL );
655 :
656 : /* return the LC_CTYPE locale */
657 1247 : *ppLocale = _parse_locale( locale );
658 :
659 1247 : pthread_mutex_unlock( &aLocalMutex );
660 1247 : }
661 :
662 : /*****************************************************************************
663 : set the current process locale
664 : *****************************************************************************/
665 :
666 0 : int _imp_setProcessLocale( rtl_Locale * pLocale )
667 : {
668 0 : char locale_buf[64] = "";
669 0 : int ret = 0;
670 :
671 : /* convert rtl_Locale to locale string */
672 0 : _compose_locale( pLocale, locale_buf, 64 );
673 :
674 : /* basic thread safeness */
675 0 : pthread_mutex_lock( &aLocalMutex );
676 :
677 : /* try to set LC_ALL locale */
678 0 : if( NULL == setlocale( LC_ALL, locale_buf ) )
679 0 : ret = -1;
680 :
681 0 : pthread_mutex_unlock( &aLocalMutex );
682 0 : return ret;
683 : }
684 :
685 : #else /* ifdef LINUX || SOLARIS || MACOSX || NETBSD */
686 :
687 : /*
688 : * This implementation of osl_getTextEncodingFromLocale maps
689 : * from the ISO language codes.
690 : */
691 :
692 : const _pair _full_locale_list[] = {
693 : { "ja_JP.eucJP", RTL_TEXTENCODING_EUC_JP },
694 : { "ja_JP.EUC", RTL_TEXTENCODING_EUC_JP },
695 : { "ko_KR.EUC", RTL_TEXTENCODING_EUC_KR },
696 : { "zh_CN.EUC", RTL_TEXTENCODING_EUC_CN },
697 : { "zh_TW.EUC", RTL_TEXTENCODING_EUC_TW }
698 : };
699 :
700 : const _pair _locale_extension_list[] = {
701 : { "big5", RTL_TEXTENCODING_BIG5 },
702 : { "big5hk", RTL_TEXTENCODING_BIG5_HKSCS },
703 : { "gb18030", RTL_TEXTENCODING_GB_18030 },
704 : { "euc", RTL_TEXTENCODING_EUC_JP },
705 : { "iso8859-1", RTL_TEXTENCODING_ISO_8859_1 },
706 : { "iso8859-10", RTL_TEXTENCODING_ISO_8859_10 },
707 : { "iso8859-13", RTL_TEXTENCODING_ISO_8859_13 },
708 : { "iso8859-14", RTL_TEXTENCODING_ISO_8859_14 },
709 : { "iso8859-15", RTL_TEXTENCODING_ISO_8859_15 },
710 : { "iso8859-2", RTL_TEXTENCODING_ISO_8859_2 },
711 : { "iso8859-3", RTL_TEXTENCODING_ISO_8859_3 },
712 : { "iso8859-4", RTL_TEXTENCODING_ISO_8859_4 },
713 : { "iso8859-5", RTL_TEXTENCODING_ISO_8859_5 },
714 : { "iso8859-6", RTL_TEXTENCODING_ISO_8859_6 },
715 : { "iso8859-7", RTL_TEXTENCODING_ISO_8859_7 },
716 : { "iso8859-8", RTL_TEXTENCODING_ISO_8859_8 },
717 : { "iso8859-9", RTL_TEXTENCODING_ISO_8859_9 },
718 : { "koi8-r", RTL_TEXTENCODING_KOI8_R },
719 : { "koi8-u", RTL_TEXTENCODING_KOI8_U },
720 : { "pck", RTL_TEXTENCODING_MS_932 },
721 : #if (0)
722 : { "sun_eu_greek", RTL_TEXTENCODING_DONTKNOW },
723 : #endif
724 : { "utf-16", RTL_TEXTENCODING_UNICODE },
725 : { "utf-7", RTL_TEXTENCODING_UTF7 },
726 : { "utf-8", RTL_TEXTENCODING_UTF8 }
727 : };
728 :
729 : const _pair _iso_language_list[] = {
730 : { "af", RTL_TEXTENCODING_ISO_8859_1 },
731 : { "ar", RTL_TEXTENCODING_ISO_8859_6 },
732 : { "az", RTL_TEXTENCODING_ISO_8859_9 },
733 : { "be", RTL_TEXTENCODING_ISO_8859_5 },
734 : { "bg", RTL_TEXTENCODING_ISO_8859_5 },
735 : { "ca", RTL_TEXTENCODING_ISO_8859_1 },
736 : { "cs", RTL_TEXTENCODING_ISO_8859_2 },
737 : { "da", RTL_TEXTENCODING_ISO_8859_1 },
738 : { "de", RTL_TEXTENCODING_ISO_8859_1 },
739 : { "el", RTL_TEXTENCODING_ISO_8859_7 },
740 : { "en", RTL_TEXTENCODING_ISO_8859_1 },
741 : { "es", RTL_TEXTENCODING_ISO_8859_1 },
742 : { "et", RTL_TEXTENCODING_ISO_8859_4 },
743 : { "eu", RTL_TEXTENCODING_ISO_8859_1 },
744 : { "fa", RTL_TEXTENCODING_ISO_8859_6 },
745 : { "fi", RTL_TEXTENCODING_ISO_8859_1 },
746 : { "fo", RTL_TEXTENCODING_ISO_8859_1 },
747 : { "fr", RTL_TEXTENCODING_ISO_8859_1 },
748 : { "gr", RTL_TEXTENCODING_ISO_8859_7 },
749 : { "he", RTL_TEXTENCODING_ISO_8859_8 },
750 : { "hi", RTL_TEXTENCODING_DONTKNOW },
751 : { "hr", RTL_TEXTENCODING_ISO_8859_2 },
752 : { "hu", RTL_TEXTENCODING_ISO_8859_2 },
753 : { "hy", RTL_TEXTENCODING_DONTKNOW },
754 : { "id", RTL_TEXTENCODING_ISO_8859_1 },
755 : { "is", RTL_TEXTENCODING_ISO_8859_1 },
756 : { "it", RTL_TEXTENCODING_ISO_8859_1 },
757 : { "iw", RTL_TEXTENCODING_ISO_8859_8 },
758 : { "ja", RTL_TEXTENCODING_EUC_JP },
759 : { "ka", RTL_TEXTENCODING_DONTKNOW },
760 : { "kk", RTL_TEXTENCODING_ISO_8859_5 },
761 : { "ko", RTL_TEXTENCODING_EUC_KR },
762 : { "lt", RTL_TEXTENCODING_ISO_8859_4 },
763 : { "lv", RTL_TEXTENCODING_ISO_8859_4 },
764 : { "mk", RTL_TEXTENCODING_ISO_8859_5 },
765 : { "mr", RTL_TEXTENCODING_DONTKNOW },
766 : { "ms", RTL_TEXTENCODING_ISO_8859_1 },
767 : { "nl", RTL_TEXTENCODING_ISO_8859_1 },
768 : { "no", RTL_TEXTENCODING_ISO_8859_1 },
769 : { "pl", RTL_TEXTENCODING_ISO_8859_2 },
770 : { "pt", RTL_TEXTENCODING_ISO_8859_1 },
771 : { "ro", RTL_TEXTENCODING_ISO_8859_2 },
772 : { "ru", RTL_TEXTENCODING_ISO_8859_5 },
773 : { "sa", RTL_TEXTENCODING_DONTKNOW },
774 : { "sk", RTL_TEXTENCODING_ISO_8859_2 },
775 : { "sl", RTL_TEXTENCODING_ISO_8859_2 },
776 : { "sq", RTL_TEXTENCODING_ISO_8859_2 },
777 : { "sv", RTL_TEXTENCODING_ISO_8859_1 },
778 : { "sw", RTL_TEXTENCODING_ISO_8859_1 },
779 : { "ta", RTL_TEXTENCODING_DONTKNOW },
780 : { "th", RTL_TEXTENCODING_DONTKNOW },
781 : { "tr", RTL_TEXTENCODING_ISO_8859_9 },
782 : { "tt", RTL_TEXTENCODING_ISO_8859_5 },
783 : { "uk", RTL_TEXTENCODING_ISO_8859_5 },
784 : { "ur", RTL_TEXTENCODING_ISO_8859_6 },
785 : { "uz", RTL_TEXTENCODING_ISO_8859_9 },
786 : { "vi", RTL_TEXTENCODING_DONTKNOW },
787 : { "zh", RTL_TEXTENCODING_BIG5 }
788 : };
789 :
790 : /*****************************************************************************
791 : return the text encoding corresponding to the given locale
792 : *****************************************************************************/
793 :
794 : rtl_TextEncoding osl_getTextEncodingFromLocale( rtl_Locale * pLocale )
795 : {
796 : const _pair *language = 0;
797 : char locale_buf[64] = "";
798 : char *cp;
799 :
800 : /* default to process locale if pLocale == NULL */
801 : if( NULL == pLocale )
802 : osl_getProcessLocale( &pLocale );
803 :
804 : /* convert rtl_Locale to locale string */
805 : if( _compose_locale( pLocale, locale_buf, 64 ) )
806 : {
807 : /* check special handling list (EUC) first */
808 : language = _pair_search( locale_buf, _full_locale_list, SAL_N_ELEMENTS( _full_locale_list ) );
809 :
810 : if( NULL == language )
811 : {
812 : /*
813 : * check if there is a charset qualifier at the end of the given locale string
814 : * e.g. de.ISO8859-15 or de.ISO8859-15@euro which strongly indicates what
815 : * charset to use
816 : */
817 : cp = strrchr( locale_buf, '.' );
818 :
819 : if( NULL != cp )
820 : {
821 : language = _pair_search( cp + 1, _locale_extension_list, SAL_N_ELEMENTS( _locale_extension_list ) );
822 : }
823 : }
824 :
825 : /* use iso language code to determine the charset */
826 : if( NULL == language )
827 : {
828 : /* iso lang codes have 2 charaters */
829 : locale_buf[2] = '\0';
830 :
831 : language = _pair_search( locale_buf, _iso_language_list, SAL_N_ELEMENTS( _iso_language_list ) );
832 : }
833 : }
834 :
835 : /* a matching item in our list provides a mapping from codeset to
836 : * rtl-codeset */
837 : if ( language != NULL )
838 : return language->value;
839 :
840 : return RTL_TEXTENCODING_DONTKNOW;
841 : }
842 :
843 : #if defined(MACOSX) || defined(IOS)
844 : #include "system.h"
845 :
846 : /* OS X locale discovery function */
847 : int (*pGetOSXLocale)( char *, sal_uInt32 );
848 :
849 : /*****************************************************************************
850 : return the current process locale
851 : *****************************************************************************/
852 :
853 : int macosx_getLocale(char *locale, sal_uInt32 bufferLen);
854 :
855 : void _imp_getProcessLocale( rtl_Locale ** ppLocale )
856 : {
857 : static char *locale = NULL;
858 :
859 : /* basic thread safeness */
860 : // pthread_mutex_lock( &aLocalMutex );
861 :
862 : /* Only fetch the locale once and cache it */
863 : if ( NULL == locale )
864 : {
865 :
866 : locale = (char *)malloc( 128 );
867 : if ( locale )
868 : macosx_getLocale( locale, 128 );
869 : else
870 : fprintf( stderr, "nlsupport.c: locale allocation returned NULL!\n" );
871 : }
872 :
873 : /* handle the case where OS specific method of finding locale fails */
874 : if ( NULL == locale )
875 : {
876 : /* simulate behavior of setlocale */
877 : locale = getenv( "LC_ALL" );
878 :
879 : if( NULL == locale )
880 : locale = getenv( "LC_CTYPE" );
881 :
882 : if( NULL == locale )
883 : locale = getenv( "LANG" );
884 :
885 : if( NULL == locale )
886 : locale = "C";
887 : }
888 :
889 : /* return the locale */
890 : *ppLocale = _parse_locale( locale );
891 :
892 : setenv( "LC_ALL", locale, 1);
893 : setenv("LC_CTYPE", locale, 1 );
894 : setenv("LANG", locale, 1 );
895 :
896 : #if OSL_DEBUG_LEVEL > 1
897 : OSL_TRACE("_imp_getProcessLocale() returning %s as current locale.", locale );
898 : #endif
899 :
900 : // pthread_mutex_unlock( &aLocalMutex );
901 :
902 : }
903 : #else
904 : /*****************************************************************************
905 : return the current process locale
906 : *****************************************************************************/
907 :
908 : void _imp_getProcessLocale( rtl_Locale ** ppLocale )
909 : {
910 : /* simulate behavior off setlocale */
911 : char * locale = getenv( "LC_ALL" );
912 :
913 : if( NULL == locale )
914 : locale = getenv( "LC_CTYPE" );
915 :
916 : if( NULL == locale )
917 : locale = getenv( "LANG" );
918 :
919 : if( NULL == locale )
920 : #ifdef ANDROID
921 : locale = "en-US.UTF-8";
922 : #else
923 : locale = "C";
924 : #endif
925 :
926 : *ppLocale = _parse_locale( locale );
927 : }
928 : #endif
929 :
930 : /*****************************************************************************
931 : set the current process locale
932 : *****************************************************************************/
933 :
934 : static int
935 : _setenv (const char* name, const char* value)
936 : {
937 : return setenv (name, value, 1);
938 : }
939 :
940 : int _imp_setProcessLocale( rtl_Locale * pLocale )
941 : {
942 : char locale_buf[64];
943 :
944 : /* convert rtl_Locale to locale string */
945 : if( NULL != _compose_locale( pLocale, locale_buf, 64 ) )
946 : {
947 : /* only change env vars that exist already */
948 : if( getenv( "LC_ALL" ) )
949 : _setenv( "LC_ALL", locale_buf );
950 :
951 : if( getenv( "LC_CTYPE" ) )
952 : _setenv("LC_CTYPE", locale_buf );
953 :
954 : if( getenv( "LANG" ) )
955 : _setenv( "LANG", locale_buf );
956 : }
957 :
958 : return 0;
959 : }
960 :
961 : #endif /* ifdef LINUX || SOLARIS || MACOSX || NETBSD || AIX */
962 :
963 :
964 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|