16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ********************************************************************** 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copyright (C) 1999-2012, International Business Machines 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Corporation and others. All Rights Reserved. 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ********************************************************************** 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Date Name Description 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 11/17/99 aliu Creation. 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ********************************************************************** 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "utypeinfo.h" // for 'typeid' to work 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_TRANSLITERATION 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/putil.h" 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/translit.h" 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/locid.h" 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/msgfmt.h" 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/rep.h" 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/resbund.h" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/unifilt.h" 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uniset.h" 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uscript.h" 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/strenum.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utf16.h" 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cpdtrans.h" 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "nultrans.h" 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "rbt_data.h" 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "rbt_pars.h" 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "rbt.h" 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "transreg.h" 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "name2uni.h" 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "nortrans.h" 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "remtrans.h" 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "titletrn.h" 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "tolowtrn.h" 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "toupptrn.h" 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uni2name.h" 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "brktrans.h" 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "esctrn.h" 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unesctrn.h" 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "tridpars.h" 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "anytrans.h" 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "util.h" 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "hash.h" 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "mutex.h" 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucln_in.h" 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h" 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uinvchar.h" 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar TARGET_SEP = 0x002D; /*-*/ 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_DELIM = 0x003B; /*;*/ 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar VARIANT_SEP = 0x002F; // '/' 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Prefix for resource bundle key for the display name for a 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * transliterator. The ID is appended to this to form the key. 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The resource bundle value should be a String. 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char RB_DISPLAY_NAME_PREFIX[] = "%Translit%%"; 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Prefix for resource bundle key for the display name for a 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * transliterator SCRIPT. The ID is appended to this to form the key. 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The resource bundle value should be a String. 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char RB_SCRIPT_DISPLAY_NAME_PREFIX[] = "%Translit%"; 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Resource bundle key for display name pattern. 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The resource bundle value should be a String forming a 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * MessageFormat pattern, e.g.: 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * "{0,choice,0#|1#{1} Transliterator|2#{1} to {2} Transliterator}". 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char RB_DISPLAY_NAME_PATTERN[] = "TransliteratorNamePattern"; 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Resource bundle key for the list of RuleBasedTransliterator IDs. 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The resource bundle value should be a String[] with each element 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * being a valid ID. The ID will be appended to RB_RULE_BASED_PREFIX 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to obtain the class name in which the RB_RULE key will be sought. 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char RB_RULE_BASED_IDS[] = "RuleBasedTransliteratorIDs"; 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The mutex controlling access to registry object. 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UMutex registryMutex = U_MUTEX_INITIALIZER; 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * System transliterator registry; non-null when initialized. 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::TransliteratorRegistry* registry = 0; 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Macro to check/initialize the registry. ONLY USE WITHIN 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// MUTEX. Avoids function call when registry is initialized. 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define HAVE_REGISTRY(status) (registry!=0 || initializeRegistry(status)) 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(Transliterator) 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Return TRUE if the given UTransPosition is valid for text of 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the given length. 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic inline UBool positionIsValid(UTransPosition& index, int32_t len) { 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return !(index.contextStart < 0 || 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.start < index.contextStart || 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.limit < index.start || 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.contextLimit < index.limit || 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org len < index.contextLimit); 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Default constructor. 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param theID the string identifier for this transliterator 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param theFilter the filter. Any character for which 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <tt>filter.contains()</tt> returns <tt>FALSE</tt> will not be 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * altered by this transliterator. If <tt>filter</tt> is 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <tt>null</tt> then no filtering is applied. 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator::Transliterator(const UnicodeString& theID, 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeFilter* adoptedFilter) : 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UObject(), ID(theID), filter(adoptedFilter), 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org maximumContextLength(0) 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // NUL-terminate the ID string, which is a non-aliased copy. 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID.append((UChar)0); 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID.truncate(ID.length()-1); 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Destructor. 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator::~Transliterator() { 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (filter) { 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete filter; 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copy constructor. 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator::Transliterator(const Transliterator& other) : 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UObject(other), ID(other.ID), filter(0), 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org maximumContextLength(other.maximumContextLength) 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // NUL-terminate the ID string, which is a non-aliased copy. 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID.append((UChar)0); 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID.truncate(ID.length()-1); 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (other.filter != 0) { 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We own the filter, so we must have our own copy 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filter = (UnicodeFilter*) other.filter->clone(); 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator* Transliterator::clone() const { 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Assignment operator. 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator& Transliterator::operator=(const Transliterator& other) { 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID = other.ID; 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // NUL-terminate the ID string 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID.getTerminatedBuffer(); 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org maximumContextLength = other.maximumContextLength; 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org adoptFilter((other.filter == 0) ? 0 : (UnicodeFilter*) other.filter->clone()); 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return *this; 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Transliterates a segment of a string. <code>Transliterator</code> API. 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param text the string to be transliterated 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param start the beginning index, inclusive; <code>0 <= start 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <= limit</code>. 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param limit the ending index, exclusive; <code>start <= limit 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <= text.length()</code>. 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return the new limit index, or -1 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t Transliterator::transliterate(Replaceable& text, 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t start, int32_t limit) const { 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (start < 0 || 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit < start || 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org text.length() < limit) { 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTransPosition offsets; 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets.contextStart= start; 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets.contextLimit = limit; 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets.start = start; 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offsets.limit = limit; 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filteredTransliterate(text, offsets, FALSE, TRUE); 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return offsets.limit; 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Transliterates an entire string in place. Convenience method. 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param text the string to be transliterated 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::transliterate(Replaceable& text) const { 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org transliterate(text, 0, text.length()); 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Transliterates the portion of the text buffer that can be 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * transliterated unambiguosly after new text has been inserted, 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * typically as a result of a keyboard event. The new text in 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>insertion</code> will be inserted into <code>text</code> 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * at <code>index.contextLimit</code>, advancing 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>index.contextLimit</code> by <code>insertion.length()</code>. 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Then the transliterator will try to transliterate characters of 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>text</code> between <code>index.start</code> and 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>index.contextLimit</code>. Characters before 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>index.start</code> will not be changed. 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <p>Upon return, values in <code>index</code> will be updated. 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>index.contextStart</code> will be advanced to the first 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * character that future calls to this method will read. 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>index.start</code> and <code>index.contextLimit</code> will 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * be adjusted to delimit the range of text that future calls to 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * this method may change. 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <p>Typical usage of this method begins with an initial call 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * with <code>index.contextStart</code> and <code>index.contextLimit</code> 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * set to indicate the portion of <code>text</code> to be 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * transliterated, and <code>index.start == index.contextStart</code>. 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Thereafter, <code>index</code> can be used without 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * modification in future calls, provided that all changes to 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>text</code> are made via this method. 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <p>This method assumes that future calls may be made that will 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * insert new text into the buffer. As a result, it only performs 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * unambiguous transliterations. After the last call to this 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * method, there may be untransliterated text that is waiting for 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * more input to resolve an ambiguity. In order to perform these 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * pending transliterations, clients should call {@link 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * #finishKeyboardTransliteration} after the last call to this 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * method has been made. 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param text the buffer holding transliterated and untransliterated text 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param index an array of three integers. 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <ul><li><code>index.contextStart</code>: the beginning index, 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * inclusive; <code>0 <= index.contextStart <= index.contextLimit</code>. 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <li><code>index.contextLimit</code>: the ending index, exclusive; 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>index.contextStart <= index.contextLimit <= text.length()</code>. 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>insertion</code> is inserted at 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>index.contextLimit</code>. 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <li><code>index.start</code>: the next character to be 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * considered for transliteration; <code>index.contextStart <= 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * index.start <= index.contextLimit</code>. Characters before 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>index.start</code> will not be changed by future calls 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to this method.</ul> 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param insertion text to be inserted and possibly 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * transliterated into the translation buffer at 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>index.contextLimit</code>. If <code>null</code> then no text 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * is inserted. 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #START 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #LIMIT 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #CURSOR 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #handleTransliterate 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @exception IllegalArgumentException if <code>index</code> 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * is invalid 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::transliterate(Replaceable& text, 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTransPosition& index, 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& insertion, 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode &status) const { 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _transliterate(text, index, &insertion, status); 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Transliterates the portion of the text buffer that can be 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * transliterated unambiguosly after a new character has been 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * inserted, typically as a result of a keyboard event. This is a 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * convenience method; see {@link 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * #transliterate(Replaceable, int[], String)} for details. 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param text the buffer holding transliterated and 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * untransliterated text 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param index an array of three integers. See {@link 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * #transliterate(Replaceable, int[], String)}. 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param insertion text to be inserted and possibly 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * transliterated into the translation buffer at 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>index.contextLimit</code>. 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #transliterate(Replaceable, int[], String) 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::transliterate(Replaceable& text, 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTransPosition& index, 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 insertion, 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) const { 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString str(insertion); 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _transliterate(text, index, &str, status); 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Transliterates the portion of the text buffer that can be 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * transliterated unambiguosly. This is a convenience method; see 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * {@link #transliterate(Replaceable, int[], String)} for 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * details. 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param text the buffer holding transliterated and 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * untransliterated text 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param index an array of three integers. See {@link 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * #transliterate(Replaceable, int[], String)}. 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #transliterate(Replaceable, int[], String) 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::transliterate(Replaceable& text, 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTransPosition& index, 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) const { 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _transliterate(text, index, 0, status); 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Finishes any pending transliterations that were waiting for 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * more characters. Clients should call this method as the last 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * call after a sequence of one or more calls to 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>transliterate()</code>. 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param text the buffer holding transliterated and 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * untransliterated text. 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param index the array of indices previously passed to {@link 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * #transliterate} 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::finishTransliteration(Replaceable& text, 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTransPosition& index) const { 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!positionIsValid(index, text.length())) { 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filteredTransliterate(text, index, FALSE, TRUE); 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This internal method does keyboard transliteration. If the 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 'insertion' is non-null then we append it to 'text' before 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * proceeding. This method calls through to the pure virtual 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * framework method handleTransliterate() to do the actual 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * work. 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::_transliterate(Replaceable& text, 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTransPosition& index, 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString* insertion, 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode &status) const { 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!positionIsValid(index, text.length())) { 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ILLEGAL_ARGUMENT_ERROR; 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// int32_t originalStart = index.contextStart; 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (insertion != 0) { 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org text.handleReplaceBetween(index.limit, index.limit, *insertion); 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.limit += insertion->length(); 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.contextLimit += insertion->length(); 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (index.limit > 0 && 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U16_IS_LEAD(text.charAt(index.limit - 1))) { 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Oops, there is a dangling lead surrogate in the buffer. 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This will break most transliterators, since they will 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // assume it is part of a pair. Don't transliterate until 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // more text comes in. 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filteredTransliterate(text, index, TRUE, TRUE); 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if 0 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // TODO 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // I CAN'T DO what I'm attempting below now that the Kleene star 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // operator is supported. For example, in the rule 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // ([:Lu:]+) { x } > $1; 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // what is the maximum context length? getMaximumContextLength() 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // will return 1, but this is just the length of the ante context 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // part of the pattern string -- 1 character, which is a standin 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // for a Quantifier, which contains a StringMatcher, which 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // contains a UnicodeSet. 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // There is a complicated way to make this work again, and that's 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // to add a "maximum left context" protocol into the 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // UnicodeMatcher hierarchy. At present I'm not convinced this is 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // worth it. 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // --- 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The purpose of the code below is to keep the context small 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // while doing incremental transliteration. When part of the left 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // context (between contextStart and start) is no longer needed, 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // we try to advance contextStart past that portion. We use the 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // maximum context length to do so. 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t newCS = index.start; 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t n = getMaximumContextLength(); 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (newCS > originalStart && n-- > 0) { 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org --newCS; 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newCS -= U16_LENGTH(text.char32At(newCS)) - 1; 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.contextStart = uprv_max(newCS, originalStart); 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This method breaks up the input text into runs of unfiltered 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * characters. It passes each such run to 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <subclass>.handleTransliterate(). Subclasses that can handle the 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * filter logic more efficiently themselves may override this method. 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * All transliteration calls in this class go through this method. 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::filteredTransliterate(Replaceable& text, 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTransPosition& index, 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool incremental, 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool rollback) const { 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Short circuit path for transliterators with no filter in 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // non-incremental mode. 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (filter == 0 && !rollback) { 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org handleTransliterate(text, index, incremental); 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //---------------------------------------------------------------------- 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This method processes text in two groupings: 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // RUNS -- A run is a contiguous group of characters which are contained 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // in the filter for this transliterator (filter.contains(ch) == TRUE). 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Text outside of runs may appear as context but it is not modified. 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The start and limit Position values are narrowed to each run. 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // PASSES (incremental only) -- To make incremental mode work correctly, 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // each run is broken up into n passes, where n is the length (in code 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // points) of the run. Each pass contains the first n characters. If a 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // pass is completely transliterated, it is committed, and further passes 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // include characters after the committed text. If a pass is blocked, 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // and does not transliterate completely, then this method rolls back 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the changes made during the pass, extends the pass by one code point, 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // and tries again. 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //---------------------------------------------------------------------- 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // globalLimit is the limit value for the entire operation. We 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // set index.limit to the end of each unfiltered run before 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // calling handleTransliterate(), so we need to maintain the real 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // value of index.limit here. After each transliteration, we 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // update globalLimit for insertions or deletions that have 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // happened. 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t globalLimit = index.limit; 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // If there is a non-null filter, then break the input text up. Say the 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // input text has the form: 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // xxxabcxxdefxx 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // where 'x' represents a filtered character (filter.contains('x') == 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // false). Then we break this up into: 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // xxxabc xxdef xx 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Each pass through the loop consumes a run of filtered 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // characters (which are ignored) and a subsequent run of 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // unfiltered characters (which are transliterated). 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (;;) { 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (filter != NULL) { 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Narrow the range to be transliterated to the first segment 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // of unfiltered characters at or after index.start. 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Advance past filtered chars 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 c; 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (index.start < globalLimit && 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org !filter->contains(c=text.char32At(index.start))) { 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.start += U16_LENGTH(c); 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Find the end of this run of unfiltered chars 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.limit = index.start; 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (index.limit < globalLimit && 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filter->contains(c=text.char32At(index.limit))) { 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.limit += U16_LENGTH(c); 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check to see if the unfiltered run is empty. This only 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // happens at the end of the string when all the remaining 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // characters are filtered. 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (index.limit == index.start) { 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // assert(index.start == globalLimit); 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Is this run incremental? If there is additional 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // filtered text (if limit < globalLimit) then we pass in 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // an incremental value of FALSE to force the subclass to 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // complete the transliteration for this run. 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool isIncrementalRun = 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (index.limit < globalLimit ? FALSE : incremental); 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t delta; 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Implement rollback. To understand the need for rollback, 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // consider the following transliterator: 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // "t" is "a > A;" 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // "u" is "A > b;" 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // "v" is a compound of "t; NFD; u" with a filter [:Ll:] 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Now apply "c" to the input text "a". The result is "b". But if 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the transliteration is done incrementally, then the NFD holds 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // things up after "t" has already transformed "a" to "A". When 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // finishTransliterate() is called, "A" is _not_ processed because 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // it gets excluded by the [:Ll:] filter, and the end result is "A" 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // -- incorrect. The problem is that the filter is applied to a 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // partially-transliterated result, when we only want it to apply to 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // input text. Although this example hinges on a compound 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // transliterator containing NFD and a specific filter, it can 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // actually happen with any transliterator which may do a partial 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // transformation in incremental mode into characters outside its 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // filter. 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // To handle this, when in incremental mode we supply characters to 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // handleTransliterate() in several passes. Each pass adds one more 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // input character to the input text. That is, for input "ABCD", we 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // first try "A", then "AB", then "ABC", and finally "ABCD". If at 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // any point we block (upon return, start < limit) then we roll 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // back. If at any point we complete the run (upon return start == 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // limit) then we commit that run. 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (rollback && isIncrementalRun) { 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t runStart = index.start; 5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t runLimit = index.limit; 5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t runLength = runLimit - runStart; 5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Make a rollback copy at the end of the string 5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t rollbackOrigin = text.length(); 5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org text.copy(runStart, runLimit, rollbackOrigin); 5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Variables reflecting the commitment of completely 5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // transliterated text. passStart is the runStart, advanced 5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // past committed text. rollbackStart is the rollbackOrigin, 5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // advanced past rollback text that corresponds to committed 5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // text. 5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t passStart = runStart; 5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t rollbackStart = rollbackOrigin; 5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The limit for each pass; we advance by one code point with 5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // each iteration. 5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t passLimit = index.start; 5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Total length, in 16-bit code units, of uncommitted text. 5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This is the length to be rolled back. 5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t uncommittedLength = 0; 5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Total delta (change in length) for all passes 5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t totalDelta = 0; 5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // PASS MAIN LOOP -- Start with a single character, and extend 5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the text by one character at a time. Roll back partial 5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // transliterations and commit complete transliterations. 5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (;;) { 5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Length of additional code point, either one or two 5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t charLength = U16_LENGTH(text.char32At(passLimit)); 5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org passLimit += charLength; 5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (passLimit > runLimit) { 5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uncommittedLength += charLength; 5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.limit = passLimit; 5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Delegate to subclass for actual transliteration. Upon 5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // return, start will be updated to point after the 5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // transliterated text, and limit and contextLimit will be 5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // adjusted for length changes. 5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org handleTransliterate(text, index, TRUE); 5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delta = index.limit - passLimit; // change in length 5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We failed to completely transliterate this pass. 5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Roll back the text. Indices remain unchanged; reset 5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // them where necessary. 5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (index.start != index.limit) { 5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Find the rollbackStart, adjusted for length changes 5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // and the deletion of partially transliterated text. 5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t rs = rollbackStart + delta - (index.limit - passStart); 5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Delete the partially transliterated text 5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org text.handleReplaceBetween(passStart, index.limit, UnicodeString()); 5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Copy the rollback text back 6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org text.copy(rs, rs + uncommittedLength, passStart); 6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Restore indices to their original values 6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.start = passStart; 6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.limit = passLimit; 6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.contextLimit -= delta; 6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We did completely transliterate this pass. Update the 6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // commit indices to record how far we got. Adjust indices 6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // for length change. 6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Move the pass indices past the committed text. 6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org passStart = passLimit = index.start; 6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Adjust the rollbackStart for length changes and move 6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // it past the committed text. All characters we've 6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // processed to this point are committed now, so zero 6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // out the uncommittedLength. 6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rollbackStart += delta + uncommittedLength; 6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uncommittedLength = 0; 6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Adjust indices for length changes. 6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org runLimit += delta; 6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org totalDelta += delta; 6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Adjust overall limit and rollbackOrigin for insertions and 6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // deletions. Don't need to worry about contextLimit because 6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // handleTransliterate() maintains that. 6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rollbackOrigin += totalDelta; 6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org globalLimit += totalDelta; 6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Delete the rollback copy 6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org text.handleReplaceBetween(rollbackOrigin, rollbackOrigin + runLength, UnicodeString()); 6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Move start past committed text 6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.start = passStart; 6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Delegate to subclass for actual transliteration. 6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t limit = index.limit; 6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org handleTransliterate(text, index, isIncrementalRun); 6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delta = index.limit - limit; // change in length 6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // In a properly written transliterator, start == limit after 6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // handleTransliterate() returns when incremental is false. 6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Catch cases where the subclass doesn't do this, and throw 6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // an exception. (Just pinning start to limit is a bad idea, 6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // because what's probably happening is that the subclass 6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // isn't transliterating all the way to the end, and it should 6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // in non-incremental mode.) 6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!incremental && index.start != index.limit) { 6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We can't throw an exception, so just fudge things 6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.start = index.limit; 6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Adjust overall limit for insertions/deletions. Don't need 6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // to worry about contextLimit because handleTransliterate() 6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // maintains that. 6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org globalLimit += delta; 6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (filter == NULL || isIncrementalRun) { 6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // If we did completely transliterate this 6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // run, then repeat with the next unfiltered run. 6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Start is valid where it is. Limit needs to be put back where 6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // it was, modulo adjustments for deletions/insertions. 6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index.limit = globalLimit; 6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::filteredTransliterate(Replaceable& text, 6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTransPosition& index, 6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool incremental) const { 6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filteredTransliterate(text, index, incremental, FALSE); 6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Method for subclasses to use to set the maximum context length. 6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #getMaximumContextLength 6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::setMaximumContextLength(int32_t maxContextLength) { 6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org maximumContextLength = maxContextLength; 6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns a programmatic identifier for this transliterator. 6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If this identifier is passed to <code>getInstance()</code>, it 6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * will return this object, if it has been registered. 6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #registerInstance 6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #getAvailableIDs 6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UnicodeString& Transliterator::getID(void) const { 7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ID; 7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns a name for this transliterator that is appropriate for 7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * display to the user in the default locale. See {@link 7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * #getDisplayName(Locale)} for details. 7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& U_EXPORT2 Transliterator::getDisplayName(const UnicodeString& ID, 7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& result) { 7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return getDisplayName(ID, Locale::getDefault(), result); 7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns a name for this transliterator that is appropriate for 7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * display to the user in the given locale. This name is taken 7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * from the locale resource data in the standard manner of the 7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>java.text</code> package. 7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <p>If no localized names exist in the system resource bundles, 7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * a name is synthesized using a localized 7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>MessageFormat</code> pattern from the resource data. The 7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * arguments to this pattern are an integer followed by one or two 7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * strings. The integer is the number of strings, either 1 or 2. 7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The strings are formed by splitting the ID for this 7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * transliterator at the first TARGET_SEP. If there is no TARGET_SEP, then the 7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * entire ID forms the only string. 7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param inLocale the Locale in which the display name should be 7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * localized. 7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see java.text.MessageFormat 7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& U_EXPORT2 Transliterator::getDisplayName(const UnicodeString& id, 7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Locale& inLocale, 7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& result) { 7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ResourceBundle bundle(U_ICUDATA_TRANSLIT, inLocale, status); 7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Suspend checking status until later... 7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.truncate(0); 7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Normalize the ID 7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString source, target, variant; 7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool sawSource; 7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TransliteratorIDParser::IDtoSTV(id, source, target, variant, sawSource); 7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (target.length() < 1) { 7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No target; malformed id 7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (variant.length() > 0) { // Change "Foo" to "/Foo" 7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org variant.insert(0, VARIANT_SEP); 7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString ID(source); 7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID.append(TARGET_SEP).append(target).append(variant); 7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // build the char* key 7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (uprv_isInvariantUString(ID.getBuffer(), ID.length())) { 7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char key[200]; 7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_strcpy(key, RB_DISPLAY_NAME_PREFIX); 7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length=(int32_t)uprv_strlen(RB_DISPLAY_NAME_PREFIX); 7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID.extract(0, (int32_t)(sizeof(key)-length), key+length, (int32_t)(sizeof(key)-length), US_INV); 7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Try to retrieve a UnicodeString from the bundle. 7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString resString = bundle.getStringEx(key, status); 7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status) && resString.length() != 0) { 7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result = resString; // [sic] assign & return 7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_FORMATTING 7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We have failed to get a name from the locale data. This is 7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // typical, since most transliterators will not have localized 7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // name data. The next step is to retrieve the MessageFormat 7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // pattern from the locale data and to use it to synthesize the 7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // name from the ID. 7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ZERO_ERROR; 7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resString = bundle.getStringEx(RB_DISPLAY_NAME_PATTERN, status); 7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status) && resString.length() != 0) { 7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MessageFormat msg(resString, inLocale, status); 7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Suspend checking status until later... 7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We pass either 2 or 3 Formattable objects to msg. 7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Formattable args[3]; 7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t nargs; 7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args[0].setLong(2); // # of args to follow 7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args[1].setString(source); 7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args[2].setString(target); 7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nargs = 3; 7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Use display names for the scripts, if they exist 7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString s; 7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=(int32_t)uprv_strlen(RB_SCRIPT_DISPLAY_NAME_PREFIX); 7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int j=1; j<=2; ++j) { 7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ZERO_ERROR; 7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_strcpy(key, RB_SCRIPT_DISPLAY_NAME_PREFIX); 7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args[j].getString(s); 8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (uprv_isInvariantUString(s.getBuffer(), s.length())) { 8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org s.extract(0, sizeof(key)-length-1, key+length, (int32_t)sizeof(key)-length-1, US_INV); 8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resString = bundle.getStringEx(key, status); 8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org args[j] = resString; 8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ZERO_ERROR; 8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPosition pos; // ignored by msg 8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msg.format(args, nargs, result, pos, status); 8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.append(variant); 8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We should not reach this point unless there is something 8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // wrong with the build or the RB_DISPLAY_NAME_PATTERN has 8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // been deleted from the root RB_LOCALE_ELEMENTS resource. 8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = ID; 8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns the filter used by this transliterator, or <tt>null</tt> 8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * if this transliterator uses no filter. Caller musn't delete 8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the result! 8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UnicodeFilter* Transliterator::getFilter(void) const { 8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return filter; 8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns the filter used by this transliterator, or 8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <tt>NULL</tt> if this transliterator uses no filter. The 8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * caller must eventually delete the result. After this call, 8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * this transliterator's filter is set to <tt>NULL</tt>. 8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeFilter* Transliterator::orphanFilter(void) { 8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeFilter *result = filter; 8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filter = NULL; 8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Changes the filter used by this transliterator. If the filter 8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * is set to <tt>null</tt> then no filtering will occur. 8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <p>Callers must take care if a transliterator is in use by 8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * multiple threads. The filter should not be changed by one 8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * thread while another thread may be transliterating. 8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::adoptFilter(UnicodeFilter* filterToAdopt) { 8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete filter; 8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filter = filterToAdopt; 8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns this transliterator's inverse. See the class 8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * documentation for details. This implementation simply inverts 8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the two entities in the ID and attempts to retrieve the 8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * resulting transliterator. That is, if <code>getID()</code> 8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * returns "A-B", then this method will return the result of 8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>getInstance("B-A")</code>, or <code>null</code> if that 8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * call fails. 8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <p>This method does not take filtering into account. The 8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * returned transliterator will have no filter. 8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <p>Subclasses with knowledge of their inverse may wish to 8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * override this method. 8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return a transliterator that is an inverse, not necessarily 8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * exact, of this transliterator, or <code>null</code> if no such 8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * transliterator is registered. 8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #registerInstance 8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator* Transliterator::createInverse(UErrorCode& status) const { 8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError parseError; 8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return Transliterator::createInstance(ID, UTRANS_REVERSE,parseError,status); 8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator* U_EXPORT2 8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator::createInstance(const UnicodeString& ID, 8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTransDirection dir, 8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) 8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError parseError; 8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return createInstance(ID, dir, parseError, status); 8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns a <code>Transliterator</code> object given its ID. 8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The ID must be either a system transliterator ID or a ID registered 9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * using <code>registerInstance()</code>. 9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param ID a valid ID, as enumerated by <code>getAvailableIDs()</code> 9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return A <code>Transliterator</code> object with the given ID 9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #registerInstance 9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #getAvailableIDs 9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #getID 9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator* U_EXPORT2 9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator::createInstance(const UnicodeString& ID, 9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTransDirection dir, 9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError& parseError, 9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) 9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString canonID; 9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVector list(status); 9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeSet* globalFilter; 9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // TODO add code for parseError...currently unused, but 9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // later may be used by parsing code... 9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!TransliteratorIDParser::parseCompoundID(ID, dir, canonID, list, globalFilter)) { 9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_INVALID_ID; 9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TransliteratorIDParser::instantiateList(list, status); 9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(list.size() > 0); 9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Transliterator* t = NULL; 9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (list.size() > 1 || canonID.indexOf(ID_DELIM) >= 0) { 9416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // [NOTE: If it's a compoundID, we instantiate a CompoundTransliterator even if it only 9426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // has one child transliterator. This is so that toRules() will return the right thing 9436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // (without any inactive ID), but our main ID still comes out correct. That is, if we 9446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // instantiate "(Lower);Latin-Greek;", we want the rules to come out as "::Latin-Greek;" 9456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // even though the ID is "(Lower);Latin-Greek;". 9466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t = new CompoundTransliterator(list, parseError, status); 9476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 9496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t = (Transliterator*)list.elementAt(0); 9506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check null pointer 9526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (t != NULL) { 9536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->setID(canonID); 9546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (globalFilter != NULL) { 9556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->adoptFilter(globalFilter); 9566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else if (U_SUCCESS(status)) { 9596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 9606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return t; 9626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 9656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Create a transliterator from a basic ID. This is an ID 9666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * containing only the forward direction source, target, and 9676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * variant. 9686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param id a basic ID of the form S-T or S-T/V. 9696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return a newly created Transliterator or null if the ID is 9706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * invalid. 9716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 9726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator* Transliterator::createBasicInstance(const UnicodeString& id, 9736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString* canon) { 9746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError pe; 9756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 9766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TransliteratorAlias* alias = 0; 9776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Transliterator* t = 0; 9786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(®istryMutex); 9806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (HAVE_REGISTRY(ec)) { 9816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t = registry->get(id, alias, ec); 9826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(®istryMutex); 9846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) { 9866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete t; 9876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete alias; 9886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 9896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We may have not gotten a transliterator: Because we can't 9926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // instantiate a transliterator from inside TransliteratorRegistry:: 9936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // get() (that would deadlock), we sometimes pass back an alias. This 9946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // contains the data we need to finish the instantiation outside the 9956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // registry mutex. The alias may, in turn, generate another alias, so 9966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // we handle aliases in a loop. The max times through the loop is two. 9976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // [alan] 9986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (alias != 0) { 9996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(t==0); 10006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Rule-based aliases are handled with TransliteratorAlias:: 10016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // parse(), followed by TransliteratorRegistry::reget(). 10026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Other aliases are handled with TransliteratorAlias::create(). 10036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (alias->isRuleBased()) { 10046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Step 1. parse 10056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TransliteratorParser parser(ec); 10066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org alias->parse(parser, pe, ec); 10076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete alias; 10086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org alias = 0; 10096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Step 2. reget 10116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(®istryMutex); 10126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (HAVE_REGISTRY(ec)) { 10136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t = registry->reget(id, parser, alias, ec); 10146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(®istryMutex); 10166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Step 3. Loop back around! 10186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 10196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t = alias->create(pe, ec); 10206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete alias; 10216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org alias = 0; 10226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 10236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) { 10256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete t; 10266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete alias; 10276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t = NULL; 10286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 10296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (t != NULL && canon != NULL) { 10336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->setID(*canon); 10346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return t; 10376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 10386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 10406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns a <code>Transliterator</code> object constructed from 10416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the given rule string. This will be a RuleBasedTransliterator, 10426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * if the rule string contains only rules, or a 10436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * CompoundTransliterator, if it contains ID blocks, or a 10446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * NullTransliterator, if it contains ID blocks which parse as 10456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * empty for the given direction. 10466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 10476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator* U_EXPORT2 10486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator::createFromRules(const UnicodeString& ID, 10496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& rules, 10506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTransDirection dir, 10516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError& parseError, 10526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) 10536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 10546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Transliterator* t = NULL; 10556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TransliteratorParser parser(status); 10576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org parser.parse(rules, dir, parseError, status); 10586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 10606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 10616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // NOTE: The logic here matches that in TransliteratorRegistry. 10646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (parser.idBlockVector.size() == 0 && parser.dataVector.size() == 0) { 10656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t = new NullTransliterator(); 10666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else if (parser.idBlockVector.size() == 0 && parser.dataVector.size() == 1) { 10686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t = new RuleBasedTransliterator(ID, (TransliterationRuleData*)parser.dataVector.orphanElementAt(0), TRUE); 10696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else if (parser.idBlockVector.size() == 1 && parser.dataVector.size() == 0) { 10716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // idBlock, no data -- this is an alias. The ID has 10726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // been munged from reverse into forward mode, if 10736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // necessary, so instantiate the ID in the forward 10746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // direction. 10756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (parser.compoundFilter != NULL) { 10766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString filterPattern; 10776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org parser.compoundFilter->toPattern(filterPattern, FALSE); 10786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t = createInstance(filterPattern + UnicodeString(ID_DELIM) 10796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org + *((UnicodeString*)parser.idBlockVector.elementAt(0)), UTRANS_FORWARD, parseError, status); 10806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 10826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t = createInstance(*((UnicodeString*)parser.idBlockVector.elementAt(0)), UTRANS_FORWARD, parseError, status); 10836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (t != NULL) { 10866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->setID(ID); 10876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 10906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVector transliterators(status); 10916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t passNumber = 1; 10926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t limit = parser.idBlockVector.size(); 10946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (parser.dataVector.size() > limit) 10956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit = parser.dataVector.size(); 10966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 0; i < limit; i++) { 10986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (i < parser.idBlockVector.size()) { 10996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString* idBlock = (UnicodeString*)parser.idBlockVector.elementAt(i); 11006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!idBlock->isEmpty()) { 11016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Transliterator* temp = createInstance(*idBlock, UTRANS_FORWARD, parseError, status); 11026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (temp != NULL && typeid(*temp) != typeid(NullTransliterator)) 11036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org transliterators.addElement(temp, status); 11046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 11056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete temp; 11066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!parser.dataVector.isEmpty()) { 11096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TransliterationRuleData* data = (TransliterationRuleData*)parser.dataVector.orphanElementAt(0); 11106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // TODO: Should passNumber be turned into a decimal-string representation (1 -> "1")? 11116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RuleBasedTransliterator* temprbt = new RuleBasedTransliterator(UnicodeString(CompoundTransliterator::PASS_STRING) + UnicodeString(passNumber++), 11126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org data, TRUE); 11136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check if NULL before adding it to transliterators to avoid future usage of NULL pointer. 11146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (temprbt == NULL) { 11156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 11166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return t; 11176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org transliterators.addElement(temprbt, status); 11196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t = new CompoundTransliterator(transliterators, passNumber - 1, parseError, status); 11236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Null pointer check 11246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (t != NULL) { 11256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->setID(ID); 11266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->adoptFilter(parser.orphanCompoundFilter()); 11276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status) && t == NULL) { 11306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 11316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return t; 11336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 11346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& Transliterator::toRules(UnicodeString& rulesSource, 11366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool escapeUnprintable) const { 11376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The base class implementation of toRules munges the ID into 11386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the correct format. That is: foo => ::foo 11396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (escapeUnprintable) { 11406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rulesSource.truncate(0); 11416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString id = getID(); 11426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i=0; i<id.length();) { 11436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 c = id.char32At(i); 11446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!ICU_Utility::escapeUnprintable(rulesSource, c)) { 11456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rulesSource.append(c); 11466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i += U16_LENGTH(c); 11486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rulesSource = getID(); 11516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // KEEP in sync with rbt_pars 11536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rulesSource.insert(0, UNICODE_STRING_SIMPLE("::")); 11546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rulesSource.append(ID_DELIM); 11556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return rulesSource; 11566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 11576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t Transliterator::countElements() const { 11596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const CompoundTransliterator* ct = dynamic_cast<const CompoundTransliterator*>(this); 11606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ct != NULL ? ct->getCount() : 0; 11616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 11626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst Transliterator& Transliterator::getElement(int32_t index, UErrorCode& ec) const { 11646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) { 11656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return *this; 11666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const CompoundTransliterator* cpd = dynamic_cast<const CompoundTransliterator*>(this); 11686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t n = (cpd == NULL) ? 1 : cpd->getCount(); 11696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (index < 0 || index >= n) { 11706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ec = U_INDEX_OUTOFBOUNDS_ERROR; 11716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return *this; 11726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (n == 1) ? *this : cpd->getTransliterator(index); 11746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 11766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeSet& Transliterator::getSourceSet(UnicodeSet& result) const { 11786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org handleGetSourceSet(result); 11796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (filter != NULL) { 11806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeSet* filterSet = dynamic_cast<UnicodeSet*>(filter); 11816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool deleteFilterSet = FALSE; 11826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Most, but not all filters will be UnicodeSets. Optimize for 11836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the high-runner case. 11846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (filterSet == NULL) { 11856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filterSet = new UnicodeSet(); 11866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check null pointer 11876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (filterSet == NULL) { 11886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 11896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org deleteFilterSet = TRUE; 11916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org filter->addMatchSetTo(*filterSet); 11926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.retainAll(*filterSet); 11946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (deleteFilterSet) { 11956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete filterSet; 11966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 11996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::handleGetSourceSet(UnicodeSet& result) const { 12026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.clear(); 12036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeSet& Transliterator::getTargetSet(UnicodeSet& result) const { 12066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result.clear(); 12076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// For public consumption 12106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid U_EXPORT2 Transliterator::registerFactory(const UnicodeString& id, 12116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Transliterator::Factory factory, 12126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Transliterator::Token context) { 12136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Mutex lock(®istryMutex); 12146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 12156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (HAVE_REGISTRY(ec)) { 12166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _registerFactory(id, factory, context); 12176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// To be called only by Transliterator subclasses that are called 12216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// to register themselves by initializeRegistry(). 12226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::_registerFactory(const UnicodeString& id, 12236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Transliterator::Factory factory, 12246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Transliterator::Token context) { 12256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 12266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry->put(id, factory, context, TRUE, ec); 12276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// To be called only by Transliterator subclasses that are called 12306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// to register themselves by initializeRegistry(). 12316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::_registerSpecialInverse(const UnicodeString& target, 12326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& inverseTarget, 12336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool bidirectional) { 12346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 12356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TransliteratorIDParser::registerSpecialInverse(target, inverseTarget, bidirectional, status); 12366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 12396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Registers a instance <tt>obj</tt> of a subclass of 12406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>Transliterator</code> with the system. This object must 12416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * implement the <tt>clone()</tt> method. When 12426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <tt>getInstance()</tt> is called with an ID string that is 12436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * equal to <tt>obj.getID()</tt>, then <tt>obj.clone()</tt> is 12446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * returned. 12456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 12466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param obj an instance of subclass of 12476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>Transliterator</code> that defines <tt>clone()</tt> 12486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #getInstance 12496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #unregister 12506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 12516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid U_EXPORT2 Transliterator::registerInstance(Transliterator* adoptedPrototype) { 12526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Mutex lock(®istryMutex); 12536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 12546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (HAVE_REGISTRY(ec)) { 12556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _registerInstance(adoptedPrototype); 12566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::_registerInstance(Transliterator* adoptedPrototype) { 12606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 12616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry->put(adoptedPrototype, TRUE, ec); 12626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid U_EXPORT2 Transliterator::registerAlias(const UnicodeString& aliasID, 12656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& realID) { 12666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Mutex lock(®istryMutex); 12676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 12686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (HAVE_REGISTRY(ec)) { 12696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _registerAlias(aliasID, realID); 12706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid Transliterator::_registerAlias(const UnicodeString& aliasID, 12746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& realID) { 12756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 12766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry->put(aliasID, realID, FALSE, TRUE, ec); 12776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 12806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Unregisters a transliterator or class. This may be either 12816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * a system transliterator or a user transliterator or class. 12826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 12836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param ID the ID of the transliterator or class 12846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @see #registerInstance 12856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 12876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid U_EXPORT2 Transliterator::unregister(const UnicodeString& ID) { 12886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Mutex lock(®istryMutex); 12896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 12906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (HAVE_REGISTRY(ec)) { 12916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry->remove(ID); 12926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 12966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * == OBSOLETE - remove in ICU 3.4 == 12976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Return the number of IDs currently registered with the system. 12986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * To retrieve the actual IDs, call getAvailableID(i) with 12996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * i from 0 to countAvailableIDs() - 1. 13006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 13016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t U_EXPORT2 Transliterator::countAvailableIDs(void) { 13026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t retVal = 0; 13036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Mutex lock(®istryMutex); 13046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 13056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (HAVE_REGISTRY(ec)) { 13066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org retVal = registry->countAvailableIDs(); 13076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return retVal; 13096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 13126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * == OBSOLETE - remove in ICU 3.4 == 13136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Return the index-th available ID. index must be between 0 13146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and countAvailableIDs() - 1, inclusive. If index is out of 13156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * range, the result of getAvailableID(0) is returned. 13166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 13176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UnicodeString& U_EXPORT2 Transliterator::getAvailableID(int32_t index) { 13186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString* result = NULL; 13196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(®istryMutex); 13206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 13216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (HAVE_REGISTRY(ec)) { 13226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = ®istry->getAvailableID(index); 13236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(®istryMutex); 13256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(result != NULL); // fail if no registry 13266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return *result; 13276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgStringEnumeration* U_EXPORT2 Transliterator::getAvailableIDs(UErrorCode& ec) { 13306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) return NULL; 13316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org StringEnumeration* result = NULL; 13326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(®istryMutex); 13336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (HAVE_REGISTRY(ec)) { 13346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = registry->getAvailableIDs(); 13356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(®istryMutex); 13376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (result == NULL) { 13386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ec = U_INTERNAL_TRANSLITERATOR_ERROR; 13396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 13416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t U_EXPORT2 Transliterator::countAvailableSources(void) { 13446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Mutex lock(®istryMutex); 13456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 13466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return HAVE_REGISTRY(ec) ? _countAvailableSources() : 0; 13476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& U_EXPORT2 Transliterator::getAvailableSource(int32_t index, 13506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& result) { 13516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Mutex lock(®istryMutex); 13526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 13536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (HAVE_REGISTRY(ec)) { 13546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _getAvailableSource(index, result); 13556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 13576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t U_EXPORT2 Transliterator::countAvailableTargets(const UnicodeString& source) { 13606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Mutex lock(®istryMutex); 13616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 13626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return HAVE_REGISTRY(ec) ? _countAvailableTargets(source) : 0; 13636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& U_EXPORT2 Transliterator::getAvailableTarget(int32_t index, 13666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& source, 13676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& result) { 13686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Mutex lock(®istryMutex); 13696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 13706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (HAVE_REGISTRY(ec)) { 13716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _getAvailableTarget(index, source, result); 13726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 13746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t U_EXPORT2 Transliterator::countAvailableVariants(const UnicodeString& source, 13776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& target) { 13786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Mutex lock(®istryMutex); 13796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 13806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return HAVE_REGISTRY(ec) ? _countAvailableVariants(source, target) : 0; 13816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& U_EXPORT2 Transliterator::getAvailableVariant(int32_t index, 13846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& source, 13856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& target, 13866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& result) { 13876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Mutex lock(®istryMutex); 13886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 13896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (HAVE_REGISTRY(ec)) { 13906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _getAvailableVariant(index, source, target, result); 13916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 13936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t Transliterator::_countAvailableSources(void) { 13966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return registry->countAvailableSources(); 13976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& Transliterator::_getAvailableSource(int32_t index, 14006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& result) { 14016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return registry->getAvailableSource(index, result); 14026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 14036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t Transliterator::_countAvailableTargets(const UnicodeString& source) { 14056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return registry->countAvailableTargets(source); 14066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 14076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& Transliterator::_getAvailableTarget(int32_t index, 14096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& source, 14106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& result) { 14116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return registry->getAvailableTarget(index, source, result); 14126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 14136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t Transliterator::_countAvailableVariants(const UnicodeString& source, 14156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& target) { 14166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return registry->countAvailableVariants(source, target); 14176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 14186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& Transliterator::_getAvailableVariant(int32_t index, 14206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& source, 14216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& target, 14226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& result) { 14236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return registry->getAvailableVariant(index, source, target, result); 14246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 14256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#ifdef U_USE_DEPRECATED_TRANSLITERATOR_API 14276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 14296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Method for subclasses to use to obtain a character in the given 14306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * string, with filtering. 14316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @deprecated the new architecture provides filtering at the top 14326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * level. This method will be removed Dec 31 2001. 14336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 14346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUChar Transliterator::filteredCharAt(const Replaceable& text, int32_t i) const { 14356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar c; 14366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeFilter* localFilter = getFilter(); 14376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (localFilter == 0) ? text.charAt(i) : 14386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (localFilter->contains(c = text.charAt(i)) ? c : (UChar)0xFFFE); 14396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 14406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 14426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 14446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If the registry is initialized, return TRUE. If not, initialize it 14456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and return TRUE. If the registry cannot be initialized, return 14466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * FALSE (rare). 14476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 14486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * IMPORTANT: Upon entry, registryMutex must be LOCKED. The entire 14496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * initialization is done with the lock held. There is NO REASON to 14506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * unlock, since no other thread that is waiting on the registryMutex 14516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * cannot itself proceed until the registry is initialized. 14526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 14536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool Transliterator::initializeRegistry(UErrorCode &status) { 14546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (registry != 0) { 14556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 14566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry = new TransliteratorRegistry(status); 14596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (registry == 0 || U_FAILURE(status)) { 14606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete registry; 14616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry = 0; 14626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; // can't create registry, no recovery 14636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* The following code parses the index table located in 14666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * icu/data/translit/root.txt. The index is an n x 4 table 14676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * that follows this format: 14686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <id>{ 14696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * file{ 14706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * resource{"<resource>"} 14716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * direction{"<direction>"} 14726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * } 14736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * } 14746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <id>{ 14756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * internal{ 14766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * resource{"<resource>"} 14776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * direction{"<direction"} 14786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * } 14796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * } 14806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <id>{ 14816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * alias{"<getInstanceArg"} 14826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * } 14836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <id> is the ID of the system transliterator being defined. These 14846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * are public IDs enumerated by Transliterator.getAvailableIDs(), 14856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * unless the second field is "internal". 14866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 14876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <resource> is a ResourceReader resource name. Currently these refer 14886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to file names under com/ibm/text/resources. This string is passed 14896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * directly to ResourceReader, together with <encoding>. 14906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 14916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <direction> is either "FORWARD" or "REVERSE". 14926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 14936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <getInstanceArg> is a string to be passed directly to 14946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Transliterator.getInstance(). The returned Transliterator object 14956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * then has its ID changed to <id> and is returned. 14966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 14976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The extra blank field on "alias" lines is to make the array square. 14986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 14996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //static const char translit_index[] = "translit_index"; 15006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle *bundle, *transIDs, *colBund; 15026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bundle = ures_open(U_ICUDATA_TRANSLIT, NULL/*open default locale*/, &status); 15036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org transIDs = ures_getByKey(bundle, RB_RULE_BASED_IDS, 0, &status); 15046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t row, maxRows; 15066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 15076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org maxRows = ures_getSize(transIDs); 15086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (row = 0; row < maxRows; row++) { 15096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org colBund = ures_getByIndex(transIDs, row, 0, &status); 15106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 15116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString id(ures_getKey(colBund), -1, US_INV); 15126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResourceBundle* res = ures_getNextResource(colBund, NULL, &status); 15136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char* typeStr = ures_getKey(res); 15146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar type; 15156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_charsToUChars(typeStr, &type, 1); 15166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 15186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len = 0; 15196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *resString; 15206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch (type) { 15216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 0x66: // 'f' 15226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 0x69: // 'i' 15236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // 'file' or 'internal'; 15246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // row[2]=resource, row[3]=direction 15256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 15266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resString = ures_getStringByKey(res, "resource", &len, &status); 15286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool visible = (type == 0x0066 /*f*/); 15296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTransDirection dir = 15306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (ures_getUnicodeStringByKey(res, "direction", &status).charAt(0) == 15316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0046 /*F*/) ? 15326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UTRANS_FORWARD : UTRANS_REVERSE; 15336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry->put(id, UnicodeString(TRUE, resString, len), dir, TRUE, visible, status); 15346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 15366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 0x61: // 'a' 15376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // 'alias'; row[2]=createInstance argument 15386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resString = ures_getString(res, &len, &status); 15396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry->put(id, UnicodeString(TRUE, resString, len), TRUE, TRUE, status); 15406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 15416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(res); 15446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(colBund); 15466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(transIDs); 15506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_close(bundle); 15516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Manually add prototypes that the system knows about to the 15536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // cache. This is how new non-rule-based transliterators are 15546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // added to the system. 15556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This is to allow for null pointer check 15576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NullTransliterator* tempNullTranslit = new NullTransliterator(); 15586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LowercaseTransliterator* tempLowercaseTranslit = new LowercaseTransliterator(); 15596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UppercaseTransliterator* tempUppercaseTranslit = new UppercaseTransliterator(); 15606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TitlecaseTransliterator* tempTitlecaseTranslit = new TitlecaseTransliterator(); 15616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeNameTransliterator* tempUnicodeTranslit = new UnicodeNameTransliterator(); 15626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NameUnicodeTransliterator* tempNameUnicodeTranslit = new NameUnicodeTransliterator(); 15636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_BREAK_ITERATION 15646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // TODO: could or should these transliterators be referenced polymorphically once constructed? 15656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org BreakTransliterator* tempBreakTranslit = new BreakTransliterator(); 15666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 15676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check for null pointers 15686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tempNullTranslit == NULL || tempLowercaseTranslit == NULL || tempUppercaseTranslit == NULL || 15696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempTitlecaseTranslit == NULL || tempUnicodeTranslit == NULL || 15706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_BREAK_ITERATION 15716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempBreakTranslit == NULL || 15726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 15736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempNameUnicodeTranslit == NULL ) 15746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 15756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tempNullTranslit; 15766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tempLowercaseTranslit; 15776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tempUppercaseTranslit; 15786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tempTitlecaseTranslit; 15796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tempUnicodeTranslit; 15806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tempNameUnicodeTranslit; 15816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_BREAK_ITERATION 15826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete tempBreakTranslit; 15836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 15846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Since there was an error, remove registry 15856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete registry; 15866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry = NULL; 15876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 15896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 15906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry->put(tempNullTranslit, TRUE, status); 15936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry->put(tempLowercaseTranslit, TRUE, status); 15946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry->put(tempUppercaseTranslit, TRUE, status); 15956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry->put(tempTitlecaseTranslit, TRUE, status); 15966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry->put(tempUnicodeTranslit, TRUE, status); 15976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry->put(tempNameUnicodeTranslit, TRUE, status); 15986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_BREAK_ITERATION 15996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry->put(tempBreakTranslit, FALSE, status); // FALSE means invisible. 16006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 16016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RemoveTransliterator::registerIDs(); // Must be within mutex 16036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org EscapeTransliterator::registerIDs(); 16046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnescapeTransliterator::registerIDs(); 16056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NormalizationTransliterator::registerIDs(); 16066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org AnyTransliterator::registerIDs(); 16076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _registerSpecialInverse(UNICODE_STRING_SIMPLE("Null"), 16096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UNICODE_STRING_SIMPLE("Null"), FALSE); 16106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _registerSpecialInverse(UNICODE_STRING_SIMPLE("Upper"), 16116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UNICODE_STRING_SIMPLE("Lower"), TRUE); 16126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org _registerSpecialInverse(UNICODE_STRING_SIMPLE("Title"), 16136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UNICODE_STRING_SIMPLE("Lower"), FALSE); 16146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucln_i18n_registerCleanup(UCLN_I18N_TRANSLITERATOR, utrans_transliterator_cleanup); 16166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 16186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 16196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END 16216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Defined in ucln_in.h: 16236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 16256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Release all static memory held by transliterator. This will 16266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * necessarily invalidate any rule-based transliterators held by the 16276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * user, because RBTs hold pointers to common data objects. 16286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 16296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC UBool utrans_transliterator_cleanup(void) { 16306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_NAMESPACE_USE 16316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TransliteratorIDParser::cleanup(); 16326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (registry) { 16336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete registry; 16346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org registry = NULL; 16356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 16376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 16386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_TRANSLITERATION */ 16406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//eof 1642