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 |