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 // 268