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