jdk/src/java.base/share/classes/sun/text/normalizer/Utility.java
author avstepan
Tue, 19 May 2015 16:04:14 +0400
changeset 30655 d83f50188ca9
parent 25859 3317bb8137f4
child 31680 88c53c2293b4
permissions -rw-r--r--
8080422: some docs cleanup for core libs Summary: some docs cleanup Reviewed-by: rriggs, lancea
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: 2497
diff changeset
     2
 * Copyright (c) 2005, 2009, 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: 2497
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: 2497
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: 2497
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2497
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2497
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
 *******************************************************************************
2497
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    27
 * (C) Copyright IBM Corp. and others, 1996-2009 - All Rights Reserved         *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 *                                                                             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * The original version of this source code and documentation is copyrighted   *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 * and owned by IBM, These materials are provided under terms of a License     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * Agreement between IBM and Sun. This technology is protected by multiple     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * US and International patents. This notice and attribution to IBM may not    *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * to removed.                                                                 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 *******************************************************************************
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
package sun.text.normalizer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
public final class Utility {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
    /**
2497
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    42
     * Convenience utility to compare two Object[]s
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    43
     * Ought to be in System.
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    44
     * @param len the length to compare.
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    45
     * The start indices and start+len must be valid.
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    46
     */
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    47
    public final static boolean arrayRegionMatches(char[] source, int sourceStart,
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    48
                                            char[] target, int targetStart,
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    49
                                            int len)
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    50
    {
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    51
        int sourceEnd = sourceStart + len;
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    52
        int delta = targetStart - sourceStart;
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    53
        for (int i = sourceStart; i < sourceEnd; i++) {
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    54
            if (source[i]!=target[i + delta])
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    55
            return false;
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    56
        }
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    57
        return true;
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    58
    }
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    59
903fd9d785ef 6404304: RFE: Unicode 5.1 support
peytoia
parents: 2
diff changeset
    60
    /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
     * Convert characters outside the range U+0020 to U+007F to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
     * Unicode escapes, and convert backslash to a double backslash.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    public static final String escape(String s) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
        StringBuffer buf = new StringBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
        for (int i=0; i<s.length(); ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
            int c = UTF16.charAt(s, i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
            i += UTF16.getCharCount(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
            if (c >= ' ' && c <= 0x007F) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
                if (c == '\\') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
                    buf.append("\\\\"); // That is, "\\"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
                    buf.append((char)c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
                boolean four = c <= 0xFFFF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
                buf.append(four ? "\\u" : "\\U");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
                hex(c, four ? 4 : 8, buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
        return buf.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    /* This map must be in ASCENDING ORDER OF THE ESCAPE CODE */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    static private final char[] UNESCAPE_MAP = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        /*"   0x22, 0x22 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        /*'   0x27, 0x27 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        /*?   0x3F, 0x3F */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
        /*\   0x5C, 0x5C */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        /*a*/ 0x61, 0x07,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        /*b*/ 0x62, 0x08,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        /*e*/ 0x65, 0x1b,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        /*f*/ 0x66, 0x0c,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        /*n*/ 0x6E, 0x0a,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        /*r*/ 0x72, 0x0d,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        /*t*/ 0x74, 0x09,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        /*v*/ 0x76, 0x0b
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     * Convert an escape to a 32-bit code point value.  We attempt
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * to parallel the icu4c unescapeAt() function.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * @param offset16 an array containing offset to the character
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     * <em>after</em> the backslash.  Upon return offset16[0] will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     * be updated to point after the escape sequence.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     * @return character value from 0 to 10FFFF, or -1 on error.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    public static int unescapeAt(String s, int[] offset16) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
        int c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        int result = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        int n = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        int minDig = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        int maxDig = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        int bitsPerDigit = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        int dig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
        boolean braces = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        /* Check that offset is in range */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        int offset = offset16[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
        int length = s.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        if (offset < 0 || offset >= length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
            return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        /* Fetch first UChar after '\\' */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
        c = UTF16.charAt(s, offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        offset += UTF16.getCharCount(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        /* Convert hexadecimal and octal escapes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        switch (c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        case 'u':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
            minDig = maxDig = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        case 'U':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
            minDig = maxDig = 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        case 'x':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
            minDig = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
            if (offset < length && UTF16.charAt(s, offset) == 0x7B /*{*/) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
                ++offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                braces = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
                maxDig = 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
                maxDig = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            dig = UCharacter.digit(c, 8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            if (dig >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
                minDig = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
                maxDig = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
                n = 1; /* Already have first octal digit */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                bitsPerDigit = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                result = dig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        if (minDig != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            while (offset < length && n < maxDig) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                c = UTF16.charAt(s, offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                dig = UCharacter.digit(c, (bitsPerDigit == 3) ? 8 : 16);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                if (dig < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
                result = (result << bitsPerDigit) | dig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
                offset += UTF16.getCharCount(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
                ++n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
            if (n < minDig) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
            if (braces) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
                if (c != 0x7D /*}*/) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
                    return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
                ++offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
            if (result < 0 || result >= 0x110000) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
                return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
            // If an escape sequence specifies a lead surrogate, see
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
            // if there is a trail surrogate after it, either as an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            // escape or as a literal.  If so, join them up into a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            // supplementary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
            if (offset < length &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
                UTF16.isLeadSurrogate((char) result)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
                int ahead = offset+1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                c = s.charAt(offset); // [sic] get 16-bit code unit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
                if (c == '\\' && ahead < length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
                    int o[] = new int[] { ahead };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
                    c = unescapeAt(s, o);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
                    ahead = o[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                if (UTF16.isTrailSurrogate((char) c)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                    offset = ahead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
                result = UCharacterProperty.getRawSupplementary(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                                  (char) result, (char) c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            offset16[0] = offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        /* Convert C-style escapes in table */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        for (i=0; i<UNESCAPE_MAP.length; i+=2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            if (c == UNESCAPE_MAP[i]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                offset16[0] = offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                return UNESCAPE_MAP[i+1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            } else if (c < UNESCAPE_MAP[i]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        /* Map \cX to control-X: X & 0x1F */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        if (c == 'c' && offset < length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
            c = UTF16.charAt(s, offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            offset16[0] = offset + UTF16.getCharCount(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            return 0x1F & c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        /* If no special forms are recognized, then consider
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
         * the backslash to generically escape the next character. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        offset16[0] = offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        return c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * Convert a integer to size width hex uppercase digits.
30655
d83f50188ca9 8080422: some docs cleanup for core libs
avstepan
parents: 25859
diff changeset
   230
     * E.g., {@code hex('a', 4, str) => "0041"}.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     * Append the output to the given StringBuffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     * If width is too small to fit, nothing will be appended to output.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    public static StringBuffer hex(int ch, int width, StringBuffer output) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        return appendNumber(output, ch, 16, width);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     * Convert a integer to size width (minimum) hex uppercase digits.
30655
d83f50188ca9 8080422: some docs cleanup for core libs
avstepan
parents: 25859
diff changeset
   240
     * E.g., {@code hex('a', 4, str) => "0041"}.  If the integer requires more
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     * than width digits, more will be used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
    public static String hex(int ch, int width) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        StringBuffer buf = new StringBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        return appendNumber(buf, ch, 16, width).toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     * Skip over a sequence of zero or more white space characters
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     * at pos.  Return the index of the first non-white-space character
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     * at or after pos, or str.length(), if there is none.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    public static int skipWhitespace(String str, int pos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        while (pos < str.length()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            int c = UTF16.charAt(str, pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            if (!UCharacterProperty.isRuleWhiteSpace(c)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            pos += UTF16.getCharCount(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        return pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    static final char DIGITS[] = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        'U', 'V', 'W', 'X', 'Y', 'Z'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     * Append the digits of a positive integer to the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     * <code>StringBuffer</code> in the given radix. This is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     * done recursively since it is easiest to generate the low-
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * order digit first, but it must be appended last.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     * @param result is the <code>StringBuffer</code> to append to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     * @param n is the positive integer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
     * @param radix is the radix, from 2 to 36 inclusive
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     * @param minDigits is the minimum number of digits to append.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    private static void recursiveAppendNumber(StringBuffer result, int n,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                                                int radix, int minDigits)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        int digit = n % radix;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        if (n >= radix || minDigits > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            recursiveAppendNumber(result, n / radix, radix, minDigits - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        result.append(DIGITS[digit]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
     * Append a number to the given StringBuffer in the given radix.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
     * Standard digits '0'-'9' are used and letters 'A'-'Z' for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
     * radices 11 through 36.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
     * @param result the digits of the number are appended here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
     * @param n the number to be converted to digits; may be negative.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     * If negative, a '-' is prepended to the digits.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     * @param radix a radix from 2 to 36 inclusive.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
     * @param minDigits the minimum number of digits, not including
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
     * any '-', to produce.  Values less than 2 have no effect.  One
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
     * digit is always emitted regardless of this parameter.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * @return a reference to result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    public static StringBuffer appendNumber(StringBuffer result, int n,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                                             int radix, int minDigits)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        throws IllegalArgumentException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        if (radix < 2 || radix > 36) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            throw new IllegalArgumentException("Illegal radix " + radix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        int abs = n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        if (n < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            abs = -n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            result.append("-");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        recursiveAppendNumber(result, abs, radix, minDigits);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     * Return true if the character is NOT printable ASCII.  The tab,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     * newline and linefeed characters are considered unprintable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
    public static boolean isUnprintable(int c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        return !(c >= 0x20 && c <= 0x7E);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    /**
30655
d83f50188ca9 8080422: some docs cleanup for core libs
avstepan
parents: 25859
diff changeset
   337
     * Escape unprintable characters using {@code <backslash>uxxxx} notation
d83f50188ca9 8080422: some docs cleanup for core libs
avstepan
parents: 25859
diff changeset
   338
     * for U+0000 to U+FFFF and {@code <backslash>Uxxxxxxxx} for U+10000 and
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
     * above.  If the character is printable ASCII, then do nothing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
     * and return FALSE.  Otherwise, append the escaped notation and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
     * return TRUE.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    public static boolean escapeUnprintable(StringBuffer result, int c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        if (isUnprintable(c)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
            result.append('\\');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
            if ((c & ~0xFFFF) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                result.append('U');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                result.append(DIGITS[0xF&(c>>28)]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                result.append(DIGITS[0xF&(c>>24)]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                result.append(DIGITS[0xF&(c>>20)]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                result.append(DIGITS[0xF&(c>>16)]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                result.append('u');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            result.append(DIGITS[0xF&(c>>12)]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            result.append(DIGITS[0xF&(c>>8)]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
            result.append(DIGITS[0xF&(c>>4)]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
            result.append(DIGITS[0xF&c]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    * Similar to StringBuffer.getChars, version 1.3.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
    * Since JDK 1.2 implements StringBuffer.getChars differently, this method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    * is here to provide consistent results.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    * To be removed after JDK 1.2 ceased to be the reference platform.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    * @param src source string buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    * @param srcBegin offset to the start of the src to retrieve from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
    * @param srcEnd offset to the end of the src to retrieve from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    * @param dst char array to store the retrieved chars
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
    * @param dstBegin offset to the start of the destination char array to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    *                 store the retrieved chars
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    public static void getChars(StringBuffer src, int srcBegin, int srcEnd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                                char dst[], int dstBegin)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        if (srcBegin == srcEnd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        src.getChars(srcBegin, srcEnd, dst, dstBegin);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
}