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

const char Locale::fgClassID=0;

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()
    : UObject(), fullName(fullNameBuffer)
{
    init(NULL);
}

Locale::Locale( const   char * newLanguage, 
                const   char * newCountry, 
                const   char * newVariant) 
    : UObject(), 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)
    : UObject(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 = (int32_t)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 = (int32_t)(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 = (int32_t)(separator - prev);
                if(length > 0) {
                    if(length >= (int32_t)sizeof(country)) {
                        break;
                    }
                    uprv_memcpy(country, prev, length);
                }
                country[length] = 0;

                variantBegin = (int32_t)((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(eCHINA);
}

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(eCHINA);
}

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

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(eCANADA_FRENCH);
}

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
