16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 1998-2013, International Business Machines 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Corporation and others. All Rights Reserved. 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* File locbund.cpp 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Modification History: 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Date Name Description 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 11/18/98 stephen Creation. 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 12/10/1999 bobbyr(at)optiosoftware.com Fix for memory leak + string allocation bugs 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_FORMATTING 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "locbund.h" 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucln_io.h" 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "mutex.h" 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "umutex.h" 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h" 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uloc.h" 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UNumberFormat *gPosixNumberFormat[ULOCALEBUNDLE_NUMBERFORMAT_COUNT]; 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_BEGIN 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool U_CALLCONV locbund_cleanup(void) { 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t style; 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (style = 0; style < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; style++) { 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unum_close(gPosixNumberFormat[style]); 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gPosixNumberFormat[style] = NULL; 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_END 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UMutex gLock = U_MUTEX_INITIALIZER; 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic inline UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNumberFormatStyle style) { 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_NAMESPACE_USE 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Mutex lock(&gLock); 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (result->fNumberFormat[style-1] == NULL) { 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (gPosixNumberFormat[style-1] == NULL) { 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UNumberFormat *formatAlias = unum_open(style, NULL, 0, "en_US_POSIX", NULL, &status); 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gPosixNumberFormat[style-1] = formatAlias; 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucln_io_registerCleanup(UCLN_IO_LOCBUND, locbund_cleanup); 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Copy the needed formatter. */ 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (gPosixNumberFormat[style-1] != NULL) { 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status); 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result->fNumberFormat[style-1]; 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI ULocaleBundle * 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgu_locbund_init(ULocaleBundle *result, const char *loc) 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len; 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(result == 0) 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (loc == NULL) { 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org loc = uloc_getDefault(); 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memset(result, 0, sizeof(ULocaleBundle)); 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org len = (int32_t)strlen(loc); 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result->fLocale = (char*) uprv_malloc(len + 1); 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(result->fLocale == 0) { 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_strcpy(result->fLocale, loc); 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result->isInvariantLocale = uprv_strcmp(result->fLocale, "en_US_POSIX") == 0; 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*U_CAPI ULocaleBundle * 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgu_locbund_new(const char *loc) 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ULocaleBundle *result = (ULocaleBundle*) uprv_malloc(sizeof(ULocaleBundle)); 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return u_locbund_init(result, loc); 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI ULocaleBundle * 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgu_locbund_clone(const ULocaleBundle *bundle) 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ULocaleBundle *result = (ULocaleBundle*)uprv_malloc(sizeof(ULocaleBundle)); 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t styleIdx; 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(result == 0) 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result->fLocale = (char*) uprv_malloc(strlen(bundle->fLocale) + 1); 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(result->fLocale == 0) { 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(result); 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org strcpy(result->fLocale, bundle->fLocale ); 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (styleIdx = 0; styleIdx < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; styleIdx++) { 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ZERO_ERROR; 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (result->fNumberFormat[styleIdx]) { 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result->fNumberFormat[styleIdx] = unum_clone(bundle->fNumberFormat[styleIdx], &status); 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result->fNumberFormat[styleIdx] = NULL; 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result->fNumberFormat[styleIdx] = NULL; 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result->fDateFormat = (bundle->fDateFormat == 0 ? 0 : 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udat_clone(bundle->fDateFormat, &status)); 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result->fTimeFormat = (bundle->fTimeFormat == 0 ? 0 : 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udat_clone(bundle->fTimeFormat, &status)); 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}*/ 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgu_locbund_close(ULocaleBundle *bundle) 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t styleIdx; 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(bundle->fLocale); 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (styleIdx = 0; styleIdx < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; styleIdx++) { 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (bundle->fNumberFormat[styleIdx]) { 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unum_close(bundle->fNumberFormat[styleIdx]); 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memset(bundle, 0, sizeof(ULocaleBundle)); 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* uprv_free(bundle);*/ 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UNumberFormat * 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgu_locbund_getNumberFormat(ULocaleBundle *bundle, UNumberFormatStyle style) 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UNumberFormat *formatAlias = NULL; 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (style > UNUM_IGNORE) { 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatAlias = bundle->fNumberFormat[style-1]; 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (formatAlias == NULL) { 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (bundle->isInvariantLocale) { 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatAlias = copyInvariantFormatter(bundle, style); 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatAlias = unum_open(style, NULL, 0, bundle->fLocale, NULL, &status); 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unum_close(formatAlias); 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatAlias = NULL; 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bundle->fNumberFormat[style-1] = formatAlias; 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return formatAlias; 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_FORMATTING */ 184