1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************** 38393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius* Copyright (c) 2002-2013, International Business Machines 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************** 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ucurr.h" 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/locid.h" 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ures.h" 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/choicfmt.h" 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/parsepos.h" 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ustr_imp.h" 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uassert.h" 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h" 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucln_in.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uenumimp.h" 25b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "uhash.h" 2659d709d503bab6e2b61931737e662dd293b40578ccornelius#include "hash.h" 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uresimp.h" 28b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "ulist.h" 2950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "ureslocs.h" 30b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 3159d709d503bab6e2b61931737e662dd293b40578ccornelius//#define UCURR_DEBUG_EQUIV 1 3259d709d503bab6e2b61931737e662dd293b40578ccornelius#ifdef UCURR_DEBUG_EQUIV 3359d709d503bab6e2b61931737e662dd293b40578ccornelius#include "stdio.h" 3459d709d503bab6e2b61931737e662dd293b40578ccornelius#endif 3559d709d503bab6e2b61931737e662dd293b40578ccornelius//#define UCURR_DEBUG 1 36b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 37b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "stdio.h" 38b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 40b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehotypedef struct IsoCodeEntry { 41b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *isoCode; /* const because it's a reference to a resource bundle string. */ 42b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UDate from; 43b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UDate to; 44b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} IsoCodeEntry; 45b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------ 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Constants 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Default currency meta data of last resort. We try to use the 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// defaults encoded in the meta data resource bundle. If there is a 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// configuration/build error and these are not available, we use these 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// hard-coded defaults (which should be identical). 5359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const int32_t LAST_RESORT_DATA[] = { 2, 0, 2, 0 }; 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// POW10[i] = 10^i, i=0..MAX_POW10 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const int32_t POW10[] = { 1, 10, 100, 1000, 10000, 100000, 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1000000, 10000000, 100000000, 1000000000 }; 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const int32_t MAX_POW10 = (sizeof(POW10)/sizeof(POW10[0])) - 1; 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 6159d709d503bab6e2b61931737e662dd293b40578ccornelius// Defines equivalent currency symbols. 6259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const char *EQUIV_CURRENCY_SYMBOLS[][2] = { 6359d709d503bab6e2b61931737e662dd293b40578ccornelius {"\\u00a5", "\\uffe5"}, 6459d709d503bab6e2b61931737e662dd293b40578ccornelius {"$", "\\ufe69"}, 6559d709d503bab6e2b61931737e662dd293b40578ccornelius {"$", "\\uff04"}, 6659d709d503bab6e2b61931737e662dd293b40578ccornelius {"\\u20a8", "\\u20b9"}, 6759d709d503bab6e2b61931737e662dd293b40578ccornelius {"\\u00a3", "\\u20a4"}}; 6859d709d503bab6e2b61931737e662dd293b40578ccornelius 69103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define ISO_CURRENCY_CODE_LENGTH 3 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------ 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Resource tags 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char CURRENCY_DATA[] = "supplementalData"; 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Tag for meta-data, in root. 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char CURRENCY_META[] = "CurrencyMeta"; 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Tag for map from countries to currencies, in root. 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char CURRENCY_MAP[] = "CurrencyMap"; 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Tag for default meta-data, in CURRENCY_META 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char DEFAULT_META[] = "DEFAULT"; 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Variant for legacy pre-euro mapping in CurrencyMap 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char VAR_PRE_EURO[] = "PREEURO"; 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Variant for legacy euro mapping in CurrencyMap 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char VAR_EURO[] = "EURO"; 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Variant delimiter 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char VAR_DELIM = '_'; 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char VAR_DELIM_STR[] = "_"; 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Variant for legacy euro mapping in CurrencyMap 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//static const char VAR_DELIM_EURO[] = "_EURO"; 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define VARIANT_IS_EMPTY 0 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define VARIANT_IS_EURO 0x1 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define VARIANT_IS_PREEURO 0x2 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Tag for localized display names (symbols) of currencies 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char CURRENCIES[] = "Currencies"; 104b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const char CURRENCYPLURALS[] = "CurrencyPlurals"; 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Marker character indicating that a display name is a ChoiceFormat 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// pattern. Strings that start with one mark are ChoiceFormat 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// patterns. Strings that start with 2 marks are static strings, and 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// the first mark is deleted. 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UChar CHOICE_FORMAT_MARK = 0x003D; // Equals sign 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UChar EUR_STR[] = {0x0045,0x0055,0x0052,0}; 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// ISO codes mapping table 11559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UHashtable* gIsoCodes = NULL; 11659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce gIsoCodesInitOnce = U_INITONCE_INITIALIZER; 11759d709d503bab6e2b61931737e662dd293b40578ccornelius 11859d709d503bab6e2b61931737e662dd293b40578ccornelius// Currency symbol equivalances 11959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const icu::Hashtable* gCurrSymbolsEquiv = NULL; 12059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce gCurrSymbolsEquivInitOnce = U_INITONCE_INITIALIZER; 12159d709d503bab6e2b61931737e662dd293b40578ccornelius 12259d709d503bab6e2b61931737e662dd293b40578ccornelius// EquivIterator iterates over all strings that are equivalent to a given 12359d709d503bab6e2b61931737e662dd293b40578ccornelius// string, s. Note that EquivIterator will never yield s itself. 12459d709d503bab6e2b61931737e662dd293b40578ccorneliusclass EquivIterator : icu::UMemory { 12559d709d503bab6e2b61931737e662dd293b40578ccorneliuspublic: 12659d709d503bab6e2b61931737e662dd293b40578ccornelius // Constructor. hash stores the equivalence relationships; s is the string 12759d709d503bab6e2b61931737e662dd293b40578ccornelius // for which we find equivalent strings. 12859d709d503bab6e2b61931737e662dd293b40578ccornelius inline EquivIterator(const icu::Hashtable& hash, const icu::UnicodeString& s) 12959d709d503bab6e2b61931737e662dd293b40578ccornelius : _hash(hash) { 13059d709d503bab6e2b61931737e662dd293b40578ccornelius _start = _current = &s; 13159d709d503bab6e2b61931737e662dd293b40578ccornelius } 13259d709d503bab6e2b61931737e662dd293b40578ccornelius inline ~EquivIterator() { } 13359d709d503bab6e2b61931737e662dd293b40578ccornelius 13459d709d503bab6e2b61931737e662dd293b40578ccornelius // next returns the next equivalent string or NULL if there are no more. 13559d709d503bab6e2b61931737e662dd293b40578ccornelius // If s has no equivalent strings, next returns NULL on the first call. 13659d709d503bab6e2b61931737e662dd293b40578ccornelius const icu::UnicodeString *next(); 13759d709d503bab6e2b61931737e662dd293b40578ccorneliusprivate: 13859d709d503bab6e2b61931737e662dd293b40578ccornelius const icu::Hashtable& _hash; 13959d709d503bab6e2b61931737e662dd293b40578ccornelius const icu::UnicodeString* _start; 14059d709d503bab6e2b61931737e662dd293b40578ccornelius const icu::UnicodeString* _current; 14159d709d503bab6e2b61931737e662dd293b40578ccornelius}; 14259d709d503bab6e2b61931737e662dd293b40578ccornelius 14359d709d503bab6e2b61931737e662dd293b40578ccorneliusconst icu::UnicodeString * 14459d709d503bab6e2b61931737e662dd293b40578ccorneliusEquivIterator::next() { 14559d709d503bab6e2b61931737e662dd293b40578ccornelius const icu::UnicodeString* _next = (const icu::UnicodeString*) _hash.get(*_current); 14659d709d503bab6e2b61931737e662dd293b40578ccornelius if (_next == NULL) { 14759d709d503bab6e2b61931737e662dd293b40578ccornelius U_ASSERT(_current == _start); 14859d709d503bab6e2b61931737e662dd293b40578ccornelius return NULL; 14959d709d503bab6e2b61931737e662dd293b40578ccornelius } 15059d709d503bab6e2b61931737e662dd293b40578ccornelius if (*_next == *_start) { 15159d709d503bab6e2b61931737e662dd293b40578ccornelius return NULL; 15259d709d503bab6e2b61931737e662dd293b40578ccornelius } 15359d709d503bab6e2b61931737e662dd293b40578ccornelius _current = _next; 15459d709d503bab6e2b61931737e662dd293b40578ccornelius return _next; 15559d709d503bab6e2b61931737e662dd293b40578ccornelius} 15659d709d503bab6e2b61931737e662dd293b40578ccornelius 15759d709d503bab6e2b61931737e662dd293b40578ccornelius// makeEquivalent makes lhs and rhs equivalent by updating the equivalence 15859d709d503bab6e2b61931737e662dd293b40578ccornelius// relations in hash accordingly. 15959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void makeEquivalent( 16059d709d503bab6e2b61931737e662dd293b40578ccornelius const icu::UnicodeString &lhs, 16159d709d503bab6e2b61931737e662dd293b40578ccornelius const icu::UnicodeString &rhs, 16259d709d503bab6e2b61931737e662dd293b40578ccornelius icu::Hashtable* hash, UErrorCode &status) { 16359d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_FAILURE(status)) { 16459d709d503bab6e2b61931737e662dd293b40578ccornelius return; 16559d709d503bab6e2b61931737e662dd293b40578ccornelius } 16659d709d503bab6e2b61931737e662dd293b40578ccornelius if (lhs == rhs) { 16759d709d503bab6e2b61931737e662dd293b40578ccornelius // already equivalent 16859d709d503bab6e2b61931737e662dd293b40578ccornelius return; 16959d709d503bab6e2b61931737e662dd293b40578ccornelius } 17059d709d503bab6e2b61931737e662dd293b40578ccornelius EquivIterator leftIter(*hash, lhs); 17159d709d503bab6e2b61931737e662dd293b40578ccornelius EquivIterator rightIter(*hash, rhs); 17259d709d503bab6e2b61931737e662dd293b40578ccornelius const icu::UnicodeString *firstLeft = leftIter.next(); 17359d709d503bab6e2b61931737e662dd293b40578ccornelius const icu::UnicodeString *firstRight = rightIter.next(); 17459d709d503bab6e2b61931737e662dd293b40578ccornelius const icu::UnicodeString *nextLeft = firstLeft; 17559d709d503bab6e2b61931737e662dd293b40578ccornelius const icu::UnicodeString *nextRight = firstRight; 17659d709d503bab6e2b61931737e662dd293b40578ccornelius while (nextLeft != NULL && nextRight != NULL) { 17759d709d503bab6e2b61931737e662dd293b40578ccornelius if (*nextLeft == rhs || *nextRight == lhs) { 17859d709d503bab6e2b61931737e662dd293b40578ccornelius // Already equivalent 17959d709d503bab6e2b61931737e662dd293b40578ccornelius return; 18059d709d503bab6e2b61931737e662dd293b40578ccornelius } 18159d709d503bab6e2b61931737e662dd293b40578ccornelius nextLeft = leftIter.next(); 18259d709d503bab6e2b61931737e662dd293b40578ccornelius nextRight = rightIter.next(); 18359d709d503bab6e2b61931737e662dd293b40578ccornelius } 18459d709d503bab6e2b61931737e662dd293b40578ccornelius // Not equivalent. Must join. 18559d709d503bab6e2b61931737e662dd293b40578ccornelius icu::UnicodeString *newFirstLeft; 18659d709d503bab6e2b61931737e662dd293b40578ccornelius icu::UnicodeString *newFirstRight; 18759d709d503bab6e2b61931737e662dd293b40578ccornelius if (firstRight == NULL && firstLeft == NULL) { 18859d709d503bab6e2b61931737e662dd293b40578ccornelius // Neither lhs or rhs belong to an equivalence circle, so we form 18959d709d503bab6e2b61931737e662dd293b40578ccornelius // a new equivalnce circle of just lhs and rhs. 19059d709d503bab6e2b61931737e662dd293b40578ccornelius newFirstLeft = new icu::UnicodeString(rhs); 19159d709d503bab6e2b61931737e662dd293b40578ccornelius newFirstRight = new icu::UnicodeString(lhs); 19259d709d503bab6e2b61931737e662dd293b40578ccornelius } else if (firstRight == NULL) { 19359d709d503bab6e2b61931737e662dd293b40578ccornelius // lhs belongs to an equivalence circle, but rhs does not, so we link 19459d709d503bab6e2b61931737e662dd293b40578ccornelius // rhs into lhs' circle. 19559d709d503bab6e2b61931737e662dd293b40578ccornelius newFirstLeft = new icu::UnicodeString(rhs); 19659d709d503bab6e2b61931737e662dd293b40578ccornelius newFirstRight = new icu::UnicodeString(*firstLeft); 19759d709d503bab6e2b61931737e662dd293b40578ccornelius } else if (firstLeft == NULL) { 19859d709d503bab6e2b61931737e662dd293b40578ccornelius // rhs belongs to an equivlance circle, but lhs does not, so we link 19959d709d503bab6e2b61931737e662dd293b40578ccornelius // lhs into rhs' circle. 20059d709d503bab6e2b61931737e662dd293b40578ccornelius newFirstLeft = new icu::UnicodeString(*firstRight); 20159d709d503bab6e2b61931737e662dd293b40578ccornelius newFirstRight = new icu::UnicodeString(lhs); 20259d709d503bab6e2b61931737e662dd293b40578ccornelius } else { 20359d709d503bab6e2b61931737e662dd293b40578ccornelius // Both lhs and rhs belong to different equivalnce circles. We link 20459d709d503bab6e2b61931737e662dd293b40578ccornelius // them together to form one single, larger equivalnce circle. 20559d709d503bab6e2b61931737e662dd293b40578ccornelius newFirstLeft = new icu::UnicodeString(*firstRight); 20659d709d503bab6e2b61931737e662dd293b40578ccornelius newFirstRight = new icu::UnicodeString(*firstLeft); 20759d709d503bab6e2b61931737e662dd293b40578ccornelius } 20859d709d503bab6e2b61931737e662dd293b40578ccornelius if (newFirstLeft == NULL || newFirstRight == NULL) { 20959d709d503bab6e2b61931737e662dd293b40578ccornelius delete newFirstLeft; 21059d709d503bab6e2b61931737e662dd293b40578ccornelius delete newFirstRight; 21159d709d503bab6e2b61931737e662dd293b40578ccornelius status = U_MEMORY_ALLOCATION_ERROR; 21259d709d503bab6e2b61931737e662dd293b40578ccornelius return; 21359d709d503bab6e2b61931737e662dd293b40578ccornelius } 21459d709d503bab6e2b61931737e662dd293b40578ccornelius hash->put(lhs, (void *) newFirstLeft, status); 21559d709d503bab6e2b61931737e662dd293b40578ccornelius hash->put(rhs, (void *) newFirstRight, status); 21659d709d503bab6e2b61931737e662dd293b40578ccornelius} 21759d709d503bab6e2b61931737e662dd293b40578ccornelius 21859d709d503bab6e2b61931737e662dd293b40578ccornelius// countEquivalent counts how many strings are equivalent to s. 21959d709d503bab6e2b61931737e662dd293b40578ccornelius// hash stores all the equivalnce relations. 22059d709d503bab6e2b61931737e662dd293b40578ccornelius// countEquivalent does not include s itself in the count. 22159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic int32_t countEquivalent(const icu::Hashtable &hash, const icu::UnicodeString &s) { 22259d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t result = 0; 22359d709d503bab6e2b61931737e662dd293b40578ccornelius EquivIterator iter(hash, s); 22459d709d503bab6e2b61931737e662dd293b40578ccornelius while (iter.next() != NULL) { 22559d709d503bab6e2b61931737e662dd293b40578ccornelius ++result; 22659d709d503bab6e2b61931737e662dd293b40578ccornelius } 22759d709d503bab6e2b61931737e662dd293b40578ccornelius#ifdef UCURR_DEBUG_EQUIV 22859d709d503bab6e2b61931737e662dd293b40578ccornelius { 22959d709d503bab6e2b61931737e662dd293b40578ccornelius char tmp[200]; 23059d709d503bab6e2b61931737e662dd293b40578ccornelius s.extract(0,s.length(),tmp, "UTF-8"); 23159d709d503bab6e2b61931737e662dd293b40578ccornelius printf("CountEquivalent('%s') = %d\n", tmp, result); 23259d709d503bab6e2b61931737e662dd293b40578ccornelius } 23359d709d503bab6e2b61931737e662dd293b40578ccornelius#endif 23459d709d503bab6e2b61931737e662dd293b40578ccornelius return result; 23559d709d503bab6e2b61931737e662dd293b40578ccornelius} 236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 23759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const icu::Hashtable* getCurrSymbolsEquiv(); 238b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------ 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Code 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Cleanup callback func 244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic UBool U_CALLCONV 246b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoisoCodes_cleanup(void) 247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho{ 248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (gIsoCodes != NULL) { 24959d709d503bab6e2b61931737e662dd293b40578ccornelius uhash_close(const_cast<UHashtable *>(gIsoCodes)); 250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho gIsoCodes = NULL; 251b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 25259d709d503bab6e2b61931737e662dd293b40578ccornelius gIsoCodesInitOnce.reset(); 25359d709d503bab6e2b61931737e662dd293b40578ccornelius return TRUE; 25459d709d503bab6e2b61931737e662dd293b40578ccornelius} 255b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 25659d709d503bab6e2b61931737e662dd293b40578ccornelius/** 25759d709d503bab6e2b61931737e662dd293b40578ccornelius * Cleanup callback func 25859d709d503bab6e2b61931737e662dd293b40578ccornelius */ 25959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic UBool U_CALLCONV 26059d709d503bab6e2b61931737e662dd293b40578ccorneliuscurrSymbolsEquiv_cleanup(void) 26159d709d503bab6e2b61931737e662dd293b40578ccornelius{ 26259d709d503bab6e2b61931737e662dd293b40578ccornelius delete const_cast<icu::Hashtable *>(gCurrSymbolsEquiv); 26359d709d503bab6e2b61931737e662dd293b40578ccornelius gCurrSymbolsEquiv = NULL; 26459d709d503bab6e2b61931737e662dd293b40578ccornelius gCurrSymbolsEquivInitOnce.reset(); 265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 267b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 268b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 269b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Deleter for OlsonToMetaMappingEntry 270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void U_CALLCONV 272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehodeleteIsoCodeEntry(void *obj) { 273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho IsoCodeEntry *entry = (IsoCodeEntry*)obj; 274b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(entry); 275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 27859d709d503bab6e2b61931737e662dd293b40578ccornelius * Deleter for gCurrSymbolsEquiv. 27959d709d503bab6e2b61931737e662dd293b40578ccornelius */ 28059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void U_CALLCONV 28159d709d503bab6e2b61931737e662dd293b40578ccorneliusdeleteUnicode(void *obj) { 28259d709d503bab6e2b61931737e662dd293b40578ccornelius icu::UnicodeString *entry = (icu::UnicodeString*)obj; 28359d709d503bab6e2b61931737e662dd293b40578ccornelius delete entry; 28459d709d503bab6e2b61931737e662dd293b40578ccornelius} 28559d709d503bab6e2b61931737e662dd293b40578ccornelius 28659d709d503bab6e2b61931737e662dd293b40578ccornelius/** 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Unfortunately, we have to convert the UChar* currency code to char* 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * to use it as a resource key. 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic inline char* 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerumyUCharsToChars(char* resultOfLen4, const UChar* currency) { 292103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius u_UCharsToChars(currency, resultOfLen4, ISO_CURRENCY_CODE_LENGTH); 293103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius resultOfLen4[ISO_CURRENCY_CODE_LENGTH] = 0; 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return resultOfLen4; 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Internal function to look up currency data. Result is an array of 29959d709d503bab6e2b61931737e662dd293b40578ccornelius * four integers. The first is the fraction digits. The second is the 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * rounding increment, or 0 if none. The rounding increment is in 30159d709d503bab6e2b61931737e662dd293b40578ccornelius * units of 10^(-fraction_digits). The third and fourth are the same 30259d709d503bab6e2b61931737e662dd293b40578ccornelius * except that they are those used in cash transations ( cashDigits 30359d709d503bab6e2b61931737e662dd293b40578ccornelius * and cashRounding ). 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const int32_t* 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru_findMetaData(const UChar* currency, UErrorCode& ec) { 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (currency == 0 || *currency == 0) { 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(ec)) { 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return LAST_RESORT_DATA; 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get CurrencyMeta resource out of root locale file. [This may 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // move out of the root locale file later; if it does, update this 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // code.] 31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UResourceBundle* currencyData = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &ec); 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle* currencyMeta = ures_getByKey(currencyData, CURRENCY_META, currencyData, &ec); 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(ec)) { 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(currencyMeta); 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Config/build error; return hard-coded defaults 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return LAST_RESORT_DATA; 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Look up our currency, or if that's not available, then DEFAULT 328103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius char buf[ISO_CURRENCY_CODE_LENGTH+1]; 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode ec2 = U_ZERO_ERROR; // local error code: soft failure 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle* rb = ures_getByKey(currencyMeta, myUCharsToChars(buf, currency), NULL, &ec2); 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(ec2)) { 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(rb); 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rb = ures_getByKey(currencyMeta,DEFAULT_META, NULL, &ec); 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(ec)) { 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(currencyMeta); 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(rb); 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Config/build error; return hard-coded defaults 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return LAST_RESORT_DATA; 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len; 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int32_t *data = ures_getIntVector(rb, &len, &ec); 34459d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_FAILURE(ec) || len != 4) { 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Config/build error; return hard-coded defaults 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(ec)) { 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec = U_INVALID_FORMAT_ERROR; 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(currencyMeta); 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(rb); 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return LAST_RESORT_DATA; 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(currencyMeta); 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(rb); 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return data; 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see VARIANT_IS_EURO 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @see VARIANT_IS_PREEURO 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint32_t 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruidForLocale(const char* locale, char* countryAndVariant, int capacity, UErrorCode* ec) 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t variantType = 0; 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // !!! this is internal only, assumes buffer is not null and capacity is sufficient 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Extract the country name and variant name. We only 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // recognize two variant names, EURO and PREEURO. 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char variant[ULOC_FULLNAME_CAPACITY]; 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_getCountry(locale, countryAndVariant, capacity, ec); 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_getVariant(locale, variant, sizeof(variant), ec); 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (variant[0] != 0) { 37654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius variantType = (uint32_t)(0 == uprv_strcmp(variant, VAR_EURO)) 37754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius | ((uint32_t)(0 == uprv_strcmp(variant, VAR_PRE_EURO)) << 1); 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (variantType) 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(countryAndVariant, VAR_DELIM_STR); 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(countryAndVariant, variant); 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return variantType; 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------------ 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Registration 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------- 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// don't use ICUService since we don't need fallback 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool U_CALLCONV currency_cleanup(void); 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END 398b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 399b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#if !UCONFIG_NO_SERVICE 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct CReg; 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 40254dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex gCRegLock = U_MUTEX_INITIALIZER; 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic CReg* gCRegHead = 0; 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 405103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstruct CReg : public icu::UMemory { 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CReg *next; 407103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar iso[ISO_CURRENCY_CODE_LENGTH+1]; 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char id[ULOC_FULLNAME_CAPACITY]; 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CReg(const UChar* _iso, const char* _id) 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : next(0) 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len = (int32_t)uprv_strlen(_id); 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len > (int32_t)(sizeof(id)-1)) { 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = (sizeof(id)-1); 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(id, _id, len); 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru id[len] = 0; 419103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uprv_memcpy(iso, _iso, ISO_CURRENCY_CODE_LENGTH * sizeof(const UChar)); 420103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius iso[ISO_CURRENCY_CODE_LENGTH] = 0; 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static UCurrRegistryKey reg(const UChar* _iso, const char* _id, UErrorCode* status) 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status && U_SUCCESS(*status) && _iso && _id) { 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CReg* n = new CReg(_iso, _id); 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (n) { 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(&gCRegLock); 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!gCRegHead) { 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* register for the first time */ 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucln_i18n_registerCleanup(UCLN_I18N_CURRENCY, currency_cleanup); 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru n->next = gCRegHead; 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gCRegHead = n; 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(&gCRegLock); 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return n; 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static UBool unreg(UCurrRegistryKey key) { 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool found = FALSE; 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(&gCRegLock); 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CReg** p = &gCRegHead; 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (*p) { 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*p == key) { 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *p = ((CReg*)key)->next; 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete (CReg*)key; 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru found = TRUE; 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p = &((*p)->next); 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(&gCRegLock); 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return found; 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static const UChar* get(const char* id) { 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar* result = NULL; 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(&gCRegLock); 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CReg* p = gCRegHead; 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* register cleanup of the mutex */ 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucln_i18n_registerCleanup(UCLN_I18N_CURRENCY, currency_cleanup); 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (p) { 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (uprv_strcmp(id, p->id) == 0) { 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = p->iso; 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p = p->next; 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(&gCRegLock); 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* This doesn't need to be thread safe. It's for u_cleanup only. */ 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static void cleanup(void) { 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (gCRegHead) { 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CReg* n = gCRegHead; 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gCRegHead = gCRegHead->next; 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete n; 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UCurrRegistryKey U_EXPORT2 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucurr_register(const UChar* isoCode, const char* locale, UErrorCode *status) 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status && U_SUCCESS(*status)) { 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char id[ULOC_FULLNAME_CAPACITY]; 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru idForLocale(locale, id, sizeof(id), status); 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return CReg::reg(isoCode, id, status); 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UBool U_EXPORT2 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucurr_unregister(UCurrRegistryKey key, UErrorCode* status) 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status && U_SUCCESS(*status)) { 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return CReg::unreg(key); 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* UCONFIG_NO_SERVICE */ 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 517b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/** 518b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Release all static memory held by currency. 519b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 520b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/*The declaration here is needed so currency_cleanup(void) 521b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * can call this function. 522b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 523b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic UBool U_CALLCONV 524b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehocurrency_cache_cleanup(void); 525b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 526b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_BEGIN 527b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic UBool U_CALLCONV currency_cleanup(void) { 528b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#if !UCONFIG_NO_SERVICE 529b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho CReg::cleanup(); 530b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#endif 531b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho /* 532b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * There might be some cached currency data or isoCodes data. 533b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 534b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho currency_cache_cleanup(); 535b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho isoCodes_cleanup(); 53659d709d503bab6e2b61931737e662dd293b40578ccornelius currSymbolsEquiv_cleanup(); 537b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 538b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 539b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 540b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_END 541b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 542b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// ------------------------------------- 543b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucurr_forLocale(const char* locale, 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar* buff, 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffCapacity, 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* ec) 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t resLen = 0; 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar* s = NULL; 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ec != NULL && U_SUCCESS(*ec)) { 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((buff && buffCapacity) || !buffCapacity) { 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode localStatus = U_ZERO_ERROR; 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char id[ULOC_FULLNAME_CAPACITY]; 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((resLen = uloc_getKeywordValue(locale, "currency", id, ULOC_FULLNAME_CAPACITY, &localStatus))) { 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // there is a currency keyword. Try to see if it's valid 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buffCapacity > resLen) { 55927f654740f2a26ad62a5c155af9199af9e69b889claireho /* Normalize the currency keyword value to upper case. */ 56027f654740f2a26ad62a5c155af9199af9e69b889claireho T_CString_toUpperCase(id); 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_charsToUChars(id, buff, resLen); 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get country or country_variant in `id' 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t variantType = idForLocale(locale, id, sizeof(id), ec); 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*ec)) { 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar* result = CReg::get(id); 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result) { 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buffCapacity > u_strlen(result)) { 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_strcpy(buff, result); 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_strlen(result); 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Remove variants, which is only needed for registration. 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *idDelim = strchr(id, VAR_DELIM); 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (idDelim) { 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru idDelim[0] = 0; 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Look up the CurrencyMap element in the root bundle. 58750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UResourceBundle *rb = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &localStatus); 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus); 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle *countryArray = ures_getByKey(rb, id, cm, &localStatus); 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle *currencyReq = ures_getByIndex(countryArray, 0, NULL, &localStatus); 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s = ures_getStringByKey(currencyReq, "id", &resLen, &localStatus); 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Get the second item when PREEURO is requested, and this is a known Euro country. 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru If the requested variant is PREEURO, and this isn't a Euro country, assume 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru that the country changed over to the Euro in the future. This is probably 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru an old version of ICU that hasn't been updated yet. The latest currency is 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru probably correct. 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(localStatus)) { 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((variantType & VARIANT_IS_PREEURO) && u_strcmp(s, EUR_STR) == 0) { 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru currencyReq = ures_getByIndex(countryArray, 1, currencyReq, &localStatus); 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s = ures_getStringByKey(currencyReq, "id", &resLen, &localStatus); 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if ((variantType & VARIANT_IS_EURO)) { 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s = EUR_STR; 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(countryArray); 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(currencyReq); 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((U_FAILURE(localStatus)) && strchr(id, '_') != 0) 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We don't know about it. Check to see if we support the variant. 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_getParent(locale, id, sizeof(id), ec); 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *ec = U_USING_FALLBACK_WARNING; 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ucurr_forLocale(id, buff, buffCapacity, ec); 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (*ec == U_ZERO_ERROR || localStatus != U_ZERO_ERROR) { 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // There is nothing to fallback to. Report the failure/warning if possible. 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *ec = localStatus; 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(*ec)) { 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buffCapacity > resLen) { 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_strcpy(buff, s); 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateUChars(buff, buffCapacity, resLen, ec); 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *ec = U_ILLEGAL_ARGUMENT_ERROR; 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return resLen; 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// end registration 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Modify the given locale name by removing the rightmost _-delimited 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * element. If there is none, empty the string ("" == root). 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * NOTE: The string "root" is not recognized; do not use it. 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @return TRUE if the fallback happened; FALSE if locale is already 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * root (""). 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool fallback(char *loc) { 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!*loc) { 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_getParent(loc, loc, (int32_t)uprv_strlen(loc), &status); 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *i = uprv_strrchr(loc, '_'); 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (i == NULL) { 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = loc; 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *i = 0; 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const UChar* U_EXPORT2 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucurr_getName(const UChar* currency, 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* locale, 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCurrNameStyle nameStyle, 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool* isChoiceFormat, // fillin 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t* len, // fillin 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode* ec) { 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Look up the Currencies resource for the given locale. The 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Currencies locale data looks like this: 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //|en { 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //| Currencies { 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //| USD { "US$", "US Dollar" } 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //| CHF { "Sw F", "Swiss Franc" } 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //| INR { "=0#Rs|1#Re|1<Rs", "=0#Rupees|1#Rupee|1<Rupees" } 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //| //... 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //| } 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //|} 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*ec)) { 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t choice = (int32_t) nameStyle; 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (choice < 0 || choice > 1) { 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *ec = U_ILLEGAL_ARGUMENT_ERROR; 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // In the future, resource bundles may implement multi-level 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fallback. That is, if a currency is not found in the en_US 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Currencies data, then the en Currencies data will be searched. 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Currently, if a Currencies datum exists in en_US and en, the 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // en_US entry hides that in en. 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We want multi-level fallback for this resource, so we implement 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // it manually. 700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Use a separate UErrorCode here that does not propagate out of 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // this function. 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode ec2 = U_ZERO_ERROR; 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char loc[ULOC_FULLNAME_CAPACITY]; 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_getName(locale, loc, sizeof(loc), &ec2); 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(ec2) || ec2 == U_STRING_NOT_TERMINATED_WARNING) { 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *ec = U_ILLEGAL_ARGUMENT_ERROR; 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 712103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius char buf[ISO_CURRENCY_CODE_LENGTH+1]; 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru myUCharsToChars(buf, currency); 71427f654740f2a26ad62a5c155af9199af9e69b889claireho 71527f654740f2a26ad62a5c155af9199af9e69b889claireho /* Normalize the keyword value to uppercase */ 71627f654740f2a26ad62a5c155af9199af9e69b889claireho T_CString_toUpperCase(buf); 71727f654740f2a26ad62a5c155af9199af9e69b889claireho 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar* s = NULL; 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec2 = U_ZERO_ERROR; 72050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UResourceBundle* rb = ures_open(U_ICUDATA_CURR, loc, &ec2); 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rb = ures_getByKey(rb, CURRENCIES, rb, &ec2); 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Fetch resource with multi-level resource inheritance fallback 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rb = ures_getByKeyWithFallback(rb, buf, rb, &ec2); 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s = ures_getStringByIndex(rb, choice, len, &ec2); 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(rb); 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If we've succeeded we're done. Otherwise, try to fallback. 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If that fails (because we are already at root) then exit. 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(ec2)) { 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ec2 == U_USING_DEFAULT_WARNING 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru || (ec2 == U_USING_FALLBACK_WARNING && *ec != U_USING_DEFAULT_WARNING)) { 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *ec = ec2; 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Determine if this is a ChoiceFormat pattern. One leading mark 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // indicates a ChoiceFormat. Two indicates a static string that 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // starts with a mark. In either case, the first mark is ignored, 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if present. Marks in the rest of the string have no special 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // meaning. 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *isChoiceFormat = FALSE; 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(ec2)) { 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_ASSERT(s != NULL); 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i=0; 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (i < *len && s[i] == CHOICE_FORMAT_MARK && i < 2) { 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++i; 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *isChoiceFormat = (i == 1); 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (i != 0) ++s; // Skip over first mark 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return s; 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If we fail to find a match, use the ISO 4217 code 757103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *len = u_strlen(currency); // Should == ISO_CURRENCY_CODE_LENGTH, but maybe not...? 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *ec = U_USING_DEFAULT_WARNING; 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return currency; 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 762b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI const UChar* U_EXPORT2 763b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruucurr_getPluralName(const UChar* currency, 764b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const char* locale, 765b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UBool* isChoiceFormat, 766b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const char* pluralCount, 767b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t* len, // fillin 768b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode* ec) { 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Look up the Currencies resource for the given locale. The 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Currencies locale data looks like this: 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //|en { 772b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru //| CurrencyPlurals { 773b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru //| USD{ 774b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru //| one{"US dollar"} 775b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru //| other{"US dollars"} 776b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru //| } 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //| } 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //|} 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 780b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(*ec)) { 781b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 782b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Use a separate UErrorCode here that does not propagate out of 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // this function. 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode ec2 = U_ZERO_ERROR; 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char loc[ULOC_FULLNAME_CAPACITY]; 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_getName(locale, loc, sizeof(loc), &ec2); 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(ec2) || ec2 == U_STRING_NOT_TERMINATED_WARNING) { 791b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *ec = U_ILLEGAL_ARGUMENT_ERROR; 792b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 795103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius char buf[ISO_CURRENCY_CODE_LENGTH+1]; 796b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru myUCharsToChars(buf, currency); 797b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar* s = NULL; 799b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ec2 = U_ZERO_ERROR; 80050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UResourceBundle* rb = ures_open(U_ICUDATA_CURR, loc, &ec2); 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 802b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru rb = ures_getByKey(rb, CURRENCYPLURALS, rb, &ec2); 803b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 804b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Fetch resource with multi-level resource inheritance fallback 805b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru rb = ures_getByKeyWithFallback(rb, buf, rb, &ec2); 806b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 807b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru s = ures_getStringByKeyWithFallback(rb, pluralCount, len, &ec2); 808b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(ec2)) { 809b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // fall back to "other" 810b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ec2 = U_ZERO_ERROR; 811b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru s = ures_getStringByKeyWithFallback(rb, "other", len, &ec2); 812b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(ec2)) { 813b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(rb); 814b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // fall back to long name in Currencies 815b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return ucurr_getName(currency, locale, UCURR_LONG_NAME, 816b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru isChoiceFormat, len, ec); 817b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 818b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 819b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(rb); 820b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 821b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // If we've succeeded we're done. Otherwise, try to fallback. 822b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // If that fails (because we are already at root) then exit. 823b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_SUCCESS(ec2)) { 824b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (ec2 == U_USING_DEFAULT_WARNING 825b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru || (ec2 == U_USING_FALLBACK_WARNING && *ec != U_USING_DEFAULT_WARNING)) { 826b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *ec = ec2; 827b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 828b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru U_ASSERT(s != NULL); 829b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return s; 830b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 831b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 832b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // If we fail to find a match, use the ISO 4217 code 833103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *len = u_strlen(currency); // Should == ISO_CURRENCY_CODE_LENGTH, but maybe not...? 834b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *ec = U_USING_DEFAULT_WARNING; 835b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return currency; 836b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 837b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 838b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 839b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru//======================================================================== 840b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Following are structure and function for parsing currency names 841b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 842b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define NEED_TO_BE_DELETED 0x1 843b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 844b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// TODO: a better way to define this? 845b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define MAX_CURRENCY_NAME_LEN 100 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 847b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querutypedef struct { 848b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const char* IsoCode; // key 849b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar* currencyName; // value 850b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t currencyNameLen; // value length 851b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t flag; // flags 852b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} CurrencyNameStruct; 853b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 854b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 855b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifndef MIN 856b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define MIN(a,b) (((a)<(b)) ? (a) : (b)) 857b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 858b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 859b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifndef MAX 860b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define MAX(a,b) (((a)<(b)) ? (b) : (a)) 861b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 862b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 863b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 864b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Comparason function used in quick sort. 86550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int U_CALLCONV currencyNameComparator(const void* a, const void* b) { 866b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const CurrencyNameStruct* currName_1 = (const CurrencyNameStruct*)a; 867b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const CurrencyNameStruct* currName_2 = (const CurrencyNameStruct*)b; 868b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t i = 0; 869b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru i < MIN(currName_1->currencyNameLen, currName_2->currencyNameLen); 870b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ++i) { 871b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (currName_1->currencyName[i] < currName_2->currencyName[i]) { 872b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return -1; 873b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 874b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (currName_1->currencyName[i] > currName_2->currencyName[i]) { 875b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 1; 876b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 877b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 878b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (currName_1->currencyNameLen < currName_2->currencyNameLen) { 879b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return -1; 880b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if (currName_1->currencyNameLen > currName_2->currencyNameLen) { 881b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 1; 882b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 883b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 884b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 885b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 886b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 887b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Give a locale, return the maximum number of currency names associated with 888b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// this locale. 889b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// It gets currency names from resource bundles using fallback. 890b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// It is the maximum number because in the fallback chain, some of the 891b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// currency names are duplicated. 892b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// For example, given locale as "en_US", the currency names get from resource 893b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// bundle in "en_US" and "en" are duplicated. The fallback mechanism will count 894b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// all currency names in "en_US" and "en". 895b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void 896b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QuerugetCurrencyNameCount(const char* loc, int32_t* total_currency_name_count, int32_t* total_currency_symbol_count) { 89750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_NAMESPACE_USE 898b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *total_currency_name_count = 0; 899b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *total_currency_symbol_count = 0; 900b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const UChar* s = NULL; 901b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char locale[ULOC_FULLNAME_CAPACITY]; 902b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_strcpy(locale, loc); 90359d709d503bab6e2b61931737e662dd293b40578ccornelius const icu::Hashtable *currencySymbolsEquiv = getCurrSymbolsEquiv(); 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (;;) { 905b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode ec2 = U_ZERO_ERROR; 906b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // TODO: ures_openDirect? 90750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UResourceBundle* rb = ures_open(U_ICUDATA_CURR, locale, &ec2); 908b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle* curr = ures_getByKey(rb, CURRENCIES, NULL, &ec2); 909b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t n = ures_getSize(curr); 910b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t i=0; i<n; ++i) { 911b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle* names = ures_getByIndex(curr, i, NULL, &ec2); 912b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t len; 913b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru s = ures_getStringByIndex(names, UCURR_SYMBOL_NAME, &len, &ec2); 914b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UBool isChoice = FALSE; 915b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (len > 0 && s[0] == CHOICE_FORMAT_MARK) { 916b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ++s; 917b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru --len; 918b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (len > 0 && s[0] != CHOICE_FORMAT_MARK) { 919b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru isChoice = TRUE; 920b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 921b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 922b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (isChoice) { 923103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ChoiceFormat fmt(UnicodeString(TRUE, s, len), ec2); 924b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t fmt_count; 925b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fmt.getFormats(fmt_count); 926b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *total_currency_symbol_count += fmt_count; 927b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 928b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ++(*total_currency_symbol_count); // currency symbol 92959d709d503bab6e2b61931737e662dd293b40578ccornelius if (currencySymbolsEquiv != NULL) { 93059d709d503bab6e2b61931737e662dd293b40578ccornelius *total_currency_symbol_count += countEquivalent(*currencySymbolsEquiv, UnicodeString(TRUE, s, len)); 93159d709d503bab6e2b61931737e662dd293b40578ccornelius } 932b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 933b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 934b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ++(*total_currency_symbol_count); // iso code 935b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ++(*total_currency_name_count); // long name 936b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(names); 937b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 938b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 939b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // currency plurals 940b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode ec3 = U_ZERO_ERROR; 941b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle* curr_p = ures_getByKey(rb, CURRENCYPLURALS, NULL, &ec3); 942b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru n = ures_getSize(curr_p); 943b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t i=0; i<n; ++i) { 944b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle* names = ures_getByIndex(curr_p, i, NULL, &ec3); 945b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *total_currency_name_count += ures_getSize(names); 946b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(names); 947b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 948b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(curr_p); 949b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(curr); 950b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(rb); 951b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 952b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (!fallback(locale)) { 953b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 954b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 955b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 956b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 957b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 958b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic UChar* 959103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliustoUpperCase(const UChar* source, int32_t len, const char* locale) { 960b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar* dest = NULL; 961b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode ec = U_ZERO_ERROR; 962103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t destLen = u_strToUpper(dest, 0, source, len, locale, &ec); 963b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 964b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ec = U_ZERO_ERROR; 965b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dest = (UChar*)uprv_malloc(sizeof(UChar) * MAX(destLen, len)); 966103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius u_strToUpper(dest, destLen, source, len, locale, &ec); 967b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(ec)) { 968b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_memcpy(dest, source, sizeof(UChar) * len); 969b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 970b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return dest; 971b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 972b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 973b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 974103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Collect all available currency names associated with the given locale 975b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// (enable fallback chain). 976b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Read currenc names defined in resource bundle "Currencies" and 977b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// "CurrencyPlural", enable fallback chain. 978b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// return the malloc-ed currency name arrays and the total number of currency 979b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// names in the array. 980b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void 981b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QuerucollectCurrencyNames(const char* locale, 982b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru CurrencyNameStruct** currencyNames, 983b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t* total_currency_name_count, 984b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru CurrencyNameStruct** currencySymbols, 985b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t* total_currency_symbol_count, 986b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode& ec) { 98750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_NAMESPACE_USE 98859d709d503bab6e2b61931737e662dd293b40578ccornelius const icu::Hashtable *currencySymbolsEquiv = getCurrSymbolsEquiv(); 989b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Look up the Currencies resource for the given locale. 990b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode ec2 = U_ZERO_ERROR; 991b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 992b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char loc[ULOC_FULLNAME_CAPACITY]; 993b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uloc_getName(locale, loc, sizeof(loc), &ec2); 994b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(ec2) || ec2 == U_STRING_NOT_TERMINATED_WARNING) { 995b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 996b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 997b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 998b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Get maximum currency name count first. 999b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru getCurrencyNameCount(loc, total_currency_name_count, total_currency_symbol_count); 1000b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1001b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *currencyNames = (CurrencyNameStruct*)uprv_malloc 1002b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (sizeof(CurrencyNameStruct) * (*total_currency_name_count)); 1003b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *currencySymbols = (CurrencyNameStruct*)uprv_malloc 1004b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (sizeof(CurrencyNameStruct) * (*total_currency_symbol_count)); 1005b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1006b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const UChar* s = NULL; // currency name 1007b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char* iso = NULL; // currency ISO code 1008b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1009b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *total_currency_name_count = 0; 1010b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *total_currency_symbol_count = 0; 1011b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1012b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode ec3 = U_ZERO_ERROR; 1013b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode ec4 = U_ZERO_ERROR; 1014b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1015b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Using hash to remove duplicates caused by locale fallback 1016b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UHashtable* currencyIsoCodes = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &ec3); 1017b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UHashtable* currencyPluralIsoCodes = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &ec4); 1018b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t localeLevel = 0; ; ++localeLevel) { 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec2 = U_ZERO_ERROR; 1020b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // TODO: ures_openDirect 102150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UResourceBundle* rb = ures_open(U_ICUDATA_CURR, loc, &ec2); 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle* curr = ures_getByKey(rb, CURRENCIES, NULL, &ec2); 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t n = ures_getSize(curr); 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int32_t i=0; i<n; ++i) { 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle* names = ures_getByIndex(curr, i, NULL, &ec2); 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len; 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s = ures_getStringByIndex(names, UCURR_SYMBOL_NAME, &len, &ec2); 1028b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // TODO: uhash_put wont change key/value? 1029b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru iso = (char*)ures_getKey(names); 1030b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (localeLevel == 0) { 1031b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uhash_put(currencyIsoCodes, iso, iso, &ec3); 1032b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1033b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (uhash_get(currencyIsoCodes, iso) != NULL) { 1034b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(names); 1035b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru continue; 1036b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1037b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uhash_put(currencyIsoCodes, iso, iso, &ec3); 1038b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1039b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool isChoice = FALSE; 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len > 0 && s[0] == CHOICE_FORMAT_MARK) { 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++s; 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru --len; 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len > 0 && s[0] != CHOICE_FORMAT_MARK) { 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isChoice = TRUE; 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isChoice) { 1049103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ChoiceFormat fmt(UnicodeString(TRUE, s, len), ec2); 1050b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t fmt_count; 1051b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const UnicodeString* formats = fmt.getFormats(fmt_count); 1052b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int i = 0; i < fmt_count; ++i) { 1053b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // put iso, formats[i]; into array 1054b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length = formats[i].length(); 1055b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar* name = (UChar*)uprv_malloc(sizeof(UChar)*length); 1056b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru formats[i].extract(0, length, name); 1057b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencySymbols)[*total_currency_symbol_count].IsoCode = iso; 1058b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencySymbols)[*total_currency_symbol_count].currencyName = name; 1059b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencySymbols)[*total_currency_symbol_count].flag = NEED_TO_BE_DELETED; 1060b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencySymbols)[(*total_currency_symbol_count)++].currencyNameLen = length; 1061b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1062b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1063b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Add currency symbol. 1064b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencySymbols)[*total_currency_symbol_count].IsoCode = iso; 1065b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencySymbols)[*total_currency_symbol_count].currencyName = (UChar*)s; 1066b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencySymbols)[*total_currency_symbol_count].flag = 0; 1067b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencySymbols)[(*total_currency_symbol_count)++].currencyNameLen = len; 106859d709d503bab6e2b61931737e662dd293b40578ccornelius // Add equivalent symbols 106959d709d503bab6e2b61931737e662dd293b40578ccornelius if (currencySymbolsEquiv != NULL) { 107059d709d503bab6e2b61931737e662dd293b40578ccornelius EquivIterator iter(*currencySymbolsEquiv, UnicodeString(TRUE, s, len)); 107159d709d503bab6e2b61931737e662dd293b40578ccornelius const UnicodeString *symbol; 107259d709d503bab6e2b61931737e662dd293b40578ccornelius while ((symbol = iter.next()) != NULL) { 107359d709d503bab6e2b61931737e662dd293b40578ccornelius (*currencySymbols)[*total_currency_symbol_count].IsoCode = iso; 107459d709d503bab6e2b61931737e662dd293b40578ccornelius (*currencySymbols)[*total_currency_symbol_count].currencyName = (UChar*) symbol->getBuffer(); 107559d709d503bab6e2b61931737e662dd293b40578ccornelius (*currencySymbols)[*total_currency_symbol_count].flag = 0; 107659d709d503bab6e2b61931737e662dd293b40578ccornelius (*currencySymbols)[(*total_currency_symbol_count)++].currencyNameLen = symbol->length(); 107759d709d503bab6e2b61931737e662dd293b40578ccornelius } 107859d709d503bab6e2b61931737e662dd293b40578ccornelius } 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1080b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1081b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Add currency long name. 1082b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru s = ures_getStringByIndex(names, UCURR_LONG_NAME, &len, &ec2); 1083b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencyNames)[*total_currency_name_count].IsoCode = iso; 1084103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar* upperName = toUpperCase(s, len, locale); 1085b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencyNames)[*total_currency_name_count].currencyName = upperName; 1086b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencyNames)[*total_currency_name_count].flag = NEED_TO_BE_DELETED; 1087b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencyNames)[(*total_currency_name_count)++].currencyNameLen = len; 1088b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1089b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // put (iso, 3, and iso) in to array 1090b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Add currency ISO code. 1091b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencySymbols)[*total_currency_symbol_count].IsoCode = iso; 1092b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencySymbols)[*total_currency_symbol_count].currencyName = (UChar*)uprv_malloc(sizeof(UChar)*3); 109327f654740f2a26ad62a5c155af9199af9e69b889claireho // Must convert iso[] into Unicode 109427f654740f2a26ad62a5c155af9199af9e69b889claireho u_charsToUChars(iso, (*currencySymbols)[*total_currency_symbol_count].currencyName, 3); 1095b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencySymbols)[*total_currency_symbol_count].flag = NEED_TO_BE_DELETED; 1096b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencySymbols)[(*total_currency_symbol_count)++].currencyNameLen = 3; 1097b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1098b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(names); 1099b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1100b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1101b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // currency plurals 1102b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode ec3 = U_ZERO_ERROR; 1103b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle* curr_p = ures_getByKey(rb, CURRENCYPLURALS, NULL, &ec3); 1104b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru n = ures_getSize(curr_p); 1105b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t i=0; i<n; ++i) { 1106b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle* names = ures_getByIndex(curr_p, i, NULL, &ec3); 1107b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru iso = (char*)ures_getKey(names); 1108b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Using hash to remove duplicated ISO codes in fallback chain. 1109b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (localeLevel == 0) { 1110b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uhash_put(currencyPluralIsoCodes, iso, iso, &ec4); 1111b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1112b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (uhash_get(currencyPluralIsoCodes, iso) != NULL) { 1113b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(names); 1114b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru continue; 1115b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1116b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uhash_put(currencyPluralIsoCodes, iso, iso, &ec4); 1117b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1118b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1119b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t num = ures_getSize(names); 1120b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t len; 1121b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t j = 0; j < num; ++j) { 1122b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // TODO: remove duplicates between singular name and 1123b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // currency long name? 1124b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru s = ures_getStringByIndex(names, j, &len, &ec3); 1125b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencyNames)[*total_currency_name_count].IsoCode = iso; 1126103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar* upperName = toUpperCase(s, len, locale); 1127b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencyNames)[*total_currency_name_count].currencyName = upperName; 1128b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencyNames)[*total_currency_name_count].flag = NEED_TO_BE_DELETED; 1129b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru (*currencyNames)[(*total_currency_name_count)++].currencyNameLen = len; 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(names); 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1133b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(curr_p); 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(curr); 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(rb); 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!fallback(loc)) { 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1142b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uhash_close(currencyIsoCodes); 1143b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uhash_close(currencyPluralIsoCodes); 1144b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1145b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // quick sort the struct 1146b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru qsort(*currencyNames, *total_currency_name_count, 1147b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru sizeof(CurrencyNameStruct), currencyNameComparator); 1148b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru qsort(*currencySymbols, *total_currency_symbol_count, 1149b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru sizeof(CurrencyNameStruct), currencyNameComparator); 1150b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1151b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1152b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("currency name count: %d\n", *total_currency_name_count); 1153b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t index = 0; index < *total_currency_name_count; ++index) { 1154b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("index: %d\n", index); 1155b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("iso: %s\n", (*currencyNames)[index].IsoCode); 115659d709d503bab6e2b61931737e662dd293b40578ccornelius char curNameBuf[1024]; 115759d709d503bab6e2b61931737e662dd293b40578ccornelius memset(curNameBuf, 0, 1024); 115859d709d503bab6e2b61931737e662dd293b40578ccornelius u_austrncpy(curNameBuf, (*currencyNames)[index].currencyName, (*currencyNames)[index].currencyNameLen); 115959d709d503bab6e2b61931737e662dd293b40578ccornelius printf("currencyName: %s\n", curNameBuf); 1160b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("len: %d\n", (*currencyNames)[index].currencyNameLen); 1161b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1162b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("currency symbol count: %d\n", *total_currency_symbol_count); 1163b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t index = 0; index < *total_currency_symbol_count; ++index) { 1164b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("index: %d\n", index); 1165b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("iso: %s\n", (*currencySymbols)[index].IsoCode); 116659d709d503bab6e2b61931737e662dd293b40578ccornelius char curNameBuf[1024]; 116759d709d503bab6e2b61931737e662dd293b40578ccornelius memset(curNameBuf, 0, 1024); 116859d709d503bab6e2b61931737e662dd293b40578ccornelius u_austrncpy(curNameBuf, (*currencySymbols)[index].currencyName, (*currencySymbols)[index].currencyNameLen); 116959d709d503bab6e2b61931737e662dd293b40578ccornelius printf("currencySymbol: %s\n", curNameBuf); 1170b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("len: %d\n", (*currencySymbols)[index].currencyNameLen); 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1172b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1173b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1175b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// @param currencyNames: currency names array 1176b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// @param indexInCurrencyNames: the index of the character in currency names 1177b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// array against which the comparison is done 1178b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// @param key: input text char to compare against 1179b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// @param begin(IN/OUT): the begin index of matching range in currency names array 1180b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// @param end(IN/OUT): the end index of matching range in currency names array. 1181b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int32_t 1182b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QuerubinarySearch(const CurrencyNameStruct* currencyNames, 1183b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t indexInCurrencyNames, 1184b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const UChar key, 1185b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t* begin, int32_t* end) { 1186b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1187b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("key = %x\n", key); 1188b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1189b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t first = *begin; 1190b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t last = *end; 1191b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru while (first <= last) { 1192b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t mid = (first + last) / 2; // compute mid point. 1193b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (indexInCurrencyNames >= currencyNames[mid].currencyNameLen) { 1194b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru first = mid + 1; 1195b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1196b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (key > currencyNames[mid].currencyName[indexInCurrencyNames]) { 1197b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru first = mid + 1; 1198b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1199b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else if (key < currencyNames[mid].currencyName[indexInCurrencyNames]) { 1200b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru last = mid - 1; 1201b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1202b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else { 1203b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Find a match, and looking for ranges 1204b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Now do two more binary searches. First, on the left side for 1205b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // the greatest L such that CurrencyNameStruct[L] < key. 1206b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t L = *begin; 1207b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t R = mid; 1208b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1209b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1210b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("mid = %d\n", mid); 1211b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1212b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru while (L < R) { 1213b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t M = (L + R) / 2; 1214b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1215b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("L = %d, R = %d, M = %d\n", L, R, M); 1216b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1217b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (indexInCurrencyNames >= currencyNames[M].currencyNameLen) { 1218b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru L = M + 1; 1219b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1220b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (currencyNames[M].currencyName[indexInCurrencyNames] < key) { 1221b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru L = M + 1; 1222b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1223b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1224b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru U_ASSERT(currencyNames[M].currencyName[indexInCurrencyNames] == key); 1225b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1226b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru R = M; 1227b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1228b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1229b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1230b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1231b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru U_ASSERT(L == R); 1232b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1233b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *begin = L; 1234b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1235b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("begin = %d\n", *begin); 1236b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru U_ASSERT(currencyNames[*begin].currencyName[indexInCurrencyNames] == key); 1237b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1238b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1239b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Now for the second search, finding the least R such that 1240b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // key < CurrencyNameStruct[R]. 1241b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru L = mid; 1242b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru R = *end; 1243b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru while (L < R) { 1244b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t M = (L + R) / 2; 1245b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1246b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("L = %d, R = %d, M = %d\n", L, R, M); 1247b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1248b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (currencyNames[M].currencyNameLen < indexInCurrencyNames) { 1249b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru L = M + 1; 1250b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1251b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (currencyNames[M].currencyName[indexInCurrencyNames] > key) { 1252b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru R = M; 1253b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1254b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1255b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru U_ASSERT(currencyNames[M].currencyName[indexInCurrencyNames] == key); 1256b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1257b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru L = M + 1; 1258b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1259b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1260b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1261b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1262b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru U_ASSERT(L == R); 1263b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1264b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (currencyNames[R].currencyName[indexInCurrencyNames] > key) { 1265b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *end = R - 1; 1266b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1267b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *end = R; 1268b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1269b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1270b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("end = %d\n", *end); 1271b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1272b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1273b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // now, found the range. check whether there is exact match 1274b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (currencyNames[*begin].currencyNameLen == indexInCurrencyNames + 1) { 1275b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return *begin; // find range and exact match. 1276b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1277b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return -1; // find range, but no exact match. 1278b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1279b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1280b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1281b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *begin = -1; 1282b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *end = -1; 1283b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return -1; // failed to find range. 1284b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 1285b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1286b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1287b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Linear search "text" in "currencyNames". 1288b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// @param begin, end: the begin and end index in currencyNames, within which 1289b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// range should the search be performed. 1290b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// @param textLen: the length of the text to be compared 1291b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// @param maxMatchLen(IN/OUT): passing in the computed max matching length 1292b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// pass out the new max matching length 1293b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// @param maxMatchIndex: the index in currencyName which has the longest 1294b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// match with input text. 1295b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void 1296b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QuerulinearSearch(const CurrencyNameStruct* currencyNames, 1297b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t begin, int32_t end, 1298b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const UChar* text, int32_t textLen, 1299b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t *maxMatchLen, int32_t* maxMatchIndex) { 1300b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t index = begin; index <= end; ++index) { 1301b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t len = currencyNames[index].currencyNameLen; 1302b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (len > *maxMatchLen && len <= textLen && 1303b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_memcmp(currencyNames[index].currencyName, text, len * sizeof(UChar)) == 0) { 1304b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *maxMatchIndex = index; 1305b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *maxMatchLen = len; 1306b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1307b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("maxMatchIndex = %d, maxMatchLen = %d\n", 1308b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *maxMatchIndex, *maxMatchLen); 1309b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1310b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1311b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1312b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 1313b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1314b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LINEAR_SEARCH_THRESHOLD 10 1315b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1316b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Find longest match between "text" and currency names in "currencyNames". 1317b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// @param total_currency_count: total number of currency names in CurrencyNames. 1318b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// @param textLen: the length of the text to be compared 1319b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// @param maxMatchLen: passing in the computed max matching length 1320b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// pass out the new max matching length 1321b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// @param maxMatchIndex: the index in currencyName which has the longest 1322b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// match with input text. 1323b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void 1324b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QuerusearchCurrencyName(const CurrencyNameStruct* currencyNames, 1325b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t total_currency_count, 1326b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const UChar* text, int32_t textLen, 1327b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t* maxMatchLen, int32_t* maxMatchIndex) { 1328b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *maxMatchIndex = -1; 1329b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *maxMatchLen = 0; 1330b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t matchIndex = -1; 1331b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t binarySearchBegin = 0; 1332b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t binarySearchEnd = total_currency_count - 1; 1333b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // It is a variant of binary search. 1334b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // For example, given the currency names in currencyNames array are: 1335b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // A AB ABC AD AZ B BB BBEX BBEXYZ BS C D E.... 1336b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // and the input text is BBEXST 1337b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // The first round binary search search "B" in the text against 1338b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // the first char in currency names, and find the first char matching range 1339b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // to be "B BB BBEX BBEXYZ BS" (and the maximum matching "B"). 1340b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // The 2nd round binary search search the second "B" in the text against 1341b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // the 2nd char in currency names, and narrow the matching range to 1342b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // "BB BBEX BBEXYZ" (and the maximum matching "BB"). 1343b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // The 3rd round returnes the range as "BBEX BBEXYZ" (without changing 1344b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // maximum matching). 1345b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // The 4th round returns the same range (the maximum matching is "BBEX"). 1346b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // The 5th round returns no matching range. 1347b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t index = 0; index < textLen; ++index) { 1348b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // matchIndex saves the one with exact match till the current point. 1349b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // [binarySearchBegin, binarySearchEnd] saves the matching range. 1350b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru matchIndex = binarySearch(currencyNames, index, 1351b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru text[index], 1352b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &binarySearchBegin, &binarySearchEnd); 1353b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (binarySearchBegin == -1) { // did not find the range 1354b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 1355b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1356b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (matchIndex != -1) { 1357b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // find an exact match for text from text[0] to text[index] 1358b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // in currencyNames array. 1359b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *maxMatchLen = index + 1; 1360b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *maxMatchIndex = matchIndex; 1361b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1362b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (binarySearchEnd - binarySearchBegin < LINEAR_SEARCH_THRESHOLD) { 1363b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // linear search if within threshold. 1364b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru linearSearch(currencyNames, binarySearchBegin, binarySearchEnd, 1365b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru text, textLen, 1366b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru maxMatchLen, maxMatchIndex); 1367b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 1368b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1369b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1370b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 1371b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 1372b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1373b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru//========================= currency name cache ===================== 1374b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querutypedef struct { 1375b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char locale[ULOC_FULLNAME_CAPACITY]; //key 1376b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // currency names, case insensitive 1377b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru CurrencyNameStruct* currencyNames; // value 1378b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t totalCurrencyNameCount; // currency name count 1379b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // currency symbols and ISO code, case sensitive 1380b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru CurrencyNameStruct* currencySymbols; // value 1381b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t totalCurrencySymbolCount; // count 1382b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // reference count. 1383b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // reference count is set to 1 when an entry is put to cache. 1384b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // it increases by 1 before accessing, and decreased by 1 after accessing. 1385b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // The entry is deleted when ref count is zero, which means 1386b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // the entry is replaced out of cache and no process is accessing it. 1387b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t refCount; 1388b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} CurrencyNameCacheEntry; 1389b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1390b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1391b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define CURRENCY_NAME_CACHE_NUM 10 1392b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1393b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Reserve 10 cache entries. 1394b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic CurrencyNameCacheEntry* currCache[CURRENCY_NAME_CACHE_NUM] = {NULL}; 1395b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Using an index to indicate which entry to be replaced when cache is full. 1396b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// It is a simple round-robin replacement strategy. 1397b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int8_t currentCacheEntryIndex = 0; 1398b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 139959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic UMutex gCurrencyCacheMutex = U_MUTEX_INITIALIZER; 140059d709d503bab6e2b61931737e662dd293b40578ccornelius 1401b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Cache deletion 1402b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void 1403b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QuerudeleteCurrencyNames(CurrencyNameStruct* currencyNames, int32_t count) { 1404b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t index = 0; index < count; ++index) { 1405b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if ( (currencyNames[index].flag & NEED_TO_BE_DELETED) ) { 1406b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(currencyNames[index].currencyName); 1407b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1408b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1409b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(currencyNames); 1410b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 1411b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1412b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1413b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic void 1414b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QuerudeleteCacheEntry(CurrencyNameCacheEntry* entry) { 1415b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru deleteCurrencyNames(entry->currencyNames, entry->totalCurrencyNameCount); 1416b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru deleteCurrencyNames(entry->currencySymbols, entry->totalCurrencySymbolCount); 1417b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(entry); 1418b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 1419b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1420b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1421b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Cache clean up 142250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool U_CALLCONV 1423b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querucurrency_cache_cleanup(void) { 1424b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t i = 0; i < CURRENCY_NAME_CACHE_NUM; ++i) { 1425b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (currCache[i]) { 1426b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru deleteCacheEntry(currCache[i]); 1427b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currCache[i] = 0; 1428b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1429b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1430b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return TRUE; 1431b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 1432b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1433b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1434b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CFUNC void 1435b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruuprv_parseCurrency(const char* locale, 1436103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const icu::UnicodeString& text, 1437103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius icu::ParsePosition& pos, 1438b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int8_t type, 1439b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar* result, 1440b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode& ec) 1441b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{ 1442b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru U_NAMESPACE_USE 1443b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1444b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(ec)) { 1445b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 1446b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1447b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1448b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t total_currency_name_count = 0; 1449b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru CurrencyNameStruct* currencyNames = NULL; 1450b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t total_currency_symbol_count = 0; 1451b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru CurrencyNameStruct* currencySymbols = NULL; 1452b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru CurrencyNameCacheEntry* cacheEntry = NULL; 1453b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 145459d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_lock(&gCurrencyCacheMutex); 1455b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // in order to handle racing correctly, 145659d709d503bab6e2b61931737e662dd293b40578ccornelius // not putting 'search' in a separate function. 1457b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int8_t found = -1; 1458b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int8_t i = 0; i < CURRENCY_NAME_CACHE_NUM; ++i) { 1459b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (currCache[i]!= NULL && 1460b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_strcmp(locale, currCache[i]->locale) == 0) { 1461b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru found = i; 1462b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 1463b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1464b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1465b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (found != -1) { 1466b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru cacheEntry = currCache[found]; 1467b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currencyNames = cacheEntry->currencyNames; 1468b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru total_currency_name_count = cacheEntry->totalCurrencyNameCount; 1469b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currencySymbols = cacheEntry->currencySymbols; 1470b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru total_currency_symbol_count = cacheEntry->totalCurrencySymbolCount; 1471b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ++(cacheEntry->refCount); 1472b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 147359d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_unlock(&gCurrencyCacheMutex); 1474b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (found == -1) { 1475b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru collectCurrencyNames(locale, ¤cyNames, &total_currency_name_count, ¤cySymbols, &total_currency_symbol_count, ec); 1476b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(ec)) { 1477b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 1478b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 147959d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_lock(&gCurrencyCacheMutex); 1480b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // check again. 1481b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int8_t found = -1; 1482b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int8_t i = 0; i < CURRENCY_NAME_CACHE_NUM; ++i) { 1483b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (currCache[i]!= NULL && 1484b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_strcmp(locale, currCache[i]->locale) == 0) { 1485b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru found = i; 1486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1489b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (found == -1) { 1490b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // insert new entry to 1491b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // currentCacheEntryIndex % CURRENCY_NAME_CACHE_NUM 1492b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // and remove the existing entry 1493b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // currentCacheEntryIndex % CURRENCY_NAME_CACHE_NUM 1494b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // from cache. 1495b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru cacheEntry = currCache[currentCacheEntryIndex]; 1496b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (cacheEntry) { 1497b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru --(cacheEntry->refCount); 1498b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // delete if the ref count is zero 1499b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (cacheEntry->refCount == 0) { 1500b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru deleteCacheEntry(cacheEntry); 1501b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1502b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1503b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru cacheEntry = (CurrencyNameCacheEntry*)uprv_malloc(sizeof(CurrencyNameCacheEntry)); 1504b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currCache[currentCacheEntryIndex] = cacheEntry; 1505b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_strcpy(cacheEntry->locale, locale); 1506b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru cacheEntry->currencyNames = currencyNames; 1507b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru cacheEntry->totalCurrencyNameCount = total_currency_name_count; 1508b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru cacheEntry->currencySymbols = currencySymbols; 1509b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru cacheEntry->totalCurrencySymbolCount = total_currency_symbol_count; 1510b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru cacheEntry->refCount = 2; // one for cache, one for reference 1511b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currentCacheEntryIndex = (currentCacheEntryIndex + 1) % CURRENCY_NAME_CACHE_NUM; 1512b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ucln_i18n_registerCleanup(UCLN_I18N_CURRENCY, currency_cache_cleanup); 1513b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1514b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1515b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru deleteCurrencyNames(currencyNames, total_currency_name_count); 1516b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru deleteCurrencyNames(currencySymbols, total_currency_symbol_count); 1517b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru cacheEntry = currCache[found]; 1518b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currencyNames = cacheEntry->currencyNames; 1519b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru total_currency_name_count = cacheEntry->totalCurrencyNameCount; 1520b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currencySymbols = cacheEntry->currencySymbols; 1521b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru total_currency_symbol_count = cacheEntry->totalCurrencySymbolCount; 1522b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ++(cacheEntry->refCount); 1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 152459d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_unlock(&gCurrencyCacheMutex); 1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1527b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t start = pos.getIndex(); 1528b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1529b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar inputText[MAX_CURRENCY_NAME_LEN]; 1530b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar upperText[MAX_CURRENCY_NAME_LEN]; 1531b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t textLen = MIN(MAX_CURRENCY_NAME_LEN, text.length() - start); 1532b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru text.extract(start, textLen, inputText); 1533b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode ec1 = U_ZERO_ERROR; 1534103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius textLen = u_strToUpper(upperText, MAX_CURRENCY_NAME_LEN, inputText, textLen, locale, &ec1); 1535b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1536b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t max = 0; 1537b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t matchIndex = -1; 1538b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // case in-sensitive comparision against currency names 1539b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru searchCurrencyName(currencyNames, total_currency_name_count, 1540b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru upperText, textLen, &max, &matchIndex); 1541b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1542b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1543b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("search in names, max = %d, matchIndex = %d\n", max, matchIndex); 1544b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1545b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1546b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t maxInSymbol = 0; 1547b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t matchIndexInSymbol = -1; 1548b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (type != UCURR_LONG_NAME) { // not name only 1549b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // case sensitive comparison against currency symbols and ISO code. 1550b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru searchCurrencyName(currencySymbols, total_currency_symbol_count, 1551b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru inputText, textLen, 1552b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &maxInSymbol, &matchIndexInSymbol); 1553b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1554b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1555b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef UCURR_DEBUG 1556b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru printf("search in symbols, maxInSymbol = %d, matchIndexInSymbol = %d\n", maxInSymbol, matchIndexInSymbol); 155759d709d503bab6e2b61931737e662dd293b40578ccornelius if(matchIndexInSymbol != -1) { 155859d709d503bab6e2b61931737e662dd293b40578ccornelius printf("== ISO=%s\n", currencySymbols[matchIndexInSymbol].IsoCode); 155959d709d503bab6e2b61931737e662dd293b40578ccornelius } 1560b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 1561b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1562b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (max >= maxInSymbol && matchIndex != -1) { 1563b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_charsToUChars(currencyNames[matchIndex].IsoCode, result, 4); 1564b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pos.setIndex(start + max); 1565b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if (maxInSymbol >= max && matchIndexInSymbol != -1) { 1566b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_charsToUChars(currencySymbols[matchIndexInSymbol].IsoCode, result, 4); 1567b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pos.setIndex(start + maxInSymbol); 1568b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1569b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1570b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // decrease reference count 157159d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_lock(&gCurrencyCacheMutex); 1572b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru --(cacheEntry->refCount); 1573b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (cacheEntry->refCount == 0) { // remove 1574b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru deleteCacheEntry(cacheEntry); 1575b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 157659d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_unlock(&gCurrencyCacheMutex); 1577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1579b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Internal method. Given a currency ISO code and a locale, return 1582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the "static" currency name. This is usually the same as the 1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * UCURR_SYMBOL_NAME, but if the latter is a choice format, then the 1584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * format is applied to the number 2.0 (to yield the more common 1585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * plural) to return a static name. 1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * This is used for backward compatibility with old currency logic in 1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * DecimalFormat and DecimalFormatSymbols. 1589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1590c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruU_CFUNC void 1591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuprv_getStaticCurrencyName(const UChar* iso, const char* loc, 1592103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius icu::UnicodeString& result, UErrorCode& ec) 1593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_NAMESPACE_USE 1595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool isChoiceFormat; 1597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len; 1598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar* currname = ucurr_getName(iso, loc, UCURR_SYMBOL_NAME, 1599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru &isChoiceFormat, &len, &ec); 1600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(ec)) { 1601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If this is a ChoiceFormat currency, then format an 1602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // arbitrary value; pick something != 1; more common. 1603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result.truncate(0); 1604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isChoiceFormat) { 1605103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ChoiceFormat f(UnicodeString(TRUE, currname, len), ec); 1606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(ec)) { 1607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru f.format(2.0, result); 1608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1609103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.setTo(iso, -1); 1610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1612103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.setTo(currname, -1); 1613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucurr_getDefaultFractionDigits(const UChar* currency, UErrorCode* ec) { 1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (_findMetaData(currency, *ec))[0]; 1620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI double U_EXPORT2 1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucurr_getRoundingIncrement(const UChar* currency, UErrorCode* ec) { 1624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int32_t *data = _findMetaData(currency, *ec); 1625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If the meta data is invalid, return 0.0. 1627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (data[0] < 0 || data[0] > MAX_POW10) { 1628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(*ec)) { 1629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *ec = U_INVALID_FORMAT_ERROR; 1630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0.0; 1632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If there is no rounding, return 0.0 to indicate no rounding. A 1635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // rounding value (data[1]) of 0 or 1 indicates no rounding. 1636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (data[1] < 2) { 1637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0.0; 1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Return data[1] / 10^(data[0]). The only actual rounding data, 1641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // as of this writing, is CHF { 2, 5 }. 1642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return double(data[1]) / POW10[data[0]]; 1643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN 1646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct UCurrencyContext { 1648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t currType; /* UCurrCurrencyType */ 1649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t listIdx; 1650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} UCurrencyContext; 1651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 1653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruPlease keep this list in alphabetical order. 1654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruYou can look at the CLDR supplemental data or ISO-4217 for the meaning of some 1655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruof these items. 1656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruISO-4217: http://www.iso.org/iso/en/prods-services/popstds/currencycodeslist.html 1657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const struct CurrencyList { 1659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *currency; 1660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t currType; 1661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} gCurrencyList[] = { 1662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ADP", UCURR_COMMON|UCURR_DEPRECATED}, 1663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"AED", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"AFA", UCURR_COMMON|UCURR_DEPRECATED}, 1665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"AFN", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1666c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"ALK", UCURR_COMMON|UCURR_DEPRECATED}, 1667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ALL", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"AMD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ANG", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"AOA", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"AOK", UCURR_COMMON|UCURR_DEPRECATED}, 1672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"AON", UCURR_COMMON|UCURR_DEPRECATED}, 1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"AOR", UCURR_COMMON|UCURR_DEPRECATED}, 1674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ARA", UCURR_COMMON|UCURR_DEPRECATED}, 1675b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"ARL", UCURR_COMMON|UCURR_DEPRECATED}, 1676b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"ARM", UCURR_COMMON|UCURR_DEPRECATED}, 1677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ARP", UCURR_COMMON|UCURR_DEPRECATED}, 1678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ARS", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ATS", UCURR_COMMON|UCURR_DEPRECATED}, 1680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"AUD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"AWG", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"AZM", UCURR_COMMON|UCURR_DEPRECATED}, 1683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"AZN", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BAD", UCURR_COMMON|UCURR_DEPRECATED}, 1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BAM", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1686b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"BAN", UCURR_COMMON|UCURR_DEPRECATED}, 1687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BBD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BDT", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BEC", UCURR_UNCOMMON|UCURR_DEPRECATED}, 1690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BEF", UCURR_COMMON|UCURR_DEPRECATED}, 1691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BEL", UCURR_UNCOMMON|UCURR_DEPRECATED}, 1692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BGL", UCURR_COMMON|UCURR_DEPRECATED}, 1693c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru {"BGM", UCURR_COMMON|UCURR_DEPRECATED}, 1694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BGN", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1695b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"BGO", UCURR_COMMON|UCURR_DEPRECATED}, 1696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BHD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BIF", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BMD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BND", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BOB", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1701b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"BOL", UCURR_COMMON|UCURR_DEPRECATED}, 1702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BOP", UCURR_COMMON|UCURR_DEPRECATED}, 1703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BOV", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BRB", UCURR_COMMON|UCURR_DEPRECATED}, 1705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BRC", UCURR_COMMON|UCURR_DEPRECATED}, 1706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BRE", UCURR_COMMON|UCURR_DEPRECATED}, 1707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BRL", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BRN", UCURR_COMMON|UCURR_DEPRECATED}, 1709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BRR", UCURR_COMMON|UCURR_DEPRECATED}, 1710b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"BRZ", UCURR_COMMON|UCURR_DEPRECATED}, 1711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BSD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BTN", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BUK", UCURR_COMMON|UCURR_DEPRECATED}, 1714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BWP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BYB", UCURR_COMMON|UCURR_DEPRECATED}, 1716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BYR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"BZD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CAD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CDF", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CHE", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CHF", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CHW", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1723b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"CLE", UCURR_COMMON|UCURR_DEPRECATED}, 1724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CLF", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CLP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CNX", UCURR_UNCOMMON|UCURR_DEPRECATED}, 1727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CNY", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"COP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"COU", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CRC", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CSD", UCURR_COMMON|UCURR_DEPRECATED}, 1732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CSK", UCURR_COMMON|UCURR_DEPRECATED}, 1733b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"CUC", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CUP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CVE", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CYP", UCURR_COMMON|UCURR_DEPRECATED}, 1737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"CZK", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"DDM", UCURR_COMMON|UCURR_DEPRECATED}, 1739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"DEM", UCURR_COMMON|UCURR_DEPRECATED}, 1740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"DJF", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"DKK", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"DOP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"DZD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ECS", UCURR_COMMON|UCURR_DEPRECATED}, 1745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ECV", UCURR_UNCOMMON|UCURR_DEPRECATED}, 1746b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho {"EEK", UCURR_COMMON|UCURR_DEPRECATED}, 1747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"EGP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"EQE", UCURR_COMMON|UCURR_DEPRECATED}, 1749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ERN", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ESA", UCURR_UNCOMMON|UCURR_DEPRECATED}, 1751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ESB", UCURR_UNCOMMON|UCURR_DEPRECATED}, 1752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ESP", UCURR_COMMON|UCURR_DEPRECATED}, 1753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ETB", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"EUR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"FIM", UCURR_COMMON|UCURR_DEPRECATED}, 1756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"FJD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"FKP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"FRF", UCURR_COMMON|UCURR_DEPRECATED}, 1759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GBP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GEK", UCURR_COMMON|UCURR_DEPRECATED}, 1761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GEL", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GHC", UCURR_COMMON|UCURR_DEPRECATED}, 1763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GHS", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GIP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GMD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GNF", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GNS", UCURR_COMMON|UCURR_DEPRECATED}, 1768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GQE", UCURR_COMMON|UCURR_DEPRECATED}, 1769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GRD", UCURR_COMMON|UCURR_DEPRECATED}, 1770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GTQ", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GWE", UCURR_COMMON|UCURR_DEPRECATED}, 1772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GWP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"GYD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"HKD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"HNL", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"HRD", UCURR_COMMON|UCURR_DEPRECATED}, 1777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"HRK", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"HTG", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"HUF", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"IDR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"IEP", UCURR_COMMON|UCURR_DEPRECATED}, 1782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ILP", UCURR_COMMON|UCURR_DEPRECATED}, 1783b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"ILR", UCURR_COMMON|UCURR_DEPRECATED}, 1784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ILS", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"INR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"IQD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"IRR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1788b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"ISJ", UCURR_COMMON|UCURR_DEPRECATED}, 1789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ISK", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ITL", UCURR_COMMON|UCURR_DEPRECATED}, 1791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"JMD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"JOD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"JPY", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"KES", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"KGS", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"KHR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"KMF", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"KPW", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1799b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"KRH", UCURR_COMMON|UCURR_DEPRECATED}, 1800b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"KRO", UCURR_COMMON|UCURR_DEPRECATED}, 1801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"KRW", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"KWD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"KYD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"KZT", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LAK", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LBP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LKR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LRD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LSL", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LSM", UCURR_COMMON|UCURR_DEPRECATED}, 1811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LTL", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LTT", UCURR_COMMON|UCURR_DEPRECATED}, 1813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LUC", UCURR_UNCOMMON|UCURR_DEPRECATED}, 1814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LUF", UCURR_COMMON|UCURR_DEPRECATED}, 1815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LUL", UCURR_UNCOMMON|UCURR_DEPRECATED}, 1816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LVL", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LVR", UCURR_COMMON|UCURR_DEPRECATED}, 1818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"LYD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MAD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MAF", UCURR_COMMON|UCURR_DEPRECATED}, 1821b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"MCF", UCURR_COMMON|UCURR_DEPRECATED}, 1822b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"MDC", UCURR_COMMON|UCURR_DEPRECATED}, 1823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MDL", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MGA", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MGF", UCURR_COMMON|UCURR_DEPRECATED}, 1826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MKD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1827b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"MKN", UCURR_COMMON|UCURR_DEPRECATED}, 1828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MLF", UCURR_COMMON|UCURR_DEPRECATED}, 1829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MMK", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MNT", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MOP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MRO", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MTL", UCURR_COMMON|UCURR_DEPRECATED}, 1834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MTP", UCURR_COMMON|UCURR_DEPRECATED}, 1835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MUR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1836b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"MVP", UCURR_COMMON|UCURR_DEPRECATED}, 1837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MVR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MWK", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MXN", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MXP", UCURR_COMMON|UCURR_DEPRECATED}, 1841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MXV", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MYR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MZE", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MZM", UCURR_COMMON|UCURR_DEPRECATED}, 1845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"MZN", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"NAD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"NGN", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"NIC", UCURR_COMMON|UCURR_DEPRECATED}, 1849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"NIO", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"NLG", UCURR_COMMON|UCURR_DEPRECATED}, 1851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"NOK", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"NPR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"NZD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"OMR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"PAB", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"PEI", UCURR_COMMON|UCURR_DEPRECATED}, 1857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"PEN", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"PES", UCURR_COMMON|UCURR_DEPRECATED}, 1859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"PGK", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"PHP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"PKR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"PLN", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"PLZ", UCURR_COMMON|UCURR_DEPRECATED}, 1864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"PTE", UCURR_COMMON|UCURR_DEPRECATED}, 1865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"PYG", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"QAR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"RHD", UCURR_COMMON|UCURR_DEPRECATED}, 1868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ROL", UCURR_COMMON|UCURR_DEPRECATED}, 1869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"RON", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"RSD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"RUB", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"RUR", UCURR_COMMON|UCURR_DEPRECATED}, 1873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"RWF", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SAR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SBD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SCR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SDD", UCURR_COMMON|UCURR_DEPRECATED}, 1878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SDG", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SDP", UCURR_COMMON|UCURR_DEPRECATED}, 1880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SEK", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SGD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SHP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SIT", UCURR_COMMON|UCURR_DEPRECATED}, 1884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SKK", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SLL", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SOS", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SRD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SRG", UCURR_COMMON|UCURR_DEPRECATED}, 18898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius {"SSP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"STD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SUR", UCURR_COMMON|UCURR_DEPRECATED}, 1892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SVC", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SYP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"SZL", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"THB", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"TJR", UCURR_COMMON|UCURR_DEPRECATED}, 1897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"TJS", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1898b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"TMM", UCURR_COMMON|UCURR_DEPRECATED}, 1899b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"TMT", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"TND", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"TOP", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"TPE", UCURR_COMMON|UCURR_DEPRECATED}, 1903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"TRL", UCURR_COMMON|UCURR_DEPRECATED}, 1904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"TRY", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"TTD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"TWD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"TZS", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"UAH", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"UAK", UCURR_COMMON|UCURR_DEPRECATED}, 1910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"UGS", UCURR_COMMON|UCURR_DEPRECATED}, 1911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"UGX", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"USD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"USN", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"USS", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"UYI", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1916b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"UYP", UCURR_COMMON|UCURR_DEPRECATED}, 1917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"UYU", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"UZS", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"VEB", UCURR_COMMON|UCURR_DEPRECATED}, 1920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"VEF", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"VND", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1922b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"VNN", UCURR_COMMON|UCURR_DEPRECATED}, 1923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"VUV", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"WST", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XAF", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XAG", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XAU", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XBA", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XBB", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XBC", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XBD", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XCD", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XDR", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XEU", UCURR_UNCOMMON|UCURR_DEPRECATED}, 1935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XFO", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XFU", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XOF", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XPD", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XPF", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XPT", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XRE", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 19428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius {"XSU", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XTS", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 19448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius {"XUA", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"XXX", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"YDD", UCURR_COMMON|UCURR_DEPRECATED}, 1947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"YER", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"YUD", UCURR_COMMON|UCURR_DEPRECATED}, 1949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"YUM", UCURR_COMMON|UCURR_DEPRECATED}, 1950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"YUN", UCURR_COMMON|UCURR_DEPRECATED}, 1951b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"YUR", UCURR_COMMON|UCURR_DEPRECATED}, 1952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ZAL", UCURR_UNCOMMON|UCURR_NON_DEPRECATED}, 1953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ZAR", UCURR_COMMON|UCURR_NON_DEPRECATED}, 19548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius {"ZMK", UCURR_COMMON|UCURR_DEPRECATED}, 19558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius {"ZMW", UCURR_COMMON|UCURR_NON_DEPRECATED}, 1956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ZRN", UCURR_COMMON|UCURR_DEPRECATED}, 1957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {"ZRZ", UCURR_COMMON|UCURR_DEPRECATED}, 19588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius {"ZWL", UCURR_COMMON|UCURR_DEPRECATED}, 1959b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"ZWR", UCURR_COMMON|UCURR_DEPRECATED}, 1960b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru {"ZWD", UCURR_COMMON|UCURR_DEPRECATED}, 1961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { NULL, 0 } // Leave here to denote the end of the list. 1962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 1963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define UCURR_MATCHES_BITMASK(variable, typeToMatch) \ 1965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((typeToMatch) == UCURR_ALL || ((variable) & (typeToMatch)) == (typeToMatch)) 1966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t U_CALLCONV 1968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucurr_countCurrencyList(UEnumeration *enumerator, UErrorCode * /*pErrorCode*/) { 1969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCurrencyContext *myContext = (UCurrencyContext *)(enumerator->context); 1970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t currType = myContext->currType; 1971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t count = 0; 1972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Count the number of items matching the type we are looking for. */ 1974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int32_t idx = 0; gCurrencyList[idx].currency != NULL; idx++) { 1975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (UCURR_MATCHES_BITMASK(gCurrencyList[idx].currType, currType)) { 1976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count++; 1977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return count; 1980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char* U_CALLCONV 1983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucurr_nextCurrencyList(UEnumeration *enumerator, 1984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t* resultLength, 1985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode * /*pErrorCode*/) 1986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCurrencyContext *myContext = (UCurrencyContext *)(enumerator->context); 1988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Find the next in the list that matches the type we are looking for. */ 1990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (myContext->listIdx < (sizeof(gCurrencyList)/sizeof(gCurrencyList[0]))-1) { 1991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const struct CurrencyList *currItem = &gCurrencyList[myContext->listIdx++]; 1992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (UCURR_MATCHES_BITMASK(currItem->currType, myContext->currType)) 1993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (resultLength) { 1995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *resultLength = 3; /* Currency codes are only 3 chars long */ 1996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return currItem->currency; 1998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* We enumerated too far. */ 2001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (resultLength) { 2002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *resultLength = 0; 2003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV 2008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucurr_resetCurrencyList(UEnumeration *enumerator, UErrorCode * /*pErrorCode*/) { 2009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((UCurrencyContext *)(enumerator->context))->listIdx = 0; 2010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV 2013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucurr_closeCurrencyList(UEnumeration *enumerator) { 2014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(enumerator->context); 2015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(enumerator); 2016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2018b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic void U_CALLCONV 201959d709d503bab6e2b61931737e662dd293b40578ccorneliusucurr_createCurrencyList(UHashtable *isoCodes, UErrorCode* status){ 2020b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode localStatus = U_ZERO_ERROR; 2021b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2022b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Look up the CurrencyMap element in the root bundle. 2023b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UResourceBundle *rb = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &localStatus); 2024b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UResourceBundle *currencyMapArray = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus); 2025b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2026b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(localStatus)) { 2027b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // process each entry in currency map 2028b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i=0; i<ures_getSize(currencyMapArray); i++) { 2029b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // get the currency resource 2030b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UResourceBundle *currencyArray = ures_getByIndex(currencyMapArray, i, NULL, &localStatus); 2031b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // process each currency 2032b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(localStatus)) { 2033b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t j=0; j<ures_getSize(currencyArray); j++) { 2034b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // get the currency resource 2035b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UResourceBundle *currencyRes = ures_getByIndex(currencyArray, j, NULL, &localStatus); 2036b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho IsoCodeEntry *entry = (IsoCodeEntry*)uprv_malloc(sizeof(IsoCodeEntry)); 2037b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (entry == NULL) { 2038b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *status = U_MEMORY_ALLOCATION_ERROR; 2039b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 2040b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2041b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2042b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // get the ISO code 2043b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t isoLength = 0; 2044b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UResourceBundle *idRes = ures_getByKey(currencyRes, "id", NULL, &localStatus); 2045b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (idRes == NULL) { 2046b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho continue; 2047b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2048b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *isoCode = ures_getString(idRes, &isoLength, &localStatus); 2049b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 205054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // get from date 205154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UDate fromDate = U_DATE_MIN; 2052b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UResourceBundle *fromRes = ures_getByKey(currencyRes, "from", NULL, &localStatus); 205354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 205454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (U_SUCCESS(localStatus)) { 205554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t fromLength = 0; 205654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius const int32_t *fromArray = ures_getIntVector(fromRes, &fromLength, &localStatus); 205754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int64_t currDate64 = (int64_t)fromArray[0] << 32; 205854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius currDate64 |= ((int64_t)fromArray[1] & (int64_t)INT64_C(0x00000000FFFFFFFF)); 205954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius fromDate = (UDate)currDate64; 206054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 206154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius ures_close(fromRes); 206254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 206354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // get to date 2064b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UDate toDate = U_DATE_MAX; 206554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius localStatus = U_ZERO_ERROR; 206654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UResourceBundle *toRes = ures_getByKey(currencyRes, "to", NULL, &localStatus); 2067b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 206854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (U_SUCCESS(localStatus)) { 2069b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t toLength = 0; 2070b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const int32_t *toArray = ures_getIntVector(toRes, &toLength, &localStatus); 207154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int64_t currDate64 = (int64_t)toArray[0] << 32; 2072b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho currDate64 |= ((int64_t)toArray[1] & (int64_t)INT64_C(0x00000000FFFFFFFF)); 2073b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho toDate = (UDate)currDate64; 207454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 207554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius ures_close(toRes); 2076b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2077b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ures_close(idRes); 2078b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ures_close(currencyRes); 2079b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2080b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho entry->isoCode = isoCode; 2081b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho entry->from = fromDate; 2082b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho entry->to = toDate; 2083b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 208454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius localStatus = U_ZERO_ERROR; 208559d709d503bab6e2b61931737e662dd293b40578ccornelius uhash_put(isoCodes, (UChar *)isoCode, entry, &localStatus); 2086b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2087b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 2088b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *status = localStatus; 2089b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2090b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ures_close(currencyArray); 2091b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2092b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 2093b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *status = localStatus; 2094b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2095b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2096b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ures_close(currencyMapArray); 2097b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 2098b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UEnumeration gEnumCurrencyList = { 2100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, 2101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, 2102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucurr_closeCurrencyList, 2103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucurr_countCurrencyList, 2104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uenum_unextDefault, 2105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucurr_nextCurrencyList, 2106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucurr_resetCurrencyList 2107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 2108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END 2109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 211159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void U_CALLCONV initIsoCodes(UErrorCode &status) { 211259d709d503bab6e2b61931737e662dd293b40578ccornelius U_ASSERT(gIsoCodes == NULL); 211359d709d503bab6e2b61931737e662dd293b40578ccornelius ucln_i18n_registerCleanup(UCLN_I18N_CURRENCY, currency_cleanup); 2114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 211559d709d503bab6e2b61931737e662dd293b40578ccornelius UHashtable *isoCodes = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status); 211659d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_FAILURE(status)) { 211759d709d503bab6e2b61931737e662dd293b40578ccornelius return; 211859d709d503bab6e2b61931737e662dd293b40578ccornelius } 211959d709d503bab6e2b61931737e662dd293b40578ccornelius uhash_setValueDeleter(isoCodes, deleteIsoCodeEntry); 212059d709d503bab6e2b61931737e662dd293b40578ccornelius 212159d709d503bab6e2b61931737e662dd293b40578ccornelius ucurr_createCurrencyList(isoCodes, &status); 212259d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_FAILURE(status)) { 212359d709d503bab6e2b61931737e662dd293b40578ccornelius uhash_close(isoCodes); 212459d709d503bab6e2b61931737e662dd293b40578ccornelius return; 212559d709d503bab6e2b61931737e662dd293b40578ccornelius } 212659d709d503bab6e2b61931737e662dd293b40578ccornelius gIsoCodes = isoCodes; // Note: gIsoCodes is const. Once set up here it is never altered, 212759d709d503bab6e2b61931737e662dd293b40578ccornelius // and read only access is safe without synchronization. 212859d709d503bab6e2b61931737e662dd293b40578ccornelius} 212959d709d503bab6e2b61931737e662dd293b40578ccornelius 213059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void populateCurrSymbolsEquiv(icu::Hashtable *hash, UErrorCode &status) { 213159d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_FAILURE(status)) { 213259d709d503bab6e2b61931737e662dd293b40578ccornelius return; 213359d709d503bab6e2b61931737e662dd293b40578ccornelius } 213459d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t length = sizeof(EQUIV_CURRENCY_SYMBOLS) / sizeof(EQUIV_CURRENCY_SYMBOLS[0]); 213559d709d503bab6e2b61931737e662dd293b40578ccornelius for (int32_t i = 0; i < length; ++i) { 213659d709d503bab6e2b61931737e662dd293b40578ccornelius icu::UnicodeString lhs(EQUIV_CURRENCY_SYMBOLS[i][0], -1, US_INV); 213759d709d503bab6e2b61931737e662dd293b40578ccornelius icu::UnicodeString rhs(EQUIV_CURRENCY_SYMBOLS[i][1], -1, US_INV); 213859d709d503bab6e2b61931737e662dd293b40578ccornelius makeEquivalent(lhs.unescape(), rhs.unescape(), hash, status); 2139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 214059d709d503bab6e2b61931737e662dd293b40578ccornelius return; 2141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 214259d709d503bab6e2b61931737e662dd293b40578ccornelius } 214359d709d503bab6e2b61931737e662dd293b40578ccornelius} 2144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 214559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void U_CALLCONV initCurrSymbolsEquiv() { 214659d709d503bab6e2b61931737e662dd293b40578ccornelius U_ASSERT(gCurrSymbolsEquiv == NULL); 214759d709d503bab6e2b61931737e662dd293b40578ccornelius UErrorCode status = U_ZERO_ERROR; 214859d709d503bab6e2b61931737e662dd293b40578ccornelius ucln_i18n_registerCleanup(UCLN_I18N_CURRENCY, currency_cleanup); 214959d709d503bab6e2b61931737e662dd293b40578ccornelius icu::Hashtable *temp = new icu::Hashtable(status); 215059d709d503bab6e2b61931737e662dd293b40578ccornelius if (temp == NULL) { 215159d709d503bab6e2b61931737e662dd293b40578ccornelius return; 2152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 215359d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_FAILURE(status)) { 215459d709d503bab6e2b61931737e662dd293b40578ccornelius delete temp; 215559d709d503bab6e2b61931737e662dd293b40578ccornelius return; 215659d709d503bab6e2b61931737e662dd293b40578ccornelius } 215759d709d503bab6e2b61931737e662dd293b40578ccornelius temp->setValueDeleter(deleteUnicode); 215859d709d503bab6e2b61931737e662dd293b40578ccornelius populateCurrSymbolsEquiv(temp, status); 215959d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_FAILURE(status)) { 216059d709d503bab6e2b61931737e662dd293b40578ccornelius delete temp; 216159d709d503bab6e2b61931737e662dd293b40578ccornelius return; 216259d709d503bab6e2b61931737e662dd293b40578ccornelius } 216359d709d503bab6e2b61931737e662dd293b40578ccornelius gCurrSymbolsEquiv = temp; 216459d709d503bab6e2b61931737e662dd293b40578ccornelius} 2165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 216659d709d503bab6e2b61931737e662dd293b40578ccorneliusU_CAPI UBool U_EXPORT2 216759d709d503bab6e2b61931737e662dd293b40578ccorneliusucurr_isAvailable(const UChar* isoCode, UDate from, UDate to, UErrorCode* eErrorCode) { 216859d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_initOnce(gIsoCodesInitOnce, &initIsoCodes, *eErrorCode); 216959d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_FAILURE(*eErrorCode)) { 217059d709d503bab6e2b61931737e662dd293b40578ccornelius return FALSE; 217159d709d503bab6e2b61931737e662dd293b40578ccornelius } 2172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 217359d709d503bab6e2b61931737e662dd293b40578ccornelius IsoCodeEntry* result = (IsoCodeEntry *) uhash_get(gIsoCodes, isoCode); 2174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (result == NULL) { 2175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 2176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (from > to) { 2177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *eErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 2178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 2179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if ((from > result->to) || (to < result->from)) { 2180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 2181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 2183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 2184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 218559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const icu::Hashtable* getCurrSymbolsEquiv() { 218659d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_initOnce(gCurrSymbolsEquivInitOnce, &initCurrSymbolsEquiv); 218759d709d503bab6e2b61931737e662dd293b40578ccornelius return gCurrSymbolsEquiv; 218859d709d503bab6e2b61931737e662dd293b40578ccornelius} 218959d709d503bab6e2b61931737e662dd293b40578ccornelius 2190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UEnumeration * U_EXPORT2 2191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucurr_openISOCurrencies(uint32_t currType, UErrorCode *pErrorCode) { 2192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UEnumeration *myEnum = NULL; 2193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCurrencyContext *myContext; 2194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru myEnum = (UEnumeration*)uprv_malloc(sizeof(UEnumeration)); 2196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (myEnum == NULL) { 2197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 2198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(myEnum, &gEnumCurrencyList, sizeof(UEnumeration)); 2201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru myContext = (UCurrencyContext*)uprv_malloc(sizeof(UCurrencyContext)); 2202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (myContext == NULL) { 2203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 2204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(myEnum); 2205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 2206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru myContext->currType = currType; 2208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru myContext->listIdx = 0; 2209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru myEnum->context = myContext; 2210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return myEnum; 2211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2213c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2214c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruucurr_countCurrencies(const char* locale, 2215c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UDate date, 2216c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UErrorCode* ec) 2217c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{ 2218b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t currCount = 0; 2219c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 2220c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (ec != NULL && U_SUCCESS(*ec)) 2221b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2222b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // local variables 2223c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UErrorCode localStatus = U_ZERO_ERROR; 2224c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru char id[ULOC_FULLNAME_CAPACITY]; 2225103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uloc_getKeywordValue(locale, "currency", id, ULOC_FULLNAME_CAPACITY, &localStatus); 2226b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // get country or country_variant in `id' 2227b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /*uint32_t variantType =*/ idForLocale(locale, id, sizeof(id), ec); 2228b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2229b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(*ec)) 2230b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2231b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 2232b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2233b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2234b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Remove variants, which is only needed for registration. 2235b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *idDelim = strchr(id, VAR_DELIM); 2236b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (idDelim) 2237b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2238b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru idDelim[0] = 0; 2239b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2240b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2241b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Look up the CurrencyMap element in the root bundle. 224250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UResourceBundle *rb = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &localStatus); 2243b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus); 2244b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2245b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Using the id derived from the local, get the currency data 2246b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle *countryArray = ures_getByKey(rb, id, cm, &localStatus); 2247b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2248b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // process each currency to see which one is valid for the given date 2249b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_SUCCESS(localStatus)) 2250b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2251b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t i=0; i<ures_getSize(countryArray); i++) 2252b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2253b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // get the currency resource 2254b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle *currencyRes = ures_getByIndex(countryArray, i, NULL, &localStatus); 2255b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2256b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // get the from date 2257b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t fromLength = 0; 2258b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle *fromRes = ures_getByKey(currencyRes, "from", NULL, &localStatus); 2259b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const int32_t *fromArray = ures_getIntVector(fromRes, &fromLength, &localStatus); 2260b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2261b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int64_t currDate64 = (int64_t)fromArray[0] << 32; 2262b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currDate64 |= ((int64_t)fromArray[1] & (int64_t)INT64_C(0x00000000FFFFFFFF)); 2263b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UDate fromDate = (UDate)currDate64; 2264b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2265b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (ures_getSize(currencyRes)> 2) 2266b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2267b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t toLength = 0; 2268b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle *toRes = ures_getByKey(currencyRes, "to", NULL, &localStatus); 2269b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const int32_t *toArray = ures_getIntVector(toRes, &toLength, &localStatus); 2270b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2271b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currDate64 = (int64_t)toArray[0] << 32; 2272b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currDate64 |= ((int64_t)toArray[1] & (int64_t)INT64_C(0x00000000FFFFFFFF)); 2273b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UDate toDate = (UDate)currDate64; 2274b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2275b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if ((fromDate <= date) && (date < toDate)) 2276b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2277b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currCount++; 2278b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2279b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2280b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(toRes); 2281b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2282b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else 2283b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2284b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (fromDate <= date) 2285b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2286b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currCount++; 2287b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2288b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2289b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2290b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // close open resources 2291b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(currencyRes); 2292b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(fromRes); 2293b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2294b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } // end For loop 2295b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } // end if (U_SUCCESS(localStatus)) 2296c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 2297b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(countryArray); 2298b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2299b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Check for errors 2300b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (*ec == U_ZERO_ERROR || localStatus != U_ZERO_ERROR) 2301b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2302b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // There is nothing to fallback to. 2303b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Report the failure/warning if possible. 2304b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *ec = localStatus; 2305b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2306b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2307b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_SUCCESS(*ec)) 2308b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2309b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // no errors 2310b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return currCount; 2311b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2312c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 2313c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 2314c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 2315b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // If we got here, either error code is invalid or 2316b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // some argument passed is no good. 2317c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return 0; 2318c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru} 2319c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 2320c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 2321c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruucurr_forLocaleAndDate(const char* locale, 2322c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UDate date, 2323c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t index, 2324c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar* buff, 2325c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t buffCapacity, 2326c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UErrorCode* ec) 2327c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{ 2328c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t resLen = 0; 2329c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t currIndex = 0; 2330c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar* s = NULL; 2331c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 2332b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (ec != NULL && U_SUCCESS(*ec)) 2333b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2334b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // check the arguments passed 2335b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if ((buff && buffCapacity) || !buffCapacity ) 2336b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2337b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // local variables 2338c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UErrorCode localStatus = U_ZERO_ERROR; 2339c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru char id[ULOC_FULLNAME_CAPACITY]; 2340c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru resLen = uloc_getKeywordValue(locale, "currency", id, ULOC_FULLNAME_CAPACITY, &localStatus); 2341c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 2342b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // get country or country_variant in `id' 2343b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /*uint32_t variantType =*/ idForLocale(locale, id, sizeof(id), ec); 2344b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(*ec)) 2345b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2346b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 2347b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2348b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2349b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Remove variants, which is only needed for registration. 2350b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *idDelim = strchr(id, VAR_DELIM); 2351b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (idDelim) 2352b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2353b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru idDelim[0] = 0; 2354b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2355b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2356b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Look up the CurrencyMap element in the root bundle. 235750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UResourceBundle *rb = ures_openDirect(U_ICUDATA_CURR, CURRENCY_DATA, &localStatus); 2358b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle *cm = ures_getByKey(rb, CURRENCY_MAP, rb, &localStatus); 2359b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2360b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Using the id derived from the local, get the currency data 2361b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle *countryArray = ures_getByKey(rb, id, cm, &localStatus); 2362b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2363b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // process each currency to see which one is valid for the given date 2364b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru bool matchFound = false; 2365b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_SUCCESS(localStatus)) 2366b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2367b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if ((index <= 0) || (index> ures_getSize(countryArray))) 2368b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2369c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // requested index is out of bounds 2370c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ures_close(countryArray); 2371b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 2372b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2373b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2374b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for (int32_t i=0; i<ures_getSize(countryArray); i++) 2375b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2376b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // get the currency resource 2377b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle *currencyRes = ures_getByIndex(countryArray, i, NULL, &localStatus); 2378b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru s = ures_getStringByKey(currencyRes, "id", &resLen, &localStatus); 2379b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2380b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // get the from date 2381b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t fromLength = 0; 2382b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle *fromRes = ures_getByKey(currencyRes, "from", NULL, &localStatus); 2383b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const int32_t *fromArray = ures_getIntVector(fromRes, &fromLength, &localStatus); 2384b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2385b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int64_t currDate64 = (int64_t)fromArray[0] << 32; 2386b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currDate64 |= ((int64_t)fromArray[1] & (int64_t)INT64_C(0x00000000FFFFFFFF)); 2387b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UDate fromDate = (UDate)currDate64; 2388b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2389b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (ures_getSize(currencyRes)> 2) 2390b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2391b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t toLength = 0; 2392b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle *toRes = ures_getByKey(currencyRes, "to", NULL, &localStatus); 2393b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const int32_t *toArray = ures_getIntVector(toRes, &toLength, &localStatus); 2394b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2395b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currDate64 = (int64_t)toArray[0] << 32; 2396b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currDate64 |= ((int64_t)toArray[1] & (int64_t)INT64_C(0x00000000FFFFFFFF)); 2397b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UDate toDate = (UDate)currDate64; 2398b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2399b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if ((fromDate <= date) && (date < toDate)) 2400b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2401b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currIndex++; 2402b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (currIndex == index) 2403b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2404b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru matchFound = true; 2405b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2406b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2407b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2408b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(toRes); 2409b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2410b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else 2411b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2412b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (fromDate <= date) 2413b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2414b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru currIndex++; 2415b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (currIndex == index) 2416b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2417b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru matchFound = true; 2418b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2419b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2420b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2421b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2422b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // close open resources 2423b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(currencyRes); 2424b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(fromRes); 2425b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2426b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // check for loop exit 2427b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (matchFound) 2428b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2429b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 2430b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2431b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2432b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } // end For loop 2433b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2434b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2435b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(countryArray); 2436b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2437b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Check for errors 2438b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (*ec == U_ZERO_ERROR || localStatus != U_ZERO_ERROR) 2439b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2440b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // There is nothing to fallback to. 2441b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Report the failure/warning if possible. 2442b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *ec = localStatus; 2443b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2444b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2445b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_SUCCESS(*ec)) 2446b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2447b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // no errors 2448b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if((buffCapacity> resLen) && matchFound) 2449b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2450b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // write out the currency value 2451b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strcpy(buff, s); 2452b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2453b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else 2454b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2455b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 2456b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2457b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2458b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2459b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // return null terminated currency string 2460c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return u_terminateUChars(buff, buffCapacity, resLen, ec); 2461b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2462b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru else 2463b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru { 2464b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // illegal argument encountered 2465c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru *ec = U_ILLEGAL_ARGUMENT_ERROR; 2466c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 2467c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 2468c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 2469c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 2470b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // If we got here, either error code is invalid or 2471b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // some argument passed is no good. 2472c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return resLen; 2473c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru} 2474c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 2475b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UEnumeration defaultKeywordValues = { 2476b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, 2477b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, 2478b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_close_keyword_values_iterator, 2479b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_count_keyword_values, 2480b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uenum_unextDefault, 2481b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_next_keyword_value, 2482b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_reset_keyword_values_iterator 2483b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}; 2484b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2485b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI UEnumeration *U_EXPORT2 ucurr_getKeywordValuesForLocale(const char *key, const char *locale, UBool commonlyUsed, UErrorCode* status) { 2486b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Resolve region 2487b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char prefRegion[ULOC_FULLNAME_CAPACITY] = ""; 2488b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t prefRegionLength = 0; 2489b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru prefRegionLength = uloc_getCountry(locale, prefRegion, sizeof(prefRegion), status); 2490b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (prefRegionLength == 0) { 2491b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char loc[ULOC_FULLNAME_CAPACITY] = ""; 2492103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uloc_addLikelySubtags(locale, loc, sizeof(loc), status); 2493b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2494b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru prefRegionLength = uloc_getCountry(loc, prefRegion, sizeof(prefRegion), status); 2495b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2496b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2497b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Read value from supplementalData 2498b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UList *values = ulist_createEmptyList(status); 2499b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UList *otherValues = ulist_createEmptyList(status); 2500b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UEnumeration *en = (UEnumeration *)uprv_malloc(sizeof(UEnumeration)); 2501b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(*status) || en == NULL) { 2502b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (en == NULL) { 2503b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 2504b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 2505b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(en); 2506b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2507b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_deleteList(values); 2508b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_deleteList(otherValues); 2509b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return NULL; 2510b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2511b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru memcpy(en, &defaultKeywordValues, sizeof(UEnumeration)); 2512b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru en->context = values; 2513b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 251450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UResourceBundle *bundle = ures_openDirect(U_ICUDATA_CURR, "supplementalData", status); 2515b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_getByKey(bundle, "CurrencyMap", bundle, status); 2516b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle bundlekey, regbndl, curbndl, to; 2517b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_initStackObject(&bundlekey); 2518b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_initStackObject(®bndl); 2519b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_initStackObject(&curbndl); 2520b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_initStackObject(&to); 2521b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2522b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru while (U_SUCCESS(*status) && ures_hasNext(bundle)) { 2523b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_getNextResource(bundle, &bundlekey, status); 2524b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(*status)) { 2525b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 2526b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2527b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const char *region = ures_getKey(&bundlekey); 2528b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UBool isPrefRegion = uprv_strcmp(region, prefRegion) == 0 ? TRUE : FALSE; 2529b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (!isPrefRegion && commonlyUsed) { 2530b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // With commonlyUsed=true, we do not put 253150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // currencies for other regions in the 2532b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // result list. 2533b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru continue; 2534b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2535b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_getByKey(bundle, region, ®bndl, status); 2536b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(*status)) { 2537b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 2538b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2539b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru while (U_SUCCESS(*status) && ures_hasNext(®bndl)) { 2540b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_getNextResource(®bndl, &curbndl, status); 2541b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (ures_getType(&curbndl) != URES_TABLE) { 2542b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Currently, an empty ARRAY is mixed in. 2543b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru continue; 2544b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2545b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *curID = (char *)uprv_malloc(sizeof(char) * ULOC_KEYWORDS_CAPACITY); 2546b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t curIDLength = ULOC_KEYWORDS_CAPACITY; 2547b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (curID == NULL) { 2548b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 2549b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 2550b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 255150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 255250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if U_CHARSET_FAMILY==U_ASCII_FAMILY 2553b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_getUTF8StringByKey(&curbndl, "id", curID, &curIDLength, TRUE, status); 255450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* optimize - use the utf-8 string */ 255550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#else 255650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho { 255750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar* defString = ures_getStringByKey(&curbndl, "id", &curIDLength, status); 255850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_SUCCESS(*status)) { 255950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(curIDLength+1 > ULOC_KEYWORDS_CAPACITY) { 256050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *status = U_BUFFER_OVERFLOW_ERROR; 256150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 256250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho u_UCharsToChars(defString, curID, curIDLength+1); 256350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 256450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 256550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 256650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 256750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 2568b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(*status)) { 2569b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 2570b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2571b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UBool hasTo = FALSE; 2572b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_getByKey(&curbndl, "to", &to, status); 2573b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(*status)) { 2574b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Do nothing here... 2575b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *status = U_ZERO_ERROR; 2576b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 2577b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru hasTo = TRUE; 2578b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 257950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (isPrefRegion && !hasTo && !ulist_containsString(values, curID, (int32_t)uprv_strlen(curID))) { 2580b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Currently active currency for the target country 2581b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_addItemEndList(values, curID, TRUE, status); 258250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (!ulist_containsString(otherValues, curID, (int32_t)uprv_strlen(curID)) && !commonlyUsed) { 2583b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_addItemEndList(otherValues, curID, TRUE, status); 2584b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 2585b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(curID); 2586b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2587b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2588b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2589b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2590b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_SUCCESS(*status)) { 2591b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (commonlyUsed) { 2592b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (ulist_getListSize(values) == 0) { 2593b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // This could happen if no valid region is supplied in the input 2594b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // locale. In this case, we use the CLDR's default. 2595b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uenum_close(en); 2596b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru en = ucurr_getKeywordValuesForLocale(key, "und", TRUE, status); 2597b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2598b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 2599b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Consolidate the list 2600b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *value = NULL; 2601b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_resetList(otherValues); 2602b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru while ((value = (char *)ulist_getNext(otherValues)) != NULL) { 260350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (!ulist_containsString(values, value, (int32_t)uprv_strlen(value))) { 2604b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *tmpValue = (char *)uprv_malloc(sizeof(char) * ULOC_KEYWORDS_CAPACITY); 2605b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_memcpy(tmpValue, value, uprv_strlen(value) + 1); 2606b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_addItemEndList(values, tmpValue, TRUE, status); 2607b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(*status)) { 2608b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 2609b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2610b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2611b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2612b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2613b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2614b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_resetList((UList *)(en->context)); 2615b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 2616b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_deleteList(values); 2617b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(en); 2618b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru values = NULL; 2619b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru en = NULL; 2620b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 2621b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(&to); 2622b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(&curbndl); 2623b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(®bndl); 2624b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(&bundlekey); 2625b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(bundle); 2626b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2627b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_deleteList(otherValues); 2628b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2629b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return en; 2630b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 2631b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 2632103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2633103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CAPI int32_t U_EXPORT2 2634103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusucurr_getNumericCode(const UChar* currency) { 2635103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t code = 0; 2636103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (currency && u_strlen(currency) == ISO_CURRENCY_CODE_LENGTH) { 2637103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode status = U_ZERO_ERROR; 2638103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2639103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UResourceBundle *bundle = ures_openDirect(0, "currencyNumericCodes", &status); 2640103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ures_getByKey(bundle, "codeMap", bundle, &status); 2641103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status)) { 2642103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius char alphaCode[ISO_CURRENCY_CODE_LENGTH+1]; 2643103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius myUCharsToChars(alphaCode, currency); 2644103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius T_CString_toUpperCase(alphaCode); 2645103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ures_getByKey(bundle, alphaCode, bundle, &status); 2646103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int tmpCode = ures_getInt(bundle, &status); 2647103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status)) { 2648103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius code = tmpCode; 2649103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2650103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2651103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ures_close(bundle); 2652103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2653103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return code; 2654103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 2655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */ 2656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//eof 2658