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) 1996-2015, International Business Machines 72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Corporation and others. All Rights Reserved. 82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ******************************************************************************* 92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * CollationCompare.java, ported from collationcompare.h/.cpp 102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * C++ version created on: 2012feb14 with new and old collation code 122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * created by: Markus W. Scherer 132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.impl.coll; 162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.text.Collator; 182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 191537b2f39245c07b00aa78c3600f7aebcb172490Neil Fuller/** 201537b2f39245c07b00aa78c3600f7aebcb172490Neil Fuller * @hide Only a subset of ICU is exposed in Android 21836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller */ 222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic final class CollationCompare /* all static */ { 232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static int compareUpToQuaternary(CollationIterator left, CollationIterator right, 242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CollationSettings settings) { 252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int options = settings.options; 262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long variableTop; 272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((options & CollationSettings.ALTERNATE_MASK) == 0) { 282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller variableTop = 0; 292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // +1 so that we can use "<" and primary ignorables test out early. 312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller variableTop = settings.variableTop + 1; 322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean anyVariable = false; 342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Fetch CEs, compare primaries, store secondary & tertiary weights. 362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) { 372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We fetch CEs until we get a non-ignorable primary or reach the end. 382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long leftPrimary; 392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long ce = left.nextCE(); 412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftPrimary = ce >>> 32; 422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftPrimary < variableTop && leftPrimary > Collation.MERGE_SEPARATOR_PRIMARY) { 432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Variable CE, shift it to quaternary level. 442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Ignore all following primary ignorables, and shift further variable CEs. 452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller anyVariable = true; 462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Store only the primary of the variable CE. 482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller left.setCurrentCE(ce & 0xffffffff00000000L); 492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) { 502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ce = left.nextCE(); 512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftPrimary = ce >>> 32; 522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftPrimary == 0) { 532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller left.setCurrentCE(0); 542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while (leftPrimary < variableTop && leftPrimary > Collation.MERGE_SEPARATOR_PRIMARY); 592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while (leftPrimary == 0); 612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long rightPrimary; 632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long ce = right.nextCE(); 652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightPrimary = ce >>> 32; 662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rightPrimary < variableTop && rightPrimary > Collation.MERGE_SEPARATOR_PRIMARY) { 672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Variable CE, shift it to quaternary level. 682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Ignore all following primary ignorables, and shift further variable CEs. 692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller anyVariable = true; 702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Store only the primary of the variable CE. 722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller right.setCurrentCE(ce & 0xffffffff00000000L); 732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) { 742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ce = right.nextCE(); 752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightPrimary = ce >>> 32; 762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rightPrimary == 0) { 772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller right.setCurrentCE(0); 782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while (rightPrimary < variableTop && rightPrimary > Collation.MERGE_SEPARATOR_PRIMARY); 832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while (rightPrimary == 0); 852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftPrimary != rightPrimary) { 872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Return the primary difference, with script reordering. 882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (settings.hasReordering()) { 892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftPrimary = settings.reorder(leftPrimary); 902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightPrimary = settings.reorder(rightPrimary); 912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (leftPrimary < rightPrimary) ? Collation.LESS : Collation.GREATER; 932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftPrimary == Collation.NO_CE_PRIMARY) { 952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Compare the buffered secondary & tertiary weights. 1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We might skip the secondary level but continue with the case level 1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // which is turned on separately. 1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (CollationSettings.getStrength(options) >= Collator.SECONDARY) { 1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((options & CollationSettings.BACKWARD_SECONDARY) == 0) { 1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int leftIndex = 0; 1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int rightIndex = 0; 1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) { 1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int leftSecondary; 1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftSecondary = ((int) left.getCE(leftIndex++)) >>> 16; 1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while (leftSecondary == 0); 1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int rightSecondary; 1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightSecondary = ((int) right.getCE(rightIndex++)) >>> 16; 1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while (rightSecondary == 0); 1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftSecondary != rightSecondary) { 1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (leftSecondary < rightSecondary) ? Collation.LESS : Collation.GREATER; 1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftSecondary == Collation.NO_CE_WEIGHT16) { 1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // The backwards secondary level compares secondary weights backwards 1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // within segments separated by the merge separator (U+FFFE, weight 02). 1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int leftStart = 0; 1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int rightStart = 0; 1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) { 1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Find the merge separator or the NO_CE terminator. 1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long p; 1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int leftLimit = leftStart; 1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while ((p = left.getCE(leftLimit) >>> 32) > Collation.MERGE_SEPARATOR_PRIMARY 1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller || p == 0) { 1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++leftLimit; 1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int rightLimit = rightStart; 1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while ((p = right.getCE(rightLimit) >>> 32) > Collation.MERGE_SEPARATOR_PRIMARY 1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller || p == 0) { 1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++rightLimit; 1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Compare the segments. 1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int leftIndex = leftLimit; 1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int rightIndex = rightLimit; 1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) { 1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int leftSecondary = 0; 1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (leftSecondary == 0 && leftIndex > leftStart) { 1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftSecondary = ((int) left.getCE(--leftIndex)) >>> 16; 1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int rightSecondary = 0; 1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (rightSecondary == 0 && rightIndex > rightStart) { 1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightSecondary = ((int) right.getCE(--rightIndex)) >>> 16; 1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftSecondary != rightSecondary) { 1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (leftSecondary < rightSecondary) ? Collation.LESS : Collation.GREATER; 1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftSecondary == 0) { 1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Did we reach the end of either string? 1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Both strings have the same number of merge separators, 1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // or else there would have been a primary-level difference. 1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert (left.getCE(leftLimit) == right.getCE(rightLimit)); 1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (p == Collation.NO_CE_PRIMARY) { 1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Skip both merge separators and continue. 1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftStart = leftLimit + 1; 1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightStart = rightLimit + 1; 1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((options & CollationSettings.CASE_LEVEL) != 0) { 1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int strength = CollationSettings.getStrength(options); 1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int leftIndex = 0; 1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int rightIndex = 0; 1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) { 1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int leftCase, leftLower32, rightCase; 1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (strength == Collator.PRIMARY) { 1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Primary+caseLevel: Ignore case level weights of primary ignorables. 1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Otherwise we would get a-umlaut > a 1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // which is not desirable for accent-insensitive sorting. 1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Check for (lower 32 bits) == 0 as well because variable CEs are stored 1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // with only primary weights. 1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long ce; 1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ce = left.getCE(leftIndex++); 1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftCase = (int) ce; 1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while ((ce >>> 32) == 0 || leftCase == 0); 1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftLower32 = leftCase; 1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftCase &= 0xc000; 1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ce = right.getCE(rightIndex++); 2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightCase = (int) ce; 2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while ((ce >>> 32) == 0 || rightCase == 0); 2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightCase &= 0xc000; 2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Secondary+caseLevel: By analogy with the above, 2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // ignore case level weights of secondary ignorables. 2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Note: A tertiary CE has uppercase case bits (0.0.ut) 2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // to keep tertiary+caseFirst well-formed. 2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Tertiary+caseLevel: Also ignore case level weights of secondary ignorables. 2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Otherwise a tertiary CE's uppercase would be no greater than 2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // a primary/secondary CE's uppercase. 2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // (See UCA well-formedness condition 2.) 2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We could construct a special case weight higher than uppercase, 2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // but it's simpler to always ignore case weights of secondary ignorables, 2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // turning 0.0.ut into 0.0.0.t. 2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // (See LDML Collation, Case Parameters.) 2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftCase = (int) left.getCE(leftIndex++); 2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while ((leftCase & 0xffff0000) == 0); 2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftLower32 = leftCase; 2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftCase &= 0xc000; 2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightCase = (int) right.getCE(rightIndex++); 2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while ((rightCase & 0xffff0000) == 0); 2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightCase &= 0xc000; 2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // No need to handle NO_CE and MERGE_SEPARATOR specially: 2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // There is one case weight for each previous-level weight, 2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // so level length differences were handled there. 2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftCase != rightCase) { 2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((options & CollationSettings.UPPER_FIRST) == 0) { 2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (leftCase < rightCase) ? Collation.LESS : Collation.GREATER; 2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (leftCase < rightCase) ? Collation.GREATER : Collation.LESS; 2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((leftLower32 >>> 16) == Collation.NO_CE_WEIGHT16) { 2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (CollationSettings.getStrength(options) <= Collator.SECONDARY) { 2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collation.EQUAL; 2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int tertiaryMask = CollationSettings.getTertiaryMask(options); 2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int leftIndex = 0; 2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int rightIndex = 0; 2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int anyQuaternaries = 0; 2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) { 2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int leftLower32, leftTertiary; 2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftLower32 = (int) left.getCE(leftIndex++); 2592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller anyQuaternaries |= leftLower32; 2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert ((leftLower32 & Collation.ONLY_TERTIARY_MASK) != 0 || (leftLower32 & 0xc0c0) == 0); 2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftTertiary = leftLower32 & tertiaryMask; 2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while (leftTertiary == 0); 2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int rightLower32, rightTertiary; 2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightLower32 = (int) right.getCE(rightIndex++); 2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller anyQuaternaries |= rightLower32; 2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller assert ((rightLower32 & Collation.ONLY_TERTIARY_MASK) != 0 || (rightLower32 & 0xc0c0) == 0); 2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightTertiary = rightLower32 & tertiaryMask; 2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while (rightTertiary == 0); 2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftTertiary != rightTertiary) { 2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (CollationSettings.sortsTertiaryUpperCaseFirst(options)) { 2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Pass through NO_CE and keep real tertiary weights larger than that. 2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Do not change the artificial uppercase weight of a tertiary CE (0.0.ut), 2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // to keep tertiary CEs well-formed. 2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Their case+tertiary weights must be greater than those of 2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // primary and secondary CEs. 2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftTertiary > Collation.NO_CE_WEIGHT16) { 2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((leftLower32 & 0xffff0000) != 0) { 2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftTertiary ^= 0xc000; 2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftTertiary += 0x4000; 2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rightTertiary > Collation.NO_CE_WEIGHT16) { 2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((rightLower32 & 0xffff0000) != 0) { 2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightTertiary ^= 0xc000; 2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightTertiary += 0x4000; 2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (leftTertiary < rightTertiary) ? Collation.LESS : Collation.GREATER; 2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftTertiary == Collation.NO_CE_WEIGHT16) { 2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (CollationSettings.getStrength(options) <= Collator.TERTIARY) { 3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collation.EQUAL; 3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!anyVariable && (anyQuaternaries & 0xc0) == 0) { 3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If there are no "variable" CEs and no non-zero quaternary weights, 3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // then there are no quaternary differences. 3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collation.EQUAL; 3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftIndex = 0; 3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightIndex = 0; 3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) { 3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long leftQuaternary; 3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 3152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long ce = left.getCE(leftIndex++); 3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftQuaternary = ce & 0xffff; 3172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftQuaternary <= Collation.NO_CE_WEIGHT16) { 3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Variable primary or completely ignorable or NO_CE. 3192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftQuaternary = ce >>> 32; 3202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Regular CE, not tertiary ignorable. 3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Preserve the quaternary weight in bits 7..6. 3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftQuaternary |= 0xffffff3fL; 3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while (leftQuaternary == 0); 3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long rightQuaternary; 3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller do { 3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long ce = right.getCE(rightIndex++); 3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightQuaternary = ce & 0xffff; 3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rightQuaternary <= Collation.NO_CE_WEIGHT16) { 3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Variable primary or completely ignorable or NO_CE. 3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightQuaternary = ce >>> 32; 3342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Regular CE, not tertiary ignorable. 3362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Preserve the quaternary weight in bits 7..6. 3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightQuaternary |= 0xffffff3fL; 3382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } while (rightQuaternary == 0); 3402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftQuaternary != rightQuaternary) { 3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Return the difference, with script reordering. 3432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (settings.hasReordering()) { 3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller leftQuaternary = settings.reorder(leftQuaternary); 3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller rightQuaternary = settings.reorder(rightQuaternary); 3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (leftQuaternary < rightQuaternary) ? Collation.LESS : Collation.GREATER; 3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (leftQuaternary == Collation.NO_CE_PRIMARY) { 3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 3512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Collation.EQUAL; 3542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller} 356