+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
/*
**********************************************************************
-* Copyright (c) 2001, International Business Machines
+* Copyright (c) 2001-2016 International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
* Date Name Description
U_NAMESPACE_BEGIN
-class Entry;
-class Spec;
+class TransliteratorEntry;
+class TransliteratorSpec;
class UnicodeString;
//------------------------------------------------------------------
class TransliteratorAlias : public UMemory {
public:
/**
- * Construct a simple alias.
+ * Construct a simple alias (type == SIMPLE)
* @param aliasID the given id.
*/
- TransliteratorAlias(const UnicodeString& aliasID);
-
+ TransliteratorAlias(const UnicodeString& aliasID, const UnicodeSet* compoundFilter);
+
/**
- * Construct a compound RBT alias.
+ * Construct a compound RBT alias (type == COMPOUND)
*/
- TransliteratorAlias(const UnicodeString& ID, const UnicodeString& idBlock,
- Transliterator* adopted, int32_t idSplitPoint,
+ TransliteratorAlias(const UnicodeString& ID, const UnicodeString& idBlocks,
+ UVector* adoptedTransliterators,
const UnicodeSet* compoundFilter);
+ /**
+ * Construct a rules alias (type = RULES)
+ */
+ TransliteratorAlias(const UnicodeString& theID,
+ const UnicodeString& rules,
+ UTransDirection dir);
+
~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.
+ *
+ * Note: Only call create() if isRuleBased() returns FALSE.
+ *
+ * This method must be called *outside* of the TransliteratorRegistry
+ * mutex.
*/
Transliterator* create(UParseError&, UErrorCode&);
-
+
+ /**
+ * Return TRUE if this alias is rule-based. If so, the caller
+ * must call parse() on it, then call TransliteratorRegistry::reget().
+ */
+ UBool isRuleBased() const;
+
+ /**
+ * If isRuleBased() returns TRUE, then the caller must call this
+ * method, followed by TransliteratorRegistry::reget(). The latter
+ * method must be called inside the TransliteratorRegistry mutex.
+ *
+ * Note: Only call parse() if isRuleBased() returns TRUE.
+ *
+ * This method must be called *outside* of the TransliteratorRegistry
+ * mutex, because it can instantiate Transliterators embedded in
+ * the rules via the "&Latin-Arabic()" syntax.
+ */
+ void parse(TransliteratorParser& parser,
+ UParseError& pe, UErrorCode& ec) const;
+
private:
- // We actually come in two flavors:
+ // We actually come in three flavors:
// 1. Simple alias
// Here aliasID is the alias string. Everything else is
// null, zero, empty.
// contained RBT, and idSplitPoint is the offet in aliasID
// where the contained RBT goes. compoundFilter is the
// compound filter, and it is _not_ owned.
+ // 3. Rules
+ // Here ID is the ID, aliasID is the rules string.
+ // idSplitPoint is the UTransDirection.
UnicodeString ID;
- UnicodeString aliasID;
- Transliterator* trans; // owned
+ UnicodeString aliasesOrRules;
+ UVector* transes; // owned
const UnicodeSet* compoundFilter; // alias
- int32_t idSplitPoint;
+ UTransDirection direction;
+ enum { SIMPLE, COMPOUND, RULES } type;
TransliteratorAlias(const TransliteratorAlias &other); // forbid copying of this class
TransliteratorAlias &operator=(const TransliteratorAlias &other); // forbid copying of this class
* 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
+ * @param aliasReturn output param to receive TransliteratorAlias;
+ * should be NULL on entry
+ * @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);
+ /**
+ * The caller must call this after calling get(), if [a] calling get()
+ * returns an alias, and [b] the alias is rule based. In that
+ * situation the caller must call alias->parse() to do the parsing
+ * OUTSIDE THE REGISTRY MUTEX, then call this method to retry
+ * instantiating the transliterator.
+ *
+ * Note: Another alias might be returned by this method.
+ *
+ * This method (like all public methods of this class) must be called
+ * from within the TransliteratorRegistry mutex.
+ *
+ * @param aliasReturn output param to receive TransliteratorAlias;
+ * should be NULL on entry
+ */
+ Transliterator* reget(const UnicodeString& ID,
+ TransliteratorParser& parser,
+ TransliteratorAlias*& aliasReturn,
+ 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);
+ UBool visible,
+ UErrorCode& ec);
/**
* Register an ID and a factory function pointer. This adds an
void put(const UnicodeString& ID,
Transliterator::Factory factory,
Transliterator::Token context,
- UBool visible);
+ UBool visible,
+ UErrorCode& ec);
/**
* Register an ID and a resource name. This adds an entry to the
void put(const UnicodeString& ID,
const UnicodeString& resourceName,
UTransDirection dir,
- UBool visible);
+ UBool readonlyResourceAlias,
+ UBool visible,
+ UErrorCode& ec);
/**
* Register an ID and an alias ID. This adds an entry to the
*/
void put(const UnicodeString& ID,
const UnicodeString& alias,
- UBool visible);
+ UBool readonlyAliasAlias,
+ UBool visible,
+ UErrorCode& ec);
/**
* Unregister an ID. This removes an entry from the dynamic store
//------------------------------------------------------------------
/**
+ * Return a StringEnumeration over the IDs currently registered
+ * with the system.
+ * @internal
+ */
+ StringEnumeration* getAvailableIDs() const;
+
+ /**
+ * == OBSOLETE - remove in ICU 3.4 ==
* 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);
+ int32_t countAvailableIDs(void) const;
/**
+ * == OBSOLETE - remove in ICU 3.4 ==
* 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.
* range, the result of getAvailableID(0) is returned.
* @internal
*/
- const UnicodeString& getAvailableID(int32_t index);
+ const UnicodeString& getAvailableID(int32_t index) const;
/**
* Return the number of registered source specifiers.
* @return the number of registered source specifiers.
*/
- int32_t countAvailableSources(void);
-
+ int32_t countAvailableSources(void) const;
+
/**
* Return a registered source specifier.
* @param index which specifier to return, from 0 to n-1, where
* @return reference to result
*/
UnicodeString& getAvailableSource(int32_t index,
- UnicodeString& result);
-
+ UnicodeString& result) const;
+
/**
* Return the number of registered target specifiers for a given
* source specifier.
* @return the number of registered target specifiers for a given
* source specifier.
*/
- int32_t countAvailableTargets(const UnicodeString& source);
-
+ int32_t countAvailableTargets(const UnicodeString& source) const;
+
/**
* Return a registered target specifier for a given source.
* @param index which specifier to return, from 0 to n-1, where
*/
UnicodeString& getAvailableTarget(int32_t index,
const UnicodeString& source,
- UnicodeString& result);
-
+ UnicodeString& result) const;
+
/**
* Return the number of registered variant specifiers for a given
* source-target pair. There is always at least one variant: If
* source-target pair.
*/
int32_t countAvailableVariants(const UnicodeString& source,
- const UnicodeString& target);
-
+ const UnicodeString& target) const;
+
/**
* Return a registered variant specifier for a given source-target
* pair. If NO_VARIANT is one of the variants, then it will be
UnicodeString& getAvailableVariant(int32_t index,
const UnicodeString& source,
const UnicodeString& target,
- UnicodeString& result);
+ UnicodeString& result) const;
private:
// Private implementation
//----------------------------------------------------------------
- Entry* find(const UnicodeString& ID);
-
- Entry* find(UnicodeString& source,
+ TransliteratorEntry* find(const UnicodeString& ID);
+
+ TransliteratorEntry* find(UnicodeString& source,
UnicodeString& target,
UnicodeString& variant);
- Entry* findInDynamicStore(const Spec& src,
- const Spec& trg,
- const UnicodeString& variant);
+ TransliteratorEntry* findInDynamicStore(const TransliteratorSpec& src,
+ const TransliteratorSpec& trg,
+ const UnicodeString& variant) const;
- Entry* findInStaticStore(const Spec& src,
- const Spec& trg,
+ TransliteratorEntry* findInStaticStore(const TransliteratorSpec& src,
+ const TransliteratorSpec& trg,
const UnicodeString& variant);
- static Entry* findInBundle(const Spec& specToOpen,
- const Spec& specToFind,
+ static TransliteratorEntry* findInBundle(const TransliteratorSpec& specToOpen,
+ const TransliteratorSpec& specToFind,
const UnicodeString& variant,
UTransDirection direction);
void registerEntry(const UnicodeString& source,
const UnicodeString& target,
const UnicodeString& variant,
- Entry* adopted,
+ TransliteratorEntry* adopted,
UBool visible);
void registerEntry(const UnicodeString& ID,
- Entry* adopted,
+ TransliteratorEntry* adopted,
UBool visible);
- void registerEntry(const UnicodeString& ID,
+ void registerEntry(const UnicodeString& ID,
const UnicodeString& source,
const UnicodeString& target,
const UnicodeString& variant,
- Entry* adopted,
+ TransliteratorEntry* adopted,
UBool visible);
void registerSTV(const UnicodeString& source,
const UnicodeString& variant);
Transliterator* instantiateEntry(const UnicodeString& ID,
- Entry *entry,
+ TransliteratorEntry *entry,
TransliteratorAlias*& aliasReturn,
- UParseError& parseError,
UErrorCode& status);
+ /**
+ * A StringEnumeration over the registered IDs in this object.
+ */
+ class Enumeration : public StringEnumeration {
+ public:
+ Enumeration(const TransliteratorRegistry& reg);
+ virtual ~Enumeration();
+ virtual int32_t count(UErrorCode& status) const;
+ virtual const UnicodeString* snext(UErrorCode& status);
+ virtual void reset(UErrorCode& status);
+ static UClassID U_EXPORT2 getStaticClassID();
+ virtual UClassID getDynamicClassID() const;
+ private:
+ int32_t index;
+ const TransliteratorRegistry& reg;
+ };
+ friend class Enumeration;
+
private:
/**
* 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.
+ * target => variant bitmask)
*/
Hashtable specDAG;
-
+
+ /**
+ * Vector of all variant names
+ */
+ UVector variantList;
+
/**
* Vector of public full IDs.
*/
U_NAMESPACE_END
+U_CFUNC UBool utrans_transliterator_cleanup(void);
+
#endif /* #if !UCONFIG_NO_TRANSLITERATION */
#endif