1/*
2 *******************************************************************************
3 * Copyright (C) 2011-2013, 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
28U_NAMESPACE_BEGIN
29
30/*
31 * ZNStringPool    Pool of (UChar *) strings.  Provides for sharing of repeated
32 *                 zone strings.
33 */
34struct ZNStringPoolChunk;
35class 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 */
70struct 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
95inline UBool CharacterNode::hasValues() const {
96    return (UBool)(fValues != NULL);
97}
98
99inline int32_t CharacterNode::countValues() const {
100    return
101        fValues == NULL ? 0 :
102        !fHasValuesVector ? 1 :
103        ((const UVector *)fValues)->size();
104}
105
106inline 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 */
117class TextTrieMapSearchResultHandler : public UMemory {
118public:
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 */
128class U_I18N_API TextTrieMap : public UMemory {
129public:
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
139private:
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
161class ZNames;
162class TZNames;
163class TextTrieMap;
164
165class TimeZoneNamesImpl : public TimeZoneNames {
166public:
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
189private:
190
191    Locale fLocale;
192
193    UResourceBundle* fZoneStrings;
194
195    UHashtable* fTZNamesMap;
196    UHashtable* fMZNamesMap;
197
198    UBool fNamesTrieFullyLoaded;
199    TextTrieMap fNamesTrie;
200
201    void initialize(const Locale& locale, UErrorCode& status);
202    void cleanup();
203
204    void loadStrings(const UnicodeString& tzCanonicalID);
205
206    ZNames* loadMetaZoneNames(const UnicodeString& mzId);
207    TZNames* loadTimeZoneNames(const UnicodeString& mzId);
208};
209
210U_NAMESPACE_END
211
212#endif /* #if !UCONFIG_NO_FORMATTING */
213
214#endif // __TZNAMES_IMPL_H__
215//eof
216//
217