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