locbund.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // © 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. /*
  4. *******************************************************************************
  5. *
  6. * Copyright (C) 1998-2014, International Business Machines
  7. * Corporation and others. All Rights Reserved.
  8. *
  9. *******************************************************************************
  10. *
  11. * File locbund.cpp
  12. *
  13. * Modification History:
  14. *
  15. * Date Name Description
  16. * 11/18/98 stephen Creation.
  17. * 12/10/1999 bobbyr(at)optiosoftware.com Fix for memory leak + string allocation bugs
  18. *******************************************************************************
  19. */
  20. #include "unicode/utypes.h"
  21. #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_CONVERSION
  22. #include "locbund.h"
  23. #include "cmemory.h"
  24. #include "cstring.h"
  25. #include "ucln_io.h"
  26. #include "mutex.h"
  27. #include "umutex.h"
  28. #include "unicode/ustring.h"
  29. #include "unicode/uloc.h"
  30. static UNumberFormat *gPosixNumberFormat[ULOCALEBUNDLE_NUMBERFORMAT_COUNT];
  31. U_CDECL_BEGIN
  32. static UBool U_CALLCONV locbund_cleanup() {
  33. int32_t style;
  34. for (style = 0; style < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; style++) {
  35. unum_close(gPosixNumberFormat[style]);
  36. gPosixNumberFormat[style] = nullptr;
  37. }
  38. return true;
  39. }
  40. U_CDECL_END
  41. static inline UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNumberFormatStyle style) {
  42. U_NAMESPACE_USE
  43. static UMutex gLock;
  44. Mutex lock(&gLock);
  45. if (result->fNumberFormat[style-1] == nullptr) {
  46. if (gPosixNumberFormat[style-1] == nullptr) {
  47. UErrorCode status = U_ZERO_ERROR;
  48. UNumberFormat *formatAlias = unum_open(style, nullptr, 0, "en_US_POSIX", nullptr, &status);
  49. if (U_SUCCESS(status)) {
  50. gPosixNumberFormat[style-1] = formatAlias;
  51. ucln_io_registerCleanup(UCLN_IO_LOCBUND, locbund_cleanup);
  52. }
  53. }
  54. /* Copy the needed formatter. */
  55. if (gPosixNumberFormat[style-1] != nullptr) {
  56. UErrorCode status = U_ZERO_ERROR;
  57. result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status);
  58. }
  59. }
  60. return result->fNumberFormat[style-1];
  61. }
  62. U_CAPI ULocaleBundle *
  63. u_locbund_init(ULocaleBundle *result, const char *loc)
  64. {
  65. int32_t len;
  66. if (result == nullptr)
  67. return nullptr;
  68. if (loc == nullptr) {
  69. loc = uloc_getDefault();
  70. }
  71. uprv_memset(result, 0, sizeof(ULocaleBundle));
  72. len = (int32_t)strlen(loc);
  73. result->fLocale = (char*) uprv_malloc(len + 1);
  74. if (result->fLocale == nullptr) {
  75. return nullptr;
  76. }
  77. uprv_strcpy(result->fLocale, loc);
  78. result->isInvariantLocale = uprv_strcmp(result->fLocale, "en_US_POSIX") == 0;
  79. return result;
  80. }
  81. /*U_CAPI ULocaleBundle *
  82. u_locbund_new(const char *loc)
  83. {
  84. ULocaleBundle *result = (ULocaleBundle*) uprv_malloc(sizeof(ULocaleBundle));
  85. return u_locbund_init(result, loc);
  86. }
  87. U_CAPI ULocaleBundle *
  88. u_locbund_clone(const ULocaleBundle *bundle)
  89. {
  90. ULocaleBundle *result = (ULocaleBundle*)uprv_malloc(sizeof(ULocaleBundle));
  91. UErrorCode status = U_ZERO_ERROR;
  92. int32_t styleIdx;
  93. if(result == 0)
  94. return 0;
  95. result->fLocale = (char*) uprv_malloc(strlen(bundle->fLocale) + 1);
  96. if(result->fLocale == 0) {
  97. uprv_free(result);
  98. return 0;
  99. }
  100. strcpy(result->fLocale, bundle->fLocale );
  101. for (styleIdx = 0; styleIdx < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; styleIdx++) {
  102. status = U_ZERO_ERROR;
  103. if (result->fNumberFormat[styleIdx]) {
  104. result->fNumberFormat[styleIdx] = unum_clone(bundle->fNumberFormat[styleIdx], &status);
  105. if (U_FAILURE(status)) {
  106. result->fNumberFormat[styleIdx] = nullptr;
  107. }
  108. }
  109. else {
  110. result->fNumberFormat[styleIdx] = nullptr;
  111. }
  112. }
  113. result->fDateFormat = (bundle->fDateFormat == 0 ? 0 :
  114. udat_clone(bundle->fDateFormat, &status));
  115. result->fTimeFormat = (bundle->fTimeFormat == 0 ? 0 :
  116. udat_clone(bundle->fTimeFormat, &status));
  117. return result;
  118. }*/
  119. U_CAPI void
  120. u_locbund_close(ULocaleBundle *bundle)
  121. {
  122. int32_t styleIdx;
  123. uprv_free(bundle->fLocale);
  124. for (styleIdx = 0; styleIdx < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; styleIdx++) {
  125. if (bundle->fNumberFormat[styleIdx]) {
  126. unum_close(bundle->fNumberFormat[styleIdx]);
  127. }
  128. }
  129. uprv_memset(bundle, 0, sizeof(ULocaleBundle));
  130. /* uprv_free(bundle);*/
  131. }
  132. U_CAPI UNumberFormat *
  133. u_locbund_getNumberFormat(ULocaleBundle *bundle, UNumberFormatStyle style)
  134. {
  135. UNumberFormat *formatAlias = nullptr;
  136. if (style > UNUM_IGNORE) {
  137. formatAlias = bundle->fNumberFormat[style-1];
  138. if (formatAlias == nullptr) {
  139. if (bundle->isInvariantLocale) {
  140. formatAlias = copyInvariantFormatter(bundle, style);
  141. }
  142. else {
  143. UErrorCode status = U_ZERO_ERROR;
  144. formatAlias = unum_open(style, nullptr, 0, bundle->fLocale, nullptr, &status);
  145. if (U_FAILURE(status)) {
  146. unum_close(formatAlias);
  147. formatAlias = nullptr;
  148. }
  149. else {
  150. bundle->fNumberFormat[style-1] = formatAlias;
  151. }
  152. }
  153. }
  154. }
  155. return formatAlias;
  156. }
  157. #endif /* #if !UCONFIG_NO_FORMATTING */