michael@0: /* michael@0: ******************************************************************************* michael@0: * michael@0: * Copyright (C) 1998-2013, International Business Machines michael@0: * Corporation and others. All Rights Reserved. michael@0: * michael@0: ******************************************************************************* michael@0: * michael@0: * File locbund.cpp michael@0: * michael@0: * Modification History: michael@0: * michael@0: * Date Name Description michael@0: * 11/18/98 stephen Creation. michael@0: * 12/10/1999 bobbyr(at)optiosoftware.com Fix for memory leak + string allocation bugs michael@0: ******************************************************************************* michael@0: */ michael@0: michael@0: #include "unicode/utypes.h" michael@0: michael@0: #if !UCONFIG_NO_FORMATTING michael@0: michael@0: #include "locbund.h" michael@0: michael@0: #include "cmemory.h" michael@0: #include "cstring.h" michael@0: #include "ucln_io.h" michael@0: #include "mutex.h" michael@0: #include "umutex.h" michael@0: #include "unicode/ustring.h" michael@0: #include "unicode/uloc.h" michael@0: michael@0: static UNumberFormat *gPosixNumberFormat[ULOCALEBUNDLE_NUMBERFORMAT_COUNT]; michael@0: michael@0: U_CDECL_BEGIN michael@0: static UBool U_CALLCONV locbund_cleanup(void) { michael@0: int32_t style; michael@0: for (style = 0; style < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; style++) { michael@0: unum_close(gPosixNumberFormat[style]); michael@0: gPosixNumberFormat[style] = NULL; michael@0: } michael@0: return TRUE; michael@0: } michael@0: U_CDECL_END michael@0: michael@0: static UMutex gLock = U_MUTEX_INITIALIZER; michael@0: static inline UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNumberFormatStyle style) { michael@0: U_NAMESPACE_USE michael@0: Mutex lock(&gLock); michael@0: if (result->fNumberFormat[style-1] == NULL) { michael@0: if (gPosixNumberFormat[style-1] == NULL) { michael@0: UErrorCode status = U_ZERO_ERROR; michael@0: UNumberFormat *formatAlias = unum_open(style, NULL, 0, "en_US_POSIX", NULL, &status); michael@0: if (U_SUCCESS(status)) { michael@0: gPosixNumberFormat[style-1] = formatAlias; michael@0: ucln_io_registerCleanup(UCLN_IO_LOCBUND, locbund_cleanup); michael@0: } michael@0: } michael@0: /* Copy the needed formatter. */ michael@0: if (gPosixNumberFormat[style-1] != NULL) { michael@0: UErrorCode status = U_ZERO_ERROR; michael@0: result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status); michael@0: } michael@0: } michael@0: return result->fNumberFormat[style-1]; michael@0: } michael@0: michael@0: U_CAPI ULocaleBundle * michael@0: u_locbund_init(ULocaleBundle *result, const char *loc) michael@0: { michael@0: int32_t len; michael@0: michael@0: if(result == 0) michael@0: return 0; michael@0: michael@0: if (loc == NULL) { michael@0: loc = uloc_getDefault(); michael@0: } michael@0: michael@0: uprv_memset(result, 0, sizeof(ULocaleBundle)); michael@0: michael@0: len = (int32_t)strlen(loc); michael@0: result->fLocale = (char*) uprv_malloc(len + 1); michael@0: if(result->fLocale == 0) { michael@0: return 0; michael@0: } michael@0: michael@0: uprv_strcpy(result->fLocale, loc); michael@0: michael@0: result->isInvariantLocale = uprv_strcmp(result->fLocale, "en_US_POSIX") == 0; michael@0: michael@0: return result; michael@0: } michael@0: michael@0: /*U_CAPI ULocaleBundle * michael@0: u_locbund_new(const char *loc) michael@0: { michael@0: ULocaleBundle *result = (ULocaleBundle*) uprv_malloc(sizeof(ULocaleBundle)); michael@0: return u_locbund_init(result, loc); michael@0: } michael@0: michael@0: U_CAPI ULocaleBundle * michael@0: u_locbund_clone(const ULocaleBundle *bundle) michael@0: { michael@0: ULocaleBundle *result = (ULocaleBundle*)uprv_malloc(sizeof(ULocaleBundle)); michael@0: UErrorCode status = U_ZERO_ERROR; michael@0: int32_t styleIdx; michael@0: michael@0: if(result == 0) michael@0: return 0; michael@0: michael@0: result->fLocale = (char*) uprv_malloc(strlen(bundle->fLocale) + 1); michael@0: if(result->fLocale == 0) { michael@0: uprv_free(result); michael@0: return 0; michael@0: } michael@0: michael@0: strcpy(result->fLocale, bundle->fLocale ); michael@0: michael@0: for (styleIdx = 0; styleIdx < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; styleIdx++) { michael@0: status = U_ZERO_ERROR; michael@0: if (result->fNumberFormat[styleIdx]) { michael@0: result->fNumberFormat[styleIdx] = unum_clone(bundle->fNumberFormat[styleIdx], &status); michael@0: if (U_FAILURE(status)) { michael@0: result->fNumberFormat[styleIdx] = NULL; michael@0: } michael@0: } michael@0: else { michael@0: result->fNumberFormat[styleIdx] = NULL; michael@0: } michael@0: } michael@0: result->fDateFormat = (bundle->fDateFormat == 0 ? 0 : michael@0: udat_clone(bundle->fDateFormat, &status)); michael@0: result->fTimeFormat = (bundle->fTimeFormat == 0 ? 0 : michael@0: udat_clone(bundle->fTimeFormat, &status)); michael@0: michael@0: return result; michael@0: }*/ michael@0: michael@0: U_CAPI void michael@0: u_locbund_close(ULocaleBundle *bundle) michael@0: { michael@0: int32_t styleIdx; michael@0: michael@0: uprv_free(bundle->fLocale); michael@0: michael@0: for (styleIdx = 0; styleIdx < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; styleIdx++) { michael@0: if (bundle->fNumberFormat[styleIdx]) { michael@0: unum_close(bundle->fNumberFormat[styleIdx]); michael@0: } michael@0: } michael@0: michael@0: uprv_memset(bundle, 0, sizeof(ULocaleBundle)); michael@0: /* uprv_free(bundle);*/ michael@0: } michael@0: michael@0: U_CAPI UNumberFormat * michael@0: u_locbund_getNumberFormat(ULocaleBundle *bundle, UNumberFormatStyle style) michael@0: { michael@0: UNumberFormat *formatAlias = NULL; michael@0: if (style > UNUM_IGNORE) { michael@0: formatAlias = bundle->fNumberFormat[style-1]; michael@0: if (formatAlias == NULL) { michael@0: if (bundle->isInvariantLocale) { michael@0: formatAlias = copyInvariantFormatter(bundle, style); michael@0: } michael@0: else { michael@0: UErrorCode status = U_ZERO_ERROR; michael@0: formatAlias = unum_open(style, NULL, 0, bundle->fLocale, NULL, &status); michael@0: if (U_FAILURE(status)) { michael@0: unum_close(formatAlias); michael@0: formatAlias = NULL; michael@0: } michael@0: else { michael@0: bundle->fNumberFormat[style-1] = formatAlias; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: return formatAlias; michael@0: } michael@0: michael@0: #endif /* #if !UCONFIG_NO_FORMATTING */