Index: /luni/src/test/java/tests/api/java/lang/StringTest.java =================================================================== --- /luni/src/test/java/tests/api/java/lang/StringTest.java (revision 395760) +++ /luni/src/test/java/tests/api/java/lang/StringTest.java (working copy) @@ -149,7 +149,67 @@ } assertTrue("Did not throw exception", exception); } + + + /** + * @tests java.lang.String#String(java.lang.StringBuilder) + */ + public void test_ConstructorLjava_lang_StringBuilder() { + StringBuilder sb = new StringBuilder(32); + sb.append("HelloWorld"); + assertEquals("HelloWorld", new String(sb)); + + try { + new String((StringBuilder)null); + fail("No NPE"); + } catch (NullPointerException e) { + } + } + + /** + * @tests java.lang.String#String(int[],int,int) + */ + public void test_Constructor$III() { + assertEquals("HelloWorld", new String(new int[] {'H','e','l','l','o','W','o','r','l','d'}, 0, 10)); + assertEquals("Hello", new String(new int[] {'H','e','l','l','o','W','o','r','l','d'}, 0, 5)); + assertEquals("World", new String(new int[] {'H','e','l','l','o','W','o','r','l','d'}, 5, 5)); + assertEquals("", new String(new int[] {'H','e','l','l','o','W','o','r','l','d'}, 5, 0)); + + assertEquals("\uD800\uDC00", new String(new int[] {0x010000}, 0, 1)); + assertEquals("\uD800\uDC00a\uDBFF\uDFFF", new String(new int[] {0x010000, 'a', 0x010FFFF}, 0, 3)); + + try { + new String((int[])null, 0, 1); + fail("No NPE"); + } catch (NullPointerException e) { + } + + try { + new String(new int[] {'a','b'}, -1, 2); + fail("No IOOBE, negative offset"); + } catch (IndexOutOfBoundsException e) { + } + + try { + new String(new int[] {'a','b'}, 0, -1); + fail("No IOOBE, negative count"); + } catch (IndexOutOfBoundsException e) { + } + + try { + new String(new int[] {'a','b'}, 0, -1); + fail("No IOOBE, negative count"); + } catch (IndexOutOfBoundsException e) { + } + + try { + new String(new int[] {'a','b'}, 0, 3); + fail("No IOOBE, too large"); + } catch (IndexOutOfBoundsException e) { + } + } + /** * @tests java.lang.String#String(java.lang.String) */ @@ -273,6 +333,54 @@ String s3 = s1.concat(s2); assertTrue("should not be identical", s2 != s3); } + + /** + * @tests java.lang.String#contentEquals(StringBuffer) + */ + public void test_contentEqualsLjava_lang_StringBuffer() { + String s = "abc"; + assertTrue(s.contentEquals(new StringBuffer("abc"))); + assertFalse(s.contentEquals(new StringBuffer("def"))); + assertFalse(s.contentEquals(new StringBuffer("ghij"))); + + try { + s.contentEquals((StringBuffer)null); + fail("No NPE"); + } catch (NullPointerException e) { + } + } + + /** + * @tests java.lang.String#contentEquals(CharSequence) + */ + public void test_contentEqualsLjava_lang_CharSequence() { + String s = "abc"; + assertTrue(s.contentEquals((CharSequence)new StringBuffer("abc"))); + assertFalse(s.contentEquals((CharSequence)new StringBuffer("def"))); + assertFalse(s.contentEquals((CharSequence)new StringBuffer("ghij"))); + + try { + s.contentEquals((CharSequence)null); + fail("No NPE"); + } catch (NullPointerException e) { + } + } + + /** + * @tests java.lang.String#contains(CharSequence) + */ + public void test_containsLjava_lang_CharSequence() { + String s = "abcdefghijklmnopqrstuvwxyz"; + assertTrue(s.contains((CharSequence)new StringBuffer("abc"))); + assertTrue(s.contains((CharSequence)new StringBuffer("def"))); + assertFalse(s.contains((CharSequence)new StringBuffer("ac"))); + + try { + s.contentEquals((CharSequence)null); + fail("No NPE"); + } catch (NullPointerException e) { + } + } /** * @tests java.lang.String#copyValueOf(char[]) @@ -606,6 +714,71 @@ } /** + * @tests java.lang.String.offsetByCodePoints(int, int)' + */ + public void test_offsetByCodePointsII() { + int result = new String("a\uD800\uDC00b").offsetByCodePoints(0, 2); + assertEquals(3, result); + + result = new String("abcd").offsetByCodePoints(3, -1); + assertEquals(2, result); + + result = new String("a\uD800\uDC00b").offsetByCodePoints(0, 3); + assertEquals(4, result); + + result = new String("a\uD800\uDC00b").offsetByCodePoints(3, -1); + assertEquals(1, result); + + result = new String("a\uD800\uDC00b").offsetByCodePoints(3, 0); + assertEquals(3, result); + + result = new String("\uD800\uDC00bc").offsetByCodePoints(3, 0); + assertEquals(3, result); + + result = new String("a\uDC00bc").offsetByCodePoints(3, -1); + assertEquals(2, result); + + result = new String("a\uD800bc").offsetByCodePoints(3, -1); + assertEquals(2, result); + + String sb = "abc"; + try { + sb.offsetByCodePoints(-1, 1); + fail("No IOOBE for negative index."); + } catch (IndexOutOfBoundsException e) { + + } + + try { + sb.offsetByCodePoints(0, 4); + fail("No IOOBE for offset that's too large."); + } catch (IndexOutOfBoundsException e) { + + } + + try { + sb.offsetByCodePoints(3, -4); + fail("No IOOBE for offset that's too small."); + } catch (IndexOutOfBoundsException e) { + + } + + try { + sb.offsetByCodePoints(3, 1); + fail("No IOOBE for index that's too large."); + } catch (IndexOutOfBoundsException e) { + + } + + try { + sb.offsetByCodePoints(4, -1); + fail("No IOOBE for index that's too large."); + } catch (IndexOutOfBoundsException e) { + + } + } + + /** * @tests java.lang.String#regionMatches(int, java.lang.String, int, int) */ public void test_regionMatchesILjava_lang_StringII() { Index: /luni/src/main/java/java/lang/String.java =================================================================== --- /luni/src/main/java/java/lang/String.java (revision 395760) +++ /luni/src/main/java/java/lang/String.java (working copy) @@ -33,13 +33,13 @@ 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. - * - * @see StringBuffer - */ + *
An immutable sequence of characters (chars).
+ * Constructs a String from the sub-array of Unicode code
+ * points.
+ *
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.
+ *
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 +768,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 +1709,26 @@
size);
}
}
+
+ /**
+ *
+ * Compares a CharSequence to this String to
+ * determine if their contents are equal.
+ *
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 +1845,105 @@
public CharSequence subSequence(int start, int end) {
return substring(start, end);
}
+
+ /**
+ *
+ * Retrieves the Unicode code point value at the index.
+ *
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 >= (offset + count))
+ throw new IndexOutOfBoundsException();
+ return Character.codePointAt(value, index + offset, count);
+ }
+
+ /**
+ *
+ * Retrieves the Unicode code point value that precedes the
+ * index.
+ *
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 > (offset + count))
+ throw new IndexOutOfBoundsException();
+ return Character.codePointBefore(value, index + offset);
+ }
+
+ /**
+ *
+ * Calculates the number of Unicode code points between
+ * beginIndex and endIndex.
+ *
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 < offset || endIndex > (offset + count) || beginIndex > endIndex)
+ throw new IndexOutOfBoundsException();
+ return Character.codePointCount(value, beginIndex, endIndex
+ - beginIndex);
+ }
+
+ /**
+ *
+ * Determines if this String contains the sequence of
+ * characters in the CharSequence passed.
+ *
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.
+ *
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) {
+ return Character.offsetByCodePoints(value, offset, count, index,
+ codePointOffset);
+ }
/*
* An implementation of a String.indexOf that is supposed to perform