| /* | 
 | ********************************************************************** | 
 | *   Copyright (c) 2001, International Business Machines | 
 | *   Corporation and others.  All Rights Reserved. | 
 | ********************************************************************** | 
 | *   Date        Name        Description | 
 | *   08/10/2001  aliu        Creation. | 
 | ********************************************************************** | 
 | */ | 
 | #ifndef _TRANSREG_H | 
 | #define _TRANSREG_H | 
 |  | 
 | #include "unicode/utypes.h" | 
 |  | 
 | #if !UCONFIG_NO_TRANSLITERATION | 
 |  | 
 | #include "unicode/uobject.h" | 
 | #include "unicode/translit.h" | 
 | #include "hash.h" | 
 | #include "uvector.h" | 
 |  | 
 | U_NAMESPACE_BEGIN | 
 |  | 
 | class Entry; | 
 | class Spec; | 
 | class UnicodeString; | 
 |  | 
 | //------------------------------------------------------------------ | 
 | // TransliteratorAlias | 
 | //------------------------------------------------------------------ | 
 |  | 
 | /** | 
 |  * A TransliteratorAlias object is returned by get() if the given ID | 
 |  * actually translates into something else.  The caller then invokes | 
 |  * the create() method on the alias to create the actual | 
 |  * transliterator, and deletes the alias. | 
 |  * | 
 |  * Why all the shenanigans?  To prevent circular calls between | 
 |  * the registry code and the transliterator code that deadlocks. | 
 |  */ | 
 | class TransliteratorAlias : public UMemory { | 
 |  public: | 
 |     /** | 
 |      * Construct a simple alias. | 
 |      * @param aliasID the given id. | 
 |      */ | 
 |     TransliteratorAlias(const UnicodeString& aliasID); | 
 |      | 
 |     /** | 
 |      * Construct a compound RBT alias. | 
 |      */ | 
 |     TransliteratorAlias(const UnicodeString& ID, const UnicodeString& idBlock, | 
 |                         Transliterator* adopted, int32_t idSplitPoint, | 
 |                         const UnicodeSet* compoundFilter); | 
 |  | 
 |     ~TransliteratorAlias(); | 
 |      | 
 |     /** | 
 |      * The whole point of create() is that the caller must invoke | 
 |      * it when the registry mutex is NOT held, to prevent deadlock. | 
 |      * It may only be called once. | 
 |      */ | 
 |     Transliterator* create(UParseError&, UErrorCode&); | 
 |      | 
 |  private: | 
 |     // We actually come in two flavors: | 
 |     // 1. Simple alias | 
 |     //    Here aliasID is the alias string.  Everything else is | 
 |     //    null, zero, empty. | 
 |     // 2. CompoundRBT | 
 |     //    Here ID is the ID, aliasID is the idBlock, trans is the | 
 |     //    contained RBT, and idSplitPoint is the offet in aliasID | 
 |     //    where the contained RBT goes.  compoundFilter is the | 
 |     //    compound filter, and it is _not_ owned. | 
 |     UnicodeString ID; | 
 |     UnicodeString aliasID; | 
 |     Transliterator* trans; // owned | 
 |     const UnicodeSet* compoundFilter; // alias | 
 |     int32_t idSplitPoint; | 
 |  | 
 |     TransliteratorAlias(const TransliteratorAlias &other); // forbid copying of this class | 
 |     TransliteratorAlias &operator=(const TransliteratorAlias &other); // forbid copying of this class | 
 | }; | 
 |  | 
 |  | 
 | /** | 
 |  * A registry of system transliterators.  This is the data structure | 
 |  * that implements the mapping between transliterator IDs and the data | 
 |  * or function pointers used to create the corresponding | 
 |  * transliterators.  There is one instance of the registry that is | 
 |  * created statically. | 
 |  * | 
 |  * The registry consists of a dynamic component -- a hashtable -- and | 
 |  * a static component -- locale resource bundles.  The dynamic store | 
 |  * is semantically overlaid on the static store, so the static mapping | 
 |  * can be dynamically overridden. | 
 |  * | 
 |  * This is an internal class that is only used by Transliterator. | 
 |  * Transliterator maintains one static instance of this class and | 
 |  * delegates all registry-related operations to it. | 
 |  * | 
 |  * @author Alan Liu | 
 |  */ | 
 | class TransliteratorRegistry : public UMemory { | 
 |  | 
 |  public: | 
 |  | 
 |     /** | 
 |      * Contructor | 
 |      * @param status Output param set to success/failure code. | 
 |      */ | 
 |     TransliteratorRegistry(UErrorCode& status); | 
 |  | 
 |     /** | 
 |      * Nonvirtual destructor -- this class is not subclassable. | 
 |      */ | 
 |     ~TransliteratorRegistry(); | 
 |  | 
 |     //------------------------------------------------------------------ | 
 |     // Basic public API | 
 |     //------------------------------------------------------------------ | 
 |  | 
 |     /** | 
 |      * Given a simple ID (forward direction, no inline filter, not | 
 |      * compound) attempt to instantiate it from the registry.  Return | 
 |      * 0 on failure. | 
 |      * | 
 |      * Return a non-NULL aliasReturn value if the ID points to an alias. | 
 |      * We cannot instantiate it ourselves because the alias may contain | 
 |      * filters or compounds, which we do not understand.  Caller should | 
 |      * make aliasReturn NULL before calling. | 
 |      * @param ID          the given ID | 
 |      * @param aliasReturn the given TransliteratorAlias | 
 |      * @param parseError  Struct to recieve information on position  | 
 |      *                    of error if an error is encountered | 
 |      * @param status      Output param set to success/failure code. | 
 |      */ | 
 |     Transliterator* get(const UnicodeString& ID, | 
 |                         TransliteratorAlias*& aliasReturn, | 
 |                         UParseError& parseError, | 
 |                         UErrorCode& status); | 
 |  | 
 |     /** | 
 |      * Register a prototype (adopted).  This adds an entry to the | 
 |      * dynamic store, or replaces an existing entry.  Any entry in the | 
 |      * underlying static locale resource store is masked. | 
 |      */ | 
 |     void put(Transliterator* adoptedProto, | 
 |              UBool visible); | 
 |  | 
 |     /** | 
 |      * Register an ID and a factory function pointer.  This adds an | 
 |      * entry to the dynamic store, or replaces an existing entry.  Any | 
 |      * entry in the underlying static locale resource store is masked. | 
 |      */ | 
 |     void put(const UnicodeString& ID, | 
 |              Transliterator::Factory factory, | 
 |              Transliterator::Token context, | 
 |              UBool visible); | 
 |  | 
 |     /** | 
 |      * Register an ID and a resource name.  This adds an entry to the | 
 |      * dynamic store, or replaces an existing entry.  Any entry in the | 
 |      * underlying static locale resource store is masked. | 
 |      */ | 
 |     void put(const UnicodeString& ID, | 
 |              const UnicodeString& resourceName, | 
 |              UTransDirection dir, | 
 |              UBool visible); | 
 |  | 
 |     /** | 
 |      * Register an ID and an alias ID.  This adds an entry to the | 
 |      * dynamic store, or replaces an existing entry.  Any entry in the | 
 |      * underlying static locale resource store is masked. | 
 |      */ | 
 |     void put(const UnicodeString& ID, | 
 |              const UnicodeString& alias, | 
 |              UBool visible); | 
 |  | 
 |     /** | 
 |      * Unregister an ID.  This removes an entry from the dynamic store | 
 |      * if there is one.  The static locale resource store is | 
 |      * unaffected. | 
 |      * @param ID    the given ID. | 
 |      */ | 
 |     void remove(const UnicodeString& ID); | 
 |  | 
 |     //------------------------------------------------------------------ | 
 |     // Public ID and spec management | 
 |     //------------------------------------------------------------------ | 
 |  | 
 |     /** | 
 |      * Return the number of IDs currently registered with the system. | 
 |      * To retrieve the actual IDs, call getAvailableID(i) with | 
 |      * i from 0 to countAvailableIDs() - 1. | 
 |      * @return the number of IDs currently registered with the system. | 
 |      * @internal | 
 |      */ | 
 |     int32_t countAvailableIDs(void); | 
 |  | 
 |     /** | 
 |      * Return the index-th available ID.  index must be between 0 | 
 |      * and countAvailableIDs() - 1, inclusive.  If index is out of | 
 |      * range, the result of getAvailableID(0) is returned. | 
 |      * @param index the given index. | 
 |      * @return the index-th available ID.  index must be between 0 | 
 |      *         and countAvailableIDs() - 1, inclusive.  If index is out of | 
 |      *         range, the result of getAvailableID(0) is returned. | 
 |      * @internal | 
 |      */ | 
 |     const UnicodeString& getAvailableID(int32_t index); | 
 |  | 
 |     /** | 
 |      * Return the number of registered source specifiers. | 
 |      * @return the number of registered source specifiers. | 
 |      */ | 
 |     int32_t countAvailableSources(void); | 
 |      | 
 |     /** | 
 |      * Return a registered source specifier. | 
 |      * @param index which specifier to return, from 0 to n-1, where | 
 |      * n = countAvailableSources() | 
 |      * @param result fill-in paramter to receive the source specifier. | 
 |      * If index is out of range, result will be empty. | 
 |      * @return reference to result | 
 |      */ | 
 |     UnicodeString& getAvailableSource(int32_t index, | 
 |                                       UnicodeString& result); | 
 |      | 
 |     /** | 
 |      * Return the number of registered target specifiers for a given | 
 |      * source specifier. | 
 |      * @param source the given source specifier. | 
 |      * @return the number of registered target specifiers for a given | 
 |      *         source specifier. | 
 |      */ | 
 |     int32_t countAvailableTargets(const UnicodeString& source); | 
 |      | 
 |     /** | 
 |      * Return a registered target specifier for a given source. | 
 |      * @param index which specifier to return, from 0 to n-1, where | 
 |      * n = countAvailableTargets(source) | 
 |      * @param source the source specifier | 
 |      * @param result fill-in paramter to receive the target specifier. | 
 |      * If source is invalid or if index is out of range, result will | 
 |      * be empty. | 
 |      * @return reference to result | 
 |      */ | 
 |     UnicodeString& getAvailableTarget(int32_t index, | 
 |                                       const UnicodeString& source, | 
 |                                       UnicodeString& result); | 
 |      | 
 |     /** | 
 |      * Return the number of registered variant specifiers for a given | 
 |      * source-target pair.  There is always at least one variant: If | 
 |      * just source-target is registered, then the single variant | 
 |      * NO_VARIANT is returned.  If source-target/variant is registered | 
 |      * then that variant is returned. | 
 |      * @param source the source specifiers | 
 |      * @param target the target specifiers | 
 |      * @return the number of registered variant specifiers for a given | 
 |      *         source-target pair. | 
 |      */ | 
 |     int32_t countAvailableVariants(const UnicodeString& source, | 
 |                                    const UnicodeString& target); | 
 |      | 
 |     /** | 
 |      * Return a registered variant specifier for a given source-target | 
 |      * pair.  If NO_VARIANT is one of the variants, then it will be | 
 |      * at index 0. | 
 |      * @param index which specifier to return, from 0 to n-1, where | 
 |      * n = countAvailableVariants(source, target) | 
 |      * @param source the source specifier | 
 |      * @param target the target specifier | 
 |      * @param result fill-in paramter to receive the variant | 
 |      * specifier.  If source is invalid or if target is invalid or if | 
 |      * index is out of range, result will be empty. | 
 |      * @return reference to result | 
 |      */ | 
 |     UnicodeString& getAvailableVariant(int32_t index, | 
 |                                        const UnicodeString& source, | 
 |                                        const UnicodeString& target, | 
 |                                        UnicodeString& result); | 
 |  | 
 |  private: | 
 |  | 
 |     //---------------------------------------------------------------- | 
 |     // Private implementation | 
 |     //---------------------------------------------------------------- | 
 |  | 
 |     Entry* find(const UnicodeString& ID); | 
 |      | 
 |     Entry* find(UnicodeString& source, | 
 |                 UnicodeString& target, | 
 |                 UnicodeString& variant); | 
 |  | 
 |     Entry* findInDynamicStore(const Spec& src, | 
 |                               const Spec& trg, | 
 |                               const UnicodeString& variant); | 
 |  | 
 |     Entry* findInStaticStore(const Spec& src, | 
 |                              const Spec& trg, | 
 |                              const UnicodeString& variant); | 
 |  | 
 |     static Entry* findInBundle(const Spec& specToOpen, | 
 |                                const Spec& specToFind, | 
 |                                const UnicodeString& variant, | 
 |                                UTransDirection direction); | 
 |  | 
 |     void registerEntry(const UnicodeString& source, | 
 |                        const UnicodeString& target, | 
 |                        const UnicodeString& variant, | 
 |                        Entry* adopted, | 
 |                        UBool visible); | 
 |  | 
 |     void registerEntry(const UnicodeString& ID, | 
 |                        Entry* adopted, | 
 |                        UBool visible); | 
 |  | 
 |    void registerEntry(const UnicodeString& ID, | 
 |                        const UnicodeString& source, | 
 |                        const UnicodeString& target, | 
 |                        const UnicodeString& variant, | 
 |                        Entry* adopted, | 
 |                        UBool visible); | 
 |  | 
 |     void registerSTV(const UnicodeString& source, | 
 |                      const UnicodeString& target, | 
 |                      const UnicodeString& variant); | 
 |  | 
 |     void removeSTV(const UnicodeString& source, | 
 |                    const UnicodeString& target, | 
 |                    const UnicodeString& variant); | 
 |  | 
 |     Transliterator* instantiateEntry(const UnicodeString& ID, | 
 |                                      Entry *entry, | 
 |                                      TransliteratorAlias*& aliasReturn, | 
 |                                      UParseError& parseError, | 
 |                                      UErrorCode& status); | 
 |  | 
 |  private: | 
 |  | 
 |     /** | 
 |      * Dynamic registry mapping full IDs to Entry objects.  This | 
 |      * contains both public and internal entities.  The visibility is | 
 |      * controlled by whether an entry is listed in availableIDs and | 
 |      * specDAG or not. | 
 |      */ | 
 |     Hashtable registry; | 
 |      | 
 |     /** | 
 |      * DAG of visible IDs by spec.  Hashtable: source => (Hashtable: | 
 |      * target => (UVector: variant)) The UVector of variants is never | 
 |      * empty.  For a source-target with no variant, the special | 
 |      * variant NO_VARIANT (the empty string) is stored in slot zero of | 
 |      * the UVector. | 
 |      */ | 
 |     Hashtable specDAG; | 
 |      | 
 |     /** | 
 |      * Vector of public full IDs. | 
 |      */ | 
 |     UVector availableIDs; | 
 |  | 
 |     TransliteratorRegistry(const TransliteratorRegistry &other); // forbid copying of this class | 
 |     TransliteratorRegistry &operator=(const TransliteratorRegistry &other); // forbid copying of this class | 
 | }; | 
 |  | 
 | U_NAMESPACE_END | 
 |  | 
 | #endif /* #if !UCONFIG_NO_TRANSLITERATION */ | 
 |  | 
 | #endif | 
 | //eof |