X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/374ca955a76ecab1204ca8bfa63ff9238d998416..729e4ab9bc6618bc3d8a898e575df7f4019e29ca:/icuSources/io/locbund.c diff --git a/icuSources/io/locbund.c b/icuSources/io/locbund.c index 3d0f9cf5..1859999b 100644 --- a/icuSources/io/locbund.c +++ b/icuSources/io/locbund.c @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 1998-2004, International Business Machines +* Copyright (C) 1998-2007, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -12,12 +12,10 @@ * * Date Name Description * 11/18/98 stephen Creation. -* 12/10/1999 bobbyr@optiosoftware.com Fix for memory leak + string allocation bugs +* 12/10/1999 bobbyr(at)optiosoftware.com Fix for memory leak + string allocation bugs ******************************************************************************* */ -#include - #include "unicode/utypes.h" #if !UCONFIG_NO_FORMATTING @@ -25,9 +23,52 @@ #include "locbund.h" #include "cmemory.h" +#include "cstring.h" +#include "ucln_io.h" +#include "umutex.h" #include "unicode/ustring.h" #include "unicode/uloc.h" +static UBool isFormatsInitialized = FALSE; +static UNumberFormat *gPosixNumberFormat[ULOCALEBUNDLE_NUMBERFORMAT_COUNT]; + +U_CDECL_BEGIN +static UBool U_CALLCONV locbund_cleanup(void) { + int32_t style; + for (style = 0; style < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; style++) { + unum_close(gPosixNumberFormat[style]); + gPosixNumberFormat[style] = NULL; + } + isFormatsInitialized = FALSE; + return TRUE; +} +U_CDECL_END + + +static U_INLINE UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNumberFormatStyle style) { + if (result->fNumberFormat[style-1] == NULL) { + UErrorCode status = U_ZERO_ERROR; + UBool needsInit; + + UMTX_CHECK(NULL, gPosixNumberFormat[style-1] == NULL, needsInit); + if (needsInit) { + UNumberFormat *formatAlias = unum_open(style, NULL, 0, "en_US_POSIX", NULL, &status); + + /* Cache upon first request. */ + if (U_SUCCESS(status)) { + umtx_lock(NULL); + gPosixNumberFormat[style-1] = formatAlias; + ucln_io_registerCleanup(UCLN_IO_LOCBUND, locbund_cleanup); + umtx_unlock(NULL); + } + } + + /* Copy the needed formatter. */ + result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status); + } + return result->fNumberFormat[style-1]; +} + ULocaleBundle* u_locbund_init(ULocaleBundle *result, const char *loc) { @@ -39,7 +80,7 @@ u_locbund_init(ULocaleBundle *result, const char *loc) if (loc == NULL) { loc = uloc_getDefault(); } - + uprv_memset(result, 0, sizeof(ULocaleBundle)); len = (int32_t)strlen(loc); @@ -47,9 +88,11 @@ u_locbund_init(ULocaleBundle *result, const char *loc) if(result->fLocale == 0) { return 0; } - - strcpy(result->fLocale, loc); - + + uprv_strcpy(result->fLocale, loc); + + result->isInvariantLocale = uprv_strcmp(result->fLocale, "en_US_POSIX") == 0; + return result; } @@ -119,17 +162,22 @@ UNumberFormat* u_locbund_getNumberFormat(ULocaleBundle *bundle, UNumberFormatStyle style) { UNumberFormat *formatAlias = NULL; - if (style >= UNUM_IGNORE) { + if (style > UNUM_IGNORE) { formatAlias = bundle->fNumberFormat[style-1]; if (formatAlias == NULL) { - UErrorCode status = U_ZERO_ERROR; - formatAlias = unum_open(style, NULL, 0, bundle->fLocale, NULL, &status); - if (U_FAILURE(status)) { - unum_close(formatAlias); - formatAlias = NULL; + if (bundle->isInvariantLocale) { + formatAlias = copyInvariantFormatter(bundle, style); } else { - bundle->fNumberFormat[style-1] = formatAlias; + UErrorCode status = U_ZERO_ERROR; + formatAlias = unum_open(style, NULL, 0, bundle->fLocale, NULL, &status); + if (U_FAILURE(status)) { + unum_close(formatAlias); + formatAlias = NULL; + } + else { + bundle->fNumberFormat[style-1] = formatAlias; + } } } }