]>
Commit | Line | Data |
---|---|---|
1 | // © 2016 and later: Unicode, Inc. and others. | |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
3 | /* | |
4 | ******************************************************************************* | |
5 | * Copyright (C) 2011-2016, International Business Machines Corporation and | |
6 | * others. All Rights Reserved. | |
7 | ******************************************************************************* | |
8 | */ | |
9 | ||
10 | #ifndef __TZNAMES_IMPL_H__ | |
11 | #define __TZNAMES_IMPL_H__ | |
12 | ||
13 | ||
14 | /** | |
15 | * \file | |
16 | * \brief C++ API: TimeZoneNames object | |
17 | */ | |
18 | ||
19 | #include "unicode/utypes.h" | |
20 | ||
21 | #if !UCONFIG_NO_FORMATTING | |
22 | ||
23 | #include "unicode/tznames.h" | |
24 | #include "unicode/ures.h" | |
25 | #include "unicode/locid.h" | |
26 | #include "uhash.h" | |
27 | #include "uvector.h" | |
28 | #include "umutex.h" | |
29 | ||
30 | // Some zone display names involving supplementary characters can be over 50 chars, 100 UTF-16 code units, 200 UTF-8 bytes | |
31 | #define ZONE_NAME_U16_MAX 128 | |
32 | ||
33 | U_NAMESPACE_BEGIN | |
34 | ||
35 | /* | |
36 | * ZNStringPool Pool of (UChar *) strings. Provides for sharing of repeated | |
37 | * zone strings. | |
38 | */ | |
39 | struct ZNStringPoolChunk; | |
40 | class U_I18N_API ZNStringPool: public UMemory { | |
41 | public: | |
42 | ZNStringPool(UErrorCode &status); | |
43 | ~ZNStringPool(); | |
44 | ||
45 | /* Get the pooled string that is equal to the supplied string s. | |
46 | * Copy the string into the pool if it is not already present. | |
47 | * | |
48 | * Life time of the returned string is that of the pool. | |
49 | */ | |
50 | const UChar *get(const UChar *s, UErrorCode &status); | |
51 | ||
52 | /* Get the pooled string that is equal to the supplied string s. | |
53 | * Copy the string into the pool if it is not already present. | |
54 | */ | |
55 | const UChar *get(const UnicodeString &s, UErrorCode &status); | |
56 | ||
57 | /* Adopt a string into the pool, without copying it. | |
58 | * Used for strings from resource bundles, which will persist without copying. | |
59 | */ | |
60 | const UChar *adopt(const UChar *s, UErrorCode &status); | |
61 | ||
62 | /* Freeze the string pool. Discards the hash table that is used | |
63 | * for looking up a string. All pointers to pooled strings remain valid. | |
64 | */ | |
65 | void freeze(); | |
66 | ||
67 | private: | |
68 | ZNStringPoolChunk *fChunks; | |
69 | UHashtable *fHash; | |
70 | }; | |
71 | ||
72 | /* | |
73 | * Character node used by TextTrieMap | |
74 | */ | |
75 | struct CharacterNode { | |
76 | // No constructor or destructor. | |
77 | // We malloc and free an uninitalized array of CharacterNode objects | |
78 | // and clear and delete them ourselves. | |
79 | ||
80 | void clear(); | |
81 | void deleteValues(UObjectDeleter *valueDeleter); | |
82 | ||
83 | void addValue(void *value, UObjectDeleter *valueDeleter, UErrorCode &status); | |
84 | inline UBool hasValues() const; | |
85 | inline int32_t countValues() const; | |
86 | inline const void *getValue(int32_t index) const; | |
87 | ||
88 | void *fValues; // Union of one single value vs. UVector of values. | |
89 | UChar fCharacter; // UTF-16 code unit. | |
90 | uint16_t fFirstChild; // 0 if no children. | |
91 | uint16_t fNextSibling; // 0 terminates the list. | |
92 | UBool fHasValuesVector; | |
93 | UBool fPadding; | |
94 | ||
95 | // No value: fValues == NULL and fHasValuesVector == FALSE | |
96 | // One value: fValues == value and fHasValuesVector == FALSE | |
97 | // >=2 values: fValues == UVector of values and fHasValuesVector == TRUE | |
98 | }; | |
99 | ||
100 | inline UBool CharacterNode::hasValues() const { | |
101 | return (UBool)(fValues != NULL); | |
102 | } | |
103 | ||
104 | inline int32_t CharacterNode::countValues() const { | |
105 | return | |
106 | fValues == NULL ? 0 : | |
107 | !fHasValuesVector ? 1 : | |
108 | ((const UVector *)fValues)->size(); | |
109 | } | |
110 | ||
111 | inline const void *CharacterNode::getValue(int32_t index) const { | |
112 | if (!fHasValuesVector) { | |
113 | return fValues; // Assume index == 0. | |
114 | } else { | |
115 | return ((const UVector *)fValues)->elementAt(index); | |
116 | } | |
117 | } | |
118 | ||
119 | /* | |
120 | * Search result handler callback interface used by TextTrieMap search. | |
121 | */ | |
122 | class TextTrieMapSearchResultHandler : public UMemory { | |
123 | public: | |
124 | virtual UBool handleMatch(int32_t matchLength, | |
125 | const CharacterNode *node, UErrorCode& status) = 0; | |
126 | virtual ~TextTrieMapSearchResultHandler(); //added to avoid warning | |
127 | }; | |
128 | ||
129 | /** | |
130 | * TextTrieMap is a trie implementation for supporting | |
131 | * fast prefix match for the string key. | |
132 | */ | |
133 | class U_I18N_API TextTrieMap : public UMemory { | |
134 | public: | |
135 | TextTrieMap(UBool ignoreCase, UObjectDeleter *valeDeleter); | |
136 | virtual ~TextTrieMap(); | |
137 | ||
138 | void put(const UnicodeString &key, void *value, ZNStringPool &sp, UErrorCode &status); | |
139 | void put(const UChar*, void *value, UErrorCode &status); | |
140 | void search(const UnicodeString &text, int32_t start, | |
141 | TextTrieMapSearchResultHandler *handler, UErrorCode& status) const; | |
142 | int32_t isEmpty() const; | |
143 | ||
144 | private: | |
145 | UBool fIgnoreCase; | |
146 | CharacterNode *fNodes; | |
147 | int32_t fNodesCapacity; | |
148 | int32_t fNodesCount; | |
149 | ||
150 | UVector *fLazyContents; | |
151 | UBool fIsEmpty; | |
152 | UObjectDeleter *fValueDeleter; | |
153 | ||
154 | UBool growNodes(); | |
155 | CharacterNode* addChildNode(CharacterNode *parent, UChar c, UErrorCode &status); | |
156 | CharacterNode* getChildNode(CharacterNode *parent, UChar c) const; | |
157 | ||
158 | void putImpl(const UnicodeString &key, void *value, UErrorCode &status); | |
159 | void buildTrie(UErrorCode &status); | |
160 | void search(CharacterNode *node, const UnicodeString &text, int32_t start, | |
161 | int32_t index, TextTrieMapSearchResultHandler *handler, UErrorCode &status) const; | |
162 | }; | |
163 | ||
164 | ||
165 | ||
166 | class ZNames; | |
167 | class TextTrieMap; | |
168 | class ZNameSearchHandler; | |
169 | ||
170 | class TimeZoneNamesImpl : public TimeZoneNames { | |
171 | public: | |
172 | TimeZoneNamesImpl(const Locale& locale, UErrorCode& status); | |
173 | ||
174 | virtual ~TimeZoneNamesImpl(); | |
175 | ||
176 | virtual UBool operator==(const TimeZoneNames& other) const; | |
177 | virtual TimeZoneNames* clone() const; | |
178 | ||
179 | StringEnumeration* getAvailableMetaZoneIDs(UErrorCode& status) const; | |
180 | StringEnumeration* getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const; | |
181 | ||
182 | UnicodeString& getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const; | |
183 | UnicodeString& getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const; | |
184 | ||
185 | UnicodeString& getMetaZoneDisplayName(const UnicodeString& mzID, UTimeZoneNameType type, UnicodeString& name) const; | |
186 | UnicodeString& getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, UnicodeString& name) const; | |
187 | ||
188 | UnicodeString& getExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) const; | |
189 | ||
190 | TimeZoneNames::MatchInfoCollection* find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const; | |
191 | ||
192 | void loadAllDisplayNames(UErrorCode& status); | |
193 | void getDisplayNames(const UnicodeString& tzID, const UTimeZoneNameType types[], int32_t numTypes, UDate date, UnicodeString dest[], UErrorCode& status) const; | |
194 | ||
195 | static UnicodeString& getDefaultExemplarLocationName(const UnicodeString& tzID, UnicodeString& name); | |
196 | ||
197 | static StringEnumeration* _getAvailableMetaZoneIDs(UErrorCode& status); | |
198 | static StringEnumeration* _getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status); | |
199 | static UnicodeString& _getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID); | |
200 | static UnicodeString& _getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID); | |
201 | ||
202 | private: | |
203 | ||
204 | Locale fLocale; | |
205 | ||
206 | UResourceBundle* fZoneStrings; | |
207 | ||
208 | UHashtable* fTZNamesMap; | |
209 | UHashtable* fMZNamesMap; | |
210 | ||
211 | UBool fNamesTrieFullyLoaded; | |
212 | UBool fNamesFullyLoaded; | |
213 | TextTrieMap fNamesTrie; | |
214 | ||
215 | void initialize(const Locale& locale, UErrorCode& status); | |
216 | void cleanup(); | |
217 | ||
218 | void loadStrings(const UnicodeString& tzCanonicalID, UErrorCode& status); | |
219 | ||
220 | ZNames* loadMetaZoneNames(const UnicodeString& mzId, UErrorCode& status); | |
221 | ZNames* loadTimeZoneNames(const UnicodeString& mzId, UErrorCode& status); | |
222 | TimeZoneNames::MatchInfoCollection* doFind(ZNameSearchHandler& handler, | |
223 | const UnicodeString& text, int32_t start, UErrorCode& status) const; | |
224 | void addAllNamesIntoTrie(UErrorCode& errorCode); | |
225 | ||
226 | void internalLoadAllDisplayNames(UErrorCode& status); | |
227 | ||
228 | struct ZoneStringsLoader; | |
229 | }; | |
230 | ||
231 | class TZDBNames; | |
232 | ||
233 | class TZDBTimeZoneNames : public TimeZoneNames { | |
234 | public: | |
235 | TZDBTimeZoneNames(const Locale& locale); | |
236 | virtual ~TZDBTimeZoneNames(); | |
237 | ||
238 | virtual UBool operator==(const TimeZoneNames& other) const; | |
239 | virtual TimeZoneNames* clone() const; | |
240 | ||
241 | StringEnumeration* getAvailableMetaZoneIDs(UErrorCode& status) const; | |
242 | StringEnumeration* getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const; | |
243 | ||
244 | UnicodeString& getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const; | |
245 | UnicodeString& getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const; | |
246 | ||
247 | UnicodeString& getMetaZoneDisplayName(const UnicodeString& mzID, UTimeZoneNameType type, UnicodeString& name) const; | |
248 | UnicodeString& getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, UnicodeString& name) const; | |
249 | ||
250 | TimeZoneNames::MatchInfoCollection* find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const; | |
251 | ||
252 | // When TZDBNames for the metazone is not available, this method returns NULL, | |
253 | // but does NOT set U_MISSING_RESOURCE_ERROR to status. | |
254 | static const TZDBNames* getMetaZoneNames(const UnicodeString& mzId, UErrorCode& status); | |
255 | ||
256 | private: | |
257 | Locale fLocale; | |
258 | char fRegion[ULOC_COUNTRY_CAPACITY]; | |
259 | }; | |
260 | ||
261 | U_NAMESPACE_END | |
262 | ||
263 | #endif /* #if !UCONFIG_NO_FORMATTING */ | |
264 | ||
265 | #endif // __TZNAMES_IMPL_H__ | |
266 | //eof | |
267 | // |