| OLD | NEW |
| 1 /* | 1 /* |
| 2 ********************************************************************** | 2 ********************************************************************** |
| 3 * Copyright (c) 2002-2013, International Business Machines | 3 * Copyright (c) 2002-2014, International Business Machines |
| 4 * Corporation and others. All Rights Reserved. | 4 * Corporation and others. All Rights Reserved. |
| 5 ********************************************************************** | 5 ********************************************************************** |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "unicode/utypes.h" | 8 #include "unicode/utypes.h" |
| 9 | 9 |
| 10 #if !UCONFIG_NO_FORMATTING | 10 #if !UCONFIG_NO_FORMATTING |
| 11 | 11 |
| 12 #include "unicode/ucurr.h" | 12 #include "unicode/ucurr.h" |
| 13 #include "unicode/locid.h" | 13 #include "unicode/locid.h" |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 static const UChar EUR_STR[] = {0x0045,0x0055,0x0052,0}; | 112 static const UChar EUR_STR[] = {0x0045,0x0055,0x0052,0}; |
| 113 | 113 |
| 114 // ISO codes mapping table | 114 // ISO codes mapping table |
| 115 static const UHashtable* gIsoCodes = NULL; | 115 static const UHashtable* gIsoCodes = NULL; |
| 116 static icu::UInitOnce gIsoCodesInitOnce = U_INITONCE_INITIALIZER; | 116 static icu::UInitOnce gIsoCodesInitOnce = U_INITONCE_INITIALIZER; |
| 117 | 117 |
| 118 // Currency symbol equivalances | 118 // Currency symbol equivalances |
| 119 static const icu::Hashtable* gCurrSymbolsEquiv = NULL; | 119 static const icu::Hashtable* gCurrSymbolsEquiv = NULL; |
| 120 static icu::UInitOnce gCurrSymbolsEquivInitOnce = U_INITONCE_INITIALIZER; | 120 static icu::UInitOnce gCurrSymbolsEquivInitOnce = U_INITONCE_INITIALIZER; |
| 121 | 121 |
| 122 U_NAMESPACE_BEGIN |
| 123 |
| 122 // EquivIterator iterates over all strings that are equivalent to a given | 124 // EquivIterator iterates over all strings that are equivalent to a given |
| 123 // string, s. Note that EquivIterator will never yield s itself. | 125 // string, s. Note that EquivIterator will never yield s itself. |
| 124 class EquivIterator : icu::UMemory { | 126 class EquivIterator : icu::UMemory { |
| 125 public: | 127 public: |
| 126 // Constructor. hash stores the equivalence relationships; s is the string | 128 // Constructor. hash stores the equivalence relationships; s is the string |
| 127 // for which we find equivalent strings. | 129 // for which we find equivalent strings. |
| 128 inline EquivIterator(const icu::Hashtable& hash, const icu::UnicodeString& s
) | 130 inline EquivIterator(const icu::Hashtable& hash, const icu::UnicodeString& s
) |
| 129 : _hash(hash) { | 131 : _hash(hash) { |
| 130 _start = _current = &s; | 132 _start = _current = &s; |
| 131 } | 133 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 147 U_ASSERT(_current == _start); | 149 U_ASSERT(_current == _start); |
| 148 return NULL; | 150 return NULL; |
| 149 } | 151 } |
| 150 if (*_next == *_start) { | 152 if (*_next == *_start) { |
| 151 return NULL; | 153 return NULL; |
| 152 } | 154 } |
| 153 _current = _next; | 155 _current = _next; |
| 154 return _next; | 156 return _next; |
| 155 } | 157 } |
| 156 | 158 |
| 159 U_NAMESPACE_END |
| 160 |
| 157 // makeEquivalent makes lhs and rhs equivalent by updating the equivalence | 161 // makeEquivalent makes lhs and rhs equivalent by updating the equivalence |
| 158 // relations in hash accordingly. | 162 // relations in hash accordingly. |
| 159 static void makeEquivalent( | 163 static void makeEquivalent( |
| 160 const icu::UnicodeString &lhs, | 164 const icu::UnicodeString &lhs, |
| 161 const icu::UnicodeString &rhs, | 165 const icu::UnicodeString &rhs, |
| 162 icu::Hashtable* hash, UErrorCode &status) { | 166 icu::Hashtable* hash, UErrorCode &status) { |
| 163 if (U_FAILURE(status)) { | 167 if (U_FAILURE(status)) { |
| 164 return; | 168 return; |
| 165 } | 169 } |
| 166 if (lhs == rhs) { | 170 if (lhs == rhs) { |
| 167 // already equivalent | 171 // already equivalent |
| 168 return; | 172 return; |
| 169 } | 173 } |
| 170 EquivIterator leftIter(*hash, lhs); | 174 icu::EquivIterator leftIter(*hash, lhs); |
| 171 EquivIterator rightIter(*hash, rhs); | 175 icu::EquivIterator rightIter(*hash, rhs); |
| 172 const icu::UnicodeString *firstLeft = leftIter.next(); | 176 const icu::UnicodeString *firstLeft = leftIter.next(); |
| 173 const icu::UnicodeString *firstRight = rightIter.next(); | 177 const icu::UnicodeString *firstRight = rightIter.next(); |
| 174 const icu::UnicodeString *nextLeft = firstLeft; | 178 const icu::UnicodeString *nextLeft = firstLeft; |
| 175 const icu::UnicodeString *nextRight = firstRight; | 179 const icu::UnicodeString *nextRight = firstRight; |
| 176 while (nextLeft != NULL && nextRight != NULL) { | 180 while (nextLeft != NULL && nextRight != NULL) { |
| 177 if (*nextLeft == rhs || *nextRight == lhs) { | 181 if (*nextLeft == rhs || *nextRight == lhs) { |
| 178 // Already equivalent | 182 // Already equivalent |
| 179 return; | 183 return; |
| 180 } | 184 } |
| 181 nextLeft = leftIter.next(); | 185 nextLeft = leftIter.next(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 } | 217 } |
| 214 hash->put(lhs, (void *) newFirstLeft, status); | 218 hash->put(lhs, (void *) newFirstLeft, status); |
| 215 hash->put(rhs, (void *) newFirstRight, status); | 219 hash->put(rhs, (void *) newFirstRight, status); |
| 216 } | 220 } |
| 217 | 221 |
| 218 // countEquivalent counts how many strings are equivalent to s. | 222 // countEquivalent counts how many strings are equivalent to s. |
| 219 // hash stores all the equivalnce relations. | 223 // hash stores all the equivalnce relations. |
| 220 // countEquivalent does not include s itself in the count. | 224 // countEquivalent does not include s itself in the count. |
| 221 static int32_t countEquivalent(const icu::Hashtable &hash, const icu::UnicodeStr
ing &s) { | 225 static int32_t countEquivalent(const icu::Hashtable &hash, const icu::UnicodeStr
ing &s) { |
| 222 int32_t result = 0; | 226 int32_t result = 0; |
| 223 EquivIterator iter(hash, s); | 227 icu::EquivIterator iter(hash, s); |
| 224 while (iter.next() != NULL) { | 228 while (iter.next() != NULL) { |
| 225 ++result; | 229 ++result; |
| 226 } | 230 } |
| 227 #ifdef UCURR_DEBUG_EQUIV | 231 #ifdef UCURR_DEBUG_EQUIV |
| 228 { | 232 { |
| 229 char tmp[200]; | 233 char tmp[200]; |
| 230 s.extract(0,s.length(),tmp, "UTF-8"); | 234 s.extract(0,s.length(),tmp, "UTF-8"); |
| 231 printf("CountEquivalent('%s') = %d\n", tmp, result); | 235 printf("CountEquivalent('%s') = %d\n", tmp, result); |
| 232 } | 236 } |
| 233 #endif | 237 #endif |
| (...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 (*currencySymbols)[(*total_currency_symbol_count)++].currenc
yNameLen = length; | 1064 (*currencySymbols)[(*total_currency_symbol_count)++].currenc
yNameLen = length; |
| 1061 } | 1065 } |
| 1062 } else { | 1066 } else { |
| 1063 // Add currency symbol. | 1067 // Add currency symbol. |
| 1064 (*currencySymbols)[*total_currency_symbol_count].IsoCode = iso; | 1068 (*currencySymbols)[*total_currency_symbol_count].IsoCode = iso; |
| 1065 (*currencySymbols)[*total_currency_symbol_count].currencyName =
(UChar*)s; | 1069 (*currencySymbols)[*total_currency_symbol_count].currencyName =
(UChar*)s; |
| 1066 (*currencySymbols)[*total_currency_symbol_count].flag = 0; | 1070 (*currencySymbols)[*total_currency_symbol_count].flag = 0; |
| 1067 (*currencySymbols)[(*total_currency_symbol_count)++].currencyNam
eLen = len; | 1071 (*currencySymbols)[(*total_currency_symbol_count)++].currencyNam
eLen = len; |
| 1068 // Add equivalent symbols | 1072 // Add equivalent symbols |
| 1069 if (currencySymbolsEquiv != NULL) { | 1073 if (currencySymbolsEquiv != NULL) { |
| 1070 EquivIterator iter(*currencySymbolsEquiv, UnicodeString(TRUE
, s, len)); | 1074 icu::EquivIterator iter(*currencySymbolsEquiv, UnicodeString(T
RUE, s, len)); |
| 1071 const UnicodeString *symbol; | 1075 const UnicodeString *symbol; |
| 1072 while ((symbol = iter.next()) != NULL) { | 1076 while ((symbol = iter.next()) != NULL) { |
| 1073 (*currencySymbols)[*total_currency_symbol_count].IsoCode
= iso; | 1077 (*currencySymbols)[*total_currency_symbol_count].IsoCode
= iso; |
| 1074 (*currencySymbols)[*total_currency_symbol_count].currenc
yName = (UChar*) symbol->getBuffer(); | 1078 (*currencySymbols)[*total_currency_symbol_count].currenc
yName = (UChar*) symbol->getBuffer(); |
| 1075 (*currencySymbols)[*total_currency_symbol_count].flag =
0; | 1079 (*currencySymbols)[*total_currency_symbol_count].flag =
0; |
| 1076 (*currencySymbols)[(*total_currency_symbol_count)++].cur
rencyNameLen = symbol->length(); | 1080 (*currencySymbols)[(*total_currency_symbol_count)++].cur
rencyNameLen = symbol->length(); |
| 1077 } | 1081 } |
| 1078 } | 1082 } |
| 1079 } | 1083 } |
| 1080 | 1084 |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1609 result.setTo(iso, -1); | 1613 result.setTo(iso, -1); |
| 1610 } | 1614 } |
| 1611 } else { | 1615 } else { |
| 1612 result.setTo(currname, -1); | 1616 result.setTo(currname, -1); |
| 1613 } | 1617 } |
| 1614 } | 1618 } |
| 1615 } | 1619 } |
| 1616 | 1620 |
| 1617 U_CAPI int32_t U_EXPORT2 | 1621 U_CAPI int32_t U_EXPORT2 |
| 1618 ucurr_getDefaultFractionDigits(const UChar* currency, UErrorCode* ec) { | 1622 ucurr_getDefaultFractionDigits(const UChar* currency, UErrorCode* ec) { |
| 1619 return (_findMetaData(currency, *ec))[0]; | 1623 return ucurr_getDefaultFractionDigitsForUsage(currency,UCURR_USAGE_STANDARD,
ec); |
| 1624 } |
| 1625 |
| 1626 U_DRAFT int32_t U_EXPORT2 |
| 1627 ucurr_getDefaultFractionDigitsForUsage(const UChar* currency, const UCurrencyUsa
ge usage, UErrorCode* ec) { |
| 1628 int32_t fracDigits = 0; |
| 1629 if (U_SUCCESS(*ec)) { |
| 1630 switch (usage) { |
| 1631 case UCURR_USAGE_STANDARD: |
| 1632 fracDigits = (_findMetaData(currency, *ec))[0]; |
| 1633 break; |
| 1634 case UCURR_USAGE_CASH: |
| 1635 fracDigits = (_findMetaData(currency, *ec))[2]; |
| 1636 break; |
| 1637 default: |
| 1638 *ec = U_UNSUPPORTED_ERROR; |
| 1639 } |
| 1640 } |
| 1641 return fracDigits; |
| 1620 } | 1642 } |
| 1621 | 1643 |
| 1622 U_CAPI double U_EXPORT2 | 1644 U_CAPI double U_EXPORT2 |
| 1623 ucurr_getRoundingIncrement(const UChar* currency, UErrorCode* ec) { | 1645 ucurr_getRoundingIncrement(const UChar* currency, UErrorCode* ec) { |
| 1646 return ucurr_getRoundingIncrementForUsage(currency, UCURR_USAGE_STANDARD, ec
); |
| 1647 } |
| 1648 |
| 1649 U_DRAFT double U_EXPORT2 |
| 1650 ucurr_getRoundingIncrementForUsage(const UChar* currency, const UCurrencyUsage u
sage, UErrorCode* ec) { |
| 1651 double result = 0.0; |
| 1652 |
| 1624 const int32_t *data = _findMetaData(currency, *ec); | 1653 const int32_t *data = _findMetaData(currency, *ec); |
| 1654 if (U_SUCCESS(*ec)) { |
| 1655 int32_t fracDigits; |
| 1656 int32_t increment; |
| 1657 switch (usage) { |
| 1658 case UCURR_USAGE_STANDARD: |
| 1659 fracDigits = data[0]; |
| 1660 increment = data[1]; |
| 1661 break; |
| 1662 case UCURR_USAGE_CASH: |
| 1663 fracDigits = data[2]; |
| 1664 increment = data[3]; |
| 1665 break; |
| 1666 default: |
| 1667 *ec = U_UNSUPPORTED_ERROR; |
| 1668 return result; |
| 1669 } |
| 1625 | 1670 |
| 1626 // If the meta data is invalid, return 0.0. | 1671 // If the meta data is invalid, return 0.0 |
| 1627 if (data[0] < 0 || data[0] > MAX_POW10) { | 1672 if (fracDigits < 0 || fracDigits > MAX_POW10) { |
| 1628 if (U_SUCCESS(*ec)) { | |
| 1629 *ec = U_INVALID_FORMAT_ERROR; | 1673 *ec = U_INVALID_FORMAT_ERROR; |
| 1674 } else { |
| 1675 // A rounding value of 0 or 1 indicates no rounding. |
| 1676 if (increment >= 2) { |
| 1677 // Return (increment) / 10^(fracDigits). The only actual roundi
ng data, |
| 1678 // as of this writing, is CHF { 2, 5 }. |
| 1679 result = double(increment) / POW10[fracDigits]; |
| 1680 } |
| 1630 } | 1681 } |
| 1631 return 0.0; | |
| 1632 } | 1682 } |
| 1633 | 1683 |
| 1634 // If there is no rounding, return 0.0 to indicate no rounding. A | 1684 return result; |
| 1635 // rounding value (data[1]) of 0 or 1 indicates no rounding. | |
| 1636 if (data[1] < 2) { | |
| 1637 return 0.0; | |
| 1638 } | |
| 1639 | |
| 1640 // Return data[1] / 10^(data[0]). The only actual rounding data, | |
| 1641 // as of this writing, is CHF { 2, 5 }. | |
| 1642 return double(data[1]) / POW10[data[0]]; | |
| 1643 } | 1685 } |
| 1644 | 1686 |
| 1645 U_CDECL_BEGIN | 1687 U_CDECL_BEGIN |
| 1646 | 1688 |
| 1647 typedef struct UCurrencyContext { | 1689 typedef struct UCurrencyContext { |
| 1648 uint32_t currType; /* UCurrCurrencyType */ | 1690 uint32_t currType; /* UCurrCurrencyType */ |
| 1649 uint32_t listIdx; | 1691 uint32_t listIdx; |
| 1650 } UCurrencyContext; | 1692 } UCurrencyContext; |
| 1651 | 1693 |
| 1652 /* | 1694 /* |
| (...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2484 | 2526 |
| 2485 U_CAPI UEnumeration *U_EXPORT2 ucurr_getKeywordValuesForLocale(const char *key,
const char *locale, UBool commonlyUsed, UErrorCode* status) { | 2527 U_CAPI UEnumeration *U_EXPORT2 ucurr_getKeywordValuesForLocale(const char *key,
const char *locale, UBool commonlyUsed, UErrorCode* status) { |
| 2486 // Resolve region | 2528 // Resolve region |
| 2487 char prefRegion[ULOC_FULLNAME_CAPACITY] = ""; | 2529 char prefRegion[ULOC_FULLNAME_CAPACITY] = ""; |
| 2488 int32_t prefRegionLength = 0; | 2530 int32_t prefRegionLength = 0; |
| 2489 prefRegionLength = uloc_getCountry(locale, prefRegion, sizeof(prefRegion), s
tatus); | 2531 prefRegionLength = uloc_getCountry(locale, prefRegion, sizeof(prefRegion), s
tatus); |
| 2490 if (prefRegionLength == 0) { | 2532 if (prefRegionLength == 0) { |
| 2491 char loc[ULOC_FULLNAME_CAPACITY] = ""; | 2533 char loc[ULOC_FULLNAME_CAPACITY] = ""; |
| 2492 uloc_addLikelySubtags(locale, loc, sizeof(loc), status); | 2534 uloc_addLikelySubtags(locale, loc, sizeof(loc), status); |
| 2493 | 2535 |
| 2494 prefRegionLength = uloc_getCountry(loc, prefRegion, sizeof(prefRegion),
status); | 2536 /*prefRegionLength = */ uloc_getCountry(loc, prefRegion, sizeof(prefRegi
on), status); |
| 2495 } | 2537 } |
| 2496 | 2538 |
| 2497 // Read value from supplementalData | 2539 // Read value from supplementalData |
| 2498 UList *values = ulist_createEmptyList(status); | 2540 UList *values = ulist_createEmptyList(status); |
| 2499 UList *otherValues = ulist_createEmptyList(status); | 2541 UList *otherValues = ulist_createEmptyList(status); |
| 2500 UEnumeration *en = (UEnumeration *)uprv_malloc(sizeof(UEnumeration)); | 2542 UEnumeration *en = (UEnumeration *)uprv_malloc(sizeof(UEnumeration)); |
| 2501 if (U_FAILURE(*status) || en == NULL) { | 2543 if (U_FAILURE(*status) || en == NULL) { |
| 2502 if (en == NULL) { | 2544 if (en == NULL) { |
| 2503 *status = U_MEMORY_ALLOCATION_ERROR; | 2545 *status = U_MEMORY_ALLOCATION_ERROR; |
| 2504 } else { | 2546 } else { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2648 code = tmpCode; | 2690 code = tmpCode; |
| 2649 } | 2691 } |
| 2650 } | 2692 } |
| 2651 ures_close(bundle); | 2693 ures_close(bundle); |
| 2652 } | 2694 } |
| 2653 return code; | 2695 return code; |
| 2654 } | 2696 } |
| 2655 #endif /* #if !UCONFIG_NO_FORMATTING */ | 2697 #endif /* #if !UCONFIG_NO_FORMATTING */ |
| 2656 | 2698 |
| 2657 //eof | 2699 //eof |
| OLD | NEW |