LCOV - code coverage report
Current view: top level - libreoffice/sal/osl/unx - nlsupport.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 97 114 85.1 %
Date: 2012-12-27 Functions: 6 7 85.7 %
Legend: Lines: hit not hit

          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: */

Generated by: LCOV version 1.10