]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/zstrfmt.h
ICU-400.38.tar.gz
[apple/icu.git] / icuSources / i18n / zstrfmt.h
CommitLineData
46f4442e
A
1/*
2*******************************************************************************
3* Copyright (C) 2007-2008, International Business Machines Corporation and *
4* others. All Rights Reserved. *
5*******************************************************************************
6*/
7#ifndef ZSTRFMT_H
8#define ZSTRFMT_H
9
10#include "unicode/utypes.h"
11
12#if !UCONFIG_NO_FORMATTING
13
14#include "unicode/unistr.h"
15#include "unicode/calendar.h"
16#include "hash.h"
17#include "uvector.h"
18
19U_NAMESPACE_BEGIN
20
21/*
22 * Character node used by TextTrieMap
23 */
24struct CharacterNode {
25 // No constructor or destructor.
26 // We malloc and free an uninitalized array of CharacterNode objects
27 // and clear and delete them ourselves.
28
29 void clear();
30 void deleteValues();
31
32 void addValue(void *value, UErrorCode &status);
33 inline UBool hasValues() const;
34 inline int32_t countValues() const;
35 inline const void *getValue(int32_t index) const;
36
37 void *fValues; // Union of one single value vs. UVector of values.
38 UChar fCharacter; // UTF-16 code unit.
39 uint16_t fFirstChild; // 0 if no children.
40 uint16_t fNextSibling; // 0 terminates the list.
41 UBool fHasValuesVector;
42 UBool fPadding;
43
44 // No value: fValues == NULL and fHasValuesVector == FALSE
45 // One value: fValues == value and fHasValuesVector == FALSE
46 // >=2 values: fValues == UVector of values and fHasValuesVector == TRUE
47};
48
49inline UBool CharacterNode::hasValues() const {
50 return (UBool)(fValues != NULL);
51}
52
53inline int32_t CharacterNode::countValues() const {
54 return
55 fValues == NULL ? 0 :
56 !fHasValuesVector ? 1 :
57 ((const UVector *)fValues)->size();
58}
59
60inline const void *CharacterNode::getValue(int32_t index) const {
61 if (!fHasValuesVector) {
62 return fValues; // Assume index == 0.
63 } else {
64 return ((const UVector *)fValues)->elementAt(index);
65 }
66}
67
68/*
69 * Search result handler callback interface used by TextTrieMap search.
70 */
71class TextTrieMapSearchResultHandler : public UMemory {
72public:
73 virtual UBool handleMatch(int32_t matchLength,
74 const CharacterNode *node, UErrorCode& status) = 0;
75 virtual ~TextTrieMapSearchResultHandler(); //added to avoid warning
76};
77
78/**
79 * TextTrieMap is a trie implementation for supporting
80 * fast prefix match for the string key.
81 */
82class TextTrieMap : public UMemory {
83public:
84 TextTrieMap(UBool ignoreCase);
85 virtual ~TextTrieMap();
86
87 void put(const UnicodeString &key, void *value, UErrorCode &status);
88 void search(const UnicodeString &text, int32_t start,
89 TextTrieMapSearchResultHandler *handler, UErrorCode& status) const;
90 inline int32_t isEmpty() const;
91
92private:
93 UBool fIgnoreCase;
94 CharacterNode *fNodes;
95 int32_t fNodesCapacity;
96 int32_t fNodesCount;
97
98 UBool growNodes();
99 CharacterNode* addChildNode(CharacterNode *parent, UChar c, UErrorCode &status);
100 CharacterNode* getChildNode(CharacterNode *parent, UChar c) const;
101
102 void search(CharacterNode *node, const UnicodeString &text, int32_t start,
103 int32_t index, TextTrieMapSearchResultHandler *handler, UErrorCode &status) const;
104};
105
106inline UChar32 TextTrieMap::isEmpty(void) const {
107 return fNodes == NULL;
108}
109
110// Name types, these bit flag are used for zone string lookup
111enum TimeZoneTranslationType {
112 LOCATION = 0x0001,
113 GENERIC_LONG = 0x0002,
114 GENERIC_SHORT = 0x0004,
115 STANDARD_LONG = 0x0008,
116 STANDARD_SHORT = 0x0010,
117 DAYLIGHT_LONG = 0x0020,
118 DAYLIGHT_SHORT = 0x0040
119};
120
121// Name type index, these constants are used for index in the zone strings array.
122enum TimeZoneTranslationTypeIndex {
123 ZSIDX_LOCATION = 0,
124 ZSIDX_LONG_STANDARD,
125 ZSIDX_SHORT_STANDARD,
126 ZSIDX_LONG_DAYLIGHT,
127 ZSIDX_SHORT_DAYLIGHT,
128 ZSIDX_LONG_GENERIC,
129 ZSIDX_SHORT_GENERIC,
130
131 ZSIDX_COUNT
132};
133
134class MessageFormat;
135
136/*
137 * ZoneStringInfo is a class holding a localized zone string
138 * information.
139 */
140class ZoneStringInfo : public UMemory {
141public:
142 virtual ~ZoneStringInfo();
143
144 inline UnicodeString& getID(UnicodeString &result) const;
145 inline UnicodeString& getString(UnicodeString &result) const;
146 inline UBool isStandard(void) const;
147 inline UBool isDaylight(void) const;
148 inline UBool isGeneric(void) const;
149
150private:
151 friend class ZoneStringFormat;
152 friend class ZoneStringSearchResultHandler;
153
154 ZoneStringInfo(const UnicodeString &id, const UnicodeString &str, TimeZoneTranslationType type);
155
156 UnicodeString fId;
157 UnicodeString fStr;
158 TimeZoneTranslationType fType;
159};
160
161inline UnicodeString& ZoneStringInfo::getID(UnicodeString &result) const {
162 return result.setTo(fId);
163}
164
165inline UnicodeString& ZoneStringInfo::getString(UnicodeString &result) const {
166 return result.setTo(fStr);
167}
168
169inline UBool ZoneStringInfo::isStandard(void) const {
170 return (fType == STANDARD_LONG || fType == STANDARD_SHORT);
171}
172
173inline UBool ZoneStringInfo::isDaylight(void) const {
174 return (fType == DAYLIGHT_LONG || fType == DAYLIGHT_SHORT);
175}
176
177inline UBool ZoneStringInfo::isGeneric(void) const {
178 return (fType == LOCATION || fType == GENERIC_LONG || fType == GENERIC_SHORT);
179}
180
181class SafeZoneStringFormatPtr;
182
183class ZoneStringFormat : public UMemory {
184public:
185 ZoneStringFormat(const UnicodeString* const* strings, int32_t rowCount, int32_t columnCount, UErrorCode &status);
186 ZoneStringFormat(const Locale& locale, UErrorCode &status);
187 virtual ~ZoneStringFormat();
188
189 static SafeZoneStringFormatPtr* getZoneStringFormat(const Locale& locale, UErrorCode &status);
190
191 /*
192 * Create a snapshot of old zone strings array for the given date
193 */
194 UnicodeString** createZoneStringsArray(UDate date, int32_t &rowCount, int32_t &colCount, UErrorCode &status) const;
195
196 const UnicodeString** getZoneStrings(int32_t &rowCount, int32_t &columnCount) const;
197
198 UnicodeString& getSpecificLongString(const Calendar &cal,
199 UnicodeString &result, UErrorCode &status) const;
200
201 UnicodeString& getSpecificShortString(const Calendar &cal,
202 UBool commonlyUsedOnly, UnicodeString &result, UErrorCode &status) const;
203
204 UnicodeString& getGenericLongString(const Calendar &cal,
205 UnicodeString &result, UErrorCode &status) const;
206
207 UnicodeString& getGenericShortString(const Calendar &cal,
208 UBool commonlyUsedOnly, UnicodeString &result, UErrorCode &status) const;
209
210 UnicodeString& getGenericLocationString(const Calendar &cal,
211 UnicodeString &result, UErrorCode &status) const;
212
213 const ZoneStringInfo* findSpecificLong(const UnicodeString &text, int32_t start,
214 int32_t &matchLength, UErrorCode &status) const;
215 const ZoneStringInfo* findSpecificShort(const UnicodeString &text, int32_t start,
216 int32_t &matchLength, UErrorCode &status) const;
217 const ZoneStringInfo* findGenericLong(const UnicodeString &text, int32_t start,
218 int32_t &matchLength, UErrorCode &status) const;
219 const ZoneStringInfo* findGenericShort(const UnicodeString &text, int32_t start,
220 int32_t &matchLength, UErrorCode &status) const;
221 const ZoneStringInfo* findGenericLocation(const UnicodeString &text, int32_t start,
222 int32_t &matchLength, UErrorCode &status) const;
223
224 // Following APIs are not used by SimpleDateFormat, but public for testing purpose
225 inline UnicodeString& getLongStandard(const UnicodeString &tzid, UDate date,
226 UnicodeString &result) const;
227 inline UnicodeString& getLongDaylight(const UnicodeString &tzid, UDate date,
228 UnicodeString &result) const;
229 inline UnicodeString& getLongGenericNonLocation(const UnicodeString &tzid, UDate date,
230 UnicodeString &result) const;
231 inline UnicodeString& getLongGenericPartialLocation(const UnicodeString &tzid, UDate date,
232 UnicodeString &result) const;
233 inline UnicodeString& getShortStandard(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
234 UnicodeString &result) const;
235 inline UnicodeString& getShortDaylight(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
236 UnicodeString &result) const;
237 inline UnicodeString& getShortGenericNonLocation(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
238 UnicodeString &result) const;
239 inline UnicodeString& getShortGenericPartialLocation(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
240 UnicodeString &result) const;
241 inline UnicodeString& getGenericLocation(const UnicodeString &tzid, UnicodeString &result) const;
242
243private:
244 Locale fLocale;
245 Hashtable fTzidToStrings;
246 Hashtable fMzidToStrings;
247 TextTrieMap fZoneStringsTrie;
248
249 /*
250 * Private method to get a zone string except generic partial location types.
251 */
252 UnicodeString& getString(const UnicodeString &tzid, TimeZoneTranslationTypeIndex typeIdx, UDate date,
253 UBool commonlyUsedOnly, UnicodeString& result) const;
254
255 /*
256 * Private method to get a generic string, with fallback logic involved,
257 * that is,
258 *
259 * 1. If a generic non-location string is avaiable for the zone, return it.
260 * 2. If a generic non-location string is associated with a metazone and
261 * the zone never use daylight time around the given date, use the standard
262 * string (if available).
263 *
264 * Note: In CLDR1.5.1, the same localization is used for generic and standard.
265 * In this case, we do not use the standard string and do the rest.
266 *
267 * 3. If a generic non-location string is associated with a metazone and
268 * the offset at the given time is different from the preferred zone for the
269 * current locale, then return the generic partial location string (if avaiable)
270 * 4. If a generic non-location string is not available, use generic location
271 * string.
272 */
273 UnicodeString& getGenericString(const Calendar &cal, UBool isShort, UBool commonlyUsedOnly,
274 UnicodeString &result, UErrorCode &status) const;
275
276 /*
277 * Private method to get a generic partial location string
278 */
279 UnicodeString& getGenericPartialLocationString(const UnicodeString &tzid, UBool isShort,
280 UDate date, UBool commonlyUsedOnly, UnicodeString &result) const;
281
282 /*
283 * Find a prefix matching time zone for the given zone string types.
284 * @param text The text contains a time zone string
285 * @param start The start index within the text
286 * @param types The bit mask representing a set of requested types
287 * @param matchLength Receives the match length
288 * @param status
289 * @return If any zone string matched for the requested types, returns a
290 * ZoneStringInfo for the longest match. If no matches are found for
291 * the requested types, returns a ZoneStringInfo for the longest match
292 * for any other types. If nothing matches at all, returns null.
293 */
294 const ZoneStringInfo* find(const UnicodeString &text, int32_t start, int32_t types,
295 int32_t &matchLength, UErrorCode &status) const;
296
297 UnicodeString& getRegion(UnicodeString &region) const;
298
299 static MessageFormat* getFallbackFormat(const Locale &locale, UErrorCode &status);
300 static MessageFormat* getRegionFormat(const Locale &locale, UErrorCode &status);
301 static const UChar* getZoneStringFromBundle(const UResourceBundle *zoneitem, const char *key);
302 static UBool isCommonlyUsed(const UResourceBundle *zoneitem);
303 static UnicodeString& getLocalizedCountry(const UnicodeString &countryCode, const Locale &locale,
304 UnicodeString &displayCountry);
305};
306
307inline UnicodeString&
308ZoneStringFormat::getLongStandard(const UnicodeString &tzid, UDate date,
309 UnicodeString &result) const {
310 return getString(tzid, ZSIDX_LONG_STANDARD, date, FALSE /* not used */, result);
311}
312
313inline UnicodeString&
314ZoneStringFormat::getLongDaylight(const UnicodeString &tzid, UDate date,
315 UnicodeString &result) const {
316 return getString(tzid, ZSIDX_LONG_DAYLIGHT, date, FALSE /* not used */, result);
317}
318
319inline UnicodeString&
320ZoneStringFormat::getLongGenericNonLocation(const UnicodeString &tzid, UDate date,
321 UnicodeString &result) const {
322 return getString(tzid, ZSIDX_LONG_GENERIC, date, FALSE /* not used */, result);
323}
324
325inline UnicodeString&
326ZoneStringFormat::getLongGenericPartialLocation(const UnicodeString &tzid, UDate date,
327 UnicodeString &result) const {
328 return getGenericPartialLocationString(tzid, FALSE, date, FALSE /* not used */, result);
329}
330
331inline UnicodeString&
332ZoneStringFormat::getShortStandard(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
333 UnicodeString &result) const {
334 return getString(tzid, ZSIDX_SHORT_STANDARD, date, commonlyUsedOnly, result);
335}
336
337inline UnicodeString&
338ZoneStringFormat::getShortDaylight(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
339 UnicodeString &result) const {
340 return getString(tzid, ZSIDX_SHORT_DAYLIGHT, date, commonlyUsedOnly, result);
341}
342
343inline UnicodeString&
344ZoneStringFormat::getShortGenericNonLocation(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
345 UnicodeString &result) const {
346 return getString(tzid, ZSIDX_SHORT_GENERIC, date, commonlyUsedOnly, result);
347}
348
349inline UnicodeString&
350ZoneStringFormat::getShortGenericPartialLocation(const UnicodeString &tzid, UDate date, UBool commonlyUsedOnly,
351 UnicodeString &result) const {
352 return getGenericPartialLocationString(tzid, TRUE, date, commonlyUsedOnly, result);
353}
354
355inline UnicodeString&
356ZoneStringFormat::getGenericLocation(const UnicodeString &tzid, UnicodeString &result) const {
357 return getString(tzid, ZSIDX_LOCATION, 0 /*not used*/, FALSE /*not used*/, result);
358}
359
360
361/*
362 * ZooneStrings is a container of localized zone strings used by ZoneStringFormat
363 */
364class ZoneStrings : public UMemory {
365public:
366 ZoneStrings(UnicodeString *strings, int32_t stringsCount, UBool commonlyUsed,
367 UnicodeString **genericPartialLocationStrings, int32_t genericRowCount, int32_t genericColCount);
368 virtual ~ZoneStrings();
369
370 UnicodeString& getString(int32_t typeIdx, UnicodeString &result) const;
371 inline UBool isShortFormatCommonlyUsed(void) const;
372 UnicodeString& getGenericPartialLocationString(const UnicodeString &mzid, UBool isShort,
373 UBool commonlyUsedOnly, UnicodeString &result) const;
374
375private:
376 UnicodeString *fStrings;
377 int32_t fStringsCount;
378 UBool fIsCommonlyUsed;
379 UnicodeString **fGenericPartialLocationStrings;
380 int32_t fGenericPartialLocationRowCount;
381 int32_t fGenericPartialLocationColCount;
382};
383
384inline UBool
385ZoneStrings::isShortFormatCommonlyUsed(void) const {
386 return fIsCommonlyUsed;
387}
388
389/*
390 * ZoneStringSearchResultHandler is an implementation of
391 * TextTrieMapSearchHandler. This class is used by ZoneStringFormat
392 * for collecting search results for localized zone strings.
393 */
394class ZoneStringSearchResultHandler : public TextTrieMapSearchResultHandler {
395public:
396 ZoneStringSearchResultHandler(UErrorCode &status);
397 virtual ~ZoneStringSearchResultHandler();
398
399 virtual UBool handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status);
400 int32_t countMatches(void);
401 const ZoneStringInfo* getMatch(int32_t index, int32_t &matchLength);
402 void clear(void);
403
404private:
405 UVector fResults;
406 int32_t fMatchLen[ZSIDX_COUNT];
407};
408
409
410/*
411 * ZoneStringFormat cache implementation
412 */
413class ZSFCacheEntry : public UMemory {
414public:
415 ~ZSFCacheEntry();
416
417 void delRef(void);
418 const ZoneStringFormat* getZoneStringFormat(void);
419
420private:
421 friend class ZSFCache;
422
423 ZSFCacheEntry(const Locale &locale, ZoneStringFormat *zsf, ZSFCacheEntry *next);
424
425 Locale fLocale;
426 ZoneStringFormat *fZoneStringFormat;
427 ZSFCacheEntry *fNext;
428 int32_t fRefCount;
429};
430
431class SafeZoneStringFormatPtr : public UMemory {
432public:
433 ~SafeZoneStringFormatPtr();
434 const ZoneStringFormat* get() const;
435
436private:
437 friend class ZSFCache;
438
439 SafeZoneStringFormatPtr(ZSFCacheEntry *cacheEntry);
440
441 ZSFCacheEntry *fCacheEntry;
442};
443
444class ZSFCache : public UMemory {
445public:
446 ZSFCache(int32_t capacity);
447 ~ZSFCache();
448
449 SafeZoneStringFormatPtr* get(const Locale &locale, UErrorCode &status);
450
451private:
452 int32_t fCapacity;
453 ZSFCacheEntry *fFirst;
454};
455
456U_NAMESPACE_END
457
458#endif /* #if !UCONFIG_NO_FORMATTING */
459
460#endif // ZSTRFMT_H