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