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