1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru **********************************************************************
354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius *   Copyright (C) 1997-2012, International Business Machines
4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *   Corporation and others.  All Rights Reserved.
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru **********************************************************************
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* File locid.cpp
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Created by: Richard Gillam
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History:
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   Date        Name        Description
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   02/11/97    aliu        Changed gLocPath to fgDataDirectory and added
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                           methods to get and set it.
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   04/02/97    aliu        Made operator!= inline; fixed return value
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                           of getName().
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   04/15/97    aliu        Cleanup for AIX/Win32.
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   04/24/97    aliu        Numerous changes per code review.
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   08/18/98    stephen     Changed getDisplayName()
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                           Added SIMPLIFIED_CHINESE, TRADITIONAL_CHINESE
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                           Added getISOCountries(), getISOLanguages(),
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                           getLanguagesForCountry()
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   03/16/99    bertrand    rehaul.
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   07/21/99    stephen     Added U_CFUNC setDefault
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   11/09/99    weiv        Added const char * getName() const;
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   04/12/00    srl         removing unicodestring api's and cached hash code
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   08/10/01    grhoten     Change the static Locales to accessor functions
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/locid.h"
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uloc.h"
35103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "putilimp.h"
3654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "mutex.h"
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h"
38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uassert.h"
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h"
40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h"
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uhash.h"
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucln_cmn.h"
43103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "ustr_imp.h"
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
4754dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CDECL_BEGIN
4854dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UBool U_CALLCONV locale_cleanup(void);
4954dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CDECL_END
5054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
5154dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_NAMESPACE_BEGIN
5254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
5354dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic Locale *gLocaleCache = NULL;
5454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
5554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// gDefaultLocaleMutex protects all access to gDefaultLocalesHashT and gDefaultLocale.
5654dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex gDefaultLocaleMutex = U_MUTEX_INITIALIZER;
5754dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UHashtable *gDefaultLocalesHashT = NULL;
5854dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic Locale *gDefaultLocale = NULL;
5954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
6054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_NAMESPACE_END
6154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef enum ELocalePos {
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eENGLISH,
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eFRENCH,
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eGERMAN,
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eITALIAN,
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eJAPANESE,
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eKOREAN,
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eCHINESE,
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eFRANCE,
72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eGERMANY,
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eITALY,
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eJAPAN,
75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eKOREA,
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eCHINA,      /* Alias for PRC */
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eTAIWAN,
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eUK,
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eUS,
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eCANADA,
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eCANADA_FRENCH,
8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    eROOT,
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //eDEFAULT,
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    eMAX_LOCALES
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} ELocalePos;
88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC int32_t locale_getKeywords(const char *localeID,
90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            char prev,
91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            char *keywords, int32_t keywordCapacity,
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            char *values, int32_t valuesCapacity, int32_t *valLen,
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UBool valuesToo,
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UErrorCode *status);
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Deleter function for Locales owned by the default Locale hash table/
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV
101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerudeleteLocale(void *obj) {
102103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    delete (icu::Locale *) obj;
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool U_CALLCONV locale_cleanup(void)
106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_NAMESPACE_USE
108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (gLocaleCache) {
110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete [] gLocaleCache;
111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        gLocaleCache = NULL;
112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (gDefaultLocalesHashT) {
115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uhash_close(gDefaultLocalesHashT);   // Automatically deletes all elements, using deleter func.
116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        gDefaultLocalesHashT = NULL;
11754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        gDefaultLocale = NULL;
118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return TRUE;
121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END
123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN
12554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
12654dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusLocale *locale_set_default_internal(const char *id, UErrorCode& status) {
12754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    // Synchronize this entire function.
12854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    Mutex lock(&gDefaultLocaleMutex);
12954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool canonicalize = FALSE;
131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // If given a NULL string for the locale id, grab the default
133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //   name from the system.
134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //   (Different from most other locale APIs, where a null name means use
135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //    the current ICU default locale.)
136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (id == NULL) {
13754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        id = uprv_getDefaultLocaleID();   // This function not thread safe? TODO: verify.
138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        canonicalize = TRUE; // always canonicalize host ID
139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char localeNameBuf[512];
142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (canonicalize) {
144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uloc_canonicalize(id, localeNameBuf, sizeof(localeNameBuf)-1, &status);
145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uloc_getName(id, localeNameBuf, sizeof(localeNameBuf)-1, &status);
147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    localeNameBuf[sizeof(localeNameBuf)-1] = 0;  // Force null termination in event of
149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                                 //   a long name filling the buffer.
150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                                 //   (long names are truncated.)
15154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                                 //
15254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (U_FAILURE(status)) {
15354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return gDefaultLocale;
154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
15654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (gDefaultLocalesHashT == NULL) {
15754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        gDefaultLocalesHashT = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
15954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            return gDefaultLocale;
160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
16154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        uhash_setValueDeleter(gDefaultLocalesHashT, deleteLocale);
16254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup);
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Locale *newDefault = (Locale *)uhash_get(gDefaultLocalesHashT, localeNameBuf);
16654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (newDefault == NULL) {
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        newDefault = new Locale(Locale::eBOGUS);
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (newDefault == NULL) {
16954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            status = U_MEMORY_ALLOCATION_ERROR;
17054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            return gDefaultLocale;
171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        newDefault->init(localeNameBuf, FALSE);
17354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        uhash_put(gDefaultLocalesHashT, (char*) newDefault->getName(), newDefault, &status);
17454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (U_FAILURE(status)) {
17554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            return gDefaultLocale;
176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
17854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    gDefaultLocale = newDefault;
17954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return gDefaultLocale;
180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
18154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END
183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* sfb 07/21/99 */
185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC void
186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querulocale_set_default(const char *id)
187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_NAMESPACE_USE
18954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UErrorCode status = U_ZERO_ERROR;
19054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    locale_set_default_internal(id, status);
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* end */
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC const char *
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querulocale_get_default(void)
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_NAMESPACE_USE
198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return Locale::getDefault().getName();
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(Locale)
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*Character separating the posix id fields*/
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// '_'
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// In the platform codepage.
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define SEP_CHAR '_'
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::~Locale()
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*if fullName is on the heap, we free it*/
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fullName != fullNameBuffer)
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(fullName);
217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fullName = NULL;
218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (baseName && baseName != baseNameBuffer) {
220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(baseName);
221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        baseName = NULL;
222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::Locale()
226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    : UObject(), fullName(fullNameBuffer), baseName(NULL)
227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    init(NULL, FALSE);
229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Internal constructor to allow construction of a locale object with
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *   NO side effects.   (Default constructor tries to get
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *   the default locale.)
235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::Locale(Locale::ELocaleType)
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    : UObject(), fullName(fullNameBuffer), baseName(NULL)
238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    setToBogus();
240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::Locale( const   char * newLanguage,
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                const   char * newCountry,
245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                const   char * newVariant,
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                const   char * newKeywords)
247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    : UObject(), fullName(fullNameBuffer), baseName(NULL)
248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if( (newLanguage==NULL) && (newCountry == NULL) && (newVariant == NULL) )
250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        init(NULL, FALSE); /* shortcut */
252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else
254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        MaybeStackArray<char, ULOC_FULLNAME_CAPACITY> togo;
256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t size = 0;
257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t lsize = 0;
258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t csize = 0;
259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t vsize = 0;
260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t ksize = 0;
261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        char    *p;
262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Calculate the size of the resulting string.
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Language
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ( newLanguage != NULL )
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            lsize = (int32_t)uprv_strlen(newLanguage);
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            size = lsize;
270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // _Country
273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ( newCountry != NULL )
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            csize = (int32_t)uprv_strlen(newCountry);
276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            size += csize;
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // _Variant
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ( newVariant != NULL )
281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // remove leading _'s
283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            while(newVariant[0] == SEP_CHAR)
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            {
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                newVariant++;
286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // remove trailing _'s
289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            vsize = (int32_t)uprv_strlen(newVariant);
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            while( (vsize>1) && (newVariant[vsize-1] == SEP_CHAR) )
291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            {
292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                vsize--;
293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if( vsize > 0 )
297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            size += vsize;
299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Separator rules:
302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ( vsize > 0 )
303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            size += 2;  // at least: __v
305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else if ( csize > 0 )
307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            size += 1;  // at least: _v
309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ( newKeywords != NULL)
312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ksize = (int32_t)uprv_strlen(newKeywords);
314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            size += ksize + 1;
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        //  NOW we have the full locale string..
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*if the whole string is longer than our internal limit, we need
321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        to go to the heap for temporary buffers*/
32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (size >= togo.getCapacity())
323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
324c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            // If togo_heap could not be created, initialize with default settings.
32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (togo.resize(size+1) == NULL) {
326c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                init(NULL, FALSE);
327c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            }
328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        togo[0] = 0;
331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Now, copy it back.
33350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        p = togo.getAlias();
334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ( lsize != 0 )
335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strcpy(p, newLanguage);
337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            p += lsize;
338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ( ( vsize != 0 ) || (csize != 0) )  // at least:  __v
341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {                                      //            ^
342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *p++ = SEP_CHAR;
343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ( csize != 0 )
346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strcpy(p, newCountry);
348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            p += csize;
349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ( vsize != 0)
352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *p++ = SEP_CHAR; // at least: __v
354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strncpy(p, newVariant, vsize);  // Must use strncpy because
356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            p += vsize;                          // of trimming (above).
357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *p = 0; // terminate
358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if ( ksize != 0)
361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (uprv_strchr(newKeywords, '=')) {
363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                *p++ = '@'; /* keyword parsing */
364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            else {
366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                *p++ = '_'; /* Variant parsing with a script */
367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if ( vsize == 0) {
368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    *p++ = '_'; /* No country found */
369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_strcpy(p, newKeywords);
372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            p += ksize;
373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Parse it, because for example 'language' might really be a complete
376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // string.
37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        init(togo.getAlias(), FALSE);
378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::Locale(const Locale &other)
382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    : UObject(other), fullName(fullNameBuffer), baseName(NULL)
383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *this = other;
385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale &Locale::operator=(const Locale &other)
388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (this == &other) {
390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return *this;
391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (&other == NULL) {
394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        this->setToBogus();
395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return *this;
396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Free our current storage */
399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(fullName != fullNameBuffer) {
400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(fullName);
401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fullName = fullNameBuffer;
402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Allocate the full name if necessary */
405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(other.fullName != other.fullNameBuffer) {
406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fullName = (char *)uprv_malloc(sizeof(char)*(uprv_strlen(other.fullName)+1));
407c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if (fullName == NULL) {
408c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            return *this;
409c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Copy the full name */
412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_strcpy(fullName, other.fullName);
413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* baseName is the cached result of getBaseName.  if 'other' has a
415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru       baseName and it fits in baseNameBuffer, then copy it. otherwise set
416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru       it to NULL, and let the user lazy-create it (in getBaseName) if they
417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru       want it. */
418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(baseName && baseName != baseNameBuffer) {
419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(baseName);
420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    baseName = NULL;
422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(other.baseName == other.baseNameBuffer) {
424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcpy(baseNameBuffer, other.baseNameBuffer);
425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        baseName = baseNameBuffer;
426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Copy the language and country fields */
429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_strcpy(language, other.language);
430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_strcpy(script, other.script);
431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_strcpy(country, other.country);
432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
43350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /* The variantBegin is an offset, just copy it */
434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    variantBegin = other.variantBegin;
435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fIsBogus = other.fIsBogus;
436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return *this;
437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale *
440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::clone() const {
441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return new Locale(*this);
442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool
445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::operator==( const   Locale& other) const
446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (uprv_strcmp(other.fullName, fullName) == 0);
448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
450103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define ISASCIIALPHA(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
451103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*This function initializes a Locale from a C locale ID*/
453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale& Locale::init(const char* localeID, UBool canonicalize)
454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fIsBogus = FALSE;
456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Free our current storage */
457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(fullName != fullNameBuffer) {
458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(fullName);
459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fullName = fullNameBuffer;
460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(baseName && baseName != baseNameBuffer) {
463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(baseName);
464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        baseName = NULL;
465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // not a loop:
468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // just an easy way to have a common error-exit
469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // without goto and without another function
470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    do {
471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        char *separator;
472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        char *field[5] = {0};
473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t fieldLen[5] = {0};
474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t fieldIdx;
475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t variantField;
476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t length;
477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UErrorCode err;
478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(localeID == NULL) {
480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // not an error, just set the default locale
481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return *this = getDefault();
482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* preset all fields to empty */
485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        language[0] = script[0] = country[0] = 0;
486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // "canonicalize" the locale ID to ICU/Java format
488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        err = U_ZERO_ERROR;
489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        length = canonicalize ?
490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uloc_canonicalize(localeID, fullName, sizeof(fullNameBuffer), &err) :
491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uloc_getName(localeID, fullName, sizeof(fullNameBuffer), &err);
492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(err == U_BUFFER_OVERFLOW_ERROR || length >= (int32_t)sizeof(fullNameBuffer)) {
494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /*Go to heap for the fullName if necessary*/
495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fullName = (char *)uprv_malloc(sizeof(char)*(length + 1));
496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(fullName == 0) {
497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fullName = fullNameBuffer;
498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break; // error: out of memory
499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            err = U_ZERO_ERROR;
501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            length = canonicalize ?
502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                uloc_canonicalize(localeID, fullName, length+1, &err) :
503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                uloc_getName(localeID, fullName, length+1, &err);
504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(U_FAILURE(err) || err == U_STRING_NOT_TERMINATED_WARNING) {
506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* should never occur */
507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        variantBegin = length;
511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* after uloc_getName/canonicalize() we know that only '_' are separators */
513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        separator = field[0] = fullName;
514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fieldIdx = 1;
515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        while ((separator = uprv_strchr(field[fieldIdx-1], SEP_CHAR)) && fieldIdx < (int32_t)(sizeof(field)/sizeof(field[0]))-1) {
516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            field[fieldIdx] = separator + 1;
517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fieldLen[fieldIdx-1] = (int32_t)(separator - field[fieldIdx-1]);
518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fieldIdx++;
519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // variant may contain @foo or .foo POSIX cruft; remove it
521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        separator = uprv_strchr(field[fieldIdx-1], '@');
522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        char* sep2 = uprv_strchr(field[fieldIdx-1], '.');
523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (separator!=NULL || sep2!=NULL) {
524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (separator==NULL || (sep2!=NULL && separator > sep2)) {
525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                separator = sep2;
526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fieldLen[fieldIdx-1] = (int32_t)(separator - field[fieldIdx-1]);
528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fieldLen[fieldIdx-1] = length - (int32_t)(field[fieldIdx-1] - fullName);
530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
532103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (fieldLen[0] >= (int32_t)(sizeof(language)))
533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
534103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            break; // error: the language field is too long
535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
537103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        variantField = 1; /* Usually the 2nd one, except when a script or country is also used. */
538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fieldLen[0] > 0) {
539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* We have a language */
540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_memcpy(language, fullName, fieldLen[0]);
541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            language[fieldLen[0]] = 0;
542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
543103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (fieldLen[1] == 4 && ISASCIIALPHA(field[1][0]) &&
544103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                ISASCIIALPHA(field[1][1]) && ISASCIIALPHA(field[1][2]) &&
545103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                ISASCIIALPHA(field[1][3])) {
546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* We have at least a script */
547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_memcpy(script, field[1], fieldLen[1]);
548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            script[fieldLen[1]] = 0;
549103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            variantField++;
550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
551103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
552103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (fieldLen[variantField] == 2 || fieldLen[variantField] == 3) {
553103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            /* We have a country */
554103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            uprv_memcpy(country, field[variantField], fieldLen[variantField]);
555103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            country[fieldLen[variantField]] = 0;
556103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            variantField++;
557103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else if (fieldLen[variantField] == 0) {
558103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            variantField++; /* script or country empty but variant in next field (i.e. en__POSIX) */
559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
560103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
561103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (fieldLen[variantField] > 0) {
562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* We have a variant */
563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            variantBegin = (int32_t)(field[variantField] - fullName);
564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // successful end of init()
567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return *this;
568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } while(0); /*loop doesn't iterate*/
569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // when an error occurs, then set this object to "bogus" (there is no UErrorCode here)
571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    setToBogus();
572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return *this;
574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t
577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::hashCode() const
578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
579103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return ustr_hashCharsN(fullName, uprv_strlen(fullName));
580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::setToBogus() {
584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Free our current storage */
585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(fullName != fullNameBuffer) {
586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(fullName);
587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fullName = fullNameBuffer;
588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
58950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if(baseName && baseName != baseNameBuffer) {
59050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        uprv_free(baseName);
59150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        baseName = NULL;
59250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *fullNameBuffer = 0;
594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *language = 0;
595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *script = 0;
596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *country = 0;
597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fIsBogus = TRUE;
598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale& U_EXPORT2
601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getDefault()
602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
60354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    {
60454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        Mutex lock(&gDefaultLocaleMutex);
60554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (gDefaultLocale != NULL) {
60654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            return *gDefaultLocale;
60754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
60954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UErrorCode status = U_ZERO_ERROR;
61054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return *locale_set_default_internal(NULL, status);
611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid U_EXPORT2
616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::setDefault( const   Locale&     newLocale,
617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            UErrorCode&  status)
618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Set the default from the full name string of the supplied locale.
624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * This is a convenient way to access the default locale caching mechanisms.
625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char *localeID = newLocale.getName();
62754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    locale_set_default_internal(localeID, status);
628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale U_EXPORT2
631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::createFromName (const char *name)
632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (name) {
634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        Locale l("");
635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        l.init(name, FALSE);
636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return l;
637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else {
639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return getDefault();
640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale U_EXPORT2
644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::createCanonical(const char* name) {
645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Locale loc("");
646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    loc.init(name, TRUE);
647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return loc;
648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char *
651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getISO3Language() const
652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uloc_getISO3Language(fullName);
654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char *
658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getISO3Country() const
659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uloc_getISO3Country(fullName);
661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return the LCID value as specified in the "LocaleID" resource for this
665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * locale.  The LocaleID must be expressed as a hexadecimal number, from
666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * one to four digits.  If the LocaleID resource is not present, or is
667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * in an incorrect format, 0 is returned.  The LocaleID is for use in
668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Windows (it is an LCID), but is available on all platforms.
669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuint32_t
671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getLCID() const
672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uloc_getLCID(fullName);
674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char* const* U_EXPORT2 Locale::getISOCountries()
677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uloc_getISOCountries();
679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char* const* U_EXPORT2 Locale::getISOLanguages()
682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uloc_getISOLanguages();
684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Set the locale's data based on a posix id.
687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Locale::setFromPOSIXID(const char *posixID)
688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    init(posixID, TRUE);
690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
69350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoLocale::getRoot(void)
69450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
69550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    return getLocale(eROOT);
69650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
69750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
69850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoconst Locale & U_EXPORT2
699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getEnglish(void)
700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eENGLISH);
702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getFrench(void)
706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eFRENCH);
708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getGerman(void)
712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eGERMAN);
714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getItalian(void)
718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eITALIAN);
720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getJapanese(void)
724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eJAPANESE);
726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getKorean(void)
730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eKOREAN);
732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getChinese(void)
736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eCHINESE);
738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getSimplifiedChinese(void)
742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eCHINA);
744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getTraditionalChinese(void)
748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eTAIWAN);
750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getFrance(void)
755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eFRANCE);
757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getGermany(void)
761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eGERMANY);
763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getItaly(void)
767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eITALY);
769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getJapan(void)
773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eJAPAN);
775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getKorea(void)
779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eKOREA);
781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getChina(void)
785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eCHINA);
787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getPRC(void)
791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eCHINA);
793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getTaiwan(void)
797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eTAIWAN);
799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getUK(void)
803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eUK);
805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getUS(void)
809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eUS);
811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getCanada(void)
815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eCANADA);
817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale & U_EXPORT2
820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getCanadaFrench(void)
821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return getLocale(eCANADA_FRENCH);
823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale &
826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getLocale(int locid)
827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Locale *localeCache = getLocaleCache();
829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_ASSERT((locid < eMAX_LOCALES)&&(locid>=0));
830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (localeCache == NULL) {
831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // Failure allocating the locale cache.
832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        //   The best we can do is return a NULL reference.
833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        locid = 0;
834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return localeCache[locid]; /*operating on NULL*/
836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThis function is defined this way in order to get around static
840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinitialization and static destruction.
841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale *
843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getLocaleCache(void)
844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    umtx_lock(NULL);
846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool needInit = (gLocaleCache == NULL);
847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    umtx_unlock(NULL);
848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (needInit) {
850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        Locale *tLocaleCache = new Locale[(int)eMAX_LOCALES];
851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (tLocaleCache == NULL) {
852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return NULL;
853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
85450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	tLocaleCache[eROOT]          = Locale("");
855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eENGLISH]       = Locale("en");
856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eFRENCH]        = Locale("fr");
857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eGERMAN]        = Locale("de");
858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eITALIAN]       = Locale("it");
859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eJAPANESE]      = Locale("ja");
860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eKOREAN]        = Locale("ko");
861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eCHINESE]       = Locale("zh");
862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eFRANCE]        = Locale("fr", "FR");
863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eGERMANY]       = Locale("de", "DE");
864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eITALY]         = Locale("it", "IT");
865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eJAPAN]         = Locale("ja", "JP");
866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eKOREA]         = Locale("ko", "KR");
867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eCHINA]         = Locale("zh", "CN");
868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eTAIWAN]        = Locale("zh", "TW");
869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eUK]            = Locale("en", "GB");
870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eUS]            = Locale("en", "US");
871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eCANADA]        = Locale("en", "CA");
872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        tLocaleCache[eCANADA_FRENCH] = Locale("fr", "CA");
873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        umtx_lock(NULL);
875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (gLocaleCache == NULL) {
876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            gLocaleCache = tLocaleCache;
877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            tLocaleCache = NULL;
878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup);
879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        umtx_unlock(NULL);
881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (tLocaleCache) {
882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete [] tLocaleCache;  // Fancy array delete will destruct each member.
883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return gLocaleCache;
886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass KeywordEnumeration : public StringEnumeration {
889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprivate:
890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char *keywords;
891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char *current;
892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t length;
893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UnicodeString currUSKey;
894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static const char fgClassID;/* Warning this is used beyond the typical RTTI usage. */
895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic:
897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    static UClassID U_EXPORT2 getStaticClassID(void) { return (UClassID)&fgClassID; }
898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual UClassID getDynamicClassID(void) const { return getStaticClassID(); }
899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic:
900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    KeywordEnumeration(const char *keys, int32_t keywordLen, int32_t currentIndex, UErrorCode &status)
901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        : keywords((char *)&fgClassID), current((char *)&fgClassID), length(0) {
902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(U_SUCCESS(status) && keywordLen != 0) {
903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(keys == NULL || keywordLen < 0) {
904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                status = U_ILLEGAL_ARGUMENT_ERROR;
905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                keywords = (char *)uprv_malloc(keywordLen+1);
907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (keywords == NULL) {
908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    status = U_MEMORY_ALLOCATION_ERROR;
909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                else {
911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    uprv_memcpy(keywords, keys, keywordLen);
912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    keywords[keywordLen] = 0;
913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    current = keywords + currentIndex;
914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    length = keywordLen;
915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
920103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    virtual ~KeywordEnumeration();
921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual StringEnumeration * clone() const
923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return new KeywordEnumeration(keywords, length, (int32_t)(current - keywords), status);
926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual int32_t count(UErrorCode &/*status*/) const {
929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        char *kw = keywords;
930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t result = 0;
931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        while(*kw) {
932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            result++;
933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            kw += uprv_strlen(kw)+1;
934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return result;
936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual const char* next(int32_t* resultLength, UErrorCode& status) {
939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const char* result;
940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t len;
941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(U_SUCCESS(status) && *current != 0) {
942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            result = current;
943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            len = (int32_t)uprv_strlen(current);
944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            current += len+1;
945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(resultLength != NULL) {
946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                *resultLength = len;
947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(resultLength != NULL) {
950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                *resultLength = 0;
951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            result = NULL;
953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return result;
955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual const UnicodeString* snext(UErrorCode& status) {
958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t resultLength = 0;
959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const char *s = next(&resultLength, status);
960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return setChars(s, resultLength, status);
961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    virtual void reset(UErrorCode& /*status*/) {
964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        current = keywords;
965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char KeywordEnumeration::fgClassID = '\0';
969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
970103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusKeywordEnumeration::~KeywordEnumeration() {
971103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    uprv_free(keywords);
972103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
973103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruStringEnumeration *
975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::createKeywords(UErrorCode &status) const
976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char keywords[256];
978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t keywordCapacity = 256;
979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    StringEnumeration *result = NULL;
980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char* variantStart = uprv_strchr(fullName, '@');
982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const char* assignment = uprv_strchr(fullName, '=');
983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(variantStart) {
984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(assignment > variantStart) {
985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t keyLen = locale_getKeywords(variantStart+1, '@', keywords, keywordCapacity, NULL, 0, NULL, FALSE, &status);
986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(keyLen) {
987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                result = new KeywordEnumeration(keywords, keyLen, 0, status);
988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status = U_INVALID_FORMAT_ERROR;
991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return result;
994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t
997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getKeywordValue(const char* keywordName, char *buffer, int32_t bufLen, UErrorCode &status) const
998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uloc_getKeywordValue(fullName, keywordName, buffer, bufLen, &status);
1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
100250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid
100350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoLocale::setKeywordValue(const char* keywordName, const char* keywordValue, UErrorCode &status)
100450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
100550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uloc_setKeywordValue(keywordName, keywordValue, fullName, ULOC_FULLNAME_CAPACITY, &status);
100650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
100750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char *
1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale::getBaseName() const
1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // lazy init
1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // semantically const
1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(baseName == 0) {
1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ((Locale *)this)->baseName = ((Locale *)this)->baseNameBuffer;
1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t baseNameSize = uloc_getBaseName(fullName, baseName, ULOC_FULLNAME_CAPACITY, &status);
1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(baseNameSize >= ULOC_FULLNAME_CAPACITY) {
1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ((Locale *)this)->baseName = (char *)uprv_malloc(sizeof(char) * baseNameSize + 1);
1019c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            if (baseName == NULL) {
1020c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                return baseName;
1021c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            }
1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uloc_getBaseName(fullName, baseName, baseNameSize+1, &status);
1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        baseName[baseNameSize] = 0;
102550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
102650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // the computation of variantBegin leaves it equal to the length
102750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // of fullName if there is no variant.  It should instead be
102850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // the length of the baseName.  Patch around this for now.
102927f654740f2a26ad62a5c155af9199af9e69b889claireho        if (variantBegin == (int32_t)uprv_strlen(fullName)) {
103050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho          ((Locale*)this)->variantBegin = baseNameSize;
103150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return baseName;
1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//eof
1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END
1038