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