Index: /luni/src/main/java/java/lang/String.java =================================================================== --- /luni/src/main/java/java/lang/String.java (revision 396753) +++ /luni/src/main/java/java/lang/String.java (working copy) @@ -33,14 +33,20 @@ import org.apache.harmony.luni.util.PriviAction; /** - * The implementation of this class is provided, but the documented native must - * be provided by the vm vendor. - * - * Strings are objects which represent immutable arrays of characters. + *

+ * An immutable sequence of characters/code units (chars). A + * String is represented by array of UTF-16 values, such that + * Unicode supplementary characters (code points) are stored/encoded as + * surrogate pairs via Unicode code units (char) + *

* * @see StringBuffer + * @see StringBuilder + * @see Charset + * @since 1.0 */ public final class String implements Serializable, Comparable, CharSequence { + private static final long serialVersionUID = -6849794470754667710L; /** @@ -472,10 +478,62 @@ count = stringbuffer.length(); } } + + /** + *

+ * Constructs a String from the sub-array of Unicode code + * points. + *

+ * + * @param codePoints The array of Unicode code points to convert. + * @param offset The inclusive index into codePoints to begin + * converting from. + * @param count The number of element in codePoints to copy. + * @throws NullPointerException if codePoints is null. + * @throws IllegalArgumentException if any of the elements of + * codePoints are not valid Unicode code points. + * @throws IndexOutOfBoundsException if offset or + * count are not within the bounds of + * codePoints. + * @since 1.5 + */ + public String(int[] codePoints, int offset, int count) { + super(); + if (codePoints == null) + throw new NullPointerException(); + if (offset < 0 || count < 0 || (offset + count) > codePoints.length) + throw new IndexOutOfBoundsException(); + this.offset = 0; + this.value = new char[count * 2]; + int end = offset + count; + int c = 0; + for (int i = offset; i < end; i++) { + c += Character.toChars(codePoints[i], this.value, c); + } + this.count = c; + } + + /** + *

+ * Constructs a String from a StringBuilder. + *

+ * + * @param sb The StringBuilder to copy from. + * @throws NullPointerException if sb is null. + * @since 1.5 + */ + public String(StringBuilder sb) { + if (sb == null) + throw new NullPointerException(); + this.offset = 0; + this.count = sb.length(); + this.value = new char[this.count]; + sb.getChars(0, this.count, this.value, 0); + } /* - * Creates a string that is s1 + v1. - */ + * Creates a string that is s1 + v1. + */ private String(String s1, int v1) { if (s1 == null) s1 = "null"; @@ -716,7 +774,7 @@ /** * Converts this String to a byte encoding using the default encoding as - * specified by the file.encoding sytem property. If the system property is + * specified by the file.encoding system property. If the system property is * not defined, the default encoding is ISO8859_1 (ISO-Latin-1). If 8859-1 * is not available, an ASCII encoding is used. * @@ -1657,6 +1715,26 @@ size); } } + + /** + *

+ * Compares a CharSequence to this String to + * determine if their contents are equal. + *

+ * + * @param cs The character sequence to compare to. + * @return true if equal, otherwise false + * @since 1.5 + */ + public boolean contentEquals(CharSequence cs) { + if (cs == null) + throw new NullPointerException(); + if (cs instanceof StringBuffer) + return contentEquals((StringBuffer)cs); + else { + return regionMatches(0, cs.toString(), 0, cs.length()); + } + } /** * Determines whether a this String matches a given regular expression. @@ -1773,6 +1851,110 @@ public CharSequence subSequence(int start, int end) { return substring(start, end); } + + /** + *

+ * Retrieves the Unicode code point value at the index. + *

+ * + * @param index The index to the char code unit within this + * object. + * @return The Unicode code point value. + * @throws IndexOutOfBoundsException if index is negative or + * greater than or equal to {@link #length()}. + * @see Character + * @see Character#codePointAt(char[], int, int) + * @since 1.5 + */ + public int codePointAt(int index) { + if (index < 0 || index >= count) + throw new IndexOutOfBoundsException(); + int s = index + offset; + return Character.codePointAt(value, s, offset + count); + } + + /** + *

+ * Retrieves the Unicode code point value that precedes the + * index. + *

+ * + * @param index The index to the char code unit within this + * object. + * @return The Unicode code point value. + * @throws IndexOutOfBoundsException if index is less than 1 + * or greater than {@link #length()}. + * @see Character + * @see Character#codePointBefore(char[], int, int) + * @since 1.5 + */ + public int codePointBefore(int index) { + if (index < 1 || index > count) + throw new IndexOutOfBoundsException(); + int s = index + offset; + return Character.codePointBefore(value, s); + } + + /** + *

+ * Calculates the number of Unicode code points between + * beginIndex and endIndex. + *

+ * + * @param beginIndex The inclusive beginning index of the subsequence. + * @param endIndex The exclusive end index of the subsequence. + * @return The number of Unicode code points in the subsequence. + * @throws IndexOutOfBoundsException if beginIndex is + * negative or greater than endIndex or + * endIndex is greater than {@link #length()}. + * @since 1.5 + */ + public int codePointCount(int beginIndex, int endIndex) { + if (beginIndex < 0 || endIndex > count + || beginIndex > endIndex) + throw new IndexOutOfBoundsException(); + int s = beginIndex + offset; + return Character.codePointCount(value, s, endIndex - beginIndex); + } + + /** + *

+ * Determines if this String contains the sequence of + * characters in the CharSequence passed. + *

+ * + * @param cs The character sequence to search for. + * @return true if the sequence of characters are contained + * in this object; otherwise false + * @since 1.5 + */ + public boolean contains(CharSequence cs) { + if (cs == null) + throw new NullPointerException(); + return indexOf(cs.toString()) >= 0; + } + + /** + *

+ * Returns the index within this object that is offset from + * index by codePointOffset code points. + *

+ * + * @param index The index within this object to calculate the offset from. + * @param codePointOffset The number of code points to count. + * @return The index within this object that is the offset. + * @throws IndexOutOfBoundsException if index is negative or + * greater than {@link #length()} or if there aren't enough code + * points before or after index to match + * codePointOffset. + * @since 1.5 + */ + public int offsetByCodePoints(int index, int codePointOffset) { + int s = index + offset; + int r = Character.offsetByCodePoints(value, offset, count, s, + codePointOffset); + return r - offset; + } /* * An implementation of a String.indexOf that is supposed to perform @@ -1782,7 +1964,7 @@ * In the jit, if we encounter a call to String.indexOf(String), where the * needle is a constant string, we compute the values cache, md2 and * lastChar, and change the call to the following method. This code can be - * enabled by setting TR_FastIndexOf=1. It searches for the availablility of + * enabled by setting TR_FastIndexOf=1. It searches for the availability of * the following signature before doing the optimization. */ private static int indexOf(String haystackString, String needleString,