16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org**********************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Copyright (C) 1999-2011, 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 "unicode/utypes.h"
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_TRANSLITERATION
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/unifilt.h"
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uniset.h"
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cpdtrans.h"
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uvector.h"
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "tridpars.h"
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h"
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// keep in sync with Transliterator
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//static const UChar ID_SEP   = 0x002D; /*-*/
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_DELIM = 0x003B; /*;*/
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar NEWLINE  = 10;
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar COLON_COLON[] = {0x3A, 0x3A, 0}; //"::"
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UChar CompoundTransliterator::PASS_STRING[] = { 0x0025, 0x0050, 0x0061, 0x0073, 0x0073, 0 }; // "%Pass"
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(CompoundTransliterator)
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Constructs a new compound transliterator given an array of
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * transliterators.  The array of transliterators may be of any
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * length, including zero or one, however, useful compound
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * transliterators have at least two components.
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param transliterators array of <code>Transliterator</code>
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * objects
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param transliteratorCount The number of
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <code>Transliterator</code> objects in transliterators.
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param filter the filter.  Any character for which
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <tt>filter.contains()</tt> returns <tt>false</tt> will not be
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * altered by this transliterator.  If <tt>filter</tt> is
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * <tt>null</tt> then no filtering is applied.
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCompoundTransliterator::CompoundTransliterator(
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                           Transliterator* const transliterators[],
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                           int32_t transliteratorCount,
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                           UnicodeFilter* adoptedFilter) :
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Transliterator(joinIDs(transliterators, transliteratorCount), adoptedFilter),
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    trans(0), count(0), numAnonymousRBTs(0)  {
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    setTransliterators(transliterators, transliteratorCount);
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Splits an ID of the form "ID;ID;..." into a compound using each
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * of the IDs.
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param id of above form
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param forward if false, does the list in reverse order, and
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * takes the inverse of each ID.
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCompoundTransliterator::CompoundTransliterator(const UnicodeString& id,
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                              UTransDirection direction,
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                              UnicodeFilter* adoptedFilter,
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                              UParseError& /*parseError*/,
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                              UErrorCode& status) :
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Transliterator(id, adoptedFilter),
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    trans(0), numAnonymousRBTs(0) {
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // TODO add code for parseError...currently unused, but
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // later may be used by parsing code...
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init(id, direction, TRUE, status);
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCompoundTransliterator::CompoundTransliterator(const UnicodeString& id,
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                              UParseError& /*parseError*/,
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                              UErrorCode& status) :
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Transliterator(id, 0), // set filter to 0 here!
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    trans(0), numAnonymousRBTs(0) {
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // TODO add code for parseError...currently unused, but
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // later may be used by parsing code...
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init(id, UTRANS_FORWARD, TRUE, status);
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Private constructor for use of TransliteratorAlias
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCompoundTransliterator::CompoundTransliterator(const UnicodeString& newID,
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                              UVector& list,
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                              UnicodeFilter* adoptedFilter,
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                              int32_t anonymousRBTs,
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                              UParseError& /*parseError*/,
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                              UErrorCode& status) :
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Transliterator(newID, adoptedFilter),
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    trans(0), numAnonymousRBTs(anonymousRBTs)
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init(list, UTRANS_FORWARD, FALSE, status);
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Private constructor for Transliterator from a vector of
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * transliterators.  The caller is responsible for fixing up the
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * ID.
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCompoundTransliterator::CompoundTransliterator(UVector& list,
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                               UParseError& /*parseError*/,
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                               UErrorCode& status) :
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Transliterator(UnicodeString(), NULL),
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    trans(0), numAnonymousRBTs(0)
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // TODO add code for parseError...currently unused, but
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // later may be used by parsing code...
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init(list, UTRANS_FORWARD, FALSE, status);
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // assume caller will fixup ID
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCompoundTransliterator::CompoundTransliterator(UVector& list,
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                               int32_t anonymousRBTs,
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                               UParseError& /*parseError*/,
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                               UErrorCode& status) :
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Transliterator(UnicodeString(), NULL),
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    trans(0), numAnonymousRBTs(anonymousRBTs)
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init(list, UTRANS_FORWARD, FALSE, status);
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Finish constructing a transliterator: only to be called by
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * constructors.  Before calling init(), set trans and filter to NULL.
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param id the id containing ';'-separated entries
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param direction either FORWARD or REVERSE
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param idSplitPoint the index into id at which the
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * adoptedSplitTransliterator should be inserted, if there is one, or
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * -1 if there is none.
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param adoptedSplitTransliterator a transliterator to be inserted
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * before the entry at offset idSplitPoint in the id string.  May be
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * NULL to insert no entry.
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param fixReverseID if TRUE, then reconstruct the ID of reverse
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * entries by calling getID() of component entries.  Some constructors
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * do not require this because they apply a facade ID anyway.
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param status the error code indicating success or failure
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CompoundTransliterator::init(const UnicodeString& id,
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  UTransDirection direction,
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  UBool fixReverseID,
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  UErrorCode& status) {
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // assert(trans == 0);
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status)) {
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UVector list(status);
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeSet* compoundFilter = NULL;
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeString regenID;
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (!TransliteratorIDParser::parseCompoundID(id, direction,
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                      regenID, list, compoundFilter)) {
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        status = U_INVALID_ID;
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delete compoundFilter;
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    TransliteratorIDParser::instantiateList(list, status);
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    init(list, direction, fixReverseID, status);
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (compoundFilter != NULL) {
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        adoptFilter(compoundFilter);
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Finish constructing a transliterator: only to be called by
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * constructors.  Before calling init(), set trans and filter to NULL.
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param list a vector of transliterator objects to be adopted.  It
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * should NOT be empty.  The list should be in declared order.  That
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * is, it should be in the FORWARD order; if direction is REVERSE then
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the list order will be reversed.
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param direction either FORWARD or REVERSE
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param fixReverseID if TRUE, then reconstruct the ID of reverse
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * entries by calling getID() of component entries.  Some constructors
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * do not require this because they apply a facade ID anyway.
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param status the error code indicating success or failure
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CompoundTransliterator::init(UVector& list,
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  UTransDirection direction,
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  UBool fixReverseID,
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                  UErrorCode& status) {
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // assert(trans == 0);
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Allocate array
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_SUCCESS(status)) {
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        count = list.size();
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        trans = (Transliterator **)uprv_malloc(count * sizeof(Transliterator *));
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* test for NULL */
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (trans == 0) {
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            status = U_MEMORY_ALLOCATION_ERROR;
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            return;
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(status) || trans == 0) {
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         // assert(trans == 0);
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Move the transliterators from the vector into an array.
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Reverse the order if necessary.
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i;
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (i=0; i<count; ++i) {
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t j = (direction == UTRANS_FORWARD) ? i : count - 1 - i;
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        trans[i] = (Transliterator*) list.elementAt(j);
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // If the direction is UTRANS_REVERSE then we may need to fix the
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // ID.
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (direction == UTRANS_REVERSE && fixReverseID) {
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UnicodeString newID;
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (i=0; i<count; ++i) {
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (i > 0) {
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                newID.append(ID_DELIM);
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            newID.append(trans[i]->getID());
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        setID(newID);
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    computeMaximumContextLength();
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Return the IDs of the given list of transliterators, concatenated
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * with ID_DELIM delimiting them.  Equivalent to the perlish expression
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * join(ID_DELIM, map($_.getID(), transliterators).
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString CompoundTransliterator::joinIDs(Transliterator* const transliterators[],
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                              int32_t transCount) {
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeString id;
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (int32_t i=0; i<transCount; ++i) {
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (i > 0) {
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            id.append(ID_DELIM);
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        id.append(transliterators[i]->getID());
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return id; // Return temporary
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copy constructor.
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCompoundTransliterator::CompoundTransliterator(const CompoundTransliterator& t) :
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Transliterator(t), trans(0), count(0), numAnonymousRBTs(-1) {
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    *this = t;
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Destructor
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCompoundTransliterator::~CompoundTransliterator() {
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    freeTransliterators();
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CompoundTransliterator::freeTransliterators(void) {
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (trans != 0) {
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (int32_t i=0; i<count; ++i) {
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete trans[i];
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uprv_free(trans);
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    trans = 0;
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    count = 0;
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Assignment operator.
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCompoundTransliterator& CompoundTransliterator::operator=(
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                             const CompoundTransliterator& t)
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Transliterator::operator=(t);
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i = 0;
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool failed = FALSE;
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (trans != NULL) {
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (i=0; i<count; ++i) {
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            delete trans[i];
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            trans[i] = 0;
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (t.count > count) {
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (trans != NULL) {
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            uprv_free(trans);
2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        trans = (Transliterator **)uprv_malloc(t.count * sizeof(Transliterator *));
2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    count = t.count;
2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (trans != NULL) {
3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (i=0; i<count; ++i) {
3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            trans[i] = t.trans[i]->clone();
3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (trans[i] == NULL) {
3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                failed = TRUE;
3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                break;
3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // if memory allocation failed delete backwards trans array
3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (failed && i > 0) {
3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t n;
3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (n = i-1; n >= 0; n--) {
3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            uprv_free(trans[n]);
3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            trans[n] = NULL;
3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    numAnonymousRBTs = t.numAnonymousRBTs;
3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return *this;
3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Transliterator API.
3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgTransliterator* CompoundTransliterator::clone(void) const {
3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return new CompoundTransliterator(*this);
3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns the number of transliterators in this chain.
3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return number of transliterators in this chain.
3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t CompoundTransliterator::getCount(void) const {
3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return count;
3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Returns the transliterator at the given index in this chain.
3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param index index into chain, from 0 to <code>getCount() - 1</code>
3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return transliterator at the given index
3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst Transliterator& CompoundTransliterator::getTransliterator(int32_t index) const {
3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return *trans[index];
3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CompoundTransliterator::setTransliterators(Transliterator* const transliterators[],
3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                                int32_t transCount) {
3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    Transliterator** a = (Transliterator **)uprv_malloc(transCount * sizeof(Transliterator *));
3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (a == NULL) {
3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i = 0;
3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool failed = FALSE;
3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (i=0; i<transCount; ++i) {
3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        a[i] = transliterators[i]->clone();
3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (a[i] == NULL) {
3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            failed = TRUE;
3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (failed && i > 0) {
3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t n;
3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for (n = i-1; n >= 0; n--) {
3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            uprv_free(a[n]);
3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            a[n] = NULL;
3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    adoptTransliterators(a, transCount);
3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CompoundTransliterator::adoptTransliterators(Transliterator* adoptedTransliterators[],
3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                                  int32_t transCount) {
3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // First free trans[] and set count to zero.  Once this is done,
3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // orphan the filter.  Set up the new trans[].
3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    freeTransliterators();
3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    trans = adoptedTransliterators;
3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    count = transCount;
3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    computeMaximumContextLength();
3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    setID(joinIDs(trans, count));
3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Append c to buf, unless buf is empty or buf already ends in c.
3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void _smartAppend(UnicodeString& buf, UChar c) {
3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (buf.length() != 0 &&
3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        buf.charAt(buf.length() - 1) != c) {
3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        buf.append(c);
3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& CompoundTransliterator::toRules(UnicodeString& rulesSource,
3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                               UBool escapeUnprintable) const {
3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // We do NOT call toRules() on our component transliterators, in
3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // general.  If we have several rule-based transliterators, this
3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // yields a concatenation of the rules -- not what we want.  We do
3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // handle compound RBT transliterators specially -- those for which
3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // compoundRBTIndex >= 0.  For the transliterator at compoundRBTIndex,
3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // we do call toRules() recursively.
4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    rulesSource.truncate(0);
4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (numAnonymousRBTs >= 1 && getFilter() != NULL) {
4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // If we are a compound RBT and if we have a global
4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // filter, then emit it at the top.
4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UnicodeString pat;
4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        rulesSource.append(COLON_COLON, 2).append(getFilter()->toPattern(pat, escapeUnprintable)).append(ID_DELIM);
4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (int32_t i=0; i<count; ++i) {
4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        UnicodeString rule;
4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Anonymous RuleBasedTransliterators (inline rules and
4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // ::BEGIN/::END blocks) are given IDs that begin with
4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // "%Pass": use toRules() to write all the rules to the output
4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // (and insert "::Null;" if we have two in a row)
4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (trans[i]->getID().startsWith(PASS_STRING, 5)) {
4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            trans[i]->toRules(rule, escapeUnprintable);
4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if (numAnonymousRBTs > 1 && i > 0 && trans[i - 1]->getID().startsWith(PASS_STRING, 5))
4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                rule = UNICODE_STRING_SIMPLE("::Null;") + rule;
4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // we also use toRules() on CompoundTransliterators (which we
4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // check for by looking for a semicolon in the ID)-- this gets
4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // the list of their child transliterators output in the right
4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // format
4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else if (trans[i]->getID().indexOf(ID_DELIM) >= 0) {
4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            trans[i]->toRules(rule, escapeUnprintable);
4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // for everything else, use Transliterator::toRules()
4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        } else {
4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            trans[i]->Transliterator::toRules(rule, escapeUnprintable);
4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        _smartAppend(rulesSource, NEWLINE);
4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        rulesSource.append(rule);
4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        _smartAppend(rulesSource, ID_DELIM);
4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return rulesSource;
4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Implement Transliterator framework
4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CompoundTransliterator::handleGetSourceSet(UnicodeSet& result) const {
4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeSet set;
4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result.clear();
4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (int32_t i=0; i<count; ++i) {
4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result.addAll(trans[i]->getSourceSet(set));
4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Take the example of Hiragana-Latin.  This is really
4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Hiragana-Katakana; Katakana-Latin.  The source set of
4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // these two is roughly [:Hiragana:] and [:Katakana:].
4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // But the source set for the entire transliterator is
4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // actually [:Hiragana:] ONLY -- that is, the first
4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // non-empty source set.
4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // This is a heuristic, and not 100% reliable.
4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (!result.isEmpty()) {
4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        break;
4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Override Transliterator framework
4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeSet& CompoundTransliterator::getTargetSet(UnicodeSet& result) const {
4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UnicodeSet set;
4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result.clear();
4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (int32_t i=0; i<count; ++i) {
4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // This is a heuristic, and not 100% reliable.
4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    result.addAll(trans[i]->getTargetSet(set));
4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return result;
4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Implements {@link Transliterator#handleTransliterate}.
4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CompoundTransliterator::handleTransliterate(Replaceable& text, UTransPosition& index,
4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                                                 UBool incremental) const {
4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Call each transliterator with the same contextStart and
4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * start, but with the limit as modified
4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * by preceding transliterators.  The start index must be
4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * reset for each transliterator to give each a chance to
4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * transliterate the text.  The initial contextStart index is known
4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * to still point to the same place after each transliterator
4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * is called because each transliterator will not change the
4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * text between contextStart and the initial start index.
4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *
4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * IMPORTANT: After the first transliterator, each subsequent
4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * transliterator only gets to transliterate text committed by
4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * preceding transliterators; that is, the start (output
4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * value) of transliterator i becomes the limit (input value)
4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * of transliterator i+1.  Finally, the overall limit is fixed
4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * up before we return.
4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *
4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * Assumptions we make here:
4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * (1) contextStart <= start <= limit <= contextLimit <= text.length()
4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * (2) start <= start' <= limit'  ;cursor doesn't move back
4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * (3) start <= limit'            ;text before cursor unchanged
4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * - start' is the value of start after calling handleKT
4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * - limit' is the value of limit after calling handleKT
4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     */
5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /**
5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * Example: 3 transliterators.  This example illustrates the
5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * mechanics we need to implement.  C, S, and L are the contextStart,
5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * start, and limit.  gl is the globalLimit.  contextLimit is
5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * equal to limit throughout.
5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *
5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * 1. h-u, changes hex to Unicode
5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *
5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *    4  7  a  d  0      4  7  a
5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *    abc/u0061/u    =>  abca/u
5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *    C  S       L       C   S L   gl=f->a
5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *
5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * 2. upup, changes "x" to "XX"
5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *
5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *    4  7  a       4  7  a
5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *    abca/u    =>  abcAA/u
5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *    C  SL         C    S
5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *                       L    gl=a->b
5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * 3. u-h, changes Unicode to hex
5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *
5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *    4  7  a        4  7  a  d  0  3
5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *    abcAA/u    =>  abc/u0041/u0041/u
5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *    C  S L         C              S
5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *                                  L   gl=b->15
5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     * 4. return
5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *
5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *    4  7  a  d  0  3
5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *    abc/u0041/u0041/u
5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     *    C S L
5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     */
5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (count < 1) {
5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        index.start = index.limit;
5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return; // Short circuit for empty compound transliterators
5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // compoundLimit is the limit value for the entire compound
5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // operation.  We overwrite index.limit with the previous
5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // index.start.  After each transliteration, we update
5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // compoundLimit for insertions or deletions that have happened.
5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t compoundLimit = index.limit;
5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // compoundStart is the start for the entire compound
5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // operation.
5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t compoundStart = index.start;
5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t delta = 0; // delta in length
5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Give each transliterator a crack at the run of characters.
5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // See comments at the top of the method for more detail.
5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (int32_t i=0; i<count; ++i) {
5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        index.start = compoundStart; // Reset start
5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t limit = index.limit;
5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (index.start == index.limit) {
5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // Short circuit for empty range
5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        trans[i]->filteredTransliterate(text, index, incremental);
5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // In a properly written transliterator, start == limit after
5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // handleTransliterate() returns when incremental is false.
5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Catch cases where the subclass doesn't do this, and throw
5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // an exception.  (Just pinning start to limit is a bad idea,
5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // because what's probably happening is that the subclass
5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // isn't transliterating all the way to the end, and it should
5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // in non-incremental mode.)
5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (!incremental && index.start != index.limit) {
5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // We can't throw an exception, so just fudge things
5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            index.start = index.limit;
5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        // Cumulative delta for insertions/deletions
5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        delta += index.limit - limit;
5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (incremental) {
5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // In the incremental case, only allow subsequent
5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // transliterators to modify what has already been
5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // completely processed by prior transliterators.  In the
5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // non-incrmental case, allow each transliterator to
5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            // process the entire text.
5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            index.limit = index.start;
5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    compoundLimit += delta;
5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // Start is good where it is -- where the last transliterator left
5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // it.  Limit needs to be put back where it was, modulo
5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    // adjustments for deletions/insertions.
5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    index.limit = compoundLimit;
5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/**
5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Sets the length of the longest context required by this transliterator.
5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This is <em>preceding</em> context.
5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid CompoundTransliterator::computeMaximumContextLength(void) {
6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t max = 0;
6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for (int32_t i=0; i<count; ++i) {
6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t len = trans[i]->getMaximumContextLength();
6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if (len > max) {
6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            max = len;
6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    setMaximumContextLength(max);
6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END
6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_TRANSLITERATION */
6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* eof */
615