tznames_impl.h 9.4 KB

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