src/java.base/share/classes/java/text/MergeCollation.java
author naoto
Tue, 15 Oct 2019 09:25:59 -0700
changeset 58603 2312d1a04c49
parent 58242 94bb65cb37d3
permissions -rw-r--r--
8212749: DecimalFormat.setGroupingSize(int) allows setting negative grouping size 8231984: Clarify semantics of DecimalFormat.getGroupingSize(0) Reviewed-by: rriggs
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
58242
94bb65cb37d3 8230648: Replace @exception tag with @throws in java.base
jboes
parents: 53018
diff changeset
     2
 * Copyright (c) 1996, 2019, 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: 2
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: 2
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: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
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, 1997 - 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.util.ArrayList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * Utility class for normalizing and merging patterns for collation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * Patterns are strings of the form <entry>*, where <entry> has the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * form:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * <pattern> := <entry>*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * <entry> := <separator><chars>{"/"<extension>}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * <separator> := "=", ",", ";", "<", "&"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * <chars>, and <extension> are both arbitrary strings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * unquoted whitespaces are ignored.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * 'xxx' can be used to quote characters
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * One difference from Collator is that & is used to reset to a current
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * point. Or, in other words, it introduces a new sequence which is to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * be added to the old.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * That is: "a < b < c < d" is the same as "a < b & b < c & c < d" OR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * "a < b < d & b < c"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * XXX: make '' be a single quote.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * @see PatternEntry
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * @author             Mark Davis, Helena Shih
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
final class MergeCollation {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
     * Creates from a pattern
58242
94bb65cb37d3 8230648: Replace @exception tag with @throws in java.base
jboes
parents: 53018
diff changeset
    67
     * @throws    ParseException If the input pattern is incorrect.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    public MergeCollation(String pattern) throws ParseException
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        for (int i = 0; i < statusArray.length; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
            statusArray[i] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
        setPattern(pattern);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
     * recovers current pattern
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    public String getPattern() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
        return getPattern(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
     * recovers current pattern.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
     * @param withWhiteSpace puts spacing around the entries, and \n
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
     * before & and <
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    public String getPattern(boolean withWhiteSpace) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
        StringBuffer result = new StringBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        PatternEntry tmp = null;
12848
da701d422d2c 7117230: clean up warnings in java.text
dbhole
parents: 5506
diff changeset
    91
        ArrayList<PatternEntry> extList = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        for (i = 0; i < patterns.size(); ++i) {
12848
da701d422d2c 7117230: clean up warnings in java.text
dbhole
parents: 5506
diff changeset
    94
            PatternEntry entry = patterns.get(i);
53018
8bf9268df0e2 8215281: Use String.isEmpty() when applicable in java.base
redestad
parents: 47216
diff changeset
    95
            if (!entry.extension.isEmpty()) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
                if (extList == null)
12848
da701d422d2c 7117230: clean up warnings in java.text
dbhole
parents: 5506
diff changeset
    97
                    extList = new ArrayList<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
                extList.add(entry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
                if (extList != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
                    PatternEntry last = findLastWithNoExtension(i-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
                    for (int j = extList.size() - 1; j >= 0 ; j--) {
12848
da701d422d2c 7117230: clean up warnings in java.text
dbhole
parents: 5506
diff changeset
   103
                        tmp = extList.get(j);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
                        tmp.addToBuffer(result, false, withWhiteSpace, last);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
                    extList = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
                entry.addToBuffer(result, false, withWhiteSpace, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        if (extList != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
            PatternEntry last = findLastWithNoExtension(i-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
            for (int j = extList.size() - 1; j >= 0 ; j--) {
12848
da701d422d2c 7117230: clean up warnings in java.text
dbhole
parents: 5506
diff changeset
   114
                tmp = extList.get(j);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
                tmp.addToBuffer(result, false, withWhiteSpace, last);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
            extList = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        return result.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    private final PatternEntry findLastWithNoExtension(int i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        for (--i;i >= 0; --i) {
12848
da701d422d2c 7117230: clean up warnings in java.text
dbhole
parents: 5506
diff changeset
   124
            PatternEntry entry = patterns.get(i);
53018
8bf9268df0e2 8215281: Use String.isEmpty() when applicable in java.base
redestad
parents: 47216
diff changeset
   125
            if (entry.extension.isEmpty()) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
                return entry;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     * emits the pattern for collation builder.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * @return emits the string in the format understable to the collation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     * builder.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    public String emitPattern() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        return emitPattern(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * emits the pattern for collation builder.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * @param withWhiteSpace puts spacing around the entries, and \n
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * before & and <
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     * @return emits the string in the format understable to the collation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * builder.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    public String emitPattern(boolean withWhiteSpace) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        StringBuffer result = new StringBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        for (int i = 0; i < patterns.size(); ++i)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        {
12848
da701d422d2c 7117230: clean up warnings in java.text
dbhole
parents: 5506
diff changeset
   152
            PatternEntry entry = patterns.get(i);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            if (entry != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                entry.addToBuffer(result, true, withWhiteSpace, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        return result.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     * sets the pattern.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    public void setPattern(String pattern) throws ParseException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        patterns.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        addPattern(pattern);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * adds a pattern to the current one.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * @param pattern the new pattern to be added
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    public void addPattern(String pattern) throws ParseException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        if (pattern == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        PatternEntry.Parser parser = new PatternEntry.Parser(pattern);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        PatternEntry entry = parser.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        while (entry != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
            fixEntry(entry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
            entry = parser.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     * gets count of separate entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * @return the size of pattern entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    public int getCount() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        return patterns.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * gets count of separate entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     * @param index the offset of the desired pattern entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     * @return the requested pattern entry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    public PatternEntry getItemAt(int index) {
12848
da701d422d2c 7117230: clean up warnings in java.text
dbhole
parents: 5506
diff changeset
   201
        return patterns.get(index);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    //============================================================
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    // privates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    //============================================================
12848
da701d422d2c 7117230: clean up warnings in java.text
dbhole
parents: 5506
diff changeset
   207
    ArrayList<PatternEntry> patterns = new ArrayList<>(); // a list of PatternEntries
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    private transient PatternEntry saveEntry = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    private transient PatternEntry lastEntry = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    // This is really used as a local variable inside fixEntry, but we cache
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    // it here to avoid newing it up every time the method is called.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    private transient StringBuffer excess = new StringBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    // When building a MergeCollation, we need to do lots of searches to see
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    // whether a given entry is already in the table.  Since we're using an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    // array, this would make the algorithm O(N*N).  To speed things up, we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    // use this bit array to remember whether the array contains any entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    // starting with each Unicode character.  If not, we can avoid the search.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    // Using BitSet would make this easier, but it's significantly slower.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    private transient byte[] statusArray = new byte[8192];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    private final byte BITARRAYMASK = (byte)0x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    private final int  BYTEPOWER = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
    private final int  BYTEMASK = (1 << BYTEPOWER) - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
      If the strength is RESET, then just change the lastEntry to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
      be the current. (If the current is not in patterns, signal an error).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
      If not, then remove the current entry, and add it after lastEntry
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
      (which is usually at the end).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
      */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    private final void fixEntry(PatternEntry newEntry) throws ParseException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
        // check to see whether the new entry has the same characters as the previous
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        // entry did (this can happen when a pattern declaring a difference between two
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        // strings that are canonically equivalent is normalized).  If so, and the strength
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        // is anything other than IDENTICAL or RESET, throw an exception (you can't
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        // declare a string to be unequal to itself).       --rtg 5/24/99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        if (lastEntry != null && newEntry.chars.equals(lastEntry.chars)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                && newEntry.extension.equals(lastEntry.extension)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
            if (newEntry.strength != Collator.IDENTICAL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                && newEntry.strength != PatternEntry.RESET) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                    throw new ParseException("The entries " + lastEntry + " and "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                            + newEntry + " are adjacent in the rules, but have conflicting "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                            + "strengths: A character can't be unequal to itself.", -1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
                // otherwise, just skip this entry and behave as though you never saw it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                return;
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
        boolean changeLastEntry = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        if (newEntry.strength != PatternEntry.RESET) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
            int oldIndex = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            if ((newEntry.chars.length() == 1)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                char c = newEntry.chars.charAt(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                int statusIndex = c >> BYTEPOWER;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                byte bitClump = statusArray[statusIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                byte setBit = (byte)(BITARRAYMASK << (c & BYTEMASK));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                if (bitClump != 0 && (bitClump & setBit) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                    oldIndex = patterns.lastIndexOf(newEntry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                    // We're going to add an element that starts with this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                    // character, so go ahead and set its bit.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                    statusArray[statusIndex] = (byte)(bitClump | setBit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
                oldIndex = patterns.lastIndexOf(newEntry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
            if (oldIndex != -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
                patterns.remove(oldIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            excess.setLength(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            int lastIndex = findLastEntry(lastEntry, excess);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            if (excess.length() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                newEntry.extension = excess + newEntry.extension;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                if (lastIndex != patterns.size()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                    lastEntry = saveEntry;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                    changeLastEntry = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            if (lastIndex == patterns.size()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                patterns.add(newEntry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                saveEntry = newEntry;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                patterns.add(lastIndex, newEntry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        if (changeLastEntry) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            lastEntry = newEntry;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    private final int findLastEntry(PatternEntry entry,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                              StringBuffer excessChars) throws ParseException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        if (entry == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        if (entry.strength != PatternEntry.RESET) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            // Search backwards for string that contains this one;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            // most likely entry is last one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            int oldIndex = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            if ((entry.chars.length() == 1)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                int index = entry.chars.charAt(0) >> BYTEPOWER;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                if ((statusArray[index] &
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                    (BITARRAYMASK << (entry.chars.charAt(0) & BYTEMASK))) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                    oldIndex = patterns.lastIndexOf(entry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                oldIndex = patterns.lastIndexOf(entry);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            if ((oldIndex == -1))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                throw new ParseException("couldn't find last entry: "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                                          + entry, oldIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            return oldIndex + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
            for (i = patterns.size() - 1; i >= 0; --i) {
12848
da701d422d2c 7117230: clean up warnings in java.text
dbhole
parents: 5506
diff changeset
   329
                PatternEntry e = patterns.get(i);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                if (e.chars.regionMatches(0,entry.chars,0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                                              e.chars.length())) {
31471
ae27c6f1d8bf 8077242: (str) Optimize AbstractStringBuilder.append(CharSequence, int, int) for String argument
igerasim
parents: 25859
diff changeset
   332
                    excessChars.append(entry.chars, e.chars.length(),
ae27c6f1d8bf 8077242: (str) Optimize AbstractStringBuilder.append(CharSequence, int, int) for String argument
igerasim
parents: 25859
diff changeset
   333
                            entry.chars.length());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            if (i == -1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                throw new ParseException("couldn't find: " + entry, i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            return i + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
}