151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.misc;
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Comparator;
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** Implements a locale and case insensitive comparator suitable for
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    strings that are known to only contain ASCII characters. Some
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    tables internal to the JDK contain only ASCII data and are using
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    the "generalized" java.lang.String case-insensitive comparator
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    which converts each character to both upper and lower case. */
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class ASCIICaseInsensitiveComparator implements Comparator<String> {
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static final Comparator<String> CASE_INSENSITIVE_ORDER =
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        new ASCIICaseInsensitiveComparator();
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int compare(String s1, String s2) {
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int n1=s1.length(), n2=s2.length();
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int minLen = n1 < n2 ? n1 : n2;
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i=0; i < minLen; i++) {
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            char c1 = s1.charAt(i);
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            char c2 = s2.charAt(i);
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            assert c1 <= '\u007F' && c2 <= '\u007F';
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (c1 != c2) {
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                c1 = (char)toLower(c1);
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                c2 = (char)toLower(c2);
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (c1 != c2) {
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return c1 - c2;
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return n1 - n2;
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * A case insensitive hash code method to go with the case insensitive
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * compare() method.
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns a hash code for this ASCII string as if it were lower case.
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * returns same answer as:<p>
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>s.toLowerCase(Locale.US).hashCode();</code><p>
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * but does not allocate memory (it does NOT have the special
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * case Turkish rules).
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param s a String to compute the hashcode on.
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  a hash code value for this object.
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static int lowerCaseHashCode(String s) {
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int h = 0;
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int len = s.length();
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < len; i++) {
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            h = 31*h + toLower(s.charAt(i));
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return h;
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /* If java.util.regex.ASCII ever becomes public or sun.*, use its code instead:*/
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static boolean isLower(int ch) {
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return ((ch-'a')|('z'-ch)) >= 0;
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static boolean isUpper(int ch) {
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return ((ch-'A')|('Z'-ch)) >= 0;
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static int toLower(int ch) {
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return isUpper(ch) ? (ch + 0x20) : ch;
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static int toUpper(int ch) {
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return isLower(ch) ? (ch - 0x20) : ch;
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
100