Home | History | Annotate | Download | only in i18n
      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