You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/04/26 19:09:55 UTC

svn commit: r397239 - in /incubator/harmony/enhanced/classlib/trunk/modules/luni/src: main/java/java/lang/String.java test/java/org/apache/harmony/tests/java/lang/AllTests.java test/java/org/apache/harmony/tests/java/lang/StringTest.java

Author: tellison
Date: Wed Apr 26 10:09:55 2006
New Revision: 397239

URL: http://svn.apache.org/viewcvs?rev=397239&view=rev
Log:
Apply patch HARMONY-292 ([classlib][luni-kernel] Update String for Java 5 and StringTest)

Added:
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/java/lang/StringTest.java   (with props)
Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/java/lang/AllTests.java

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java?rev=397239&r1=397238&r2=397239&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/String.java Wed Apr 26 10:09:55 2006
@@ -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.
+ * <p>
+ * An immutable sequence of characters/code units (<code>char</code>s). A
+ * <code>String</code> 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 (<code>char</code>)
+ * </p>
  * 
  * @see StringBuffer
+ * @see StringBuilder
+ * @see Charset
+ * @since 1.0
  */
 public final class String implements Serializable, Comparable<String>, CharSequence {
+    
 	private static final long serialVersionUID = -6849794470754667710L;
 
 	/**
@@ -472,10 +478,62 @@
 			count = stringbuffer.length();
 		}
 	}
+    
+    /**
+     * <p>
+     * Constructs a <code>String</code> from the sub-array of Unicode code
+     * points.
+     * </p>
+     * 
+     * @param codePoints The array of Unicode code points to convert.
+     * @param offset The inclusive index into <code>codePoints</code> to begin
+     *        converting from.
+     * @param count The number of element in <code>codePoints</code> to copy.
+     * @throws NullPointerException if <code>codePoints</code> is null.
+     * @throws IllegalArgumentException if any of the elements of
+     *         <code>codePoints</code> are not valid Unicode code points.
+     * @throws IndexOutOfBoundsException if <code>offset</code> or
+     *         <code>count</code> are not within the bounds of
+     *         <code>codePoints</code>.
+     * @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;
+    }
+    
+    /**
+     * <p>
+     * Constructs a <code>String</code> from a <code>StringBuilder</code>.
+     * </p>
+     * 
+     * @param sb The StringBuilder to copy from.
+     * @throws NullPointerException if <code>sb</code> is <code>null</code>.
+     * @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);
 		}
 	}
+    
+    /**
+     * <p>
+     * Compares a <code>CharSequence</code> to this <code>String</code> to
+     * determine if their contents are equal.
+     * </p>
+     * 
+     * @param cs The character sequence to compare to.
+     * @return <code>true</code> if equal, otherwise <code>false</code>
+     * @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);
 	}
+    
+    /**
+     * <p>
+     * Retrieves the Unicode code point value at the <code>index</code>.
+     * </p>
+     * 
+     * @param index The index to the <code>char</code> code unit within this
+     *        object.
+     * @return The Unicode code point value.
+     * @throws IndexOutOfBoundsException if <code>index</code> 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);
+    }
+    
+    /**
+     * <p>
+     * Retrieves the Unicode code point value that precedes the
+     * <code>index</code>.
+     * </p>
+     * 
+     * @param index The index to the <code>char</code> code unit within this
+     *        object.
+     * @return The Unicode code point value.
+     * @throws IndexOutOfBoundsException if <code>index</code> 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);
+    }
+    
+    /**
+     * <p>
+     * Calculates the number of Unicode code points between
+     * <code>beginIndex</code> and <code>endIndex</code>.
+     * </p>
+     * 
+     * @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 <code>beginIndex</code> is
+     *         negative or greater than <code>endIndex</code> or
+     *         <code>endIndex</code> 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);
+    }
+    
+    /**
+     * <p>
+     * Determines if this <code>String</code> contains the sequence of
+     * characters in the <code>CharSequence</code> passed.
+     * </p>
+     * 
+     * @param cs The character sequence to search for.
+     * @return <code>true</code> if the sequence of characters are contained
+     *         in this object; otherwise <code>false</code>
+     * @since 1.5
+     */
+    public boolean contains(CharSequence cs) {
+        if (cs == null)
+            throw new NullPointerException();
+        return indexOf(cs.toString()) >= 0;
+    }
+    
+    /**
+     * <p>
+     * Returns the index within this object that is offset from
+     * <code>index</code> by <code>codePointOffset</code> code points.
+     * </p>
+     * 
+     * @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 <code>index</code> is negative or
+     *         greater than {@link #length()} or if there aren't enough code
+     *         points before or after <code>index</code> to match
+     *         <code>codePointOffset</code>.
+     * @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,

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/java/lang/AllTests.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/java/lang/AllTests.java?rev=397239&r1=397238&r2=397239&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/java/lang/AllTests.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/java/lang/AllTests.java Wed Apr 26 10:09:55 2006
@@ -40,6 +40,7 @@
 		suite.addTestSuite(ShortTest.class);
 		suite.addTestSuite(LongTest.class);
 		suite.addTestSuite(TypeNotPresentExceptionTest.class);
+		suite.addTestSuite(StringTest.class);
 		//$JUnit-END$
 		return suite;
 	}

Added: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/java/lang/StringTest.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/java/lang/StringTest.java?rev=397239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/java/lang/StringTest.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/java/lang/StringTest.java Wed Apr 26 10:09:55 2006
@@ -0,0 +1,459 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.harmony.tests.java.lang;
+
+import java.lang.reflect.Constructor;
+
+import junit.framework.TestCase;
+
+public class StringTest extends TestCase {
+
+    private static final Constructor UNSAFE_CONSTRUCTOR;
+    static {
+        Constructor uc;
+        try {
+            uc = String.class.getDeclaredConstructor(new Class[] { int.class,
+                    int.class, char[].class });
+            uc.setAccessible(true);
+        } catch (Exception e) {
+            uc = null;
+        }
+        UNSAFE_CONSTRUCTOR = uc;
+    }
+
+    private static String newString(int start, int len, char[] data) {
+        if (UNSAFE_CONSTRUCTOR == null) {
+            return new String(data, start, len);
+        }
+
+        try {
+            return (String) UNSAFE_CONSTRUCTOR.newInstance(new Object[] {
+                    Integer.valueOf(start), Integer.valueOf(len), data });
+        } catch (Exception e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    /**
+     * @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#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")));
+
+        s = newString(1, 3, "_abc_".toCharArray());
+        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")));
+
+        s = newString(1, 26, "_abcdefghijklmnopqrstuvwxyz_".toCharArray());
+        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.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);
+
+        result = newString(2, 4, "__a\uD800\uDC00b__".toCharArray())
+                .offsetByCodePoints(0, 2);
+        assertEquals(3, result);
+
+        result = newString(2, 4, "__abcd__".toCharArray()).offsetByCodePoints(
+                3, -1);
+        assertEquals(2, result);
+
+        result = newString(2, 4, "__a\uD800\uDC00b__".toCharArray())
+                .offsetByCodePoints(0, 3);
+        assertEquals(4, result);
+
+        result = newString(2, 4, "__a\uD800\uDC00b__".toCharArray())
+                .offsetByCodePoints(3, -1);
+        assertEquals(1, result);
+
+        result = newString(2, 4, "__a\uD800\uDC00b__".toCharArray())
+                .offsetByCodePoints(3, 0);
+        assertEquals(3, result);
+
+        result = newString(2, 4, "__\uD800\uDC00bc__".toCharArray())
+                .offsetByCodePoints(3, 0);
+        assertEquals(3, result);
+
+        result = newString(2, 4, "__a\uDC00bc__".toCharArray())
+                .offsetByCodePoints(3, -1);
+        assertEquals(2, result);
+
+        result = newString(2, 4, "__a\uD800bc__".toCharArray())
+                .offsetByCodePoints(3, -1);
+        assertEquals(2, result);
+
+        String s = "abc";
+        try {
+            s.offsetByCodePoints(-1, 1);
+            fail("No IOOBE for negative index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.offsetByCodePoints(0, 4);
+            fail("No IOOBE for offset that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.offsetByCodePoints(3, -4);
+            fail("No IOOBE for offset that's too small.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.offsetByCodePoints(3, 1);
+            fail("No IOOBE for index that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.offsetByCodePoints(4, -1);
+            fail("No IOOBE for index that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+        
+        s = newString(2,3,"__abc__".toCharArray());
+        try {
+            s.offsetByCodePoints(-1, 1);
+            fail("No IOOBE for negative index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.offsetByCodePoints(0, 4);
+            fail("No IOOBE for offset that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.offsetByCodePoints(3, -4);
+            fail("No IOOBE for offset that's too small.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.offsetByCodePoints(3, 1);
+            fail("No IOOBE for index that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.offsetByCodePoints(4, -1);
+            fail("No IOOBE for index that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    /**
+     * @tests java.lang.StringBuilder.codePointAt(int)
+     */
+    public void test_codePointAtI() {
+        String s = "abc";
+        assertEquals('a', s.codePointAt(0));
+        assertEquals('b', s.codePointAt(1));
+        assertEquals('c', s.codePointAt(2));
+        
+        s = newString(2,3,"__abc__".toCharArray());
+        assertEquals('a', s.codePointAt(0));
+        assertEquals('b', s.codePointAt(1));
+        assertEquals('c', s.codePointAt(2));
+
+        s = "\uD800\uDC00";
+        assertEquals(0x10000, s.codePointAt(0));
+        assertEquals('\uDC00', s.codePointAt(1));
+        
+        s = newString(2,2,"__\uD800\uDC00__".toCharArray());
+        assertEquals(0x10000, s.codePointAt(0));
+        assertEquals('\uDC00', s.codePointAt(1));
+
+        s = "abc";
+        try {
+            s.codePointAt(-1);
+            fail("No IOOBE on negative index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.codePointAt(s.length());
+            fail("No IOOBE on index equal to length.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.codePointAt(s.length() + 1);
+            fail("No IOOBE on index greater than length.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+        
+        s = newString(2,3,"__abc__".toCharArray());
+        try {
+            s.codePointAt(-1);
+            fail("No IOOBE on negative index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.codePointAt(s.length());
+            fail("No IOOBE on index equal to length.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.codePointAt(s.length() + 1);
+            fail("No IOOBE on index greater than length.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    /**
+     * @tests java.lang.StringBuilder.codePointBefore(int)
+     */
+    public void test_codePointBeforeI() {
+        String s = "abc";
+        assertEquals('a', s.codePointBefore(1));
+        assertEquals('b', s.codePointBefore(2));
+        assertEquals('c', s.codePointBefore(3));
+        
+        s = newString(2,3,"__abc__".toCharArray());
+        assertEquals('a', s.codePointBefore(1));
+        assertEquals('b', s.codePointBefore(2));
+        assertEquals('c', s.codePointBefore(3));
+
+        s = "\uD800\uDC00";
+        assertEquals(0x10000, s.codePointBefore(2));
+        assertEquals('\uD800', s.codePointBefore(1));
+        
+        s = newString(2,2,"__\uD800\uDC00__".toCharArray());
+        assertEquals(0x10000, s.codePointBefore(2));
+        assertEquals('\uD800', s.codePointBefore(1));
+
+        s = "abc";
+        try {
+            s.codePointBefore(0);
+            fail("No IOOBE on zero index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.codePointBefore(-1);
+            fail("No IOOBE on negative index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.codePointBefore(s.length() + 1);
+            fail("No IOOBE on index greater than length.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+        
+        s = newString(2,3,"__abc__".toCharArray());
+        try {
+            s.codePointBefore(0);
+            fail("No IOOBE on zero index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.codePointBefore(-1);
+            fail("No IOOBE on negative index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.codePointBefore(s.length() + 1);
+            fail("No IOOBE on index greater than length.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    /**
+     * @tests java.lang.StringBuilder.codePointCount(int, int)
+     */
+    public void test_codePointCountII() {
+        assertEquals(1, "\uD800\uDC00".codePointCount(0, 2));
+        assertEquals(1, "\uD800\uDC01".codePointCount(0, 2));
+        assertEquals(1, "\uD801\uDC01".codePointCount(0, 2));
+        assertEquals(1, "\uDBFF\uDFFF".codePointCount(0, 2));
+
+        assertEquals(3, "a\uD800\uDC00b".codePointCount(0, 4));
+        assertEquals(4, "a\uD800\uDC00b\uD800".codePointCount(0, 5));
+        
+        assertEquals(1, newString(2,2,"__\uD800\uDC00__".toCharArray()).codePointCount(0, 2));
+        assertEquals(1, newString(2,2,"__\uD800\uDC01__".toCharArray()).codePointCount(0, 2));
+        assertEquals(1, newString(2,2,"__\uD801\uDC01__".toCharArray()).codePointCount(0, 2));
+        assertEquals(1, newString(2,2,"__\uDBFF\uDFFF__".toCharArray()).codePointCount(0, 2));
+
+        assertEquals(3, newString(2,4,"__a\uD800\uDC00b__".toCharArray()).codePointCount(0, 4));
+        assertEquals(4, newString(2,5,"__a\uD800\uDC00b\uD800__".toCharArray()).codePointCount(0, 5));
+
+        String s = "abc";
+        try {
+            s.codePointCount(-1, 2);
+            fail("No IOOBE for negative begin index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.codePointCount(0, 4);
+            fail("No IOOBE for end index that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.codePointCount(3, 2);
+            fail("No IOOBE for begin index larger than end index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+        
+        s = newString(2, 3, "__abc__".toCharArray());
+        try {
+            s.codePointCount(-1, 2);
+            fail("No IOOBE for negative begin index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.codePointCount(0, 4);
+            fail("No IOOBE for end index that's too large.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            s.codePointCount(3, 2);
+            fail("No IOOBE for begin index larger than end index.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/org/apache/harmony/tests/java/lang/StringTest.java
------------------------------------------------------------------------------
    svn:eol-style = native