diff -r 3392f250c784 -r ecbd252fd3a7 emul/mini/src/main/java/java/lang/String.java --- a/emul/mini/src/main/java/java/lang/String.java Fri Mar 22 16:59:47 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3079 +0,0 @@ -/* - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.lang; - -import java.io.UnsupportedEncodingException; -import java.util.Comparator; -import org.apidesign.bck2brwsr.core.ExtraJavaScript; -import org.apidesign.bck2brwsr.core.JavaScriptBody; -import org.apidesign.bck2brwsr.core.JavaScriptOnly; -import org.apidesign.bck2brwsr.core.JavaScriptPrototype; -import org.apidesign.bck2brwsr.emul.lang.System; - -/** - * The String class represents character strings. All - * string literals in Java programs, such as "abc", are - * implemented as instances of this class. - *

- * Strings are constant; their values cannot be changed after they - * are created. String buffers support mutable strings. - * Because String objects are immutable they can be shared. For example: - *

- *     String str = "abc";
- * 

- * is equivalent to: - *

- *     char data[] = {'a', 'b', 'c'};
- *     String str = new String(data);
- * 

- * Here are some more examples of how strings can be used: - *

- *     System.out.println("abc");
- *     String cde = "cde";
- *     System.out.println("abc" + cde);
- *     String c = "abc".substring(2,3);
- *     String d = cde.substring(1, 2);
- * 
- *

- * The class String includes methods for examining - * individual characters of the sequence, for comparing strings, for - * searching strings, for extracting substrings, and for creating a - * copy of a string with all characters translated to uppercase or to - * lowercase. Case mapping is based on the Unicode Standard version - * specified by the {@link java.lang.Character Character} class. - *

- * The Java language provides special support for the string - * concatenation operator ( + ), and for conversion of - * other objects to strings. String concatenation is implemented - * through the StringBuilder(or StringBuffer) - * class and its append method. - * String conversions are implemented through the method - * toString, defined by Object and - * inherited by all classes in Java. For additional information on - * string concatenation and conversion, see Gosling, Joy, and Steele, - * The Java Language Specification. - * - *

Unless otherwise noted, passing a null argument to a constructor - * or method in this class will cause a {@link NullPointerException} to be - * thrown. - * - *

A String represents a string in the UTF-16 format - * in which supplementary characters are represented by surrogate - * pairs (see the section Unicode - * Character Representations in the Character class for - * more information). - * Index values refer to char code units, so a supplementary - * character uses two positions in a String. - *

The String class provides methods for dealing with - * Unicode code points (i.e., characters), in addition to those for - * dealing with Unicode code units (i.e., char values). - * - * @author Lee Boynton - * @author Arthur van Hoff - * @author Martin Buchholz - * @author Ulf Zibis - * @see java.lang.Object#toString() - * @see java.lang.StringBuffer - * @see java.lang.StringBuilder - * @see java.nio.charset.Charset - * @since JDK1.0 - */ - -@ExtraJavaScript( - resource="/org/apidesign/vm4brwsr/emul/lang/java_lang_String.js", - processByteCode=true -) -@JavaScriptPrototype(container = "String.prototype", prototype = "new String") -public final class String - implements java.io.Serializable, Comparable, CharSequence -{ - /** real string to delegate to */ - private Object r; - - /** use serialVersionUID from JDK 1.0.2 for interoperability */ - private static final long serialVersionUID = -6849794470754667710L; - - @JavaScriptOnly(name="toString", value="String.prototype._r") - private static void jsToString() { - } - - @JavaScriptOnly(name="valueOf", value="function() { return this.toString().valueOf(); }") - private static void jsValudOf() { - } - - /** - * Class String is special cased within the Serialization Stream Protocol. - * - * A String instance is written initially into an ObjectOutputStream in the - * following format: - *

-     *      TC_STRING (utf String)
-     * 
- * The String is written by method DataOutput.writeUTF. - * A new handle is generated to refer to all future references to the - * string instance within the stream. - */ -// private static final ObjectStreamField[] serialPersistentFields = -// new ObjectStreamField[0]; - - /** - * Initializes a newly created {@code String} object so that it represents - * an empty character sequence. Note that use of this constructor is - * unnecessary since Strings are immutable. - */ - public String() { - this.r = ""; - } - - /** - * Initializes a newly created {@code String} object so that it represents - * the same sequence of characters as the argument; in other words, the - * newly created string is a copy of the argument string. Unless an - * explicit copy of {@code original} is needed, use of this constructor is - * unnecessary since Strings are immutable. - * - * @param original - * A {@code String} - */ - public String(String original) { - this.r = original.toString(); - } - - /** - * Allocates a new {@code String} so that it represents the sequence of - * characters currently contained in the character array argument. The - * contents of the character array are copied; subsequent modification of - * the character array does not affect the newly created string. - * - * @param value - * The initial value of the string - */ - @JavaScriptBody(args = { "charArr" }, body= - "for (var i = 0; i < charArr.length; i++) {\n" - + " if (typeof charArr[i] === 'number') charArr[i] = String.fromCharCode(charArr[i]);\n" - + "}\n" - + "this._r(charArr.join(''));\n" - ) - public String(char value[]) { - } - - /** - * Allocates a new {@code String} that contains characters from a subarray - * of the character array argument. The {@code offset} argument is the - * index of the first character of the subarray and the {@code count} - * argument specifies the length of the subarray. The contents of the - * subarray are copied; subsequent modification of the character array does - * not affect the newly created string. - * - * @param value - * Array that is the source of characters - * - * @param offset - * The initial offset - * - * @param count - * The length - * - * @throws IndexOutOfBoundsException - * If the {@code offset} and {@code count} arguments index - * characters outside the bounds of the {@code value} array - */ - public String(char value[], int offset, int count) { - initFromCharArray(value, offset, count); - } - - @JavaScriptBody(args = { "charArr", "off", "cnt" }, body = - "var up = off + cnt;\n" + - "for (var i = off; i < up; i++) {\n" + - " if (typeof charArr[i] === 'number') charArr[i] = String.fromCharCode(charArr[i]);\n" + - "}\n" + - "this._r(charArr.slice(off, up).join(\"\"));\n" - ) - private native void initFromCharArray(char value[], int offset, int count); - - /** - * Allocates a new {@code String} that contains characters from a subarray - * of the Unicode code point array - * argument. The {@code offset} argument is the index of the first code - * point of the subarray and the {@code count} argument specifies the - * length of the subarray. The contents of the subarray are converted to - * {@code char}s; subsequent modification of the {@code int} array does not - * affect the newly created string. - * - * @param codePoints - * Array that is the source of Unicode code points - * - * @param offset - * The initial offset - * - * @param count - * The length - * - * @throws IllegalArgumentException - * If any invalid Unicode code point is found in {@code - * codePoints} - * - * @throws IndexOutOfBoundsException - * If the {@code offset} and {@code count} arguments index - * characters outside the bounds of the {@code codePoints} array - * - * @since 1.5 - */ - public String(int[] codePoints, int offset, int count) { - if (offset < 0) { - throw new StringIndexOutOfBoundsException(offset); - } - if (count < 0) { - throw new StringIndexOutOfBoundsException(count); - } - // Note: offset or count might be near -1>>>1. - if (offset > codePoints.length - count) { - throw new StringIndexOutOfBoundsException(offset + count); - } - - final int end = offset + count; - - // Pass 1: Compute precise size of char[] - int n = count; - for (int i = offset; i < end; i++) { - int c = codePoints[i]; - if (Character.isBmpCodePoint(c)) - continue; - else if (Character.isValidCodePoint(c)) - n++; - else throw new IllegalArgumentException(Integer.toString(c)); - } - - // Pass 2: Allocate and fill in char[] - final char[] v = new char[n]; - - for (int i = offset, j = 0; i < end; i++, j++) { - int c = codePoints[i]; - if (Character.isBmpCodePoint(c)) - v[j] = (char) c; - else - Character.toSurrogates(c, v, j++); - } - - this.r = new String(v, 0, n); - } - - /** - * Allocates a new {@code String} constructed from a subarray of an array - * of 8-bit integer values. - * - *

The {@code offset} argument is the index of the first byte of the - * subarray, and the {@code count} argument specifies the length of the - * subarray. - * - *

Each {@code byte} in the subarray is converted to a {@code char} as - * specified in the method above. - * - * @deprecated This method does not properly convert bytes into characters. - * As of JDK 1.1, the preferred way to do this is via the - * {@code String} constructors that take a {@link - * java.nio.charset.Charset}, charset name, or that use the platform's - * default charset. - * - * @param ascii - * The bytes to be converted to characters - * - * @param hibyte - * The top 8 bits of each 16-bit Unicode code unit - * - * @param offset - * The initial offset - * @param count - * The length - * - * @throws IndexOutOfBoundsException - * If the {@code offset} or {@code count} argument is invalid - * - * @see #String(byte[], int) - * @see #String(byte[], int, int, java.lang.String) - * @see #String(byte[], int, int, java.nio.charset.Charset) - * @see #String(byte[], int, int) - * @see #String(byte[], java.lang.String) - * @see #String(byte[], java.nio.charset.Charset) - * @see #String(byte[]) - */ - @Deprecated - public String(byte ascii[], int hibyte, int offset, int count) { - checkBounds(ascii, offset, count); - char value[] = new char[count]; - - if (hibyte == 0) { - for (int i = count ; i-- > 0 ;) { - value[i] = (char) (ascii[i + offset] & 0xff); - } - } else { - hibyte <<= 8; - for (int i = count ; i-- > 0 ;) { - value[i] = (char) (hibyte | (ascii[i + offset] & 0xff)); - } - } - initFromCharArray(value, offset, count); - } - - /** - * Allocates a new {@code String} containing characters constructed from - * an array of 8-bit integer values. Each character cin the - * resulting string is constructed from the corresponding component - * b in the byte array such that: - * - *

-     *     c == (char)(((hibyte & 0xff) << 8)
-     *                         | (b & 0xff))
-     * 
- * - * @deprecated This method does not properly convert bytes into - * characters. As of JDK 1.1, the preferred way to do this is via the - * {@code String} constructors that take a {@link - * java.nio.charset.Charset}, charset name, or that use the platform's - * default charset. - * - * @param ascii - * The bytes to be converted to characters - * - * @param hibyte - * The top 8 bits of each 16-bit Unicode code unit - * - * @see #String(byte[], int, int, java.lang.String) - * @see #String(byte[], int, int, java.nio.charset.Charset) - * @see #String(byte[], int, int) - * @see #String(byte[], java.lang.String) - * @see #String(byte[], java.nio.charset.Charset) - * @see #String(byte[]) - */ - @Deprecated - public String(byte ascii[], int hibyte) { - this(ascii, hibyte, 0, ascii.length); - } - - /* Common private utility method used to bounds check the byte array - * and requested offset & length values used by the String(byte[],..) - * constructors. - */ - private static void checkBounds(byte[] bytes, int offset, int length) { - if (length < 0) - throw new StringIndexOutOfBoundsException(length); - if (offset < 0) - throw new StringIndexOutOfBoundsException(offset); - if (offset > bytes.length - length) - throw new StringIndexOutOfBoundsException(offset + length); - } - - /** - * Constructs a new {@code String} by decoding the specified subarray of - * bytes using the specified charset. The length of the new {@code String} - * is a function of the charset, and hence may not be equal to the length - * of the subarray. - * - *

The behavior of this constructor when the given bytes are not valid - * in the given charset is unspecified. The {@link - * java.nio.charset.CharsetDecoder} class should be used when more control - * over the decoding process is required. - * - * @param bytes - * The bytes to be decoded into characters - * - * @param offset - * The index of the first byte to decode - * - * @param length - * The number of bytes to decode - - * @param charsetName - * The name of a supported {@linkplain java.nio.charset.Charset - * charset} - * - * @throws UnsupportedEncodingException - * If the named charset is not supported - * - * @throws IndexOutOfBoundsException - * If the {@code offset} and {@code length} arguments index - * characters outside the bounds of the {@code bytes} array - * - * @since JDK1.1 - */ - public String(byte bytes[], int offset, int length, String charsetName) - throws UnsupportedEncodingException - { - this(checkUTF8(bytes, charsetName), offset, length); - } - - /** - * Constructs a new {@code String} by decoding the specified subarray of - * bytes using the specified {@linkplain java.nio.charset.Charset charset}. - * The length of the new {@code String} is a function of the charset, and - * hence may not be equal to the length of the subarray. - * - *

This method always replaces malformed-input and unmappable-character - * sequences with this charset's default replacement string. The {@link - * java.nio.charset.CharsetDecoder} class should be used when more control - * over the decoding process is required. - * - * @param bytes - * The bytes to be decoded into characters - * - * @param offset - * The index of the first byte to decode - * - * @param length - * The number of bytes to decode - * - * @param charset - * The {@linkplain java.nio.charset.Charset charset} to be used to - * decode the {@code bytes} - * - * @throws IndexOutOfBoundsException - * If the {@code offset} and {@code length} arguments index - * characters outside the bounds of the {@code bytes} array - * - * @since 1.6 - */ - /* don't want dependnecy on Charset - public String(byte bytes[], int offset, int length, Charset charset) { - if (charset == null) - throw new NullPointerException("charset"); - checkBounds(bytes, offset, length); - char[] v = StringCoding.decode(charset, bytes, offset, length); - this.offset = 0; - this.count = v.length; - this.value = v; - } - */ - - /** - * Constructs a new {@code String} by decoding the specified array of bytes - * using the specified {@linkplain java.nio.charset.Charset charset}. The - * length of the new {@code String} is a function of the charset, and hence - * may not be equal to the length of the byte array. - * - *

The behavior of this constructor when the given bytes are not valid - * in the given charset is unspecified. The {@link - * java.nio.charset.CharsetDecoder} class should be used when more control - * over the decoding process is required. - * - * @param bytes - * The bytes to be decoded into characters - * - * @param charsetName - * The name of a supported {@linkplain java.nio.charset.Charset - * charset} - * - * @throws UnsupportedEncodingException - * If the named charset is not supported - * - * @since JDK1.1 - */ - public String(byte bytes[], String charsetName) - throws UnsupportedEncodingException - { - this(bytes, 0, bytes.length, charsetName); - } - - /** - * Constructs a new {@code String} by decoding the specified array of - * bytes using the specified {@linkplain java.nio.charset.Charset charset}. - * The length of the new {@code String} is a function of the charset, and - * hence may not be equal to the length of the byte array. - * - *

This method always replaces malformed-input and unmappable-character - * sequences with this charset's default replacement string. The {@link - * java.nio.charset.CharsetDecoder} class should be used when more control - * over the decoding process is required. - * - * @param bytes - * The bytes to be decoded into characters - * - * @param charset - * The {@linkplain java.nio.charset.Charset charset} to be used to - * decode the {@code bytes} - * - * @since 1.6 - */ - /* don't want dep on Charset - public String(byte bytes[], Charset charset) { - this(bytes, 0, bytes.length, charset); - } - */ - - /** - * Constructs a new {@code String} by decoding the specified subarray of - * bytes using the platform's default charset. The length of the new - * {@code String} is a function of the charset, and hence may not be equal - * to the length of the subarray. - * - *

The behavior of this constructor when the given bytes are not valid - * in the default charset is unspecified. The {@link - * java.nio.charset.CharsetDecoder} class should be used when more control - * over the decoding process is required. - * - * @param bytes - * The bytes to be decoded into characters - * - * @param offset - * The index of the first byte to decode - * - * @param length - * The number of bytes to decode - * - * @throws IndexOutOfBoundsException - * If the {@code offset} and the {@code length} arguments index - * characters outside the bounds of the {@code bytes} array - * - * @since JDK1.1 - */ - public String(byte bytes[], int offset, int length) { - checkBounds(bytes, offset, length); - char[] v = new char[length]; - int[] at = { offset }; - int end = offset + length; - int chlen = 0; - while (at[0] < end) { - int ch = nextChar(bytes, at); - v[chlen++] = (char)ch; - } - initFromCharArray(v, 0, chlen); - } - - /** - * Constructs a new {@code String} by decoding the specified array of bytes - * using the platform's default charset. The length of the new {@code - * String} is a function of the charset, and hence may not be equal to the - * length of the byte array. - * - *

The behavior of this constructor when the given bytes are not valid - * in the default charset is unspecified. The {@link - * java.nio.charset.CharsetDecoder} class should be used when more control - * over the decoding process is required. - * - * @param bytes - * The bytes to be decoded into characters - * - * @since JDK1.1 - */ - public String(byte bytes[]) { - this(bytes, 0, bytes.length); - } - - /** - * Allocates a new string that contains the sequence of characters - * currently contained in the string buffer argument. The contents of the - * string buffer are copied; subsequent modification of the string buffer - * does not affect the newly created string. - * - * @param buffer - * A {@code StringBuffer} - */ - public String(StringBuffer buffer) { - this.r = buffer.toString(); - } - - /** - * Allocates a new string that contains the sequence of characters - * currently contained in the string builder argument. The contents of the - * string builder are copied; subsequent modification of the string builder - * does not affect the newly created string. - * - *

This constructor is provided to ease migration to {@code - * StringBuilder}. Obtaining a string from a string builder via the {@code - * toString} method is likely to run faster and is generally preferred. - * - * @param builder - * A {@code StringBuilder} - * - * @since 1.5 - */ - public String(StringBuilder builder) { - this.r = builder.toString(); - } - - /** - * Returns the length of this string. - * The length is equal to the number of Unicode - * code units in the string. - * - * @return the length of the sequence of characters represented by this - * object. - */ - @JavaScriptBody(args = {}, body = "return this.toString().length;") - public int length() { - throw new UnsupportedOperationException(); - } - - /** - * Returns true if, and only if, {@link #length()} is 0. - * - * @return true if {@link #length()} is 0, otherwise - * false - * - * @since 1.6 - */ - @JavaScriptBody(args = {}, body="return this.toString().length === 0;") - public boolean isEmpty() { - return length() == 0; - } - - /** - * Returns the char value at the - * specified index. An index ranges from 0 to - * length() - 1. The first char value of the sequence - * is at index 0, the next at index 1, - * and so on, as for array indexing. - * - *

If the char value specified by the index is a - * surrogate, the surrogate - * value is returned. - * - * @param index the index of the char value. - * @return the char value at the specified index of this string. - * The first char value is at index 0. - * @exception IndexOutOfBoundsException if the index - * argument is negative or not less than the length of this - * string. - */ - @JavaScriptBody(args = { "index" }, - body = "return this.toString().charCodeAt(index);" - ) - public char charAt(int index) { - throw new UnsupportedOperationException(); - } - - /** - * Returns the character (Unicode code point) at the specified - * index. The index refers to char values - * (Unicode code units) and ranges from 0 to - * {@link #length()} - 1. - * - *

If the char value specified at the given index - * is in the high-surrogate range, the following index is less - * than the length of this String, and the - * char value at the following index is in the - * low-surrogate range, then the supplementary code point - * corresponding to this surrogate pair is returned. Otherwise, - * the char value at the given index is returned. - * - * @param index the index to the char values - * @return the code point value of the character at the - * index - * @exception IndexOutOfBoundsException if the index - * argument is negative or not less than the length of this - * string. - * @since 1.5 - */ - public int codePointAt(int index) { - if ((index < 0) || (index >= length())) { - throw new StringIndexOutOfBoundsException(index); - } - return Character.codePointAtImpl(toCharArray(), offset() + index, offset() + length()); - } - - /** - * Returns the character (Unicode code point) before the specified - * index. The index refers to char values - * (Unicode code units) and ranges from 1 to {@link - * CharSequence#length() length}. - * - *

If the char value at (index - 1) - * is in the low-surrogate range, (index - 2) is not - * negative, and the char value at (index - - * 2) is in the high-surrogate range, then the - * supplementary code point value of the surrogate pair is - * returned. If the char value at index - - * 1 is an unpaired low-surrogate or a high-surrogate, the - * surrogate value is returned. - * - * @param index the index following the code point that should be returned - * @return the Unicode code point value before the given index. - * @exception IndexOutOfBoundsException if the index - * argument is less than 1 or greater than the length - * of this string. - * @since 1.5 - */ - public int codePointBefore(int index) { - int i = index - 1; - if ((i < 0) || (i >= length())) { - throw new StringIndexOutOfBoundsException(index); - } - return Character.codePointBeforeImpl(toCharArray(), offset() + index, offset()); - } - - /** - * Returns the number of Unicode code points in the specified text - * range of this String. The text range begins at the - * specified beginIndex and extends to the - * char at index endIndex - 1. Thus the - * length (in chars) of the text range is - * endIndex-beginIndex. Unpaired surrogates within - * the text range count as one code point each. - * - * @param beginIndex the index to the first char of - * the text range. - * @param endIndex the index after the last char of - * the text range. - * @return the number of Unicode code points in the specified text - * range - * @exception IndexOutOfBoundsException if the - * beginIndex is negative, or endIndex - * is larger than the length of this String, or - * beginIndex is larger than endIndex. - * @since 1.5 - */ - public int codePointCount(int beginIndex, int endIndex) { - if (beginIndex < 0 || endIndex > length() || beginIndex > endIndex) { - throw new IndexOutOfBoundsException(); - } - return Character.codePointCountImpl(toCharArray(), offset()+beginIndex, endIndex-beginIndex); - } - - /** - * Returns the index within this String that is - * offset from the given index by - * codePointOffset code points. Unpaired surrogates - * within the text range given by index and - * codePointOffset count as one code point each. - * - * @param index the index to be offset - * @param codePointOffset the offset in code points - * @return the index within this String - * @exception IndexOutOfBoundsException if index - * is negative or larger then the length of this - * String, or if codePointOffset is positive - * and the substring starting with index has fewer - * than codePointOffset code points, - * or if codePointOffset is negative and the substring - * before index has fewer than the absolute value - * of codePointOffset code points. - * @since 1.5 - */ - public int offsetByCodePoints(int index, int codePointOffset) { - if (index < 0 || index > length()) { - throw new IndexOutOfBoundsException(); - } - return Character.offsetByCodePointsImpl(toCharArray(), offset(), length(), - offset()+index, codePointOffset) - offset(); - } - - /** - * Copy characters from this string into dst starting at dstBegin. - * This method doesn't perform any range checking. - */ - @JavaScriptBody(args = { "arr", "to" }, body = - "var s = this.toString();\n" + - "for (var i = 0; i < s.length; i++) {\n" + - " arr[to++] = s[i];\n" + - "}" - ) - void getChars(char dst[], int dstBegin) { - System.arraycopy(toCharArray(), offset(), dst, dstBegin, length()); - } - - /** - * Copies characters from this string into the destination character - * array. - *

- * The first character to be copied is at index srcBegin; - * the last character to be copied is at index srcEnd-1 - * (thus the total number of characters to be copied is - * srcEnd-srcBegin). The characters are copied into the - * subarray of dst starting at index dstBegin - * and ending at index: - *

-     *     dstbegin + (srcEnd-srcBegin) - 1
-     * 
- * - * @param srcBegin index of the first character in the string - * to copy. - * @param srcEnd index after the last character in the string - * to copy. - * @param dst the destination array. - * @param dstBegin the start offset in the destination array. - * @exception IndexOutOfBoundsException If any of the following - * is true: - * - */ - @JavaScriptBody(args = { "beg", "end", "arr", "dst" }, body= - "var s = this.toString();\n" + - "while (beg < end) {\n" + - " arr[dst++] = s.charCodeAt(beg++);\n" + - "}\n" - ) - public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) { - if (srcBegin < 0) { - throw new StringIndexOutOfBoundsException(srcBegin); - } - if (srcEnd > length()) { - throw new StringIndexOutOfBoundsException(srcEnd); - } - if (srcBegin > srcEnd) { - throw new StringIndexOutOfBoundsException(srcEnd - srcBegin); - } - System.arraycopy(toCharArray(), offset() + srcBegin, dst, dstBegin, - srcEnd - srcBegin); - } - - /** - * Copies characters from this string into the destination byte array. Each - * byte receives the 8 low-order bits of the corresponding character. The - * eight high-order bits of each character are not copied and do not - * participate in the transfer in any way. - * - *

The first character to be copied is at index {@code srcBegin}; the - * last character to be copied is at index {@code srcEnd-1}. The total - * number of characters to be copied is {@code srcEnd-srcBegin}. The - * characters, converted to bytes, are copied into the subarray of {@code - * dst} starting at index {@code dstBegin} and ending at index: - * - *

-     *     dstbegin + (srcEnd-srcBegin) - 1
-     * 
- * - * @deprecated This method does not properly convert characters into - * bytes. As of JDK 1.1, the preferred way to do this is via the - * {@link #getBytes()} method, which uses the platform's default charset. - * - * @param srcBegin - * Index of the first character in the string to copy - * - * @param srcEnd - * Index after the last character in the string to copy - * - * @param dst - * The destination array - * - * @param dstBegin - * The start offset in the destination array - * - * @throws IndexOutOfBoundsException - * If any of the following is true: - * - */ - @Deprecated - public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) { - if (srcBegin < 0) { - throw new StringIndexOutOfBoundsException(srcBegin); - } - if (srcEnd > length()) { - throw new StringIndexOutOfBoundsException(srcEnd); - } - if (srcBegin > srcEnd) { - throw new StringIndexOutOfBoundsException(srcEnd - srcBegin); - } - int j = dstBegin; - int n = offset() + srcEnd; - int i = offset() + srcBegin; - char[] val = toCharArray(); /* avoid getfield opcode */ - - while (i < n) { - dst[j++] = (byte)val[i++]; - } - } - - /** - * Encodes this {@code String} into a sequence of bytes using the named - * charset, storing the result into a new byte array. - * - *

The behavior of this method when this string cannot be encoded in - * the given charset is unspecified. The {@link - * java.nio.charset.CharsetEncoder} class should be used when more control - * over the encoding process is required. - * - * @param charsetName - * The name of a supported {@linkplain java.nio.charset.Charset - * charset} - * - * @return The resultant byte array - * - * @throws UnsupportedEncodingException - * If the named charset is not supported - * - * @since JDK1.1 - */ - public byte[] getBytes(String charsetName) - throws UnsupportedEncodingException - { - checkUTF8(null, charsetName); - return getBytes(); - } - - /** - * Encodes this {@code String} into a sequence of bytes using the given - * {@linkplain java.nio.charset.Charset charset}, storing the result into a - * new byte array. - * - *

This method always replaces malformed-input and unmappable-character - * sequences with this charset's default replacement byte array. The - * {@link java.nio.charset.CharsetEncoder} class should be used when more - * control over the encoding process is required. - * - * @param charset - * The {@linkplain java.nio.charset.Charset} to be used to encode - * the {@code String} - * - * @return The resultant byte array - * - * @since 1.6 - */ - /* don't want dep on Charset - public byte[] getBytes(Charset charset) { - if (charset == null) throw new NullPointerException(); - return StringCoding.encode(charset, value, offset, count); - } - */ - - /** - * Encodes this {@code String} into a sequence of bytes using the - * platform's default charset, storing the result into a new byte array. - * - *

The behavior of this method when this string cannot be encoded in - * the default charset is unspecified. The {@link - * java.nio.charset.CharsetEncoder} class should be used when more control - * over the encoding process is required. - * - * @return The resultant byte array - * - * @since JDK1.1 - */ - public byte[] getBytes() { - int len = length(); - byte[] arr = new byte[len]; - for (int i = 0, j = 0; j < len; j++) { - final int v = charAt(j); - if (v < 128) { - arr[i++] = (byte) v; - continue; - } - if (v < 0x0800) { - arr = System.expandArray(arr, i + 1); - arr[i++] = (byte) (0xC0 | (v >> 6)); - arr[i++] = (byte) (0x80 | (0x3F & v)); - continue; - } - arr = System.expandArray(arr, i + 2); - arr[i++] = (byte) (0xE0 | (v >> 12)); - arr[i++] = (byte) (0x80 | ((v >> 6) & 0x7F)); - arr[i++] = (byte) (0x80 | (0x3F & v)); - } - return arr; - } - - /** - * Compares this string to the specified object. The result is {@code - * true} if and only if the argument is not {@code null} and is a {@code - * String} object that represents the same sequence of characters as this - * object. - * - * @param anObject - * The object to compare this {@code String} against - * - * @return {@code true} if the given object represents a {@code String} - * equivalent to this string, {@code false} otherwise - * - * @see #compareTo(String) - * @see #equalsIgnoreCase(String) - */ - @JavaScriptBody(args = { "obj" }, body = - "return obj != null && obj.$instOf_java_lang_String && " - + "this.toString() === obj.toString();" - ) - public boolean equals(Object anObject) { - if (this == anObject) { - return true; - } - if (anObject instanceof String) { - String anotherString = (String)anObject; - int n = length(); - if (n == anotherString.length()) { - char v1[] = toCharArray(); - char v2[] = anotherString.toCharArray(); - int i = offset(); - int j = anotherString.offset(); - while (n-- != 0) { - if (v1[i++] != v2[j++]) - return false; - } - return true; - } - } - return false; - } - - /** - * Compares this string to the specified {@code StringBuffer}. The result - * is {@code true} if and only if this {@code String} represents the same - * sequence of characters as the specified {@code StringBuffer}. - * - * @param sb - * The {@code StringBuffer} to compare this {@code String} against - * - * @return {@code true} if this {@code String} represents the same - * sequence of characters as the specified {@code StringBuffer}, - * {@code false} otherwise - * - * @since 1.4 - */ - public boolean contentEquals(StringBuffer sb) { - synchronized(sb) { - return contentEquals((CharSequence)sb); - } - } - - /** - * Compares this string to the specified {@code CharSequence}. The result - * is {@code true} if and only if this {@code String} represents the same - * sequence of char values as the specified sequence. - * - * @param cs - * The sequence to compare this {@code String} against - * - * @return {@code true} if this {@code String} represents the same - * sequence of char values as the specified sequence, {@code - * false} otherwise - * - * @since 1.5 - */ - public boolean contentEquals(CharSequence cs) { - if (length() != cs.length()) - return false; - // Argument is a StringBuffer, StringBuilder - if (cs instanceof AbstractStringBuilder) { - char v1[] = toCharArray(); - char v2[] = ((AbstractStringBuilder)cs).getValue(); - int i = offset(); - int j = 0; - int n = length(); - while (n-- != 0) { - if (v1[i++] != v2[j++]) - return false; - } - return true; - } - // Argument is a String - if (cs.equals(this)) - return true; - // Argument is a generic CharSequence - char v1[] = toCharArray(); - int i = offset(); - int j = 0; - int n = length(); - while (n-- != 0) { - if (v1[i++] != cs.charAt(j++)) - return false; - } - return true; - } - - /** - * Compares this {@code String} to another {@code String}, ignoring case - * considerations. Two strings are considered equal ignoring case if they - * are of the same length and corresponding characters in the two strings - * are equal ignoring case. - * - *

Two characters {@code c1} and {@code c2} are considered the same - * ignoring case if at least one of the following is true: - *

- * - * @param anotherString - * The {@code String} to compare this {@code String} against - * - * @return {@code true} if the argument is not {@code null} and it - * represents an equivalent {@code String} ignoring case; {@code - * false} otherwise - * - * @see #equals(Object) - */ - public boolean equalsIgnoreCase(String anotherString) { - return (this == anotherString) ? true : - (anotherString != null) && (anotherString.length() == length()) && - regionMatches(true, 0, anotherString, 0, length()); - } - - /** - * Compares two strings lexicographically. - * The comparison is based on the Unicode value of each character in - * the strings. The character sequence represented by this - * String object is compared lexicographically to the - * character sequence represented by the argument string. The result is - * a negative integer if this String object - * lexicographically precedes the argument string. The result is a - * positive integer if this String object lexicographically - * follows the argument string. The result is zero if the strings - * are equal; compareTo returns 0 exactly when - * the {@link #equals(Object)} method would return true. - *

- * This is the definition of lexicographic ordering. If two strings are - * different, then either they have different characters at some index - * that is a valid index for both strings, or their lengths are different, - * or both. If they have different characters at one or more index - * positions, let k be the smallest such index; then the string - * whose character at position k has the smaller value, as - * determined by using the < operator, lexicographically precedes the - * other string. In this case, compareTo returns the - * difference of the two character values at position k in - * the two string -- that is, the value: - *

-     * this.charAt(k)-anotherString.charAt(k)
-     * 
- * If there is no index position at which they differ, then the shorter - * string lexicographically precedes the longer string. In this case, - * compareTo returns the difference of the lengths of the - * strings -- that is, the value: - *
-     * this.length()-anotherString.length()
-     * 
- * - * @param anotherString the String to be compared. - * @return the value 0 if the argument string is equal to - * this string; a value less than 0 if this string - * is lexicographically less than the string argument; and a - * value greater than 0 if this string is - * lexicographically greater than the string argument. - */ - public int compareTo(String anotherString) { - int len1 = length(); - int len2 = anotherString.length(); - int n = Math.min(len1, len2); - char v1[] = toCharArray(); - char v2[] = anotherString.toCharArray(); - int i = offset(); - int j = anotherString.offset(); - - if (i == j) { - int k = i; - int lim = n + i; - while (k < lim) { - char c1 = v1[k]; - char c2 = v2[k]; - if (c1 != c2) { - return c1 - c2; - } - k++; - } - } else { - while (n-- != 0) { - char c1 = v1[i++]; - char c2 = v2[j++]; - if (c1 != c2) { - return c1 - c2; - } - } - } - return len1 - len2; - } - - /** - * A Comparator that orders String objects as by - * compareToIgnoreCase. This comparator is serializable. - *

- * Note that this Comparator does not take locale into account, - * and will result in an unsatisfactory ordering for certain locales. - * The java.text package provides Collators to allow - * locale-sensitive ordering. - * - * @see java.text.Collator#compare(String, String) - * @since 1.2 - */ - public static final Comparator CASE_INSENSITIVE_ORDER - = new CaseInsensitiveComparator(); - - private static int offset() { - return 0; - } - - private static class CaseInsensitiveComparator - implements Comparator, java.io.Serializable { - // use serialVersionUID from JDK 1.2.2 for interoperability - private static final long serialVersionUID = 8575799808933029326L; - - public int compare(String s1, String s2) { - int n1 = s1.length(); - int n2 = s2.length(); - int min = Math.min(n1, n2); - for (int i = 0; i < min; i++) { - char c1 = s1.charAt(i); - char c2 = s2.charAt(i); - if (c1 != c2) { - c1 = Character.toUpperCase(c1); - c2 = Character.toUpperCase(c2); - if (c1 != c2) { - c1 = Character.toLowerCase(c1); - c2 = Character.toLowerCase(c2); - if (c1 != c2) { - // No overflow because of numeric promotion - return c1 - c2; - } - } - } - } - return n1 - n2; - } - } - - /** - * Compares two strings lexicographically, ignoring case - * differences. This method returns an integer whose sign is that of - * calling compareTo with normalized versions of the strings - * where case differences have been eliminated by calling - * Character.toLowerCase(Character.toUpperCase(character)) on - * each character. - *

- * Note that this method does not take locale into account, - * and will result in an unsatisfactory ordering for certain locales. - * The java.text package provides collators to allow - * locale-sensitive ordering. - * - * @param str the String to be compared. - * @return a negative integer, zero, or a positive integer as the - * specified String is greater than, equal to, or less - * than this String, ignoring case considerations. - * @see java.text.Collator#compare(String, String) - * @since 1.2 - */ - public int compareToIgnoreCase(String str) { - return CASE_INSENSITIVE_ORDER.compare(this, str); - } - - /** - * Tests if two string regions are equal. - *

- * A substring of this String object is compared to a substring - * of the argument other. The result is true if these substrings - * represent identical character sequences. The substring of this - * String object to be compared begins at index toffset - * and has length len. The substring of other to be compared - * begins at index ooffset and has length len. The - * result is false if and only if at least one of the following - * is true: - *

- * - * @param toffset the starting offset of the subregion in this string. - * @param other the string argument. - * @param ooffset the starting offset of the subregion in the string - * argument. - * @param len the number of characters to compare. - * @return true if the specified subregion of this string - * exactly matches the specified subregion of the string argument; - * false otherwise. - */ - public boolean regionMatches(int toffset, String other, int ooffset, - int len) { - char ta[] = toCharArray(); - int to = offset() + toffset; - char pa[] = other.toCharArray(); - int po = other.offset() + ooffset; - // Note: toffset, ooffset, or len might be near -1>>>1. - if ((ooffset < 0) || (toffset < 0) || (toffset > (long)length() - len) - || (ooffset > (long)other.length() - len)) { - return false; - } - while (len-- > 0) { - if (ta[to++] != pa[po++]) { - return false; - } - } - return true; - } - - /** - * Tests if two string regions are equal. - *

- * A substring of this String object is compared to a substring - * of the argument other. The result is true if these - * substrings represent character sequences that are the same, ignoring - * case if and only if ignoreCase is true. The substring of - * this String object to be compared begins at index - * toffset and has length len. The substring of - * other to be compared begins at index ooffset and - * has length len. The result is false if and only if - * at least one of the following is true: - *

- * - * @param ignoreCase if true, ignore case when comparing - * characters. - * @param toffset the starting offset of the subregion in this - * string. - * @param other the string argument. - * @param ooffset the starting offset of the subregion in the string - * argument. - * @param len the number of characters to compare. - * @return true if the specified subregion of this string - * matches the specified subregion of the string argument; - * false otherwise. Whether the matching is exact - * or case insensitive depends on the ignoreCase - * argument. - */ - public boolean regionMatches(boolean ignoreCase, int toffset, - String other, int ooffset, int len) { - char ta[] = toCharArray(); - int to = offset() + toffset; - char pa[] = other.toCharArray(); - int po = other.offset() + ooffset; - // Note: toffset, ooffset, or len might be near -1>>>1. - if ((ooffset < 0) || (toffset < 0) || (toffset > (long)length() - len) || - (ooffset > (long)other.length() - len)) { - return false; - } - while (len-- > 0) { - char c1 = ta[to++]; - char c2 = pa[po++]; - if (c1 == c2) { - continue; - } - if (ignoreCase) { - // If characters don't match but case may be ignored, - // try converting both characters to uppercase. - // If the results match, then the comparison scan should - // continue. - char u1 = Character.toUpperCase(c1); - char u2 = Character.toUpperCase(c2); - if (u1 == u2) { - continue; - } - // Unfortunately, conversion to uppercase does not work properly - // for the Georgian alphabet, which has strange rules about case - // conversion. So we need to make one last check before - // exiting. - if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) { - continue; - } - } - return false; - } - return true; - } - - /** - * Tests if the substring of this string beginning at the - * specified index starts with the specified prefix. - * - * @param prefix the prefix. - * @param toffset where to begin looking in this string. - * @return true if the character sequence represented by the - * argument is a prefix of the substring of this object starting - * at index toffset; false otherwise. - * The result is false if toffset is - * negative or greater than the length of this - * String object; otherwise the result is the same - * as the result of the expression - *
-     *          this.substring(toffset).startsWith(prefix)
-     *          
- */ - @JavaScriptBody(args = { "find", "from" }, body= - "find = find.toString();\n" + - "return this.toString().substring(from, from + find.length) === find;\n" - ) - public boolean startsWith(String prefix, int toffset) { - char ta[] = toCharArray(); - int to = offset() + toffset; - char pa[] = prefix.toCharArray(); - int po = prefix.offset(); - int pc = prefix.length(); - // Note: toffset might be near -1>>>1. - if ((toffset < 0) || (toffset > length() - pc)) { - return false; - } - while (--pc >= 0) { - if (ta[to++] != pa[po++]) { - return false; - } - } - return true; - } - - /** - * Tests if this string starts with the specified prefix. - * - * @param prefix the prefix. - * @return true if the character sequence represented by the - * argument is a prefix of the character sequence represented by - * this string; false otherwise. - * Note also that true will be returned if the - * argument is an empty string or is equal to this - * String object as determined by the - * {@link #equals(Object)} method. - * @since 1. 0 - */ - public boolean startsWith(String prefix) { - return startsWith(prefix, 0); - } - - /** - * Tests if this string ends with the specified suffix. - * - * @param suffix the suffix. - * @return true if the character sequence represented by the - * argument is a suffix of the character sequence represented by - * this object; false otherwise. Note that the - * result will be true if the argument is the - * empty string or is equal to this String object - * as determined by the {@link #equals(Object)} method. - */ - public boolean endsWith(String suffix) { - return startsWith(suffix, length() - suffix.length()); - } - - /** - * Returns a hash code for this string. The hash code for a - * String object is computed as - *
-     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
-     * 
- * using int arithmetic, where s[i] is the - * ith character of the string, n is the length of - * the string, and ^ indicates exponentiation. - * (The hash value of the empty string is zero.) - * - * @return a hash code value for this object. - */ - public int hashCode() { - return super.hashCode(); - } - int computeHashCode() { - int h = 0; - if (h == 0 && length() > 0) { - int off = offset(); - int len = length(); - - for (int i = 0; i < len; i++) { - h = 31*h + charAt(off++); - } - } - return h; - } - - /** - * Returns the index within this string of the first occurrence of - * the specified character. If a character with value - * ch occurs in the character sequence represented by - * this String object, then the index (in Unicode - * code units) of the first such occurrence is returned. For - * values of ch in the range from 0 to 0xFFFF - * (inclusive), this is the smallest value k such that: - *
-     * this.charAt(k) == ch
-     * 
- * is true. For other values of ch, it is the - * smallest value k such that: - *
-     * this.codePointAt(k) == ch
-     * 
- * is true. In either case, if no such character occurs in this - * string, then -1 is returned. - * - * @param ch a character (Unicode code point). - * @return the index of the first occurrence of the character in the - * character sequence represented by this object, or - * -1 if the character does not occur. - */ - public int indexOf(int ch) { - return indexOf(ch, 0); - } - - /** - * Returns the index within this string of the first occurrence of the - * specified character, starting the search at the specified index. - *

- * If a character with value ch occurs in the - * character sequence represented by this String - * object at an index no smaller than fromIndex, then - * the index of the first such occurrence is returned. For values - * of ch in the range from 0 to 0xFFFF (inclusive), - * this is the smallest value k such that: - *

-     * (this.charAt(k) == ch) && (k >= fromIndex)
-     * 
- * is true. For other values of ch, it is the - * smallest value k such that: - *
-     * (this.codePointAt(k) == ch) && (k >= fromIndex)
-     * 
- * is true. In either case, if no such character occurs in this - * string at or after position fromIndex, then - * -1 is returned. - * - *

- * There is no restriction on the value of fromIndex. If it - * is negative, it has the same effect as if it were zero: this entire - * string may be searched. If it is greater than the length of this - * string, it has the same effect as if it were equal to the length of - * this string: -1 is returned. - * - *

All indices are specified in char values - * (Unicode code units). - * - * @param ch a character (Unicode code point). - * @param fromIndex the index to start the search from. - * @return the index of the first occurrence of the character in the - * character sequence represented by this object that is greater - * than or equal to fromIndex, or -1 - * if the character does not occur. - */ - @JavaScriptBody(args = { "ch", "from" }, body = - "if (typeof ch === 'number') ch = String.fromCharCode(ch);\n" + - "return this.toString().indexOf(ch, from);\n" - ) - public int indexOf(int ch, int fromIndex) { - if (fromIndex < 0) { - fromIndex = 0; - } else if (fromIndex >= length()) { - // Note: fromIndex might be near -1>>>1. - return -1; - } - - if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { - // handle most cases here (ch is a BMP code point or a - // negative value (invalid code point)) - final char[] value = this.toCharArray(); - final int offset = this.offset(); - final int max = offset + length(); - for (int i = offset + fromIndex; i < max ; i++) { - if (value[i] == ch) { - return i - offset; - } - } - return -1; - } else { - return indexOfSupplementary(ch, fromIndex); - } - } - - /** - * Handles (rare) calls of indexOf with a supplementary character. - */ - private int indexOfSupplementary(int ch, int fromIndex) { - if (Character.isValidCodePoint(ch)) { - final char[] value = this.toCharArray(); - final int offset = this.offset(); - final char hi = Character.highSurrogate(ch); - final char lo = Character.lowSurrogate(ch); - final int max = offset + length() - 1; - for (int i = offset + fromIndex; i < max; i++) { - if (value[i] == hi && value[i+1] == lo) { - return i - offset; - } - } - } - return -1; - } - - /** - * Returns the index within this string of the last occurrence of - * the specified character. For values of ch in the - * range from 0 to 0xFFFF (inclusive), the index (in Unicode code - * units) returned is the largest value k such that: - *

-     * this.charAt(k) == ch
-     * 
- * is true. For other values of ch, it is the - * largest value k such that: - *
-     * this.codePointAt(k) == ch
-     * 
- * is true. In either case, if no such character occurs in this - * string, then -1 is returned. The - * String is searched backwards starting at the last - * character. - * - * @param ch a character (Unicode code point). - * @return the index of the last occurrence of the character in the - * character sequence represented by this object, or - * -1 if the character does not occur. - */ - public int lastIndexOf(int ch) { - return lastIndexOf(ch, length() - 1); - } - - /** - * Returns the index within this string of the last occurrence of - * the specified character, searching backward starting at the - * specified index. For values of ch in the range - * from 0 to 0xFFFF (inclusive), the index returned is the largest - * value k such that: - *
-     * (this.charAt(k) == ch) && (k <= fromIndex)
-     * 
- * is true. For other values of ch, it is the - * largest value k such that: - *
-     * (this.codePointAt(k) == ch) && (k <= fromIndex)
-     * 
- * is true. In either case, if no such character occurs in this - * string at or before position fromIndex, then - * -1 is returned. - * - *

All indices are specified in char values - * (Unicode code units). - * - * @param ch a character (Unicode code point). - * @param fromIndex the index to start the search from. There is no - * restriction on the value of fromIndex. If it is - * greater than or equal to the length of this string, it has - * the same effect as if it were equal to one less than the - * length of this string: this entire string may be searched. - * If it is negative, it has the same effect as if it were -1: - * -1 is returned. - * @return the index of the last occurrence of the character in the - * character sequence represented by this object that is less - * than or equal to fromIndex, or -1 - * if the character does not occur before that point. - */ - @JavaScriptBody(args = { "ch", "from" }, body = - "if (typeof ch === 'number') ch = String.fromCharCode(ch);\n" + - "return this.toString().lastIndexOf(ch, from);" - ) - public int lastIndexOf(int ch, int fromIndex) { - if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { - // handle most cases here (ch is a BMP code point or a - // negative value (invalid code point)) - final char[] value = this.toCharArray(); - final int offset = this.offset(); - int i = offset + Math.min(fromIndex, length() - 1); - for (; i >= offset ; i--) { - if (value[i] == ch) { - return i - offset; - } - } - return -1; - } else { - return lastIndexOfSupplementary(ch, fromIndex); - } - } - - /** - * Handles (rare) calls of lastIndexOf with a supplementary character. - */ - private int lastIndexOfSupplementary(int ch, int fromIndex) { - if (Character.isValidCodePoint(ch)) { - final char[] value = this.toCharArray(); - final int offset = this.offset(); - char hi = Character.highSurrogate(ch); - char lo = Character.lowSurrogate(ch); - int i = offset + Math.min(fromIndex, length() - 2); - for (; i >= offset; i--) { - if (value[i] == hi && value[i+1] == lo) { - return i - offset; - } - } - } - return -1; - } - - /** - * Returns the index within this string of the first occurrence of the - * specified substring. - * - *

The returned index is the smallest value k for which: - *

-     * this.startsWith(str, k)
-     * 
- * If no such value of k exists, then {@code -1} is returned. - * - * @param str the substring to search for. - * @return the index of the first occurrence of the specified substring, - * or {@code -1} if there is no such occurrence. - */ - public int indexOf(String str) { - return indexOf(str, 0); - } - - /** - * Returns the index within this string of the first occurrence of the - * specified substring, starting at the specified index. - * - *

The returned index is the smallest value k for which: - *

-     * k >= fromIndex && this.startsWith(str, k)
-     * 
- * If no such value of k exists, then {@code -1} is returned. - * - * @param str the substring to search for. - * @param fromIndex the index from which to start the search. - * @return the index of the first occurrence of the specified substring, - * starting at the specified index, - * or {@code -1} if there is no such occurrence. - */ - @JavaScriptBody(args = { "str", "fromIndex" }, body = - "return this.toString().indexOf(str.toString(), fromIndex);" - ) - public native int indexOf(String str, int fromIndex); - - /** - * Returns the index within this string of the last occurrence of the - * specified substring. The last occurrence of the empty string "" - * is considered to occur at the index value {@code this.length()}. - * - *

The returned index is the largest value k for which: - *

-     * this.startsWith(str, k)
-     * 
- * If no such value of k exists, then {@code -1} is returned. - * - * @param str the substring to search for. - * @return the index of the last occurrence of the specified substring, - * or {@code -1} if there is no such occurrence. - */ - public int lastIndexOf(String str) { - return lastIndexOf(str, length()); - } - - /** - * Returns the index within this string of the last occurrence of the - * specified substring, searching backward starting at the specified index. - * - *

The returned index is the largest value k for which: - *

-     * k <= fromIndex && this.startsWith(str, k)
-     * 
- * If no such value of k exists, then {@code -1} is returned. - * - * @param str the substring to search for. - * @param fromIndex the index to start the search from. - * @return the index of the last occurrence of the specified substring, - * searching backward from the specified index, - * or {@code -1} if there is no such occurrence. - */ - @JavaScriptBody(args = { "s", "from" }, body = - "return this.toString().lastIndexOf(s.toString(), from);" - ) - public int lastIndexOf(String str, int fromIndex) { - return lastIndexOf(toCharArray(), offset(), length(), str.toCharArray(), str.offset(), str.length(), fromIndex); - } - - /** - * Code shared by String and StringBuffer to do searches. The - * source is the character array being searched, and the target - * is the string being searched for. - * - * @param source the characters being searched. - * @param sourceOffset offset of the source string. - * @param sourceCount count of the source string. - * @param target the characters being searched for. - * @param targetOffset offset of the target string. - * @param targetCount count of the target string. - * @param fromIndex the index to begin searching from. - */ - static int lastIndexOf(char[] source, int sourceOffset, int sourceCount, - char[] target, int targetOffset, int targetCount, - int fromIndex) { - /* - * Check arguments; return immediately where possible. For - * consistency, don't check for null str. - */ - int rightIndex = sourceCount - targetCount; - if (fromIndex < 0) { - return -1; - } - if (fromIndex > rightIndex) { - fromIndex = rightIndex; - } - /* Empty string always matches. */ - if (targetCount == 0) { - return fromIndex; - } - - int strLastIndex = targetOffset + targetCount - 1; - char strLastChar = target[strLastIndex]; - int min = sourceOffset + targetCount - 1; - int i = min + fromIndex; - - startSearchForLastChar: - while (true) { - while (i >= min && source[i] != strLastChar) { - i--; - } - if (i < min) { - return -1; - } - int j = i - 1; - int start = j - (targetCount - 1); - int k = strLastIndex - 1; - - while (j > start) { - if (source[j--] != target[k--]) { - i--; - continue startSearchForLastChar; - } - } - return start - sourceOffset + 1; - } - } - - /** - * Returns a new string that is a substring of this string. The - * substring begins with the character at the specified index and - * extends to the end of this string.

- * Examples: - *

-     * "unhappy".substring(2) returns "happy"
-     * "Harbison".substring(3) returns "bison"
-     * "emptiness".substring(9) returns "" (an empty string)
-     * 
- * - * @param beginIndex the beginning index, inclusive. - * @return the specified substring. - * @exception IndexOutOfBoundsException if - * beginIndex is negative or larger than the - * length of this String object. - */ - public String substring(int beginIndex) { - return substring(beginIndex, length()); - } - - /** - * Returns a new string that is a substring of this string. The - * substring begins at the specified beginIndex and - * extends to the character at index endIndex - 1. - * Thus the length of the substring is endIndex-beginIndex. - *

- * Examples: - *

-     * "hamburger".substring(4, 8) returns "urge"
-     * "smiles".substring(1, 5) returns "mile"
-     * 
- * - * @param beginIndex the beginning index, inclusive. - * @param endIndex the ending index, exclusive. - * @return the specified substring. - * @exception IndexOutOfBoundsException if the - * beginIndex is negative, or - * endIndex is larger than the length of - * this String object, or - * beginIndex is larger than - * endIndex. - */ - @JavaScriptBody(args = { "beginIndex", "endIndex" }, body = - "return this.toString().substring(beginIndex, endIndex);" - ) - public String substring(int beginIndex, int endIndex) { - if (beginIndex < 0) { - throw new StringIndexOutOfBoundsException(beginIndex); - } - if (endIndex > length()) { - throw new StringIndexOutOfBoundsException(endIndex); - } - if (beginIndex > endIndex) { - throw new StringIndexOutOfBoundsException(endIndex - beginIndex); - } - return ((beginIndex == 0) && (endIndex == length())) ? this : - new String(toCharArray(), offset() + beginIndex, endIndex - beginIndex); - } - - /** - * Returns a new character sequence that is a subsequence of this sequence. - * - *

An invocation of this method of the form - * - *

-     * str.subSequence(begin, end)
- * - * behaves in exactly the same way as the invocation - * - *
-     * str.substring(begin, end)
- * - * This method is defined so that the String class can implement - * the {@link CharSequence} interface.

- * - * @param beginIndex the begin index, inclusive. - * @param endIndex the end index, exclusive. - * @return the specified subsequence. - * - * @throws IndexOutOfBoundsException - * if beginIndex or endIndex are negative, - * if endIndex is greater than length(), - * or if beginIndex is greater than startIndex - * - * @since 1.4 - * @spec JSR-51 - */ - public CharSequence subSequence(int beginIndex, int endIndex) { - return this.substring(beginIndex, endIndex); - } - - /** - * Concatenates the specified string to the end of this string. - *

- * If the length of the argument string is 0, then this - * String object is returned. Otherwise, a new - * String object is created, representing a character - * sequence that is the concatenation of the character sequence - * represented by this String object and the character - * sequence represented by the argument string.

- * Examples: - *

-     * "cares".concat("s") returns "caress"
-     * "to".concat("get").concat("her") returns "together"
-     * 
- * - * @param str the String that is concatenated to the end - * of this String. - * @return a string that represents the concatenation of this object's - * characters followed by the string argument's characters. - */ - public String concat(String str) { - int otherLen = str.length(); - if (otherLen == 0) { - return this; - } - char buf[] = new char[length() + otherLen]; - getChars(0, length(), buf, 0); - str.getChars(0, otherLen, buf, length()); - return new String(buf, 0, length() + otherLen); - } - - /** - * Returns a new string resulting from replacing all occurrences of - * oldChar in this string with newChar. - *

- * If the character oldChar does not occur in the - * character sequence represented by this String object, - * then a reference to this String object is returned. - * Otherwise, a new String object is created that - * represents a character sequence identical to the character sequence - * represented by this String object, except that every - * occurrence of oldChar is replaced by an occurrence - * of newChar. - *

- * Examples: - *

-     * "mesquite in your cellar".replace('e', 'o')
-     *         returns "mosquito in your collar"
-     * "the war of baronets".replace('r', 'y')
-     *         returns "the way of bayonets"
-     * "sparring with a purple porpoise".replace('p', 't')
-     *         returns "starring with a turtle tortoise"
-     * "JonL".replace('q', 'x') returns "JonL" (no change)
-     * 
- * - * @param oldChar the old character. - * @param newChar the new character. - * @return a string derived from this string by replacing every - * occurrence of oldChar with newChar. - */ - @JavaScriptBody(args = { "arg1", "arg2" }, body = - "if (typeof arg1 === 'number') arg1 = String.fromCharCode(arg1);\n" + - "if (typeof arg2 === 'number') arg2 = String.fromCharCode(arg2);\n" + - "var s = this.toString();\n" + - "for (;;) {\n" + - " var ret = s.replace(arg1, arg2);\n" + - " if (ret === s) {\n" + - " return ret;\n" + - " }\n" + - " s = ret;\n" + - "}" - ) - public String replace(char oldChar, char newChar) { - if (oldChar != newChar) { - int len = length(); - int i = -1; - char[] val = toCharArray(); /* avoid getfield opcode */ - int off = offset(); /* avoid getfield opcode */ - - while (++i < len) { - if (val[off + i] == oldChar) { - break; - } - } - if (i < len) { - char buf[] = new char[len]; - for (int j = 0 ; j < i ; j++) { - buf[j] = val[off+j]; - } - while (i < len) { - char c = val[off + i]; - buf[i] = (c == oldChar) ? newChar : c; - i++; - } - return new String(buf, 0, len); - } - } - return this; - } - - /** - * Tells whether or not this string matches the given regular expression. - * - *

An invocation of this method of the form - * str.matches(regex) yields exactly the - * same result as the expression - * - *

{@link java.util.regex.Pattern}.{@link - * java.util.regex.Pattern#matches(String,CharSequence) - * matches}(regex, str)
- * - * @param regex - * the regular expression to which this string is to be matched - * - * @return true if, and only if, this string matches the - * given regular expression - * - * @throws PatternSyntaxException - * if the regular expression's syntax is invalid - * - * @see java.util.regex.Pattern - * - * @since 1.4 - * @spec JSR-51 - */ - @JavaScriptBody(args = { "regex" }, body = - "var self = this.toString();\n" - + "var re = new RegExp(regex.toString());\n" - + "var r = re.exec(self);\n" - + "return r != null && r.length > 0 && self.length == r[0].length;" - ) - public boolean matches(String regex) { - throw new UnsupportedOperationException(); - } - - /** - * Returns true if and only if this string contains the specified - * sequence of char values. - * - * @param s the sequence to search for - * @return true if this string contains s, false otherwise - * @throws NullPointerException if s is null - * @since 1.5 - */ - public boolean contains(CharSequence s) { - return indexOf(s.toString()) > -1; - } - - /** - * Replaces the first substring of this string that matches the given regular expression with the - * given replacement. - * - *

An invocation of this method of the form - * str.replaceFirst(regex, repl) - * yields exactly the same result as the expression - * - *

- * {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile - * compile}(regex).{@link - * java.util.regex.Pattern#matcher(java.lang.CharSequence) - * matcher}(str).{@link java.util.regex.Matcher#replaceFirst - * replaceFirst}(repl)
- * - *

- * Note that backslashes (\) and dollar signs ($) in the - * replacement string may cause the results to be different than if it were - * being treated as a literal replacement string; see - * {@link java.util.regex.Matcher#replaceFirst}. - * Use {@link java.util.regex.Matcher#quoteReplacement} to suppress the special - * meaning of these characters, if desired. - * - * @param regex - * the regular expression to which this string is to be matched - * @param replacement - * the string to be substituted for the first match - * - * @return The resulting String - * - * @throws PatternSyntaxException - * if the regular expression's syntax is invalid - * - * @see java.util.regex.Pattern - * - * @since 1.4 - * @spec JSR-51 - */ - public String replaceFirst(String regex, String replacement) { - throw new UnsupportedOperationException(); - } - - /** - * Replaces each substring of this string that matches the given regular expression with the - * given replacement. - * - *

An invocation of this method of the form - * str.replaceAll(regex, repl) - * yields exactly the same result as the expression - * - *

- * {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile - * compile}(regex).{@link - * java.util.regex.Pattern#matcher(java.lang.CharSequence) - * matcher}(str).{@link java.util.regex.Matcher#replaceAll - * replaceAll}(repl)
- * - *

- * Note that backslashes (\) and dollar signs ($) in the - * replacement string may cause the results to be different than if it were - * being treated as a literal replacement string; see - * {@link java.util.regex.Matcher#replaceAll Matcher.replaceAll}. - * Use {@link java.util.regex.Matcher#quoteReplacement} to suppress the special - * meaning of these characters, if desired. - * - * @param regex - * the regular expression to which this string is to be matched - * @param replacement - * the string to be substituted for each match - * - * @return The resulting String - * - * @throws PatternSyntaxException - * if the regular expression's syntax is invalid - * - * @see java.util.regex.Pattern - * - * @since 1.4 - * @spec JSR-51 - */ - public String replaceAll(String regex, String replacement) { - throw new UnsupportedOperationException(); - } - - /** - * Replaces each substring of this string that matches the literal target - * sequence with the specified literal replacement sequence. The - * replacement proceeds from the beginning of the string to the end, for - * example, replacing "aa" with "b" in the string "aaa" will result in - * "ba" rather than "ab". - * - * @param target The sequence of char values to be replaced - * @param replacement The replacement sequence of char values - * @return The resulting string - * @throws NullPointerException if target or - * replacement is null. - * @since 1.5 - */ - public String replace(CharSequence target, CharSequence replacement) { - throw new UnsupportedOperationException("This one should be supported, but without dep on rest of regexp"); - } - - /** - * Splits this string around matches of the given - * regular expression. - * - *

The array returned by this method contains each substring of this - * string that is terminated by another substring that matches the given - * expression or is terminated by the end of the string. The substrings in - * the array are in the order in which they occur in this string. If the - * expression does not match any part of the input then the resulting array - * has just one element, namely this string. - * - *

The limit parameter controls the number of times the - * pattern is applied and therefore affects the length of the resulting - * array. If the limit n is greater than zero then the pattern - * will be applied at most n - 1 times, the array's - * length will be no greater than n, and the array's last entry - * will contain all input beyond the last matched delimiter. If n - * is non-positive then the pattern will be applied as many times as - * possible and the array can have any length. If n is zero then - * the pattern will be applied as many times as possible, the array can - * have any length, and trailing empty strings will be discarded. - * - *

The string "boo:and:foo", for example, yields the - * following results with these parameters: - * - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
RegexLimitResult
:2{ "boo", "and:foo" }
:5{ "boo", "and", "foo" }
:-2{ "boo", "and", "foo" }
o5{ "b", "", ":and:f", "", "" }
o-2{ "b", "", ":and:f", "", "" }
o0{ "b", "", ":and:f" }
- * - *

An invocation of this method of the form - * str.split(regex, n) - * yields the same result as the expression - * - *

- * {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile - * compile}(regex).{@link - * java.util.regex.Pattern#split(java.lang.CharSequence,int) - * split}(str, n) - *
- * - * - * @param regex - * the delimiting regular expression - * - * @param limit - * the result threshold, as described above - * - * @return the array of strings computed by splitting this string - * around matches of the given regular expression - * - * @throws PatternSyntaxException - * if the regular expression's syntax is invalid - * - * @see java.util.regex.Pattern - * - * @since 1.4 - * @spec JSR-51 - */ - public String[] split(String regex, int limit) { - throw new UnsupportedOperationException("Needs regexp"); - } - - /** - * Splits this string around matches of the given regular expression. - * - *

This method works as if by invoking the two-argument {@link - * #split(String, int) split} method with the given expression and a limit - * argument of zero. Trailing empty strings are therefore not included in - * the resulting array. - * - *

The string "boo:and:foo", for example, yields the following - * results with these expressions: - * - *

- * - * - * - * - * - * - * - * - *
RegexResult
:{ "boo", "and", "foo" }
o{ "b", "", ":and:f" }
- * - * - * @param regex - * the delimiting regular expression - * - * @return the array of strings computed by splitting this string - * around matches of the given regular expression - * - * @throws PatternSyntaxException - * if the regular expression's syntax is invalid - * - * @see java.util.regex.Pattern - * - * @since 1.4 - * @spec JSR-51 - */ - public String[] split(String regex) { - return split(regex, 0); - } - - /** - * Converts all of the characters in this String to lower - * case using the rules of the given Locale. Case mapping is based - * on the Unicode Standard version specified by the {@link java.lang.Character Character} - * class. Since case mappings are not always 1:1 char mappings, the resulting - * String may be a different length than the original String. - *

- * Examples of lowercase mappings are in the following table: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Language Code of LocaleUpper CaseLower CaseDescription
tr (Turkish)\u0130\u0069capital letter I with dot above -> small letter i
tr (Turkish)\u0049\u0131capital letter I -> small letter dotless i
(all)French Friesfrench frieslowercased all chars in String
(all)capiotacapchi - * capthetacapupsil - * capsigmaiotachi - * thetaupsilon - * sigmalowercased all chars in String
- * - * @param locale use the case transformation rules for this locale - * @return the String, converted to lowercase. - * @see java.lang.String#toLowerCase() - * @see java.lang.String#toUpperCase() - * @see java.lang.String#toUpperCase(Locale) - * @since 1.1 - */ -// public String toLowerCase(Locale locale) { -// if (locale == null) { -// throw new NullPointerException(); -// } -// -// int firstUpper; -// -// /* Now check if there are any characters that need to be changed. */ -// scan: { -// for (firstUpper = 0 ; firstUpper < count; ) { -// char c = value[offset+firstUpper]; -// if ((c >= Character.MIN_HIGH_SURROGATE) && -// (c <= Character.MAX_HIGH_SURROGATE)) { -// int supplChar = codePointAt(firstUpper); -// if (supplChar != Character.toLowerCase(supplChar)) { -// break scan; -// } -// firstUpper += Character.charCount(supplChar); -// } else { -// if (c != Character.toLowerCase(c)) { -// break scan; -// } -// firstUpper++; -// } -// } -// return this; -// } -// -// char[] result = new char[count]; -// int resultOffset = 0; /* result may grow, so i+resultOffset -// * is the write location in result */ -// -// /* Just copy the first few lowerCase characters. */ -// System.arraycopy(value, offset, result, 0, firstUpper); -// -// String lang = locale.getLanguage(); -// boolean localeDependent = -// (lang == "tr" || lang == "az" || lang == "lt"); -// char[] lowerCharArray; -// int lowerChar; -// int srcChar; -// int srcCount; -// for (int i = firstUpper; i < count; i += srcCount) { -// srcChar = (int)value[offset+i]; -// if ((char)srcChar >= Character.MIN_HIGH_SURROGATE && -// (char)srcChar <= Character.MAX_HIGH_SURROGATE) { -// srcChar = codePointAt(i); -// srcCount = Character.charCount(srcChar); -// } else { -// srcCount = 1; -// } -// if (localeDependent || srcChar == '\u03A3') { // GREEK CAPITAL LETTER SIGMA -// lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale); -// } else if (srcChar == '\u0130') { // LATIN CAPITAL LETTER I DOT -// lowerChar = Character.ERROR; -// } else { -// lowerChar = Character.toLowerCase(srcChar); -// } -// if ((lowerChar == Character.ERROR) || -// (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) { -// if (lowerChar == Character.ERROR) { -// if (!localeDependent && srcChar == '\u0130') { -// lowerCharArray = -// ConditionalSpecialCasing.toLowerCaseCharArray(this, i, Locale.ENGLISH); -// } else { -// lowerCharArray = -// ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale); -// } -// } else if (srcCount == 2) { -// resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount; -// continue; -// } else { -// lowerCharArray = Character.toChars(lowerChar); -// } -// -// /* Grow result if needed */ -// int mapLen = lowerCharArray.length; -// if (mapLen > srcCount) { -// char[] result2 = new char[result.length + mapLen - srcCount]; -// System.arraycopy(result, 0, result2, 0, -// i + resultOffset); -// result = result2; -// } -// for (int x=0; xString to lower - * case using the rules of the default locale. This is equivalent to calling - * toLowerCase(Locale.getDefault()). - *

- * Note: This method is locale sensitive, and may produce unexpected - * results if used for strings that are intended to be interpreted locale - * independently. - * Examples are programming language identifiers, protocol keys, and HTML - * tags. - * For instance, "TITLE".toLowerCase() in a Turkish locale - * returns "t\u005Cu0131tle", where '\u005Cu0131' is the - * LATIN SMALL LETTER DOTLESS I character. - * To obtain correct results for locale insensitive strings, use - * toLowerCase(Locale.ENGLISH). - *

- * @return the String, converted to lowercase. - * @see java.lang.String#toLowerCase(Locale) - */ - @JavaScriptBody(args = {}, body = "return this.toLowerCase();") - public String toLowerCase() { - throw new UnsupportedOperationException("Should be supported but without connection to locale"); - } - - /** - * Converts all of the characters in this String to upper - * case using the rules of the given Locale. Case mapping is based - * on the Unicode Standard version specified by the {@link java.lang.Character Character} - * class. Since case mappings are not always 1:1 char mappings, the resulting - * String may be a different length than the original String. - *

- * Examples of locale-sensitive and 1:M case mappings are in the following table. - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Language Code of LocaleLower CaseUpper CaseDescription
tr (Turkish)\u0069\u0130small letter i -> capital letter I with dot above
tr (Turkish)\u0131\u0049small letter dotless i -> capital letter I
(all)\u00df\u0053 \u0053small letter sharp s -> two letters: SS
(all)FahrvergnügenFAHRVERGNÜGEN
- * @param locale use the case transformation rules for this locale - * @return the String, converted to uppercase. - * @see java.lang.String#toUpperCase() - * @see java.lang.String#toLowerCase() - * @see java.lang.String#toLowerCase(Locale) - * @since 1.1 - */ - /* not for javascript - public String toUpperCase(Locale locale) { - if (locale == null) { - throw new NullPointerException(); - } - - int firstLower; - - // Now check if there are any characters that need to be changed. - scan: { - for (firstLower = 0 ; firstLower < count; ) { - int c = (int)value[offset+firstLower]; - int srcCount; - if ((c >= Character.MIN_HIGH_SURROGATE) && - (c <= Character.MAX_HIGH_SURROGATE)) { - c = codePointAt(firstLower); - srcCount = Character.charCount(c); - } else { - srcCount = 1; - } - int upperCaseChar = Character.toUpperCaseEx(c); - if ((upperCaseChar == Character.ERROR) || - (c != upperCaseChar)) { - break scan; - } - firstLower += srcCount; - } - return this; - } - - char[] result = new char[count]; /* may grow * - int resultOffset = 0; /* result may grow, so i+resultOffset - * is the write location in result * - - /* Just copy the first few upperCase characters. * - System.arraycopy(value, offset, result, 0, firstLower); - - String lang = locale.getLanguage(); - boolean localeDependent = - (lang == "tr" || lang == "az" || lang == "lt"); - char[] upperCharArray; - int upperChar; - int srcChar; - int srcCount; - for (int i = firstLower; i < count; i += srcCount) { - srcChar = (int)value[offset+i]; - if ((char)srcChar >= Character.MIN_HIGH_SURROGATE && - (char)srcChar <= Character.MAX_HIGH_SURROGATE) { - srcChar = codePointAt(i); - srcCount = Character.charCount(srcChar); - } else { - srcCount = 1; - } - if (localeDependent) { - upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale); - } else { - upperChar = Character.toUpperCaseEx(srcChar); - } - if ((upperChar == Character.ERROR) || - (upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) { - if (upperChar == Character.ERROR) { - if (localeDependent) { - upperCharArray = - ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale); - } else { - upperCharArray = Character.toUpperCaseCharArray(srcChar); - } - } else if (srcCount == 2) { - resultOffset += Character.toChars(upperChar, result, i + resultOffset) - srcCount; - continue; - } else { - upperCharArray = Character.toChars(upperChar); - } - - /* Grow result if needed * - int mapLen = upperCharArray.length; - if (mapLen > srcCount) { - char[] result2 = new char[result.length + mapLen - srcCount]; - System.arraycopy(result, 0, result2, 0, - i + resultOffset); - result = result2; - } - for (int x=0; xString to upper - * case using the rules of the default locale. This method is equivalent to - * toUpperCase(Locale.getDefault()). - *

- * Note: This method is locale sensitive, and may produce unexpected - * results if used for strings that are intended to be interpreted locale - * independently. - * Examples are programming language identifiers, protocol keys, and HTML - * tags. - * For instance, "title".toUpperCase() in a Turkish locale - * returns "T\u005Cu0130TLE", where '\u005Cu0130' is the - * LATIN CAPITAL LETTER I WITH DOT ABOVE character. - * To obtain correct results for locale insensitive strings, use - * toUpperCase(Locale.ENGLISH). - *

- * @return the String, converted to uppercase. - * @see java.lang.String#toUpperCase(Locale) - */ - @JavaScriptBody(args = {}, body = "return this.toUpperCase();") - public String toUpperCase() { - throw new UnsupportedOperationException(); - } - - /** - * Returns a copy of the string, with leading and trailing whitespace - * omitted. - *

- * If this String object represents an empty character - * sequence, or the first and last characters of character sequence - * represented by this String object both have codes - * greater than '\u0020' (the space character), then a - * reference to this String object is returned. - *

- * Otherwise, if there is no character with a code greater than - * '\u0020' in the string, then a new - * String object representing an empty string is created - * and returned. - *

- * Otherwise, let k be the index of the first character in the - * string whose code is greater than '\u0020', and let - * m be the index of the last character in the string whose code - * is greater than '\u0020'. A new String - * object is created, representing the substring of this string that - * begins with the character at index k and ends with the - * character at index m-that is, the result of - * this.substring(km+1). - *

- * This method may be used to trim whitespace (as defined above) from - * the beginning and end of a string. - * - * @return A copy of this string with leading and trailing white - * space removed, or this string if it has no leading or - * trailing white space. - */ - public String trim() { - int len = length(); - int st = 0; - int off = offset(); /* avoid getfield opcode */ - char[] val = toCharArray(); /* avoid getfield opcode */ - - while ((st < len) && (val[off + st] <= ' ')) { - st++; - } - while ((st < len) && (val[off + len - 1] <= ' ')) { - len--; - } - return ((st > 0) || (len < length())) ? substring(st, len) : this; - } - - /** - * This object (which is already a string!) is itself returned. - * - * @return the string itself. - */ - @JavaScriptBody(args = {}, body = "return this.toString();") - public String toString() { - return this; - } - - /** - * Converts this string to a new character array. - * - * @return a newly allocated character array whose length is the length - * of this string and whose contents are initialized to contain - * the character sequence represented by this string. - */ - public char[] toCharArray() { - char result[] = new char[length()]; - getChars(0, length(), result, 0); - return result; - } - - /** - * Returns a formatted string using the specified format string and - * arguments. - * - *

The locale always used is the one returned by {@link - * java.util.Locale#getDefault() Locale.getDefault()}. - * - * @param format - * A format string - * - * @param args - * Arguments referenced by the format specifiers in the format - * string. If there are more arguments than format specifiers, the - * extra arguments are ignored. The number of arguments is - * variable and may be zero. The maximum number of arguments is - * limited by the maximum dimension of a Java array as defined by - * The Java™ Virtual Machine Specification. - * The behaviour on a - * null argument depends on the conversion. - * - * @throws IllegalFormatException - * If a format string contains an illegal syntax, a format - * specifier that is incompatible with the given arguments, - * insufficient arguments given the format string, or other - * illegal conditions. For specification of all possible - * formatting errors, see the Details section of the - * formatter class specification. - * - * @throws NullPointerException - * If the format is null - * - * @return A formatted string - * - * @see java.util.Formatter - * @since 1.5 - */ - public static String format(String format, Object ... args) { - throw new UnsupportedOperationException(); - } - - /** - * Returns a formatted string using the specified locale, format string, - * and arguments. - * - * @param l - * The {@linkplain java.util.Locale locale} to apply during - * formatting. If l is null then no localization - * is applied. - * - * @param format - * A format string - * - * @param args - * Arguments referenced by the format specifiers in the format - * string. If there are more arguments than format specifiers, the - * extra arguments are ignored. The number of arguments is - * variable and may be zero. The maximum number of arguments is - * limited by the maximum dimension of a Java array as defined by - * The Java™ Virtual Machine Specification. - * The behaviour on a - * null argument depends on the conversion. - * - * @throws IllegalFormatException - * If a format string contains an illegal syntax, a format - * specifier that is incompatible with the given arguments, - * insufficient arguments given the format string, or other - * illegal conditions. For specification of all possible - * formatting errors, see the Details section of the - * formatter class specification - * - * @throws NullPointerException - * If the format is null - * - * @return A formatted string - * - * @see java.util.Formatter - * @since 1.5 - */ -// public static String format(Locale l, String format, Object ... args) { -// return new Formatter(l).format(format, args).toString(); -// } - - /** - * Returns the string representation of the Object argument. - * - * @param obj an Object. - * @return if the argument is null, then a string equal to - * "null"; otherwise, the value of - * obj.toString() is returned. - * @see java.lang.Object#toString() - */ - public static String valueOf(Object obj) { - return (obj == null) ? "null" : obj.toString(); - } - - /** - * Returns the string representation of the char array - * argument. The contents of the character array are copied; subsequent - * modification of the character array does not affect the newly - * created string. - * - * @param data a char array. - * @return a newly allocated string representing the same sequence of - * characters contained in the character array argument. - */ - public static String valueOf(char data[]) { - return new String(data); - } - - /** - * Returns the string representation of a specific subarray of the - * char array argument. - *

- * The offset argument is the index of the first - * character of the subarray. The count argument - * specifies the length of the subarray. The contents of the subarray - * are copied; subsequent modification of the character array does not - * affect the newly created string. - * - * @param data the character array. - * @param offset the initial offset into the value of the - * String. - * @param count the length of the value of the String. - * @return a string representing the sequence of characters contained - * in the subarray of the character array argument. - * @exception IndexOutOfBoundsException if offset is - * negative, or count is negative, or - * offset+count is larger than - * data.length. - */ - public static String valueOf(char data[], int offset, int count) { - return new String(data, offset, count); - } - - /** - * Returns a String that represents the character sequence in the - * array specified. - * - * @param data the character array. - * @param offset initial offset of the subarray. - * @param count length of the subarray. - * @return a String that contains the characters of the - * specified subarray of the character array. - */ - public static String copyValueOf(char data[], int offset, int count) { - // All public String constructors now copy the data. - return new String(data, offset, count); - } - - /** - * Returns a String that represents the character sequence in the - * array specified. - * - * @param data the character array. - * @return a String that contains the characters of the - * character array. - */ - public static String copyValueOf(char data[]) { - return copyValueOf(data, 0, data.length); - } - - /** - * Returns the string representation of the boolean argument. - * - * @param b a boolean. - * @return if the argument is true, a string equal to - * "true" is returned; otherwise, a string equal to - * "false" is returned. - */ - public static String valueOf(boolean b) { - return b ? "true" : "false"; - } - - /** - * Returns the string representation of the char - * argument. - * - * @param c a char. - * @return a string of length 1 containing - * as its single character the argument c. - */ - public static String valueOf(char c) { - char data[] = {c}; - return new String(data, 0, 1); - } - - /** - * Returns the string representation of the int argument. - *

- * The representation is exactly the one returned by the - * Integer.toString method of one argument. - * - * @param i an int. - * @return a string representation of the int argument. - * @see java.lang.Integer#toString(int, int) - */ - public static String valueOf(int i) { - return Integer.toString(i); - } - - /** - * Returns the string representation of the long argument. - *

- * The representation is exactly the one returned by the - * Long.toString method of one argument. - * - * @param l a long. - * @return a string representation of the long argument. - * @see java.lang.Long#toString(long) - */ - public static String valueOf(long l) { - return Long.toString(l); - } - - /** - * Returns the string representation of the float argument. - *

- * The representation is exactly the one returned by the - * Float.toString method of one argument. - * - * @param f a float. - * @return a string representation of the float argument. - * @see java.lang.Float#toString(float) - */ - public static String valueOf(float f) { - return Float.toString(f); - } - - /** - * Returns the string representation of the double argument. - *

- * The representation is exactly the one returned by the - * Double.toString method of one argument. - * - * @param d a double. - * @return a string representation of the double argument. - * @see java.lang.Double#toString(double) - */ - public static String valueOf(double d) { - return Double.toString(d); - } - - /** - * Returns a canonical representation for the string object. - *

- * A pool of strings, initially empty, is maintained privately by the - * class String. - *

- * When the intern method is invoked, if the pool already contains a - * string equal to this String object as determined by - * the {@link #equals(Object)} method, then the string from the pool is - * returned. Otherwise, this String object is added to the - * pool and a reference to this String object is returned. - *

- * It follows that for any two strings s and t, - * s.intern() == t.intern() is true - * if and only if s.equals(t) is true. - *

- * All literal strings and string-valued constant expressions are - * interned. String literals are defined in section 3.10.5 of the - * The Java™ Language Specification. - * - * @return a string that has the same contents as this string, but is - * guaranteed to be from a pool of unique strings. - */ - public native String intern(); - - - private static T checkUTF8(T data, String charsetName) - throws UnsupportedEncodingException { - if (charsetName == null) { - throw new NullPointerException("charsetName"); - } - if (!charsetName.equalsIgnoreCase("UTF-8") - && !charsetName.equalsIgnoreCase("UTF8")) { - throw new UnsupportedEncodingException(charsetName); - } - return data; - } - - private static int nextChar(byte[] arr, int[] index) throws IndexOutOfBoundsException { - int c = arr[index[0]++] & 0xff; - switch (c >> 4) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - /* 0xxxxxxx*/ - return c; - case 12: - case 13: { - /* 110x xxxx 10xx xxxx*/ - int char2 = (int) arr[index[0]++]; - if ((char2 & 0xC0) != 0x80) { - throw new IndexOutOfBoundsException("malformed input"); - } - return (((c & 0x1F) << 6) | (char2 & 0x3F)); - } - case 14: { - /* 1110 xxxx 10xx xxxx 10xx xxxx */ - int char2 = arr[index[0]++]; - int char3 = arr[index[0]++]; - if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) { - throw new IndexOutOfBoundsException("malformed input"); - } - return (((c & 0x0F) << 12) - | ((char2 & 0x3F) << 6) - | ((char3 & 0x3F) << 0)); - } - default: - /* 10xx xxxx, 1111 xxxx */ - throw new IndexOutOfBoundsException("malformed input"); - } - - } -}