1b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/*
2b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *******************************************************************************
3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * Copyright (C) 2008-2014, Google, International Business Machines Corporation
4b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * and others. All Rights Reserved.
5b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *******************************************************************************
6b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */
7b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
8b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "unicode/tmutfmt.h"
9b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
10b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#if !UCONFIG_NO_FORMATTING
11b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
12fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/decimfmt.h"
13fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "plurrule_impl.h"
1454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "uvector.h"
15b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "charstr.h"
16b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "cmemory.h"
17b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "cstring.h"
18b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "hash.h"
19b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "uresimp.h"
20b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "unicode/msgfmt.h"
21103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "uassert.h"
22b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
23b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LEFT_CURLY_BRACKET  ((UChar)0x007B)
24b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define RIGHT_CURLY_BRACKET ((UChar)0x007D)
25b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define SPACE             ((UChar)0x0020)
26b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define DIGIT_ZERO        ((UChar)0x0030)
27b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_S             ((UChar)0x0073)
28b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_M             ((UChar)0x006D)
29b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_I             ((UChar)0x0069)
30b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_N             ((UChar)0x006E)
31b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_H             ((UChar)0x0068)
32b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_W             ((UChar)0x0077)
33b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_D             ((UChar)0x0064)
34b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_Y             ((UChar)0x0079)
35b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_Z             ((UChar)0x007A)
36b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_E             ((UChar)0x0065)
37b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_R             ((UChar)0x0072)
38b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_O             ((UChar)0x006F)
39b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_N             ((UChar)0x006E)
40b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define LOW_T             ((UChar)0x0074)
41b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
42b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
43b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru//TODO: define in compile time
44b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru//#define TMUTFMT_DEBUG 1
45b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
46b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef TMUTFMT_DEBUG
47b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include <iostream>
48b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif
49b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
50b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_NAMESPACE_BEGIN
51b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
52b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
53b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
54b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeUnitFormat)
55b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
56b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const char gUnitsTag[] = "units";
57b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const char gShortUnitsTag[] = "unitsShort";
58b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const char gTimeUnitYear[] = "year";
59b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const char gTimeUnitMonth[] = "month";
60b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const char gTimeUnitDay[] = "day";
61b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const char gTimeUnitWeek[] = "week";
62b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const char gTimeUnitHour[] = "hour";
63b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const char gTimeUnitMinute[] = "minute";
64b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const char gTimeUnitSecond[] = "second";
65b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const char gPluralCountOther[] = "other";
66b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
67b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar DEFAULT_PATTERN_FOR_SECOND[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_S, 0};
68b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar DEFAULT_PATTERN_FOR_MINUTE[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_M, LOW_I, LOW_N, 0};
69b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar DEFAULT_PATTERN_FOR_HOUR[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_H, 0};
70b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar DEFAULT_PATTERN_FOR_WEEK[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_W, 0};
71b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar DEFAULT_PATTERN_FOR_DAY[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_D, 0};
72b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar DEFAULT_PATTERN_FOR_MONTH[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_M, 0};
73b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar DEFAULT_PATTERN_FOR_YEAR[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, LOW_Y, 0};
74b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
75b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar PLURAL_COUNT_ZERO[] = {LOW_Z, LOW_E, LOW_R, LOW_O, 0};
76b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar PLURAL_COUNT_ONE[] = {LOW_O, LOW_N, LOW_E, 0};
77b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UChar PLURAL_COUNT_TWO[] = {LOW_T, LOW_W, LOW_O, 0};
78b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
79fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusTimeUnitFormat::TimeUnitFormat(UErrorCode& status) {
80fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initMeasureFormat(Locale::getDefault(), UMEASFMT_WIDTH_WIDE, NULL, status);
81fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    create(UTMUTFMT_FULL_STYLE, status);
82b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
83b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
84b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
85fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusTimeUnitFormat::TimeUnitFormat(const Locale& locale, UErrorCode& status) {
86fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initMeasureFormat(locale, UMEASFMT_WIDTH_WIDE, NULL, status);
87fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    create(UTMUTFMT_FULL_STYLE, status);
88b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
89b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
90b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
91fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusTimeUnitFormat::TimeUnitFormat(const Locale& locale, UTimeUnitFormatStyle style, UErrorCode& status) {
92fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    switch (style) {
93fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    case UTMUTFMT_FULL_STYLE:
94fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        initMeasureFormat(locale, UMEASFMT_WIDTH_WIDE, NULL, status);
95fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        break;
96fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    case UTMUTFMT_ABBREVIATED_STYLE:
97fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        initMeasureFormat(locale, UMEASFMT_WIDTH_SHORT, NULL, status);
98fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        break;
99fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    default:
100fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        initMeasureFormat(locale, UMEASFMT_WIDTH_WIDE, NULL, status);
101fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        break;
102fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
103fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    create(style, status);
104b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
105b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
106b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat::TimeUnitFormat(const TimeUnitFormat& other)
107b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru:   MeasureFormat(other),
108fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fStyle(other.fStyle)
109b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{
110b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
111b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
112b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         i = (TimeUnit::UTimeUnitFields)(i+1)) {
113fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        UErrorCode status = U_ZERO_ERROR;
114fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        fTimeUnitToCountToPatterns[i] = initHash(status);
115fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        if (U_SUCCESS(status)) {
116fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            copyHash(other.fTimeUnitToCountToPatterns[i], fTimeUnitToCountToPatterns[i], status);
117fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        } else {
118fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            delete fTimeUnitToCountToPatterns[i];
119fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            fTimeUnitToCountToPatterns[i] = NULL;
120fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        }
121fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
122b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
123b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
124b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
125b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat::~TimeUnitFormat() {
126b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
127b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
128b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         i = (TimeUnit::UTimeUnitFields)(i+1)) {
129b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        deleteHash(fTimeUnitToCountToPatterns[i]);
130b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fTimeUnitToCountToPatterns[i] = NULL;
131b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
132b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
133b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
134b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
135b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruFormat*
136b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat::clone(void) const {
137b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return new TimeUnitFormat(*this);
138b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
139b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
140b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
141b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat&
142b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat::operator=(const TimeUnitFormat& other) {
143b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (this == &other) {
144b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return *this;
145b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
146fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    MeasureFormat::operator=(other);
147b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
148b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
149b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         i = (TimeUnit::UTimeUnitFields)(i+1)) {
150b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        deleteHash(fTimeUnitToCountToPatterns[i]);
151b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fTimeUnitToCountToPatterns[i] = NULL;
152b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
153b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
154b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
155b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         i = (TimeUnit::UTimeUnitFields)(i+1)) {
156b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
157b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fTimeUnitToCountToPatterns[i] = initHash(status);
158b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (U_SUCCESS(status)) {
159b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            copyHash(other.fTimeUnitToCountToPatterns[i], fTimeUnitToCountToPatterns[i], status);
160b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else {
161b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            delete fTimeUnitToCountToPatterns[i];
162b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            fTimeUnitToCountToPatterns[i] = NULL;
163b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
164b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
165b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fStyle = other.fStyle;
166b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return *this;
167b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
168b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
169b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
170b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat::parseObject(const UnicodeString& source,
171b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            Formattable& result,
172b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            ParsePosition& pos) const {
173fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    Formattable resultNumber(0.0);
174b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UBool withNumberFormat = false;
175b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    TimeUnit::UTimeUnitFields resultTimeUnit = TimeUnit::UTIMEUNIT_FIELD_COUNT;
176b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t oldPos = pos.getIndex();
177b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t newPos = -1;
178b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t longestParseDistance = 0;
179b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UnicodeString* countOfLongestMatch = NULL;
180b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef TMUTFMT_DEBUG
181b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    char res[1000];
182b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    source.extract(0, source.length(), res, "UTF-8");
183b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    std::cout << "parse source: " << res << "\n";
184b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif
185b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // parse by iterating through all available patterns
186b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // and looking for the longest match.
187b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
188b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
189b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         i = (TimeUnit::UTimeUnitFields)(i+1)) {
190b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i];
191b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        int32_t elemPos = -1;
192b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const UHashElement* elem = NULL;
193b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        while ((elem = countToPatterns->nextElement(elemPos)) != NULL){
194b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UHashTok keyTok = elem->key;
195b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            UnicodeString* count = (UnicodeString*)keyTok.pointer;
196b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifdef TMUTFMT_DEBUG
197b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            count->extract(0, count->length(), res, "UTF-8");
198b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            std::cout << "parse plural count: " << res << "\n";
199b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif
200b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UHashTok valueTok = elem->value;
201b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            // the value is a pair of MessageFormat*
202b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            MessageFormat** patterns = (MessageFormat**)valueTok.pointer;
203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            for (UTimeUnitFormatStyle style = UTMUTFMT_FULL_STYLE; style < UTMUTFMT_FORMAT_STYLE_COUNT;
204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                 style = (UTimeUnitFormatStyle)(style + 1)) {
205b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                MessageFormat* pattern = patterns[style];
206b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                pos.setErrorIndex(-1);
207b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                pos.setIndex(oldPos);
208b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                // see if we can parse
209b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                Formattable parsed;
210b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                pattern->parseObject(source, parsed, pos);
211b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if (pos.getErrorIndex() != -1 || pos.getIndex() == oldPos) {
212b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    continue;
213b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
214b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    #ifdef TMUTFMT_DEBUG
215b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                std::cout << "parsed.getType: " << parsed.getType() << "\n";
216b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    #endif
217fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                Formattable tmpNumber(0.0);
218b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if (pattern->getArgTypeCount() != 0) {
219b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    Formattable& temp = parsed[0];
220fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    if (temp.getType() == Formattable::kString) {
221fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                        UnicodeString tmpString;
222fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                        UErrorCode pStatus = U_ZERO_ERROR;
223fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                        getNumberFormat().parse(temp.getString(tmpString), tmpNumber, pStatus);
224fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                        if (U_FAILURE(pStatus)) {
225fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                            continue;
226fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                        }
227fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    } else if (temp.isNumeric()) {
228fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                        tmpNumber = temp;
229b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    } else {
230b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        continue;
231b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    }
232b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
233b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                int32_t parseDistance = pos.getIndex() - oldPos;
234b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if (parseDistance > longestParseDistance) {
235b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    if (pattern->getArgTypeCount() != 0) {
236b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        resultNumber = tmpNumber;
237b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        withNumberFormat = true;
238b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    } else {
239b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        withNumberFormat = false;
240b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    }
241b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    resultTimeUnit = i;
242b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    newPos = pos.getIndex();
243b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    longestParseDistance = parseDistance;
244b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    countOfLongestMatch = count;
245b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
246b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
247b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
248b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
249b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    /* After find the longest match, parse the number.
250b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     * Result number could be null for the pattern without number pattern.
251b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     * such as unit pattern in Arabic.
252b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     * When result number is null, use plural rule to set the number.
253b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru     */
254b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (withNumberFormat == false && longestParseDistance != 0) {
255b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // set the number using plurrual count
256b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (0 == countOfLongestMatch->compare(PLURAL_COUNT_ZERO, 4)) {
257fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            resultNumber = Formattable(0.0);
258b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_ONE, 3)) {
259fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            resultNumber = Formattable(1.0);
260b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else if (0 == countOfLongestMatch->compare(PLURAL_COUNT_TWO, 3)) {
261fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            resultNumber = Formattable(2.0);
262b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else {
263b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            // should not happen.
264b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            // TODO: how to handle?
265fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            resultNumber = Formattable(3.0);
266b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
267b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
268b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (longestParseDistance == 0) {
269b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        pos.setIndex(oldPos);
270b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        pos.setErrorIndex(0);
271b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    } else {
272b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
273b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        TimeUnitAmount* tmutamt = new TimeUnitAmount(resultNumber, resultTimeUnit, status);
274b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (U_SUCCESS(status)) {
275b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            result.adoptObject(tmutamt);
276b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            pos.setIndex(newPos);
277b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            pos.setErrorIndex(-1);
278b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else {
279b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            pos.setIndex(oldPos);
280b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            pos.setErrorIndex(0);
281b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
282b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
283b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
284b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
285b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
286fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusTimeUnitFormat::create(UTimeUnitFormatStyle style, UErrorCode& status) {
287fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    // fTimeUnitToCountToPatterns[] must have its elements initialized to NULL first
288fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    // before checking for failure status.
289fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
290fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
291fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius         i = (TimeUnit::UTimeUnitFields)(i+1)) {
292fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        fTimeUnitToCountToPatterns[i] = NULL;
293fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
294fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
295b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(status)) {
296b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
297b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
29859d709d503bab6e2b61931737e662dd293b40578ccornelius    if (style < UTMUTFMT_FULL_STYLE || style >= UTMUTFMT_FORMAT_STYLE_COUNT) {
299b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        status = U_ILLEGAL_ARGUMENT_ERROR;
300b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
301b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
302b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    fStyle = style;
303fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
304b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //TODO: format() and parseObj() are const member functions,
305b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //so, can not do lazy initialization in C++.
306b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //setup has to be done in constructors.
307b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //and here, the behavior is not consistent with Java.
308b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //In Java, create an empty instance does not setup locale as
309b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //default locale. If it followed by setNumberFormat(),
310b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //in format(), the locale will set up as the locale in fNumberFormat.
311b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //But in C++, this sets the locale as the default locale.
312b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    setup(status);
313b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
314b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
315b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
316b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat::setup(UErrorCode& err) {
317b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    initDataMembers(err);
31854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
31954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UVector pluralCounts(0, uhash_compareUnicodeString, 6, err);
320fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    StringEnumeration* keywords = getPluralRules().getKeywords(err);
32154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (U_FAILURE(err)) {
32254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return;
32354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
32454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UnicodeString* pluralCount;
32554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    while ((pluralCount = const_cast<UnicodeString*>(keywords->snext(err))) != NULL) {
32654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius      pluralCounts.addElement(pluralCount, err);
32754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
32854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    readFromCurrentLocale(UTMUTFMT_FULL_STYLE, gUnitsTag, pluralCounts, err);
329b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    checkConsistency(UTMUTFMT_FULL_STYLE, gUnitsTag, err);
33054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    readFromCurrentLocale(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, pluralCounts, err);
331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    checkConsistency(UTMUTFMT_ABBREVIATED_STYLE, gShortUnitsTag, err);
33254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    delete keywords;
333b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
334b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
335b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
336b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
337b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat::initDataMembers(UErrorCode& err){
338b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(err)) {
339b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
340b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
341b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
342b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
343b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru         i = (TimeUnit::UTimeUnitFields)(i+1)) {
344b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        deleteHash(fTimeUnitToCountToPatterns[i]);
345b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        fTimeUnitToCountToPatterns[i] = NULL;
346b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
347b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
348b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
349b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
35054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusTimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* key,
35154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                                      const UVector& pluralCounts, UErrorCode& err) {
352b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(err)) {
353b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
354b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
355b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // fill timeUnitToCountToPatterns from resource file
356b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // err is used to indicate wrong status except missing resource.
357b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // status is an error code used in resource lookup.
358b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // status does not affect "err".
359b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
360b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UResourceBundle *rb, *unitsRes;
361fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    rb = ures_open(NULL, getLocaleID(status), &status);
362b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    unitsRes = ures_getByKey(rb, key, NULL, &status);
36359d709d503bab6e2b61931737e662dd293b40578ccornelius    unitsRes = ures_getByKey(unitsRes, "duration", unitsRes, &status);
364b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(status)) {
365b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        ures_close(unitsRes);
366b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        ures_close(rb);
367b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
368b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
369b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t size = ures_getSize(unitsRes);
370b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    for ( int32_t index = 0; index < size; ++index) {
371b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // resource of one time unit
372b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        UResourceBundle* oneTimeUnit = ures_getByIndex(unitsRes, index,
373b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                                       NULL, &status);
374b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (U_SUCCESS(status)) {
375b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const char* timeUnitName = ures_getKey(oneTimeUnit);
376b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if (timeUnitName == NULL) {
377b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                ures_close(oneTimeUnit);
378b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                continue;
379b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
380b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            UResourceBundle* countsToPatternRB = ures_getByKey(unitsRes,
381b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                                             timeUnitName,
382b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                                             NULL, &status);
383b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if (countsToPatternRB == NULL || U_FAILURE(status)) {
384b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                ures_close(countsToPatternRB);
385b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                ures_close(oneTimeUnit);
386b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                continue;
387b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
388b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            TimeUnit::UTimeUnitFields timeUnitField = TimeUnit::UTIMEUNIT_FIELD_COUNT;
389b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if ( uprv_strcmp(timeUnitName, gTimeUnitYear) == 0 ) {
390b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                timeUnitField = TimeUnit::UTIMEUNIT_YEAR;
391b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            } else if ( uprv_strcmp(timeUnitName, gTimeUnitMonth) == 0 ) {
392b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                timeUnitField = TimeUnit::UTIMEUNIT_MONTH;
393b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            } else if ( uprv_strcmp(timeUnitName, gTimeUnitDay) == 0 ) {
394b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                timeUnitField = TimeUnit::UTIMEUNIT_DAY;
395b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            } else if ( uprv_strcmp(timeUnitName, gTimeUnitHour) == 0 ) {
396b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                timeUnitField = TimeUnit::UTIMEUNIT_HOUR;
397b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            } else if ( uprv_strcmp(timeUnitName, gTimeUnitMinute) == 0 ) {
398b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                timeUnitField = TimeUnit::UTIMEUNIT_MINUTE;
399b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            } else if ( uprv_strcmp(timeUnitName, gTimeUnitSecond) == 0 ) {
400b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                timeUnitField = TimeUnit::UTIMEUNIT_SECOND;
401b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            } else if ( uprv_strcmp(timeUnitName, gTimeUnitWeek) == 0 ) {
402b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                timeUnitField = TimeUnit::UTIMEUNIT_WEEK;
403b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            } else {
404b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                ures_close(countsToPatternRB);
405b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                ures_close(oneTimeUnit);
406b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                continue;
407b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
408b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            Hashtable* countToPatterns = fTimeUnitToCountToPatterns[timeUnitField];
409b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if (countToPatterns == NULL) {
410b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                countToPatterns = initHash(err);
411b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if (U_FAILURE(err)) {
412b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    ures_close(countsToPatternRB);
413b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    ures_close(oneTimeUnit);
414b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    delete countToPatterns;
415b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    break;
416b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
417b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
418b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            int32_t count = ures_getSize(countsToPatternRB);
419b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const char*  pluralCount;
420b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            for ( int32_t pluralIndex = 0; pluralIndex < count; ++pluralIndex) {
421b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                // resource of count to pattern
422b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                UnicodeString pattern =
423b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    ures_getNextUnicodeString(countsToPatternRB, &pluralCount, &status);
424b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if (U_FAILURE(status)) {
425b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    continue;
426b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
42754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                UnicodeString pluralCountUniStr(pluralCount, -1, US_INV);
42854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                if (!pluralCounts.contains(&pluralCountUniStr)) {
42954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                  continue;
43054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                }
431fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                MessageFormat* messageFormat = new MessageFormat(pattern, getLocale(err), err);
432b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if ( U_SUCCESS(err) ) {
433b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                  MessageFormat** formatters = (MessageFormat**)countToPatterns->get(pluralCountUniStr);
434b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                  if (formatters == NULL) {
435b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*));
436b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    formatters[UTMUTFMT_FULL_STYLE] = NULL;
437b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL;
438b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    countToPatterns->put(pluralCountUniStr, formatters, err);
439b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    if (U_FAILURE(err)) {
44027f654740f2a26ad62a5c155af9199af9e69b889claireho                        uprv_free(formatters);
441b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    }
442b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                  }
443b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                  if (U_SUCCESS(err)) {
444b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                      //delete formatters[style];
445b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                      formatters[style] = messageFormat;
446b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                  }
447b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
448b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if (U_FAILURE(err)) {
449b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    ures_close(countsToPatternRB);
450b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    ures_close(oneTimeUnit);
451b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    ures_close(unitsRes);
452b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    ures_close(rb);
453b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    delete messageFormat;
454b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    delete countToPatterns;
455b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    return;
456b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
457b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
458b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if (fTimeUnitToCountToPatterns[timeUnitField] == NULL) {
459b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                fTimeUnitToCountToPatterns[timeUnitField] = countToPatterns;
460b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
461b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            ures_close(countsToPatternRB);
462b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
463b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        ures_close(oneTimeUnit);
464b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
465b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    ures_close(unitsRes);
466b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    ures_close(rb);
467b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
468b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
469b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
470b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
471b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeUnitFormat::checkConsistency(UTimeUnitFormatStyle style, const char* key, UErrorCode& err) {
472b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(err)) {
473b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
474b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
475b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // there should be patterns for each plural rule in each time unit.
476b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // For each time unit,
477b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //     for each plural rule, following is unit pattern fall-back rule:
478b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //         ( for example: "one" hour )
479b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //         look for its unit pattern in its locale tree.
480b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //         if pattern is not found in its own locale, such as de_DE,
481b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //         look for the pattern in its parent, such as de,
482b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //         keep looking till found or till root.
483b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //         if the pattern is not found in root either,
484b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //         fallback to plural count "other",
485b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //         look for the pattern of "other" in the locale tree:
486b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //         "de_DE" to "de" to "root".
487b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //         If not found, fall back to value of
488b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //         static variable DEFAULT_PATTERN_FOR_xxx, such as "{0} h".
489b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //
490b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // Following is consistency check to create pattern for each
491b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // plural rule in each time unit using above fall-back rule.
492b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    //
493fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    StringEnumeration* keywords = getPluralRules().getKeywords(err);
494b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_SUCCESS(err)) {
495b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        const UnicodeString* pluralCount;
496b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        while ((pluralCount = keywords->snext(err)) != NULL) {
497b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if ( U_SUCCESS(err) ) {
498b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                for (int32_t i = 0; i < TimeUnit::UTIMEUNIT_FIELD_COUNT; ++i) {
499b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    // for each time unit,
500b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    // get all the patterns for each plural rule in this locale.
501b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    Hashtable* countToPatterns = fTimeUnitToCountToPatterns[i];
502b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    if ( countToPatterns == NULL ) {
503b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        countToPatterns = initHash(err);
504b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        if (U_FAILURE(err)) {
505b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            delete countToPatterns;
506b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            return;
507b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        }
508b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        fTimeUnitToCountToPatterns[i] = countToPatterns;
509b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    }
510b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    MessageFormat** formatters = (MessageFormat**)countToPatterns->get(*pluralCount);
511b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    if( formatters == NULL || formatters[style] == NULL ) {
512b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        // look through parents
513fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                        const char* localeName = getLocaleID(err);
514b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        CharString pluralCountChars;
515b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        pluralCountChars.appendInvariantChars(*pluralCount, err);
51627f654740f2a26ad62a5c155af9199af9e69b889claireho                        searchInLocaleChain(style, key, localeName,
517b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                            (TimeUnit::UTimeUnitFields)i,
518b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                            *pluralCount, pluralCountChars.data(),
519b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                            countToPatterns, err);
520b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    }
521b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
522b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
523b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
524b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
525b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    delete keywords;
526b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
527b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
528b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
529b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
530b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// srcPluralCount is the original plural count on which the pattern is
531b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// searched for.
532b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// searchPluralCount is the fallback plural count.
533b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// For example, to search for pattern for ""one" hour",
534b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// "one" is the srcPluralCount,
535b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// if the pattern is not found even in root, fallback to
536b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// using patterns of plural count "other",
537b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// then, "other" is the searchPluralCount.
538b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
539b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeUnitFormat::searchInLocaleChain(UTimeUnitFormatStyle style, const char* key, const char* localeName,
540b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                TimeUnit::UTimeUnitFields srcTimeUnitField,
541b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                const UnicodeString& srcPluralCount,
542b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                const char* searchPluralCount,
543b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                Hashtable* countToPatterns,
544b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                UErrorCode& err) {
545b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(err)) {
546b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
547b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
548b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
549b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    char parentLocale[ULOC_FULLNAME_CAPACITY];
55027f654740f2a26ad62a5c155af9199af9e69b889claireho    uprv_strcpy(parentLocale, localeName);
551b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t locNameLen;
552103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    U_ASSERT(countToPatterns != NULL);
553b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    while ((locNameLen = uloc_getParent(parentLocale, parentLocale,
554b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                        ULOC_FULLNAME_CAPACITY, &status)) >= 0){
555b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // look for pattern for srcPluralCount in locale tree
556b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        UResourceBundle *rb, *unitsRes, *countsToPatternRB;
557b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        rb = ures_open(NULL, parentLocale, &status);
558b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        unitsRes = ures_getByKey(rb, key, NULL, &status);
559b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const char* timeUnitName = getTimeUnitName(srcTimeUnitField, status);
560b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        countsToPatternRB = ures_getByKey(unitsRes, timeUnitName, NULL, &status);
561b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        const UChar* pattern;
562b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        int32_t      ptLength;
563b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        pattern = ures_getStringByKeyWithFallback(countsToPatternRB, searchPluralCount, &ptLength, &status);
564b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (U_SUCCESS(status)) {
565b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            //found
566fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            MessageFormat* messageFormat = new MessageFormat(UnicodeString(TRUE, pattern, ptLength), getLocale(err), err);
567b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if (U_SUCCESS(err)) {
568b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount);
569b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if (formatters == NULL) {
570b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*));
571b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    formatters[UTMUTFMT_FULL_STYLE] = NULL;
572b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL;
573b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    countToPatterns->put(srcPluralCount, formatters, err);
574b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    if (U_FAILURE(err)) {
57527f654740f2a26ad62a5c155af9199af9e69b889claireho                        uprv_free(formatters);
576b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                        delete messageFormat;
577b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    }
578b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
579b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if (U_SUCCESS(err)) {
580b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    //delete formatters[style];
581b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    formatters[style] = messageFormat;
582b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
583b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            } else {
584b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                delete messageFormat;
585b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
586b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            ures_close(countsToPatternRB);
587b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            ures_close(unitsRes);
588b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            ures_close(rb);
589b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            return;
590b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
591b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        ures_close(countsToPatternRB);
592b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        ures_close(unitsRes);
593b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        ures_close(rb);
59427f654740f2a26ad62a5c155af9199af9e69b889claireho        status = U_ZERO_ERROR;
595b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if ( locNameLen ==0 ) {
596b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            break;
597b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
598b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
59927f654740f2a26ad62a5c155af9199af9e69b889claireho
60027f654740f2a26ad62a5c155af9199af9e69b889claireho    // if no unitsShort resource was found even after fallback to root locale
60127f654740f2a26ad62a5c155af9199af9e69b889claireho    // then search the units resource fallback from the current level to root
60227f654740f2a26ad62a5c155af9199af9e69b889claireho    if ( locNameLen == 0 && uprv_strcmp(key, gShortUnitsTag) == 0) {
60327f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef TMUTFMT_DEBUG
60427f654740f2a26ad62a5c155af9199af9e69b889claireho        std::cout << "loop into searchInLocaleChain since Short-Long-Alternative \n";
60527f654740f2a26ad62a5c155af9199af9e69b889claireho#endif
60627f654740f2a26ad62a5c155af9199af9e69b889claireho        char pLocale[ULOC_FULLNAME_CAPACITY];
60727f654740f2a26ad62a5c155af9199af9e69b889claireho        uprv_strcpy(pLocale, localeName);
60827f654740f2a26ad62a5c155af9199af9e69b889claireho        // Add an underscore at the tail of locale name,
60927f654740f2a26ad62a5c155af9199af9e69b889claireho        // so that searchInLocaleChain will check the current locale before falling back
61027f654740f2a26ad62a5c155af9199af9e69b889claireho        uprv_strcat(pLocale, "_");
61127f654740f2a26ad62a5c155af9199af9e69b889claireho        searchInLocaleChain(style, gUnitsTag, pLocale, srcTimeUnitField, srcPluralCount,
61227f654740f2a26ad62a5c155af9199af9e69b889claireho                             searchPluralCount, countToPatterns, err);
613103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount);
614103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (formatters != NULL && formatters[style] != NULL) {
615103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return;
61627f654740f2a26ad62a5c155af9199af9e69b889claireho        }
61727f654740f2a26ad62a5c155af9199af9e69b889claireho    }
61827f654740f2a26ad62a5c155af9199af9e69b889claireho
619b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // if not found the pattern for this plural count at all,
620b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // fall-back to plural count "other"
621b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( uprv_strcmp(searchPluralCount, gPluralCountOther) == 0 ) {
622b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // set default fall back the same as the resource in root
623b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        MessageFormat* messageFormat = NULL;
624b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        const UChar *pattern = NULL;
625b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_SECOND ) {
626b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            pattern = DEFAULT_PATTERN_FOR_SECOND;
627b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_MINUTE ) {
628b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            pattern = DEFAULT_PATTERN_FOR_MINUTE;
629b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_HOUR ) {
630b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            pattern = DEFAULT_PATTERN_FOR_HOUR;
631b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_WEEK ) {
632b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            pattern = DEFAULT_PATTERN_FOR_WEEK;
633b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_DAY ) {
634b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            pattern = DEFAULT_PATTERN_FOR_DAY;
635b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_MONTH ) {
636b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            pattern = DEFAULT_PATTERN_FOR_MONTH;
637b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else if ( srcTimeUnitField == TimeUnit::UTIMEUNIT_YEAR ) {
638b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            pattern = DEFAULT_PATTERN_FOR_YEAR;
639b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
640b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (pattern != NULL) {
641fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            messageFormat = new MessageFormat(UnicodeString(TRUE, pattern, -1), getLocale(err), err);
642b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
643b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        if (U_SUCCESS(err)) {
644b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount);
645b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if (formatters == NULL) {
646b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                formatters = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*));
647b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                formatters[UTMUTFMT_FULL_STYLE] = NULL;
648b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                formatters[UTMUTFMT_ABBREVIATED_STYLE] = NULL;
649b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                countToPatterns->put(srcPluralCount, formatters, err);
650b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                if (U_FAILURE(err)) {
65127f654740f2a26ad62a5c155af9199af9e69b889claireho                    uprv_free(formatters);
652b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                    delete messageFormat;
653b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                }
654b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
655b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if (U_SUCCESS(err)) {
656b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                //delete formatters[style];
657b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                formatters[style] = messageFormat;
658b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
659b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        } else {
660b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            delete messageFormat;
661b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
662b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    } else {
663b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        // fall back to rule "other", and search in parents
66427f654740f2a26ad62a5c155af9199af9e69b889claireho        searchInLocaleChain(style, key, localeName, srcTimeUnitField, srcPluralCount,
665b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                            gPluralCountOther, countToPatterns, err);
666b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
667b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
668b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
669b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
670b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat::setLocale(const Locale& locale, UErrorCode& status) {
671fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (setMeasureFormatLocale(locale, status)) {
672b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        setup(status);
673b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
674b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
675b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
676b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
677b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
678b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat::setNumberFormat(const NumberFormat& format, UErrorCode& status){
679fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (U_FAILURE(status)) {
680b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
681b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
682fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    adoptNumberFormat((NumberFormat *)format.clone(), status);
683b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
684b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
685b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
686b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
687b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat::deleteHash(Hashtable* htable) {
688b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t pos = -1;
689b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UHashElement* element = NULL;
690b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( htable ) {
691b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        while ( (element = htable->nextElement(pos)) != NULL ) {
692b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UHashTok valueTok = element->value;
693b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const MessageFormat** value = (const MessageFormat**)valueTok.pointer;
694b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            delete value[UTMUTFMT_FULL_STYLE];
695b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            delete value[UTMUTFMT_ABBREVIATED_STYLE];
696b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            //delete[] value;
697b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            uprv_free(value);
698b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
699b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
700b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    delete htable;
701b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
702b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
703b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
704b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid
705b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat::copyHash(const Hashtable* source, Hashtable* target, UErrorCode& status) {
706b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( U_FAILURE(status) ) {
707b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
708b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
709b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    int32_t pos = -1;
710b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const UHashElement* element = NULL;
711b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( source ) {
712b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        while ( (element = source->nextElement(pos)) != NULL ) {
713b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UHashTok keyTok = element->key;
714b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UnicodeString* key = (UnicodeString*)keyTok.pointer;
715b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const UHashTok valueTok = element->value;
716b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            const MessageFormat** value = (const MessageFormat**)valueTok.pointer;
717b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            MessageFormat** newVal = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*));
718b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            newVal[0] = (MessageFormat*)value[0]->clone();
719b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            newVal[1] = (MessageFormat*)value[1]->clone();
720b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            target->put(UnicodeString(*key), newVal, status);
721b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            if ( U_FAILURE(status) ) {
722b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                delete newVal[0];
723b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                delete newVal[1];
72427f654740f2a26ad62a5c155af9199af9e69b889claireho                uprv_free(newVal);
725b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                return;
726b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru            }
727b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        }
728b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
729b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
730b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
731b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
732b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CDECL_BEGIN
733b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
734b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/**
735b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * set hash table value comparator
736b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *
737b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param val1  one value in comparison
738b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @param val2  the other value in comparison
739b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * @return      TRUE if 2 values are the same, FALSE otherwise
740b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */
74150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool U_CALLCONV tmutfmtHashTableValueComparator(UHashTok val1, UHashTok val2);
742b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
74327f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UBool
74450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CALLCONV tmutfmtHashTableValueComparator(UHashTok val1, UHashTok val2) {
745b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const MessageFormat** pattern1 = (const MessageFormat**)val1.pointer;
746b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    const MessageFormat** pattern2 = (const MessageFormat**)val2.pointer;
747b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return *pattern1[0] == *pattern2[0] && *pattern1[1] == *pattern2[1];
748b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
749b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
75050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CDECL_END
75150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
752b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruHashtable*
753b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat::initHash(UErrorCode& status) {
754b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( U_FAILURE(status) ) {
755b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return NULL;
756b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
757b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    Hashtable* hTable;
758b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if ( (hTable = new Hashtable(TRUE, status)) == NULL ) {
759b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        status = U_MEMORY_ALLOCATION_ERROR;
760b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return NULL;
761b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
762b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if ( U_FAILURE(status) ) {
763b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        delete hTable;
764b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return NULL;
765b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
76650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    hTable->setValueComparator(tmutfmtHashTableValueComparator);
767b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    return hTable;
768b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
769b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
770b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
771b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruconst char*
772b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruTimeUnitFormat::getTimeUnitName(TimeUnit::UTimeUnitFields unitField,
773b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru                                UErrorCode& status) {
774b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(status)) {
775b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return NULL;
776b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
777b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    switch (unitField) {
778b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru      case TimeUnit::UTIMEUNIT_YEAR:
779b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return gTimeUnitYear;
780b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru      case TimeUnit::UTIMEUNIT_MONTH:
781b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return gTimeUnitMonth;
782b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru      case TimeUnit::UTIMEUNIT_DAY:
783b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return gTimeUnitDay;
784b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru      case TimeUnit::UTIMEUNIT_WEEK:
785b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return gTimeUnitWeek;
786b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru      case TimeUnit::UTIMEUNIT_HOUR:
787b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return gTimeUnitHour;
788b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru      case TimeUnit::UTIMEUNIT_MINUTE:
789b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return gTimeUnitMinute;
790b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru      case TimeUnit::UTIMEUNIT_SECOND:
791b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return gTimeUnitSecond;
792b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru      default:
793b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        status = U_ILLEGAL_ARGUMENT_ERROR;
794b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return NULL;
795b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
796b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
797b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
798b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_NAMESPACE_END
799b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
800b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif
801