1c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru/*******************************************************************************
21b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert* Copyright (C) 2008-2015, International Business Machines Corporation and
3c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru* others. All Rights Reserved.
4c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru*******************************************************************************
5c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru*
6c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru* File DTITVINF.CPP
7c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru*
8c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru*******************************************************************************
9c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru*/
10c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
11c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include "unicode/dtitvinf.h"
12c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
13c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
14c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING
15c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
16b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru//TODO: define it in compiler time
17c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru//#define DTITVINF_DEBUG 1
18c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
19c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
20c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#ifdef DTITVINF_DEBUG
21c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include <iostream>
22c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#endif
23c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
24c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include "cstring.h"
25c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include "unicode/msgfmt.h"
2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/uloc.h"
2750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/ures.h"
28c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include "dtitv_impl.h"
29c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include "hash.h"
30c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include "gregoimp.h"
31c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include "uresimp.h"
32c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include "hash.h"
33c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include "gregoimp.h"
34c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include "uresimp.h"
35c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
36c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
37c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruU_NAMESPACE_BEGIN
38c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
39c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
40c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#ifdef DTITVINF_DEBUG
41c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#define PRINTMESG(msg) { std::cout << "(" << __FILE__ << ":" << __LINE__ << ") " << msg << "\n"; }
42c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#endif
43c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
44c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateIntervalInfo)
45c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
46c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const char gCalendarTag[]="calendar";
47c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const char gGregorianTag[]="gregorian";
48c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const char gIntervalDateTimePatternTag[]="intervalFormats";
49c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const char gFallbackPatternTag[]="fallback";
50c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
51c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru// {0}
52c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const UChar gFirstPattern[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET};
53c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru// {1}
54c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const UChar gSecondPattern[] = {LEFT_CURLY_BRACKET, DIGIT_ONE, RIGHT_CURLY_BRACKET};
55c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
56c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru// default fall-back
57c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const UChar gDefaultFallbackPattern[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, EN_DASH, SPACE, LEFT_CURLY_BRACKET, DIGIT_ONE, RIGHT_CURLY_BRACKET, 0};
58c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
59c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
60c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
61c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::DateIntervalInfo(UErrorCode& status)
62c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru:   fFallbackIntervalPattern(gDefaultFallbackPattern),
63c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    fFirstDateInPtnIsLaterDate(false),
64c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    fIntervalPatterns(NULL)
65c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
66c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    fIntervalPatterns = initHash(status);
67c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
68c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
69c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
70c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
71c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::DateIntervalInfo(const Locale& locale, UErrorCode& status)
72c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru:   fFallbackIntervalPattern(gDefaultFallbackPattern),
73c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    fFirstDateInPtnIsLaterDate(false),
74c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    fIntervalPatterns(NULL)
75c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
76c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    initializeData(locale, status);
77c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
78c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
79c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
80c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
81c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid
82c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::setIntervalPattern(const UnicodeString& skeleton,
83c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                     UCalendarDateFields lrgDiffCalUnit,
84c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                     const UnicodeString& intervalPattern,
85c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                     UErrorCode& status) {
86c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
87c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( lrgDiffCalUnit == UCAL_HOUR_OF_DAY ) {
88c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        setIntervalPatternInternally(skeleton, UCAL_AM_PM, intervalPattern, status);
89c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        setIntervalPatternInternally(skeleton, UCAL_HOUR, intervalPattern, status);
90c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    } else if ( lrgDiffCalUnit == UCAL_DAY_OF_MONTH ||
91c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                lrgDiffCalUnit == UCAL_DAY_OF_WEEK ) {
92c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        setIntervalPatternInternally(skeleton, UCAL_DATE, intervalPattern, status);
93c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    } else {
94c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        setIntervalPatternInternally(skeleton, lrgDiffCalUnit, intervalPattern, status);
95c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
96c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
97c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
98c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
99c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid
100c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::setFallbackIntervalPattern(
101c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                    const UnicodeString& fallbackPattern,
102c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                    UErrorCode& status) {
103c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( U_FAILURE(status) ) {
104c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return;
105c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
106c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t firstPatternIndex = fallbackPattern.indexOf(gFirstPattern,
107c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                        sizeof(gFirstPattern)/sizeof(gFirstPattern[0]), 0);
108c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t secondPatternIndex = fallbackPattern.indexOf(gSecondPattern,
109c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                        sizeof(gSecondPattern)/sizeof(gSecondPattern[0]), 0);
110c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( firstPatternIndex == -1 || secondPatternIndex == -1 ) {
111c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        status = U_ILLEGAL_ARGUMENT_ERROR;
112c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return;
113c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
114c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( firstPatternIndex > secondPatternIndex ) {
115c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        fFirstDateInPtnIsLaterDate = true;
116c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
117c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    fFallbackIntervalPattern = fallbackPattern;
118c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
119c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
120c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
121c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
122c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::DateIntervalInfo(const DateIntervalInfo& dtitvinf)
123c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru:   UObject(dtitvinf),
124c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    fIntervalPatterns(NULL)
125c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
126c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    *this = dtitvinf;
127c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
128c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
129c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
130c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
131c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo&
132c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::operator=(const DateIntervalInfo& dtitvinf) {
133c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( this == &dtitvinf ) {
134c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return *this;
135c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
136c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
137c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
138c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    deleteHash(fIntervalPatterns);
139c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    fIntervalPatterns = initHash(status);
140c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    copyHash(dtitvinf.fIntervalPatterns, fIntervalPatterns, status);
141c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( U_FAILURE(status) ) {
142c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return *this;
143c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
144c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
145c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    fFallbackIntervalPattern = dtitvinf.fFallbackIntervalPattern;
146c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    fFirstDateInPtnIsLaterDate = dtitvinf.fFirstDateInPtnIsLaterDate;
147c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return *this;
148c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
149c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
150c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
151c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo*
152c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::clone() const {
153c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return new DateIntervalInfo(*this);
154c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
155c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
156c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
157c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::~DateIntervalInfo() {
158c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    deleteHash(fIntervalPatterns);
159c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    fIntervalPatterns = NULL;
160c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
161c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
162c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
163c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruUBool
164c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::operator==(const DateIntervalInfo& other) const {
165c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UBool equal = (
166c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      fFallbackIntervalPattern == other.fFallbackIntervalPattern &&
167c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      fFirstDateInPtnIsLaterDate == other.fFirstDateInPtnIsLaterDate );
168c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
169c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( equal == TRUE ) {
170c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        equal = fIntervalPatterns->equals(*(other.fIntervalPatterns));
171c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
172c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
173c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return equal;
174c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
175c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
176c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
177c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruUnicodeString&
178c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::getIntervalPattern(const UnicodeString& skeleton,
179c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                     UCalendarDateFields field,
180c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                     UnicodeString& result,
181c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                     UErrorCode& status) const {
182c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( U_FAILURE(status) ) {
183c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return result;
184c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
185c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
186c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const UnicodeString* patternsOfOneSkeleton = (UnicodeString*) fIntervalPatterns->get(skeleton);
187c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( patternsOfOneSkeleton != NULL ) {
188c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        IntervalPatternIndex index = calendarFieldToIntervalIndex(field, status);
189c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if ( U_FAILURE(status) ) {
190c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            return result;
191c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
192c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        const UnicodeString& intervalPattern =  patternsOfOneSkeleton[index];
193c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if ( !intervalPattern.isEmpty() ) {
194c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            result = intervalPattern;
195c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
196c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
197c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return result;
198c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
199c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
200c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
201c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruUBool
202c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::getDefaultOrder() const {
203c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return fFirstDateInPtnIsLaterDate;
204c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
205c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
206c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
207c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruUnicodeString&
208c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::getFallbackIntervalPattern(UnicodeString& result) const {
209c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    result = fFallbackIntervalPattern;
210c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return result;
211c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
212c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
21350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define ULOC_LOCALE_IDENTIFIER_CAPACITY (ULOC_FULLNAME_CAPACITY + 1 + ULOC_KEYWORD_AND_VALUES_CAPACITY)
214c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
215c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid
216c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::initializeData(const Locale& locale, UErrorCode& err)
217c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
218c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  fIntervalPatterns = initHash(err);
219c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  if ( U_FAILURE(err) ) {
220c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      return;
221c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  }
222c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  const char *locName = locale.getName();
223c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  char parentLocale[ULOC_FULLNAME_CAPACITY];
224c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  uprv_strcpy(parentLocale, locName);
225c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  UErrorCode status = U_ZERO_ERROR;
2261b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert  Hashtable skeletonKeyPairs(FALSE, status);
227c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  if ( U_FAILURE(status) ) {
228c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      return;
229c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  }
23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
23150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  // determine calendar type
23250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  const char * calendarTypeToUse = gGregorianTag; // initial default
23350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  char         calendarType[ULOC_KEYWORDS_CAPACITY]; // to be filled in with the type to use, if all goes well
23450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  char         localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY];
23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  // obtain a locale that always has the calendar key value that should be used
23650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  (void)ures_getFunctionalEquivalent(localeWithCalendarKey, ULOC_LOCALE_IDENTIFIER_CAPACITY, NULL,
23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                     "calendar", "calendar", locName, NULL, FALSE, &status);
23850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY-1] = 0; // ensure null termination
23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  // now get the calendar key value from that locale
24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  int32_t calendarTypeLen = uloc_getKeywordValue(localeWithCalendarKey, "calendar", calendarType, ULOC_KEYWORDS_CAPACITY, &status);
24150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  if (U_SUCCESS(status) && calendarTypeLen < ULOC_KEYWORDS_CAPACITY) {
24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    calendarTypeToUse = calendarType;
24350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  }
24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  status = U_ZERO_ERROR;
24550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
246c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  do {
24750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UResourceBundle *rb, *calBundle, *calTypeBundle, *itvDtPtnResource;
248c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    rb = ures_open(NULL, parentLocale, &status);
24983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    if ( U_FAILURE(status) ) {
25083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        break;
25183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    }
252c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    calBundle = ures_getByKey(rb, gCalendarTag, NULL, &status);
25350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    calTypeBundle = ures_getByKey(calBundle, calendarTypeToUse, NULL, &status);
25450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    itvDtPtnResource = ures_getByKeyWithFallback(calTypeBundle,
255c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                         gIntervalDateTimePatternTag, NULL, &status);
256c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
257c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( U_SUCCESS(status) ) {
258c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // look for fallback first, since it establishes the default order
259c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        const UChar* resStr;
260c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        int32_t resStrLen = 0;
261c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        resStr = ures_getStringByKeyWithFallback(itvDtPtnResource,
262c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                             gFallbackPatternTag,
263c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                             &resStrLen, &status);
264c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if ( U_SUCCESS(status) ) {
265c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            UnicodeString pattern = UnicodeString(TRUE, resStr, resStrLen);
266c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            setFallbackIntervalPattern(pattern, status);
267c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
268c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
269c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        int32_t size = ures_getSize(itvDtPtnResource);
270c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        int32_t index;
271c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        for ( index = 0; index < size; ++index ) {
272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            LocalUResourceBundlePointer oneRes(ures_getByIndex(itvDtPtnResource, index,
273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                                     NULL, &status));
274c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            if ( U_SUCCESS(status) ) {
275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                const char* skeleton = ures_getKey(oneRes.getAlias());
276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (skeleton == NULL) {
277c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    continue;
278c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                }
279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                UnicodeString skeletonUniStr(skeleton, -1, US_INV);
280c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                if ( uprv_strcmp(skeleton, gFallbackPatternTag) == 0 ) {
281c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    continue;  // fallback
282c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                }
283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                LocalUResourceBundlePointer intervalPatterns(ures_getByKey(
285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                     itvDtPtnResource, skeleton, NULL, &status));
286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
287c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                if ( U_FAILURE(status) ) {
288c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    break;
289c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                }
290c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                if ( intervalPatterns == NULL ) {
291c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    continue;
292c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                }
293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
294c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                const char* key;
295b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                int32_t ptnNum = ures_getSize(intervalPatterns.getAlias());
296c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                int32_t ptnIndex;
297c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                for ( ptnIndex = 0; ptnIndex < ptnNum; ++ptnIndex ) {
298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    UnicodeString pattern =
299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        ures_getNextUnicodeString(intervalPatterns.getAlias(), &key, &status);
300c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    if ( U_FAILURE(status) ) {
301c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                        break;
302c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    }
3031b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                    UnicodeString keyUniStr(key, -1, US_INV);
3041b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                    UnicodeString skeletonKeyPair(skeletonUniStr + keyUniStr);
3051b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                    if ( skeletonKeyPairs.geti(skeletonKeyPair) == 1 ) {
3061b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                        continue;
3071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                    }
3081b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                    skeletonKeyPairs.puti(skeletonKeyPair, 1, status);
309c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
310c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    UCalendarDateFields calendarField = UCAL_FIELD_COUNT;
311c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    if ( !uprv_strcmp(key, "y") ) {
312c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                        calendarField = UCAL_YEAR;
313c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    } else if ( !uprv_strcmp(key, "M") ) {
314c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                        calendarField = UCAL_MONTH;
315c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    } else if ( !uprv_strcmp(key, "d") ) {
316c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                        calendarField = UCAL_DATE;
317c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    } else if ( !uprv_strcmp(key, "a") ) {
318c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                        calendarField = UCAL_AM_PM;
31950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    } else if ( !uprv_strcmp(key, "h") || !uprv_strcmp(key, "H") ) {
320c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                        calendarField = UCAL_HOUR;
321c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    } else if ( !uprv_strcmp(key, "m") ) {
322c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                        calendarField = UCAL_MINUTE;
323c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    }
324c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    if ( calendarField != UCAL_FIELD_COUNT ) {
325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        setIntervalPatternInternally(skeletonUniStr, calendarField, pattern,status);
326c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    }
327c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                }
328c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            }
329c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
330c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
331c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ures_close(itvDtPtnResource);
33250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ures_close(calTypeBundle);
333c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ures_close(calBundle);
33483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius
335c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    status = U_ZERO_ERROR;
33683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    // Find the name of the appropriate parent locale (from %%Parent if present, else
33783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    // uloc_getParent on the actual locale name)
33883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    // (It would be nice to have a ures function that did this...)
33983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    int32_t locNameLen;
34083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    const UChar * parentUName = ures_getStringByKey(rb, "%%Parent", &locNameLen, &status);
34183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    if (U_SUCCESS(status) && status != U_USING_FALLBACK_WARNING && locNameLen < ULOC_FULLNAME_CAPACITY) {
34283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        u_UCharsToChars(parentUName, parentLocale, locNameLen + 1);
34383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    } else {
34483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        status = U_ZERO_ERROR;
34583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        // Get the actual name of the current locale being used
34683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        const char *curLocaleName=ures_getLocaleByType(rb, ULOC_ACTUAL_LOCALE, &status);
34783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        if ( U_FAILURE(status) ) {
34883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius            curLocaleName = parentLocale;
34983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius            status = U_ZERO_ERROR;
35083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        }
35183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        uloc_getParent(curLocaleName, parentLocale, ULOC_FULLNAME_CAPACITY, &status);
35283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        if (U_FAILURE(err) || err == U_STRING_NOT_TERMINATED_WARNING) {
35383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius            parentLocale[0] = 0; // just fallback to root, will cause us to stop
35483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius            status = U_ZERO_ERROR;
35583a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        }
35683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    }
35783a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    // Now we can close the current locale bundle
35883a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    ures_close(rb);
35983a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    // If the new current locale is root, then stop
36083a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    // (unlike for DateTimePatternGenerator, DateIntervalFormat does not go all the way up
36183a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius    // to root to find additional data for non-root locales)
36283a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius  } while ( parentLocale[0] != 0 && uprv_strcmp(parentLocale,"root")!=0 );
363c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
364c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
365c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
366c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
367c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid
368c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::setIntervalPatternInternally(const UnicodeString& skeleton,
369c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                      UCalendarDateFields lrgDiffCalUnit,
370c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                      const UnicodeString& intervalPattern,
371c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                      UErrorCode& status) {
372c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    IntervalPatternIndex index = calendarFieldToIntervalIndex(lrgDiffCalUnit,status);
373c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( U_FAILURE(status) ) {
374c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return;
375c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
376c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UnicodeString* patternsOfOneSkeleton = (UnicodeString*)(fIntervalPatterns->get(skeleton));
377c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UBool emptyHash = false;
378c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( patternsOfOneSkeleton == NULL ) {
379c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        patternsOfOneSkeleton = new UnicodeString[kIPI_MAX_INDEX];
380c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        emptyHash = true;
381c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
382c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
383c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    patternsOfOneSkeleton[index] = intervalPattern;
384c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( emptyHash == TRUE ) {
385c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        fIntervalPatterns->put(skeleton, patternsOfOneSkeleton, status);
386c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
387c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
388c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
389c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
390c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
391c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid
392c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::parseSkeleton(const UnicodeString& skeleton,
393c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                int32_t* skeletonFieldWidth) {
394c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const int8_t PATTERN_CHAR_BASE = 0x41;
395c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t i;
396c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    for ( i = 0; i < skeleton.length(); ++i ) {
397c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // it is an ASCII char in skeleton
398c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        int8_t ch = (int8_t)skeleton.charAt(i);
399c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        ++skeletonFieldWidth[ch - PATTERN_CHAR_BASE];
400c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
401c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
402c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
403c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
404c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
405c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruUBool
406c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::stringNumeric(int32_t fieldWidth, int32_t anotherFieldWidth,
407c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                char patternLetter) {
408c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( patternLetter == 'M' ) {
40927f654740f2a26ad62a5c155af9199af9e69b889claireho        if ( (fieldWidth <= 2 && anotherFieldWidth > 2) ||
41027f654740f2a26ad62a5c155af9199af9e69b889claireho             (fieldWidth > 2 && anotherFieldWidth <= 2 )) {
411c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            return true;
412c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
413c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
414c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return false;
415c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
416c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
417c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
418c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
419c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruconst UnicodeString*
420c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton,
421c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                  int8_t& bestMatchDistanceInfo) const {
422c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#ifdef DTITVINF_DEBUG
423c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    char result[1000];
424c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    char result_1[1000];
425c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    char mesg[2000];
426c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    skeleton.extract(0,  skeleton.length(), result, "UTF-8");
427c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    sprintf(mesg, "in getBestSkeleton: skeleton: %s; \n", result);
428c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    PRINTMESG(mesg)
429c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#endif
430c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
431c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
432c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t inputSkeletonFieldWidth[] =
433c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    {
434c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    //       A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
435c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
436c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    //   P   Q   R   S   T   U   V   W   X   Y   Z
437c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  0, 0, 0,
438c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    //       a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
439c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
440c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    //   p   q   r   s   t   u   v   w   x   y   z
441c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
442c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    };
443c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
444c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t skeletonFieldWidth[] =
445c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    {
446c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    //       A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
447c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
448c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    //   P   Q   R   S   T   U   V   W   X   Y   Z
449c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,  0, 0, 0,
450c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    //       a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
451c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
452c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    //   p   q   r   s   t   u   v   w   x   y   z
453c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
454c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    };
455c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
456c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const int32_t DIFFERENT_FIELD = 0x1000;
457c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const int32_t STRING_NUMERIC_DIFFERENCE = 0x100;
458c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const int32_t BASE = 0x41;
459c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const UChar CHAR_V = 0x0076;
460c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const UChar CHAR_Z = 0x007A;
461c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
462c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // hack for 'v' and 'z'.
463c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // resource bundle only have time skeletons ending with 'v',
464c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // but not for time skeletons ending with 'z'.
465c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UBool replaceZWithV = false;
466c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const UnicodeString* inputSkeleton = &skeleton;
467c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UnicodeString copySkeleton;
468c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( skeleton.indexOf(CHAR_Z) != -1 ) {
469c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        copySkeleton = skeleton;
470b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        copySkeleton.findAndReplace(UnicodeString(CHAR_Z), UnicodeString(CHAR_V));
471c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        inputSkeleton = &copySkeleton;
472c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        replaceZWithV = true;
473c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
474c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
475c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    parseSkeleton(*inputSkeleton, inputSkeletonFieldWidth);
476c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t bestDistance = MAX_POSITIVE_INT;
477c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const UnicodeString* bestSkeleton = NULL;
478c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
479c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // 0 means exact the same skeletons;
480c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // 1 means having the same field, but with different length,
481c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // 2 means only z/v differs
482c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // -1 means having different field.
483c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    bestMatchDistanceInfo = 0;
484c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int8_t fieldLength = sizeof(skeletonFieldWidth)/sizeof(skeletonFieldWidth[0]);
485c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
4861b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    int32_t pos = UHASH_FIRST;
487c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const UHashElement* elem = NULL;
488c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    while ( (elem = fIntervalPatterns->nextElement(pos)) != NULL ) {
489c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        const UHashTok keyTok = elem->key;
490c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        UnicodeString* skeleton = (UnicodeString*)keyTok.pointer;
491c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#ifdef DTITVINF_DEBUG
492c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    skeleton->extract(0,  skeleton->length(), result, "UTF-8");
493c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    sprintf(mesg, "available skeletons: skeleton: %s; \n", result);
494c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    PRINTMESG(mesg)
495c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#endif
496c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
497c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // clear skeleton field width
498c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        int8_t i;
499c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        for ( i = 0; i < fieldLength; ++i ) {
500c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            skeletonFieldWidth[i] = 0;
501c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
502c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        parseSkeleton(*skeleton, skeletonFieldWidth);
503c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // calculate distance
504c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        int32_t distance = 0;
505c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        int8_t fieldDifference = 1;
506c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        for ( i = 0; i < fieldLength; ++i ) {
507c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            int32_t inputFieldWidth = inputSkeletonFieldWidth[i];
508c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            int32_t fieldWidth = skeletonFieldWidth[i];
509c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            if ( inputFieldWidth == fieldWidth ) {
510c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                continue;
511c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            }
512c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            if ( inputFieldWidth == 0 ) {
513c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                fieldDifference = -1;
514c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                distance += DIFFERENT_FIELD;
515c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            } else if ( fieldWidth == 0 ) {
516c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                fieldDifference = -1;
517c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                distance += DIFFERENT_FIELD;
518c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            } else if (stringNumeric(inputFieldWidth, fieldWidth,
519c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                     (char)(i+BASE) ) ) {
520c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                distance += STRING_NUMERIC_DIFFERENCE;
521c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            } else {
522c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                distance += (inputFieldWidth > fieldWidth) ?
523c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                            (inputFieldWidth - fieldWidth) :
524c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                            (fieldWidth - inputFieldWidth);
525c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            }
526c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
527c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if ( distance < bestDistance ) {
528c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            bestSkeleton = skeleton;
529c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            bestDistance = distance;
530c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            bestMatchDistanceInfo = fieldDifference;
531c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
532c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if ( distance == 0 ) {
533c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            bestMatchDistanceInfo = 0;
534c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            break;
535c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
536c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
537c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( replaceZWithV && bestMatchDistanceInfo != -1 ) {
538c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        bestMatchDistanceInfo = 2;
539c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
540c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return bestSkeleton;
541c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
542c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
543c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
544c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
545c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::IntervalPatternIndex
546c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::calendarFieldToIntervalIndex(UCalendarDateFields field,
547c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                               UErrorCode& status) {
548c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( U_FAILURE(status) ) {
549c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return kIPI_MAX_INDEX;
550c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
551c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    IntervalPatternIndex index = kIPI_MAX_INDEX;
552c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    switch ( field ) {
553c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      case UCAL_ERA:
554c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        index = kIPI_ERA;
555c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        break;
556c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      case UCAL_YEAR:
557c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        index = kIPI_YEAR;
558c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        break;
559c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      case UCAL_MONTH:
560c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        index = kIPI_MONTH;
561c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        break;
562c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      case UCAL_DATE:
563c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      case UCAL_DAY_OF_WEEK:
564c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      //case UCAL_DAY_OF_MONTH:
565c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        index = kIPI_DATE;
566c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        break;
567c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      case UCAL_AM_PM:
568c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        index = kIPI_AM_PM;
569c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        break;
570c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      case UCAL_HOUR:
571c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      case UCAL_HOUR_OF_DAY:
572c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        index = kIPI_HOUR;
573c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        break;
574c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      case UCAL_MINUTE:
575c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        index = kIPI_MINUTE;
576c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        break;
577c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert      case UCAL_SECOND:
578c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        index = kIPI_SECOND;
579c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert        break;
580c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      default:
581c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        status = U_ILLEGAL_ARGUMENT_ERROR;
582c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
583c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return index;
584c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
585c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
586c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
587c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
588c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid
589c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::deleteHash(Hashtable* hTable)
590c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
591c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( hTable == NULL ) {
592c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return;
593c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
5941b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    int32_t pos = UHASH_FIRST;
595c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const UHashElement* element = NULL;
596c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    while ( (element = hTable->nextElement(pos)) != NULL ) {
597c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        const UHashTok valueTok = element->value;
598c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        const UnicodeString* value = (UnicodeString*)valueTok.pointer;
599c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        delete[] value;
600c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
601c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    delete fIntervalPatterns;
602c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
603c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
604c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
605c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruU_CDECL_BEGIN
606c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
607c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru/**
608c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru * set hash table value comparator
609c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru *
610c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru * @param val1  one value in comparison
611c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru * @param val2  the other value in comparison
612c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru * @return      TRUE if 2 values are the same, FALSE otherwise
613c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru */
61450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool U_CALLCONV dtitvinfHashTableValueComparator(UHashTok val1, UHashTok val2);
615c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
61650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool
617b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CALLCONV dtitvinfHashTableValueComparator(UHashTok val1, UHashTok val2) {
618c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const UnicodeString* pattern1 = (UnicodeString*)val1.pointer;
619c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const UnicodeString* pattern2 = (UnicodeString*)val2.pointer;
620c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UBool ret = TRUE;
621c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int8_t i;
62250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    for ( i = 0; i < DateIntervalInfo::kMaxIntervalPatternIndex && ret == TRUE; ++i ) {
623c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        ret = (pattern1[i] == pattern2[i]);
624c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
625c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return ret;
626c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
627c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
62850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CDECL_END
629c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
630c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
631c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruHashtable*
632c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::initHash(UErrorCode& status) {
633c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( U_FAILURE(status) ) {
634c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return NULL;
635c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
636c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    Hashtable* hTable;
63750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if ( (hTable = new Hashtable(FALSE, status)) == NULL ) {
638c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        status = U_MEMORY_ALLOCATION_ERROR;
639c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return NULL;
640c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
641b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if ( U_FAILURE(status) ) {
642b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        delete hTable;
643b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return NULL;
644b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
64550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    hTable->setValueComparator(dtitvinfHashTableValueComparator);
646c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return hTable;
647c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
648c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
649c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
650c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid
651c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruDateIntervalInfo::copyHash(const Hashtable* source,
652c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                           Hashtable* target,
653c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                           UErrorCode& status) {
654c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( U_FAILURE(status) ) {
655c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return;
656c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
6571b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    int32_t pos = UHASH_FIRST;
658c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const UHashElement* element = NULL;
659c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ( source ) {
660c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        while ( (element = source->nextElement(pos)) != NULL ) {
661c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            const UHashTok keyTok = element->key;
662c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            const UnicodeString* key = (UnicodeString*)keyTok.pointer;
663c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            const UHashTok valueTok = element->value;
664c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            const UnicodeString* value = (UnicodeString*)valueTok.pointer;
665c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            UnicodeString* copy = new UnicodeString[kIPI_MAX_INDEX];
666c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            int8_t i;
667c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            for ( i = 0; i < kIPI_MAX_INDEX; ++i ) {
668c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                copy[i] = value[i];
669c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            }
670c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            target->put(UnicodeString(*key), copy, status);
671c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            if ( U_FAILURE(status) ) {
672c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                return;
673c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            }
674c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
675c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
676c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
677c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
678c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
679c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruU_NAMESPACE_END
680c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
681c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#endif
682