1b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/*
2b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *******************************************************************************
3b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Copyright (C) 2009-2011, International Business Machines Corporation and
450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * others. All Rights Reserved.
5b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *******************************************************************************
6b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */
7b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
8b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "unicode/currpinf.h"
9b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
10b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#if !UCONFIG_NO_FORMATTING
11b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
12b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru//#define CURRENCY_PLURAL_INFO_DEBUG 1
13b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
14b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef CURRENCY_PLURAL_INFO_DEBUG
15b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include <iostream>
16b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif
17b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
18b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
19b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "unicode/locid.h"
20b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "unicode/plurrule.h"
21b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "unicode/ures.h"
2283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#include "unicode/numsys.h"
23b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "cstring.h"
24b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "hash.h"
25b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "uresimp.h"
2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "ureslocs.h"
27b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
28b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_NAMESPACE_BEGIN
29b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
30b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
31b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar gNumberPatternSeparator = 0x3B; // ;
32b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
33b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CDECL_BEGIN
34b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
35b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/**
36b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @internal ICU 4.2
37b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */
38b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic UBool U_CALLCONV ValueComparator(UHashTok val1, UHashTok val2);
39b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
40b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUBool
41b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CALLCONV ValueComparator(UHashTok val1, UHashTok val2) {
42b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UnicodeString* affix_1 = (UnicodeString*)val1.pointer;
43b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UnicodeString* affix_2 = (UnicodeString*)val2.pointer;
44b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return  *affix_1 == *affix_2;
45b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
46b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
4750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CDECL_END
48b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
49b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
50b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(CurrencyPluralInfo)
51b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
52b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar gDefaultCurrencyPluralPattern[] = {'0', '.', '#', '#', ' ', 0xA4, 0xA4, 0xA4, 0};
53b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar gTripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0};
54b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar gPluralCountOther[] = {0x6F, 0x74, 0x68, 0x65, 0x72, 0};
55b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar gPart0[] = {0x7B, 0x30, 0x7D, 0};
56b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar gPart1[] = {0x7B, 0x31, 0x7D, 0};
57b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
5827f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char gNumberElementsTag[]="NumberElements";
5927f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char gLatnTag[]="latn";
6027f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char gPatternsTag[]="patterns";
6127f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char gDecimalFormatTag[]="decimalFormat";
62b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const char gCurrUnitPtnTag[]="CurrencyUnitPatterns";
63b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
64b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::CurrencyPluralInfo(UErrorCode& status)
65b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru:   fPluralCountToCurrencyUnitPattern(NULL),
66b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fPluralRules(NULL),
67b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fLocale(NULL) {
68b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    initialize(Locale::getDefault(), status);
69b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
70b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
71b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::CurrencyPluralInfo(const Locale& locale, UErrorCode& status)
72b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru:   fPluralCountToCurrencyUnitPattern(NULL),
73b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fPluralRules(NULL),
74b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fLocale(NULL) {
75b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    initialize(locale, status);
76b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
77b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
78b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::CurrencyPluralInfo(const CurrencyPluralInfo& info)
79b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru:   UObject(info),
80b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fPluralCountToCurrencyUnitPattern(NULL),
81b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fPluralRules(NULL),
82b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fLocale(NULL) {
83b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    *this = info;
84b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
85b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
86b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
87b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo&
88b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::operator=(const CurrencyPluralInfo& info) {
89b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (this == &info) {
90b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return *this;
91b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
92b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
93b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    deleteHash(fPluralCountToCurrencyUnitPattern);
94b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
95b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fPluralCountToCurrencyUnitPattern = initHash(status);
96b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    copyHash(info.fPluralCountToCurrencyUnitPattern,
97b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru             fPluralCountToCurrencyUnitPattern, status);
98b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( U_FAILURE(status) ) {
99b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return *this;
100b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
101b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
102b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    delete fPluralRules;
103b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    delete fLocale;
104b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (info.fPluralRules) {
105b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fPluralRules = info.fPluralRules->clone();
106b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    } else {
107b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fPluralRules = NULL;
108b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
109b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (info.fLocale) {
110b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fLocale = info.fLocale->clone();
111b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    } else {
112b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fLocale = NULL;
113b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
114b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return *this;
115b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
116b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
117b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
118b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::~CurrencyPluralInfo() {
119b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    deleteHash(fPluralCountToCurrencyUnitPattern);
120b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fPluralCountToCurrencyUnitPattern = NULL;
121b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    delete fPluralRules;
122b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    delete fLocale;
123b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fPluralRules = NULL;
124b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fLocale = NULL;
125b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
126b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
127b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUBool
128b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::operator==(const CurrencyPluralInfo& info) const {
129b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef CURRENCY_PLURAL_INFO_DEBUG
130b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (*fPluralRules == *info.fPluralRules) {
131b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        std::cout << "same plural rules\n";
132b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
133b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (*fLocale == *info.fLocale) {
134b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        std::cout << "same locale\n";
135b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
136b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (fPluralCountToCurrencyUnitPattern->equals(*info.fPluralCountToCurrencyUnitPattern)) {
137b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        std::cout << "same pattern\n";
138b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
139b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif
140b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return *fPluralRules == *info.fPluralRules &&
141b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           *fLocale == *info.fLocale &&
142b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru           fPluralCountToCurrencyUnitPattern->equals(*info.fPluralCountToCurrencyUnitPattern);
143b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
144b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
145b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
146b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo*
147b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::clone() const {
148b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return new CurrencyPluralInfo(*this);
149b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
150b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
151b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruconst PluralRules*
152b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::getPluralRules() const {
153b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return fPluralRules;
154b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
155b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
156b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString&
157b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::getCurrencyPluralPattern(const UnicodeString&  pluralCount,
158b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                             UnicodeString& result) const {
159b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UnicodeString* currencyPluralPattern =
160b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        (UnicodeString*)fPluralCountToCurrencyUnitPattern->get(pluralCount);
161b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (currencyPluralPattern == NULL) {
162b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // fall back to "other"
163b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (pluralCount.compare(gPluralCountOther, 5)) {
164b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            currencyPluralPattern =
165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                (UnicodeString*)fPluralCountToCurrencyUnitPattern->get(UnicodeString(TRUE, gPluralCountOther, 5));
166b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
167b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (currencyPluralPattern == NULL) {
168b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            // no currencyUnitPatterns defined,
169b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            // fallback to predefined defult.
170b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            // This should never happen when ICU resource files are
171b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            // available, since currencyUnitPattern of "other" is always
172b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            // defined in root.
173b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            result = UnicodeString(gDefaultCurrencyPluralPattern);
174b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            return result;
175b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
176b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
177b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    result = *currencyPluralPattern;
178b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return result;
179b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
180b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
181b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruconst Locale&
182b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::getLocale() const {
183b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return *fLocale;
184b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
185b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
186b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
187b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::setPluralRules(const UnicodeString& ruleDescription,
188b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                   UErrorCode& status) {
189b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_SUCCESS(status)) {
19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (fPluralRules) {
19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            delete fPluralRules;
19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
193b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fPluralRules = PluralRules::createRules(ruleDescription, status);
194b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
195b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
196b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
197b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
198b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
199b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::setCurrencyPluralPattern(const UnicodeString& pluralCount,
200b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                             const UnicodeString& pattern,
201b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                             UErrorCode& status) {
202b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_SUCCESS(status)) {
203b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fPluralCountToCurrencyUnitPattern->put(pluralCount, new UnicodeString(pattern), status);
204b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
205b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
206b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
207b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
208b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
209b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::setLocale(const Locale& loc, UErrorCode& status) {
210b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    initialize(loc, status);
211b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
212b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
213b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
214b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
215b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::initialize(const Locale& loc, UErrorCode& status) {
216b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(status)) {
217b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
218b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
219b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    delete fLocale;
220b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fLocale = loc.clone();
22150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fPluralRules) {
22250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        delete fPluralRules;
22350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
224b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fPluralRules = PluralRules::forLocale(loc, status);
225b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    setupCurrencyPluralPattern(loc, status);
226b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
227b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
228b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
229b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
230b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::setupCurrencyPluralPattern(const Locale& loc, UErrorCode& status) {
231b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(status)) {
232b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
233b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
234b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (fPluralCountToCurrencyUnitPattern) {
23650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        deleteHash(fPluralCountToCurrencyUnitPattern);
23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
238b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fPluralCountToCurrencyUnitPattern = initHash(status);
239b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(status)) {
240b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
241b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
242b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
24383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    NumberingSystem *ns = NumberingSystem::createInstance(loc,status);
244b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UErrorCode ec = U_ZERO_ERROR;
245b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UResourceBundle *rb = ures_open(NULL, loc.getName(), &ec);
24683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    UResourceBundle *numElements = ures_getByKeyWithFallback(rb, gNumberElementsTag, NULL, &ec);
24783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    rb = ures_getByKeyWithFallback(numElements, ns->getName(), rb, &ec);
248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    rb = ures_getByKeyWithFallback(rb, gPatternsTag, rb, &ec);
249b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t ptnLen;
25027f654740f2a26ad62a5c155af9199af9e69b889claireho    const UChar* numberStylePattern = ures_getStringByKeyWithFallback(rb, gDecimalFormatTag, &ptnLen, &ec);
25183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    // Fall back to "latn" if num sys specific pattern isn't there.
25283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    if ( ec == U_MISSING_RESOURCE_ERROR && uprv_strcmp(ns->getName(),gLatnTag)) {
25383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        ec = U_ZERO_ERROR;
25483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        rb = ures_getByKeyWithFallback(numElements, gLatnTag, rb, &ec);
25583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        rb = ures_getByKeyWithFallback(rb, gPatternsTag, rb, &ec);
25683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        numberStylePattern = ures_getStringByKeyWithFallback(rb, gDecimalFormatTag, &ptnLen, &ec);
25783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    }
258b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t numberStylePatternLen = ptnLen;
259b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UChar* negNumberStylePattern = NULL;
260b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t negNumberStylePatternLen = 0;
261b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // TODO: Java
262b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // parse to check whether there is ";" separator in the numberStylePattern
263b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UBool hasSeparator = false;
2646d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    if (U_SUCCESS(ec)) {
2656d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        for (int32_t styleCharIndex = 0; styleCharIndex < ptnLen; ++styleCharIndex) {
2666d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            if (numberStylePattern[styleCharIndex] == gNumberPatternSeparator) {
2676d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru                hasSeparator = true;
2686d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru                // split the number style pattern into positive and negative
2696d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru                negNumberStylePattern = numberStylePattern + styleCharIndex + 1;
2706d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru                negNumberStylePatternLen = ptnLen - styleCharIndex - 1;
2716d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru                numberStylePatternLen = styleCharIndex;
2726d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            }
273b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
274b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
27583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius
27683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    ures_close(numElements);
27750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ures_close(rb);
27883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    delete ns;
279b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
280b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(ec)) {
281b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
282b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
283b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UResourceBundle *currRb = ures_open(U_ICUDATA_CURR, loc.getName(), &ec);
28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UResourceBundle *currencyRes = ures_getByKeyWithFallback(currRb, gCurrUnitPtnTag, NULL, &ec);
286b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
287b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef CURRENCY_PLURAL_INFO_DEBUG
288b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    std::cout << "in set up\n";
289b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif
290b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    StringEnumeration* keywords = fPluralRules->getKeywords(ec);
291b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_SUCCESS(ec)) {
292b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const char* pluralCount;
293b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        while ((pluralCount = keywords->next(NULL, ec)) != NULL) {
294b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if ( U_SUCCESS(ec) ) {
295b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                int32_t ptnLen;
296b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                UErrorCode err = U_ZERO_ERROR;
297b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                const UChar* patternChars = ures_getStringByKeyWithFallback(
298b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    currencyRes, pluralCount, &ptnLen, &err);
299b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if (U_SUCCESS(err) && ptnLen > 0) {
300b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    UnicodeString* pattern = new UnicodeString(patternChars, ptnLen);
301b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef CURRENCY_PLURAL_INFO_DEBUG
302b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    char result_1[1000];
303b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    pattern->extract(0, pattern->length(), result_1, "UTF-8");
304b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    std::cout << "pluralCount: " << pluralCount << "; pattern: " << result_1 << "\n";
305b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif
306b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    pattern->findAndReplace(UnicodeString(TRUE, gPart0, 3),
307b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                      UnicodeString(numberStylePattern, numberStylePatternLen));
308b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    pattern->findAndReplace(UnicodeString(TRUE, gPart1, 3), UnicodeString(TRUE, gTripleCurrencySign, 3));
309b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
310b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    if (hasSeparator) {
311b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        UnicodeString negPattern(patternChars, ptnLen);
312b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        negPattern.findAndReplace(UnicodeString(TRUE, gPart0, 3),
313b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                          UnicodeString(negNumberStylePattern, negNumberStylePatternLen));
314b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        negPattern.findAndReplace(UnicodeString(TRUE, gPart1, 3), UnicodeString(TRUE, gTripleCurrencySign, 3));
315b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        pattern->append(gNumberPatternSeparator);
316b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        pattern->append(negPattern);
317b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    }
318b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef CURRENCY_PLURAL_INFO_DEBUG
319b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    pattern->extract(0, pattern->length(), result_1, "UTF-8");
320b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    std::cout << "pluralCount: " << pluralCount << "; pattern: " << result_1 << "\n";
321b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif
322b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
323b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    fPluralCountToCurrencyUnitPattern->put(UnicodeString(pluralCount, -1, US_INV), pattern, status);
324b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
325b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
326b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
327b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
328b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    delete keywords;
329b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    ures_close(currencyRes);
33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ures_close(currRb);
331b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
332b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
333b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
334b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
335b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
336b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::deleteHash(Hashtable* hTable)
337b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{
338b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( hTable == NULL ) {
339b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
340b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
341b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t pos = -1;
342b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UHashElement* element = NULL;
343b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    while ( (element = hTable->nextElement(pos)) != NULL ) {
344b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const UHashTok valueTok = element->value;
345b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const UnicodeString* value = (UnicodeString*)valueTok.pointer;
346b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        delete value;
347b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
348b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    delete hTable;
349b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    hTable = NULL;
350b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
351b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
352b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
353b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruHashtable*
354b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::initHash(UErrorCode& status) {
355b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( U_FAILURE(status) ) {
356b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return NULL;
357b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
358b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    Hashtable* hTable;
359b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( (hTable = new Hashtable(TRUE, status)) == NULL ) {
360b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        status = U_MEMORY_ALLOCATION_ERROR;
361b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return NULL;
362b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if ( U_FAILURE(status) ) {
364b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        delete hTable;
365b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return NULL;
366b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
36750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    hTable->setValueComparator(ValueComparator);
368b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return hTable;
369b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
370b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
371b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
372b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
373b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruCurrencyPluralInfo::copyHash(const Hashtable* source,
374b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                           Hashtable* target,
375b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                           UErrorCode& status) {
376b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( U_FAILURE(status) ) {
377b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
378b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
379b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t pos = -1;
380b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UHashElement* element = NULL;
381b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( source ) {
382b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        while ( (element = source->nextElement(pos)) != NULL ) {
383b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UHashTok keyTok = element->key;
384b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UnicodeString* key = (UnicodeString*)keyTok.pointer;
385b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UHashTok valueTok = element->value;
386b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UnicodeString* value = (UnicodeString*)valueTok.pointer;
387b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            UnicodeString* copy = new UnicodeString(*value);
388b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            target->put(UnicodeString(*key), copy, status);
389b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if ( U_FAILURE(status) ) {
390b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                return;
391b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
392b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
393b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
394b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
395b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
396b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
397b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_NAMESPACE_END
398b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
399b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif
400