Home | History | Annotate | Download | only in i18n
      1 /*
      2  *******************************************************************************
      3  * Copyright (C) 2011, 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 "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 
     95 inline UBool CharacterNode::hasValues() const {
     96     return (UBool)(fValues != NULL);
     97 }
     98 
     99 inline int32_t CharacterNode::countValues() const {
    100     return
    101         fValues == NULL ? 0 :
    102         !fHasValuesVector ? 1 :
    103         ((const UVector *)fValues)->size();
    104 }
    105 
    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     StringEnumeration* getAvailableMetaZoneIDs(UErrorCode& status) const;
    172     StringEnumeration* getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const;
    173 
    174     UnicodeString& getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const;
    175     UnicodeString& getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const;
    176 
    177     UnicodeString& getMetaZoneDisplayName(const UnicodeString& mzID, UTimeZoneNameType type, UnicodeString& name) const;
    178     UnicodeString& getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, UnicodeString& name) const;
    179 
    180     UnicodeString& getExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) const;
    181 
    182     TimeZoneNameMatchInfo* find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const;
    183 
    184 private:
    185 
    186     Locale fLocale;
    187     UMTX fLock;
    188 
    189     UResourceBundle* fZoneStrings;
    190 
    191     UHashtable* fTZNamesMap;
    192     UHashtable* fMZNamesMap;
    193 
    194     UBool fNamesTrieFullyLoaded;
    195     TextTrieMap fNamesTrie;
    196 
    197     void initialize(const Locale& locale, UErrorCode& status);
    198     void cleanup();
    199 
    200     void loadStrings(const UnicodeString& tzCanonicalID);
    201 
    202     ZNames* loadMetaZoneNames(const UnicodeString& mzId);
    203     TZNames* loadTimeZoneNames(const UnicodeString& mzId);
    204 };
    205 
    206 U_NAMESPACE_END
    207 
    208 #endif /* #if !UCONFIG_NO_FORMATTING */
    209 
    210 #endif // __TZNAMES_IMPL_H__
    211 //eof
    212 //
    213