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