1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ********************************************************************** 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Copyright (C) 1999-2010, International Business Machines 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Corporation and others. All Rights Reserved. 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ********************************************************************** 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Date Name Description 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 11/17/99 aliu Creation. 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ********************************************************************** 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypeinfo.h" // for 'typeid' to work 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h" 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_TRANSLITERATION 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/putil.h" 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/translit.h" 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/locid.h" 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/msgfmt.h" 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/rep.h" 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/resbund.h" 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/unifilt.h" 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uniset.h" 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uscript.h" 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/strenum.h" 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cpdtrans.h" 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "nultrans.h" 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "rbt_data.h" 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "rbt_pars.h" 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "rbt.h" 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "transreg.h" 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "name2uni.h" 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "nortrans.h" 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "remtrans.h" 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "titletrn.h" 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "tolowtrn.h" 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "toupptrn.h" 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uni2name.h" 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "brktrans.h" 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "esctrn.h" 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unesctrn.h" 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "tridpars.h" 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "anytrans.h" 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "util.h" 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "hash.h" 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "mutex.h" 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucln_in.h" 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uassert.h" 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h" 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h" 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uinvchar.h" 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar TARGET_SEP = 0x002D; /*-*/ 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar ID_DELIM = 0x003B; /*;*/ 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar VARIANT_SEP = 0x002F; // '/' 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Prefix for resource bundle key for the display name for a 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * transliterator. The ID is appended to this to form the key. 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The resource bundle value should be a String. 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char RB_DISPLAY_NAME_PREFIX[] = "%Translit%%"; 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Prefix for resource bundle key for the display name for a 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * transliterator SCRIPT. The ID is appended to this to form the key. 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The resource bundle value should be a String. 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char RB_SCRIPT_DISPLAY_NAME_PREFIX[] = "%Translit%"; 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Resource bundle key for display name pattern. 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The resource bundle value should be a String forming a 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * MessageFormat pattern, e.g.: 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * "{0,choice,0#|1#{1} Transliterator|2#{1} to {2} Transliterator}". 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char RB_DISPLAY_NAME_PATTERN[] = "TransliteratorNamePattern"; 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Resource bundle key for the list of RuleBasedTransliterator IDs. 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The resource bundle value should be a String[] with each element 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * being a valid ID. The ID will be appended to RB_RULE_BASED_PREFIX 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * to obtain the class name in which the RB_RULE key will be sought. 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char RB_RULE_BASED_IDS[] = "RuleBasedTransliteratorIDs"; 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The mutex controlling access to registry object. 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UMTX registryMutex = 0; 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * System transliterator registry; non-null when initialized. 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static U_NAMESPACE_QUALIFIER TransliteratorRegistry* registry = 0; 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Macro to check/initialize the registry. ONLY USE WITHIN 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// MUTEX. Avoids function call when registry is initialized. 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define HAVE_REGISTRY(status) (registry!=0 || initializeRegistry(status)) 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Empty string 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar EMPTY[] = {0}; //"" 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_BEGIN 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(Transliterator) 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Return TRUE if the given UTransPosition is valid for text of 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the given length. 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static inline UBool positionIsValid(UTransPosition& index, int32_t len) { 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return !(index.contextStart < 0 || 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.start < index.contextStart || 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.limit < index.start || 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.contextLimit < index.limit || 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) len < index.contextLimit); 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Default constructor. 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param theID the string identifier for this transliterator 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param theFilter the filter. Any character for which 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <tt>filter.contains()</tt> returns <tt>FALSE</tt> will not be 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * altered by this transliterator. If <tt>filter</tt> is 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <tt>null</tt> then no filtering is applied. 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Transliterator::Transliterator(const UnicodeString& theID, 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeFilter* adoptedFilter) : 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UObject(), ID(theID), filter(adoptedFilter), 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) maximumContextLength(0) 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // NUL-terminate the ID string, which is a non-aliased copy. 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ID.append((UChar)0); 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ID.truncate(ID.length()-1); 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Destructor. 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Transliterator::~Transliterator() { 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (filter) { 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete filter; 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Copy constructor. 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Transliterator::Transliterator(const Transliterator& other) : 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UObject(other), ID(other.ID), filter(0), 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) maximumContextLength(other.maximumContextLength) 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // NUL-terminate the ID string, which is a non-aliased copy. 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ID.append((UChar)0); 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ID.truncate(ID.length()-1); 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (other.filter != 0) { 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We own the filter, so we must have our own copy 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) filter = (UnicodeFilter*) other.filter->clone(); 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Transliterator* Transliterator::clone() const { 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Assignment operator. 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Transliterator& Transliterator::operator=(const Transliterator& other) { 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ID = other.ID; 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // NUL-terminate the ID string 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ID.getTerminatedBuffer(); 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) maximumContextLength = other.maximumContextLength; 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) adoptFilter((other.filter == 0) ? 0 : (UnicodeFilter*) other.filter->clone()); 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return *this; 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Transliterates a segment of a string. <code>Transliterator</code> API. 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param text the string to be transliterated 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param start the beginning index, inclusive; <code>0 <= start 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <= limit</code>. 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param limit the ending index, exclusive; <code>start <= limit 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <= text.length()</code>. 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @return the new limit index, or -1 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t Transliterator::transliterate(Replaceable& text, 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t start, int32_t limit) const { 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (start < 0 || 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) limit < start || 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) text.length() < limit) { 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return -1; 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTransPosition offsets; 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) offsets.contextStart= start; 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) offsets.contextLimit = limit; 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) offsets.start = start; 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) offsets.limit = limit; 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) filteredTransliterate(text, offsets, FALSE, TRUE); 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return offsets.limit; 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Transliterates an entire string in place. Convenience method. 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param text the string to be transliterated 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::transliterate(Replaceable& text) const { 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) transliterate(text, 0, text.length()); 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Transliterates the portion of the text buffer that can be 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * transliterated unambiguosly after new text has been inserted, 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * typically as a result of a keyboard event. The new text in 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>insertion</code> will be inserted into <code>text</code> 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * at <code>index.contextLimit</code>, advancing 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>index.contextLimit</code> by <code>insertion.length()</code>. 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Then the transliterator will try to transliterate characters of 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>text</code> between <code>index.start</code> and 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>index.contextLimit</code>. Characters before 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>index.start</code> will not be changed. 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <p>Upon return, values in <code>index</code> will be updated. 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>index.contextStart</code> will be advanced to the first 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * character that future calls to this method will read. 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>index.start</code> and <code>index.contextLimit</code> will 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * be adjusted to delimit the range of text that future calls to 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * this method may change. 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <p>Typical usage of this method begins with an initial call 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * with <code>index.contextStart</code> and <code>index.contextLimit</code> 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * set to indicate the portion of <code>text</code> to be 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * transliterated, and <code>index.start == index.contextStart</code>. 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Thereafter, <code>index</code> can be used without 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * modification in future calls, provided that all changes to 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>text</code> are made via this method. 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <p>This method assumes that future calls may be made that will 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * insert new text into the buffer. As a result, it only performs 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * unambiguous transliterations. After the last call to this 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * method, there may be untransliterated text that is waiting for 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * more input to resolve an ambiguity. In order to perform these 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * pending transliterations, clients should call {@link 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * #finishKeyboardTransliteration} after the last call to this 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * method has been made. 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param text the buffer holding transliterated and untransliterated text 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param index an array of three integers. 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <ul><li><code>index.contextStart</code>: the beginning index, 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * inclusive; <code>0 <= index.contextStart <= index.contextLimit</code>. 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <li><code>index.contextLimit</code>: the ending index, exclusive; 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>index.contextStart <= index.contextLimit <= text.length()</code>. 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>insertion</code> is inserted at 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>index.contextLimit</code>. 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <li><code>index.start</code>: the next character to be 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * considered for transliteration; <code>index.contextStart <= 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * index.start <= index.contextLimit</code>. Characters before 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>index.start</code> will not be changed by future calls 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * to this method.</ul> 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param insertion text to be inserted and possibly 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * transliterated into the translation buffer at 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>index.contextLimit</code>. If <code>null</code> then no text 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * is inserted. 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #START 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #LIMIT 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #CURSOR 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #handleTransliterate 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @exception IllegalArgumentException if <code>index</code> 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * is invalid 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::transliterate(Replaceable& text, 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTransPosition& index, 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString& insertion, 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode &status) const { 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _transliterate(text, index, &insertion, status); 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Transliterates the portion of the text buffer that can be 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * transliterated unambiguosly after a new character has been 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * inserted, typically as a result of a keyboard event. This is a 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * convenience method; see {@link 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * #transliterate(Replaceable, int[], String)} for details. 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param text the buffer holding transliterated and 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * untransliterated text 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param index an array of three integers. See {@link 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * #transliterate(Replaceable, int[], String)}. 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param insertion text to be inserted and possibly 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * transliterated into the translation buffer at 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>index.contextLimit</code>. 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #transliterate(Replaceable, int[], String) 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::transliterate(Replaceable& text, 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTransPosition& index, 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 insertion, 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode& status) const { 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString str(insertion); 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _transliterate(text, index, &str, status); 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Transliterates the portion of the text buffer that can be 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * transliterated unambiguosly. This is a convenience method; see 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * {@link #transliterate(Replaceable, int[], String)} for 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * details. 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param text the buffer holding transliterated and 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * untransliterated text 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param index an array of three integers. See {@link 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * #transliterate(Replaceable, int[], String)}. 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #transliterate(Replaceable, int[], String) 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::transliterate(Replaceable& text, 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTransPosition& index, 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode& status) const { 324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _transliterate(text, index, 0, status); 325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Finishes any pending transliterations that were waiting for 329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * more characters. Clients should call this method as the last 330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * call after a sequence of one or more calls to 331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>transliterate()</code>. 332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param text the buffer holding transliterated and 333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * untransliterated text. 334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param index the array of indices previously passed to {@link 335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * #transliterate} 336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::finishTransliteration(Replaceable& text, 338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTransPosition& index) const { 339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!positionIsValid(index, text.length())) { 340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) filteredTransliterate(text, index, FALSE, TRUE); 344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * This internal method does keyboard transliteration. If the 348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 'insertion' is non-null then we append it to 'text' before 349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * proceeding. This method calls through to the pure virtual 350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * framework method handleTransliterate() to do the actual 351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * work. 352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::_transliterate(Replaceable& text, 354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTransPosition& index, 355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString* insertion, 356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode &status) const { 357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!positionIsValid(index, text.length())) { 362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ILLEGAL_ARGUMENT_ERROR; 363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// int32_t originalStart = index.contextStart; 367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (insertion != 0) { 368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) text.handleReplaceBetween(index.limit, index.limit, *insertion); 369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.limit += insertion->length(); 370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.contextLimit += insertion->length(); 371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (index.limit > 0 && 374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTF_IS_LEAD(text.charAt(index.limit - 1))) { 375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Oops, there is a dangling lead surrogate in the buffer. 376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // This will break most transliterators, since they will 377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // assume it is part of a pair. Don't transliterate until 378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // more text comes in. 379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) filteredTransliterate(text, index, TRUE, TRUE); 383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if 0 385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // TODO 386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // I CAN'T DO what I'm attempting below now that the Kleene star 387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // operator is supported. For example, in the rule 388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // ([:Lu:]+) { x } > $1; 390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // what is the maximum context length? getMaximumContextLength() 392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // will return 1, but this is just the length of the ante context 393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // part of the pattern string -- 1 character, which is a standin 394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // for a Quantifier, which contains a StringMatcher, which 395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // contains a UnicodeSet. 396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // There is a complicated way to make this work again, and that's 398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // to add a "maximum left context" protocol into the 399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // UnicodeMatcher hierarchy. At present I'm not convinced this is 400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // worth it. 401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // --- 403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The purpose of the code below is to keep the context small 405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // while doing incremental transliteration. When part of the left 406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // context (between contextStart and start) is no longer needed, 407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // we try to advance contextStart past that portion. We use the 408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // maximum context length to do so. 409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t newCS = index.start; 410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t n = getMaximumContextLength(); 411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (newCS > originalStart && n-- > 0) { 412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) --newCS; 413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) newCS -= UTF_CHAR_LENGTH(text.char32At(newCS)) - 1; 414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.contextStart = uprv_max(newCS, originalStart); 416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * This method breaks up the input text into runs of unfiltered 421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * characters. It passes each such run to 422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <subclass>.handleTransliterate(). Subclasses that can handle the 423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * filter logic more efficiently themselves may override this method. 424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * All transliteration calls in this class go through this method. 426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::filteredTransliterate(Replaceable& text, 428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTransPosition& index, 429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool incremental, 430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool rollback) const { 431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Short circuit path for transliterators with no filter in 432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // non-incremental mode. 433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (filter == 0 && !rollback) { 434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) handleTransliterate(text, index, incremental); 435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //---------------------------------------------------------------------- 439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // This method processes text in two groupings: 440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // RUNS -- A run is a contiguous group of characters which are contained 442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // in the filter for this transliterator (filter.contains(ch) == TRUE). 443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Text outside of runs may appear as context but it is not modified. 444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The start and limit Position values are narrowed to each run. 445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // PASSES (incremental only) -- To make incremental mode work correctly, 447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // each run is broken up into n passes, where n is the length (in code 448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // points) of the run. Each pass contains the first n characters. If a 449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // pass is completely transliterated, it is committed, and further passes 450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // include characters after the committed text. If a pass is blocked, 451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // and does not transliterate completely, then this method rolls back 452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the changes made during the pass, extends the pass by one code point, 453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // and tries again. 454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //---------------------------------------------------------------------- 455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // globalLimit is the limit value for the entire operation. We 457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // set index.limit to the end of each unfiltered run before 458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // calling handleTransliterate(), so we need to maintain the real 459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // value of index.limit here. After each transliteration, we 460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // update globalLimit for insertions or deletions that have 461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // happened. 462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t globalLimit = index.limit; 463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // If there is a non-null filter, then break the input text up. Say the 465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // input text has the form: 466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // xxxabcxxdefxx 467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // where 'x' represents a filtered character (filter.contains('x') == 468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // false). Then we break this up into: 469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // xxxabc xxdef xx 470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Each pass through the loop consumes a run of filtered 471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // characters (which are ignored) and a subsequent run of 472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // unfiltered characters (which are transliterated). 473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (;;) { 475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (filter != NULL) { 477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Narrow the range to be transliterated to the first segment 478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // of unfiltered characters at or after index.start. 479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Advance past filtered chars 481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 c; 482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (index.start < globalLimit && 483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) !filter->contains(c=text.char32At(index.start))) { 484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.start += UTF_CHAR_LENGTH(c); 485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Find the end of this run of unfiltered chars 488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.limit = index.start; 489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (index.limit < globalLimit && 490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) filter->contains(c=text.char32At(index.limit))) { 491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.limit += UTF_CHAR_LENGTH(c); 492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Check to see if the unfiltered run is empty. This only 496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // happens at the end of the string when all the remaining 497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // characters are filtered. 498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (index.limit == index.start) { 499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // assert(index.start == globalLimit); 500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Is this run incremental? If there is additional 504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // filtered text (if limit < globalLimit) then we pass in 505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // an incremental value of FALSE to force the subclass to 506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // complete the transliteration for this run. 507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool isIncrementalRun = 508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (index.limit < globalLimit ? FALSE : incremental); 509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t delta; 511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Implement rollback. To understand the need for rollback, 513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // consider the following transliterator: 514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // "t" is "a > A;" 516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // "u" is "A > b;" 517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // "v" is a compound of "t; NFD; u" with a filter [:Ll:] 518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Now apply "c" to the input text "a". The result is "b". But if 520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the transliteration is done incrementally, then the NFD holds 521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // things up after "t" has already transformed "a" to "A". When 522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // finishTransliterate() is called, "A" is _not_ processed because 523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // it gets excluded by the [:Ll:] filter, and the end result is "A" 524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // -- incorrect. The problem is that the filter is applied to a 525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // partially-transliterated result, when we only want it to apply to 526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // input text. Although this example hinges on a compound 527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // transliterator containing NFD and a specific filter, it can 528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // actually happen with any transliterator which may do a partial 529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // transformation in incremental mode into characters outside its 530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // filter. 531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // To handle this, when in incremental mode we supply characters to 533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // handleTransliterate() in several passes. Each pass adds one more 534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // input character to the input text. That is, for input "ABCD", we 535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // first try "A", then "AB", then "ABC", and finally "ABCD". If at 536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // any point we block (upon return, start < limit) then we roll 537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // back. If at any point we complete the run (upon return start == 538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // limit) then we commit that run. 539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (rollback && isIncrementalRun) { 541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t runStart = index.start; 543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t runLimit = index.limit; 544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t runLength = runLimit - runStart; 545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Make a rollback copy at the end of the string 547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t rollbackOrigin = text.length(); 548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) text.copy(runStart, runLimit, rollbackOrigin); 549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Variables reflecting the commitment of completely 551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // transliterated text. passStart is the runStart, advanced 552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // past committed text. rollbackStart is the rollbackOrigin, 553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // advanced past rollback text that corresponds to committed 554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // text. 555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t passStart = runStart; 556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t rollbackStart = rollbackOrigin; 557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The limit for each pass; we advance by one code point with 559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // each iteration. 560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t passLimit = index.start; 561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Total length, in 16-bit code units, of uncommitted text. 563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // This is the length to be rolled back. 564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t uncommittedLength = 0; 565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Total delta (change in length) for all passes 567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t totalDelta = 0; 568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // PASS MAIN LOOP -- Start with a single character, and extend 570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the text by one character at a time. Roll back partial 571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // transliterations and commit complete transliterations. 572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (;;) { 573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Length of additional code point, either one or two 574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t charLength = 575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTF_CHAR_LENGTH(text.char32At(passLimit)); 576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) passLimit += charLength; 577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (passLimit > runLimit) { 578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uncommittedLength += charLength; 581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.limit = passLimit; 583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Delegate to subclass for actual transliteration. Upon 585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // return, start will be updated to point after the 586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // transliterated text, and limit and contextLimit will be 587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // adjusted for length changes. 588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) handleTransliterate(text, index, TRUE); 589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delta = index.limit - passLimit; // change in length 591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We failed to completely transliterate this pass. 593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Roll back the text. Indices remain unchanged; reset 594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // them where necessary. 595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (index.start != index.limit) { 596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Find the rollbackStart, adjusted for length changes 597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // and the deletion of partially transliterated text. 598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t rs = rollbackStart + delta - (index.limit - passStart); 599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Delete the partially transliterated text 601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) text.handleReplaceBetween(passStart, index.limit, EMPTY); 602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Copy the rollback text back 604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) text.copy(rs, rs + uncommittedLength, passStart); 605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Restore indices to their original values 607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.start = passStart; 608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.limit = passLimit; 609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.contextLimit -= delta; 610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We did completely transliterate this pass. Update the 613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // commit indices to record how far we got. Adjust indices 614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // for length change. 615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Move the pass indices past the committed text. 617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) passStart = passLimit = index.start; 618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Adjust the rollbackStart for length changes and move 620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // it past the committed text. All characters we've 621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // processed to this point are committed now, so zero 622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // out the uncommittedLength. 623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) rollbackStart += delta + uncommittedLength; 624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uncommittedLength = 0; 625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Adjust indices for length changes. 627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) runLimit += delta; 628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) totalDelta += delta; 629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Adjust overall limit and rollbackOrigin for insertions and 633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // deletions. Don't need to worry about contextLimit because 634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // handleTransliterate() maintains that. 635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) rollbackOrigin += totalDelta; 636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) globalLimit += totalDelta; 637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Delete the rollback copy 639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) text.handleReplaceBetween(rollbackOrigin, rollbackOrigin + runLength, EMPTY); 640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Move start past committed text 642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.start = passStart; 643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Delegate to subclass for actual transliteration. 647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t limit = index.limit; 648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) handleTransliterate(text, index, isIncrementalRun); 649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delta = index.limit - limit; // change in length 650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // In a properly written transliterator, start == limit after 652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // handleTransliterate() returns when incremental is false. 653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Catch cases where the subclass doesn't do this, and throw 654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // an exception. (Just pinning start to limit is a bad idea, 655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // because what's probably happening is that the subclass 656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // isn't transliterating all the way to the end, and it should 657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // in non-incremental mode.) 658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!incremental && index.start != index.limit) { 659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We can't throw an exception, so just fudge things 660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.start = index.limit; 661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Adjust overall limit for insertions/deletions. Don't need 664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // to worry about contextLimit because handleTransliterate() 665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // maintains that. 666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) globalLimit += delta; 667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (filter == NULL || isIncrementalRun) { 670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // If we did completely transliterate this 674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // run, then repeat with the next unfiltered run. 675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Start is valid where it is. Limit needs to be put back where 678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // it was, modulo adjustments for deletions/insertions. 679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) index.limit = globalLimit; 680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::filteredTransliterate(Replaceable& text, 683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTransPosition& index, 684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool incremental) const { 685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) filteredTransliterate(text, index, incremental, FALSE); 686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Method for subclasses to use to set the maximum context length. 690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #getMaximumContextLength 691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::setMaximumContextLength(int32_t maxContextLength) { 693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) maximumContextLength = maxContextLength; 694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Returns a programmatic identifier for this transliterator. 698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * If this identifier is passed to <code>getInstance()</code>, it 699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * will return this object, if it has been registered. 700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #registerInstance 701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #getAvailableIDs 702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UnicodeString& Transliterator::getID(void) const { 704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ID; 705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Returns a name for this transliterator that is appropriate for 709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * display to the user in the default locale. See {@link 710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * #getDisplayName(Locale)} for details. 711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& U_EXPORT2 Transliterator::getDisplayName(const UnicodeString& ID, 713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString& result) { 714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return getDisplayName(ID, Locale::getDefault(), result); 715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Returns a name for this transliterator that is appropriate for 719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * display to the user in the given locale. This name is taken 720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * from the locale resource data in the standard manner of the 721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>java.text</code> package. 722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <p>If no localized names exist in the system resource bundles, 724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * a name is synthesized using a localized 725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>MessageFormat</code> pattern from the resource data. The 726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * arguments to this pattern are an integer followed by one or two 727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * strings. The integer is the number of strings, either 1 or 2. 728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The strings are formed by splitting the ID for this 729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * transliterator at the first TARGET_SEP. If there is no TARGET_SEP, then the 730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * entire ID forms the only string. 731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param inLocale the Locale in which the display name should be 732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * localized. 733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see java.text.MessageFormat 734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& U_EXPORT2 Transliterator::getDisplayName(const UnicodeString& id, 736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const Locale& inLocale, 737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString& result) { 738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ResourceBundle bundle(U_ICUDATA_TRANSLIT, inLocale, status); 741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Suspend checking status until later... 743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.truncate(0); 745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Normalize the ID 747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString source, target, variant; 748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool sawSource; 749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TransliteratorIDParser::IDtoSTV(id, source, target, variant, sawSource); 750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (target.length() < 1) { 751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // No target; malformed id 752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (variant.length() > 0) { // Change "Foo" to "/Foo" 755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) variant.insert(0, VARIANT_SEP); 756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString ID(source); 758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ID.append(TARGET_SEP).append(target).append(variant); 759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // build the char* key 761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (uprv_isInvariantUString(ID.getBuffer(), ID.length())) { 762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char key[200]; 763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_strcpy(key, RB_DISPLAY_NAME_PREFIX); 764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length=(int32_t)uprv_strlen(RB_DISPLAY_NAME_PREFIX); 765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ID.extract(0, (int32_t)(sizeof(key)-length), key+length, (int32_t)(sizeof(key)-length), US_INV); 766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Try to retrieve a UnicodeString from the bundle. 768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString resString = bundle.getStringEx(key, status); 769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status) && resString.length() != 0) { 771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result = resString; // [sic] assign & return 772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_FORMATTING 775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We have failed to get a name from the locale data. This is 776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // typical, since most transliterators will not have localized 777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // name data. The next step is to retrieve the MessageFormat 778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // pattern from the locale data and to use it to synthesize the 779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // name from the ID. 780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ZERO_ERROR; 782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resString = bundle.getStringEx(RB_DISPLAY_NAME_PATTERN, status); 783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status) && resString.length() != 0) { 785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) MessageFormat msg(resString, inLocale, status); 786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Suspend checking status until later... 787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We pass either 2 or 3 Formattable objects to msg. 789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Formattable args[3]; 790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t nargs; 791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args[0].setLong(2); // # of args to follow 792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args[1].setString(source); 793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args[2].setString(target); 794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nargs = 3; 795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Use display names for the scripts, if they exist 797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString s; 798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length=(int32_t)uprv_strlen(RB_SCRIPT_DISPLAY_NAME_PREFIX); 799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int j=1; j<=2; ++j) { 800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ZERO_ERROR; 801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_strcpy(key, RB_SCRIPT_DISPLAY_NAME_PREFIX); 802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args[j].getString(s); 803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (uprv_isInvariantUString(s.getBuffer(), s.length())) { 804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) s.extract(0, sizeof(key)-length-1, key+length, (int32_t)sizeof(key)-length-1, US_INV); 805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resString = bundle.getStringEx(key, status); 807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status)) { 809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) args[j] = resString; 810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_ZERO_ERROR; 815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) FieldPosition pos; // ignored by msg 816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) msg.format(args, nargs, result, pos, status); 817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status)) { 818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.append(variant); 819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We should not reach this point unless there is something 826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // wrong with the build or the RB_DISPLAY_NAME_PATTERN has 827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // been deleted from the root RB_LOCALE_ELEMENTS resource. 828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = ID; 829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Returns the filter used by this transliterator, or <tt>null</tt> 834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * if this transliterator uses no filter. Caller musn't delete 835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the result! 836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UnicodeFilter* Transliterator::getFilter(void) const { 838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return filter; 839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Returns the filter used by this transliterator, or 843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <tt>NULL</tt> if this transliterator uses no filter. The 844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * caller must eventually delete the result. After this call, 845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * this transliterator's filter is set to <tt>NULL</tt>. 846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeFilter* Transliterator::orphanFilter(void) { 848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeFilter *result = filter; 849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) filter = NULL; 850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Changes the filter used by this transliterator. If the filter 855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * is set to <tt>null</tt> then no filtering will occur. 856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <p>Callers must take care if a transliterator is in use by 858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * multiple threads. The filter should not be changed by one 859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * thread while another thread may be transliterating. 860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::adoptFilter(UnicodeFilter* filterToAdopt) { 862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete filter; 863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) filter = filterToAdopt; 864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Returns this transliterator's inverse. See the class 868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * documentation for details. This implementation simply inverts 869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the two entities in the ID and attempts to retrieve the 870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * resulting transliterator. That is, if <code>getID()</code> 871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * returns "A-B", then this method will return the result of 872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>getInstance("B-A")</code>, or <code>null</code> if that 873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * call fails. 874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <p>This method does not take filtering into account. The 876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * returned transliterator will have no filter. 877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <p>Subclasses with knowledge of their inverse may wish to 879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * override this method. 880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @return a transliterator that is an inverse, not necessarily 882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * exact, of this transliterator, or <code>null</code> if no such 883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * transliterator is registered. 884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #registerInstance 885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Transliterator* Transliterator::createInverse(UErrorCode& status) const { 887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError parseError; 888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return Transliterator::createInstance(ID, UTRANS_REVERSE,parseError,status); 889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Transliterator* U_EXPORT2 892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Transliterator::createInstance(const UnicodeString& ID, 893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTransDirection dir, 894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode& status) 895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError parseError; 897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return createInstance(ID, dir, parseError, status); 898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Returns a <code>Transliterator</code> object given its ID. 902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The ID must be either a system transliterator ID or a ID registered 903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * using <code>registerInstance()</code>. 904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param ID a valid ID, as enumerated by <code>getAvailableIDs()</code> 906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @return A <code>Transliterator</code> object with the given ID 907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #registerInstance 908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #getAvailableIDs 909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #getID 910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Transliterator* U_EXPORT2 912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Transliterator::createInstance(const UnicodeString& ID, 913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTransDirection dir, 914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError& parseError, 915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode& status) 916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString canonID; 922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UVector list(status); 923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeSet* globalFilter; 928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // TODO add code for parseError...currently unused, but 929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // later may be used by parsing code... 930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!TransliteratorIDParser::parseCompoundID(ID, dir, canonID, list, globalFilter)) { 931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_INVALID_ID; 932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TransliteratorIDParser::instantiateList(list, status); 936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U_ASSERT(list.size() > 0); 941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Transliterator* t = NULL; 942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (list.size() > 1 || canonID.indexOf(ID_DELIM) >= 0) { 944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // [NOTE: If it's a compoundID, we instantiate a CompoundTransliterator even if it only 945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // has one child transliterator. This is so that toRules() will return the right thing 946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // (without any inactive ID), but our main ID still comes out correct. That is, if we 947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // instantiate "(Lower);Latin-Greek;", we want the rules to come out as "::Latin-Greek;" 948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // even though the ID is "(Lower);Latin-Greek;". 949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t = new CompoundTransliterator(list, parseError, status); 950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t = (Transliterator*)list.elementAt(0); 953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Check null pointer 955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (t != NULL) { 956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t->setID(canonID); 957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (globalFilter != NULL) { 958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t->adoptFilter(globalFilter); 959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if (U_SUCCESS(status)) { 962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return t; 965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Create a transliterator from a basic ID. This is an ID 969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * containing only the forward direction source, target, and 970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * variant. 971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param id a basic ID of the form S-T or S-T/V. 972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @return a newly created Transliterator or null if the ID is 973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * invalid. 974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Transliterator* Transliterator::createBasicInstance(const UnicodeString& id, 976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString* canon) { 977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError pe; 978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TransliteratorAlias* alias = 0; 980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Transliterator* t = 0; 981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(®istryMutex); 983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (HAVE_REGISTRY(ec)) { 984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t = registry->get(id, alias, ec); 985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(®istryMutex); 987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 988f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(ec)) { 989f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete t; 990f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete alias; 991f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 992f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 993f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 994f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We may have not gotten a transliterator: Because we can't 995f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // instantiate a transliterator from inside TransliteratorRegistry:: 996f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // get() (that would deadlock), we sometimes pass back an alias. This 997f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // contains the data we need to finish the instantiation outside the 998f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // registry mutex. The alias may, in turn, generate another alias, so 999f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // we handle aliases in a loop. The max times through the loop is two. 1000f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // [alan] 1001f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (alias != 0) { 1002f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U_ASSERT(t==0); 1003f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Rule-based aliases are handled with TransliteratorAlias:: 1004f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // parse(), followed by TransliteratorRegistry::reget(). 1005f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Other aliases are handled with TransliteratorAlias::create(). 1006f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (alias->isRuleBased()) { 1007f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Step 1. parse 1008f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TransliteratorParser parser(ec); 1009f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias->parse(parser, pe, ec); 1010f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete alias; 1011f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias = 0; 1012f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1013f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Step 2. reget 1014f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(®istryMutex); 1015f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (HAVE_REGISTRY(ec)) { 1016f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t = registry->reget(id, parser, alias, ec); 1017f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1018f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(®istryMutex); 1019f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1020f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Step 3. Loop back around! 1021f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1022f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t = alias->create(pe, ec); 1023f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete alias; 1024f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) alias = 0; 1025f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1026f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1027f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(ec)) { 1028f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete t; 1029f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete alias; 1030f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t = NULL; 1031f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1032f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1033f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1034f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1035f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (t != NULL && canon != NULL) { 1036f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t->setID(*canon); 1037f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1038f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1039f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return t; 1040f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1041f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1042f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 1043f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Returns a <code>Transliterator</code> object constructed from 1044f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the given rule string. This will be a RuleBasedTransliterator, 1045f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * if the rule string contains only rules, or a 1046f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * CompoundTransliterator, if it contains ID blocks, or a 1047f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * NullTransliterator, if it contains ID blocks which parse as 1048f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * empty for the given direction. 1049f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 1050f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Transliterator* U_EXPORT2 1051f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Transliterator::createFromRules(const UnicodeString& ID, 1052f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString& rules, 1053f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTransDirection dir, 1054f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError& parseError, 1055f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode& status) 1056f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 1057f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Transliterator* t = NULL; 1058f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1059f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TransliteratorParser parser(status); 1060f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) parser.parse(rules, dir, parseError, status); 1061f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1062f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 1063f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 1064f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1065f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1066f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // NOTE: The logic here matches that in TransliteratorRegistry. 1067f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (parser.idBlockVector.size() == 0 && parser.dataVector.size() == 0) { 1068f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t = new NullTransliterator(); 1069f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1070f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if (parser.idBlockVector.size() == 0 && parser.dataVector.size() == 1) { 1071f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t = new RuleBasedTransliterator(ID, (TransliterationRuleData*)parser.dataVector.orphanElementAt(0), TRUE); 1072f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1073f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else if (parser.idBlockVector.size() == 1 && parser.dataVector.size() == 0) { 1074f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // idBlock, no data -- this is an alias. The ID has 1075f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // been munged from reverse into forward mode, if 1076f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // necessary, so instantiate the ID in the forward 1077f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // direction. 1078f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (parser.compoundFilter != NULL) { 1079f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString filterPattern; 1080f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) parser.compoundFilter->toPattern(filterPattern, FALSE); 1081f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t = createInstance(filterPattern + UnicodeString(ID_DELIM) 1082f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) + *((UnicodeString*)parser.idBlockVector.elementAt(0)), UTRANS_FORWARD, parseError, status); 1083f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1084f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else 1085f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t = createInstance(*((UnicodeString*)parser.idBlockVector.elementAt(0)), UTRANS_FORWARD, parseError, status); 1086f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1087f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1088f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (t != NULL) { 1089f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t->setID(ID); 1090f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1091f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1092f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 1093f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UVector transliterators(status); 1094f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t passNumber = 1; 1095f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1096f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t limit = parser.idBlockVector.size(); 1097f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (parser.dataVector.size() > limit) 1098f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) limit = parser.dataVector.size(); 1099f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i = 0; i < limit; i++) { 1101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (i < parser.idBlockVector.size()) { 1102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString* idBlock = (UnicodeString*)parser.idBlockVector.elementAt(i); 1103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!idBlock->isEmpty()) { 1104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Transliterator* temp = createInstance(*idBlock, UTRANS_FORWARD, parseError, status); 1105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (temp != NULL && typeid(*temp) != typeid(NullTransliterator)) 1106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) transliterators.addElement(temp, status); 1107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else 1108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete temp; 1109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!parser.dataVector.isEmpty()) { 1112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TransliterationRuleData* data = (TransliterationRuleData*)parser.dataVector.orphanElementAt(0); 1113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) RuleBasedTransliterator* temprbt = new RuleBasedTransliterator(UnicodeString(CompoundTransliterator::PASS_STRING) + (passNumber++), 1114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) data, TRUE); 1115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Check if NULL before adding it to transliterators to avoid future usage of NULL pointer. 1116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (temprbt == NULL) { 1117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 1118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return t; 1119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) transliterators.addElement(temprbt, status); 1121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t = new CompoundTransliterator(transliterators, passNumber - 1, parseError, status); 1125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Null pointer check 1126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (t != NULL) { 1127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t->setID(ID); 1128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t->adoptFilter(parser.orphanCompoundFilter()); 1129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status) && t == NULL) { 1132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 1133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return t; 1135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& Transliterator::toRules(UnicodeString& rulesSource, 1138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool escapeUnprintable) const { 1139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The base class implementation of toRules munges the ID into 1140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the correct format. That is: foo => ::foo 1141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (escapeUnprintable) { 1142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) rulesSource.truncate(0); 1143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString id = getID(); 1144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t i=0; i<id.length();) { 1145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar32 c = id.char32At(i); 1146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!ICU_Utility::escapeUnprintable(rulesSource, c)) { 1147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) rulesSource.append(c); 1148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i += UTF_CHAR_LENGTH(c); 1150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) rulesSource = getID(); 1153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // KEEP in sync with rbt_pars 1155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) rulesSource.insert(0, UNICODE_STRING_SIMPLE("::")); 1156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) rulesSource.append(ID_DELIM); 1157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return rulesSource; 1158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t Transliterator::countElements() const { 1161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const CompoundTransliterator* ct = dynamic_cast<const CompoundTransliterator*>(this); 1162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ct != NULL ? ct->getCount() : 0; 1163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const Transliterator& Transliterator::getElement(int32_t index, UErrorCode& ec) const { 1166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(ec)) { 1167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return *this; 1168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const CompoundTransliterator* cpd = dynamic_cast<const CompoundTransliterator*>(this); 1170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t n = (cpd == NULL) ? 1 : cpd->getCount(); 1171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (index < 0 || index >= n) { 1172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ec = U_INDEX_OUTOFBOUNDS_ERROR; 1173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return *this; 1174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (n == 1) ? *this : cpd->getTransliterator(index); 1176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeSet& Transliterator::getSourceSet(UnicodeSet& result) const { 1180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) handleGetSourceSet(result); 1181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (filter != NULL) { 1182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeSet* filterSet = dynamic_cast<UnicodeSet*>(filter); 1183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool deleteFilterSet = FALSE; 1184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Most, but not all filters will be UnicodeSets. Optimize for 1185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the high-runner case. 1186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (filterSet == NULL) { 1187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) filterSet = new UnicodeSet(); 1188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Check null pointer 1189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (filterSet == NULL) { 1190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) deleteFilterSet = TRUE; 1193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) filter->addMatchSetTo(*filterSet); 1194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.retainAll(*filterSet); 1196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (deleteFilterSet) { 1197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete filterSet; 1198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::handleGetSourceSet(UnicodeSet& result) const { 1204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result.clear(); 1205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeSet& Transliterator::getTargetSet(UnicodeSet& result) const { 1208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result.clear(); 1209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// For public consumption 1212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void U_EXPORT2 Transliterator::registerFactory(const UnicodeString& id, 1213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Transliterator::Factory factory, 1214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Transliterator::Token context) { 1215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Mutex lock(®istryMutex); 1216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (HAVE_REGISTRY(ec)) { 1218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _registerFactory(id, factory, context); 1219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// To be called only by Transliterator subclasses that are called 1223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// to register themselves by initializeRegistry(). 1224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::_registerFactory(const UnicodeString& id, 1225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Transliterator::Factory factory, 1226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Transliterator::Token context) { 1227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry->put(id, factory, context, TRUE, ec); 1229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// To be called only by Transliterator subclasses that are called 1232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// to register themselves by initializeRegistry(). 1233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::_registerSpecialInverse(const UnicodeString& target, 1234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString& inverseTarget, 1235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool bidirectional) { 1236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 1237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TransliteratorIDParser::registerSpecialInverse(target, inverseTarget, bidirectional, status); 1238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 1241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Registers a instance <tt>obj</tt> of a subclass of 1242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>Transliterator</code> with the system. This object must 1243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * implement the <tt>clone()</tt> method. When 1244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <tt>getInstance()</tt> is called with an ID string that is 1245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * equal to <tt>obj.getID()</tt>, then <tt>obj.clone()</tt> is 1246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * returned. 1247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 1248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param obj an instance of subclass of 1249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <code>Transliterator</code> that defines <tt>clone()</tt> 1250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #getInstance 1251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #unregister 1252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 1253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void U_EXPORT2 Transliterator::registerInstance(Transliterator* adoptedPrototype) { 1254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Mutex lock(®istryMutex); 1255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (HAVE_REGISTRY(ec)) { 1257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _registerInstance(adoptedPrototype); 1258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::_registerInstance(Transliterator* adoptedPrototype) { 1262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry->put(adoptedPrototype, TRUE, ec); 1264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void U_EXPORT2 Transliterator::registerAlias(const UnicodeString& aliasID, 1267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString& realID) { 1268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Mutex lock(®istryMutex); 1269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (HAVE_REGISTRY(ec)) { 1271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _registerAlias(aliasID, realID); 1272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void Transliterator::_registerAlias(const UnicodeString& aliasID, 1276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString& realID) { 1277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry->put(aliasID, realID, FALSE, TRUE, ec); 1279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 1282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Unregisters a transliterator or class. This may be either 1283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * a system transliterator or a user transliterator or class. 1284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 1285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param ID the ID of the transliterator or class 1286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @see #registerInstance 1287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 1289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void U_EXPORT2 Transliterator::unregister(const UnicodeString& ID) { 1290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Mutex lock(®istryMutex); 1291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (HAVE_REGISTRY(ec)) { 1293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry->remove(ID); 1294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 1298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * == OBSOLETE - remove in ICU 3.4 == 1299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Return the number of IDs currently registered with the system. 1300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * To retrieve the actual IDs, call getAvailableID(i) with 1301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * i from 0 to countAvailableIDs() - 1. 1302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 1303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t U_EXPORT2 Transliterator::countAvailableIDs(void) { 1304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t retVal = 0; 1305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Mutex lock(®istryMutex); 1306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (HAVE_REGISTRY(ec)) { 1308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) retVal = registry->countAvailableIDs(); 1309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return retVal; 1311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 1314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * == OBSOLETE - remove in ICU 3.4 == 1315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Return the index-th available ID. index must be between 0 1316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * and countAvailableIDs() - 1, inclusive. If index is out of 1317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * range, the result of getAvailableID(0) is returned. 1318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 1319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UnicodeString& U_EXPORT2 Transliterator::getAvailableID(int32_t index) { 1320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString* result = NULL; 1321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(®istryMutex); 1322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (HAVE_REGISTRY(ec)) { 1324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = ®istry->getAvailableID(index); 1325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(®istryMutex); 1327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U_ASSERT(result != NULL); // fail if no registry 1328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return *result; 1329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)StringEnumeration* U_EXPORT2 Transliterator::getAvailableIDs(UErrorCode& ec) { 1332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(ec)) return NULL; 1333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) StringEnumeration* result = NULL; 1334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(®istryMutex); 1335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (HAVE_REGISTRY(ec)) { 1336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = registry->getAvailableIDs(); 1337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(®istryMutex); 1339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result == NULL) { 1340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ec = U_INTERNAL_TRANSLITERATOR_ERROR; 1341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t U_EXPORT2 Transliterator::countAvailableSources(void) { 1346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Mutex lock(®istryMutex); 1347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return HAVE_REGISTRY(ec) ? _countAvailableSources() : 0; 1349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& U_EXPORT2 Transliterator::getAvailableSource(int32_t index, 1352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString& result) { 1353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Mutex lock(®istryMutex); 1354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (HAVE_REGISTRY(ec)) { 1356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _getAvailableSource(index, result); 1357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t U_EXPORT2 Transliterator::countAvailableTargets(const UnicodeString& source) { 1362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Mutex lock(®istryMutex); 1363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return HAVE_REGISTRY(ec) ? _countAvailableTargets(source) : 0; 1365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& U_EXPORT2 Transliterator::getAvailableTarget(int32_t index, 1368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString& source, 1369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString& result) { 1370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Mutex lock(®istryMutex); 1371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (HAVE_REGISTRY(ec)) { 1373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _getAvailableTarget(index, source, result); 1374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t U_EXPORT2 Transliterator::countAvailableVariants(const UnicodeString& source, 1379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString& target) { 1380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Mutex lock(®istryMutex); 1381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return HAVE_REGISTRY(ec) ? _countAvailableVariants(source, target) : 0; 1383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& U_EXPORT2 Transliterator::getAvailableVariant(int32_t index, 1386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString& source, 1387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString& target, 1388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString& result) { 1389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Mutex lock(®istryMutex); 1390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode ec = U_ZERO_ERROR; 1391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (HAVE_REGISTRY(ec)) { 1392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _getAvailableVariant(index, source, target, result); 1393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 1395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t Transliterator::_countAvailableSources(void) { 1398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return registry->countAvailableSources(); 1399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& Transliterator::_getAvailableSource(int32_t index, 1402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString& result) { 1403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return registry->getAvailableSource(index, result); 1404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t Transliterator::_countAvailableTargets(const UnicodeString& source) { 1407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return registry->countAvailableTargets(source); 1408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& Transliterator::_getAvailableTarget(int32_t index, 1411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString& source, 1412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString& result) { 1413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return registry->getAvailableTarget(index, source, result); 1414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t Transliterator::_countAvailableVariants(const UnicodeString& source, 1417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString& target) { 1418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return registry->countAvailableVariants(source, target); 1419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString& Transliterator::_getAvailableVariant(int32_t index, 1422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString& source, 1423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeString& target, 1424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString& result) { 1425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return registry->getAvailableVariant(index, source, target, result); 1426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef U_USE_DEPRECATED_TRANSLITERATOR_API 1429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 1431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Method for subclasses to use to obtain a character in the given 1432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * string, with filtering. 1433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @deprecated the new architecture provides filtering at the top 1434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * level. This method will be removed Dec 31 2001. 1435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 1436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UChar Transliterator::filteredCharAt(const Replaceable& text, int32_t i) const { 1437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar c; 1438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UnicodeFilter* localFilter = getFilter(); 1439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (localFilter == 0) ? text.charAt(i) : 1440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (localFilter->contains(c = text.charAt(i)) ? c : (UChar)0xFFFE); 1441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 1444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 1446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * If the registry is initialized, return TRUE. If not, initialize it 1447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * and return TRUE. If the registry cannot be initialized, return 1448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * FALSE (rare). 1449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 1450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * IMPORTANT: Upon entry, registryMutex must be LOCKED. The entire 1451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * initialization is done with the lock held. There is NO REASON to 1452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * unlock, since no other thread that is waiting on the registryMutex 1453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * cannot itself proceed until the registry is initialized. 1454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 1455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool Transliterator::initializeRegistry(UErrorCode &status) { 1456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (registry != 0) { 1457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 1458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry = new TransliteratorRegistry(status); 1461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (registry == 0 || U_FAILURE(status)) { 1462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete registry; 1463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry = 0; 1464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; // can't create registry, no recovery 1465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* The following code parses the index table located in 1468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * icu/data/translit/root.txt. The index is an n x 4 table 1469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * that follows this format: 1470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <id>{ 1471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * file{ 1472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * resource{"<resource>"} 1473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * direction{"<direction>"} 1474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * } 1475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * } 1476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <id>{ 1477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * internal{ 1478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * resource{"<resource>"} 1479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * direction{"<direction"} 1480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * } 1481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * } 1482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <id>{ 1483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * alias{"<getInstanceArg"} 1484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * } 1485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <id> is the ID of the system transliterator being defined. These 1486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * are public IDs enumerated by Transliterator.getAvailableIDs(), 1487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * unless the second field is "internal". 1488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 1489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <resource> is a ResourceReader resource name. Currently these refer 1490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * to file names under com/ibm/text/resources. This string is passed 1491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * directly to ResourceReader, together with <encoding>. 1492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 1493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <direction> is either "FORWARD" or "REVERSE". 1494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 1495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <getInstanceArg> is a string to be passed directly to 1496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Transliterator.getInstance(). The returned Transliterator object 1497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * then has its ID changed to <id> and is returned. 1498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 1499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The extra blank field on "alias" lines is to make the array square. 1500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 1501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //static const char translit_index[] = "translit_index"; 1502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle *bundle, *transIDs, *colBund; 1504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bundle = ures_open(U_ICUDATA_TRANSLIT, NULL/*open default locale*/, &status); 1505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) transIDs = ures_getByKey(bundle, RB_RULE_BASED_IDS, 0, &status); 1506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t row, maxRows; 1508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status)) { 1509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) maxRows = ures_getSize(transIDs); 1510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (row = 0; row < maxRows; row++) { 1511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) colBund = ures_getByIndex(transIDs, row, 0, &status); 1512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status)) { 1513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString id(ures_getKey(colBund), -1, US_INV); 1514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle* res = ures_getNextResource(colBund, NULL, &status); 1515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char* typeStr = ures_getKey(res); 1516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar type; 1517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_charsToUChars(typeStr, &type, 1); 1518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status)) { 1520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len = 0; 1521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *resString; 1522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch (type) { 1523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 0x66: // 'f' 1524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 0x69: // 'i' 1525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 'file' or 'internal'; 1526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // row[2]=resource, row[3]=direction 1527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 1528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resString = ures_getStringByKey(res, "resource", &len, &status); 1530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool visible = (type == 0x0066 /*f*/); 1531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTransDirection dir = 1532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (ures_getUnicodeStringByKey(res, "direction", &status).charAt(0) == 1533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 0x0046 /*F*/) ? 1534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTRANS_FORWARD : UTRANS_REVERSE; 1535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry->put(id, UnicodeString(TRUE, resString, len), dir, TRUE, visible, status); 1536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 0x61: // 'a' 1539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 'alias'; row[2]=createInstance argument 1540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) resString = ures_getString(res, &len, &status); 1541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry->put(id, UnicodeString(TRUE, resString, len), TRUE, TRUE, status); 1542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 1543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(res); 1546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(colBund); 1548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(transIDs); 1552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(bundle); 1553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Manually add prototypes that the system knows about to the 1555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // cache. This is how new non-rule-based transliterators are 1556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // added to the system. 1557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // This is to allow for null pointer check 1559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NullTransliterator* tempNullTranslit = new NullTransliterator(); 1560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) LowercaseTransliterator* tempLowercaseTranslit = new LowercaseTransliterator(); 1561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UppercaseTransliterator* tempUppercaseTranslit = new UppercaseTransliterator(); 1562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TitlecaseTransliterator* tempTitlecaseTranslit = new TitlecaseTransliterator(); 1563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeNameTransliterator* tempUnicodeTranslit = new UnicodeNameTransliterator(); 1564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NameUnicodeTransliterator* tempNameUnicodeTranslit = new NameUnicodeTransliterator(); 1565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_BREAK_ITERATION 1566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // TODO: could or should these transliterators be referenced polymorphically once constructed? 1567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) BreakTransliterator* tempBreakTranslit = new BreakTransliterator(); 1568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 1569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Check for null pointers 1570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (tempNullTranslit == NULL || tempLowercaseTranslit == NULL || tempUppercaseTranslit == NULL || 1571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempTitlecaseTranslit == NULL || tempUnicodeTranslit == NULL || 1572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_BREAK_ITERATION 1573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempBreakTranslit == NULL || 1574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 1575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempNameUnicodeTranslit == NULL ) 1576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 1577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete tempNullTranslit; 1578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete tempLowercaseTranslit; 1579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete tempUppercaseTranslit; 1580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete tempTitlecaseTranslit; 1581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete tempUnicodeTranslit; 1582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete tempNameUnicodeTranslit; 1583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_BREAK_ITERATION 1584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete tempBreakTranslit; 1585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 1586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Since there was an error, remove registry 1587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete registry; 1588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry = NULL; 1589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 1591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 1592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry->put(tempNullTranslit, TRUE, status); 1595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry->put(tempLowercaseTranslit, TRUE, status); 1596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry->put(tempUppercaseTranslit, TRUE, status); 1597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry->put(tempTitlecaseTranslit, TRUE, status); 1598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry->put(tempUnicodeTranslit, TRUE, status); 1599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry->put(tempNameUnicodeTranslit, TRUE, status); 1600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_BREAK_ITERATION 1601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry->put(tempBreakTranslit, FALSE, status); // FALSE means invisible. 1602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 1603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) RemoveTransliterator::registerIDs(); // Must be within mutex 1605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) EscapeTransliterator::registerIDs(); 1606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnescapeTransliterator::registerIDs(); 1607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NormalizationTransliterator::registerIDs(); 1608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) AnyTransliterator::registerIDs(); 1609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _registerSpecialInverse(UNICODE_STRING_SIMPLE("Null"), 1611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNICODE_STRING_SIMPLE("Null"), FALSE); 1612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _registerSpecialInverse(UNICODE_STRING_SIMPLE("Upper"), 1613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNICODE_STRING_SIMPLE("Lower"), TRUE); 1614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _registerSpecialInverse(UNICODE_STRING_SIMPLE("Title"), 1615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UNICODE_STRING_SIMPLE("Lower"), FALSE); 1616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucln_i18n_registerCleanup(UCLN_I18N_TRANSLITERATOR, utrans_transliterator_cleanup); 1618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 1620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_END 1623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Defined in ucln_in.h: 1625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 1627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Release all static memory held by transliterator. This will 1628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * necessarily invalidate any rule-based transliterators held by the 1629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * user, because RBTs hold pointers to common data objects. 1630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 1631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CFUNC UBool utrans_transliterator_cleanup(void) { 1632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U_NAMESPACE_USE 1633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) TransliteratorIDParser::cleanup(); 1634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (registry) { 1635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete registry; 1636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) registry = NULL; 1637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_destroy(®istryMutex); 1639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 1640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_TRANSLITERATION */ 1643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//eof 1645