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* CollationRootElements.java, ported from collationrootelements.h/.cpp 102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* 112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* C++ version created on: 2013mar01 122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* created by: Markus W. Scherer 132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller*/ 142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.impl.coll; 162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/** 182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Container and access methods for collation elements and weights 192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * that occur in the root collator. 202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Needed for finding boundaries for building a tailoring. 212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This class takes and returns 16-bit secondary and tertiary weights. 23836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide Only a subset of ICU is exposed in Android 242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic final class CollationRootElements { 262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public CollationRootElements(long[] rootElements) { 272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller elements = rootElements; 282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Higher than any root primary. 322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final long PRIMARY_SENTINEL = 0xffffff00L; 342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Flag in a root element, set if the element contains secondary & tertiary weights, 372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * rather than a primary. 382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final int SEC_TER_DELTA_FLAG = 0x80; 402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Mask for getting the primary range step value from a primary-range-end element. 422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final int PRIMARY_STEP_MASK = 0x7f; 442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Index of the first CE with a non-zero tertiary weight. 472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Same as the start of the compact root elements table. 482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final int IX_FIRST_TERTIARY_INDEX = 0; 502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Index of the first CE with a non-zero secondary weight. 522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller static final int IX_FIRST_SECONDARY_INDEX = 1; 542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Index of the first CE with a non-zero primary weight. 562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller static final int IX_FIRST_PRIMARY_INDEX = 2; 582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Must match Collation.COMMON_SEC_AND_TER_CE. 602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller static final int IX_COMMON_SEC_AND_TER_CE = 3; 622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Secondary & tertiary boundaries. 642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Bits 31..24: [fixed last secondary common byte 45] 652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Bits 23..16: [fixed first ignorable secondary byte 80] 662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Bits 15.. 8: reserved, 0 672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Bits 7.. 0: [fixed first ignorable tertiary byte 3C] 682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller static final int IX_SEC_TER_BOUNDARIES = 4; 702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The current number of indexes. 722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Currently the same as elements[IX_FIRST_TERTIARY_INDEX]. 732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller static final int IX_COUNT = 5; 752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the boundary between tertiary weights of primary/secondary CEs 782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and those of tertiary CEs. 792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is the upper limit for tertiaries of primary/secondary CEs. 802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This minus one is the lower limit for tertiaries of tertiary CEs. 812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getTertiaryBoundary() { 832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ((int)elements[IX_SEC_TER_BOUNDARIES] << 8) & 0xff00; 842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the first assigned tertiary CE. 882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long getFirstTertiaryCE() { 902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return elements[(int)elements[IX_FIRST_TERTIARY_INDEX]] & ~SEC_TER_DELTA_FLAG; 912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the last assigned tertiary CE. 952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long getLastTertiaryCE() { 972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return elements[(int)elements[IX_FIRST_SECONDARY_INDEX] - 1] & ~SEC_TER_DELTA_FLAG; 982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the last common secondary weight. 1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is the lower limit for secondaries of primary CEs. 1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getLastCommonSecondary() { 1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ((int)elements[IX_SEC_TER_BOUNDARIES] >> 16) & 0xff00; 1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the boundary between secondary weights of primary CEs 1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and those of secondary CEs. 1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is the upper limit for secondaries of primary CEs. 1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This minus one is the lower limit for secondaries of secondary CEs. 1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int getSecondaryBoundary() { 1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ((int)elements[IX_SEC_TER_BOUNDARIES] >> 8) & 0xff00; 1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the first assigned secondary CE. 1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long getFirstSecondaryCE() { 1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return elements[(int)elements[IX_FIRST_SECONDARY_INDEX]] & ~SEC_TER_DELTA_FLAG; 1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the last assigned secondary CE. 1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long getLastSecondaryCE() { 1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return elements[(int)elements[IX_FIRST_PRIMARY_INDEX] - 1] & ~SEC_TER_DELTA_FLAG; 1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the first assigned primary weight. 1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long getFirstPrimary() { 1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return elements[(int)elements[IX_FIRST_PRIMARY_INDEX]]; // step=0: cannot be a range end 1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the first assigned primary CE. 1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long getFirstPrimaryCE() { 1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collation.makeCE(getFirstPrimary()); 1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the last root CE with a primary weight before p. 1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Intended only for reordering group boundaries. 1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long lastCEWithPrimaryBefore(long p) { 1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(p == 0) { return 0; } 1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(p > elements[(int)elements[IX_FIRST_PRIMARY_INDEX]]); 1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index = findP(p); 1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long q = elements[index]; 1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long secTer; 1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(p == (q & 0xffffff00L)) { 1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // p == elements[index] is a root primary. Find the CE before it. 1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We must not be in a primary range. 1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert((q & PRIMARY_STEP_MASK) == 0); 1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer = elements[index - 1]; 1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((secTer & SEC_TER_DELTA_FLAG) == 0) { 1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Primary CE just before p. 1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller p = secTer & 0xffffff00L; 1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer = Collation.COMMON_SEC_AND_TER_CE; 1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // secTer = last secondary & tertiary for the previous primary 1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index -= 2; 1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for(;;) { 1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller p = elements[index]; 1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((p & SEC_TER_DELTA_FLAG) == 0) { 1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller p &= 0xffffff00L; 1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller --index; 1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // p > elements[index] which is the previous primary. 1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Find the last secondary & tertiary weights for it. 1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller p = q & 0xffffff00L; 1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer = Collation.COMMON_SEC_AND_TER_CE; 1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for(;;) { 1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller q = elements[++index]; 1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((q & SEC_TER_DELTA_FLAG) == 0) { 1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We must not be in a primary range. 1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert((q & PRIMARY_STEP_MASK) == 0); 1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer = q; 1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (p << 32) | (secTer & ~SEC_TER_DELTA_FLAG); 1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the first root CE with a primary weight of at least p. 1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Intended only for reordering group boundaries. 1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long firstCEWithPrimaryAtLeast(long p) { 2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(p == 0) { return 0; } 2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index = findP(p); 2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(p != (elements[index] & 0xffffff00L)) { 2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for(;;) { 2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller p = elements[++index]; 2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((p & SEC_TER_DELTA_FLAG) == 0) { 2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // First primary after p. We must not be in a primary range. 2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert((p & PRIMARY_STEP_MASK) == 0); 2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // The code above guarantees that p has at most 3 bytes: (p & 0xff) == 0. 2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (p << 32) | Collation.COMMON_SEC_AND_TER_CE; 2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the primary weight before p. 2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * p must be greater than the first root primary. 2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long getPrimaryBefore(long p, boolean isCompressible) { 2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index = findPrimary(p); 2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int step; 2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long q = elements[index]; 2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(p == (q & 0xffffff00L)) { 2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Found p itself. Return the previous primary. 2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // See if p is at the end of a previous range. 2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller step = (int)q & PRIMARY_STEP_MASK; 2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(step == 0) { 2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // p is not at the end of a range. Look for the previous primary. 2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller p = elements[--index]; 2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while((p & SEC_TER_DELTA_FLAG) != 0); 2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return p & 0xffffff00L; 2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // p is in a range, and not at the start. 2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long nextElement = elements[index + 1]; 2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(isEndOfPrimaryRange(nextElement)); 2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller step = (int)nextElement & PRIMARY_STEP_MASK; 2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Return the previous range primary. 2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((p & 0xffff) == 0) { 2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collation.decTwoBytePrimaryByOneStep(p, isCompressible, step); 2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collation.decThreeBytePrimaryByOneStep(p, isCompressible, step); 2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** Returns the secondary weight before [p, s]. */ 2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int getSecondaryBefore(long p, int s) { 2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index; 2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int previousSec, sec; 2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(p == 0) { 2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index = (int)elements[IX_FIRST_SECONDARY_INDEX]; 2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Gap at the beginning of the secondary CE range. 2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller previousSec = 0; 2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller sec = (int)(elements[index] >> 16); 2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index = findPrimary(p) + 1; 2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller previousSec = Collation.BEFORE_WEIGHT16; 2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller sec = (int)getFirstSecTerForPrimary(index) >>> 16; 2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(s >= sec); 2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while(s > sec) { 2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller previousSec = sec; 2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert((elements[index] & SEC_TER_DELTA_FLAG) != 0); 2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller sec = (int)(elements[index++] >> 16); 2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(sec == s); 2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return previousSec; 2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** Returns the tertiary weight before [p, s, t]. */ 2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int getTertiaryBefore(long p, int s, int t) { 2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert((t & ~Collation.ONLY_TERTIARY_MASK) == 0); 2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index; 2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int previousTer; 2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long secTer; 2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(p == 0) { 2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(s == 0) { 2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index = (int)elements[IX_FIRST_TERTIARY_INDEX]; 2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Gap at the beginning of the tertiary CE range. 2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller previousTer = 0; 2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index = (int)elements[IX_FIRST_SECONDARY_INDEX]; 2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller previousTer = Collation.BEFORE_WEIGHT16; 2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer = elements[index] & ~SEC_TER_DELTA_FLAG; 2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index = findPrimary(p) + 1; 2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller previousTer = Collation.BEFORE_WEIGHT16; 2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer = getFirstSecTerForPrimary(index); 2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long st = ((long)s << 16) | t; 2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while(st > secTer) { 2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((int)(secTer >> 16) == s) { previousTer = (int)secTer; } 2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert((elements[index] & SEC_TER_DELTA_FLAG) != 0); 2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer = elements[index++] & ~SEC_TER_DELTA_FLAG; 2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(secTer == st); 3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return previousTer & 0xffff; 3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Finds the index of the input primary. 3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * p must occur as a root primary, and must not be 0. 3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int findPrimary(long p) { 3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Requirement: p must occur as a root primary. 3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert((p & 0xff) == 0); // at most a 3-byte primary 3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index = findP(p); 3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If p is in a range, then we just assume that p is an actual primary in this range. 3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // (Too cumbersome/expensive to check.) 3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Otherwise, it must be an exact match. 3152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(isEndOfPrimaryRange(elements[index + 1]) || p == (elements[index] & 0xffffff00L)); 3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return index; 3172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the primary weight after p where index=findPrimary(p). 3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * p must be at least the first root primary. 3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long getPrimaryAfter(long p, int index, boolean isCompressible) { 3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(p == (elements[index] & 0xffffff00L) || isEndOfPrimaryRange(elements[index + 1])); 3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long q = elements[++index]; 3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int step; 3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((q & SEC_TER_DELTA_FLAG) == 0 && (step = (int)q & PRIMARY_STEP_MASK) != 0) { 3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Return the next primary in this range. 3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((p & 0xffff) == 0) { 3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collation.incTwoBytePrimaryByOffset(p, isCompressible, step); 3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collation.incThreeBytePrimaryByOffset(p, isCompressible, step); 3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Return the next primary in the list. 3362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while((q & SEC_TER_DELTA_FLAG) != 0) { 3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller q = elements[++index]; 3382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert((q & PRIMARY_STEP_MASK) == 0); 3402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return q; 3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the secondary weight after [p, s] where index=findPrimary(p) 3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * except use index=0 for p=0. 3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>Must return a weight for every root [p, s] as well as for every weight 3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * returned by getSecondaryBefore(). If p!=0 then s can be BEFORE_WEIGHT16. 3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>Exception: [0, 0] is handled by the CollationBuilder: 3512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Both its lower and upper boundaries are special. 3522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int getSecondaryAfter(int index, int s) { 3542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long secTer; 3552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int secLimit; 3562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(index == 0) { 3572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // primary = 0 3582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(s != 0); 3592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index = (int)elements[IX_FIRST_SECONDARY_INDEX]; 3602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer = elements[index]; 3612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Gap at the end of the secondary CE range. 3622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secLimit = 0x10000; 3632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 3642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(index >= (int)elements[IX_FIRST_PRIMARY_INDEX]); 3652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer = getFirstSecTerForPrimary(index + 1); 3662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If this is an explicit sec/ter unit, then it will be read once more. 3672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Gap for secondaries of primary CEs. 3682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secLimit = getSecondaryBoundary(); 3692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for(;;) { 3712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int sec = (int)(secTer >> 16); 3722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(sec > s) { return sec; } 3732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer = elements[++index]; 3742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((secTer & SEC_TER_DELTA_FLAG) == 0) { return secLimit; } 3752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the tertiary weight after [p, s, t] where index=findPrimary(p) 3792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * except use index=0 for p=0. 3802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>Must return a weight for every root [p, s, t] as well as for every weight 3822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * returned by getTertiaryBefore(). If s!=0 then t can be BEFORE_WEIGHT16. 3832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>Exception: [0, 0, 0] is handled by the CollationBuilder: 3852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Both its lower and upper boundaries are special. 3862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int getTertiaryAfter(int index, int s, int t) { 3882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long secTer; 3892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int terLimit; 3902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(index == 0) { 3912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // primary = 0 3922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(s == 0) { 3932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(t != 0); 3942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index = (int)elements[IX_FIRST_TERTIARY_INDEX]; 3952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Gap at the end of the tertiary CE range. 3962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller terLimit = 0x4000; 3972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 3982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index = (int)elements[IX_FIRST_SECONDARY_INDEX]; 3992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Gap for tertiaries of primary/secondary CEs. 4002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller terLimit = getTertiaryBoundary(); 4012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer = elements[index] & ~SEC_TER_DELTA_FLAG; 4032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 4042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(index >= (int)elements[IX_FIRST_PRIMARY_INDEX]); 4052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer = getFirstSecTerForPrimary(index + 1); 4062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If this is an explicit sec/ter unit, then it will be read once more. 4072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller terLimit = getTertiaryBoundary(); 4082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long st = (((long)s & 0xffffffffL) << 16) | t; 4102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for(;;) { 4112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(secTer > st) { 4122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert((secTer >> 16) == s); 4132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (int)secTer & 0xffff; 4142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer = elements[++index]; 4162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // No tertiary greater than t for this primary+secondary. 4172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((secTer & SEC_TER_DELTA_FLAG) == 0 || (secTer >> 16) > s) { return terLimit; } 4182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer &= ~SEC_TER_DELTA_FLAG; 4192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the first secondary & tertiary weights for p where index=findPrimary(p)+1. 4242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private long getFirstSecTerForPrimary(int index) { 4262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long secTer = elements[index]; 4272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((secTer & SEC_TER_DELTA_FLAG) == 0) { 4282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // No sec/ter delta. 4292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collation.COMMON_SEC_AND_TER_CE; 4302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secTer &= ~SEC_TER_DELTA_FLAG; 4322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(secTer > Collation.COMMON_SEC_AND_TER_CE) { 4332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Implied sec/ter. 4342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collation.COMMON_SEC_AND_TER_CE; 4352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Explicit sec/ter below common/common. 4372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return secTer; 4382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Finds the largest index i where elements[i]<=p. 4422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Requires first primary<=p<0xffffff00 (PRIMARY_SENTINEL). 4432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Does not require that p is a root collator primary. 4442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int findP(long p) { 4462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // p need not occur as a root primary. 4472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // For example, it might be a reordering group boundary. 4482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert((p >> 24) != Collation.UNASSIGNED_IMPLICIT_BYTE); 4492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // modified binary search 4502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int start = (int)elements[IX_FIRST_PRIMARY_INDEX]; 4512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(p >= elements[start]); 4522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int limit = elements.length - 1; 4532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(elements[limit] >= PRIMARY_SENTINEL); 4542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert(p < elements[limit]); 4552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while((start + 1) < limit) { 4562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Invariant: elements[start] and elements[limit] are primaries, 4572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // and elements[start]<=p<=elements[limit]. 458f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert int i = (int)(((long)start + (long)limit) / 2); 4592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long q = elements[i]; 4602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((q & SEC_TER_DELTA_FLAG) != 0) { 4612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Find the next primary. 4622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int j = i + 1; 4632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for(;;) { 4642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(j == limit) { break; } 4652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller q = elements[j]; 4662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((q & SEC_TER_DELTA_FLAG) == 0) { 4672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i = j; 4682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 4692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++j; 4712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((q & SEC_TER_DELTA_FLAG) != 0) { 4732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Find the preceding primary. 4742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller j = i - 1; 4752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for(;;) { 4762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(j == start) { break; } 4772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller q = elements[j]; 4782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((q & SEC_TER_DELTA_FLAG) == 0) { 4792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i = j; 4802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 4812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller --j; 4832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((q & SEC_TER_DELTA_FLAG) != 0) { 4852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // No primary between start and limit. 4862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 4872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(p < (q & 0xffffff00L)) { // Reset the "step" bits of a range end primary. 4912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller limit = i; 4922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 4932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller start = i; 4942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return start; 4972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static boolean isEndOfPrimaryRange(long q) { 5002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (q & SEC_TER_DELTA_FLAG) == 0 && (q & PRIMARY_STEP_MASK) != 0; 5012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Data structure: See ICU4C source/i18n/collationrootelements.h. 5052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private long[] elements; 5072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller} 508