Return-Path: Delivered-To: apmail-incubator-harmony-commits-archive@www.apache.org Received: (qmail 76954 invoked from network); 26 Apr 2006 17:10:20 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 26 Apr 2006 17:10:20 -0000 Received: (qmail 29647 invoked by uid 500); 26 Apr 2006 17:10:19 -0000 Delivered-To: apmail-incubator-harmony-commits-archive@incubator.apache.org Received: (qmail 29613 invoked by uid 500); 26 Apr 2006 17:10:19 -0000 Mailing-List: contact harmony-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: harmony-dev@incubator.apache.org Delivered-To: mailing list harmony-commits@incubator.apache.org Received: (qmail 29602 invoked by uid 99); 26 Apr 2006 17:10:18 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 Apr 2006 10:10:18 -0700 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Wed, 26 Apr 2006 10:10:17 -0700 Received: (qmail 76804 invoked by uid 65534); 26 Apr 2006 17:09:56 -0000 Message-ID: <20060426170956.76803.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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 Date: Wed, 26 Apr 2006 17:09:55 -0000 To: harmony-commits@incubator.apache.org From: tellison@apache.org X-Mailer: svnmailer-1.0.8 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N 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. + *

+ * 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, 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