12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */ 2f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// © 2016 and later: Unicode, Inc. and others. 3f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License 42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* 52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller******************************************************************************* 62ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* Copyright (C) 2013-2014, International Business Machines 72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* Corporation and others. All Rights Reserved. 82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller******************************************************************************* 92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* ContractionsAndExpansions.java, ported from collationsets.h/.cpp 102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* 112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* C++ version created on: 2013feb09 122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* created by: Markus W. Scherer 132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller*/ 142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.impl.coll; 162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Iterator; 182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.impl.Trie2; 202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.text.UnicodeSet; 212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.CharsTrie; 222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.CharsTrie.Entry; 232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 241537b2f39245c07b00aa78c3600f7aebcb172490Neil Fuller/** 251537b2f39245c07b00aa78c3600f7aebcb172490Neil Fuller * @hide Only a subset of ICU is exposed in Android 26836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller */ 272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic final class ContractionsAndExpansions { 281fba789ac68efdd9120a7373f49daef42833e674Neil Fuller // C++: The following fields are @internal, only public for access by callback. 292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private CollationData data; 302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private UnicodeSet contractions; 312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private UnicodeSet expansions; 322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private CESink sink; 332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private boolean addPrefixes; 342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int checkTailored = 0; // -1: collected tailored +1: exclude tailored 352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private UnicodeSet tailored = new UnicodeSet(); 362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private UnicodeSet ranges; 372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private StringBuilder unreversedPrefix = new StringBuilder(); 382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String suffix; 392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private long[] ces = new long[Collation.MAX_EXPANSION_LENGTH]; 402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static interface CESink { 422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller void handleCE(long ce); 432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller void handleExpansion(long ces[], int start, int length); 442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public ContractionsAndExpansions(UnicodeSet con, UnicodeSet exp, CESink s, boolean prefixes) { 472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller contractions = con; 482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller expansions = exp; 492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller sink = s; 502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller addPrefixes = prefixes; 512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void forData(CollationData d) { 542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Add all from the data, can be tailoring or base. 552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (d.base != null) { 562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller checkTailored = -1; 572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller data = d; 592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Iterator<Trie2.Range> trieIterator = data.trie.iterator(); 602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Trie2.Range range; 612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (trieIterator.hasNext() && !(range = trieIterator.next()).leadSurrogate) { 622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller enumCnERange(range.startCodePoint, range.endCodePoint, range.value, this); 632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (d.base == null) { 652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Add all from the base data but only for un-tailored code points. 682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller tailored.freeze(); 692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller checkTailored = 1; 702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller data = d.base; 712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller trieIterator = data.trie.iterator(); 722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (trieIterator.hasNext() && !(range = trieIterator.next()).leadSurrogate) { 732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller enumCnERange(range.startCodePoint, range.endCodePoint, range.value, this); 742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void enumCnERange(int start, int end, int ce32, ContractionsAndExpansions cne) { 782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (cne.checkTailored == 0) { 792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // There is no tailoring. 802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // No need to collect nor check the tailored set. 812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (cne.checkTailored < 0) { 822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Collect the set of code points with mappings in the tailoring data. 832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ce32 == Collation.FALLBACK_CE32) { 842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; // fallback to base, not tailored 852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cne.tailored.add(start, end); 872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // checkTailored > 0: Exclude tailored ranges from the base data enumeration. 892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (start == end) { 902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (cne.tailored.contains(start)) { 912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (cne.tailored.containsSome(start, end)) { 942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (cne.ranges == null) { 952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cne.ranges = new UnicodeSet(); 962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cne.ranges.set(start, end).removeAll(cne.tailored); 982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int count = cne.ranges.getRangeCount(); 992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < count; ++i) { 1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cne.handleCE32(cne.ranges.getRangeStart(i), cne.ranges.getRangeEnd(i), ce32); 1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cne.handleCE32(start, end, ce32); 1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void forCodePoint(CollationData d, int c) { 1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int ce32 = d.getCE32(c); 1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ce32 == Collation.FALLBACK_CE32) { 1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller d = d.base; 1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ce32 = d.getCE32(c); 1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller data = d; 1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller handleCE32(c, c, ce32); 1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void handleCE32(int start, int end, int ce32) { 1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) { 1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((ce32 & 0xff) < Collation.SPECIAL_CE32_LOW_BYTE) { 1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // !isSpecialCE32() 1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (sink != null) { 1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller sink.handleCE(Collation.ceFromSimpleCE32(ce32)); 1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller switch (Collation.tagFromCE32(ce32)) { 1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.FALLBACK_TAG: 1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.RESERVED_TAG_3: 1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.BUILDER_DATA_TAG: 1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.LEAD_SURROGATE_TAG: 1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Java porting note: U_INTERNAL_PROGRAM_ERROR is set to errorCode in ICU4C. 1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new AssertionError( 1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String.format("Unexpected CE32 tag type %d for ce32=0x%08x", 1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Collation.tagFromCE32(ce32), ce32)); 1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.LONG_PRIMARY_TAG: 1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (sink != null) { 1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller sink.handleCE(Collation.ceFromLongPrimaryCE32(ce32)); 1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.LONG_SECONDARY_TAG: 1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (sink != null) { 1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller sink.handleCE(Collation.ceFromLongSecondaryCE32(ce32)); 1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.LATIN_EXPANSION_TAG: 1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (sink != null) { 1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ces[0] = Collation.latinCE0FromCE32(ce32); 1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ces[1] = Collation.latinCE1FromCE32(ce32); 1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller sink.handleExpansion(ces, 0, 2); 1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Optimization: If we have a prefix, 1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // then the relevant strings have been added already. 1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (unreversedPrefix.length() == 0) { 1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller addExpansions(start, end); 1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.EXPANSION32_TAG: 1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (sink != null) { 1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int idx = Collation.indexFromCE32(ce32); 1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int length = Collation.lengthFromCE32(ce32); 1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < length; ++i) { 1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ces[i] = Collation.ceFromCE32(data.ce32s[idx + i]); 1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller sink.handleExpansion(ces, 0, length); 1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Optimization: If we have a prefix, 1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // then the relevant strings have been added already. 1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (unreversedPrefix.length() == 0) { 1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller addExpansions(start, end); 1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.EXPANSION_TAG: 1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (sink != null) { 1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int idx = Collation.indexFromCE32(ce32); 1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int length = Collation.lengthFromCE32(ce32); 1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller sink.handleExpansion(data.ces, idx, length); 1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Optimization: If we have a prefix, 1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // then the relevant strings have been added already. 1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (unreversedPrefix.length() == 0) { 1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller addExpansions(start, end); 1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.PREFIX_TAG: 1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller handlePrefixes(start, end, ce32); 1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.CONTRACTION_TAG: 1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller handleContractions(start, end, ce32); 1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.DIGIT_TAG: 1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Fetch the non-numeric-collation CE32 and continue. 1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ce32 = data.ce32s[Collation.indexFromCE32(ce32)]; 1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.U0000_TAG: 1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert (start == 0 && end == 0); 1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Fetch the normal ce32 for U+0000 and continue. 1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ce32 = data.ce32s[0]; 1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.HANGUL_TAG: 2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (sink != null) { 2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // TODO: This should be optimized, 2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // especially if [start..end] is the complete Hangul range. (assert that) 2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UTF16CollationIterator iter = new UTF16CollationIterator(data); 2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder hangul = new StringBuilder(1); 2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int c = start; c <= end; ++c) { 2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller hangul.setLength(0); 2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller hangul.appendCodePoint(c); 2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller iter.setText(false, hangul, 0); 2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int length = iter.fetchCEs(); 2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Ignore the terminating non-CE. 2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert (length >= 2 && iter.getCE(length - 1) == Collation.NO_CE); 2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller sink.handleExpansion(iter.getCEs(), 0, length - 1); 2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Optimization: If we have a prefix, 2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // then the relevant strings have been added already. 2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (unreversedPrefix.length() == 0) { 2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller addExpansions(start, end); 2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.OFFSET_TAG: 2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Currently no need to send offset CEs to the sink. 2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case Collation.IMPLICIT_TAG: 2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Currently no need to send implicit CEs to the sink. 2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void handlePrefixes(int start, int end, int ce32) { 2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index = Collation.indexFromCE32(ce32); 2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ce32 = data.getCE32FromContexts(index); // Default if no prefix match. 2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller handleCE32(start, end, ce32); 2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!addPrefixes) { 2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CharsTrie.Iterator prefixes = new CharsTrie(data.contexts, index + 2).iterator(); 2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (prefixes.hasNext()) { 2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Entry e = prefixes.next(); 2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller setPrefix(e.chars); 2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Prefix/pre-context mappings are special kinds of contractions 2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // that always yield expansions. 2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller addStrings(start, end, contractions); 2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller addStrings(start, end, expansions); 2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller handleCE32(start, end, e.value); 2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller resetPrefix(); 2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller void handleContractions(int start, int end, int ce32) { 2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index = Collation.indexFromCE32(ce32); 2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((ce32 & Collation.CONTRACT_SINGLE_CP_NO_MATCH) != 0) { 2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // No match on the single code point. 2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We are underneath a prefix, and the default mapping is just 2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // a fallback to the mappings for a shorter prefix. 2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert (unreversedPrefix.length() != 0); 2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ce32 = data.getCE32FromContexts(index); // Default if no suffix match. 2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert (!Collation.isContractionCE32(ce32)); 2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller handleCE32(start, end, ce32); 2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CharsTrie.Iterator suffixes = new CharsTrie(data.contexts, index + 2).iterator(); 2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (suffixes.hasNext()) { 2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Entry e = suffixes.next(); 2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller suffix = e.chars.toString(); 2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller addStrings(start, end, contractions); 2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (unreversedPrefix.length() != 0) { 2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller addStrings(start, end, expansions); 2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller handleCE32(start, end, e.value); 2722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller suffix = null; 2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller void addExpansions(int start, int end) { 2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (unreversedPrefix.length() == 0 && suffix == null) { 2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (expansions != null) { 2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller expansions.add(start, end); 2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller addStrings(start, end, expansions); 2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller void addStrings(int start, int end, UnicodeSet set) { 2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (set == null) { 2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder s = new StringBuilder(unreversedPrefix); 2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller s.appendCodePoint(start); 2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (suffix != null) { 2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller s.append(suffix); 2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller set.add(s); 2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller s.setLength(unreversedPrefix.length()); 2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while (++start <= end); 2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Prefixes are reversed in the data structure. 3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void setPrefix(CharSequence pfx) { 3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller unreversedPrefix.setLength(0); 3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller unreversedPrefix.append(pfx).reverse(); 3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void resetPrefix() { 3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller unreversedPrefix.setLength(0); 3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller}