jdk/src/share/classes/java/text/CollationElementIterator.java
author ohair
Tue, 25 May 2010 15:58:33 -0700
changeset 5506 202f599c92aa
parent 4839 6b3edc448285
child 7509 bc7eaae38fff
permissions -rw-r--r--
6943119: Rebrand source copyright notices Reviewed-by: darcy, weijun
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4839
diff changeset
     2
 * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4839
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4839
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4839
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4839
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4839
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 * (C) Copyright IBM Corp. 1996-1998 - All Rights Reserved
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 *   The original version of this source code and documentation is copyrighted
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * materials are provided under terms of a License Agreement between Taligent
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * and Sun. This technology is protected by multiple US and International
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * patents. This notice and attribution to Taligent may not be removed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 *   Taligent is a registered trademark of Taligent, Inc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
package java.text;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.lang.Character;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.util.Vector;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import sun.text.CollatorUtilities;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import sun.text.normalizer.NormalizerBase;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * The <code>CollationElementIterator</code> class is used as an iterator
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * to walk through each character of an international string. Use the iterator
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * to return the ordering priority of the positioned character. The ordering
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * priority of a character, which we refer to as a key, defines how a character
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * is collated in the given collation object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * For example, consider the following in Spanish:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * "ca" -> the first key is key('c') and second key is key('a').
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * "cha" -> the first key is key('ch') and second key is key('a').
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * And in German,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * "\u00e4b"-> the first key is key('a'), the second key is key('e'), and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * the third key is key('b').
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * The key of a character is an integer composed of primary order(short),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * secondary order(byte), and tertiary order(byte). Java strictly defines
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * the size and signedness of its primitive data types. Therefore, the static
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * functions <code>primaryOrder</code>, <code>secondaryOrder</code>, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * <code>tertiaryOrder</code> return <code>int</code>, <code>short</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * and <code>short</code> respectively to ensure the correctness of the key
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * Example of the iterator usage,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 *  String testString = "This is a test";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 *  RuleBasedCollator ruleBasedCollator = (RuleBasedCollator)Collator.getInstance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 *  CollationElementIterator collationElementIterator = ruleBasedCollator.getCollationElementIterator(testString);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 *  int primaryOrder = CollationElementIterator.primaryOrder(collationElementIterator.next());
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 * <code>CollationElementIterator.next</code> returns the collation order
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 * of the next character. A collation order consists of primary order,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
 * secondary order and tertiary order. The data type of the collation
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
 * order is <strong>int</strong>. The first 16 bits of a collation order
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
 * is its primary order; the next 8 bits is the secondary order and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
 * last 8 bits is the tertiary order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
 * @see                Collator
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
 * @see                RuleBasedCollator
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
 * @author             Helena Shih, Laura Werner, Richard Gillam
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
public final class CollationElementIterator
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * Null order which indicates the end of string is reached by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     * cursor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    public final static int NULLORDER = 0xffffffff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     * CollationElementIterator constructor.  This takes the source string and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * the collation object.  The cursor will walk thru the source string based
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * on the predefined collation rules.  If the source string is empty,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     * NULLORDER will be returned on the calls to next().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     * @param sourceText the source string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     * @param order the collation object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    CollationElementIterator(String sourceText, RuleBasedCollator owner) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
        this.owner = owner;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        ordering = owner.getTables();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        if ( sourceText.length() != 0 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
            NormalizerBase.Mode mode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
                CollatorUtilities.toNormalizerMode(owner.getDecomposition());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
            text = new NormalizerBase(sourceText, mode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     * CollationElementIterator constructor.  This takes the source string and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     * the collation object.  The cursor will walk thru the source string based
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     * on the predefined collation rules.  If the source string is empty,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     * NULLORDER will be returned on the calls to next().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     * @param sourceText the source string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     * @param order the collation object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    CollationElementIterator(CharacterIterator sourceText, RuleBasedCollator owner) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        this.owner = owner;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        ordering = owner.getTables();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        NormalizerBase.Mode mode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
            CollatorUtilities.toNormalizerMode(owner.getDecomposition());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        text = new NormalizerBase(sourceText, mode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * Resets the cursor to the beginning of the string.  The next call
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * to next() will return the first collation element in the string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    public void reset()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        if (text != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            text.reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            NormalizerBase.Mode mode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
                CollatorUtilities.toNormalizerMode(owner.getDecomposition());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
            text.setMode(mode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        buffer = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        expIndex = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        swapOrder = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     * Get the next collation element in the string.  <p>This iterator iterates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     * over a sequence of collation elements that were built from the string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     * Because there isn't necessarily a one-to-one mapping from characters to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     * collation elements, this doesn't mean the same thing as "return the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     * collation element [or ordering priority] of the next character in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     * string".</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * <p>This function returns the collation element that the iterator is currently
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     * pointing to and then updates the internal pointer to point to the next element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * previous() updates the pointer first and then returns the element.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     * means that when you change direction while iterating (i.e., call next() and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * then call previous(), or call previous() and then call next()), you'll get
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * back the same element twice.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    public int next()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        if (text == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            return NULLORDER;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        NormalizerBase.Mode textMode = text.getMode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        // convert the owner's mode to something the Normalizer understands
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        NormalizerBase.Mode ownerMode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
            CollatorUtilities.toNormalizerMode(owner.getDecomposition());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        if (textMode != ownerMode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
            text.setMode(ownerMode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        // if buffer contains any decomposed char values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        // return their strength orders before continuing in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        // the Normalizer's CharacterIterator.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        if (buffer != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            if (expIndex < buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
                return strengthOrder(buffer[expIndex++]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
                buffer = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                expIndex = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        } else if (swapOrder != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            if (Character.isSupplementaryCodePoint(swapOrder)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                char[] chars = Character.toChars(swapOrder);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                swapOrder = chars[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
                return chars[0] << 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            int order = swapOrder << 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            swapOrder = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            return order;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        int ch  = text.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        // are we at the end of Normalizer's text?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        if (ch == NormalizerBase.DONE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            return NULLORDER;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        int value = ordering.getUnicodeOrder(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        if (value == RuleBasedCollator.UNMAPPED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            swapOrder = ch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
            return UNMAPPEDCHARVALUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        else if (value >= RuleBasedCollator.CONTRACTCHARINDEX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            value = nextContractChar(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        if (value >= RuleBasedCollator.EXPANDCHARINDEX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
            buffer = ordering.getExpandValueList(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
            expIndex = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
            value = buffer[expIndex++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        if (ordering.isSEAsianSwapping()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            int consonant;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
            if (isThaiPreVowel(ch)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                consonant = text.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                if (isThaiBaseConsonant(consonant)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
                    buffer = makeReorderedBuffer(consonant, value, buffer, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                    value = buffer[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                    expIndex = 1;
4839
6b3edc448285 5047314: [Col] Collator.compare() runs indefinitely for a certain set of Thai strings
peytoia
parents: 2
diff changeset
   235
                } else if (consonant != NormalizerBase.DONE) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                    text.previous();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
            if (isLaoPreVowel(ch)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                consonant = text.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                if (isLaoBaseConsonant(consonant)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                    buffer = makeReorderedBuffer(consonant, value, buffer, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                    value = buffer[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                    expIndex = 1;
4839
6b3edc448285 5047314: [Col] Collator.compare() runs indefinitely for a certain set of Thai strings
peytoia
parents: 2
diff changeset
   245
                } else if (consonant != NormalizerBase.DONE) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                    text.previous();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        return strengthOrder(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     * Get the previous collation element in the string.  <p>This iterator iterates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     * over a sequence of collation elements that were built from the string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     * Because there isn't necessarily a one-to-one mapping from characters to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
     * collation elements, this doesn't mean the same thing as "return the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * collation element [or ordering priority] of the previous character in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * string".</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     * <p>This function updates the iterator's internal pointer to point to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     * collation element preceding the one it's currently pointing to and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
     * returns that element, while next() returns the current element and then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
     * updates the pointer.  This means that when you change direction while
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     * iterating (i.e., call next() and then call previous(), or call previous()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
     * and then call next()), you'll get back the same element twice.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    public int previous()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        if (text == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            return NULLORDER;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        NormalizerBase.Mode textMode = text.getMode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        // convert the owner's mode to something the Normalizer understands
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        NormalizerBase.Mode ownerMode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            CollatorUtilities.toNormalizerMode(owner.getDecomposition());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        if (textMode != ownerMode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            text.setMode(ownerMode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        if (buffer != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            if (expIndex > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                return strengthOrder(buffer[--expIndex]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                buffer = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                expIndex = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        } else if (swapOrder != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            if (Character.isSupplementaryCodePoint(swapOrder)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                char[] chars = Character.toChars(swapOrder);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                swapOrder = chars[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                return chars[0] << 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            int order = swapOrder << 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            swapOrder = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
            return order;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        int ch = text.previous();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        if (ch == NormalizerBase.DONE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            return NULLORDER;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        int value = ordering.getUnicodeOrder(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        if (value == RuleBasedCollator.UNMAPPED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            swapOrder = UNMAPPEDCHARVALUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            return ch;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        } else if (value >= RuleBasedCollator.CONTRACTCHARINDEX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            value = prevContractChar(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        if (value >= RuleBasedCollator.EXPANDCHARINDEX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            buffer = ordering.getExpandValueList(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            expIndex = buffer.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            value = buffer[--expIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        if (ordering.isSEAsianSwapping()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            int vowel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            if (isThaiBaseConsonant(ch)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                vowel = text.previous();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
                if (isThaiPreVowel(vowel)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
                    buffer = makeReorderedBuffer(vowel, value, buffer, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                    expIndex = buffer.length - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                    value = buffer[expIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
                    text.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
            if (isLaoBaseConsonant(ch)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                vowel = text.previous();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                if (isLaoPreVowel(vowel)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                    buffer = makeReorderedBuffer(vowel, value, buffer, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                    expIndex = buffer.length - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                    value = buffer[expIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                    text.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        return strengthOrder(value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
     * Return the primary component of a collation element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
     * @param order the collation element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
     * @return the element's primary component
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    public final static int primaryOrder(int order)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        order &= RBCollationTables.PRIMARYORDERMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
        return (order >>> RBCollationTables.PRIMARYORDERSHIFT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
     * Return the secondary component of a collation element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
     * @param order the collation element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
     * @return the element's secondary component
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
    public final static short secondaryOrder(int order)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        order = order & RBCollationTables.SECONDARYORDERMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        return ((short)(order >> RBCollationTables.SECONDARYORDERSHIFT));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     * Return the tertiary component of a collation element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
     * @param order the collation element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
     * @return the element's tertiary component
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    public final static short tertiaryOrder(int order)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        return ((short)(order &= RBCollationTables.TERTIARYORDERMASK));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     *  Get the comparison order in the desired strength.  Ignore the other
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
     *  differences.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
     *  @param order The order value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
    final int strengthOrder(int order)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        int s = owner.getStrength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        if (s == Collator.PRIMARY)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            order &= RBCollationTables.PRIMARYDIFFERENCEONLY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        } else if (s == Collator.SECONDARY)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
            order &= RBCollationTables.SECONDARYDIFFERENCEONLY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
        return order;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     * Sets the iterator to point to the collation element corresponding to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
     * the specified character (the parameter is a CHARACTER offset in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
     * original string, not an offset into its corresponding sequence of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
     * collation elements).  The value returned by the next call to next()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
     * will be the collation element corresponding to the specified position
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     * in the text.  If that position is in the middle of a contracting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     * character sequence, the result of the next call to next() is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     * collation element for that sequence.  This means that getOffset()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
     * is not guaranteed to return the same value as was passed to a preceding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
     * call to setOffset().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
     * @param newOffset The new character offset into the original text.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    public void setOffset(int newOffset)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        if (text != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            if (newOffset < text.getBeginIndex()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                || newOffset >= text.getEndIndex()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                    text.setIndexOnly(newOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                int c = text.setIndex(newOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                // if the desired character isn't used in a contracting character
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                // sequence, bypass all the backing-up logic-- we're sitting on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                // the right character already
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                if (ordering.usedInContractSeq(c)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                    // walk backwards through the string until we see a character
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                    // that DOESN'T participate in a contracting character sequence
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
                    while (ordering.usedInContractSeq(c)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                        c = text.previous();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
                    // now walk forward using this object's next() method until
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
                    // we pass the starting point and set our current position
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                    // to the beginning of the last "character" before or at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
                    // our starting position
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
                    int last = text.getIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
                    while (text.getIndex() <= newOffset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
                        last = text.getIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
                        next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                    text.setIndexOnly(last);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                    // we don't need this, since last is the last index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
                    // that is the starting of the contraction which encompass
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                    // newOffset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
                    // text.previous();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        buffer = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        expIndex = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        swapOrder = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
     * Returns the character offset in the original text corresponding to the next
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     * collation element.  (That is, getOffset() returns the position in the text
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     * corresponding to the collation element that will be returned by the next
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     * call to next().)  This value will always be the index of the FIRST character
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     * corresponding to the collation element (a contracting character sequence is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     * when two or more characters all correspond to the same collation element).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     * This means if you do setOffset(x) followed immediately by getOffset(), getOffset()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
     * won't necessarily return x.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
     * @return The character offset in the original text corresponding to the collation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     * element that will be returned by the next call to next().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
    public int getOffset()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
        return (text != null) ? text.getIndex() : 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
     * Return the maximum length of any expansion sequences that end
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
     * with the specified comparison order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
     * @param order a collation order returned by previous or next.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
     * @return the maximum length of any expansion sequences ending
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
     *         with the specified order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    public int getMaxExpansion(int order)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        return ordering.getMaxExpansion(order);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
     * Set a new string over which to iterate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
     * @param source  the new source text
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
    public void setText(String source)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
        buffer = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        swapOrder = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
        expIndex = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        NormalizerBase.Mode mode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            CollatorUtilities.toNormalizerMode(owner.getDecomposition());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        if (text == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
            text = new NormalizerBase(source, mode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
            text.setMode(mode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
            text.setText(source);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
     * Set a new string over which to iterate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
     * @param source  the new source text.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
     * @since 1.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
    public void setText(CharacterIterator source)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        buffer = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        swapOrder = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        expIndex = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        NormalizerBase.Mode mode =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            CollatorUtilities.toNormalizerMode(owner.getDecomposition());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        if (text == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
            text = new NormalizerBase(source, mode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            text.setMode(mode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            text.setText(source);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
    //============================================================
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
    // privates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
    //============================================================
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
     * Determine if a character is a Thai vowel (which sorts after
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
     * its base consonant).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
    private final static boolean isThaiPreVowel(int ch) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        return (ch >= 0x0e40) && (ch <= 0x0e44);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
     * Determine if a character is a Thai base consonant
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
    private final static boolean isThaiBaseConsonant(int ch) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        return (ch >= 0x0e01) && (ch <= 0x0e2e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
     * Determine if a character is a Lao vowel (which sorts after
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
     * its base consonant).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    private final static boolean isLaoPreVowel(int ch) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
        return (ch >= 0x0ec0) && (ch <= 0x0ec4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
     * Determine if a character is a Lao base consonant
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
    private final static boolean isLaoBaseConsonant(int ch) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
        return (ch >= 0x0e81) && (ch <= 0x0eae);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
     * This method produces a buffer which contains the collation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
     * elements for the two characters, with colFirst's values preceding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
     * another character's.  Presumably, the other character precedes colFirst
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
     * in logical order (otherwise you wouldn't need this method would you?).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
     * The assumption is that the other char's value(s) have already been
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
     * computed.  If this char has a single element it is passed to this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
     * method as lastValue, and lastExpansion is null.  If it has an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
     * expansion it is passed in lastExpansion, and colLastValue is ignored.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
    private int[] makeReorderedBuffer(int colFirst,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                                      int lastValue,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
                                      int[] lastExpansion,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                                      boolean forward) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        int[] result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
        int firstValue = ordering.getUnicodeOrder(colFirst);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
        if (firstValue >= RuleBasedCollator.CONTRACTCHARINDEX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
            firstValue = forward? nextContractChar(colFirst) : prevContractChar(colFirst);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
        int[] firstExpansion = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
        if (firstValue >= RuleBasedCollator.EXPANDCHARINDEX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
            firstExpansion = ordering.getExpandValueList(firstValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
        if (!forward) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            int temp1 = firstValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            firstValue = lastValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
            lastValue = temp1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            int[] temp2 = firstExpansion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            firstExpansion = lastExpansion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            lastExpansion = temp2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
        if (firstExpansion == null && lastExpansion == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
            result = new int [2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
            result[0] = firstValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
            result[1] = lastValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
            int firstLength = firstExpansion==null? 1 : firstExpansion.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
            int lastLength = lastExpansion==null? 1 : lastExpansion.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
            result = new int[firstLength + lastLength];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
            if (firstExpansion == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
                result[0] = firstValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
                System.arraycopy(firstExpansion, 0, result, 0, firstLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
            if (lastExpansion == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
                result[firstLength] = lastValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
            else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
                System.arraycopy(lastExpansion, 0, result, firstLength, lastLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
     *  Check if a comparison order is ignorable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
     *  @return true if a character is ignorable, false otherwise.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    final static boolean isIgnorable(int order)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
        return ((primaryOrder(order) == 0) ? true : false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
     * Get the ordering priority of the next contracting character in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
     * string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
     * @param ch the starting character of a contracting character token
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
     * @return the next contracting character's ordering.  Returns NULLORDER
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
     * if the end of string is reached.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
    private int nextContractChar(int ch)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        // First get the ordering of this single character,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
        // which is always the first element in the list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
        Vector list = ordering.getContractValues(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        EntryPair pair = (EntryPair)list.firstElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        int order = pair.value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        // find out the length of the longest contracting character sequence in the list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
        // There's logic in the builder code to make sure the longest sequence is always
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
        // the last.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
        pair = (EntryPair)list.lastElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
        int maxLength = pair.entryName.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        // (the Normalizer is cloned here so that the seeking we do in the next loop
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
        // won't affect our real position in the text)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
        NormalizerBase tempText = (NormalizerBase)text.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
        // extract the next maxLength characters in the string (we have to do this using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
        // Normalizer to ensure that our offsets correspond to those the rest of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
        // iterator is using) and store it in "fragment".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
        tempText.previous();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        key.setLength(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        int c = tempText.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        while (maxLength > 0 && c != NormalizerBase.DONE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
            if (Character.isSupplementaryCodePoint(c)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
                key.append(Character.toChars(c));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
                maxLength -= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
                key.append((char)c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
                --maxLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
            c = tempText.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
        String fragment = key.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        // now that we have that fragment, iterate through this list looking for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        // longest sequence that matches the characters in the actual text.  (maxLength
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        // is used here to keep track of the length of the longest sequence)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
        // Upon exit from this loop, maxLength will contain the length of the matching
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
        // sequence and order will contain the collation-element value corresponding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        // to this sequence
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
        maxLength = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        for (int i = list.size() - 1; i > 0; i--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
            pair = (EntryPair)list.elementAt(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
            if (!pair.fwd)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            if (fragment.startsWith(pair.entryName) && pair.entryName.length()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
                    > maxLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
                maxLength = pair.entryName.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
                order = pair.value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
        // seek our current iteration position to the end of the matching sequence
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        // and return the appropriate collation-element value (if there was no matching
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
        // sequence, we're already seeked to the right position and order already contains
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        // the correct collation-element value for the single character)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
        while (maxLength > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
            c = text.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
            maxLength -= Character.charCount(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        return order;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
     * Get the ordering priority of the previous contracting character in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
     * string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
     * @param ch the starting character of a contracting character token
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
     * @return the next contracting character's ordering.  Returns NULLORDER
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
     * if the end of string is reached.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
    private int prevContractChar(int ch)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
        // This function is identical to nextContractChar(), except that we've
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        // switched things so that the next() and previous() calls on the Normalizer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
        // are switched and so that we skip entry pairs with the fwd flag turned on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        // rather than off.  Notice that we still use append() and startsWith() when
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        // working on the fragment.  This is because the entry pairs that are used
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        // in reverse iteration have their names reversed already.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
        Vector list = ordering.getContractValues(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        EntryPair pair = (EntryPair)list.firstElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
        int order = pair.value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
        pair = (EntryPair)list.lastElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
        int maxLength = pair.entryName.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        NormalizerBase tempText = (NormalizerBase)text.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
        tempText.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
        key.setLength(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        int c = tempText.previous();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
        while (maxLength > 0 && c != NormalizerBase.DONE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            if (Character.isSupplementaryCodePoint(c)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
                key.append(Character.toChars(c));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
                maxLength -= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
                key.append((char)c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
                --maxLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
            c = tempText.previous();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        String fragment = key.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        maxLength = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        for (int i = list.size() - 1; i > 0; i--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
            pair = (EntryPair)list.elementAt(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
            if (pair.fwd)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
            if (fragment.startsWith(pair.entryName) && pair.entryName.length()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
                    > maxLength) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
                maxLength = pair.entryName.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
                order = pair.value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
        while (maxLength > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
            c = text.previous();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
            maxLength -= Character.charCount(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        return order;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
    final static int UNMAPPEDCHARVALUE = 0x7FFF0000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
    private NormalizerBase text = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
    private int[] buffer = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
    private int expIndex = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
    private StringBuffer key = new StringBuffer(5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
    private int swapOrder = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
    private RBCollationTables ordering;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
    private RuleBasedCollator owner;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
}