/*
 **********************************************************************
 *   Copyright (C) 1997-2001, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
*
* File locid.cpp
*
* Created by: Richard Gillam
*
* Modification History:
*
*   Date        Name        Description
*   02/11/97    aliu        Changed gLocPath to fgDataDirectory and added 
*                           methods to get and set it.
*   04/02/97    aliu        Made operator!= inline; fixed return value 
*                           of getName().
*   04/15/97    aliu        Cleanup for AIX/Win32.
*   04/24/97    aliu        Numerous changes per code review.
*   08/18/98    stephen     Changed getDisplayName()
*                           Added SIMPLIFIED_CHINESE, TRADITIONAL_CHINESE
*                           Added getISOCountries(), getISOLanguages(),
*                           getLanguagesForCountry()
*   03/16/99    bertrand    rehaul.
*   07/21/99    stephen     Added U_CFUNC setDefault
*   11/09/99    weiv        Added const char * getName() const;
*   04/12/00    srl         removing unicodestring api's and cached hash code
*   08/10/01    grhoten     Change the static Locales to accessor functions
******************************************************************************
*/


#include "unicode/locid.h"
#include "unicode/uloc.h"
#include "mutex.h"
#include "cmemory.h"
#include "cstring.h"
#include "uhash.h"
#include "ucln_cmn.h"

U_NAMESPACE_BEGIN

static Locale*  availableLocaleList = NULL;
static int32_t  availableLocaleListCount;
typedef enum ELocalePos {
    eENGLISH,
    eFRENCH,
    eGERMAN,
    eITALIAN,
    eJAPANESE,
    eKOREAN,
    eCHINESE,

    eFRANCE,
    eGERMANY,
    eITALY,
    eJAPAN,
    eKOREA,
    eCHINA,      /* Alias for PRC */
    eTAIWAN,
    eUK,
    eUS,
    eCANADA,
    eCANADA_FRENCH,


    eDEFAULT,
    eMAX_LOCALES
} ELocalePos;

/* Use void * to make it properly aligned */
/* Add 1 for rounding */
static void *gByteLocaleCache[(eMAX_LOCALES + 1) * sizeof(Locale) / sizeof(void*)];

static Locale *gLocaleCache = NULL;

U_NAMESPACE_END

UBool
locale_cleanup(void)
{
    U_NAMESPACE_USE

    if (availableLocaleList) {
        delete []availableLocaleList;
        availableLocaleList = NULL;
    }
    availableLocaleListCount = 0;
    if (gLocaleCache) {
        gLocaleCache[eDEFAULT].~Locale();
        gLocaleCache = NULL;
    }
    return TRUE;
}

U_NAMESPACE_BEGIN
void locale_set_default_internal(const char *id)
{
    U_NAMESPACE_USE

#ifdef ICU_LOCID_USE_DEPRECATES
    Locale::fgDefaultLocale.init(id);
#else
if (gLocaleCache == NULL) {
        Locale::initLocaleCache();
    }

    {
        Mutex lock;
        gLocaleCache[eDEFAULT].init(id);
    }
#endif
}
U_NAMESPACE_END

/* sfb 07/21/99 */
U_CFUNC void
locale_set_default(const char *id)
{
    U_NAMESPACE_USE

    locale_set_default_internal(id);
}
/* end */

U_CFUNC const char *
locale_get_default(void)
{
    U_NAMESPACE_USE

    return Locale::getDefault().getName();
}


U_NAMESPACE_BEGIN

/*Character separating the posix id fields*/
// '_'
// In the platform codepage.
#define SEP_CHAR '_'

/**
 * static variables
 */
#ifdef ICU_LOCID_USE_DEPRECATES
Locale Locale::fgDefaultLocale;

/**
 * Constant definitions
 */
const Locale  Locale::ENGLISH("en");
const Locale  Locale::FRENCH("fr");
const Locale  Locale::GERMAN("de");
const Locale  Locale::ITALIAN("it");
const Locale  Locale::JAPANESE("ja");
const Locale  Locale::KOREAN("ko");
const Locale  Locale::CHINESE("zh");
const Locale  Locale::SIMPLIFIED_CHINESE("zh", "CN");
const Locale  Locale::TRADITIONAL_CHINESE("zh", "TW");

// Useful constant for country.

const Locale  Locale::FRANCE    ("fr", "FR");
const Locale  Locale::GERMANY   ("de", "DE");
const Locale  Locale::ITALY     ("it", "IT");
const Locale  Locale::JAPAN     ("ja", "JP");
const Locale  Locale::KOREA     ("ko", "KR");
const Locale  Locale::CHINA     ("zh", "CN");
const Locale  Locale::PRC       ("zh", "CN");
const Locale  Locale::TAIWAN    ("zh", "TW");
const Locale  Locale::UK        ("en", "GB");
const Locale  Locale::US        ("en", "US");
const Locale  Locale::CANADA    ("en", "CA");
const Locale  Locale::CANADA_FRENCH("fr", "CA");

#else
const Locale::LocaleProxy Locale::ENGLISH  = {eENGLISH};
const Locale::LocaleProxy Locale::FRENCH   = {eFRENCH};
const Locale::LocaleProxy Locale::GERMAN   = {eGERMAN};
const Locale::LocaleProxy Locale::ITALIAN  = {eITALIAN};
const Locale::LocaleProxy Locale::JAPANESE = {eJAPANESE};
const Locale::LocaleProxy Locale::KOREAN   = {eKOREAN};
const Locale::LocaleProxy Locale::CHINESE  = {eCHINESE};
const Locale::LocaleProxy Locale::SIMPLIFIED_CHINESE={eCHINA};
const Locale::LocaleProxy Locale::TRADITIONAL_CHINESE={eTAIWAN};

const Locale::LocaleProxy Locale::FRANCE   = {eFRANCE};
const Locale::LocaleProxy Locale::GERMANY  = {eGERMANY};
const Locale::LocaleProxy Locale::ITALY    = {eITALY};
const Locale::LocaleProxy Locale::JAPAN    = {eJAPAN};
const Locale::LocaleProxy Locale::KOREA    = {eKOREA};
const Locale::LocaleProxy Locale::CHINA    = {eCHINA};
const Locale::LocaleProxy Locale::PRC      = {eCHINA};
const Locale::LocaleProxy Locale::TAIWAN   = {eTAIWAN};
const Locale::LocaleProxy Locale::UK       = {eUK};
const Locale::LocaleProxy Locale::US       = {eUS};
const Locale::LocaleProxy Locale::CANADA   = {eCANADA};
const Locale::LocaleProxy Locale::CANADA_FRENCH={eCANADA_FRENCH};

Locale::LocaleProxy::operator const Locale&(void) const
{
    return Locale::getLocale(magicLocaleNumber);
}

#endif

Locale::~Locale()
{   
    /*if fullName is on the heap, we free it*/
    if (fullName != fullNameBuffer) 
    {
        uprv_free(fullName);
        fullName = NULL;
    }
}

Locale::Locale()
    : fullName(fullNameBuffer)
{
    init(NULL);
}

Locale::Locale( const   char * newLanguage, 
                const   char * newCountry, 
                const   char * newVariant) 
    : fullName(fullNameBuffer)
{
    if( (newLanguage==NULL) && (newCountry == NULL) && (newVariant == NULL) )
    {
        init(NULL); /* shortcut */
    }
    else
    {
        char togo_stack[ULOC_FULLNAME_CAPACITY];
        char *togo;
        char *togo_heap = NULL;
        int32_t size = 0;
        int32_t lsize = 0;
        int32_t csize = 0;
        int32_t vsize = 0;
        char    *p;

        // Calculate the size of the resulting string.

        // Language
        if ( newLanguage != NULL )
        {
            lsize = (int32_t)uprv_strlen(newLanguage);
            size = lsize;
        }

        // _Country
        if ( newCountry != NULL )
        {
            csize = (int32_t)uprv_strlen(newCountry);
            size += csize;
        }

        // _Variant
        if ( newVariant != NULL )
        {
            // remove leading _'s
            while(newVariant[0] == SEP_CHAR)
            {
                newVariant++;
            }
            
            // remove trailing _'s
            vsize = (int32_t)uprv_strlen(newVariant);
            while( (vsize>1) && (newVariant[vsize-1] == SEP_CHAR) )
            {
                vsize--;
            }
        }

        if( vsize > 0 )
        {
            size += vsize;
        }

        // Separator rules:
        if ( vsize > 0 )
        {
            size += 2;  // at least: __v 
        }
        else if ( csize > 0 )
        {
            size += 1;  // at least: _v 
        }

        //  NOW we have the full locale string..

        /*if the whole string is longer than our internal limit, we need
        to go to the heap for temporary buffers*/
        if (size > ULOC_FULLNAME_CAPACITY)
        {
            togo_heap = (char *)uprv_malloc(sizeof(char)*(size+1));
            togo = togo_heap;
        }
        else
        {
            togo = togo_stack;
        }

        togo[0] = 0;

        // Now, copy it back.
        p = togo;
        if ( lsize != 0 )
        {
            uprv_strcpy(p, newLanguage);
            p += lsize;
        }

        if ( ( vsize != 0 ) || (csize != 0) )  // at least:  __v
        {                                      //            ^
            *p++ = SEP_CHAR;
        }

        if ( csize != 0 )
        { 
            uprv_strcpy(p, newCountry);
            p += csize;
        }

        if ( vsize != 0)
        {
            *p++ = SEP_CHAR; // at least: __v

            uprv_strncpy(p, newVariant, vsize);  // Must use strncpy because 
            p += vsize;                          // of trimming (above).
            *p = 0; // terminate
        }

        // Parse it, because for example 'language' might really be a complete
        // string.
        init(togo);

        if (togo_heap) {
            uprv_free(togo_heap);
        }
    }
}

Locale::Locale(const Locale &other)
    : fullName(fullNameBuffer)
{
    *this = other;
}

Locale &Locale::operator=(const Locale &other)
{
    /* Free our current storage */
    if(fullName != fullNameBuffer) {
        uprv_free(fullName);
        fullName = fullNameBuffer;
    }

    /* Allocate the full name if necessary */
    if(other.fullName != other.fullNameBuffer) {
        fullName = (char *)uprv_malloc(sizeof(char)*(uprv_strlen(other.fullName)+1));
    }

    /* Copy the full name */
    uprv_strcpy(fullName, other.fullName);

    /* Copy the language and country fields */
    uprv_strcpy(language, other.language);
    uprv_strcpy(country, other.country);

    /* The variantBegin is an offset into fullName, just copy it */
    variantBegin = other.variantBegin;
    fIsBogus = other.fIsBogus;
    return *this;
}

UBool
Locale::operator==( const   Locale& other) const
{
    return (uprv_strcmp(other.fullName, fullName) == 0);
}

/*This function initializes a Locale from a C locale ID*/
Locale& Locale::init(const char* localeID)
{
    fIsBogus = FALSE;
    /* Free our current storage */
    if(fullName != fullNameBuffer) {
        uprv_free(fullName);
        fullName = fullNameBuffer;
    }

    // not a loop:
    // just an easy way to have a common error-exit
    // without goto and without another function
    do {
        char *separator, *prev;
        int32_t length;
        UErrorCode err;

        if(localeID == NULL) {
            // not an error, just set the default locale
            break;
        }

        // "canonicalize" the locale ID to ICU/Java format
        err = U_ZERO_ERROR;
        length = uloc_getName(localeID, fullName, sizeof(fullNameBuffer), &err);
        if(U_FAILURE(err) || err == U_STRING_NOT_TERMINATED_WARNING) {
            /*Go to heap for the fullName if necessary*/
            fullName = (char *)uprv_malloc(sizeof(char)*(length + 1));
            if(fullName == 0) {
                fullName = fullNameBuffer;
                break;
            }
            err = U_ZERO_ERROR;
            length = uloc_getName(localeID, fullName, length + 1, &err);
        }
        if(U_FAILURE(err) || err == U_STRING_NOT_TERMINATED_WARNING) {
            /* should never occur */
            break;
        }

        /* preset all fields to empty */
        language[0] = country[0] = 0;
        variantBegin = uprv_strlen(fullName);

        /* after uloc_getName() we know that only '_' are separators */
        separator = uprv_strchr(fullName, SEP_CHAR);
        if(separator != 0) {
            /* there is a country field */
            length = separator - fullName;
            if(length > 0) {
                if(length >= (int32_t)sizeof(language)) {
                    break;
                }
                uprv_memcpy(language, fullName, length);
            }
            language[length] = 0;

            prev = separator + 1;
            separator = uprv_strchr(prev, SEP_CHAR);
            if(separator != 0) {
                /* there is a variant field */
                length = separator - prev;
                if(length > 0) {
                    if(length >= (int32_t)sizeof(country)) {
                        break;
                    }
                    uprv_memcpy(country, prev, length);
                }
                country[length] = 0;

                variantBegin = (separator + 1) - fullName;
            } else {
                /* variantBegin==strlen(fullName), length==strlen(language)==prev-1-fullName */
                if((variantBegin - length - 1) >= (int32_t)sizeof(country)) {
                    break;
                }
                uprv_strcpy(country, prev);
            }
        } else {
            /* variantBegin==strlen(fullName) */
            if(variantBegin >= (int32_t)sizeof(language)) {
                break;
            }
            uprv_strcpy(language, fullName);
        }

        // successful end of init()
        return *this;
    } while(0);

    if (gLocaleCache) {
        // when an error occurs, then set the default locale (there is no UErrorCode here)
        return *this = getLocale(eDEFAULT);
    }
    else {
        // Prevent any possible infinite recursion
        // for bad default Locale IDs
        return init("en");
    }
}

int32_t
Locale::hashCode() const 
{
    UHashTok hashKey;
    hashKey.pointer = fullName;
    return uhash_hashChars(hashKey);
}

void 
Locale::setToBogus() {
  /* Free our current storage */
  if(fullName != fullNameBuffer) {
      uprv_free(fullName);
      fullName = fullNameBuffer;
  }
  *fullNameBuffer = 0;
  *language = 0;
  *country = 0;
  fIsBogus = TRUE;
}

const Locale&
Locale::getDefault() 
{
#ifdef ICU_LOCID_USE_DEPRECATES
    return fgDefaultLocale;
#else
    return getLocale(eDEFAULT);
#endif
}

void 
Locale::setDefault( const   Locale&     newLocale, 
                            UErrorCode&  status) 
{
    if (U_FAILURE(status))
        return;

#ifdef ICU_LOCID_USE_DEPRECATES
    fgDefaultLocale = newLocale;
#else
    if (gLocaleCache == NULL) {
        initLocaleCache();
    }

    {
        Mutex lock;
        gLocaleCache[eDEFAULT] = newLocale;
    }
#endif
}

Locale
Locale::createFromName (const char *name)
{
    if (name) {
        Locale l;
        l.init(name);
        return l;
    }
    else {
        return getDefault();
    }
}


const char *
Locale::getISO3Language() const
{
    return uloc_getISO3Language(fullName);
}


const char *
Locale::getISO3Country() const
{
    return uloc_getISO3Country(fullName);
}

/**
 * Return the LCID value as specified in the "LocaleID" resource for this
 * locale.  The LocaleID must be expressed as a hexadecimal number, from
 * one to four digits.  If the LocaleID resource is not present, or is
 * in an incorrect format, 0 is returned.  The LocaleID is for use in
 * Windows (it is an LCID), but is available on all platforms.
 */
uint32_t 
Locale::getLCID() const
{
    return uloc_getLCID(fullName);
}

UnicodeString& 
Locale::getDisplayLanguage(UnicodeString& dispLang) const
{
    return this->getDisplayLanguage(getDefault(), dispLang);
}

/*We cannot make any assumptions on the size of the output display strings
* Yet, since we are calling through to a C API, we need to set limits on
* buffer size. For all the following getDisplay functions we first attempt
* to fill up a stack allocated buffer. If it is to small we heap allocated
* the exact buffer we need copy it to the UnicodeString and delete it*/

UnicodeString&
Locale::getDisplayLanguage(const Locale &displayLocale,
                           UnicodeString &result) const {
    UChar *buffer;
    UErrorCode errorCode=U_ZERO_ERROR;
    int32_t length;

    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
    if(buffer==0) {
        result.truncate(0);
        return result;
    }

    length=uloc_getDisplayLanguage(fullName, displayLocale.fullName,
                                   buffer, result.getCapacity(),
                                   &errorCode);
    result.releaseBuffer(length);

    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
        buffer=result.getBuffer(length);
        if(buffer==0) {
            result.truncate(0);
            return result;
        }
        errorCode=U_ZERO_ERROR;
        length=uloc_getDisplayLanguage(fullName, displayLocale.fullName,
                                       buffer, result.getCapacity(),
                                       &errorCode);
        result.releaseBuffer(length);
    }

    if(U_FAILURE(errorCode)) {
        result.truncate(0);
    }

    return result;
}

UnicodeString& 
Locale::getDisplayCountry(UnicodeString& dispCntry) const
{
    return this->getDisplayCountry(getDefault(), dispCntry);
}

UnicodeString&
Locale::getDisplayCountry(const Locale &displayLocale,
                          UnicodeString &result) const {
    UChar *buffer;
    UErrorCode errorCode=U_ZERO_ERROR;
    int32_t length;

    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
    if(buffer==0) {
        result.truncate(0);
        return result;
    }

    length=uloc_getDisplayCountry(fullName, displayLocale.fullName,
                                  buffer, result.getCapacity(),
                                  &errorCode);
    result.releaseBuffer(length);

    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
        buffer=result.getBuffer(length);
        if(buffer==0) {
            result.truncate(0);
            return result;
        }
        errorCode=U_ZERO_ERROR;
        length=uloc_getDisplayCountry(fullName, displayLocale.fullName,
                                      buffer, result.getCapacity(),
                                      &errorCode);
        result.releaseBuffer(length);
    }

    if(U_FAILURE(errorCode)) {
        result.truncate(0);
    }

    return result;
}

UnicodeString& 
Locale::getDisplayVariant(UnicodeString& dispVar) const
{
    return this->getDisplayVariant(getDefault(), dispVar);
}

UnicodeString&
Locale::getDisplayVariant(const Locale &displayLocale,
                          UnicodeString &result) const {
    UChar *buffer;
    UErrorCode errorCode=U_ZERO_ERROR;
    int32_t length;

    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
    if(buffer==0) {
        result.truncate(0);
        return result;
    }

    length=uloc_getDisplayVariant(fullName, displayLocale.fullName,
                                  buffer, result.getCapacity(),
                                  &errorCode);
    result.releaseBuffer(length);

    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
        buffer=result.getBuffer(length);
        if(buffer==0) {
            result.truncate(0);
            return result;
        }
        errorCode=U_ZERO_ERROR;
        length=uloc_getDisplayVariant(fullName, displayLocale.fullName,
                                      buffer, result.getCapacity(),
                                      &errorCode);
        result.releaseBuffer(length);
    }

    if(U_FAILURE(errorCode)) {
        result.truncate(0);
    }

    return result;
}

UnicodeString& 
Locale::getDisplayName( UnicodeString& name ) const
{
    return this->getDisplayName(getDefault(), name);
}

UnicodeString&
Locale::getDisplayName(const Locale &displayLocale,
                       UnicodeString &result) const {
    UChar *buffer;
    UErrorCode errorCode=U_ZERO_ERROR;
    int32_t length;

    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
    if(buffer==0) {
        result.truncate(0);
        return result;
    }

    length=uloc_getDisplayName(fullName, displayLocale.fullName,
                               buffer, result.getCapacity(),
                               &errorCode);
    result.releaseBuffer(length);

    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
        buffer=result.getBuffer(length);
        if(buffer==0) {
            result.truncate(0);
            return result;
        }
        errorCode=U_ZERO_ERROR;
        length=uloc_getDisplayName(fullName, displayLocale.fullName,
                                   buffer, result.getCapacity(),
                                   &errorCode);
        result.releaseBuffer(length);
    }

    if(U_FAILURE(errorCode)) {
        result.truncate(0);
    }

    return result;
}
const Locale*
Locale::getAvailableLocales(int32_t& count) 
{
    // for now, there is a hardcoded list, so just walk through that list and set it up.
    if (availableLocaleList == 0) {
        int32_t locCount = uloc_countAvailable();
        Locale *newLocaleList = new Locale[locCount];

        count = locCount;

        while(--locCount >= 0) {
            newLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount));
        }

        Mutex mutex;
        if(availableLocaleList != 0) {
            delete []newLocaleList;
        }
        else {
            availableLocaleListCount = count;
            availableLocaleList = newLocaleList;
        }
    }
    count = availableLocaleListCount;
    return availableLocaleList;
}

const char* const* Locale::getISOCountries()
{
    return uloc_getISOCountries();
}

const char* const* Locale::getISOLanguages()
{
    return uloc_getISOLanguages();
}

// Set the locale's data based on a posix id. 
void Locale::setFromPOSIXID(const char *posixID)
{
    init(posixID);
}

#ifndef ICU_LOCID_USE_DEPRECATES
const Locale &
Locale::getEnglish(void)
{
    return getLocale(eENGLISH);
}

const Locale &
Locale::getFrench(void)
{
    return getLocale(eFRENCH);
}

const Locale &
Locale::getGerman(void)
{
    return getLocale(eGERMAN);
}

const Locale &
Locale::getItalian(void)
{
    return getLocale(eITALIAN);
}

const Locale &
Locale::getJapanese(void)
{
    return getLocale(eJAPANESE);
}

const Locale &
Locale::getKorean(void)
{
    return getLocale(eKOREAN);
}

const Locale &
Locale::getChinese(void)
{
    return getLocale(eCHINESE);
}

const Locale &
Locale::getSimplifiedChinese(void)
{
    return getLocale(eCHINESE);
}

const Locale &
Locale::getTraditionalChinese(void)
{
    return getLocale(eTAIWAN);
}


const Locale &
Locale::getFrance(void)
{
    return getLocale(eFRANCE);
}

const Locale &
Locale::getGermany(void)
{
    return getLocale(eGERMANY);
}

const Locale &
Locale::getItaly(void)
{
    return getLocale(eITALY);
}

const Locale &
Locale::getJapan(void)
{
    return getLocale(eJAPAN);
}

const Locale &
Locale::getKorea(void)
{
    return getLocale(eKOREA);
}

const Locale &
Locale::getChina(void)
{
    return getLocale(eCHINESE);
}

const Locale &
Locale::getPRC(void)
{
    return getLocale(eCHINESE);
}

const Locale &
Locale::getTaiwan(void)
{
    return getLocale(eTAIWAN);
}

const Locale &
Locale::getUK(void)
{
    return getLocale(eUK);
}

const Locale &
Locale::getUS(void)
{
    return getLocale(eUS);
}

const Locale &
Locale::getCanada(void)
{
    return getLocale(eCANADA);
}

const Locale &
Locale::getCanadaFrench(void)
{
    return getLocale(eFRENCH);
}

const Locale &
Locale::getLocale(int locid)
{
    if (gLocaleCache) {
        return gLocaleCache[locid];
    }

    initLocaleCache();

    return gLocaleCache[locid];
}

/*
This function is defined this way in order to get around static
initialization and static destruction.
 */
void
Locale::initLocaleCache(void)
{
    const char *defaultLocale = uprv_getDefaultLocaleID();
    // Can't use empty parameters, or we'll call this function again.
    Locale newLocales[] = {
        Locale("en"),
        Locale("fr"),
        Locale("de"),
        Locale("it"),
        Locale("ja"),
        Locale("ko"),
        Locale("zh"),
        Locale("fr", "FR"),
        Locale("de", "DE"),
        Locale("it", "IT"),
        Locale("ja", "JP"),
        Locale("ko", "KR"),
        Locale("zh", "CN"),
        Locale("zh", "TW"),
        Locale("en", "GB"),
        Locale("en", "US"),
        Locale("en", "CA"),
        Locale("fr", "CA"),
        Locale(defaultLocale)
    };
    Locale *localeCache = (Locale *)(gByteLocaleCache);

    {
        Mutex lock;
        if (gLocaleCache != NULL) {
            return;
        }
        uprv_memcpy(gByteLocaleCache, newLocales, sizeof(newLocales));

        for (int idx = 0; idx < eMAX_LOCALES; idx++)
        {
            if (localeCache[idx].fullName == newLocales[idx].fullNameBuffer)
            {
                localeCache[idx].fullName = localeCache[idx].fullNameBuffer;
            }
            else
            {
                // Since we did a memcpy we need to make sure that the local
                // Locales do not destroy the memory of the permanent locales.
                //
                // This can be a memory leak for an extra long default locale,
                // but this code shouldn't normally get executed.
                localeCache[idx].fullName = (char *)uprv_malloc(sizeof(char)*(uprv_strlen(localeCache[idx].fullNameBuffer) + 1));
                uprv_strcpy(localeCache[idx].fullName, localeCache[idx].fullNameBuffer);
            }
        }
        gLocaleCache = localeCache;
    }
}

#endif

//eof
U_NAMESPACE_END
