undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
59
test/jdk/java/lang/String/CaseConvertSameInstance.java
Normal file
59
test/jdk/java/lang/String/CaseConvertSameInstance.java
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
@bug 4130097
|
||||
@summary toUpperCase and toLowerCase always return a new String,
|
||||
whereas if there is no conversion that needs to be done,
|
||||
they should be returning the same instance.
|
||||
@author James Bond/007
|
||||
*/
|
||||
public class CaseConvertSameInstance {
|
||||
public static void main(String[] args) throws Exception {
|
||||
/* these two are the real tests for this bug. */
|
||||
if ("foobar".toLowerCase() != "foobar")
|
||||
throw new Exception("toLowerCase returned different object");
|
||||
if ("FOOBAR".toUpperCase() != "FOOBAR")
|
||||
throw new Exception("toUpperCase returned different object");
|
||||
|
||||
/* sanity test toLowerCase with some border conditions. */
|
||||
if (!("FooBar".toLowerCase().equals("foobar")))
|
||||
throw new Exception("toLowerCase broken");
|
||||
if (!("fooBar".toLowerCase().equals("foobar")))
|
||||
throw new Exception("toLowerCase broken");
|
||||
if (!("foobaR".toLowerCase().equals("foobar")))
|
||||
throw new Exception("toLowerCase broken");
|
||||
if (!("FOOBAR".toLowerCase().equals("foobar")))
|
||||
throw new Exception("toLowerCase broken");
|
||||
|
||||
/* sanity test toUpperCase with some border conditions. */
|
||||
if (!("FooBar".toUpperCase().equals("FOOBAR")))
|
||||
throw new Exception("toUpperCase broken");
|
||||
if (!("fooBar".toUpperCase().equals("FOOBAR")))
|
||||
throw new Exception("toUpperCase broken");
|
||||
if (!("foobaR".toUpperCase().equals("FOOBAR")))
|
||||
throw new Exception("toUpperCase broken");
|
||||
if (!("foobar".toUpperCase().equals("FOOBAR")))
|
||||
throw new Exception("toUpperCase broken");
|
||||
}
|
||||
}
|
||||
68
test/jdk/java/lang/String/CaseInsensitiveComparator.java
Normal file
68
test/jdk/java/lang/String/CaseInsensitiveComparator.java
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This test tests that the String.CaseInsensitiveComparator.readResolve method
|
||||
* deserializes String.CASE_INSENSITIVE_ORDER into an object which satisfies the
|
||||
* equals method.
|
||||
*
|
||||
* @test
|
||||
* @bug 5035850
|
||||
* @summary Test for String.CaseInsensitiveComparator.readResolve
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
public class CaseInsensitiveComparator {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Object result;
|
||||
|
||||
try (ByteArrayOutputStream outBuffer = new ByteArrayOutputStream();
|
||||
ObjectOutputStream out = new ObjectOutputStream(outBuffer))
|
||||
{
|
||||
out.writeObject(String.CASE_INSENSITIVE_ORDER);
|
||||
out.close();
|
||||
|
||||
try (ByteArrayInputStream inBuffer = new ByteArrayInputStream(outBuffer.toByteArray());
|
||||
ObjectInputStream in = new ObjectInputStream(inBuffer))
|
||||
{
|
||||
result = in.readObject();
|
||||
}
|
||||
}
|
||||
|
||||
if (!String.CASE_INSENSITIVE_ORDER.equals(result)) {
|
||||
throw new Exception("Value restored from serial form does not equal original!");
|
||||
}
|
||||
|
||||
if (!result.equals(String.CASE_INSENSITIVE_ORDER)) {
|
||||
throw new Exception("Value restored from serial form does not equal original!");
|
||||
}
|
||||
|
||||
if (String.CASE_INSENSITIVE_ORDER != result) {
|
||||
throw new Exception("Value restored from serial form does not equal original!");
|
||||
}
|
||||
}
|
||||
}
|
||||
138
test/jdk/java/lang/String/Chars.java
Normal file
138
test/jdk/java/lang/String/Chars.java
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2023, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8054307 8311906 8321514
|
||||
* @summary test String chars() and codePoints()
|
||||
* @run main/othervm -XX:+CompactStrings Chars
|
||||
* @run main/othervm -XX:-CompactStrings Chars
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
public class Chars {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Random r = new Random();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int n = 100 + r.nextInt(100);
|
||||
char[] cc = new char[n];
|
||||
int[] ccExp = new int[n];
|
||||
int[] cpExp = new int[n];
|
||||
// latin1
|
||||
for (int j = 0; j < n; j++) {
|
||||
cc[j] = (char)(ccExp[j] = cpExp[j] = r.nextInt(0x80));
|
||||
}
|
||||
testChars(cc, ccExp);
|
||||
testCharsSubrange(cc, ccExp);
|
||||
testIntsSubrange(ccExp);
|
||||
testCPs(cc, cpExp);
|
||||
|
||||
// bmp without surrogates
|
||||
for (int j = 0; j < n; j++) {
|
||||
cc[j] = (char)(ccExp[j] = cpExp[j] = r.nextInt(0x8000));
|
||||
}
|
||||
testChars(cc, ccExp);
|
||||
testCharsSubrange(cc, ccExp);
|
||||
testCPs(cc, cpExp);
|
||||
|
||||
// bmp with surrogates
|
||||
int k = 0;
|
||||
for (int j = 0; j < n; j++) {
|
||||
if (j % 9 == 5 && j + 1 < n) {
|
||||
int cp = 0x10000 + r.nextInt(2000);
|
||||
cpExp[k++] = cp;
|
||||
Character.toChars(cp, cc, j);
|
||||
ccExp[j] = cc[j];
|
||||
ccExp[j + 1] = cc[j + 1];
|
||||
j++;
|
||||
} else {
|
||||
cc[j] = (char)(ccExp[j] = cpExp[k++] = r.nextInt(0x8000));
|
||||
}
|
||||
}
|
||||
cpExp = Arrays.copyOf(cpExp, k);
|
||||
testChars(cc, ccExp);
|
||||
testCharsSubrange(cc, ccExp);
|
||||
testIntsSubrange(ccExp);
|
||||
testCPs(cc, cpExp);
|
||||
}
|
||||
}
|
||||
|
||||
static void testChars(char[] cc, int[] expected) {
|
||||
String str = new String(cc);
|
||||
if (!Arrays.equals(expected, str.chars().toArray())) {
|
||||
throw new RuntimeException("testChars failed!");
|
||||
}
|
||||
}
|
||||
|
||||
static void testCharsSubrange(char[] cc, int[] expected) {
|
||||
int[] offsets = { 7, 31 }; // offsets to test
|
||||
int LENGTH = 13;
|
||||
for (int i = 0; i < offsets.length; i++) {
|
||||
int offset = Math.max(0, offsets[i]); // confine to the input array
|
||||
int count = Math.min(LENGTH, cc.length - offset);
|
||||
String str = new String(cc, offset, count);
|
||||
int[] actual = str.chars().toArray();
|
||||
int errOffset = Arrays.mismatch(actual, 0, actual.length,
|
||||
expected, offset, offset + count);
|
||||
if (errOffset >= 0) {
|
||||
System.err.printf("expected[%d] (%d) != actual[%d] (%d)%n",
|
||||
offset + errOffset, expected[offset + errOffset],
|
||||
errOffset, actual[errOffset]);
|
||||
System.err.println("expected: " + Arrays.toString(expected));
|
||||
System.err.println("actual: " + Arrays.toString(actual));
|
||||
throw new RuntimeException("testCharsSubrange failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void testIntsSubrange(int[] expected) {
|
||||
int[] offsets = { 7, 31 }; // offsets to test
|
||||
int LENGTH = 13;
|
||||
for (int i = 0; i < offsets.length; i++) {
|
||||
int offset = Math.max(0, offsets[i]); // confine to the input array
|
||||
int count = Math.min(LENGTH, expected.length - offset);
|
||||
String str = new String(expected, offset, count);
|
||||
int[] actual = str.chars().toArray();
|
||||
int errOffset = Arrays.mismatch(actual, 0, actual.length,
|
||||
expected, offset, offset + count);
|
||||
if (errOffset >= 0) {
|
||||
System.err.printf("expected[%d] (%d) != actual[%d] (%d)%n",
|
||||
offset + errOffset, expected[offset + errOffset],
|
||||
errOffset, actual[errOffset]);
|
||||
System.err.println("expected: " + Arrays.toString(expected));
|
||||
System.err.println("actual: " + Arrays.toString(actual));
|
||||
throw new RuntimeException("testIntsSubrange failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void testCPs(char[] cc, int[] expected) {
|
||||
String str = new String(cc);
|
||||
if (!Arrays.equals(expected, str.codePoints().toArray())) {
|
||||
throw new RuntimeException("testCPs failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
72
test/jdk/java/lang/String/CompactString/CharAt.java
Normal file
72
test/jdk/java/lang/String/CompactString/CharAt.java
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.charAt.
|
||||
* @run testng/othervm -XX:+CompactStrings CharAt
|
||||
* @run testng/othervm -XX:-CompactStrings CharAt
|
||||
*/
|
||||
|
||||
public class CharAt extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
new Object[] { STRING_L1, new char[] { 'A' } },
|
||||
new Object[] { STRING_L2, new char[] { 'A', 'B' } },
|
||||
new Object[] { STRING_L4, new char[] { 'A', 'B', 'C', 'D' } },
|
||||
new Object[] { STRING_LLONG,
|
||||
new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' } },
|
||||
new Object[] { STRING_U1, new char[] { '\uFF21' } },
|
||||
new Object[] { STRING_U2, new char[] { '\uFF21', '\uFF22' } },
|
||||
new Object[] { STRING_M12, new char[] { '\uFF21', 'A' } },
|
||||
new Object[] { STRING_M11, new char[] { 'A', '\uFF21' } }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testCharAt(String str, char[] expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
IntStream
|
||||
.range(0, str.length())
|
||||
.forEach(
|
||||
i -> assertEquals(
|
||||
str.charAt(i),
|
||||
expected[i],
|
||||
String.format(
|
||||
"testing String(%s).charAt(%d), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
i, source)));
|
||||
});
|
||||
}
|
||||
}
|
||||
79
test/jdk/java/lang/String/CompactString/CodePointAt.java
Normal file
79
test/jdk/java/lang/String/CompactString/CodePointAt.java
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.codePointAt.
|
||||
* @run testng/othervm -XX:+CompactStrings CodePointAt
|
||||
* @run testng/othervm -XX:-CompactStrings CodePointAt
|
||||
*/
|
||||
|
||||
public class CodePointAt extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_L1, new int[] { 'A' } },
|
||||
new Object[] { STRING_L2, new int[] { 'A', 'B' } },
|
||||
new Object[] { STRING_L4, new int[] { 'A', 'B', 'C', 'D' } },
|
||||
new Object[] { STRING_LLONG,
|
||||
new int[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' } },
|
||||
new Object[] { STRING_U1, new int[] { '\uFF21' } },
|
||||
new Object[] { STRING_U2, new int[] { '\uFF21', '\uFF22' } },
|
||||
new Object[] { STRING_M12, new int[] { '\uFF21', 'A' } },
|
||||
new Object[] { STRING_M11, new int[] { 'A', '\uFF21' } },
|
||||
new Object[] {
|
||||
STRING_SUPPLEMENTARY,
|
||||
new int[] { Character.toCodePoint('\uD801', '\uDC00'),
|
||||
'\uDC00',
|
||||
Character.toCodePoint('\uD801', '\uDC01'),
|
||||
'\uDC01', '\uFF21', 'A' }, } };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testCodePointAt(String str, int[] expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
IntStream
|
||||
.range(0, str.length())
|
||||
.forEach(
|
||||
i -> assertEquals(
|
||||
str.codePointAt(i),
|
||||
expected[i],
|
||||
String.format(
|
||||
"testing String(%s).codePointAt(%d), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
i, source)));
|
||||
});
|
||||
}
|
||||
}
|
||||
79
test/jdk/java/lang/String/CompactString/CodePointBefore.java
Normal file
79
test/jdk/java/lang/String/CompactString/CodePointBefore.java
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.codePointBefore.
|
||||
* @run testng/othervm -XX:+CompactStrings CodePointBefore
|
||||
* @run testng/othervm -XX:-CompactStrings CodePointBefore
|
||||
*/
|
||||
|
||||
public class CodePointBefore extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_L1, new int[] { 'A' } },
|
||||
new Object[] { STRING_L2, new int[] { 'A', 'B' } },
|
||||
new Object[] { STRING_L4, new int[] { 'A', 'B', 'C', 'D' } },
|
||||
new Object[] { STRING_LLONG,
|
||||
new int[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' } },
|
||||
new Object[] { STRING_U1, new int[] { '\uFF21' } },
|
||||
new Object[] { STRING_U2, new int[] { '\uFF21', '\uFF22' } },
|
||||
new Object[] { STRING_M12, new int[] { '\uFF21', 'A' } },
|
||||
new Object[] { STRING_M11, new int[] { 'A', '\uFF21' } },
|
||||
new Object[] {
|
||||
STRING_SUPPLEMENTARY,
|
||||
new int[] { '\uD801', Character.toCodePoint('\uD801', '\uDC00'),
|
||||
'\uD801', Character.toCodePoint('\uD801', '\uDC01'),
|
||||
'\uFF21', 'A' }, } };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testCodePointBefore(String str, int[] expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
IntStream
|
||||
.range(0, str.length())
|
||||
.forEach(
|
||||
i -> assertEquals(
|
||||
str.codePointBefore(i + 1),
|
||||
expected[i],
|
||||
String.format(
|
||||
"testing String(%s).codePointBefore(%d), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
i + 1, source)));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
89
test/jdk/java/lang/String/CompactString/CodePointCount.java
Normal file
89
test/jdk/java/lang/String/CompactString/CodePointCount.java
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.codePointCount.
|
||||
* @run testng/othervm -XX:+CompactStrings CodePointCount
|
||||
* @run testng/othervm -XX:-CompactStrings CodePointCount
|
||||
*/
|
||||
|
||||
public class CodePointCount extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] { new Object[] { STRING_EMPTY, 0, 0, 0 },
|
||||
new Object[] { STRING_L1, 0, 1, 1 },
|
||||
new Object[] { STRING_L1, 1, 1, 0 },
|
||||
new Object[] { STRING_L2, 0, 2, 2 },
|
||||
new Object[] { STRING_L2, 0, 1, 1 },
|
||||
new Object[] { STRING_L2, 1, 2, 1 },
|
||||
new Object[] { STRING_L4, 0, 4, 4 },
|
||||
new Object[] { STRING_L4, 0, 1, 1 },
|
||||
new Object[] { STRING_L4, 2, 4, 2 },
|
||||
new Object[] { STRING_LLONG, 0, 8, 8 },
|
||||
new Object[] { STRING_LLONG, 0, 5, 5 },
|
||||
new Object[] { STRING_LLONG, 4, 8, 4 },
|
||||
new Object[] { STRING_LLONG, 0, 7, 7 },
|
||||
new Object[] { STRING_U1, 0, 1, 1 },
|
||||
new Object[] { STRING_U2, 0, 2, 2 },
|
||||
new Object[] { STRING_U2, 0, 1, 1 },
|
||||
new Object[] { STRING_U2, 1, 2, 1 },
|
||||
new Object[] { STRING_M12, 0, 2, 2 },
|
||||
new Object[] { STRING_M12, 0, 1, 1 },
|
||||
new Object[] { STRING_M12, 1, 2, 1 },
|
||||
new Object[] { STRING_M11, 0, 2, 2 },
|
||||
new Object[] { STRING_M11, 0, 1, 1 },
|
||||
new Object[] { STRING_M11, 1, 2, 1 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 0, 1, 1 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 0, 2, 1 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 0, 3, 2 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 0, 5, 3 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 0, 6, 4 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 1, 4, 2 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 1, 6, 4 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 2, 4, 1 },};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testCodePointCount(String str, int beginIndex, int endIndex,
|
||||
int expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.codePointCount(beginIndex, endIndex),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).codePointCount(%d, %d), source : %s, ",
|
||||
escapeNonASCIIs(data), beginIndex,
|
||||
endIndex, source));
|
||||
});
|
||||
}
|
||||
}
|
||||
305
test/jdk/java/lang/String/CompactString/CompactString.java
Normal file
305
test/jdk/java/lang/String/CompactString/CompactString.java
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2018, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.testng.annotations.BeforeClass;
|
||||
|
||||
/*
|
||||
* Base class of tests for Compact String.
|
||||
*
|
||||
*/
|
||||
public class CompactString {
|
||||
|
||||
final Map<String, Map<String, String>> map = new HashMap<>();
|
||||
|
||||
enum StringSources {
|
||||
EMPTY(STRING_EMPTY, BYTE_ARRAY_EMTPY, CHAR_ARRAY_EMPTY,
|
||||
POINT_ARRAY_EMTPY), LDUPLICATE(STRING_LDUPLICATE,
|
||||
BYTE_ARRAY_LDUPLICATE, CHAR_ARRAY_LDUPLICATE,
|
||||
POINT_ARRAY_LDUPLICATE), LLONG(STRING_LLONG, BYTE_ARRAY_LLONG,
|
||||
CHAR_ARRAY_LLONG, POINT_ARRAY_LLONG), L1(STRING_L1,
|
||||
BYTE_ARRAY_L1, CHAR_ARRAY_L1, POINT_ARRAY_L1), L2(STRING_L2,
|
||||
BYTE_ARRAY_L2, CHAR_ARRAY_L2, POINT_ARRAY_L2), L4(STRING_L4,
|
||||
BYTE_ARRAY_L4, CHAR_ARRAY_L4, POINT_ARRAY_L4), UDUPLICATE(
|
||||
STRING_UDUPLICATE, BYTE_ARRAY_UDUPLICATE,
|
||||
CHAR_ARRAY_UDUPLICATE, POINT_ARRAY_UDUPLICATE), U1(STRING_U1,
|
||||
BYTE_ARRAY_U1, CHAR_ARRAY_U1, POINT_ARRAY_U1), U2(STRING_U2,
|
||||
BYTE_ARRAY_U2, CHAR_ARRAY_U2, POINT_ARRAY_U2), MDUPLICATE1(
|
||||
STRING_MDUPLICATE1, BYTE_ARRAY_MDUPLICATE1,
|
||||
CHAR_ARRAY_MDUPLICATE1, POINT_ARRAY_MDUPLICATE1), MDUPLICATE2(
|
||||
STRING_MDUPLICATE2, BYTE_ARRAY_MDUPLICATE2,
|
||||
CHAR_ARRAY_MDUPLICATE2, POINT_ARRAY_MDUPLICATE2), MLONG1(
|
||||
STRING_MLONG1, BYTE_ARRAY_MLONG1, CHAR_ARRAY_MLONG1,
|
||||
POINT_ARRAY_MLONG1), MLONG2(STRING_MLONG2, BYTE_ARRAY_MLONG2,
|
||||
CHAR_ARRAY_MLONG2, POINT_ARRAY_MLONG2), M11(STRING_M11,
|
||||
BYTE_ARRAY_M11, CHAR_ARRAY_M11, POINT_ARRAY_M11), M12(
|
||||
STRING_M12, BYTE_ARRAY_M12, CHAR_ARRAY_M12, POINT_ARRAY_M12), SUPPLEMENTARY(
|
||||
STRING_SUPPLEMENTARY, BYTE_ARRAY_SUPPLEMENTARY,
|
||||
CHAR_ARRAY_SUPPLEMENTARY, POINT_ARRAY_SUPPLEMENTARY), SUPPLEMENTARY_LOWERCASE(
|
||||
STRING_SUPPLEMENTARY_LOWERCASE,
|
||||
BYTE_ARRAY_SUPPLEMENTARY_LOWERCASE,
|
||||
CHAR_ARRAY_SUPPLEMENTARY_LOWERCASE,
|
||||
POINT_ARRAY_SUPPLEMENTARY_LOWERCASE);
|
||||
|
||||
private StringSources(String s, byte[] b, char[] c, int[] i) {
|
||||
str = s;
|
||||
ba = b;
|
||||
ca = c;
|
||||
ia = i;
|
||||
}
|
||||
|
||||
String getString() {
|
||||
return str;
|
||||
}
|
||||
|
||||
byte[] getByteArray() {
|
||||
return ba;
|
||||
}
|
||||
|
||||
char[] getCharArray() {
|
||||
return ca;
|
||||
}
|
||||
|
||||
int[] getIntArray() {
|
||||
return ia;
|
||||
}
|
||||
|
||||
private final String str;
|
||||
private final byte[] ba;
|
||||
private final char[] ca;
|
||||
private final int[] ia;
|
||||
}
|
||||
|
||||
protected static final String DEFAULT_CHARSET_NAME = "UTF-8";
|
||||
protected static final Charset DEFAULT_CHARSET = Charset
|
||||
.forName(DEFAULT_CHARSET_NAME);
|
||||
|
||||
protected static final String STRING_EMPTY = "";
|
||||
protected static final byte[] BYTE_ARRAY_EMTPY = new byte[0];
|
||||
protected static final char[] CHAR_ARRAY_EMPTY = new char[0];
|
||||
protected static final int[] POINT_ARRAY_EMTPY = new int[0];
|
||||
|
||||
protected static final String STRING_LDUPLICATE = "ABABABABAB";
|
||||
protected static final byte[] BYTE_ARRAY_LDUPLICATE = new byte[] { 'A', 'B',
|
||||
'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B' };
|
||||
protected static final char[] CHAR_ARRAY_LDUPLICATE = new char[] { 'A', 'B',
|
||||
'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B' };
|
||||
protected static final int[] POINT_ARRAY_LDUPLICATE = new int[] { 'A', 'B',
|
||||
'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B' };
|
||||
|
||||
protected static final String STRING_LLONG = "ABCDEFGH";
|
||||
protected static final byte[] BYTE_ARRAY_LLONG = new byte[] { 'A', 'B', 'C',
|
||||
'D', 'E', 'F', 'G', 'H' };
|
||||
protected static final char[] CHAR_ARRAY_LLONG = new char[] { 'A', 'B', 'C',
|
||||
'D', 'E', 'F', 'G', 'H' };
|
||||
protected static final int[] POINT_ARRAY_LLONG = new int[] { 'A', 'B', 'C',
|
||||
'D', 'E', 'F', 'G', 'H' };
|
||||
|
||||
protected static final String STRING_L1 = "A";
|
||||
protected static final byte[] BYTE_ARRAY_L1 = new byte[] { 'A' };
|
||||
protected static final char[] CHAR_ARRAY_L1 = new char[] { 'A' };
|
||||
protected static final int[] POINT_ARRAY_L1 = new int[] { 'A' };
|
||||
|
||||
protected static final String STRING_L2 = "AB";
|
||||
protected static final byte[] BYTE_ARRAY_L2 = new byte[] { 'A', 'B' };
|
||||
protected static final char[] CHAR_ARRAY_L2 = new char[] { 'A', 'B' };
|
||||
protected static final int[] POINT_ARRAY_L2 = new int[] { 'A', 'B' };
|
||||
|
||||
protected static final String STRING_L4 = "ABCD";
|
||||
protected static final byte[] BYTE_ARRAY_L4 = new byte[] { 'A', 'B', 'C', 'D' };
|
||||
protected static final char[] CHAR_ARRAY_L4 = new char[] { 'A', 'B', 'C', 'D' };
|
||||
protected static final int[] POINT_ARRAY_L4 = new int[] { 'A', 'B', 'C', 'D' };
|
||||
|
||||
/*
|
||||
* Because right now ASCII is the default encoding parameter for source code
|
||||
* in JDK build environment, so we escape them. same as below.
|
||||
*/
|
||||
protected static final String STRING_UDUPLICATE = "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22";
|
||||
protected static final byte[] BYTE_ARRAY_UDUPLICATE = getBytes(STRING_UDUPLICATE);
|
||||
protected static final char[] CHAR_ARRAY_UDUPLICATE = new char[] { '\uFF21',
|
||||
'\uFF22', '\uFF21', '\uFF22', '\uFF21', '\uFF22', '\uFF21',
|
||||
'\uFF22', '\uFF21', '\uFF22' };
|
||||
protected static final int[] POINT_ARRAY_UDUPLICATE = new int[] { '\uFF21',
|
||||
'\uFF22', '\uFF21', '\uFF22', '\uFF21', '\uFF22', '\uFF21',
|
||||
'\uFF22', '\uFF21', '\uFF22' };
|
||||
|
||||
protected static final String STRING_U1 = "\uFF21";
|
||||
protected static final byte[] BYTE_ARRAY_U1 = getBytes(STRING_U1);
|
||||
protected static final char[] CHAR_ARRAY_U1 = new char[] { '\uFF21' };
|
||||
protected static final int[] POINT_ARRAY_U1 = new int[] { '\uFF21' };
|
||||
|
||||
protected static final String STRING_U2 = "\uFF21\uFF22";
|
||||
protected static final byte[] BYTE_ARRAY_U2 = getBytes(STRING_U2);
|
||||
protected static final char[] CHAR_ARRAY_U2 = new char[] { '\uFF21', '\uFF22' };
|
||||
protected static final int[] POINT_ARRAY_U2 = new int[] { '\uFF21', '\uFF22' };
|
||||
|
||||
protected static final String STRING_MDUPLICATE1 = "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A";
|
||||
protected static final byte[] BYTE_ARRAY_MDUPLICATE1 = getBytes(STRING_MDUPLICATE1);
|
||||
protected static final char[] CHAR_ARRAY_MDUPLICATE1 = new char[] { '\uFF21',
|
||||
'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A' };
|
||||
protected static final int[] POINT_ARRAY_MDUPLICATE1 = new int[] { '\uFF21',
|
||||
'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A' };
|
||||
|
||||
protected static final String STRING_MDUPLICATE2 = "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21";
|
||||
protected static final byte[] BYTE_ARRAY_MDUPLICATE2 = getBytes(STRING_MDUPLICATE2);
|
||||
protected static final char[] CHAR_ARRAY_MDUPLICATE2 = new char[] { 'A',
|
||||
'\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A',
|
||||
'\uFF21' };
|
||||
protected static final int[] POINT_ARRAY_MDUPLICATE2 = new int[] { 'A',
|
||||
'\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A',
|
||||
'\uFF21' };
|
||||
|
||||
protected static final String STRING_MLONG1 = "A\uFF21B\uFF22C\uFF23D\uFF24E\uFF25F\uFF26G\uFF27H\uFF28";
|
||||
protected static final byte[] BYTE_ARRAY_MLONG1 = getBytes(STRING_MLONG1);
|
||||
protected static final char[] CHAR_ARRAY_MLONG1 = new char[] { 'A', '\uFF21',
|
||||
'B', '\uFF22', 'C', '\uFF23', 'D', '\uFF24', 'E', '\uFF25', 'F',
|
||||
'\uFF26', 'G', '\uFF27', 'H', '\uFF28' };
|
||||
protected static final int[] POINT_ARRAY_MLONG1 = new int[] { 'A', '\uFF21',
|
||||
'B', '\uFF22', 'C', '\uFF23', 'D', '\uFF24', 'E', '\uFF25', 'F',
|
||||
'\uFF26', 'G', '\uFF27', 'H', '\uFF28' };
|
||||
|
||||
protected static final String STRING_MLONG2 = "\uFF21A\uFF22B\uFF23C\uFF24D\uFF25E\uFF26F\uFF27G\uFF28H";
|
||||
protected static final byte[] BYTE_ARRAY_MLONG2 = getBytes(STRING_MLONG2);
|
||||
protected static final char[] CHAR_ARRAY_MLONG2 = new char[] { '\uFF21', 'A',
|
||||
'\uFF22', 'B', '\uFF23', 'C', '\uFF24', 'D', '\uFF25', 'E',
|
||||
'\uFF26', 'F', '\uFF27', 'G', '\uFF28', 'H' };
|
||||
protected static final int[] POINT_ARRAY_MLONG2 = new int[] { '\uFF21', 'A',
|
||||
'\uFF22', 'B', '\uFF23', 'C', '\uFF24', 'D', '\uFF25', 'E',
|
||||
'\uFF26', 'F', '\uFF27', 'G', '\uFF28', 'H' };
|
||||
|
||||
protected static final String STRING_M11 = "A\uFF21";
|
||||
protected static final byte[] BYTE_ARRAY_M11 = getBytes(STRING_M11);
|
||||
protected static final char[] CHAR_ARRAY_M11 = new char[] { 'A', '\uFF21' };
|
||||
protected static final int[] POINT_ARRAY_M11 = new int[] { 'A', '\uFF21' };
|
||||
|
||||
protected static final String STRING_M12 = "\uFF21A";
|
||||
protected static final byte[] BYTE_ARRAY_M12 = getBytes(STRING_M12);
|
||||
protected static final char[] CHAR_ARRAY_M12 = new char[] { '\uFF21', 'A' };
|
||||
protected static final int[] POINT_ARRAY_M12 = new int[] { '\uFF21', 'A' };
|
||||
|
||||
protected static final String STRING_SUPPLEMENTARY = "\uD801\uDC00\uD801\uDC01\uFF21A";
|
||||
protected static final byte[] BYTE_ARRAY_SUPPLEMENTARY = getBytes(STRING_SUPPLEMENTARY);
|
||||
protected static final char[] CHAR_ARRAY_SUPPLEMENTARY = new char[] {
|
||||
'\uD801', '\uDC00', '\uD801', '\uDC01', '\uFF21', 'A' };
|
||||
protected static final int[] POINT_ARRAY_SUPPLEMENTARY = new int[] {
|
||||
'\uD801', '\uDC00', '\uD801', '\uDC01', '\uFF21', 'A' };
|
||||
|
||||
protected static final String STRING_SUPPLEMENTARY_LOWERCASE = "\uD801\uDC28\uD801\uDC29\uFF41a";
|
||||
protected static final byte[] BYTE_ARRAY_SUPPLEMENTARY_LOWERCASE = getBytes(STRING_SUPPLEMENTARY_LOWERCASE);
|
||||
protected static final char[] CHAR_ARRAY_SUPPLEMENTARY_LOWERCASE = new char[] {
|
||||
'\uD801', '\uDC28', '\uD801', '\uDC29', '\uFF41', 'a' };
|
||||
protected static final int[] POINT_ARRAY_SUPPLEMENTARY_LOWERCASE = new int[] {
|
||||
'\uD801', '\uDC28', '\uD801', '\uDC29', '\uFF41', 'a' };
|
||||
|
||||
protected static final String SRC_BYTE_ARRAY_WITH_CHARSETNAME = "source from byte array with charset name";
|
||||
protected static final String SRC_BYTE_ARRAY_WITH_CHARSET = "source from byte array with charset";
|
||||
protected static final String SRC_CHAR_ARRAY = "source from char array";
|
||||
protected static final String SRC_POINT_ARRAY = "source from code point array";
|
||||
protected static final String SRC_STRING = "source from String";
|
||||
protected static final String SRC_STRINGBUFFER = "source from StringBuffer";
|
||||
protected static final String SRC_STRINGBUILDER = "source from StringBuilder";
|
||||
protected static final String SRC_COPYVALUEOF = "source from copyValueOf from char array";
|
||||
protected static final String SRC_VALUEOF = "source from valueOf from char array";
|
||||
|
||||
static {
|
||||
System.out
|
||||
.println(String
|
||||
.format("====== The platform's default charset is \"%s\", we're using \"%s\" for testing.",
|
||||
Charset.defaultCharset().name(),
|
||||
DEFAULT_CHARSET_NAME));
|
||||
}
|
||||
|
||||
private static byte[] getBytes(String str) {
|
||||
byte[] res = null;
|
||||
try {
|
||||
res = str.getBytes(DEFAULT_CHARSET_NAME);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("caught UnsupportedEncodingException!!!", e);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private void setUpOneString(String content, byte[] ba, char[] ca, int[] cpa)
|
||||
throws UnsupportedEncodingException {
|
||||
final Map<String, String> m = new HashMap<>();
|
||||
m.put(SRC_BYTE_ARRAY_WITH_CHARSETNAME, new String(ba,
|
||||
DEFAULT_CHARSET_NAME));
|
||||
m.put(SRC_BYTE_ARRAY_WITH_CHARSET, new String(ba, DEFAULT_CHARSET));
|
||||
m.put(SRC_CHAR_ARRAY, new String(ca));
|
||||
m.put(SRC_POINT_ARRAY, new String(cpa, 0, cpa.length));
|
||||
m.put(SRC_STRING, new String(content));
|
||||
m.put(SRC_STRINGBUFFER, new String(new StringBuffer(content)));
|
||||
m.put(SRC_STRINGBUILDER, new String(new StringBuilder(content)));
|
||||
m.put(SRC_COPYVALUEOF, String.copyValueOf(ca));
|
||||
m.put(SRC_VALUEOF, String.valueOf(ca));
|
||||
map.put(content, m);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the test data, use 9 ways to construct one String.
|
||||
*
|
||||
* @throws UnsupportedEncodingException
|
||||
* If the named charset is not supported in setUpOneString(xxx).
|
||||
*/
|
||||
@BeforeClass
|
||||
public void setUp() throws UnsupportedEncodingException {
|
||||
for (StringSources src : StringSources.values()) {
|
||||
setUpOneString(src.getString(), src.getByteArray(),
|
||||
src.getCharArray(), src.getIntArray());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Escape non-ASCII characters since not all systems support them.
|
||||
*/
|
||||
protected String escapeNonASCIIs(String str) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
char c = str.charAt(i);
|
||||
if (c > 0x7F) {
|
||||
sb.append("\\u").append(Integer.toHexString((int) c));
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Escape non-ASCII characters since not all systems support them.
|
||||
*/
|
||||
protected String escapeNonASCII(char c) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (c > 0x7F) {
|
||||
sb.append("\\u").append(Integer.toHexString((int) c));
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
137
test/jdk/java/lang/String/CompactString/CompareTo.java
Normal file
137
test/jdk/java/lang/String/CompactString/CompareTo.java
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559 8137326
|
||||
* @summary Tests Compact String. Verifies the compareTo method for String,
|
||||
* StringBuilder and StringBuffer.
|
||||
* @run testng/othervm -XX:+CompactStrings CompareTo
|
||||
* @run testng/othervm -XX:-CompactStrings CompareTo
|
||||
*/
|
||||
|
||||
public class CompareTo extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, "A", -1 },
|
||||
new Object[] { STRING_EMPTY, "\uFF21", -1 },
|
||||
new Object[] { STRING_L1, "AB", -1 },
|
||||
new Object[] { STRING_L1, "A", 0 },
|
||||
new Object[] { STRING_L1, "a", -32 },
|
||||
new Object[] { STRING_L1, "\uFF21", -65248 },
|
||||
new Object[] { STRING_L2, "AB", 0 },
|
||||
new Object[] { STRING_L2, "Ab", -32 },
|
||||
new Object[] { STRING_L2, "AA", 1 },
|
||||
new Object[] { STRING_L2, "\uFF21", -65248 },
|
||||
new Object[] { STRING_L2, "A\uFF21", -65247 },
|
||||
new Object[] { STRING_L4, "ABC", 1 },
|
||||
new Object[] { STRING_L4, "AB", 2 },
|
||||
new Object[] { STRING_L4, "ABcD", -32 },
|
||||
new Object[] { STRING_L4, "ABCD\uFF21\uFF21", -2 },
|
||||
new Object[] { STRING_L4, "ABCD\uFF21", -1 },
|
||||
new Object[] { STRING_LLONG, "ABCDEFG\uFF21", -65241 },
|
||||
new Object[] { STRING_LLONG, "AB", 6 },
|
||||
new Object[] { STRING_LLONG, "ABCD", 4 },
|
||||
new Object[] { STRING_LLONG, "ABCDEFGH\uFF21\uFF21", -2 },
|
||||
new Object[] { STRING_U1, "\uFF21", 0 },
|
||||
new Object[] { STRING_U1, "\uFF22", -1 },
|
||||
new Object[] { STRING_U1, "\uFF21\uFF22", -1 },
|
||||
new Object[] { STRING_U1, "A", 65248 },
|
||||
new Object[] { STRING_U2, "\uFF21\uFF22", 0 },
|
||||
new Object[] { STRING_U2, "\uFF22", -1 },
|
||||
new Object[] { STRING_U2, "\uFF21\uFF21", 1 },
|
||||
new Object[] { STRING_U2, "A", 65248 },
|
||||
new Object[] { STRING_M12, "\uFF21A", 0 },
|
||||
new Object[] { STRING_M12, "A\uFF21", 65248 },
|
||||
new Object[] { STRING_M12, "\uFF21\uFF21", -65248 },
|
||||
new Object[] { STRING_M11, "A\uFF21", 0 },
|
||||
new Object[] { STRING_M11, "\uFF21A", -65248 },
|
||||
new Object[] { STRING_M11, "AA", 65248 }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testCompareTo(String str, String anotherString, int expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.compareTo(anotherString),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).compareTo(%s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(anotherString),
|
||||
source));
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Runs the same test with StringBuilder
|
||||
*/
|
||||
@Test(dataProvider = "provider")
|
||||
public void testStringBuilder(String str, String anotherString, int expected) {
|
||||
StringBuilder another = new StringBuilder(anotherString);
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
StringBuilder sb = new StringBuilder(data);
|
||||
assertEquals(
|
||||
sb.compareTo(another),
|
||||
expected,
|
||||
String.format(
|
||||
"testing StringBuilder(%s).compareTo(%s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(anotherString),
|
||||
source));
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Runs the same test with StringBuffer
|
||||
*/
|
||||
@Test(dataProvider = "provider")
|
||||
public void testStringBuffer(String str, String anotherString, int expected) {
|
||||
StringBuffer another = new StringBuffer(anotherString);
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
StringBuffer sb = new StringBuffer(data);
|
||||
assertEquals(
|
||||
sb.compareTo(another),
|
||||
expected,
|
||||
String.format(
|
||||
"testing StringBuffer(%s).compareTo(%s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(anotherString),
|
||||
source));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2021, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559 8248655 8264544
|
||||
* @summary Tests Compact String. This one is for String.compareToIgnoreCase.
|
||||
* @run testng/othervm -XX:+CompactStrings CompareToIgnoreCase
|
||||
* @run testng/othervm -XX:-CompactStrings CompareToIgnoreCase
|
||||
*/
|
||||
|
||||
public class CompareToIgnoreCase extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
new Object[] { STRING_EMPTY, "A", -1 },
|
||||
new Object[] { STRING_L1, "a", 0 },
|
||||
new Object[] { STRING_L1, "A", 0 },
|
||||
new Object[] { STRING_L1, "\uFF21", -65248 },
|
||||
new Object[] { STRING_L1, "B", -1 },
|
||||
new Object[] { STRING_L2, "AB", 0 },
|
||||
new Object[] { STRING_L2, "aB", 0 },
|
||||
new Object[] { STRING_L2, "\uFF21", -65248 },
|
||||
new Object[] { STRING_L2, "A\uFF21", -65247 },
|
||||
new Object[] { STRING_L4, "ABCD", 0 },
|
||||
new Object[] { STRING_L4, "abcd", 0 },
|
||||
new Object[] { STRING_L4, "ABc\uFF21", -65245 },
|
||||
new Object[] { STRING_LLONG, "ABCDEFGH", 0 },
|
||||
new Object[] { STRING_LLONG, "abcdefgh", 0 },
|
||||
new Object[] { STRING_LLONG, "ABCDEFG\uFF21", -65241 },
|
||||
new Object[] { STRING_LLONG, "abcdefg\uFF21", -65241 },
|
||||
new Object[] { STRING_U1, "\uFF41", 0 },
|
||||
new Object[] { STRING_U1,
|
||||
"\uFF41\uFF42\uFF43\uFF44\uFF45\uFF46\uFF47\uFF48", -7 },
|
||||
new Object[] { STRING_U1, "A", 65248 },
|
||||
new Object[] { STRING_U2, "\uFF41", 1 },
|
||||
new Object[] { STRING_U2, "\uFF41\uFF42", 0 },
|
||||
new Object[] { STRING_U2,
|
||||
"\uFF41\uFF42\uFF43\uFF44\uFF45\uFF46\uFF47\uFF48", -6 },
|
||||
new Object[] { STRING_M12, "\uFF41a", 0 },
|
||||
new Object[] { STRING_M12, "\uFF41\uFF42", -65249 },
|
||||
new Object[] { STRING_M11, "a\uFF41", 0 },
|
||||
new Object[] { STRING_M11, "a\uFF42", -1 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, STRING_SUPPLEMENTARY_LOWERCASE, 0 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, "\uD801\uDC28\uD801\uDC27\uFF41a", -38 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, "\uD802\uDC00\uD801\uDC01\uFF21A", -984 },
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testCompareToIgnoreCase(String str, String anotherString,
|
||||
int expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.compareToIgnoreCase(anotherString),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).compareToIgnoreCase(%s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(anotherString),
|
||||
source));
|
||||
});
|
||||
}
|
||||
}
|
||||
132
test/jdk/java/lang/String/CompactString/Concat.java
Normal file
132
test/jdk/java/lang/String/CompactString/Concat.java
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.concat.
|
||||
* @run testng/othervm -XX:+CompactStrings Concat
|
||||
* @run testng/othervm -XX:-CompactStrings Concat
|
||||
*/
|
||||
|
||||
public class Concat extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
new Object[] { STRING_EMPTY, "ABC", "ABC" },
|
||||
new Object[] { STRING_EMPTY,
|
||||
"ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
|
||||
"ABC\uFF21\uFF22\uFF23DEF" },
|
||||
new Object[] {
|
||||
STRING_EMPTY,
|
||||
"\uFF21\uFF22\uFF23".concat("ABC").concat(
|
||||
"\uFF24\uFF25\uFF26"),
|
||||
"\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
|
||||
new Object[] { STRING_L1,
|
||||
"ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
|
||||
"AABC\uFF21\uFF22\uFF23DEF" },
|
||||
new Object[] {
|
||||
STRING_L1,
|
||||
"\uFF21\uFF22\uFF23".concat("ABC").concat(
|
||||
"\uFF24\uFF25\uFF26"),
|
||||
"A\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
|
||||
new Object[] { STRING_L2,
|
||||
"ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
|
||||
"ABABC\uFF21\uFF22\uFF23DEF" },
|
||||
new Object[] {
|
||||
STRING_L2,
|
||||
"\uFF21\uFF22\uFF23".concat("ABC").concat(
|
||||
"\uFF24\uFF25\uFF26"),
|
||||
"AB\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
|
||||
new Object[] { STRING_L4,
|
||||
"ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
|
||||
"ABCDABC\uFF21\uFF22\uFF23DEF" },
|
||||
new Object[] {
|
||||
STRING_L4,
|
||||
"\uFF21\uFF22\uFF23".concat("ABC").concat(
|
||||
"\uFF24\uFF25\uFF26"),
|
||||
"ABCD\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
|
||||
new Object[] { STRING_LLONG,
|
||||
"ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
|
||||
"ABCDEFGHABC\uFF21\uFF22\uFF23DEF" },
|
||||
new Object[] {
|
||||
STRING_LLONG,
|
||||
"\uFF21\uFF22\uFF23".concat("ABC").concat(
|
||||
"\uFF24\uFF25\uFF26"),
|
||||
"ABCDEFGH\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
|
||||
new Object[] { STRING_U1,
|
||||
"ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
|
||||
"\uFF21ABC\uFF21\uFF22\uFF23DEF" },
|
||||
new Object[] {
|
||||
STRING_U1,
|
||||
"\uFF21\uFF22\uFF23".concat("ABC").concat(
|
||||
"\uFF24\uFF25\uFF26"),
|
||||
"\uFF21\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
|
||||
new Object[] { STRING_U2,
|
||||
"ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
|
||||
"\uFF21\uFF22ABC\uFF21\uFF22\uFF23DEF" },
|
||||
new Object[] {
|
||||
STRING_U2,
|
||||
"\uFF21\uFF22\uFF23".concat("ABC").concat(
|
||||
"\uFF24\uFF25\uFF26"),
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
|
||||
new Object[] { STRING_M12,
|
||||
"ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
|
||||
"\uFF21AABC\uFF21\uFF22\uFF23DEF" },
|
||||
new Object[] {
|
||||
STRING_M12,
|
||||
"\uFF21\uFF22\uFF23".concat("ABC").concat(
|
||||
"\uFF24\uFF25\uFF26"),
|
||||
"\uFF21A\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
|
||||
new Object[] { STRING_M11,
|
||||
"ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
|
||||
"A\uFF21ABC\uFF21\uFF22\uFF23DEF" },
|
||||
new Object[] {
|
||||
STRING_M11,
|
||||
"\uFF21\uFF22\uFF23".concat("ABC").concat(
|
||||
"\uFF24\uFF25\uFF26"),
|
||||
"A\uFF21\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testConcat(String str, String anotherString, String expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.concat(anotherString),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).concat(%s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(anotherString),
|
||||
source));
|
||||
});
|
||||
}
|
||||
}
|
||||
91
test/jdk/java/lang/String/CompactString/Contains.java
Normal file
91
test/jdk/java/lang/String/CompactString/Contains.java
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.contains.
|
||||
* @run testng/othervm -XX:+CompactStrings Contains
|
||||
* @run testng/othervm -XX:-CompactStrings Contains
|
||||
*/
|
||||
|
||||
public class Contains extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, "", true },
|
||||
new Object[] { STRING_EMPTY, "A", false },
|
||||
new Object[] { STRING_EMPTY, "\uFF21", false },
|
||||
new Object[] { STRING_L1, "", true },
|
||||
new Object[] { STRING_L1, "A", true },
|
||||
new Object[] { STRING_L1, "\uFF21", false },
|
||||
new Object[] { STRING_L2, "", true },
|
||||
new Object[] { STRING_L2, "A", true },
|
||||
new Object[] { STRING_L2, "AB", true },
|
||||
new Object[] { STRING_L2, "B", true },
|
||||
new Object[] { STRING_L2, "ABC", false },
|
||||
new Object[] { STRING_L2, "ab", false },
|
||||
new Object[] { STRING_L4, "ABCD", true },
|
||||
new Object[] { STRING_L4, "BC", true },
|
||||
new Object[] { STRING_LLONG, "ABCDEFGH", true },
|
||||
new Object[] { STRING_LLONG, "BCDEFGH", true },
|
||||
new Object[] { STRING_LLONG, "EF", true },
|
||||
new Object[] { STRING_U1, "", true },
|
||||
new Object[] { STRING_U1, "\uFF21", true },
|
||||
new Object[] { STRING_U1, "a", false },
|
||||
new Object[] { STRING_U1, "\uFF21B", false },
|
||||
new Object[] { STRING_U2, "", true },
|
||||
new Object[] { STRING_U2, "\uFF21\uFF22", true },
|
||||
new Object[] { STRING_U2, "a", false },
|
||||
new Object[] { STRING_U2, "\uFF21B", false },
|
||||
new Object[] { STRING_M12, "\uFF21A", true },
|
||||
new Object[] { STRING_M12, "\uFF21", true },
|
||||
new Object[] { STRING_M12, "A", true },
|
||||
new Object[] { STRING_M12, "A\uFF21", false },
|
||||
new Object[] { STRING_M11, "A\uFF21", true },
|
||||
new Object[] { STRING_M11, "Ab", false }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testContains(String str, String anotherString, boolean expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.contains(anotherString),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).contains(%s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(anotherString),
|
||||
source));
|
||||
});
|
||||
}
|
||||
}
|
||||
92
test/jdk/java/lang/String/CompactString/EndsWith.java
Normal file
92
test/jdk/java/lang/String/CompactString/EndsWith.java
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.endsWith.
|
||||
* @run testng/othervm -XX:+CompactStrings EndsWith
|
||||
* @run testng/othervm -XX:-CompactStrings EndsWith
|
||||
*/
|
||||
|
||||
public class EndsWith extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] { new Object[] { STRING_EMPTY, "", true },
|
||||
new Object[] { STRING_EMPTY, "A", false },
|
||||
new Object[] { STRING_L1, "A", true },
|
||||
new Object[] { STRING_L1, "", true },
|
||||
new Object[] { STRING_L1, " ", false },
|
||||
new Object[] { STRING_L2, "AB", true },
|
||||
new Object[] { STRING_L2, "B", true },
|
||||
new Object[] { STRING_L2, "", true },
|
||||
new Object[] { STRING_L2, "A", false },
|
||||
new Object[] { STRING_L4, "ABCD", true },
|
||||
new Object[] { STRING_L4, "CD", true },
|
||||
new Object[] { STRING_L4, "D", true },
|
||||
new Object[] { STRING_L4, "", true },
|
||||
new Object[] { STRING_L4, "BC", false },
|
||||
new Object[] { STRING_LLONG, "ABCDEFGH", true },
|
||||
new Object[] { STRING_LLONG, "EFGH", true },
|
||||
new Object[] { STRING_LLONG, "", true },
|
||||
new Object[] { STRING_LLONG, "CDEF", false },
|
||||
new Object[] { STRING_LLONG, "\uFF28", false },
|
||||
new Object[] { STRING_U1, "\uFF21", true },
|
||||
new Object[] { STRING_U1, "", true },
|
||||
new Object[] { STRING_U1, "\uFF22", false },
|
||||
new Object[] { STRING_U1, "B", false },
|
||||
new Object[] { STRING_U2, "\uFF21\uFF22", true },
|
||||
new Object[] { STRING_U2, "\uFF22", true },
|
||||
new Object[] { STRING_U2, "", true },
|
||||
new Object[] { STRING_U2, "\uFF21", false },
|
||||
new Object[] { STRING_M12, "\uFF21A", true },
|
||||
new Object[] { STRING_M12, "A", true },
|
||||
new Object[] { STRING_M12, "", true },
|
||||
new Object[] { STRING_M12, "AA", false },
|
||||
new Object[] { STRING_M11, "A\uFF21", true },
|
||||
new Object[] { STRING_M11, "\uFF21", true },
|
||||
new Object[] { STRING_M11, "", true },
|
||||
new Object[] { STRING_M11, "\uFF21\uFF21", false }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testEndsWith(String str, String suffix, boolean expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.endsWith(suffix),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).endsWith(%s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(suffix), source));
|
||||
});
|
||||
}
|
||||
}
|
||||
81
test/jdk/java/lang/String/CompactString/Equals.java
Normal file
81
test/jdk/java/lang/String/CompactString/Equals.java
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.equals.
|
||||
* @run testng/othervm -XX:+CompactStrings Equals
|
||||
* @run testng/othervm -XX:-CompactStrings Equals
|
||||
*/
|
||||
|
||||
public class Equals extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
new Object[] { STRING_EMPTY, "", true },
|
||||
new Object[] { STRING_EMPTY, "A", false },
|
||||
new Object[] { STRING_EMPTY, new StringBuffer(""), false },
|
||||
new Object[] { STRING_L1, "A", true },
|
||||
new Object[] { STRING_L1, "", false },
|
||||
new Object[] { STRING_L1, new StringBuffer("A"), false },
|
||||
new Object[] { STRING_L2, "AB", true },
|
||||
new Object[] { STRING_L2, "", false },
|
||||
new Object[] { STRING_L2, new StringBuilder("AB"), false },
|
||||
new Object[] { STRING_L4, "ABCD", true },
|
||||
new Object[] { STRING_L4, "abc", false },
|
||||
new Object[] { STRING_L4, "", false },
|
||||
new Object[] { STRING_LLONG, "ABCDEFGH", true },
|
||||
new Object[] { STRING_LLONG, "ABCDEFG", false },
|
||||
new Object[] { STRING_LLONG, new StringBuilder("ABCDEFGH"),
|
||||
false },
|
||||
new Object[] { STRING_U1, "\uFF21", true },
|
||||
new Object[] { STRING_U1, "", false },
|
||||
new Object[] { STRING_U2, "\uFF21\uFF22", true },
|
||||
new Object[] { STRING_U2, "\uFF21", false },
|
||||
new Object[] { STRING_U2, "", false },
|
||||
new Object[] { STRING_U2, new StringBuilder("\uFF21\uFF22"),
|
||||
false },
|
||||
new Object[] { STRING_M12, "\uFF21A", true },
|
||||
new Object[] { STRING_M12, "A\uFF21", false },
|
||||
new Object[] { STRING_M11, "A\uFF21", true },
|
||||
new Object[] { STRING_M11, new StringBuilder("\uFF21A"), false }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testEquals(String str, Object obj, boolean expected) {
|
||||
map.get(str).forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(data.equals(obj), expected, String.format(
|
||||
"testing String(%s).equals(%s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(obj.toString()), source));
|
||||
});
|
||||
}
|
||||
}
|
||||
107
test/jdk/java/lang/String/CompactString/EqualsIgnoreCase.java
Normal file
107
test/jdk/java/lang/String/CompactString/EqualsIgnoreCase.java
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2023, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559 8248655 8302871
|
||||
* @summary Tests Compact String. This one is for String.equalsIgnoreCase.
|
||||
* @run testng/othervm -XX:+CompactStrings EqualsIgnoreCase
|
||||
* @run testng/othervm -XX:-CompactStrings EqualsIgnoreCase
|
||||
*/
|
||||
|
||||
public class EqualsIgnoreCase extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, "", true },
|
||||
new Object[] { STRING_L1, "a", true },
|
||||
new Object[] { STRING_L2, "aB", true },
|
||||
new Object[] { STRING_L4, "AbCd", true },
|
||||
new Object[] { STRING_LLONG, "aBcDeFgH", true },
|
||||
new Object[] { STRING_U1, "\uFF41", true },
|
||||
new Object[] { STRING_U1, "\uFF21", true },
|
||||
new Object[] { STRING_U2, "\uFF41\uFF42", true },
|
||||
new Object[] { STRING_U2, "\uFF41\uFF22", true },
|
||||
new Object[] { STRING_U2, "\uFF21\uFF42", true },
|
||||
new Object[] { STRING_M12, "\uFF41a", true },
|
||||
new Object[] { STRING_M12, "\uFF21A", true },
|
||||
new Object[] { STRING_M11, "a\uFF41", true },
|
||||
new Object[] { STRING_M11, "A\uFF21", true },
|
||||
new Object[] { STRING_SUPPLEMENTARY, STRING_SUPPLEMENTARY_LOWERCASE, true },
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testEqualsIgnoreCase(String str, String anotherString,
|
||||
boolean expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.equalsIgnoreCase(anotherString),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).equalsIgnoreCase(%s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(anotherString),
|
||||
source));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Exhaustively check that all 256x256 latin1 code point pairs are equalsIgnoreCased
|
||||
* in a manner consistent with Character.toLowerCase(Character.toUpperCase(c));
|
||||
*/
|
||||
@Test
|
||||
public void checkConsistencyWithCharacterUppercaseLowerCase() {
|
||||
for (char a = 0; a < 256; a++) {
|
||||
for (char b = 0; b < 256; b++) {
|
||||
|
||||
int caseFoldA = Character.toLowerCase(Character.toUpperCase(a));
|
||||
int caseFoldB = Character.toLowerCase(Character.toUpperCase(b));
|
||||
|
||||
String astr = Character.toString(a);
|
||||
String bstr = Character.toString(b);
|
||||
|
||||
// If characters fold to the same lowercase, their strings should equalsIgnoreCase:
|
||||
if (caseFoldA == caseFoldB) {
|
||||
assertTrue(astr.equalsIgnoreCase(bstr),
|
||||
"Expected %s to equalsIgnoreCase %s".formatted(astr, bstr));
|
||||
} else {
|
||||
assertFalse(astr.equalsIgnoreCase(bstr),
|
||||
"Expected %s to not equalsIgnoreCase %s".formatted(astr, bstr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
91
test/jdk/java/lang/String/CompactString/GetChars.java
Normal file
91
test/jdk/java/lang/String/CompactString/GetChars.java
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.getChars.
|
||||
* @run testng/othervm -XX:+CompactStrings GetChars
|
||||
* @run testng/othervm -XX:-CompactStrings GetChars
|
||||
*/
|
||||
|
||||
public class GetChars extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, 0, STRING_EMPTY.length(),
|
||||
new char[STRING_EMPTY.length()], 0, CHAR_ARRAY_EMPTY },
|
||||
new Object[] { STRING_L1, 0, STRING_L1.length(),
|
||||
new char[STRING_L1.length()], 0, CHAR_ARRAY_L1 },
|
||||
new Object[] { STRING_L2, 0, STRING_L2.length(),
|
||||
new char[STRING_L2.length()], 0, CHAR_ARRAY_L2 },
|
||||
new Object[] { STRING_L4, 0, STRING_L4.length(),
|
||||
new char[STRING_L4.length()], 0, CHAR_ARRAY_L4 },
|
||||
new Object[] { STRING_LLONG, 0, STRING_LLONG.length(),
|
||||
new char[STRING_LLONG.length()], 0, CHAR_ARRAY_LLONG },
|
||||
new Object[] { STRING_U1, 0, STRING_U1.length(),
|
||||
new char[STRING_U1.length()], 0, CHAR_ARRAY_U1 },
|
||||
new Object[] { STRING_U2, 0, STRING_U2.length(),
|
||||
new char[STRING_U2.length()], 0, CHAR_ARRAY_U2 },
|
||||
new Object[] { STRING_M12, 0, STRING_M12.length(),
|
||||
new char[STRING_M12.length()], 0, CHAR_ARRAY_M12 },
|
||||
new Object[] { STRING_M11, 0, STRING_M11.length(),
|
||||
new char[STRING_M11.length()], 0, CHAR_ARRAY_M11 },
|
||||
new Object[] { STRING_UDUPLICATE, 0,
|
||||
STRING_UDUPLICATE.length(),
|
||||
new char[STRING_UDUPLICATE.length()], 0,
|
||||
CHAR_ARRAY_UDUPLICATE },
|
||||
new Object[] { STRING_MDUPLICATE1, 0,
|
||||
STRING_MDUPLICATE1.length(),
|
||||
new char[STRING_MDUPLICATE1.length()], 0,
|
||||
CHAR_ARRAY_MDUPLICATE1 }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testGetChars(String str, int srcBegin, int srcEnd, char[] dst,
|
||||
int dstBegin, char[] expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
data.getChars(srcBegin, srcEnd, dst, dstBegin);
|
||||
assertTrue(
|
||||
Arrays.equals(dst, expected),
|
||||
String.format(
|
||||
"testing String(%s).getChars(%d, %d, %s, %d), source : %s, ",
|
||||
escapeNonASCIIs(data), srcBegin,
|
||||
srcEnd, escapeNonASCIIs(Arrays
|
||||
.toString(dst)), dstBegin,
|
||||
source));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
249
test/jdk/java/lang/String/CompactString/IndexOf.java
Normal file
249
test/jdk/java/lang/String/CompactString/IndexOf.java
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.indexOf.
|
||||
* @run testng/othervm -XX:+CompactStrings IndexOf
|
||||
* @run testng/othervm -XX:-CompactStrings IndexOf
|
||||
*/
|
||||
|
||||
public class IndexOf extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, (int) 'A', -1 },
|
||||
new Object[] { STRING_L1, (int) 'A', 0 },
|
||||
new Object[] { STRING_L2, (int) 'A', 0 },
|
||||
new Object[] { STRING_L2, (int) 'B', 1 },
|
||||
new Object[] { STRING_L4, (int) 'A', 0 },
|
||||
new Object[] { STRING_L4, (int) 'D', 3 },
|
||||
new Object[] { STRING_L4, (int) 'E', -1 },
|
||||
new Object[] { STRING_LLONG, (int) 'A', 0 },
|
||||
new Object[] { STRING_LLONG, (int) 'H', 7 },
|
||||
new Object[] { STRING_U1, (int) '\uFF21', 0 },
|
||||
new Object[] { STRING_U1, (int) 'A', -1 },
|
||||
new Object[] { STRING_U2, (int) '\uFF21', 0 },
|
||||
new Object[] { STRING_U2, (int) '\uFF22', 1 },
|
||||
new Object[] { STRING_M12, (int) '\uFF21', 0 },
|
||||
new Object[] { STRING_M12, (int) 'A', 1 },
|
||||
new Object[] { STRING_M11, (int) 'A', 0 },
|
||||
new Object[] { STRING_M11, (int) '\uFF21', 1 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 0 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 1 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 'A', 5 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, '\uFF21', 4 },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
Character.toCodePoint('\uD801', '\uDC00'), 0 },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
Character.toCodePoint('\uD801', '\uDC01'), 2 }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testIndexOf(String str, int ch, int expected) {
|
||||
map.get(str).forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(data.indexOf(ch), expected, String.format(
|
||||
"testing String(%s).indexOf(%d), source : %s, ",
|
||||
escapeNonASCIIs(data), ch, source));
|
||||
});
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider2() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, (int) 'A', 0, -1 },
|
||||
new Object[] { STRING_L1, (int) 'A', 0, 0 },
|
||||
new Object[] { STRING_L1, (int) 'A', 1, -1 },
|
||||
new Object[] { STRING_L1, (int) 'B', 0, -1 },
|
||||
new Object[] { STRING_L2, (int) 'A', 0, 0 },
|
||||
new Object[] { STRING_L2, (int) 'A', 1, -1 },
|
||||
new Object[] { STRING_L2, (int) 'B', 0, 1 },
|
||||
new Object[] { STRING_L2, (int) 'B', 1, 1 },
|
||||
new Object[] { STRING_L4, (int) 'A', 0, 0 },
|
||||
new Object[] { STRING_L4, (int) 'D', 2, 3 },
|
||||
new Object[] { STRING_L4, (int) 'B', 2, -1 },
|
||||
new Object[] { STRING_LLONG, (int) 'A', 0, 0 },
|
||||
new Object[] { STRING_LLONG, (int) 'H', 5, 7 },
|
||||
new Object[] { STRING_U1, (int) '\uFF21', 0, 0 },
|
||||
new Object[] { STRING_U1, (int) 'A', 0, -1 },
|
||||
new Object[] { STRING_U2, (int) '\uFF21', 0, 0 },
|
||||
new Object[] { STRING_U2, (int) '\uFF22', 0, 1 },
|
||||
new Object[] { STRING_M12, (int) '\uFF21', 0, 0 },
|
||||
new Object[] { STRING_M12, (int) 'A', 1, 1 },
|
||||
new Object[] { STRING_M11, (int) 'A', 0, 0 },
|
||||
new Object[] { STRING_M11, (int) '\uFF21', 1, 1 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 1, 2 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 1, 1 }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider2")
|
||||
public void testIndexOf(String str, int ch, int fromIndex, int expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.indexOf(ch, fromIndex),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).indexOf(%d, %d), source : %s, ",
|
||||
escapeNonASCIIs(data), ch,
|
||||
fromIndex, source));
|
||||
});
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider3() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, "A", -1 },
|
||||
new Object[] { STRING_L1, "A", 0 },
|
||||
new Object[] { STRING_L1, "AB", -1 },
|
||||
new Object[] { STRING_L2, "A", 0 },
|
||||
new Object[] { STRING_L2, "B", 1 },
|
||||
new Object[] { STRING_L2, "AB", 0 },
|
||||
new Object[] { STRING_L2, "AC", -1 },
|
||||
new Object[] { STRING_L2, "ABC", -1 },
|
||||
new Object[] { STRING_L4, "ABCD", 0 },
|
||||
new Object[] { STRING_L4, "D", 3 },
|
||||
new Object[] { STRING_LLONG, "ABCDEFGH", 0 },
|
||||
new Object[] { STRING_LLONG, "EFGH", 4 },
|
||||
new Object[] { STRING_LLONG, "EFGHI", -1 },
|
||||
new Object[] { STRING_U1, "\uFF21", 0 },
|
||||
new Object[] { STRING_U1, "\uFF21A", -1 },
|
||||
new Object[] { STRING_U2, "\uFF21\uFF22", 0 },
|
||||
new Object[] { STRING_U2, "\uFF22", 1 },
|
||||
new Object[] { STRING_U2, "A\uFF22", -1 },
|
||||
new Object[] { STRING_M12, "\uFF21A", 0 },
|
||||
new Object[] { STRING_M12, "A", 1 },
|
||||
new Object[] { STRING_M12, "\uFF21\uFF21", -1 },
|
||||
new Object[] { STRING_M11, "A\uFF21", 0 },
|
||||
new Object[] { STRING_M11, "\uFF21", 1 },
|
||||
new Object[] { STRING_M11, "A", 0 },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
|
||||
0 },
|
||||
new Object[] { STRING_UDUPLICATE,
|
||||
"\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21", 1 },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21",
|
||||
-1 }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider3")
|
||||
public void testIndexOf(String str, String anotherString, int expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.indexOf(anotherString),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).indexOf(%s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(anotherString),
|
||||
source));
|
||||
});
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider4() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, "A", 0, -1 },
|
||||
new Object[] { STRING_L1, "A", 0, 0 },
|
||||
new Object[] { STRING_L1, "A", 1, -1 },
|
||||
new Object[] { STRING_L1, "AB", 0, -1 },
|
||||
new Object[] { STRING_L2, "A", 0, 0 },
|
||||
new Object[] { STRING_L2, "B", 0, 1 },
|
||||
new Object[] { STRING_L2, "AB", 0, 0 },
|
||||
new Object[] { STRING_L2, "AB", 1, -1 },
|
||||
new Object[] { STRING_L4, "ABCD", 0, 0 },
|
||||
new Object[] { STRING_L4, "BC", 0, 1 },
|
||||
new Object[] { STRING_L4, "A", 0, 0 },
|
||||
new Object[] { STRING_L4, "CD", 0, 2 },
|
||||
new Object[] { STRING_L4, "A", 2, -1 },
|
||||
new Object[] { STRING_L4, "ABCDE", 0, -1 },
|
||||
new Object[] { STRING_LLONG, "ABCDEFGH", 0, 0 },
|
||||
new Object[] { STRING_LLONG, "DEFGH", 0, 3 },
|
||||
new Object[] { STRING_LLONG, "A", 0, 0 },
|
||||
new Object[] { STRING_LLONG, "GHI", 0, -1 },
|
||||
new Object[] { STRING_U1, "\uFF21", 0, 0 },
|
||||
new Object[] { STRING_U1, "\uFF21A", 0, -1 },
|
||||
new Object[] { STRING_U2, "\uFF21\uFF22", 0, 0 },
|
||||
new Object[] { STRING_U2, "\uFF22", 0, 1 },
|
||||
new Object[] { STRING_U2, "\uFF21", 1, -1 },
|
||||
new Object[] { STRING_M12, "\uFF21A", 0, 0 },
|
||||
new Object[] { STRING_M12, "A", 1, 1 },
|
||||
new Object[] { STRING_M12, "\uFF21A", 1, -1 },
|
||||
new Object[] { STRING_M12, "\uFF21", 0, 0 },
|
||||
new Object[] { STRING_M11, "A\uFF21", 0, 0 },
|
||||
new Object[] { STRING_M11, "\uFF21", 1, 1 },
|
||||
new Object[] { STRING_M11, "A\uFF21", 1, -1 },
|
||||
new Object[] { STRING_M11, "A\uFF21A", 0, -1 },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
|
||||
0, 0 },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
|
||||
1, -1 },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
|
||||
1, 1 },
|
||||
new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21\uFF22",
|
||||
4, 4 },
|
||||
new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21\uFF22",
|
||||
7, -1 }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider4")
|
||||
public void testIndexOf(String str, String anotherString, int fromIndex,
|
||||
int expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.indexOf(anotherString, fromIndex),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).indexOf(%s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(anotherString),
|
||||
fromIndex, source));
|
||||
});
|
||||
}
|
||||
}
|
||||
64
test/jdk/java/lang/String/CompactString/Intern.java
Normal file
64
test/jdk/java/lang/String/CompactString/Intern.java
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.intern.
|
||||
* @run testng/othervm -XX:+CompactStrings Intern
|
||||
* @run testng/othervm -XX:-CompactStrings Intern
|
||||
*/
|
||||
|
||||
public class Intern extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, "" },
|
||||
new Object[] { STRING_L1, "A" },
|
||||
new Object[] { STRING_LLONG, "ABCDEFGH" },
|
||||
new Object[] { STRING_U1, "\uFF21" },
|
||||
new Object[] { STRING_U2, "\uFF21\uFF22" },
|
||||
new Object[] { STRING_M12, "\uFF21A" },
|
||||
new Object[] { STRING_M11, "A\uFF21" },
|
||||
new Object[] { STRING_MDUPLICATE1,
|
||||
"\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A" }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testIntern(String str, String expected) {
|
||||
map.get(str).forEach(
|
||||
(source, data) -> {
|
||||
assertTrue(data.intern() == expected, String.format(
|
||||
"testing String(%s).intern(), source : %s, ",
|
||||
escapeNonASCIIs(data), source));
|
||||
});
|
||||
}
|
||||
}
|
||||
225
test/jdk/java/lang/String/CompactString/LastIndexOf.java
Normal file
225
test/jdk/java/lang/String/CompactString/LastIndexOf.java
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.lastIndexOf.
|
||||
* @run testng/othervm -XX:+CompactStrings LastIndexOf
|
||||
* @run testng/othervm -XX:-CompactStrings LastIndexOf
|
||||
*/
|
||||
|
||||
public class LastIndexOf extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, (int) 'A', -1 },
|
||||
new Object[] { STRING_L1, (int) 'A', 0 },
|
||||
new Object[] { STRING_L2, (int) 'A', 0 },
|
||||
new Object[] { STRING_L2, (int) 'B', 1 },
|
||||
new Object[] { STRING_L4, (int) 'A', 0 },
|
||||
new Object[] { STRING_L4, (int) 'D', 3 },
|
||||
new Object[] { STRING_LLONG, (int) 'A', 0 },
|
||||
new Object[] { STRING_LLONG, (int) 'H', 7 },
|
||||
new Object[] { STRING_U1, (int) '\uFF21', 0 },
|
||||
new Object[] { STRING_U1, (int) 'B', -1 },
|
||||
new Object[] { STRING_U2, (int) '\uFF21', 0 },
|
||||
new Object[] { STRING_U2, (int) '\uFF22', 1 },
|
||||
new Object[] { STRING_M12, (int) '\uFF21', 0 },
|
||||
new Object[] { STRING_M12, (int) 'A', 1 },
|
||||
new Object[] { STRING_M11, (int) 'A', 0 },
|
||||
new Object[] { STRING_M11, (int) '\uFF21', 1 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 9 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 8 },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
Character.toCodePoint('\uD801', '\uDC01'), 2 }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testLastIndexOf(String str, int ch, int expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.lastIndexOf(ch),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).lastIndexOf(%d), source : %s, ",
|
||||
escapeNonASCIIs(data), ch, source));
|
||||
});
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider2() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, (int) 'A', 0, -1 },
|
||||
new Object[] { STRING_L1, (int) 'A', 0, 0 },
|
||||
new Object[] { STRING_L1, (int) 'A', 1, 0 },
|
||||
new Object[] { STRING_L2, (int) 'A', 0, 0 },
|
||||
new Object[] { STRING_L2, (int) 'B', 1, 1 },
|
||||
new Object[] { STRING_L2, (int) 'B', 2, 1 },
|
||||
new Object[] { STRING_L4, (int) 'A', 0, 0 },
|
||||
new Object[] { STRING_L4, (int) 'C', 2, 2 },
|
||||
new Object[] { STRING_L4, (int) 'C', 1, -1 },
|
||||
new Object[] { STRING_LLONG, (int) 'A', 0, 0 },
|
||||
new Object[] { STRING_LLONG, (int) 'H', 7, 7 },
|
||||
new Object[] { STRING_LLONG, (int) 'H', 6, -1 },
|
||||
new Object[] { STRING_U1, (int) '\uFF21', 0, 0 },
|
||||
new Object[] { STRING_U1, (int) '\uFF21', 7, 0 },
|
||||
new Object[] { STRING_U2, (int) '\uFF21', 0, 0 },
|
||||
new Object[] { STRING_U2, (int) '\uFF22', 0, -1 },
|
||||
new Object[] { STRING_M12, (int) '\uFF21', 0, 0 },
|
||||
new Object[] { STRING_M12, (int) 'A', 1, 1 },
|
||||
new Object[] { STRING_M12, (int) 'A', 0, -1 },
|
||||
new Object[] { STRING_M11, (int) 'A', 0, 0 },
|
||||
new Object[] { STRING_M11, (int) '\uFF21', 1, 1 },
|
||||
new Object[] { STRING_M11, (int) '\uFF21', 0, -1 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 5, 4 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 6, 6 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 5, 5 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 6, 5 }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider2")
|
||||
public void testLastIndexOf(String str, int ch, int fromIndex, int expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.lastIndexOf(ch, fromIndex),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).lastIndexOf(%d, %d), source : %s, ",
|
||||
escapeNonASCIIs(data), ch,
|
||||
fromIndex, source));
|
||||
});
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider3() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, "A", -1 },
|
||||
new Object[] { STRING_L1, "A", 0 },
|
||||
new Object[] { STRING_L1, "AB", -1 },
|
||||
|
||||
new Object[] { STRING_L2, "AB", 0 },
|
||||
new Object[] { STRING_L2, "B", 1 },
|
||||
new Object[] { STRING_L4, "ABCD", 0 },
|
||||
new Object[] { STRING_L4, "B", 1 },
|
||||
new Object[] { STRING_LLONG, "ABCD", 0 },
|
||||
new Object[] { STRING_LLONG, "GH", 6 },
|
||||
new Object[] { STRING_U1, "\uFF21", 0 },
|
||||
new Object[] { STRING_U1, "\uFF22", -1 },
|
||||
new Object[] { STRING_U2, "\uFF21\uFF22", 0 },
|
||||
new Object[] { STRING_U2, "\uFF22", 1 },
|
||||
new Object[] { STRING_M12, "\uFF21A", 0 },
|
||||
new Object[] { STRING_M12, "A", 1 },
|
||||
new Object[] { STRING_M11, "A\uFF21", 0 },
|
||||
new Object[] { STRING_M11, "\uFF21", 1 },
|
||||
new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21\uFF22", 6 },
|
||||
new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22", 8 }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider3")
|
||||
public void testLastIndexOf(String str, String anotherString, int expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.lastIndexOf(anotherString),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).lastIndexOf(%s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(anotherString),
|
||||
source));
|
||||
});
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider4() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, "A", 0, -1 },
|
||||
new Object[] { STRING_L2, "AB", 0, 0 },
|
||||
|
||||
new Object[] { STRING_L1, "AB", -1, -1 },
|
||||
|
||||
new Object[] { STRING_L2, "B", 1, 1 },
|
||||
new Object[] { STRING_L2, "B", 0, -1 },
|
||||
new Object[] { STRING_L4, "ABC", 3, 0 },
|
||||
new Object[] { STRING_L4, "ABC", 0, 0 },
|
||||
new Object[] { STRING_L4, "ABC", 1, 0 },
|
||||
new Object[] { STRING_L4, "BC", 1, 1 },
|
||||
new Object[] { STRING_L4, "BC", 0, -1 },
|
||||
new Object[] { STRING_LLONG, "ABCDEFGH", 0, 0 },
|
||||
new Object[] { STRING_LLONG, "EFGH", 7, 4 },
|
||||
new Object[] { STRING_LLONG, "EFGH", 3, -1 },
|
||||
new Object[] { STRING_U1, "\uFF21", 0, 0 },
|
||||
new Object[] { STRING_U1, "\uFF21", 7, 0 },
|
||||
new Object[] { STRING_U2, "\uFF21\uFF22", 0, 0 },
|
||||
new Object[] { STRING_U2, "\uFF21\uFF22", 1, 0 },
|
||||
new Object[] { STRING_M12, "\uFF21A", 0, 0 },
|
||||
new Object[] { STRING_M12, "A", 1, 1 },
|
||||
new Object[] { STRING_M12, "A", 0, -1 },
|
||||
new Object[] { STRING_M11, "A\uFF21", 0, 0 },
|
||||
new Object[] { STRING_M11, "A\uFF21", 1, 0 },
|
||||
new Object[] { STRING_M11, "\uFF21", 0, -1 },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
|
||||
9, 0 },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
|
||||
0, 0 },
|
||||
new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22", 6, 6 },
|
||||
new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21", 6, 6 }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider4")
|
||||
public void testLastIndexOf(String str, String anotherString,
|
||||
int fromIndex, int expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.lastIndexOf(anotherString, fromIndex),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).lastIndexOf(%s, %d), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(anotherString),
|
||||
fromIndex, source));
|
||||
});
|
||||
}
|
||||
}
|
||||
61
test/jdk/java/lang/String/CompactString/Length.java
Normal file
61
test/jdk/java/lang/String/CompactString/Length.java
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.length.
|
||||
* @run testng/othervm -XX:+CompactStrings Length
|
||||
* @run testng/othervm -XX:-CompactStrings Length
|
||||
*/
|
||||
|
||||
public class Length extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, 0 }, new Object[] { STRING_L1, 1 },
|
||||
new Object[] { STRING_L2, 2 },
|
||||
new Object[] { STRING_LLONG, 8 },
|
||||
new Object[] { STRING_U1, 1 }, new Object[] { STRING_U2, 2 },
|
||||
new Object[] { STRING_M12, 2 }, new Object[] { STRING_M11, 2 },
|
||||
new Object[] { STRING_UDUPLICATE, 10 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 6 }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testLength(String str, int expected) {
|
||||
map.get(str).forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(data.length(), expected, String.format(
|
||||
"testing String(%s).length(), source : %s, ",
|
||||
escapeNonASCIIs(data), source));
|
||||
});
|
||||
}
|
||||
}
|
||||
150
test/jdk/java/lang/String/CompactString/MaxSizeUTF16String.java
Normal file
150
test/jdk/java/lang/String/CompactString/MaxSizeUTF16String.java
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 2025, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559 8321180
|
||||
* @summary Tests Compact String for maximum size strings
|
||||
* @requires os.maxMemory >= 8g & vm.bits == 64
|
||||
* @requires vm.flagless
|
||||
* @run junit/othervm/timeout=480 -XX:+CompactStrings -Xmx8g MaxSizeUTF16String
|
||||
* @run junit/othervm/timeout=480 -XX:-CompactStrings -Xmx8g MaxSizeUTF16String
|
||||
* @run junit/othervm/timeout=480 -Xcomp -Xmx8g MaxSizeUTF16String
|
||||
*/
|
||||
|
||||
public class MaxSizeUTF16String {
|
||||
|
||||
private final static int MAX_UTF16_STRING_LENGTH = Integer.MAX_VALUE / 2;
|
||||
|
||||
private final static String EXPECTED_OOME_MESSAGE = "UTF16 String size is";
|
||||
private final static String EXPECTED_VM_LIMIT_MESSAGE = "Requested array size exceeds VM limit";
|
||||
private final static String UNEXPECTED_JAVA_HEAP_SPACE = "Java heap space";
|
||||
|
||||
// Create a large UTF-8 byte array with a single non-latin1 character
|
||||
private static byte[] generateUTF8Data(int byteSize) {
|
||||
byte[] nonAscii = "\u0100".getBytes(StandardCharsets.UTF_8);
|
||||
byte[] arr = new byte[byteSize];
|
||||
System.arraycopy(nonAscii, 0, arr, 0, nonAscii.length); // non-latin1 at start
|
||||
return arr;
|
||||
}
|
||||
|
||||
// Create a large char array with a single non-latin1 character
|
||||
private static char[] generateCharData(int size) {
|
||||
char[] nonAscii = "\u0100".toCharArray();
|
||||
char[] arr = new char[size];
|
||||
System.arraycopy(nonAscii, 0, arr, 0, nonAscii.length); // non-latin1 at start
|
||||
return arr;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxUTF8() {
|
||||
// Overly large UTF-8 data with 1 non-latin1 char
|
||||
final byte[] large_utf8_bytes = generateUTF8Data(MAX_UTF16_STRING_LENGTH + 1);
|
||||
int[] sizes = new int[] {
|
||||
MAX_UTF16_STRING_LENGTH + 1,
|
||||
MAX_UTF16_STRING_LENGTH,
|
||||
MAX_UTF16_STRING_LENGTH - 1};
|
||||
for (int size : sizes) {
|
||||
System.err.println("Checking max UTF16 string len: " + size);
|
||||
try {
|
||||
// Use only part of the UTF-8 byte array
|
||||
new String(large_utf8_bytes, 0, size, StandardCharsets.UTF_8);
|
||||
if (size >= MAX_UTF16_STRING_LENGTH) {
|
||||
fail("Expected OutOfMemoryError with message prefix: " + EXPECTED_OOME_MESSAGE);
|
||||
}
|
||||
} catch (OutOfMemoryError ex) {
|
||||
if (ex.getMessage().equals(UNEXPECTED_JAVA_HEAP_SPACE)) {
|
||||
// Insufficient heap size
|
||||
throw ex;
|
||||
}
|
||||
if (!ex.getMessage().startsWith(EXPECTED_OOME_MESSAGE) &&
|
||||
!ex.getMessage().startsWith(EXPECTED_VM_LIMIT_MESSAGE)) {
|
||||
fail("Failed: Not the OutOfMemoryError expected", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxCharArray() {
|
||||
// Overly large UTF-8 data with 1 non-latin1 char
|
||||
final char[] large_char_array = generateCharData(MAX_UTF16_STRING_LENGTH + 1);
|
||||
int[] sizes = new int[]{
|
||||
MAX_UTF16_STRING_LENGTH + 1,
|
||||
MAX_UTF16_STRING_LENGTH,
|
||||
MAX_UTF16_STRING_LENGTH - 1};
|
||||
for (int size : sizes) {
|
||||
System.err.println("Checking max UTF16 string len: " + size);
|
||||
try {
|
||||
// Large char array with 1 non-latin1 char
|
||||
new String(large_char_array, 0, size);
|
||||
if (size >= MAX_UTF16_STRING_LENGTH) {
|
||||
fail("Expected OutOfMemoryError with message prefix: " + EXPECTED_OOME_MESSAGE);
|
||||
}
|
||||
} catch (OutOfMemoryError ex) {
|
||||
if (ex.getMessage().equals(UNEXPECTED_JAVA_HEAP_SPACE)) {
|
||||
// Insufficient heap size
|
||||
throw ex;
|
||||
}
|
||||
if (!ex.getMessage().startsWith(EXPECTED_OOME_MESSAGE) &&
|
||||
!ex.getMessage().startsWith(EXPECTED_VM_LIMIT_MESSAGE)) {
|
||||
throw new RuntimeException("Wrong exception message: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that UTF-8 of too large strings throws OOME, (not NegativeArraySizeException).
|
||||
*/
|
||||
@Test
|
||||
public void testMaxUTF8_UTF16Encode() {
|
||||
String s = "\uFFFF";
|
||||
final byte[] bytes1 = s.getBytes(StandardCharsets.UTF_8);
|
||||
assertEquals(3, bytes1.length, "UTF_8 encoded length of 0xffff");
|
||||
|
||||
int min = Integer.MAX_VALUE / bytes1.length - 1;
|
||||
int max = min + 3;
|
||||
|
||||
// String of size min can be UTF_8 encoded.
|
||||
System.out.println("testing size: " + min);
|
||||
String s1 = s.repeat(min);
|
||||
byte[] bytes = s1.getBytes(StandardCharsets.UTF_8);
|
||||
int remaining = Integer.MAX_VALUE - bytes.length;
|
||||
assertTrue(remaining >= bytes1.length, "remainder too large: " + remaining);
|
||||
|
||||
// Strings of size min+1...min+2, throw OOME
|
||||
// The resulting byte array would exceed implementation limits
|
||||
for (int count = min + 1; count < max; count++) {
|
||||
System.out.println("testing size: " + count);
|
||||
final String s2 = s.repeat(count);
|
||||
OutOfMemoryError ex = assertThrows(OutOfMemoryError.class, () -> s2.getBytes(StandardCharsets.UTF_8));
|
||||
ex.printStackTrace();
|
||||
};
|
||||
}
|
||||
}
|
||||
75
test/jdk/java/lang/String/CompactString/NegativeSize.java
Normal file
75
test/jdk/java/lang/String/CompactString/NegativeSize.java
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String for negative size.
|
||||
* @requires vm.bits == 64 & os.maxMemory >= 4G
|
||||
* @run main/othervm -XX:+CompactStrings -Xmx4g NegativeSize
|
||||
* @run main/othervm -XX:-CompactStrings -Xmx4g NegativeSize
|
||||
*/
|
||||
|
||||
// In Java8: java.lang.OutOfMemoryError: Java heap space
|
||||
// In Java9+: was java.lang.NegativeArraySizeException: -1894967266
|
||||
public class NegativeSize {
|
||||
|
||||
static byte[] generateData() {
|
||||
int asciisize = 1_200_000_000;
|
||||
byte[] nonAscii = "非アスキー".getBytes();
|
||||
int nonAsciiSize = nonAscii.length;
|
||||
// 1 GB
|
||||
byte[] arr = new byte[asciisize + nonAsciiSize];
|
||||
for (int i=0; i<asciisize; ++i) {
|
||||
arr[i] = (byte)('0' + (i % 40));
|
||||
}
|
||||
for(int i=0; i<nonAsciiSize; ++i) {
|
||||
arr[i + asciisize] = nonAscii[i];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
try {
|
||||
byte[] largeBytes = generateData();
|
||||
String inStr = new String(largeBytes, StandardCharsets.UTF_8);
|
||||
System.out.println(inStr.length());
|
||||
System.out.println(inStr.substring(1_200_000_000));
|
||||
} catch (OutOfMemoryError ex) {
|
||||
if (ex.getMessage().startsWith("UTF16 String size is")) {
|
||||
System.out.println("Succeeded with OutOfMemoryError");
|
||||
} else {
|
||||
throw new RuntimeException("Failed: Not the OutOfMemoryError expected", ex);
|
||||
}
|
||||
} catch (NegativeArraySizeException ex) {
|
||||
throw new RuntimeException("Failed: Expected OutOfMemoryError", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
106
test/jdk/java/lang/String/CompactString/Numbers.java
Normal file
106
test/jdk/java/lang/String/CompactString/Numbers.java
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is testing
|
||||
* Integer/Long's methods related to String.
|
||||
* @run testng/othervm -XX:+CompactStrings Numbers
|
||||
* @run testng/othervm -XX:-CompactStrings Numbers
|
||||
*/
|
||||
|
||||
public class Numbers {
|
||||
|
||||
/*
|
||||
* Data provider for testIntegerLong
|
||||
*
|
||||
* @return input parameter for testIntegerLong
|
||||
*/
|
||||
@DataProvider
|
||||
public Object[][] numbers() {
|
||||
return new Object[][] {
|
||||
{ Integer.toBinaryString(Integer.MAX_VALUE),
|
||||
"1111111111111111111111111111111" },
|
||||
{ Integer.toBinaryString(Integer.MIN_VALUE),
|
||||
"10000000000000000000000000000000" },
|
||||
{ Integer.toBinaryString(7), "111" },
|
||||
{ Integer.toBinaryString(0), "0" },
|
||||
{ Integer.toOctalString(Integer.MAX_VALUE), "17777777777" },
|
||||
{ Integer.toOctalString(Integer.MIN_VALUE), "20000000000" },
|
||||
{ Integer.toOctalString(9), "11" },
|
||||
{ Integer.toOctalString(0), "0" },
|
||||
{ Integer.toHexString(Integer.MAX_VALUE), "7fffffff" },
|
||||
{ Integer.toHexString(Integer.MIN_VALUE), "80000000" },
|
||||
{ Integer.toHexString(17), "11" },
|
||||
{ Integer.toHexString(0), "0" },
|
||||
{ Integer.toString(Integer.MAX_VALUE, 2),
|
||||
"1111111111111111111111111111111" },
|
||||
{ Integer.toString(Integer.MIN_VALUE, 2),
|
||||
"-10000000000000000000000000000000" },
|
||||
{ Integer.toString(7, 2), "111" },
|
||||
{ Integer.toString(0, 2), "0" },
|
||||
{ Integer.toString(Integer.MAX_VALUE, 8), "17777777777" },
|
||||
{ Integer.toString(Integer.MIN_VALUE, 8), "-20000000000" },
|
||||
{ Integer.toString(9, 8), "11" },
|
||||
{ Integer.toString(Integer.MAX_VALUE, 16), "7fffffff" },
|
||||
{ Integer.toString(Integer.MIN_VALUE, 16), "-80000000" },
|
||||
{ Integer.toString(17, 16), "11" },
|
||||
{ Long.toBinaryString(Long.MAX_VALUE),
|
||||
"111111111111111111111111111111111111111111111111111111111111111" },
|
||||
{ Long.toBinaryString(Long.MIN_VALUE),
|
||||
"1000000000000000000000000000000000000000000000000000000000000000" },
|
||||
{ Long.toOctalString(Long.MAX_VALUE), "777777777777777777777" },
|
||||
{ Long.toOctalString(Long.MIN_VALUE), "1000000000000000000000" },
|
||||
{ Long.toHexString(Long.MAX_VALUE), "7fffffffffffffff" },
|
||||
{ Long.toHexString(Long.MIN_VALUE), "8000000000000000" },
|
||||
{ Long.toString(Long.MAX_VALUE, 2),
|
||||
"111111111111111111111111111111111111111111111111111111111111111" },
|
||||
{ Long.toString(Long.MIN_VALUE, 2),
|
||||
"-1000000000000000000000000000000000000000000000000000000000000000" },
|
||||
{ Long.toString(Long.MAX_VALUE, 8), "777777777777777777777" },
|
||||
{ Long.toString(Long.MIN_VALUE, 8), "-1000000000000000000000" },
|
||||
{ Long.toString(Long.MAX_VALUE, 16), "7fffffffffffffff" },
|
||||
{ Long.toString(Long.MIN_VALUE, 16), "-8000000000000000" } };
|
||||
}
|
||||
|
||||
/*
|
||||
* test Integer/Long's methods related to String.
|
||||
*
|
||||
* @param res
|
||||
* real result
|
||||
* @param expected
|
||||
* expected result
|
||||
*/
|
||||
@Test(dataProvider = "numbers")
|
||||
public void testIntegerLong(String res, String expected) {
|
||||
assertEquals(res, expected);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.offsetByCodePoints.
|
||||
* @run testng/othervm -XX:+CompactStrings OffsetByCodePoints
|
||||
* @run testng/othervm -XX:-CompactStrings OffsetByCodePoints
|
||||
*/
|
||||
|
||||
public class OffsetByCodePoints extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_SUPPLEMENTARY, 0, 1, 2 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 0, 3, 5 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 1, 1, 2 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 1, 3, 5 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 2, 1, 4 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 2, 2, 5 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 2, 3, 6 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 3, 1, 4 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 3, 2, 5 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 3, 3, 6 }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testOffsetByCodePoints(String str, int index,
|
||||
int codePointOffset, int expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.offsetByCodePoints(index,
|
||||
codePointOffset),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).offsetByCodePoints(%d, %d), source : %s, ",
|
||||
escapeNonASCIIs(data), index,
|
||||
codePointOffset, source));
|
||||
});
|
||||
}
|
||||
}
|
||||
192
test/jdk/java/lang/String/CompactString/RegionMatches.java
Normal file
192
test/jdk/java/lang/String/CompactString/RegionMatches.java
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2024, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Map;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559 8248655 8264544
|
||||
* @summary Tests Compact String. This one is for String.regionMatches.
|
||||
* @run testng/othervm -XX:+CompactStrings RegionMatches
|
||||
* @run testng/othervm -XX:-CompactStrings RegionMatches
|
||||
*/
|
||||
|
||||
public class RegionMatches extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, true, 0, "", 0, 0, true },
|
||||
new Object[] { STRING_EMPTY, true, 0, "", 0, 1, false },
|
||||
new Object[] { STRING_EMPTY, true, 0, "A", 0, 0, true },
|
||||
new Object[] { STRING_EMPTY, true, 0, "", 0, 0, true },
|
||||
new Object[] { STRING_EMPTY, true, 0, "", 0, 1, false },
|
||||
new Object[] { STRING_L1, false, 0, "a", 0, 1, false },
|
||||
new Object[] { STRING_L1, false, 0, "BA", 1, 1, true },
|
||||
new Object[] { STRING_L1, false, 0, "Ba", 1, 1, false },
|
||||
new Object[] { STRING_L1, true, 0, "a", 0, 1, true },
|
||||
new Object[] { STRING_L1, true, 0, "BA", 1, 1, true },
|
||||
new Object[] { STRING_L1, true, 0, "Ba", 1, 1, true },
|
||||
new Object[] { STRING_L2, true, 1, "b", 0, 1, true },
|
||||
new Object[] { STRING_L2, true, 1, "B", 0, 1, true },
|
||||
new Object[] { STRING_L2, true, 0, "xaBc", 1, 2, true },
|
||||
new Object[] { STRING_L2, false, 0, "AB", 0, 2, true },
|
||||
new Object[] { STRING_L2, false, 0, "Ab", 0, 2, false },
|
||||
new Object[] { STRING_L2, false, 1, "BAB", 2, 1, true },
|
||||
new Object[] { STRING_LLONG, true, 1, "bCdEF", 0, 5, true },
|
||||
new Object[] { STRING_LLONG, false, 2, "CDEFG", 0, 5, true },
|
||||
new Object[] { STRING_LLONG, true, 2, "CDEFg", 0, 5, true },
|
||||
new Object[] { STRING_U1, true, 0, "\uFF41", 0, 1, true },
|
||||
new Object[] { STRING_U1, false, 0, "\uFF41", 0, 1, false },
|
||||
new Object[] { STRING_MDUPLICATE1, true, 0, "\uFF41a\uFF41", 0,
|
||||
3, true },
|
||||
new Object[] { STRING_MDUPLICATE1, false, 0, "\uFF21a\uFF21",
|
||||
0, 3, false },
|
||||
new Object[] { STRING_SUPPLEMENTARY, true, 0, "\uD801\uDC28\uD801\uDC29",
|
||||
0, 4, true },
|
||||
new Object[] { STRING_SUPPLEMENTARY, true, 1, "\uDC00\uD801",
|
||||
0, 2, true },
|
||||
new Object[] { STRING_SUPPLEMENTARY, true, 1, "\uDC28",
|
||||
0, 1, false },
|
||||
new Object[] { STRING_SUPPLEMENTARY, true, 4, "\uFF21", 0, 1,
|
||||
true },
|
||||
new Object[] { STRING_SUPPLEMENTARY, true, 5, "A", 0, 1, true },
|
||||
new Object[] { STRING_SUPPLEMENTARY, true, 0, "\uD802\uDC00\uD801\uDC01\uFF21A", 0, 2, false },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, false, 0,
|
||||
"\uD801\uDC28\uD801\uDC29", 0, 4, true },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, true, 0,
|
||||
"\uD801\uDC00\uD801\uDC01", 0, 4, true },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, true, 1,
|
||||
"\uDC28\uD801", 0, 2, true },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, true, 1,
|
||||
"\uDC00", 0, 1, false },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, true, 1,
|
||||
"\uDC00\uD801", 0, 2, false },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, true, 4,
|
||||
"\uFF21", 0, 1, true },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, false, 4,
|
||||
"\uFF21", 0, 1, false },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, false, 4,
|
||||
"\uFF41", 0, 1, true },
|
||||
// Turkish I with dot
|
||||
new Object[] { "\u0130", false, 0, "i", 0, 1, false },
|
||||
new Object[] { "\u0130", true, 0, "i", 0, 1, true },
|
||||
new Object[] { "\u0130", false, 0, "I", 0, 1, false },
|
||||
new Object[] { "\u0130", true, 0, "I", 0, 1, true },
|
||||
// i without dot
|
||||
new Object[] { "\u0131", false, 0, "i", 0, 1, false },
|
||||
new Object[] { "\u0131", true, 0, "i", 0, 1, true },
|
||||
new Object[] { "\u0131", false, 0, "I", 0, 1, false },
|
||||
new Object[] { "\u0131", true, 0, "I", 0, 1, true },
|
||||
// Exhaustive list of 1-char latin1 strings that match
|
||||
// case-insensitively:
|
||||
// for (char c1 = 0; c1 < 255; c1++) {
|
||||
// for (char c2 = c; c2 < 255; c2++) {
|
||||
// if (c1 == c2) continue;
|
||||
// if (String.valueOf(c1).regionMatches(true, 0, String.valueOf(c2), 0, 1)) {
|
||||
// System.out.println(" new Object[] { \"\\u00"
|
||||
// + Integer.toHexString((int)c) + "\", true, 0, \"\\u00"
|
||||
// + Integer.toHexString((int)c2) + "\", 0, 1, true },");
|
||||
// }}}
|
||||
new Object[] { "\u0041", true, 0, "\u0061", 0, 1, true },
|
||||
new Object[] { "\u0042", true, 0, "\u0062", 0, 1, true },
|
||||
new Object[] { "\u0043", true, 0, "\u0063", 0, 1, true },
|
||||
new Object[] { "\u0044", true, 0, "\u0064", 0, 1, true },
|
||||
new Object[] { "\u0045", true, 0, "\u0065", 0, 1, true },
|
||||
new Object[] { "\u0046", true, 0, "\u0066", 0, 1, true },
|
||||
new Object[] { "\u0047", true, 0, "\u0067", 0, 1, true },
|
||||
new Object[] { "\u0048", true, 0, "\u0068", 0, 1, true },
|
||||
new Object[] { "\u0049", true, 0, "\u0069", 0, 1, true },
|
||||
new Object[] { "\u004a", true, 0, "\u006a", 0, 1, true },
|
||||
new Object[] { "\u004b", true, 0, "\u006b", 0, 1, true },
|
||||
new Object[] { "\u004c", true, 0, "\u006c", 0, 1, true },
|
||||
new Object[] { "\u004d", true, 0, "\u006d", 0, 1, true },
|
||||
new Object[] { "\u004e", true, 0, "\u006e", 0, 1, true },
|
||||
new Object[] { "\u004f", true, 0, "\u006f", 0, 1, true },
|
||||
new Object[] { "\u0050", true, 0, "\u0070", 0, 1, true },
|
||||
new Object[] { "\u0051", true, 0, "\u0071", 0, 1, true },
|
||||
new Object[] { "\u0052", true, 0, "\u0072", 0, 1, true },
|
||||
new Object[] { "\u0053", true, 0, "\u0073", 0, 1, true },
|
||||
new Object[] { "\u0054", true, 0, "\u0074", 0, 1, true },
|
||||
new Object[] { "\u0055", true, 0, "\u0075", 0, 1, true },
|
||||
new Object[] { "\u0056", true, 0, "\u0076", 0, 1, true },
|
||||
new Object[] { "\u0057", true, 0, "\u0077", 0, 1, true },
|
||||
new Object[] { "\u0058", true, 0, "\u0078", 0, 1, true },
|
||||
new Object[] { "\u0059", true, 0, "\u0079", 0, 1, true },
|
||||
new Object[] { "\u005a", true, 0, "\u007a", 0, 1, true },
|
||||
new Object[] { "\u00c0", true, 0, "\u00e0", 0, 1, true },
|
||||
new Object[] { "\u00c1", true, 0, "\u00e1", 0, 1, true },
|
||||
new Object[] { "\u00c2", true, 0, "\u00e2", 0, 1, true },
|
||||
new Object[] { "\u00c3", true, 0, "\u00e3", 0, 1, true },
|
||||
new Object[] { "\u00c4", true, 0, "\u00e4", 0, 1, true },
|
||||
new Object[] { "\u00c5", true, 0, "\u00e5", 0, 1, true },
|
||||
new Object[] { "\u00c6", true, 0, "\u00e6", 0, 1, true },
|
||||
new Object[] { "\u00c7", true, 0, "\u00e7", 0, 1, true },
|
||||
new Object[] { "\u00c8", true, 0, "\u00e8", 0, 1, true },
|
||||
new Object[] { "\u00c9", true, 0, "\u00e9", 0, 1, true },
|
||||
new Object[] { "\u00ca", true, 0, "\u00ea", 0, 1, true },
|
||||
new Object[] { "\u00cb", true, 0, "\u00eb", 0, 1, true },
|
||||
new Object[] { "\u00cc", true, 0, "\u00ec", 0, 1, true },
|
||||
new Object[] { "\u00cd", true, 0, "\u00ed", 0, 1, true },
|
||||
new Object[] { "\u00ce", true, 0, "\u00ee", 0, 1, true },
|
||||
new Object[] { "\u00cf", true, 0, "\u00ef", 0, 1, true },
|
||||
new Object[] { "\u00d0", true, 0, "\u00f0", 0, 1, true },
|
||||
new Object[] { "\u00d1", true, 0, "\u00f1", 0, 1, true },
|
||||
new Object[] { "\u00d2", true, 0, "\u00f2", 0, 1, true },
|
||||
new Object[] { "\u00d3", true, 0, "\u00f3", 0, 1, true },
|
||||
new Object[] { "\u00d4", true, 0, "\u00f4", 0, 1, true },
|
||||
new Object[] { "\u00d5", true, 0, "\u00f5", 0, 1, true },
|
||||
new Object[] { "\u00d6", true, 0, "\u00f6", 0, 1, true },
|
||||
new Object[] { "\u00d8", true, 0, "\u00f8", 0, 1, true },
|
||||
new Object[] { "\u00d9", true, 0, "\u00f9", 0, 1, true },
|
||||
new Object[] { "\u00da", true, 0, "\u00fa", 0, 1, true },
|
||||
new Object[] { "\u00db", true, 0, "\u00fb", 0, 1, true },
|
||||
new Object[] { "\u00dc", true, 0, "\u00fc", 0, 1, true },
|
||||
new Object[] { "\u00dd", true, 0, "\u00fd", 0, 1, true },
|
||||
new Object[] { "\u00de", true, 0, "\u00fe", 0, 1, true },
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testRegionMatches(String str, boolean ignoreCase, int toffset,
|
||||
String other, int ooffset, int len, boolean expected) {
|
||||
map.getOrDefault(str, Map.of(str, str)) // Allow data provider to test adhoc strings
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.regionMatches(ignoreCase, toffset,
|
||||
other, ooffset, len),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).regionMatches(%b, %d, %s, %d, %d), source : %s, ",
|
||||
escapeNonASCIIs(data), ignoreCase,
|
||||
toffset, escapeNonASCIIs(other),
|
||||
ooffset, len, source));
|
||||
});
|
||||
}
|
||||
}
|
||||
117
test/jdk/java/lang/String/CompactString/Replace.java
Normal file
117
test/jdk/java/lang/String/CompactString/Replace.java
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.replace.
|
||||
* @run testng/othervm -XX:+CompactStrings Replace
|
||||
* @run testng/othervm -XX:-CompactStrings Replace
|
||||
*/
|
||||
|
||||
public class Replace extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_L1, 'A', 'B', "B" },
|
||||
new Object[] { STRING_L1, 'A', 'A', "A" },
|
||||
new Object[] { STRING_L1, 'A', '\uFF21', "\uFF21" },
|
||||
new Object[] { STRING_L2, 'A', 'B', "BB" },
|
||||
new Object[] { STRING_L2, 'B', 'A', "AA" },
|
||||
new Object[] { STRING_L2, 'C', 'A', "AB" },
|
||||
new Object[] { STRING_L2, 'B', '\uFF21', "A\uFF21" },
|
||||
new Object[] { STRING_U1, '\uFF21', 'A', "A" },
|
||||
new Object[] { STRING_U1, '\uFF22', 'A', "\uFF21" },
|
||||
new Object[] { STRING_U2, '\uFF22', 'A', "\uFF21A" },
|
||||
new Object[] { STRING_M12, 'A', '\uFF21', "\uFF21\uFF21" },
|
||||
new Object[] { STRING_M11, '\uFF21', 'A', "AA" },
|
||||
new Object[] { STRING_UDUPLICATE, '\uFF21', 'A',
|
||||
"A\uFF22A\uFF22A\uFF22A\uFF22A\uFF22" },
|
||||
new Object[] { STRING_MDUPLICATE1, '\uFF21', 'A', "AAAAAAAAAA" },
|
||||
new Object[] { STRING_MDUPLICATE1, 'A', '\uFF21',
|
||||
"\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21" }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testReplace(String str, char oldChar, char newChar,
|
||||
String expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.replace(oldChar, newChar),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).replace(%s, %s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCII(oldChar),
|
||||
escapeNonASCII(newChar), source));
|
||||
});
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider2() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, "", "ABC", "ABC" },
|
||||
new Object[] { STRING_EMPTY, "", "", "" },
|
||||
new Object[] { STRING_L1, "A", "B", "B" },
|
||||
new Object[] { STRING_L1, "A", "A", "A" },
|
||||
new Object[] { STRING_L2, "B", "\uFF21", "A\uFF21" },
|
||||
new Object[] { STRING_LLONG, "BCD", "\uFF21", "A\uFF21EFGH" },
|
||||
new Object[] { STRING_U1, "\uFF21", "A", "A" },
|
||||
new Object[] { STRING_U1, "\uFF21", "A\uFF21", "A\uFF21" },
|
||||
new Object[] { STRING_U2, "\uFF21", "A", "A\uFF22" },
|
||||
new Object[] { STRING_U2, "\uFF22", "A", "\uFF21A" },
|
||||
new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22", "AB",
|
||||
"ABABABABAB" },
|
||||
new Object[] { STRING_MDUPLICATE1, "\uFF21", "A", "AAAAAAAAAA" },
|
||||
new Object[] { STRING_MDUPLICATE1, "A", "\uFF21",
|
||||
"\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21" }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider2")
|
||||
public void testReplace(String str, CharSequence target,
|
||||
CharSequence replacement, String expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.replace(target, replacement),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).replace(%s, %s), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(target.toString()),
|
||||
escapeNonASCIIs(replacement
|
||||
.toString()), source));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2017, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static jdk.test.lib.util.SerializationUtils.*;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.util.SerializationUtils
|
||||
* @summary Tests Compact String. This one is testing String serialization
|
||||
* among -XX:+CompactStrings/-XX:-CompactStrings/LegacyString
|
||||
* @run testng/othervm -XX:+CompactStrings SerializationTest
|
||||
* @run testng/othervm -XX:-CompactStrings SerializationTest
|
||||
*/
|
||||
|
||||
public class SerializationTest {
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
// every byte array is serialized from corresponding String object
|
||||
// by previous JDK(build 1.8.0_45-b14).
|
||||
new Object[] { "", new byte[] { -84, -19, 0, 5, 116, 0, 0 } },
|
||||
new Object[] { "A", new byte[] { -84, -19, 0, 5, 116, 0, 1, 65 } },
|
||||
new Object[] { "AB", new byte[] { -84, -19, 0, 5, 116, 0, 2, 65, 66 } },
|
||||
new Object[] { "abcdefghijk",
|
||||
new byte[] {-84, -19, 0, 5, 116, 0, 11, 97, 98, 99, 100, 101,
|
||||
102, 103, 104, 105, 106, 107 } },
|
||||
new Object[] { "\uff21", new byte[] { -84, -19, 0, 5, 116, 0, 3, -17, -68, -95 } },
|
||||
new Object[] { "\uff21\uff22", new byte[] { -84, -19, 0, 5, 116, 0, 6, -17, -68,
|
||||
-95, -17, -68, -94 } },
|
||||
new Object[] { "\uff21A\uff21A\uff21A\uff21A\uff21A",
|
||||
new byte[] { -84, -19, 0, 5, 116, 0, 20, -17, -68, -95, 65, -17, -68,
|
||||
-95, 65, -17, -68, -95, 65, -17, -68, -95, 65, -17, -68, -95, 65 } },
|
||||
new Object[] { "A\uff21B\uff22C\uff23D\uff24E\uff25F\uff26G\uff27H\uff28",
|
||||
new byte[] { -84, -19, 0, 5, 116, 0, 32, 65, -17, -68, -95, 66, -17, -68,
|
||||
-94, 67, -17, -68, -93, 68, -17, -68, -92, 69, -17, -68, -91, 70, -17,
|
||||
-68, -90, 71, -17, -68, -89, 72, -17, -68, -88 } },
|
||||
new Object[] { "\uff21A\uff22B\uff23C\uff24D\uff25E\uff26F\uff27G\uff28H",
|
||||
new byte[] { -84, -19, 0, 5, 116, 0, 32, -17, -68, -95, 65, -17, -68,
|
||||
-94, 66, -17, -68, -93, 67, -17, -68, -92, 68, -17, -68, -91, 69, -17,
|
||||
-68, -90, 70, -17, -68, -89, 71, -17, -68, -88, 72 } },
|
||||
new Object[] { "\ud801\udc00\ud801\udc01\uff21A",
|
||||
new byte[] { -84, -19, 0, 5, 116, 0, 16, -19, -96, -127, -19, -80, -128,
|
||||
-19, -96, -127, -19, -80, -127, -17, -68, -95, 65 } },
|
||||
new Object[] { "\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22",
|
||||
new byte[] { -84, -19, 0, 5, 116, 0, 30, -17, -68, -95, -17, -68, -94, -17,
|
||||
-68, -95, -17, -68, -94, -17, -68, -95, -17, -68, -94, -17, -68, -95, -17,
|
||||
-68, -94, -17, -68, -95, -17, -68, -94 } } };
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify serialization works between Compact String/Legacy String
|
||||
*/
|
||||
@Test(dataProvider = "provider")
|
||||
public void test(String strContent, byte[] baInJDK8) throws Exception {
|
||||
// Serialize a String object into byte array.
|
||||
byte[] ba = serialize(strContent);
|
||||
assertEquals(ba, baInJDK8);
|
||||
// Deserialize a String object from byte array which is generated by previous JDK(build 1.8.0_45-b14).
|
||||
Object obj = deserialize(ba);
|
||||
assertEquals(obj.getClass(), String.class);
|
||||
assertEquals((String)obj, strContent);
|
||||
}
|
||||
}
|
||||
181
test/jdk/java/lang/String/CompactString/Split.java
Normal file
181
test/jdk/java/lang/String/CompactString/Split.java
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.split.
|
||||
* @run testng/othervm -XX:+CompactStrings Split
|
||||
* @run testng/othervm -XX:-CompactStrings Split
|
||||
*/
|
||||
|
||||
public class Split extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
new Object[] { STRING_L1, "", 0, new String[] { "A" } },
|
||||
new Object[] { STRING_L1, "", 1, new String[] { "A" } },
|
||||
new Object[] { STRING_L1, "", 2, new String[] { "A", "" } },
|
||||
new Object[] { STRING_L1, "A", 0, new String[] {} },
|
||||
new Object[] { STRING_L2, "A", 0, new String[] { "", "B" } },
|
||||
new Object[] { STRING_L2, "B", 0, new String[] { "A" } },
|
||||
new Object[] { STRING_LLONG, "D", 0,
|
||||
new String[] { "ABC", "EFGH" } },
|
||||
new Object[] { STRING_LLONG, "[D]", 0,
|
||||
new String[] { "ABC", "EFGH" } },
|
||||
new Object[] { STRING_LLONG, "CD", 0,
|
||||
new String[] { "AB", "EFGH" } },
|
||||
new Object[] { STRING_LLONG, "DC", 0,
|
||||
new String[] { "ABCDEFGH" } },
|
||||
new Object[] { STRING_LLONG, "[CF]", 0,
|
||||
new String[] { "AB", "DE", "GH" } },
|
||||
new Object[] { STRING_LLONG, "[CF]", 1,
|
||||
new String[] { "ABCDEFGH" } },
|
||||
new Object[] { STRING_LLONG, "[CF]", 2,
|
||||
new String[] { "AB", "DEFGH" } },
|
||||
new Object[] { STRING_LLONG, "[FC]", 0,
|
||||
new String[] { "AB", "DE", "GH" } },
|
||||
new Object[] { STRING_LLONG, "[FC]", 1,
|
||||
new String[] { "ABCDEFGH" } },
|
||||
new Object[] { STRING_LLONG, "[FC]", 2,
|
||||
new String[] { "AB", "DEFGH" } },
|
||||
new Object[] { STRING_U1, "", 0, new String[] { "\uFF21" } },
|
||||
new Object[] { STRING_U1, "", 1, new String[] { "\uFF21" } },
|
||||
new Object[] { STRING_U1, "", 2, new String[] { "\uFF21", "" } },
|
||||
new Object[] { STRING_U1, "\uFF21", 0, new String[] {} },
|
||||
new Object[] { STRING_M12, "\uFF21", 0,
|
||||
new String[] { "", "A" } },
|
||||
new Object[] { STRING_M12, "A", 0, new String[] { "\uFF21" } },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF21",
|
||||
0,
|
||||
new String[] { "", "\uFF22", "\uFF22", "\uFF22",
|
||||
"\uFF22", "\uFF22" } },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF21",
|
||||
2,
|
||||
new String[] { "",
|
||||
"\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22" } },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF21",
|
||||
4,
|
||||
new String[] { "", "\uFF22", "\uFF22",
|
||||
"\uFF22\uFF21\uFF22\uFF21\uFF22" } },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF22",
|
||||
0,
|
||||
new String[] { "\uFF21", "\uFF21", "\uFF21", "\uFF21",
|
||||
"\uFF21" } },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF22",
|
||||
3,
|
||||
new String[] { "\uFF21", "\uFF21",
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22" } },
|
||||
|
||||
new Object[] { STRING_MDUPLICATE1, "\uFF21", 0,
|
||||
new String[] { "", "A", "A", "A", "A", "A" } },
|
||||
new Object[] { STRING_MDUPLICATE1, "\uFF21", 3,
|
||||
new String[] { "", "A", "A\uFF21A\uFF21A\uFF21A" } },
|
||||
new Object[] {
|
||||
STRING_MDUPLICATE1,
|
||||
"A",
|
||||
0,
|
||||
new String[] { "\uFF21", "\uFF21", "\uFF21", "\uFF21",
|
||||
"\uFF21" } },
|
||||
new Object[] {
|
||||
STRING_MDUPLICATE1,
|
||||
"A",
|
||||
4,
|
||||
new String[] { "\uFF21", "\uFF21", "\uFF21",
|
||||
"\uFF21A\uFF21A" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY, "\uD801\uDC01", 0,
|
||||
new String[] { "\uD801\uDC00", "\uFF21A" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY, "\uDC01", 0,
|
||||
new String[] { "\uD801\uDC00\uD801\uDC01\uFF21A" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY, "\uD801\uDC01", 0,
|
||||
new String[] { "\uD801\uDC00", "\uFF21A" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY, "[\uD801\uDC01\uFF21]", 0,
|
||||
new String[] { "\uD801\uDC00", "", "A" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY, "[\uD801\uDC01\uFF21]", 1,
|
||||
new String[] { "\uD801\uDC00\uD801\uDC01\uFF21A" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY, "[\uD801\uDC01\uFF21]", 2,
|
||||
new String[] { "\uD801\uDC00", "\uFF21A" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY, "[\uFF21\uD801\uDC01]", 0,
|
||||
new String[] { "\uD801\uDC00", "", "A" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY, "[\uFF21\uD801\uDC01]", 1,
|
||||
new String[] { "\uD801\uDC00\uD801\uDC01\uFF21A" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY, "[\uFF21\uD801\uDC01]", 2,
|
||||
new String[] { "\uD801\uDC00", "\uFF21A" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, "\uDC01", 0,
|
||||
new String[] { "\uD801\uDC28\uD801\uDC29\uFF41a" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, "\uD801\uDC29",
|
||||
0, new String[] { "\uD801\uDC28", "\uFF41a" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
|
||||
"[\uD801\uDC29\uFF41]", 0,
|
||||
new String[] { "\uD801\uDC28", "", "a" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
|
||||
"[\uD801\uDC29\uFF41]", 1,
|
||||
new String[] { "\uD801\uDC28\uD801\uDC29\uFF41a" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
|
||||
"[\uD801\uDC29\uFF41]", 2,
|
||||
new String[] { "\uD801\uDC28", "\uFF41a" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
|
||||
"[\uFF41\uD801\uDC29]", 0,
|
||||
new String[] { "\uD801\uDC28", "", "a" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
|
||||
"[\uFF41\uD801\uDC29]", 1,
|
||||
new String[] { "\uD801\uDC28\uD801\uDC29\uFF41a" } },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
|
||||
"[\uFF41\uD801\uDC29]", 2,
|
||||
new String[] { "\uD801\uDC28", "\uFF41a" } }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testSplit(String str, String regex, int limit, String[] expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertTrue(
|
||||
Arrays.equals(data.split(regex, limit),
|
||||
expected),
|
||||
String.format(
|
||||
"testing String(%s).split(%s, %d), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(regex), limit,
|
||||
source));
|
||||
});
|
||||
}
|
||||
}
|
||||
109
test/jdk/java/lang/String/CompactString/StartsWith.java
Normal file
109
test/jdk/java/lang/String/CompactString/StartsWith.java
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.startsWith.
|
||||
* @run testng/othervm -XX:+CompactStrings StartsWith
|
||||
* @run testng/othervm -XX:-CompactStrings StartsWith
|
||||
*/
|
||||
|
||||
public class StartsWith extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
new Object[] {STRING_EMPTY, "", 0, true},
|
||||
new Object[] {STRING_EMPTY, "A", 0, false},
|
||||
new Object[] {STRING_EMPTY, "", 0, true},
|
||||
new Object[] {STRING_EMPTY, "", -1, false},
|
||||
new Object[] {STRING_L1, "A", 0, true},
|
||||
new Object[] {STRING_L1, "A", -1, false},
|
||||
new Object[] {STRING_L1, "A", 1, false},
|
||||
new Object[] {STRING_L2, "B", 1, true},
|
||||
new Object[] {STRING_L2, "B", 0, false},
|
||||
new Object[] {STRING_L2, "A", 0, true},
|
||||
new Object[] {STRING_L2, "AB", 1, false},
|
||||
new Object[] {STRING_L4, "ABC", 0, true},
|
||||
new Object[] {STRING_LLONG, "ABCDEFGH", 0, true},
|
||||
new Object[] {STRING_LLONG, "ABCDE", 0, true},
|
||||
new Object[] {STRING_LLONG, "CDE", 0, false},
|
||||
new Object[] {STRING_LLONG, "FG", 5, true},
|
||||
new Object[] {STRING_U1, "\uFF21", 0, true},
|
||||
new Object[] {STRING_U1, "", 1, true},
|
||||
new Object[] {STRING_U1, "\uFF21", 0, true},
|
||||
new Object[] {STRING_U1, "A", 0, false},
|
||||
new Object[] {STRING_U2, "\uFF21\uFF22", 0, true},
|
||||
new Object[] {STRING_U2, "\uFF21", 0, true},
|
||||
new Object[] {STRING_U2, "\uFF22", 0, false},
|
||||
new Object[] {STRING_U2, "", 0, true},
|
||||
new Object[] {STRING_M12, "\uFF21", 0, true},
|
||||
new Object[] {STRING_M12, "\uFF21A", 0, true},
|
||||
new Object[] {STRING_M12, "A", 0, false},
|
||||
new Object[] {STRING_M12, "\uFF21A", 0, true},
|
||||
new Object[] {STRING_M12, "A", 1, true},
|
||||
new Object[] {STRING_M11, "A", 0, true},
|
||||
new Object[] {STRING_M11, "A\uFF21", 0, true},
|
||||
new Object[] {STRING_M11, "A\uFF21", 0, true},
|
||||
new Object[] {STRING_M11, "\uFF21", 1, true},
|
||||
new Object[] {STRING_UDUPLICATE,
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
|
||||
0, true},
|
||||
new Object[] {STRING_UDUPLICATE,
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22", 0, true},
|
||||
new Object[] {STRING_UDUPLICATE,
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22", 2, true},
|
||||
new Object[] {STRING_UDUPLICATE,
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22", 5, false},
|
||||
new Object[] {STRING_MDUPLICATE1,
|
||||
"\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A", 0, true},
|
||||
new Object[] {STRING_MDUPLICATE1,
|
||||
"\uFF21A\uFF21A\uFF21A\uFF21A\uFF21", 0, true},
|
||||
new Object[] {STRING_MDUPLICATE1, "A\uFF21A\uFF21A\uFF21A", 1, true},
|
||||
new Object[] {STRING_SUPPLEMENTARY, "\uDC01\uFF21", 3, true},
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testStartsWith(String str, String prefix, int toffset,
|
||||
boolean expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.startsWith(prefix, toffset),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).startsWith(%s, %d), source : %s, ",
|
||||
escapeNonASCIIs(data),
|
||||
escapeNonASCIIs(prefix), toffset,
|
||||
source));
|
||||
});
|
||||
}
|
||||
}
|
||||
84
test/jdk/java/lang/String/CompactString/SubString.java
Normal file
84
test/jdk/java/lang/String/CompactString/SubString.java
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.subString.
|
||||
* @run testng/othervm -XX:+CompactStrings SubString
|
||||
* @run testng/othervm -XX:-CompactStrings SubString
|
||||
*/
|
||||
|
||||
public class SubString extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, 0, 0, "" },
|
||||
new Object[] { STRING_L1, 0, 1, "A" },
|
||||
new Object[] { STRING_L1, 1, 1, "" },
|
||||
new Object[] { STRING_L2, 0, 2, "AB" },
|
||||
new Object[] { STRING_L2, 1, 2, "B" },
|
||||
new Object[] { STRING_LLONG, 0, 8, "ABCDEFGH" },
|
||||
new Object[] { STRING_LLONG, 7, 8, "H" },
|
||||
new Object[] { STRING_LLONG, 8, 8, "" },
|
||||
new Object[] { STRING_LLONG, 3, 7, "DEFG" },
|
||||
new Object[] { STRING_U1, 0, 1, "\uFF21" },
|
||||
new Object[] { STRING_U1, 1, 1, "" },
|
||||
new Object[] { STRING_U1, 0, 0, "" },
|
||||
new Object[] { STRING_U2, 0, 2, "\uFF21\uFF22" },
|
||||
new Object[] { STRING_U2, 1, 2, "\uFF22" },
|
||||
new Object[] { STRING_U2, 2, 2, "" },
|
||||
new Object[] { STRING_U2, 0, 2, "\uFF21\uFF22" },
|
||||
new Object[] { STRING_U2, 1, 2, "\uFF22" },
|
||||
new Object[] { STRING_M12, 1, 2, "A" },
|
||||
new Object[] { STRING_M11, 0, 1, "A" },
|
||||
new Object[] { STRING_M11, 1, 2, "\uFF21" },
|
||||
new Object[] { STRING_UDUPLICATE, 1, 5,
|
||||
"\uFF22\uFF21\uFF22\uFF21" },
|
||||
new Object[] { STRING_MDUPLICATE1, 9, 10, "A" },
|
||||
new Object[] { STRING_MDUPLICATE1, 7, 8, "A" }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testSubstring(String str, int beginIndex, int endIndex,
|
||||
String expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(
|
||||
data.substring(beginIndex, endIndex),
|
||||
expected,
|
||||
String.format(
|
||||
"testing String(%s).substring(%d, %d), source : %s, ",
|
||||
escapeNonASCIIs(data), beginIndex,
|
||||
endIndex, source));
|
||||
});
|
||||
}
|
||||
}
|
||||
67
test/jdk/java/lang/String/CompactString/ToCharArray.java
Normal file
67
test/jdk/java/lang/String/CompactString/ToCharArray.java
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.toCharArray.
|
||||
* @run testng/othervm -XX:+CompactStrings ToCharArray
|
||||
* @run testng/othervm -XX:-CompactStrings ToCharArray
|
||||
*/
|
||||
|
||||
public class ToCharArray extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
new Object[] { STRING_EMPTY, new char[] {} },
|
||||
new Object[] { STRING_L1, new char[] { 'A' } },
|
||||
new Object[] { STRING_L2, new char[] { 'A', 'B' } },
|
||||
new Object[] { STRING_LLONG,
|
||||
new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' } },
|
||||
new Object[] { STRING_U1, new char[] { '\uFF21' } },
|
||||
new Object[] { STRING_U2, new char[] { '\uFF21', '\uFF22' } },
|
||||
new Object[] { STRING_M12, new char[] { '\uFF21', 'A' } },
|
||||
new Object[] { STRING_M11, new char[] { 'A', '\uFF21' } }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testToCharArray(String str, char[] expected) {
|
||||
map.get(str)
|
||||
.forEach(
|
||||
(source, data) -> {
|
||||
assertTrue(
|
||||
Arrays.equals(data.toCharArray(), expected),
|
||||
String.format(
|
||||
"testing String(%s).toCharArray(), source : %s, ",
|
||||
escapeNonASCIIs(data), source));
|
||||
});
|
||||
}
|
||||
}
|
||||
66
test/jdk/java/lang/String/CompactString/ToLowerCase.java
Normal file
66
test/jdk/java/lang/String/CompactString/ToLowerCase.java
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.toLowerCase.
|
||||
* @run testng/othervm -XX:+CompactStrings ToLowerCase
|
||||
* @run testng/othervm -XX:-CompactStrings ToLowerCase
|
||||
*/
|
||||
|
||||
public class ToLowerCase extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
new Object[] { STRING_EMPTY, "" },
|
||||
new Object[] { STRING_L1, "a" },
|
||||
new Object[] { STRING_L2, "ab" },
|
||||
new Object[] { STRING_U1, "\uFF41" },
|
||||
new Object[] { STRING_MDUPLICATE1,
|
||||
"\uFF41a\uFF41a\uFF41a\uFF41a\uFF41a" },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
"\uD801\uDC28\uD801\uDC29\uFF41a" },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
|
||||
"\uD801\uDC28\uD801\uDC29\uFF41a" },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
STRING_SUPPLEMENTARY_LOWERCASE } };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testToLowerCase(String str, String expected) {
|
||||
map.get(str).forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(data.toLowerCase(), expected, String.format(
|
||||
"testing String(%s).toLowerCase(), source : %s, ",
|
||||
escapeNonASCIIs(data), source));
|
||||
});
|
||||
}
|
||||
}
|
||||
67
test/jdk/java/lang/String/CompactString/ToUpperCase.java
Normal file
67
test/jdk/java/lang/String/CompactString/ToUpperCase.java
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.toUpperCase.
|
||||
* @run testng/othervm -XX:+CompactStrings ToUpperCase
|
||||
* @run testng/othervm -XX:-CompactStrings ToUpperCase
|
||||
*/
|
||||
|
||||
public class ToUpperCase extends CompactString {
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, "" },
|
||||
new Object[] { STRING_L1, "A" },
|
||||
new Object[] { STRING_L2, "AB" },
|
||||
new Object[] { STRING_U1, "\uFF21" },
|
||||
new Object[] { STRING_MDUPLICATE1,
|
||||
"\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A" },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
"\uD801\uDC00\uD801\uDC01\uFF21A" },
|
||||
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
|
||||
"\uD801\uDC00\uD801\uDC01\uFF21A" },
|
||||
new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
|
||||
STRING_SUPPLEMENTARY }, };
|
||||
}
|
||||
|
||||
@Test(dataProvider = "provider")
|
||||
public void testToUpperCase(String str, String expected) {
|
||||
map.get(str).forEach(
|
||||
(source, data) -> {
|
||||
assertEquals(data.toUpperCase(), expected, String.format(
|
||||
"testing String(%s).toUpperCase(), source : %s, ",
|
||||
escapeNonASCIIs(data), source));
|
||||
});
|
||||
}
|
||||
}
|
||||
71
test/jdk/java/lang/String/CompactString/Trim.java
Normal file
71
test/jdk/java/lang/String/CompactString/Trim.java
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.trim.
|
||||
* @run testng/othervm -XX:+CompactStrings Trim
|
||||
* @run testng/othervm -XX:-CompactStrings Trim
|
||||
*/
|
||||
|
||||
public class Trim {
|
||||
|
||||
/*
|
||||
* Data provider for testTrim
|
||||
*
|
||||
* @return input parameter for testTrim
|
||||
*/
|
||||
@DataProvider
|
||||
public Object[][] trims() {
|
||||
return new Object[][] {
|
||||
{ " \t \t".trim(), "" },
|
||||
{ "\t \t ".trim(), "" },
|
||||
{ "\t A B C\t ".trim(), "A B C" },
|
||||
{ " \t A B C \t".trim(), "A B C" },
|
||||
{ "\t \uFF21 \uFF22 \uFF23\t ".trim(), "\uFF21 \uFF22 \uFF23" },
|
||||
{ " \t \uFF21 \uFF22 \uFF23 \t".trim(), "\uFF21 \uFF22 \uFF23" },
|
||||
{ " \t \uFF41 \uFF42 \uFF43 \t".trim(), "\uFF41 \uFF42 \uFF43" },
|
||||
{ " \t A\uFF21 B\uFF22 C\uFF23 \t".trim(),
|
||||
"A\uFF21 B\uFF22 C\uFF23" } };
|
||||
}
|
||||
|
||||
/*
|
||||
* test trim().
|
||||
*
|
||||
* @param res
|
||||
* real result
|
||||
* @param expected
|
||||
* expected result
|
||||
*/
|
||||
@Test(dataProvider = "trims")
|
||||
public void testTrim(String res, String expected) {
|
||||
assertEquals(res, expected);
|
||||
}
|
||||
|
||||
}
|
||||
92
test/jdk/java/lang/String/CompactString/VMOptionsTest.java
Normal file
92
test/jdk/java/lang/String/CompactString/VMOptionsTest.java
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is testing
|
||||
* if Compact String enable/disable VM Options is indeed working in String class,
|
||||
* it's verified by testing if the VM option affect coder and
|
||||
* COMPACT_STRINGS field in String class.
|
||||
* @modules java.base/java.lang:open
|
||||
* @run testng/othervm -XX:+CompactStrings -DCompactStringEnabled=true VMOptionsTest
|
||||
* @run testng/othervm -XX:-CompactStrings -DCompactStringEnabled=false VMOptionsTest
|
||||
*/
|
||||
|
||||
public class VMOptionsTest {
|
||||
boolean compactStringEnabled;
|
||||
// corresponding "COMPACT_STRINGS" field in String class.
|
||||
Field COMPACT_STRINGS;
|
||||
// corresponding "coder" field in String class.
|
||||
Field coder;
|
||||
|
||||
// corresponding coder type in String class.
|
||||
final byte LATIN1 = 0;
|
||||
final byte UTF16 = 1;
|
||||
|
||||
@BeforeClass
|
||||
public void setUp() throws Exception {
|
||||
compactStringEnabled = Boolean.valueOf(System.getProperty("CompactStringEnabled", null));
|
||||
COMPACT_STRINGS = String.class.getDeclaredField("COMPACT_STRINGS");
|
||||
COMPACT_STRINGS.setAccessible(true);
|
||||
coder = String.class.getDeclaredField("coder");
|
||||
coder.setAccessible(true);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] provider() {
|
||||
return new Object[][] {
|
||||
new Object[] {"", LATIN1},
|
||||
new Object[] {"abc", LATIN1},
|
||||
new Object[] {"A\uff21", UTF16},
|
||||
new Object[] {"\uff21\uff22", UTF16}
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* verify the coder field in String objects.
|
||||
*/
|
||||
@Test(dataProvider = "provider")
|
||||
public void testCoder(String str, byte expected) throws Exception {
|
||||
byte c = (byte) coder.get(str);
|
||||
expected = compactStringEnabled ? expected : UTF16;
|
||||
assertEquals(c, expected);
|
||||
}
|
||||
|
||||
/*
|
||||
* verify the COMPACT_STRINGS flag in String objects.
|
||||
*/
|
||||
@Test(dataProvider = "provider")
|
||||
public void testCompactStringFlag(String str, byte ignore) throws Exception {
|
||||
assertTrue(COMPACT_STRINGS.get(str).equals(compactStringEnabled));
|
||||
}
|
||||
}
|
||||
78
test/jdk/java/lang/String/CompactString/ValueOf.java
Normal file
78
test/jdk/java/lang/String/CompactString/ValueOf.java
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8077559
|
||||
* @summary Tests Compact String. This one is for String.valueOf.
|
||||
* valueOf(char[] data) is not tested here.
|
||||
* @run testng/othervm -XX:+CompactStrings ValueOf
|
||||
* @run testng/othervm -XX:-CompactStrings ValueOf
|
||||
*/
|
||||
|
||||
public class ValueOf {
|
||||
|
||||
/*
|
||||
* Data provider for testValueOf
|
||||
*
|
||||
* @return input parameter for testValueOf
|
||||
*/
|
||||
@DataProvider
|
||||
public Object[][] valueOfs() {
|
||||
return new Object[][] { { String.valueOf(true), "true" },
|
||||
{ String.valueOf(false), "false" },
|
||||
{ String.valueOf(1.0f), "1.0" },
|
||||
{ String.valueOf(0.0f), "0.0" },
|
||||
{ String.valueOf(Float.MAX_VALUE), "3.4028235E38" },
|
||||
{ String.valueOf(Float.MIN_VALUE), "1.4E-45" },
|
||||
{ String.valueOf(1.0d), "1.0" },
|
||||
{ String.valueOf(0.0d), "0.0" },
|
||||
{ String.valueOf(Double.MAX_VALUE), "1.7976931348623157E308" },
|
||||
{ String.valueOf(Double.MIN_VALUE), "4.9E-324" },
|
||||
{ String.valueOf(1), "1" }, { String.valueOf(0), "0" },
|
||||
{ String.valueOf(Integer.MAX_VALUE), "2147483647" },
|
||||
{ String.valueOf(Integer.MIN_VALUE), "-2147483648" },
|
||||
{ String.valueOf(1L), "1" }, { String.valueOf(0L), "0" },
|
||||
{ String.valueOf(Long.MAX_VALUE), "9223372036854775807" },
|
||||
{ String.valueOf(Long.MIN_VALUE), "-9223372036854775808" } };
|
||||
}
|
||||
|
||||
/*
|
||||
* test String.valueOf(xxx).
|
||||
*
|
||||
* @param res
|
||||
* real result
|
||||
* @param expected
|
||||
* expected result
|
||||
*/
|
||||
@Test(dataProvider = "valueOfs")
|
||||
public void testValueOf(String res, String expected) {
|
||||
assertEquals(res, expected);
|
||||
}
|
||||
|
||||
}
|
||||
64
test/jdk/java/lang/String/CompareIC.java
Normal file
64
test/jdk/java/lang/String/CompareIC.java
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4124769 8160312
|
||||
* @summary Test ignore-case comparison
|
||||
*
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class CompareIC {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String test1 = "Tess";
|
||||
String test2 = "Test";
|
||||
String test3 = "Tesu";
|
||||
CompareIC comparer = new CompareIC();
|
||||
|
||||
comparer.testTriplet(test1, test2, test3);
|
||||
test2 = test2.toUpperCase();
|
||||
comparer.testTriplet(test1, test2, test3);
|
||||
test2 = test2.toLowerCase();
|
||||
comparer.testTriplet(test1, test2, test3);
|
||||
|
||||
// toLowerCase -> non-latin1
|
||||
if ("\u00b5".compareToIgnoreCase("X") < 0)
|
||||
throw new RuntimeException("Comparison failure1");
|
||||
}
|
||||
|
||||
private void testTriplet(String one, String two, String three)
|
||||
throws Exception {
|
||||
if (one.compareToIgnoreCase(two) > 0)
|
||||
throw new RuntimeException("Comparison failure1");
|
||||
if (two.compareToIgnoreCase(three) > 0)
|
||||
throw new RuntimeException("Comparison failure2");
|
||||
if (three.compareToIgnoreCase(one) < 0)
|
||||
throw new RuntimeException("Comparison failure3");
|
||||
}
|
||||
|
||||
}
|
||||
122
test/jdk/java/lang/String/ContentEquals.java
Normal file
122
test/jdk/java/lang/String/ContentEquals.java
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2004, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4242309 4982981
|
||||
* @summary Test equals and contentEquals in String
|
||||
* @key randomness
|
||||
*/
|
||||
import java.util.Random;
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
// Yes, I used cut and paste for this test. Yes more code
|
||||
// sharing could have been accomplished.
|
||||
public class ContentEquals {
|
||||
|
||||
private static Random rnd = new Random();
|
||||
private static final int ITERATIONS = 1000;
|
||||
private static final int STR_LEN = 20;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
testStringBuffer();
|
||||
testStringBuilder();
|
||||
testString();
|
||||
testCharSequence();
|
||||
}
|
||||
|
||||
// Test a StringBuffer, which uses the old method from 1.4
|
||||
public static void testStringBuffer() throws Exception {
|
||||
for (int i=0; i<ITERATIONS; i++) {
|
||||
int length = rnd.nextInt(STR_LEN) + 1;
|
||||
StringBuffer testStringBuffer = new StringBuffer();
|
||||
for(int x=0; x<length; x++) {
|
||||
char aChar = (char)rnd.nextInt();
|
||||
testStringBuffer.append(aChar);
|
||||
}
|
||||
String testString = testStringBuffer.toString();
|
||||
char c = testStringBuffer.charAt(0);
|
||||
testStringBuffer.setCharAt(0, 'c');
|
||||
testStringBuffer.setCharAt(0, c);
|
||||
if (!testString.contentEquals(testStringBuffer))
|
||||
throw new RuntimeException("ContentsEqual failure");
|
||||
}
|
||||
}
|
||||
|
||||
// Test StringBuilder as a CharSequence using new method in 1.5
|
||||
public static void testStringBuilder() throws Exception {
|
||||
for (int i=0; i<ITERATIONS; i++) {
|
||||
int length = rnd.nextInt(STR_LEN) + 1;
|
||||
StringBuilder testStringBuilder = new StringBuilder();
|
||||
for(int x=0; x<length; x++) {
|
||||
char aChar = (char)rnd.nextInt();
|
||||
testStringBuilder.append(aChar);
|
||||
}
|
||||
String testString = testStringBuilder.toString();
|
||||
char c = testStringBuilder.charAt(0);
|
||||
testStringBuilder.setCharAt(0, 'c');
|
||||
testStringBuilder.setCharAt(0, c);
|
||||
if (!testString.contentEquals(testStringBuilder))
|
||||
throw new RuntimeException("ContentsEqual failure");
|
||||
}
|
||||
}
|
||||
|
||||
// Test a String as a CharSequence. This takes a different codepath in
|
||||
// the new method in 1.5
|
||||
public static void testString() throws Exception {
|
||||
for (int i=0; i<ITERATIONS; i++) {
|
||||
int length = rnd.nextInt(STR_LEN) + 1;
|
||||
StringBuilder testStringBuilder = new StringBuilder();
|
||||
for(int x=0; x<length; x++) {
|
||||
char aChar = (char)rnd.nextInt();
|
||||
testStringBuilder.append(aChar);
|
||||
}
|
||||
String testString = testStringBuilder.toString();
|
||||
char c = testStringBuilder.charAt(0);
|
||||
testStringBuilder.setCharAt(0, 'c');
|
||||
testStringBuilder.setCharAt(0, c);
|
||||
if (!testString.contentEquals(testStringBuilder.toString()))
|
||||
throw new RuntimeException("ContentsEqual failure");
|
||||
}
|
||||
}
|
||||
|
||||
// Test a CharSequence that is not an AbstractStringBuilder,
|
||||
// this takes a different codepath in the new method in 1.5
|
||||
public static void testCharSequence() throws Exception {
|
||||
for (int i=0; i<ITERATIONS; i++) {
|
||||
int length = rnd.nextInt(STR_LEN) + 1;
|
||||
StringBuilder testStringBuilder = new StringBuilder();
|
||||
for(int x=0; x<length; x++) {
|
||||
char aChar = (char)rnd.nextInt();
|
||||
testStringBuilder.append(aChar);
|
||||
}
|
||||
String testString = testStringBuilder.toString();
|
||||
char c = testStringBuilder.charAt(0);
|
||||
testStringBuilder.setCharAt(0, 'c');
|
||||
testStringBuilder.setCharAt(0, c);
|
||||
CharBuffer buf = CharBuffer.wrap(testStringBuilder.toString());
|
||||
if (!testString.contentEquals(buf))
|
||||
throw new RuntimeException("ContentsEqual failure");
|
||||
}
|
||||
}
|
||||
}
|
||||
63
test/jdk/java/lang/String/CountNonZeroAscii.java
Normal file
63
test/jdk/java/lang/String/CountNonZeroAscii.java
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2024, Alibaba Group Holding Limited. 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import jdk.internal.access.JavaLangAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.access
|
||||
* @summary test latin1 String countNonZeroAscii
|
||||
* @run main/othervm -XX:+CompactStrings CountNonZeroAscii
|
||||
* @run main/othervm -XX:-CompactStrings CountNonZeroAscii
|
||||
*/
|
||||
public class CountNonZeroAscii {
|
||||
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
|
||||
|
||||
public static void main(String [] args) {
|
||||
byte[] bytes = new byte[1000];
|
||||
|
||||
Arrays.fill(bytes, (byte) 'A');
|
||||
String s = new String(bytes, StandardCharsets.ISO_8859_1);
|
||||
assertEquals(bytes.length, JLA.countNonZeroAscii(s));
|
||||
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
for (int j = Byte.MIN_VALUE; j <= 0; j++) {
|
||||
bytes[i] = (byte) j;
|
||||
s = new String(bytes, StandardCharsets.ISO_8859_1);
|
||||
assertEquals(i, JLA.countNonZeroAscii(s));
|
||||
}
|
||||
bytes[i] = (byte) 'A';
|
||||
}
|
||||
}
|
||||
|
||||
static void assertEquals(int expected, int actual) {
|
||||
if (expected != actual) {
|
||||
throw new AssertionError("Expected " + expected + " but got " + actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
183
test/jdk/java/lang/String/Encodings.java
Normal file
183
test/jdk/java/lang/String/Encodings.java
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2026, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4085160 4139951 5005831 8372353
|
||||
* @summary Test that required character encodings are supported
|
||||
*/
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
|
||||
|
||||
public class Encodings {
|
||||
|
||||
|
||||
static boolean equals(byte[] a, byte[] b) {
|
||||
if (a.length != b.length) return false;
|
||||
for (int i = 0; i < a.length; i++)
|
||||
if (a[i] != b[i]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void go(String enc, String str, final byte[] bytes, boolean bidir)
|
||||
throws Exception
|
||||
{
|
||||
final Charset charset = Charset.forName(enc);
|
||||
|
||||
/* String(byte[] bs, String enc) */
|
||||
if (!(new String(bytes, enc).equals(str)))
|
||||
throw new Exception(enc + ": String constructor failed");
|
||||
|
||||
/* String(byte[] bs, Charset charset) */
|
||||
if (!(new String(bytes, charset).equals(str)))
|
||||
throw new Exception(charset + ": String constructor failed");
|
||||
|
||||
/* String(byte[] bs, int off, int len, Charset charset) */
|
||||
String start = str.substring(0, 2);
|
||||
String end = str.substring(2);
|
||||
if (enc.equals("UTF-16BE") || enc.equals("UTF-16LE")) {
|
||||
if (!(new String(bytes, 0, 4, charset).equals(start)))
|
||||
throw new Exception(charset + ": String constructor failed");
|
||||
if (!(new String(bytes, 4, bytes.length - 4, charset).equals(end)))
|
||||
throw new Exception(charset + ": String constructor failed");
|
||||
} else if (enc.equals("UTF-16")) {
|
||||
if (!(new String(bytes, 0, 6, charset).equals(start)))
|
||||
throw new Exception(charset + ": String constructor failed");
|
||||
} else {
|
||||
if (!(new String(bytes, 0, 2, charset).equals(start)))
|
||||
throw new Exception(charset + ": String constructor failed");
|
||||
if (!(new String(bytes, 2, bytes.length - 2, charset).equals(end)))
|
||||
throw new Exception(charset + ": String constructor failed");
|
||||
}
|
||||
|
||||
/* InputStreamReader */
|
||||
ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
|
||||
InputStreamReader r = new InputStreamReader(bi, enc);
|
||||
String inEnc = r.getEncoding();
|
||||
int n = str.length();
|
||||
char[] cs = new char[n];
|
||||
for (int i = 0; i < n;) {
|
||||
int m;
|
||||
if ((m = r.read(cs, i, n - i)) < 0)
|
||||
throw new Exception(enc + ": EOF on InputStreamReader");
|
||||
i += m;
|
||||
}
|
||||
if (!(new String(cs).equals(str)))
|
||||
throw new Exception(enc + ": InputStreamReader failed");
|
||||
|
||||
if (!bidir) {
|
||||
System.err.println(enc + " --> " + inEnc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* String.getBytes(String enc) */
|
||||
byte[] bs = str.getBytes(enc);
|
||||
if (!equals(bs, bytes))
|
||||
throw new Exception(enc + ": String.getBytes failed");
|
||||
|
||||
/* String.getBytes(Charset charset) */
|
||||
bs = str.getBytes(charset);
|
||||
if (!equals(bs, bytes))
|
||||
throw new Exception(charset + ": String.getBytes failed");
|
||||
|
||||
/* String.encodedLength(Charset charset) */
|
||||
if (bs.length != str.encodedLength(charset))
|
||||
throw new Exception(charset + ": String.encodedLength failed");
|
||||
|
||||
// Calls to String.getBytes(Charset) shouldn't automatically
|
||||
// use the cached thread-local encoder.
|
||||
if (charset.name().equals("UTF-16BE")) {
|
||||
String s = new String(bytes, charset);
|
||||
// Replace the thread-local encoder with this one.
|
||||
byte[] bb = s.getBytes(Charset.forName("UTF-16LE"));
|
||||
if (bytes.length != bb.length) {
|
||||
// Incidental test.
|
||||
throw new RuntimeException("unequal length: "
|
||||
+ bytes.length + " != "
|
||||
+ bb.length);
|
||||
} else {
|
||||
boolean diff = false;
|
||||
// Expect different byte[] between UTF-16LE and UTF-16BE
|
||||
// even though encoder was previously cached by last call
|
||||
// to getBytes().
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
if (bytes[i] != bb[i])
|
||||
diff = true;
|
||||
}
|
||||
if (!diff)
|
||||
throw new RuntimeException("byte arrays equal");
|
||||
}
|
||||
}
|
||||
|
||||
/* OutputStreamWriter */
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
OutputStreamWriter w = new OutputStreamWriter(bo, enc);
|
||||
String outEnc = w.getEncoding();
|
||||
w.write(str);
|
||||
w.close();
|
||||
bs = bo.toByteArray();
|
||||
if (!equals(bs, bytes))
|
||||
throw new Exception(enc + ": OutputStreamWriter failed");
|
||||
|
||||
System.err.println(enc + " --> " + inEnc + " / " + outEnc);
|
||||
}
|
||||
|
||||
|
||||
static void go(String enc, String str, byte[] bytes) throws Exception {
|
||||
go(enc, str, bytes, true);
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
go("US-ASCII", "abc", new byte[] { 'a', 'b', 'c' });
|
||||
go("us-ascii", "abc", new byte[] { 'a', 'b', 'c' });
|
||||
go("ISO646-US", "abc", new byte[] { 'a', 'b', 'c' });
|
||||
go("ISO-8859-1", "ab\u00c7", new byte[] { 'a', 'b', (byte)'\u00c7' });
|
||||
go("UTF-8", "ab\u1e09",
|
||||
new byte[] { 'a', 'b',
|
||||
(byte)(0xe0 | (0x0f & (0x1e09 >> 12))),
|
||||
(byte)(0x80 | (0x3f & (0x1e09 >> 6))),
|
||||
(byte)(0x80 | (0x3f & 0x1e09)) });
|
||||
go("UTF-16BE", "ab\u1e09",
|
||||
new byte[] { 0, 'a', 0, 'b', 0x1e, 0x09 });
|
||||
go("UTF-16LE", "ab\u1e09",
|
||||
new byte[] { 'a', 0, 'b', 0, 0x09, 0x1e });
|
||||
|
||||
/* UTF-16 accepts both byte orders on input but always uses big-endian
|
||||
* on output, so test all three cases
|
||||
*/
|
||||
go("UTF-16", "ab\u1e09",
|
||||
new byte[] { (byte)0xfe, (byte)0xff, 0, 'a', 0, 'b', 0x1e, 0x09 });
|
||||
go("UTF-16", "ab\u1e09",
|
||||
new byte[] { (byte)0xff, (byte)0xfe, 'a', 0, 'b', 0, 0x09, 0x1e },
|
||||
false);
|
||||
}
|
||||
|
||||
}
|
||||
104
test/jdk/java/lang/String/EqualsIgnoreCase.java
Normal file
104
test/jdk/java/lang/String/EqualsIgnoreCase.java
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8138824
|
||||
* @summary Test expected equalsIgnoreCase behavior for some known asymmetric case mappings
|
||||
*/
|
||||
|
||||
public class EqualsIgnoreCase {
|
||||
private static final String SMALL_I = "i";
|
||||
private static final String CAPITAL_I = "I";
|
||||
// Characters that do not map symmetrically between upper/lower case
|
||||
private static final String SMALL_DOTLESS_I = "\u0131";
|
||||
private static final String CAPITAL_I_WITH_DOT = "\u0130";
|
||||
private static final String LOWER_GREEK_THETA = "\u03D1";
|
||||
private static final String CAPITAL_GREEK_THETA = "\u03F4";
|
||||
|
||||
public static void main(String[] args) {
|
||||
compareFuncs(SMALL_I, CAPITAL_I, true, true);
|
||||
compareFuncs(CAPITAL_I_WITH_DOT, SMALL_DOTLESS_I, true, false);
|
||||
compareFuncs(LOWER_GREEK_THETA, CAPITAL_GREEK_THETA, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the actual results of equalsIgnoreCase():
|
||||
* toUpperCase(toLowerCase(eachChar))
|
||||
* to the behavior described in the equalsIgnoreCase() spec prior to 8138824:
|
||||
* toUpperCase(eachChar)
|
||||
* toLowerCase(eachChar)
|
||||
*
|
||||
* @param s1 A string
|
||||
* @param s2 Another string
|
||||
* @param expectEquals Expected result of equalsIgnoreCase()
|
||||
* @param expectTuTl Expected result of toUpperToLowerOriginals()
|
||||
*/
|
||||
private static void compareFuncs(String s1, String s2, boolean expectEquals, boolean expectTuTl) {
|
||||
System.out.println(s1 + ", " + s2);
|
||||
boolean equalsResult = s1.equalsIgnoreCase(s2);
|
||||
System.out.println("equalsIgnoreCase:" + equalsResult);
|
||||
|
||||
boolean tuTlResult = toUpperToLowerOriginals(s1, s2);
|
||||
System.out.println("tUtLO:" + tuTlResult);
|
||||
boolean failed = false;
|
||||
|
||||
if (equalsResult != expectEquals) {
|
||||
System.out.println("Expected " + expectEquals + " from equalsIgnoreCase() but got " + equalsResult);
|
||||
failed = true;
|
||||
}
|
||||
if (tuTlResult != expectTuTl) {
|
||||
System.out.println("Expected " + expectTuTl + " from toUpperToLowerOriginals() but got " + tuTlResult);
|
||||
failed = true;
|
||||
}
|
||||
if (failed) { throw new RuntimeException("Test Failed"); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply toUpperCase() and toLowerCase() to corresponding chars of both
|
||||
* Strings. Returns true if each pair of corresponding chars are either:
|
||||
* 1. == after both are converted to upper case
|
||||
* or
|
||||
* 2. == after both are converted to lower case
|
||||
* and the String lengths are equal.
|
||||
*/
|
||||
private static boolean toUpperToLowerOriginals(String str1, String str2) {
|
||||
if (str1.length() != str2.length()) { return false; }
|
||||
for (int i = 0; i < str1.length(); i++) {
|
||||
char c1 = str1.charAt(i);
|
||||
char c2 = str2.charAt(i);
|
||||
|
||||
char uc1 = Character.toUpperCase(c1);
|
||||
char uc2 = Character.toUpperCase(c2);
|
||||
boolean upperMatch = uc1 == uc2;
|
||||
|
||||
char lc1 = Character.toLowerCase(c1);
|
||||
char lc2 = Character.toLowerCase(c2);
|
||||
boolean lowerMatch = lc1 == lc2;
|
||||
|
||||
if (!(upperMatch || lowerMatch)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
678
test/jdk/java/lang/String/Exceptions.java
Normal file
678
test/jdk/java/lang/String/Exceptions.java
Normal file
|
|
@ -0,0 +1,678 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2026, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 4472841 4703640 4705681 4705683 4833095 5005831 8372353
|
||||
* @summary Verify that constructor exceptions are thrown as expected.
|
||||
*/
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class Exceptions {
|
||||
private static final byte [] b = { 0x48, 0x69, 0x2c, 0x20,
|
||||
0x44, 0x75, 0x6b, 0x65, 0x21 };
|
||||
|
||||
private static final char [] c
|
||||
= "Attack of the Killer Tomatoes!".toCharArray();
|
||||
|
||||
private static boolean ok = true;
|
||||
|
||||
private static void fail(Class ex, String s) {
|
||||
ok = false;
|
||||
System.err.println("expected " + ex.getName() + " for " + s
|
||||
+ " - FAILED");
|
||||
}
|
||||
|
||||
private static void pass(String s) {
|
||||
System.out.println(s + " -- OK");
|
||||
}
|
||||
|
||||
private static void tryCatch(String s, Class ex, Runnable thunk) {
|
||||
Throwable t = null;
|
||||
try {
|
||||
thunk.run();
|
||||
} catch (Throwable x) {
|
||||
if (ex.isAssignableFrom(x.getClass()))
|
||||
t = x;
|
||||
else
|
||||
x.printStackTrace();
|
||||
}
|
||||
if ((t == null) && (ex != null))
|
||||
fail(ex, s);
|
||||
else
|
||||
pass(s);
|
||||
}
|
||||
|
||||
// -- Constructors --
|
||||
|
||||
private static void noArgs() {
|
||||
System.out.println("String()");
|
||||
tryCatch(" default ctor", null, new Runnable() {
|
||||
public void run() {
|
||||
new String();
|
||||
}});
|
||||
}
|
||||
|
||||
private static void string() {
|
||||
System.out.println("String(String original)");
|
||||
tryCatch(" \"foo\"", null, new Runnable() {
|
||||
public void run() {
|
||||
new String("foo");
|
||||
}});
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
new String((String) null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void charArray() {
|
||||
System.out.println("String(char value[])");
|
||||
tryCatch(" char [] = \"Duke says \"Hi!\"\"", null, new Runnable() {
|
||||
public void run() {
|
||||
new String("Duke says \"Hi!\"".toCharArray());
|
||||
}});
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
new String((char []) null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void charArrayOffCount() {
|
||||
System.out.println("String(char value[], int offset, int count)");
|
||||
tryCatch(" c, 0, 3", null, new Runnable() {
|
||||
public void run() {
|
||||
new String(c, 0, 3);
|
||||
}});
|
||||
tryCatch(" null, 1, 2", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
new String((char []) null, 1, 2);
|
||||
}});
|
||||
tryCatch(" c, -1, 4", IndexOutOfBoundsException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
new String(c, -1, 4);
|
||||
}});
|
||||
tryCatch(" c, 1, -1", IndexOutOfBoundsException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
new String(c, 1, -1);
|
||||
}});
|
||||
tryCatch(" c, c.lengh + 1, 1", IndexOutOfBoundsException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
new String(c, c.length + 1, 1);
|
||||
}});
|
||||
tryCatch(" c, 0, c.length + 1", IndexOutOfBoundsException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
new String(c, 0, c.length + 1);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void byteArrayHiOffCount() {
|
||||
System.out.println("String(byte ascii[], int hibyte, int offset, "
|
||||
+ "int count)");
|
||||
tryCatch(" b, 0, 0, b.length", null, new Runnable() {
|
||||
public void run() {
|
||||
System.out.println(new String(b, 0, 0, b.length));
|
||||
}});
|
||||
|
||||
tryCatch(" b, -1, 4, 4", null, new Runnable() {
|
||||
public void run() {
|
||||
new String(b, -1, 4, 4);
|
||||
}});
|
||||
tryCatch(" null, 0, 0, 0", NullPointerException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
new String((byte[]) null, 0, 0, 0);
|
||||
}});
|
||||
tryCatch(" b, 0, -1, r", IndexOutOfBoundsException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
new String(b, 0, -1, 4);
|
||||
}});
|
||||
tryCatch(" b, 0, 4, -1", IndexOutOfBoundsException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
new String(b, 0, 4, -1);
|
||||
}});
|
||||
tryCatch(" b, 0, b.length + 1, 1", IndexOutOfBoundsException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
new String(b, 0, b.length + 1, 1);
|
||||
}});
|
||||
tryCatch(" b, 0, 0, b.length + 1", IndexOutOfBoundsException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
new String(b, 0, 0, b.length + 1);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void byteArrayHi() {
|
||||
System.out.println("String(byte ascii[], int hibyte)");
|
||||
tryCatch(" b, 0", null, new Runnable() {
|
||||
public void run() {
|
||||
new String(b, 0);
|
||||
}});
|
||||
tryCatch(" null, 0", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
new String((byte []) null, 0);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void byteArrayOffLengthCharset0(String s, Class ex,
|
||||
byte [] b, int off,
|
||||
int len, Object cs)
|
||||
{
|
||||
Throwable t = null;
|
||||
try {
|
||||
if (cs instanceof String)
|
||||
new String(b, off, len, (String)cs);
|
||||
else // (cs instanceof Charset)
|
||||
new String(b, off, len, (Charset)cs);
|
||||
} catch (Throwable x) {
|
||||
if (ex.isAssignableFrom(x.getClass()))
|
||||
t = x;
|
||||
else
|
||||
x.printStackTrace();
|
||||
}
|
||||
if ((t == null) && (ex != null))
|
||||
fail(ex, s);
|
||||
else
|
||||
pass(s);
|
||||
}
|
||||
|
||||
private static void byteArrayOffLengthCharsetName() {
|
||||
System.out.println("String(byte bytes[], int offset, int length, "
|
||||
+ "String charsetName)");
|
||||
System.out.println(" throws UnsupportedEncodingException");
|
||||
String enc = "UTF-8";
|
||||
byteArrayOffLengthCharset0(" b, 0, 0," + enc, null, b, 0, 0, enc);
|
||||
byteArrayOffLengthCharset0(" null, 0, 0," + enc,
|
||||
NullPointerException.class,
|
||||
(byte []) null, 0, 0, enc);
|
||||
byteArrayOffLengthCharset0(" b, -1, 0, " + enc,
|
||||
IndexOutOfBoundsException.class,
|
||||
b, -1, 0, enc);
|
||||
byteArrayOffLengthCharset0(" b, 0, -1, " + enc,
|
||||
IndexOutOfBoundsException.class,
|
||||
b, 0, -1, enc);
|
||||
byteArrayOffLengthCharset0(" b, b.length + 1, 1, " + enc,
|
||||
IndexOutOfBoundsException.class,
|
||||
b, b.length + 1, 1, enc);
|
||||
byteArrayOffLengthCharset0(" b, 0, b.length + 1 " + enc,
|
||||
IndexOutOfBoundsException.class,
|
||||
b, 0, b.length + 1, enc);
|
||||
byteArrayOffLengthCharset0(" b, -1, 0, null",
|
||||
NullPointerException.class,
|
||||
b, -1, 0, null);
|
||||
byteArrayOffLengthCharset0(" b, 0, b.length, foo",
|
||||
UnsupportedEncodingException.class,
|
||||
b, 0, b.length, "foo");
|
||||
}
|
||||
|
||||
private static void byteArrayOffLengthCharset() {
|
||||
System.out.println("String(byte bytes[], int offset, int length, "
|
||||
+ "Charset charset)");
|
||||
Charset cs = Charset.forName("UTF-16BE");
|
||||
byteArrayOffLengthCharset0(" b, 0, 0," + cs, null, b, 0, 0, cs);
|
||||
byteArrayOffLengthCharset0(" null, 0, 0," + cs,
|
||||
NullPointerException.class,
|
||||
(byte []) null, 0, 0, cs);
|
||||
byteArrayOffLengthCharset0(" b, -1, 0, " + cs,
|
||||
IndexOutOfBoundsException.class,
|
||||
b, -1, 0, cs);
|
||||
byteArrayOffLengthCharset0(" b, 0, -1, " + cs,
|
||||
IndexOutOfBoundsException.class,
|
||||
b, 0, -1, cs);
|
||||
byteArrayOffLengthCharset0(" b, b.length + 1, 1, " + cs,
|
||||
IndexOutOfBoundsException.class,
|
||||
b, b.length + 1, 1, cs);
|
||||
byteArrayOffLengthCharset0(" b, 0, b.length + 1 " + cs,
|
||||
IndexOutOfBoundsException.class,
|
||||
b, 0, b.length + 1, cs);
|
||||
byteArrayOffLengthCharset0(" b, -1, 0, null",
|
||||
NullPointerException.class,
|
||||
b, -1, 0, null);
|
||||
}
|
||||
|
||||
private static void byteArrayCharset0(String s, Class ex, byte [] b,
|
||||
Object cs)
|
||||
{
|
||||
Throwable t = null;
|
||||
try {
|
||||
if (cs instanceof String)
|
||||
new String(b, (String)cs);
|
||||
else // (cs instanceof Charset)
|
||||
new String(b, (Charset)cs);
|
||||
} catch (Throwable x) {
|
||||
if (ex.isAssignableFrom(x.getClass()))
|
||||
t = x;
|
||||
else
|
||||
x.printStackTrace();
|
||||
}
|
||||
if ((t == null) && (ex != null))
|
||||
fail(ex, s);
|
||||
else
|
||||
pass(s);
|
||||
}
|
||||
|
||||
private static void byteArrayCharsetName() {
|
||||
System.out.println("String(byte bytes[], String charsetName)");
|
||||
System.out.println(" throws UnsupportedEncodingException");
|
||||
String enc = "US-ASCII";
|
||||
byteArrayCharset0(" b, " + enc, null, b, enc);
|
||||
byteArrayCharset0(" null, " + enc, NullPointerException.class,
|
||||
(byte []) null, enc);
|
||||
byteArrayCharset0(" b, null", NullPointerException.class, b, null);
|
||||
byteArrayCharset0(" null, null", NullPointerException.class,
|
||||
(byte []) null, null);
|
||||
byteArrayCharset0(" b, bar", UnsupportedEncodingException.class,
|
||||
b, "bar");
|
||||
}
|
||||
|
||||
private static void byteArrayCharset() {
|
||||
System.out.println("String(byte bytes[], Charset charset)");
|
||||
Charset cs = Charset.forName("ISO-8859-1");
|
||||
byteArrayCharset0(" b, " + cs, null, b, cs);
|
||||
byteArrayCharset0(" null, " + cs, NullPointerException.class,
|
||||
(byte []) null, cs);
|
||||
byteArrayCharset0(" b, null", NullPointerException.class, b, null);
|
||||
byteArrayCharset0(" null, null", NullPointerException.class,
|
||||
(byte []) null, null);
|
||||
}
|
||||
|
||||
private static void byteArrayOffLength() {
|
||||
System.out.println("String(byte bytes[], int offset, int length)");
|
||||
tryCatch(" b, 0, b.length", null, new Runnable() {
|
||||
public void run() {
|
||||
new String(b, 0, b.length);
|
||||
}});
|
||||
tryCatch(" null, 0, 0", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
new String((byte []) null, 0, 0);
|
||||
}});
|
||||
tryCatch(" b, -1, b.length", IndexOutOfBoundsException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
new String(b, -1, b.length);
|
||||
}});
|
||||
tryCatch(" b, 0, -1", IndexOutOfBoundsException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
new String(b, 0, -1);
|
||||
}});
|
||||
tryCatch(" b, b.length + 1, 1", IndexOutOfBoundsException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
new String(b, b.length + 1, 1);
|
||||
}});
|
||||
tryCatch(" b, 0, b.length", IndexOutOfBoundsException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
new String(b, 0, b.length + 1);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void byteArray() {
|
||||
System.out.println("String(byte bytes[])");
|
||||
tryCatch(" b", null, new Runnable() {
|
||||
public void run() {
|
||||
new String(b);
|
||||
}});
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
new String((byte []) null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void stringBuffer() {
|
||||
System.out.println("String(StringBuffer buffer)");
|
||||
tryCatch(" \"bar\"", null, new Runnable() {
|
||||
public void run() {
|
||||
new String(new StringBuffer("bar"));
|
||||
}});
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
new String((StringBuffer) null);
|
||||
}});
|
||||
}
|
||||
|
||||
// -- Methods --
|
||||
|
||||
private static void getChars() {
|
||||
System.out.println("getChars.(int srcBegin, int srcEnd, char dst[], "
|
||||
+ " int dstBegin");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".getChars(1, 2, null, 1);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void getBytes() {
|
||||
System.out.println("getChars.(int srcBegin, int srcEnd, char dst[], "
|
||||
+ " int dstBegin");
|
||||
tryCatch(" 1, 2, null, 1", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".getBytes(1, 2, null, 1);
|
||||
}});
|
||||
|
||||
System.out.println("getBytes.(String charsetName)"
|
||||
+ " throws UnsupportedEncodingException");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
"foo".getBytes((String)null);
|
||||
} catch (UnsupportedEncodingException x) {
|
||||
throw new RuntimeException(x);
|
||||
}
|
||||
}});
|
||||
|
||||
System.out.println("getBytes.(Charset charset)");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".getBytes((Charset)null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void encodedLength() {
|
||||
System.out.println("encodedLength(Charset charset)");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".encodedLength((Charset)null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void contentEquals() {
|
||||
System.out.println("contentEquals(StringBuffer sb)");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".contentEquals(null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void compareTo() {
|
||||
System.out.println("compareTo(String anotherString)");
|
||||
tryCatch(" (String) null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".compareTo((String) null);
|
||||
}});
|
||||
|
||||
/* 4830291 (javac generics bug) causes this test to fail
|
||||
System.out.println("compareTo(Object o)");
|
||||
tryCatch(" (Object) null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".compareTo((Object) null);
|
||||
}});
|
||||
*/
|
||||
}
|
||||
|
||||
private static void compareToIgnoreCase() {
|
||||
System.out.println("compareToIgnoreCase(String anotherString)");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".compareToIgnoreCase((String) null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void regionMatches() {
|
||||
System.out.println("regionMatches(int toffset, String other,"
|
||||
+ " int ooffset, int len)");
|
||||
tryCatch(" 1, null, 1, 1", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".regionMatches(1, null, 1, 1);
|
||||
}});
|
||||
|
||||
System.out.println("regionMatches(boolean ignore, int toffset,"
|
||||
+ " String other, int ooffset, int len)");
|
||||
tryCatch(" true, 1, null, 1, 1", NullPointerException.class,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
"foo".regionMatches(true, 1, null, 1, 1);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void startsWith() {
|
||||
System.out.println("startsWith(String prefix, int toffset)");
|
||||
tryCatch(" null, 1", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".startsWith(null, 1);
|
||||
}});
|
||||
|
||||
System.out.println("startsWith(String prefix)");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".startsWith(null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void endsWith() {
|
||||
System.out.println("endsWith(String suffix)");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".endsWith(null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void indexOf() {
|
||||
System.out.println("indexOf(String str)");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".indexOf(null);
|
||||
}});
|
||||
|
||||
System.out.println("indexOf(String str, int fromIndex)");
|
||||
tryCatch(" null, 1", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".indexOf(null, 1);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void lastIndexOf() {
|
||||
System.out.println("lastIndexOf(String str)");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".lastIndexOf(null);
|
||||
}});
|
||||
|
||||
System.out.println("lastIndexOf(String str, int fromIndex)");
|
||||
tryCatch(" null, 1", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".lastIndexOf(null, 1);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void concat() {
|
||||
System.out.println("concat(String str)");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".concat(null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void matches() {
|
||||
System.out.println("matches(String regex)");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".matches(null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void replaceFirst() {
|
||||
System.out.println("replaceFirst(String regex, String replacement)");
|
||||
tryCatch(" \".\", null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".replaceFirst(".", null);
|
||||
}});
|
||||
tryCatch(" null, \"-\"", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".replaceFirst(null, "-");
|
||||
}});
|
||||
}
|
||||
|
||||
private static void replaceAll() {
|
||||
System.out.println("replaceAll(String regex, String replacement)");
|
||||
tryCatch(" \".\", null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".replaceAll(".", null);
|
||||
}});
|
||||
tryCatch(" null, \"-\"", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".replaceAll(null, "-");
|
||||
}});
|
||||
}
|
||||
|
||||
private static void split() {
|
||||
System.out.println("split(String regex, int limit)");
|
||||
tryCatch(" null, 1", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".split(null, 1);
|
||||
}});
|
||||
|
||||
System.out.println("split(String regex, int limit)");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".split(null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void toLowerCase() {
|
||||
System.out.println("toLowerCase(Locale locale)");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".toLowerCase(null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void toUpperCase() {
|
||||
System.out.println("toUpperCase(Locale locale)");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".toUpperCase(null);
|
||||
}});
|
||||
}
|
||||
|
||||
private static void valueOf() {
|
||||
System.out.println("valueOf(Object obj)");
|
||||
tryCatch(" null", null, new Runnable() {
|
||||
public void run() {
|
||||
String.valueOf((Object) null);
|
||||
}});
|
||||
|
||||
System.out.println("valueOf(char data[])");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
String.valueOf((char []) null);
|
||||
}});
|
||||
|
||||
System.out.println("valueOf(char data[], int offset, int count)");
|
||||
tryCatch(" null, 1, 2", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
String.valueOf((char []) null, 1, 2);
|
||||
}});
|
||||
|
||||
}
|
||||
|
||||
private static void copyValueOf() {
|
||||
System.out.println("copyValueOf(char data[], int offset, int count)");
|
||||
tryCatch(" null, 1, 2", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
"foo".copyValueOf((char []) null, 1, 2);
|
||||
}});
|
||||
|
||||
System.out.println("copyVlueOf(char data[])");
|
||||
tryCatch(" null", NullPointerException.class, new Runnable() {
|
||||
public void run() {
|
||||
String.copyValueOf((char []) null);
|
||||
}});
|
||||
}
|
||||
|
||||
public static void main(String [] args) {
|
||||
|
||||
// -- Constructors --
|
||||
|
||||
noArgs(); // String()
|
||||
string(); // String(String original)
|
||||
charArray(); // String(char value[])
|
||||
charArrayOffCount(); // String(char value[], int offset, int count)
|
||||
|
||||
// String(byte ascii[], int hibyte, int offset, int count)
|
||||
byteArrayHiOffCount();
|
||||
|
||||
byteArrayHi(); // String(byte ascii[], int hibyte)
|
||||
|
||||
// String(byte bytes[], int offset, int length, String charsetName)
|
||||
// throws UnsupportedEncodingException
|
||||
byteArrayOffLengthCharsetName();
|
||||
|
||||
// String(byte bytes[], int offset, int length, Charset charset)
|
||||
byteArrayOffLengthCharset();
|
||||
|
||||
// String(byte bytes[], String charsetName)
|
||||
// throws UnsupportedEncodingException
|
||||
byteArrayCharsetName();
|
||||
|
||||
// String(byte bytes[], Charset charset)
|
||||
byteArrayCharset();
|
||||
|
||||
byteArrayOffLength(); // String(byte bytes[], int offset, int length)
|
||||
byteArray(); // String(byte bytes[])
|
||||
stringBuffer(); // String(StringBuffer buffer)
|
||||
|
||||
// -- Methods --
|
||||
|
||||
getChars(); // getChars(int, int. char [], int)
|
||||
getBytes(); // getBytes(int, int, byte [], int),
|
||||
// getBytes(Locale)
|
||||
// getBytes(String)
|
||||
// getBytes(Charset)
|
||||
encodedLength(); // encodedLength(Charset)
|
||||
contentEquals(); // contentEquals(StringBuffer)
|
||||
compareTo(); // compareTo(String), compareTo(Object)
|
||||
compareToIgnoreCase();// compareToIgnoreCase(String)
|
||||
regionMatches(); // regionMatches(int, String, int, int)
|
||||
// regionMatches(boolean, int, String, int, int)
|
||||
startsWith(); // startsWith(String, int), startsWith(String)
|
||||
endsWith(); // endsWith(String)
|
||||
indexOf(); // indexOf(String), indexOf(String, int),
|
||||
lastIndexOf(); // lastIndexOf(String), lastIndexOf(String, int)
|
||||
concat(); // concat(String)
|
||||
matches(); // matches(String)
|
||||
replaceFirst(); // replaceFirst(String, String)
|
||||
replaceAll(); // replaceAll(String, String)
|
||||
split(); // split(String, int), split(String)
|
||||
toLowerCase(); // toLowerCase(Locale)
|
||||
toUpperCase(); // toUpperCase(Locale)
|
||||
valueOf(); // valueOf(Object), valueOf(char []),
|
||||
// valueOf(char [], int, int)
|
||||
copyValueOf(); // copyValueOf(char [], int, int),
|
||||
// copyValueOf(char [])
|
||||
|
||||
if (!ok)
|
||||
throw new RuntimeException("Some tests FAILED");
|
||||
else
|
||||
System.out.println("All tests PASSED");
|
||||
}
|
||||
}
|
||||
56
test/jdk/java/lang/String/Formatted.java
Normal file
56
test/jdk/java/lang/String/Formatted.java
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8203444
|
||||
* @summary Unit tests for instance versions of String#format
|
||||
* @compile Formatted.java
|
||||
* @run main Formatted
|
||||
*/
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class Formatted {
|
||||
public static void main(String[] args) {
|
||||
test1();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test String#formatted(Object... args) functionality.
|
||||
*/
|
||||
static void test1() {
|
||||
check("formatted(Object... args)",
|
||||
"Test this %s".formatted("and that"),
|
||||
String.format("Test this %s", "and that"));
|
||||
}
|
||||
|
||||
static void check(String test, String output, String expected) {
|
||||
if (output != expected && (output == null || !output.equals(expected))) {
|
||||
System.err.println("Testing " + test + ": unexpected result");
|
||||
System.err.println("Output: " + output);
|
||||
System.err.println("Expected: " + expected);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
56
test/jdk/java/lang/String/HashCode.java
Normal file
56
test/jdk/java/lang/String/HashCode.java
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Datadog, Inc. 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Basic hashCode functionality and stability
|
||||
* @run main/othervm -XX:+CompactStrings HashCode
|
||||
* @run main/othervm -XX:-CompactStrings HashCode
|
||||
*/
|
||||
|
||||
public class HashCode {
|
||||
private static String [] tests = { "", " ", "a", "å",
|
||||
"It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only. -- Charles Dickens, Tale of Two Cities",
|
||||
"C'était le meilleur des temps, c'était le pire des temps, c'était l'âge de la sagesse, c'était l'âge de la folie, c'était l'époque de la croyance, c'était l'époque de l'incrédulité, c'était la saison de la Lumière, c'était C'était la saison des Ténèbres, c'était le printemps de l'espoir, c'était l'hiver du désespoir, nous avions tout devant nous, nous n'avions rien devant nous, nous allions tous directement au Ciel, nous allions tous directement dans l'autre sens bref, la période ressemblait tellement à la période actuelle, que certaines de ses autorités les plus bruyantes ont insisté pour qu'elle soit reçue, pour le bien ou pour le mal, au degré superlatif de la comparaison seulement. -- Charles Dickens, Tale of Two Cities (in French)",
|
||||
"禅",
|
||||
"禅道修行を志した雲水は、一般に参禅のしきたりを踏んだうえで一人の師につき、各地にある専門道場と呼ばれる養成寺院に入門し、与えられた公案に取り組むことになる。公案は、師家(老師)から雲水が悟りの境地へと進んで行くために手助けとして課す問題であり、悟りの境地に達していない人には容易に理解し難い難問だが、屁理屈や詭弁が述べられているわけではなく、頓知や謎かけとも異なる。"
|
||||
};
|
||||
|
||||
private static int [] expected = { 0, 32, 97, 229, 1094896285, -331808333, 31109, 349367663 };
|
||||
|
||||
public static void main(String [] args) throws Exception {
|
||||
for (int j = 0; j < 20_000; j++) {
|
||||
for (int i = 0; i < tests.length; i++) {
|
||||
// Force use of a new String without cached hash
|
||||
String s = new String(tests[i].getBytes("UTF-8"), "UTF-8");
|
||||
int e = expected[i];
|
||||
int hashCode = s.hashCode();
|
||||
if (hashCode != e)
|
||||
throw new RuntimeException("String \"" + s + "\": "
|
||||
+ " e = " + e
|
||||
+ ", hashCode = " + hashCode
|
||||
+ ", repetition = " + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
112
test/jdk/java/lang/String/ICCBasher.java
Normal file
112
test/jdk/java/lang/String/ICCBasher.java
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2002, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 4152868
|
||||
* @summary test Case Insensitive Comparator in String
|
||||
* @key randomness
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ICCBasher {
|
||||
|
||||
static final int TEST_SIZE = 20;
|
||||
static final int STRING_SIZE = 5;
|
||||
static final int CHAR_VALUE_LIMIT = 128;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
LinkedList L1 = new LinkedList();
|
||||
LinkedList L2 = new LinkedList();
|
||||
LinkedList L3 = new LinkedList();
|
||||
LinkedList L4 = new LinkedList();
|
||||
|
||||
// First generate L1 and L2 with random lower case chars
|
||||
//System.out.println("Generate L1 and L2");
|
||||
Random generator = new Random();
|
||||
int achar=0;
|
||||
StringBuffer entryBuffer = new StringBuffer(10);
|
||||
String snippet = null;
|
||||
for (int x=0; x<TEST_SIZE * 2; x++) {
|
||||
for(int y=0; y<STRING_SIZE; y++) {
|
||||
achar = generator.nextInt(CHAR_VALUE_LIMIT);
|
||||
char test = (char)(achar);
|
||||
entryBuffer.append(test);
|
||||
}
|
||||
snippet = entryBuffer.toString();
|
||||
snippet.toLowerCase();
|
||||
if (x < TEST_SIZE)
|
||||
L1.add(snippet);
|
||||
else
|
||||
L2.add(snippet);
|
||||
}
|
||||
|
||||
// Concatenate L1 and L2 to form L3
|
||||
//System.out.println("Generate L3");
|
||||
for (int x=0; x<TEST_SIZE; x++) {
|
||||
String entry = (String)L1.get(x) + (String)L2.get(x);
|
||||
L3.add(entry);
|
||||
}
|
||||
|
||||
// Randomly toUpper L1 and L2
|
||||
//System.out.println("Modify L1 and L2");
|
||||
for (int x=0; x<TEST_SIZE; x++) {
|
||||
achar = generator.nextInt();
|
||||
if (achar > 0) {
|
||||
String mod = (String)L1.get(x);
|
||||
mod = mod.toUpperCase();
|
||||
L1.set(x, mod);
|
||||
}
|
||||
achar = generator.nextInt();
|
||||
if (achar > 0) {
|
||||
String mod = (String)L2.get(x);
|
||||
mod = mod.toUpperCase();
|
||||
L2.set(x, mod);
|
||||
}
|
||||
}
|
||||
|
||||
// Concatenate L1 and L2 to form L4
|
||||
//System.out.println("Generate L4");
|
||||
for (int x=0; x<TEST_SIZE; x++) {
|
||||
String entry = (String)L1.get(x) + (String)L2.get(x);
|
||||
L4.add(entry);
|
||||
}
|
||||
|
||||
// Sort L3 and L4 using case insensitive comparator
|
||||
//System.out.println("Sort L3 and L4");
|
||||
Collections.sort(L3, String.CASE_INSENSITIVE_ORDER);
|
||||
Collections.sort(L4, String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
// Check to see that order of L3 and L4 are identical
|
||||
// ignoring case considerations
|
||||
//System.out.println("Check order of L3 and L4");
|
||||
for (int x=0; x<TEST_SIZE; x++) {
|
||||
String one = (String)L3.get(x);
|
||||
String two = (String)L4.get(x);
|
||||
if (!one.equalsIgnoreCase(two))
|
||||
throw new RuntimeException("Case Insensitive Sort Failure.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
130
test/jdk/java/lang/String/Indent.java
Normal file
130
test/jdk/java/lang/String/Indent.java
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Unit tests for String#indent
|
||||
* @run main Indent
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Indent {
|
||||
static final List<String> ENDS = List.of("", "\n", " \n", "\n\n", "\n\n\n");
|
||||
static final List<String> MIDDLES = List.of(
|
||||
"",
|
||||
"xyz",
|
||||
" xyz",
|
||||
" xyz",
|
||||
"xyz ",
|
||||
" xyz ",
|
||||
" xyz ",
|
||||
"xyz\u2022",
|
||||
" xyz\u2022",
|
||||
"xyz\u2022 ",
|
||||
" xyz\u2022 ",
|
||||
" // comment"
|
||||
);
|
||||
|
||||
public static void main(String[] args) {
|
||||
test1();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test String#indent(int n) functionality.
|
||||
*/
|
||||
static void test1() {
|
||||
for (int adjust : new int[] {-8, -7, -4, -3, -2, -1, 0, 1, 2, 3, 4, 7, 8}) {
|
||||
for (String prefix : ENDS) {
|
||||
for (String suffix : ENDS) {
|
||||
for (String middle : MIDDLES) {
|
||||
String input = prefix + " abc \n" + middle + "\n def \n" + suffix;
|
||||
String output = input.indent(adjust);
|
||||
|
||||
Stream<String> stream = input.lines();
|
||||
if (adjust > 0) {
|
||||
final String spaces = " ".repeat(adjust);
|
||||
stream = stream.map(s -> spaces + s);
|
||||
} else if (adjust < 0) {
|
||||
stream = stream.map(s -> s.substring(Math.min(-adjust, indexOfNonWhitespace(s))));
|
||||
}
|
||||
String expected = stream.collect(Collectors.joining("\n", "", "\n"));
|
||||
|
||||
if (!output.equals(expected)) {
|
||||
report("String::indent(int n)",
|
||||
"Result indentation not as expected", expected, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int indexOfNonWhitespace(String s) {
|
||||
int left = 0;
|
||||
while (left < s.length()) {
|
||||
char ch = s.charAt(left);
|
||||
if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
|
||||
break;
|
||||
}
|
||||
left++;
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
|
||||
private static String[] getBody(String[] inLines) {
|
||||
int from = -1, to = -1;
|
||||
for (int i = 0; i < inLines.length; i++) {
|
||||
String line = inLines[i];
|
||||
if (!line.isBlank()) {
|
||||
if (from == -1) {
|
||||
from = i;
|
||||
}
|
||||
to = i + 1;
|
||||
}
|
||||
}
|
||||
return Arrays.copyOfRange(inLines, from, to);
|
||||
}
|
||||
|
||||
/*
|
||||
* Report difference in result.
|
||||
*/
|
||||
static void report(String test, String message, String input, String output) {
|
||||
System.err.println("Testing " + test + ": " + message);
|
||||
System.err.println();
|
||||
System.err.println("Input: length = " + input.length());
|
||||
System.err.println("_".repeat(40));
|
||||
System.err.print(input.replaceAll(" ", "."));
|
||||
System.err.println("_".repeat(40));
|
||||
System.err.println();
|
||||
System.err.println("Output: length = " + output.length());
|
||||
System.err.println("_".repeat(40));
|
||||
System.err.print(output.replaceAll(" ", "."));
|
||||
System.err.println("_".repeat(40));
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
267
test/jdk/java/lang/String/IndexOf.java
Normal file
267
test/jdk/java/lang/String/IndexOf.java
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
* Copyright (c) 2024, 2026, Intel Corporation. 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8320448
|
||||
* @summary test String indexOf() intrinsic
|
||||
* @run driver IndexOf
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8320448
|
||||
* @summary test String indexOf() intrinsic
|
||||
* @requires vm.cpu.features ~= ".*avx2.*"
|
||||
* @requires vm.compiler2.enabled
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:-TieredCompilation -XX:UseAVX=2 -XX:+UnlockDiagnosticVMOptions -XX:+EnableX86ECoreOpts IndexOf
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8360271
|
||||
* @summary test String indexOf() intrinsic
|
||||
* @requires vm.cpu.features ~= ".*avx2.*"
|
||||
* @requires vm.compiler2.enabled
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:-TieredCompilation -XX:UseAVX=2 -XX:+UnlockDiagnosticVMOptions -XX:+EnableX86ECoreOpts -XX:-CompactStrings IndexOf
|
||||
*/
|
||||
|
||||
public class IndexOf {
|
||||
final int scope = 32*2+16+8;
|
||||
final char a, aa, b, c, d;
|
||||
enum Encoding {LL, UU, UL; }
|
||||
final Encoding ae;
|
||||
int failures;
|
||||
|
||||
IndexOf(Encoding _ae) {
|
||||
failures = 0;
|
||||
ae = _ae;
|
||||
switch (ae) {
|
||||
case LL:
|
||||
a = 'a';
|
||||
aa = a;
|
||||
b = 'b';
|
||||
c = 'c';
|
||||
d = 'd';
|
||||
break;
|
||||
case UU:
|
||||
a = '\u1061';
|
||||
aa = a;
|
||||
b = '\u1062';
|
||||
c = '\u1063';
|
||||
d = '\u1064';
|
||||
break;
|
||||
default: //case UL:
|
||||
a = 'a';
|
||||
aa = '\u1061';
|
||||
b = 'b';
|
||||
c = 'c';
|
||||
d = 'd';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// needle =~ /ab*d/
|
||||
// badNeedle =~ /ab*cb*d/
|
||||
interface Append {void append(int pos, char cc);}
|
||||
String newNeedle(int size, int badPosition) {
|
||||
if (size<2) {throw new RuntimeException("Fix testcase "+size);}
|
||||
|
||||
StringBuilder needle = new StringBuilder(size);
|
||||
Append n = (int pos, char cc) -> {
|
||||
if (pos == badPosition)
|
||||
needle.append(c);
|
||||
else
|
||||
needle.append(cc);
|
||||
};
|
||||
|
||||
n.append(0, a);
|
||||
for (int i=1; i<size-1; i++) {
|
||||
n.append(i, b);
|
||||
}
|
||||
n.append(size-1, d);
|
||||
|
||||
return needle.toString();
|
||||
}
|
||||
|
||||
// haystack =~ /a*{needle}d*/
|
||||
String newHaystack(int size, String needle, int nPosition) {
|
||||
if (nPosition+needle.length()>size) {throw new RuntimeException("Fix testcase "+nPosition+" "+needle.length()+" "+size);}
|
||||
StringBuilder haystack = new StringBuilder(size);
|
||||
int i = 0;
|
||||
for (; i<nPosition; i++) {
|
||||
haystack.append(aa);
|
||||
}
|
||||
haystack.append(needle);
|
||||
i += needle.length();
|
||||
for (; i<size; i++) {
|
||||
haystack.append(d);
|
||||
}
|
||||
return haystack.toString();
|
||||
}
|
||||
|
||||
// haystack =~ /a*{needle}+b*/
|
||||
String newHaystackRepeat(int size, String needle, int nPosition) {
|
||||
if (nPosition+needle.length()>size) {throw new RuntimeException("Fix testcase "+nPosition+" "+needle.length()+" "+size);}
|
||||
StringBuilder haystack = new StringBuilder(size);
|
||||
int i = 0;
|
||||
for (; i<nPosition; i++) {
|
||||
haystack.append(aa);
|
||||
}
|
||||
for (; i< nPosition+needle.length(); i += needle.length()) {
|
||||
haystack.append(needle);
|
||||
}
|
||||
for (; i<size; i++) {
|
||||
haystack.append(d);
|
||||
}
|
||||
return haystack.toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int failures = 0;
|
||||
for (Encoding ae : Encoding.values()) {
|
||||
failures += (new IndexOf(ae))
|
||||
.test0()
|
||||
.test1()
|
||||
.test2()
|
||||
.test3()
|
||||
.test4()
|
||||
.failures;
|
||||
}
|
||||
if (failures != 0) {
|
||||
throw new RuntimeException("IndexOf test failed.");
|
||||
}
|
||||
}
|
||||
|
||||
// Need to disable checks in String.java if intrinsic is to be tested
|
||||
IndexOf test0() { // Test 'trivial cases'
|
||||
// if (0==needle_len) return haystack_off;
|
||||
if (3 != "Hello".indexOf("", 3)) {
|
||||
System.out.println("FAILED: if (0==needle_len) return haystack_off");
|
||||
failures++;
|
||||
}
|
||||
//if (0==haystack_len) return -1;
|
||||
if (-1 != "".indexOf("Hello", 3)) {
|
||||
System.out.println("FAILED: if (0==haystack_len) return -1");
|
||||
failures++;
|
||||
}
|
||||
//if (needle_len>haystack_len) return -1;
|
||||
if (-1 != "Hello".indexOf("HelloWorld", 3)) {
|
||||
System.out.println("FAILED: if (needle_len>haystack_len) return -1");
|
||||
failures++;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
IndexOf test1() { // Test expected to find one needle
|
||||
for (int nSize = 2; nSize<scope; nSize++) {
|
||||
String needle = newNeedle(nSize, -1);
|
||||
for (int hSize = nSize; hSize<scope; hSize++) {
|
||||
for (int i = 0; i<hSize-nSize; i++) {
|
||||
String haystack = newHaystack(hSize, needle, i);
|
||||
for (int j = 0; j<=i; j++) {
|
||||
int found = haystack.indexOf(needle, j);
|
||||
if (i != found) {
|
||||
System.out.println("("+ae.name()+")(T1) Trying needle["+nSize+"] in haystack["+hSize+"] at offset["+i+"]");
|
||||
System.out.println(" FAILED: Found " + needle + "@" + found + " in " + haystack + " from ["+j+"]");
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
IndexOf test2() { // Test needle with one mismatched character
|
||||
for (int nSize = 2; nSize<scope; nSize++) {
|
||||
for (int hSize = nSize; hSize<scope; hSize++) {
|
||||
String needle = newNeedle(nSize, -1);
|
||||
for (int badPosition = 0; badPosition < nSize; badPosition+=1) {
|
||||
String badNeedle = newNeedle(nSize, badPosition);
|
||||
for (int i = 0; i<hSize-nSize; i++) {
|
||||
String haystack = newHaystack(hSize, needle, i);
|
||||
int found = haystack.indexOf(badNeedle, 1);
|
||||
if (-1 != found) {
|
||||
System.out.println("("+ae.name()+")(T2) Trying bad needle["+nSize+"]["+badPosition+"] in haystack["+hSize+"] at offset["+i+"]");
|
||||
System.out.println(" FAILED: False " + found + " " + haystack + "["+needle+"]["+badNeedle+"]");
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
IndexOf test3() { // Test expected to find first of the repeated needles
|
||||
for (int nSize = 2; nSize<scope; nSize++) {
|
||||
String needle = newNeedle(nSize, -1);
|
||||
for (int hSize = nSize; hSize<scope; hSize++) {
|
||||
for (int i = 0; i<hSize-nSize; i++) {
|
||||
String haystack = newHaystackRepeat(hSize, needle, i);
|
||||
for (int j = 0; j<=i; j++) {
|
||||
int found = haystack.indexOf(needle, j);
|
||||
if (i != found) {
|
||||
System.out.println("("+ae.name()+")(T3) Trying repeaded needle["+nSize+"] in haystack["+hSize+"] at offset["+i+"]");
|
||||
System.out.println(" FAILED: " + found + " " + haystack + "["+needle+"]");
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
IndexOf test4() { // Test needle at unreachable offset
|
||||
for (int nSize = 2; nSize<scope; nSize++) {
|
||||
String needle = newNeedle(nSize, -1);
|
||||
for (int hSize = nSize; hSize<scope; hSize++) {
|
||||
for (int i = 0; i<hSize-nSize; i++) {
|
||||
String haystack = newHaystack(hSize, needle, i);
|
||||
// prefix lookup
|
||||
for (int j = nSize-1; j<i+nSize; j++) {
|
||||
int found = haystack.indexOf(needle, 0, j);
|
||||
if (-1 != found) {
|
||||
System.out.println("("+ae.name()+")(T4) Trying needle["+nSize+"] at offset ["+i+"] in haystack["+hSize+"] upto ["+j+"]");
|
||||
System.out.println(" FAILED: False " + found + " " + haystack + "["+needle+"]");
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
|
||||
// sufix lookup
|
||||
for (int j = i+1; j<hSize; j++) {
|
||||
int found = haystack.indexOf(needle, j);
|
||||
if (-1 != found) {
|
||||
System.out.println("("+ae.name()+")(T4) Trying needle["+nSize+"] at offset ["+i+"] in haystack["+hSize+"] from ["+j+"]");
|
||||
System.out.println(" FAILED: False " + found + " " + haystack + "["+needle+"]");
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
414
test/jdk/java/lang/String/IndexOfBeginEnd.java
Normal file
414
test/jdk/java/lang/String/IndexOfBeginEnd.java
Normal file
|
|
@ -0,0 +1,414 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertThrows;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8302590 8303648
|
||||
* @summary This one is for String.indexOf([int|String],int,int).
|
||||
* @run testng IndexOfBeginEnd
|
||||
*/
|
||||
|
||||
public class IndexOfBeginEnd {
|
||||
|
||||
private static final String STRING_EMPTY = "";
|
||||
private static final String STRING_L1 = "A";
|
||||
private static final String STRING_L2 = "AB";
|
||||
private static final String STRING_L4 = "ABCD";
|
||||
private static final String STRING_LLONG = "ABCDEFGH";
|
||||
private static final String STRING_U1 = "\uFF21";
|
||||
private static final String STRING_U2 = "\uFF21\uFF22";
|
||||
private static final String STRING_LDUPLICATE = "ABABABABAB";
|
||||
private static final String STRING_M11 = "A\uFF21";
|
||||
private static final String STRING_M12 = "\uFF21A";
|
||||
private static final String STRING_UDUPLICATE = "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22";
|
||||
private static final String STRING_SUPPLEMENTARY = "\uD801\uDC00\uD801\uDC01\uFF21A";
|
||||
private static final String STRING_MDUPLICATE1 = "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A";
|
||||
private static final String STRING_MDUPLICATE2 = "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21";
|
||||
|
||||
@DataProvider
|
||||
public Object[][] results() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, (int) 'Z', 0, 0, -1 },
|
||||
|
||||
new Object[] { STRING_L1, (int) 'A', 0, 1, 0 },
|
||||
new Object[] { STRING_L1, (int) 'A', 1, 1, -1 },
|
||||
new Object[] { STRING_L1, (int) 'Z', 0, 1, -1 },
|
||||
|
||||
new Object[] { STRING_L2, (int) 'A', 0, 2, 0 },
|
||||
new Object[] { STRING_L2, (int) 'A', 0, 1, 0 },
|
||||
new Object[] { STRING_L2, (int) 'A', 1, 1, -1 },
|
||||
new Object[] { STRING_L2, (int) 'A', 1, 2, -1 },
|
||||
new Object[] { STRING_L2, (int) 'B', 0, 2, 1 },
|
||||
new Object[] { STRING_L2, (int) 'B', 0, 1, -1 },
|
||||
new Object[] { STRING_L2, (int) 'B', 1, 1, -1 },
|
||||
new Object[] { STRING_L2, (int) 'B', 1, 2, 1 },
|
||||
new Object[] { STRING_L2, (int) 'B', 2, 2, -1 },
|
||||
new Object[] { STRING_L2, (int) 'Z', 0, 2, -1 },
|
||||
|
||||
new Object[] { STRING_L4, (int) 'A', 0, 4, 0 },
|
||||
new Object[] { STRING_L4, (int) 'A', 0, 1, 0 },
|
||||
new Object[] { STRING_L4, (int) 'A', 1, 4, -1 },
|
||||
new Object[] { STRING_L4, (int) 'D', 0, 4, 3 },
|
||||
new Object[] { STRING_L4, (int) 'D', 0, 3, -1 },
|
||||
new Object[] { STRING_L4, (int) 'D', 3, 4, 3 },
|
||||
new Object[] { STRING_L4, (int) 'D', 4, 4, -1 },
|
||||
new Object[] { STRING_L4, (int) 'Z', 0, 4, -1 },
|
||||
|
||||
new Object[] { STRING_LLONG, (int) 'A', 0, 8, 0 },
|
||||
new Object[] { STRING_LLONG, (int) 'A', 0, 1, 0 },
|
||||
new Object[] { STRING_LLONG, (int) 'A', 1, 1, -1 },
|
||||
new Object[] { STRING_LLONG, (int) 'A', 1, 8, -1 },
|
||||
new Object[] { STRING_LLONG, (int) 'H', 0, 8, 7 },
|
||||
new Object[] { STRING_LLONG, (int) 'H', 0, 7, -1 },
|
||||
new Object[] { STRING_LLONG, (int) 'H', 7, 8, 7 },
|
||||
new Object[] { STRING_LLONG, (int) 'H', 8, 8, -1 },
|
||||
new Object[] { STRING_LLONG, (int) 'Z', 0, 8, -1 },
|
||||
|
||||
new Object[] { STRING_U1, (int) '\uFF21', 0, 1, 0 },
|
||||
new Object[] { STRING_U1, (int) '\uFF21', 0, 0, -1 },
|
||||
new Object[] { STRING_U1, (int) '\uFF21', 1, 1, -1 },
|
||||
new Object[] { STRING_U1, (int) 'A', 0, 1, -1 },
|
||||
|
||||
new Object[] { STRING_U2, (int) '\uFF21', 0, 2, 0 },
|
||||
new Object[] { STRING_U2, (int) '\uFF21', 0, 1, 0 },
|
||||
new Object[] { STRING_U2, (int) '\uFF21', 1, 2, -1 },
|
||||
new Object[] { STRING_U2, (int) '\uFF22', 0, 2, 1 },
|
||||
new Object[] { STRING_U2, (int) '\uFF22', 0, 1, -1 },
|
||||
new Object[] { STRING_U2, (int) '\uFF22', 1, 2, 1 },
|
||||
new Object[] { STRING_U2, (int) '\uFF22', 2, 2, -1 },
|
||||
new Object[] { STRING_U2, (int) '\uFF3A', 0, 2, -1 },
|
||||
|
||||
new Object[] { STRING_LDUPLICATE, (int) 'A', 0, 10, 0 },
|
||||
new Object[] { STRING_LDUPLICATE, (int) 'A', 1, 3, 2 },
|
||||
new Object[] { STRING_LDUPLICATE, (int) 'A', 3, 3, -1 },
|
||||
new Object[] { STRING_LDUPLICATE, (int) 'A', 3, 5, 4 },
|
||||
new Object[] { STRING_LDUPLICATE, (int) 'B', 0, 10, 1 },
|
||||
new Object[] { STRING_LDUPLICATE, (int) 'B', 2, 4, 3 },
|
||||
new Object[] { STRING_LDUPLICATE, (int) 'B', 4, 6, 5 },
|
||||
|
||||
new Object[] { STRING_M11, (int) 'A', 0, 2, 0 },
|
||||
new Object[] { STRING_M11, (int) 'A', 0, 1, 0 },
|
||||
new Object[] { STRING_M11, (int) 'A', 1, 2, -1 },
|
||||
new Object[] { STRING_M11, (int) 'A', 2, 2, -1 },
|
||||
new Object[] { STRING_M11, (int) '\uFF21', 0, 2, 1 },
|
||||
new Object[] { STRING_M11, (int) '\uFF21', 0, 1, -1 },
|
||||
new Object[] { STRING_M11, (int) '\uFF21', 1, 2, 1 },
|
||||
new Object[] { STRING_M11, (int) '\uFF21', 2, 2, -1 },
|
||||
new Object[] { STRING_M11, (int) '\uFF3A', 0, 2, -1 },
|
||||
|
||||
new Object[] { STRING_M12, (int) '\uFF21', 0, 2, 0 },
|
||||
new Object[] { STRING_M12, (int) '\uFF21', 0, 1, 0 },
|
||||
new Object[] { STRING_M12, (int) '\uFF21', 1, 2, -1 },
|
||||
new Object[] { STRING_M12, (int) '\uFF21', 2, 2, -1 },
|
||||
new Object[] { STRING_M12, (int) 'A', 0, 2, 1 },
|
||||
new Object[] { STRING_M12, (int) 'A', 0, 1, -1 },
|
||||
new Object[] { STRING_M12, (int) 'A', 1, 2, 1 },
|
||||
new Object[] { STRING_M12, (int) 'A', 2, 2, -1 },
|
||||
new Object[] { STRING_M12, (int) '\uFF3A', 0, 2, -1 },
|
||||
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 0, 10, 0 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 1, 3, 2 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 3, 3, -1 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 3, 5, 4 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 0, 10, 1 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 2, 4, 3 },
|
||||
new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 4, 6, 5 },
|
||||
|
||||
new Object[] { STRING_SUPPLEMENTARY, 'A', 0, 6, 5 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 'A', 2, 6, 5 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 'A', 2, 4, -1 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, 'A', 4, 4, -1 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, '\uFF21', 0, 6, 4 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, '\uFF21', 2, 2, -1 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, '\uFF21', 2, 6, 4 },
|
||||
new Object[] { STRING_SUPPLEMENTARY, '\uFF21', 2, 4, -1 },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
Character.toCodePoint('\uD801', '\uDC00'), 0, 6, 0 },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
Character.toCodePoint('\uD801', '\uDC00'), 0, 3, 0 },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
Character.toCodePoint('\uD801', '\uDC00'), 0, 1, -1 },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
Character.toCodePoint('\uD801', '\uDC00'), 1, 4, -1 },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
Character.toCodePoint('\uD801', '\uDC01'), 0, 6, 2 },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
Character.toCodePoint('\uD801', '\uDC01'), 2, 2, -1 },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
Character.toCodePoint('\uD801', '\uDC01'), 2, 5, 2 },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
Character.toCodePoint('\uD801', '\uDC01'), 2, 3, -1 },
|
||||
new Object[] { STRING_SUPPLEMENTARY,
|
||||
Character.toCodePoint('\uD801', '\uDC01'), 3, 6, -1 },
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] exceptions() {
|
||||
return new Object[][]{
|
||||
new Object[]{STRING_LDUPLICATE, 'A', -1, 0},
|
||||
new Object[]{STRING_LDUPLICATE, 'A', 0, 100},
|
||||
new Object[]{STRING_LDUPLICATE, 'A', -1, 100},
|
||||
new Object[]{STRING_LDUPLICATE, 'A', 3, 1},
|
||||
|
||||
new Object[]{STRING_UDUPLICATE, 'A', -1, 0},
|
||||
new Object[]{STRING_UDUPLICATE, 'A', 0, 100},
|
||||
new Object[]{STRING_UDUPLICATE, 'A', -1, 100},
|
||||
new Object[]{STRING_UDUPLICATE, 'A', 3, 1},
|
||||
|
||||
new Object[]{STRING_MDUPLICATE1, 'A', -1, 0},
|
||||
new Object[]{STRING_MDUPLICATE1, 'A', 0, 100},
|
||||
new Object[]{STRING_MDUPLICATE1, 'A', -1, 100},
|
||||
new Object[]{STRING_MDUPLICATE1, 'A', 3, 1},
|
||||
|
||||
new Object[]{STRING_MDUPLICATE2, 'A', -1, 0},
|
||||
new Object[]{STRING_MDUPLICATE2, 'A', 0, 100},
|
||||
new Object[]{STRING_MDUPLICATE2, 'A', -1, 100},
|
||||
new Object[]{STRING_MDUPLICATE2, 'A', 3, 1},
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] resultsStr() {
|
||||
return new Object[][] {
|
||||
|
||||
new Object[] { STRING_EMPTY, "A", 0, 0, -1 },
|
||||
new Object[] { STRING_EMPTY, "", 0, 0, 0 },
|
||||
|
||||
new Object[] { STRING_L1, "A", 0, 1, 0 },
|
||||
new Object[] { STRING_L1, "A", 1, 1, -1 },
|
||||
new Object[] { STRING_L1, "AB", 0, 1, -1 },
|
||||
new Object[] { STRING_L1, "", 0, 0, 0 },
|
||||
new Object[] { STRING_L1, "", 0, 1, 0 },
|
||||
new Object[] { STRING_L1, "", 1, 1, 1 },
|
||||
|
||||
new Object[] { STRING_L2, "A", 0, 2, 0 },
|
||||
new Object[] { STRING_L2, "A", 0, 1, 0 },
|
||||
new Object[] { STRING_L2, "A", 1, 2, -1 },
|
||||
new Object[] { STRING_L2, "B", 0, 2, 1 },
|
||||
new Object[] { STRING_L2, "B", 1, 2, 1 },
|
||||
new Object[] { STRING_L2, "B", 0, 0, -1 },
|
||||
new Object[] { STRING_L2, "AB", 0, 2, 0 },
|
||||
new Object[] { STRING_L2, "AB", 1, 2, -1 },
|
||||
new Object[] { STRING_L2, "AB", 0, 1, -1 },
|
||||
new Object[] { STRING_L2, "", 0, 2, 0 },
|
||||
new Object[] { STRING_L2, "", 1, 2, 1 },
|
||||
new Object[] { STRING_L2, "", 2, 2, 2 },
|
||||
|
||||
new Object[] { STRING_L4, "ABCD", 0, 4, 0 },
|
||||
new Object[] { STRING_L4, "ABCD", 0, 3, -1 },
|
||||
new Object[] { STRING_L4, "ABCD", 1, 4, -1 },
|
||||
new Object[] { STRING_L4, "BC", 0, 4, 1 },
|
||||
new Object[] { STRING_L4, "BC", 0, 3, 1 },
|
||||
new Object[] { STRING_L4, "BC", 1, 4, 1 },
|
||||
new Object[] { STRING_L4, "BC", 1, 2, -1 },
|
||||
new Object[] { STRING_L4, "BC", 2, 4, -1 },
|
||||
new Object[] { STRING_L4, "A", 0, 4, 0 },
|
||||
new Object[] { STRING_L4, "A", 1, 4, -1 },
|
||||
new Object[] { STRING_L4, "CD", 0, 4, 2 },
|
||||
new Object[] { STRING_L4, "CD", 2, 4, 2 },
|
||||
new Object[] { STRING_L4, "CD", 1, 4, 2 },
|
||||
new Object[] { STRING_L4, "CD", 0, 3, -1 },
|
||||
new Object[] { STRING_L4, "A", 2, 4, -1 },
|
||||
new Object[] { STRING_L4, "A", 2, 2, -1 },
|
||||
new Object[] { STRING_L4, "A", 4, 4, -1 },
|
||||
new Object[] { STRING_L4, "ABCDE", 0, 4, -1 },
|
||||
|
||||
new Object[] { STRING_LLONG, "ABCDEFGH", 0, 8, 0 },
|
||||
new Object[] { STRING_LLONG, "ABCDEFGH", 1, 8, -1 },
|
||||
new Object[] { STRING_LLONG, "ABCDEFGH", 0, 7, -1 },
|
||||
new Object[] { STRING_LLONG, "DEFGH", 0, 8, 3 },
|
||||
new Object[] { STRING_LLONG, "DEFGH", 3, 8, 3 },
|
||||
new Object[] { STRING_LLONG, "DEFGH", 4, 8, -1 },
|
||||
new Object[] { STRING_LLONG, "DEFGH", 0, 7, -1 },
|
||||
new Object[] { STRING_LLONG, "A", 0, 8, 0 },
|
||||
new Object[] { STRING_LLONG, "A", 1, 8, -1 },
|
||||
new Object[] { STRING_LLONG, "A", 0, 0, -1 },
|
||||
new Object[] { STRING_LLONG, "GHI", 0, 8, -1 },
|
||||
new Object[] { STRING_LLONG, "GHI", 8, 8, -1 },
|
||||
new Object[] { STRING_LLONG, "", 4, 4, 4 },
|
||||
new Object[] { STRING_LLONG, "", 4, 8, 4 },
|
||||
new Object[] { STRING_LLONG, "", 8, 8, 8 },
|
||||
|
||||
new Object[] { STRING_U1, "\uFF21", 0, 1, 0 },
|
||||
new Object[] { STRING_U1, "\uFF21", 0, 0, -1 },
|
||||
new Object[] { STRING_U1, "\uFF21", 1, 1, -1 },
|
||||
new Object[] { STRING_U1, "\uFF21A", 0, 1, -1 },
|
||||
|
||||
new Object[] { STRING_U2, "\uFF21\uFF22", 0, 2, 0 },
|
||||
new Object[] { STRING_U2, "\uFF21\uFF22", 1, 2, -1 },
|
||||
new Object[] { STRING_U2, "\uFF22", 0, 2, 1 },
|
||||
new Object[] { STRING_U2, "\uFF22", 0, 1, -1 },
|
||||
new Object[] { STRING_U2, "\uFF22", 1, 2, 1 },
|
||||
new Object[] { STRING_U2, "\uFF21", 1, 2, -1 },
|
||||
new Object[] { STRING_U2, "\uFF21", 0, 1, 0 },
|
||||
new Object[] { STRING_U2, "", 0, 1, 0 },
|
||||
new Object[] { STRING_U2, "", 1, 1, 1 },
|
||||
new Object[] { STRING_U2, "", 2, 2, 2 },
|
||||
|
||||
new Object[] { STRING_M12, "\uFF21A", 0, 2, 0 },
|
||||
new Object[] { STRING_M12, "\uFF21A", 0, 1, -1 },
|
||||
new Object[] { STRING_M12, "\uFF21A", 1, 2, -1 },
|
||||
new Object[] { STRING_M12, "A", 1, 2, 1 },
|
||||
new Object[] { STRING_M12, "A", 0, 2, 1 },
|
||||
new Object[] { STRING_M12, "A", 0, 1, -1 },
|
||||
new Object[] { STRING_M12, "\uFF21", 0, 2, 0 },
|
||||
new Object[] { STRING_M12, "\uFF21", 0, 1, 0 },
|
||||
new Object[] { STRING_M12, "\uFF21", 1, 2, -1 },
|
||||
|
||||
new Object[] { STRING_M11, "A\uFF21", 0, 2, 0 },
|
||||
new Object[] { STRING_M11, "\uFF21", 1, 2, 1 },
|
||||
new Object[] { STRING_M11, "A\uFF21", 1, 2, -1 },
|
||||
new Object[] { STRING_M11, "A\uFF21A", 0, 2, -1 },
|
||||
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
|
||||
0, 10, 0 },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
|
||||
0, 9, -1 },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
|
||||
1, 10, -1 },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
|
||||
1, 10, 1 },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
|
||||
0, 10, 1 },
|
||||
new Object[] {
|
||||
STRING_UDUPLICATE,
|
||||
"\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
|
||||
0, 9, -1 },
|
||||
new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21\uFF22",
|
||||
4, 10, 4 },
|
||||
new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21\uFF22",
|
||||
3, 8, 4 },
|
||||
new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21\uFF22",
|
||||
2, 7, 2 },
|
||||
new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21\uFF22",
|
||||
7, 10, -1 },
|
||||
new Object[] { STRING_UDUPLICATE, "",
|
||||
7, 10, 7 },
|
||||
new Object[] { STRING_UDUPLICATE, "",
|
||||
10, 10, 10 },
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] exceptionsStr() {
|
||||
return new Object[][]{
|
||||
new Object[]{STRING_LDUPLICATE, "", -1, 0},
|
||||
new Object[]{STRING_LDUPLICATE, "", 0, 100},
|
||||
new Object[]{STRING_LDUPLICATE, "", -1, 100},
|
||||
new Object[]{STRING_LDUPLICATE, "", 3, 1},
|
||||
|
||||
new Object[]{STRING_UDUPLICATE, "", -1, 0},
|
||||
new Object[]{STRING_UDUPLICATE, "", 0, 100},
|
||||
new Object[]{STRING_UDUPLICATE, "", -1, 100},
|
||||
new Object[]{STRING_UDUPLICATE, "", 3, 1},
|
||||
|
||||
new Object[]{STRING_MDUPLICATE1, "", -1, 0},
|
||||
new Object[]{STRING_MDUPLICATE1, "", 0, 100},
|
||||
new Object[]{STRING_MDUPLICATE1, "", -1, 100},
|
||||
new Object[]{STRING_MDUPLICATE1, "", 3, 1},
|
||||
|
||||
new Object[]{STRING_MDUPLICATE2, "", -1, 0},
|
||||
new Object[]{STRING_MDUPLICATE2, "", 0, 100},
|
||||
new Object[]{STRING_MDUPLICATE2, "", -1, 100},
|
||||
new Object[]{STRING_MDUPLICATE2, "", 3, 1},
|
||||
|
||||
new Object[]{STRING_LDUPLICATE, "A", -1, 0},
|
||||
new Object[]{STRING_LDUPLICATE, "A", 0, 100},
|
||||
new Object[]{STRING_LDUPLICATE, "A", -1, 100},
|
||||
new Object[]{STRING_LDUPLICATE, "A", 3, 1},
|
||||
|
||||
new Object[]{STRING_UDUPLICATE, "A", -1, 0},
|
||||
new Object[]{STRING_UDUPLICATE, "A", 0, 100},
|
||||
new Object[]{STRING_UDUPLICATE, "A", -1, 100},
|
||||
new Object[]{STRING_UDUPLICATE, "A", 3, 1},
|
||||
|
||||
new Object[]{STRING_MDUPLICATE1, "A", -1, 0},
|
||||
new Object[]{STRING_MDUPLICATE1, "A", 0, 100},
|
||||
new Object[]{STRING_MDUPLICATE1, "A", -1, 100},
|
||||
new Object[]{STRING_MDUPLICATE1, "A", 3, 1},
|
||||
|
||||
new Object[]{STRING_MDUPLICATE2, "A", -1, 0},
|
||||
new Object[]{STRING_MDUPLICATE2, "A", 0, 100},
|
||||
new Object[]{STRING_MDUPLICATE2, "A", -1, 100},
|
||||
new Object[]{STRING_MDUPLICATE2, "A", 3, 1},
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "results")
|
||||
public void testIndexOf(String str, int ch, int from, int to, int expected) {
|
||||
assertEquals(str.indexOf(ch, from, to), expected,
|
||||
String.format("testing String(%s).indexOf(%d,%d,%d)",
|
||||
escapeNonASCIIs(str), ch, from, to));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "exceptions")
|
||||
public void testIndexOf(String str, int ch, int from, int to) {
|
||||
assertThrows(StringIndexOutOfBoundsException.class,
|
||||
() -> str.indexOf(ch, from, to));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "resultsStr")
|
||||
public void testIndexOf(String str, String sub, int from, int to, int expected) {
|
||||
assertEquals(str.indexOf(sub, from, to), expected,
|
||||
String.format("testing String(%s).indexOf(%s,%d,%d)",
|
||||
escapeNonASCIIs(str), escapeNonASCIIs(sub), from, to));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "exceptionsStr")
|
||||
public void testIndexOf(String str, String sub, int from, int to) {
|
||||
assertThrows(StringIndexOutOfBoundsException.class,
|
||||
() -> str.indexOf(sub, from, to));
|
||||
}
|
||||
|
||||
private static String escapeNonASCIIs(String s) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < s.length(); ++i) {
|
||||
char c = s.charAt(i);
|
||||
if (c >= 0x100) {
|
||||
sb.append("\\u").append(Integer.toHexString(c));
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
36
test/jdk/java/lang/String/IndexOfEmptyInEmpty.java
Normal file
36
test/jdk/java/lang/String/IndexOfEmptyInEmpty.java
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
@bug 4096273
|
||||
@summary new String("").indexOf("") must give 0, not -1
|
||||
@author Anand Palaniswamy
|
||||
*/
|
||||
public class IndexOfEmptyInEmpty {
|
||||
public static void main(String[] args) throws Exception {
|
||||
int result = new String("").indexOf("");
|
||||
if (result != 0) {
|
||||
throw new Exception("new String(\"\").indexOf(\"\") must be 0, but got " + result);
|
||||
}
|
||||
}
|
||||
}
|
||||
74
test/jdk/java/lang/String/IsBlank.java
Normal file
74
test/jdk/java/lang/String/IsBlank.java
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Basic isBlank functionality
|
||||
* @bug 8200436
|
||||
* @run main/othervm IsBlank
|
||||
*/
|
||||
|
||||
public class IsBlank {
|
||||
public static void main(String... arg) {
|
||||
testIsBlank();
|
||||
testWhitespace();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test with strings
|
||||
*/
|
||||
static void testIsBlank() {
|
||||
test("", true);
|
||||
test(" ", true);
|
||||
test(" \t", true);
|
||||
test(" \u1680", true);
|
||||
test(" abc ", false);
|
||||
test(" abc\u2022", false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test full whitespace range
|
||||
*/
|
||||
static void testWhitespace() {
|
||||
StringBuilder sb = new StringBuilder(64);
|
||||
IntStream.range(1, 0xFFFF).filter(c -> Character.isWhitespace(c))
|
||||
.forEach(c -> sb.append((char)c));
|
||||
String whiteSpace = sb.toString();
|
||||
|
||||
test(whiteSpace, true);
|
||||
test(whiteSpace + "abc" + whiteSpace, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Raise an exception if the two inputs are not equivalent.
|
||||
*/
|
||||
static void test(String input, boolean expected) {
|
||||
if (input.isBlank() != expected) {
|
||||
System.err.format("Failed test, Input: %s, Expected: %b%n", input, expected);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
47
test/jdk/java/lang/String/IsEmpty.java
Normal file
47
test/jdk/java/lang/String/IsEmpty.java
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Basic isEmpty functionality
|
||||
* @bug 6189137
|
||||
*/
|
||||
|
||||
public class IsEmpty {
|
||||
private static String [] tests = { "", " ", "a",
|
||||
"It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way- in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only. -- Charles Dickens, Tale of Two Cities"
|
||||
};
|
||||
|
||||
public static void main(String [] args) {
|
||||
for (int i = 0; i < tests.length; i++) {
|
||||
String s = tests[i];
|
||||
int len = s.length();
|
||||
boolean empty = s.isEmpty();
|
||||
|
||||
if ((len != 0 && empty) || (len == 0 && !empty))
|
||||
throw new RuntimeException("String \"" + s + "\": "
|
||||
+ " isEmpty = " + empty
|
||||
+ ", length = " + len);
|
||||
}
|
||||
}
|
||||
}
|
||||
99
test/jdk/java/lang/String/Lines.java
Normal file
99
test/jdk/java/lang/String/Lines.java
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Basic lines functionality
|
||||
* @bug 8200380
|
||||
* @run main/othervm Lines
|
||||
*/
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.stream.Stream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.StringReader;
|
||||
|
||||
public class Lines {
|
||||
public static void main(String... arg) {
|
||||
testLines();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test with strings
|
||||
*/
|
||||
static void testLines() {
|
||||
testString("");
|
||||
testString(" ");
|
||||
testString("\n");
|
||||
testString("\n\n\n");
|
||||
testString("\r\r\r");
|
||||
testString("\r\n\r\n\r\n");
|
||||
testString("\n\r\r\n");
|
||||
testString("abc\ndef\nghi\n");
|
||||
testString("abc\ndef\nghi");
|
||||
testString("abc\rdef\rghi\r");
|
||||
testString("abc\rdef\rghi");
|
||||
testString("abc\r\ndef\r\nghi\r\n");
|
||||
testString("abc\r\ndef\r\nghi");
|
||||
|
||||
testString("\2022");
|
||||
testString("\2022\n");
|
||||
testString("\2022\n\2022\n\2022\n");
|
||||
testString("\2022\r\2022\r\2022\r");
|
||||
testString("\2022\r\n\2022\r\n\2022\r\n");
|
||||
testString("\2022\n\2022\r\2022\r\n");
|
||||
testString("abc\2022\ndef\2022\nghi\2022\n");
|
||||
testString("abc\2022\ndef\2022\nghi\2022");
|
||||
testString("abc\2022\rdef\2022\rghi\2022\r");
|
||||
testString("abc\2022\rdef\2022\rghi\2022");
|
||||
testString("abc\2022\r\ndef\2022\r\nghi\2022\r\n");
|
||||
testString("abc\2022\r\ndef\2022\r\nghi\2022");
|
||||
testString("\2022\n\n\n");
|
||||
}
|
||||
|
||||
static void testString(String string) {
|
||||
Stream<String> lines = string.lines();
|
||||
Stream<String> brLines = new BufferedReader(new StringReader(string)).lines();
|
||||
|
||||
Iterator<String> iterator = lines.iterator();
|
||||
Iterator<String> brIterator = brLines.iterator();
|
||||
int count = 0;
|
||||
|
||||
while (iterator.hasNext() && brIterator.hasNext()) {
|
||||
count++;
|
||||
String line = iterator.next();
|
||||
String brLine = brIterator.next();
|
||||
|
||||
if (!line.equals(brLine)) {
|
||||
String replace = string.replaceAll("\n", "\\n").replaceAll("\r", "\\r");
|
||||
System.err.format("Mismatch at line %d of \"%s\"%n", count, replace);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
if (iterator.hasNext() || brIterator.hasNext()) {
|
||||
System.err.format("Mismatch after line %d of \"%s\"%n", count, string);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
335
test/jdk/java/lang/String/LiteralReplace.java
Normal file
335
test/jdk/java/lang/String/LiteralReplace.java
Normal file
|
|
@ -0,0 +1,335 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2019, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8058779 8054307 8222955
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.RandomFactory
|
||||
* @run testng LiteralReplace
|
||||
* @summary Basic tests of String.replace(CharSequence, CharSequence)
|
||||
* @key randomness
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.Random;
|
||||
|
||||
import jdk.test.lib.RandomFactory;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
public class LiteralReplace {
|
||||
|
||||
@Test(dataProvider="sourceTargetReplacementExpected")
|
||||
public void testExpected(String source, String target,
|
||||
String replacement, String expected)
|
||||
{
|
||||
String canonical = canonicalReplace(source, target, replacement);
|
||||
if (!canonical.equals(expected)) {
|
||||
fail("Canonical: " + canonical + " != " + expected);
|
||||
}
|
||||
test0(source, target, replacement, expected);
|
||||
}
|
||||
|
||||
@Test(dataProvider="sourceTargetReplacement")
|
||||
public void testCanonical(String source, String target,
|
||||
String replacement)
|
||||
{
|
||||
String canonical = canonicalReplace(source, target, replacement);
|
||||
test0(source, target, replacement, canonical);
|
||||
}
|
||||
|
||||
private void test0(String source, String target, String replacement,
|
||||
String expected)
|
||||
{
|
||||
String result = source.replace(target, replacement);
|
||||
if (!result.equals(expected)) {
|
||||
fail(result + " != " + expected);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider="sourceTargetReplacementWithNull",
|
||||
expectedExceptions = {NullPointerException.class})
|
||||
public void testNPE(String source, String target, String replacement) {
|
||||
source.replace(target, replacement);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = {OutOfMemoryError.class})
|
||||
public void testOOM() {
|
||||
"1".repeat(65537).replace("1", "2".repeat(65537));
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public static Object[][] sourceTargetReplacementExpected() {
|
||||
return new Object[][] {
|
||||
{"aaa", "aa", "b", "ba"},
|
||||
{"abcdefgh", "def", "DEF", "abcDEFgh"},
|
||||
{"abcdefgh", "123", "DEF", "abcdefgh"},
|
||||
{"abcdefgh", "abcdefghi", "DEF", "abcdefgh"},
|
||||
{"abcdefghabc", "abc", "DEF", "DEFdefghDEF"},
|
||||
{"abcdefghdef", "def", "", "abcgh"},
|
||||
{"abcdefgh", "", "_", "_a_b_c_d_e_f_g_h_"},
|
||||
{"", "", "", ""},
|
||||
{"", "a", "b", ""},
|
||||
{"", "", "abc", "abc"},
|
||||
{"abcdefgh", "abcdefgh", "abcdefgh", "abcdefgh"},
|
||||
{"abcdefgh", "abcdefgh", "abcdefghi", "abcdefghi"},
|
||||
{"abcdefgh", "abcdefgh", "", ""},
|
||||
{"abcdabcd", "abcd", "", ""},
|
||||
{"aaaaaaaaa", "aa", "_X_", "_X__X__X__X_a"},
|
||||
{"aaaaaaaaa", "aa", "aaa", "aaaaaaaaaaaaa"},
|
||||
{"aaaaaaaaa", "aa", "aa", "aaaaaaaaa"},
|
||||
{"a.c.e.g.", ".", "-", "a-c-e-g-"},
|
||||
{"abcdefgh", "[a-h]", "X", "abcdefgh"},
|
||||
{"aa+", "a+", "", "a"},
|
||||
{"^abc$", "abc", "x", "^x$"},
|
||||
{"abc", "b", "_", "a_c"},
|
||||
{"abc", "bc", "_", "a_"},
|
||||
{"abc".repeat(65537) + "end", "b", "_XYZ_", "a_XYZ_c".repeat(65537) + "end"},
|
||||
{"abc".repeat(65537) + "end", "a", "_", "_bc".repeat(65537) + "end"},
|
||||
{"a".repeat(65537), "a", "", ""},
|
||||
{"ab".repeat(65537), "a", "", "b".repeat(65537)},
|
||||
{"ab".repeat(65537), "ab", "", ""},
|
||||
{"b" + "ab".repeat(65537), "ab", "", "b"},
|
||||
|
||||
// more with non-latin1 characters
|
||||
{"\u4e00\u4e00\u4e00",
|
||||
"\u4e00\u4e00",
|
||||
"\u4e01",
|
||||
"\u4e01\u4e00"},
|
||||
|
||||
{"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08",
|
||||
"\u4e03\u4e04\u4e05",
|
||||
"\u4e10\u4e11\u4e12",
|
||||
"\u4e00\u4e01\u4e02\u4e10\u4e11\u4e12\u4e06\u4e07\u4e08"},
|
||||
|
||||
{"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08",
|
||||
"ABC",
|
||||
"\u4e10\u4e11\u4e12",
|
||||
"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08"},
|
||||
|
||||
{"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e02\u4e03\u4e07\u4e08",
|
||||
"\u4e02\u4e03",
|
||||
"\u4e12\u4e13",
|
||||
"\u4e00\u4e01\u4e12\u4e13\u4e04\u4e12\u4e13\u4e07\u4e08"},
|
||||
|
||||
{"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e02\u4e03\u4e07\u4e08",
|
||||
"\u4e02\u4e03",
|
||||
"ab",
|
||||
"\u4e00\u4e01ab\u4e04ab\u4e07\u4e08"},
|
||||
|
||||
{"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07",
|
||||
"",
|
||||
"_",
|
||||
"_\u4e00_\u4e01_\u4e02_\u4e03_\u4e04_\u4e05_\u4e06_\u4e07_"},
|
||||
{"^\u4e00\u4e01\u4e02$",
|
||||
"\u4e00\u4e01\u4e02",
|
||||
"\u4e03",
|
||||
"^\u4e03$"},
|
||||
|
||||
{"", "\u4e00", "\u4e01", ""},
|
||||
{"", "", "\u4e00\u4e01\u4e02", "\u4e00\u4e01\u4e02"},
|
||||
|
||||
{"^\u4e00\u4e01\u4e02$",
|
||||
"\u4e00\u4e01\u4e02",
|
||||
"X",
|
||||
"^X$"},
|
||||
|
||||
{"abcdefgh",
|
||||
"def",
|
||||
"\u4e01",
|
||||
"abc\u4e01gh"},
|
||||
|
||||
{"abcdefgh",
|
||||
"def",
|
||||
"\u4e01\u4e02",
|
||||
"abc\u4e01\u4e02gh"},
|
||||
|
||||
{"abcdefabcgh",
|
||||
"abc",
|
||||
"\u4e01\u4e02",
|
||||
"\u4e01\u4e02def\u4e01\u4e02gh"},
|
||||
|
||||
{"abcdefabcghabc",
|
||||
"abc",
|
||||
"\u4e01\u4e02",
|
||||
"\u4e01\u4e02def\u4e01\u4e02gh\u4e01\u4e02"},
|
||||
|
||||
{"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05",
|
||||
"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05",
|
||||
"abcd",
|
||||
"abcd"},
|
||||
|
||||
{"\u4e00\u4e01",
|
||||
"\u4e00\u4e01",
|
||||
"abcdefg",
|
||||
"abcdefg"},
|
||||
|
||||
{"\u4e00\u4e01xyz",
|
||||
"\u4e00\u4e01",
|
||||
"abcdefg",
|
||||
"abcdefgxyz"},
|
||||
|
||||
{"\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00",
|
||||
"\u4e00\u4e00",
|
||||
"\u4e00\u4e00\u4e00",
|
||||
"\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00"},
|
||||
|
||||
{"\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00",
|
||||
"\u4e00\u4e00\u4e00",
|
||||
"\u4e00\u4e00",
|
||||
"\u4e00\u4e00\u4e00\u4e00"},
|
||||
|
||||
{"\u4e00.\u4e01.\u4e02.\u4e03.\u4e04.",
|
||||
".",
|
||||
"-",
|
||||
"\u4e00-\u4e01-\u4e02-\u4e03-\u4e04-"},
|
||||
|
||||
{"\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00",
|
||||
"\u4e00",
|
||||
"",
|
||||
""},
|
||||
|
||||
{"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05",
|
||||
"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05",
|
||||
"",
|
||||
""},
|
||||
|
||||
{"\u4e01\u4e02\u4e03", "\u4e02", "\u4e02", "\u4e01\u4e02\u4e03"},
|
||||
{"\u4e01\u4e02\u4e03", "\u4e02", "\u4e04", "\u4e01\u4e04\u4e03"},
|
||||
{"\u4e01\u4e02\u4e03", "\u4e02", "_", "\u4e01_\u4e03"},
|
||||
{"a\u4e02c", "\u4e02", "_", "a_c"},
|
||||
{"\u4e01@\u4e03", "@", "_", "\u4e01_\u4e03"},
|
||||
{"\u4e01@\u4e03", "@", "\u4e02", "\u4e01\u4e02\u4e03"},
|
||||
{"\u4e01\u4e02\u4e03", "\u4e02\u4e03", "\u4e02\u4e03", "\u4e01\u4e02\u4e03"},
|
||||
{"\u4e01\u4e02\u4e03", "\u4e02\u4e03", "\u4e04\u4e05", "\u4e01\u4e04\u4e05"},
|
||||
{"\u4e01\u4e02\u4e03", "\u4e02\u4e03", "\u4e06", "\u4e01\u4e06"},
|
||||
{"\u4e01\u4e02\u4e03", "\u4e02\u4e03", "<>", "\u4e01<>"},
|
||||
{"@\u4e02\u4e03", "\u4e02\u4e03", "<>", "@<>"},
|
||||
{"\u4e01@@", "\u4e01@", "", "@"},
|
||||
{"\u4e01@@", "\u4e01@", "#", "#@"},
|
||||
{"\u4e01@@", "\u4e01@", "\u4e09", "\u4e09@"},
|
||||
{"\u4e01@@", "\u4e01@", "#\u4e09", "#\u4e09@"},
|
||||
{"\u4e01\u4e02\u4e03".repeat(32771) + "end", "\u4e02", "\u4e02", "\u4e01\u4e02\u4e03".repeat(32771) + "end"},
|
||||
{"\u4e01\u4e02\u4e03".repeat(32771) + "end", "\u4e02", "\u4e04", "\u4e01\u4e04\u4e03".repeat(32771) + "end"},
|
||||
{"\u4e01\u4e02\u4e03".repeat(32771) + "end", "\u4e02", "\u4e04\u4e05", "\u4e01\u4e04\u4e05\u4e03".repeat(32771) + "end"},
|
||||
{"\u4e01\u4e02\u4e03".repeat(32771) + "end", "\u4e02", "_", "\u4e01_\u4e03".repeat(32771) + "end"},
|
||||
{"\u4e01_\u4e03".repeat(32771) + "end", "_", "_", "\u4e01_\u4e03".repeat(32771) + "end"},
|
||||
{"\u4e01_\u4e03".repeat(32771) + "end", "_", "\u4e06", "\u4e01\u4e06\u4e03".repeat(32771) + "end"},
|
||||
{"\u4e01_\u4e03".repeat(32771) + "end", "_", "\u4e06\u4e06", "\u4e01\u4e06\u4e06\u4e03".repeat(32771) + "end"},
|
||||
{"X_Y".repeat(32771) + "end", "_", "\u4e07", "X\u4e07Y".repeat(32771) + "end"},
|
||||
{"X_Y".repeat(32771) + "end", "_", "\u4e07\u4e08", "X\u4e07\u4e08Y".repeat(32771) + "end"},
|
||||
{"X_Y".repeat(32771) + "end", "_", ".\u4e08.", "X.\u4e08.Y".repeat(32771) + "end"},
|
||||
{"\u4e0a".repeat(32771), "\u4e0a", "", ""},
|
||||
{"\u4e0a\u4e0b".repeat(32771), "\u4e0a", "", "\u4e0b".repeat(32771)},
|
||||
{"\u4e0a\u4e0b".repeat(32771), "\u4e0b", "", "\u4e0a".repeat(32771)},
|
||||
{"\u4e0a\u4e0b".repeat(32771), "\u4e0a\u4e0b", "", ""},
|
||||
{"\u4e0b" + "\u4e0a\u4e0b".repeat(32771), "\u4e0a\u4e0b", "", "\u4e0b"},
|
||||
{"\u4e0a\u4e0b".repeat(32771) + "\u4e0a", "\u4e0a\u4e0b", "", "\u4e0a"},
|
||||
{"\u4e0b" + "\u4e0a\u4e0b".repeat(32771) + "\u4e0a", "\u4e0a\u4e0b", "", "\u4e0b\u4e0a"},
|
||||
{"b" + "\u4e0a\u4e0b".repeat(32771), "\u4e0a\u4e0b", "", "b"},
|
||||
{"\u4e0a\u4e0b".repeat(32771) + "a", "\u4e0a\u4e0b", "", "a"},
|
||||
{"b" + "\u4e0a\u4e0b".repeat(32771) + "a", "\u4e0a\u4e0b", "", "ba"},
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public static Iterator<Object[]> sourceTargetReplacement() {
|
||||
ArrayList<Object[]> list = new ArrayList<>();
|
||||
for (int maxSrcLen = 1; maxSrcLen <= (1 << 10); maxSrcLen <<= 1) {
|
||||
for (int maxTrgLen = 1; maxTrgLen <= (1 << 10); maxTrgLen <<= 1) {
|
||||
for (int maxPrlLen = 1; maxPrlLen <= (1 << 10); maxPrlLen <<= 1) {
|
||||
list.add(makeArray(makeRandomString(maxSrcLen),
|
||||
makeRandomString(maxTrgLen),
|
||||
makeRandomString(maxPrlLen)));
|
||||
|
||||
String source = makeRandomString(maxSrcLen);
|
||||
list.add(makeArray(source,
|
||||
mekeRandomSubstring(source, maxTrgLen),
|
||||
makeRandomString(maxPrlLen)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public static Iterator<Object[]> sourceTargetReplacementWithNull() {
|
||||
ArrayList<Object[]> list = new ArrayList<>();
|
||||
Object[] arr = {null, "", "a", "b", "string", "str", "ababstrstr"};
|
||||
for (int i = 0; i < arr.length; ++i) {
|
||||
for (int j = 0; j < arr.length; ++j) {
|
||||
for (int k = 0; k < arr.length; ++k) {
|
||||
if (arr[i] != null && (arr[j] == null || arr[k] == null)) {
|
||||
list.add(makeArray(arr[i], arr[j], arr[k]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
// utilities
|
||||
|
||||
/**
|
||||
* How the String.replace(CharSequence, CharSequence) used to be implemented
|
||||
*/
|
||||
private static String canonicalReplace(String source, String target, String replacement) {
|
||||
return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
|
||||
source).replaceAll(Matcher.quoteReplacement(replacement.toString()));
|
||||
}
|
||||
|
||||
private static final Random random = RandomFactory.getRandom();
|
||||
|
||||
private static final char[] CHARS = ("qwertyuiop[]12345678" +
|
||||
"90-=\\`asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+|QWERTYUIOP{" +
|
||||
"}ASDFGHJKL:\"ZXCVBNM<>?\n\r\t\u0444\u044B\u0432\u0430").toCharArray();
|
||||
|
||||
private static String makeRandomString(int maxLen) {
|
||||
int len = random.nextInt(maxLen);
|
||||
char[] buf = new char[len];
|
||||
for (int i = 0; i < len; ++i) {
|
||||
buf[i] = CHARS[random.nextInt(CHARS.length)];
|
||||
}
|
||||
return new String(buf);
|
||||
}
|
||||
|
||||
private static String mekeRandomSubstring(String source, int maxLen) {
|
||||
if (source.isEmpty()) {
|
||||
return source;
|
||||
}
|
||||
int pos = random.nextInt(source.length());
|
||||
int len = Integer.min(source.length() - pos,
|
||||
random.nextInt(maxLen));
|
||||
return source.substring(pos, pos + len);
|
||||
}
|
||||
|
||||
private static Object[] makeArray(Object... array) {
|
||||
return array;
|
||||
}
|
||||
}
|
||||
84
test/jdk/java/lang/String/NonCharacterMapping.java
Normal file
84
test/jdk/java/lang/String/NonCharacterMapping.java
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2022, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 5101626
|
||||
* @summary Case conversion should not trip over non-character code points.
|
||||
*/
|
||||
|
||||
import java.util.Locale;
|
||||
import static java.util.Locale.ENGLISH;
|
||||
|
||||
public class NonCharacterMapping {
|
||||
|
||||
private static final Locale TURKISH = Locale.of("tr");
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (Character.toLowerCase('\uFFFF') != '\uFFFF') {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (Character.toUpperCase('\uFFFF') != '\uFFFF') {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (Character.toTitleCase('\uFFFF') != '\uFFFF') {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (!"\uFFFF".toLowerCase(ENGLISH).equals("\uFFFF")) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (!"\uFFFF".toUpperCase(ENGLISH).equals("\uFFFF")) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (!"\uFFFF".toLowerCase(TURKISH).equals("\uFFFF")) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (!"\uFFFF".toUpperCase(TURKISH).equals("\uFFFF")) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (!"A\uFFFF".toLowerCase(ENGLISH).equals("a\uFFFF")) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (!"A\uFFFF".toUpperCase(ENGLISH).equals("A\uFFFF")) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (!"A\uFFFF".toLowerCase(TURKISH).equals("a\uFFFF")) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (!"A\uFFFF".toUpperCase(TURKISH).equals("A\uFFFF")) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (!"a\uFFFF".toLowerCase(ENGLISH).equals("a\uFFFF")) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (!"a\uFFFF".toUpperCase(ENGLISH).equals("A\uFFFF")) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (!"a\uFFFF".toLowerCase(TURKISH).equals("a\uFFFF")) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (!"a\uFFFF".toUpperCase(TURKISH).equals("A\uFFFF")) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
85
test/jdk/java/lang/String/OrThrowTest.java
Normal file
85
test/jdk/java/lang/String/OrThrowTest.java
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2022, 2025, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8286287 8288589
|
||||
* @summary Tests for *OrThrow() shared secret methods.
|
||||
* @run testng OrThrowTest
|
||||
* @modules jdk.charsets
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HexFormat;
|
||||
import static java.nio.charset.StandardCharsets.UTF_16;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Test
|
||||
public class OrThrowTest {
|
||||
private final static byte[] MALFORMED_UTF16 = {(byte)0x00, (byte)0x20, (byte)0x00};
|
||||
private final static String MALFORMED_WINDOWS_1252 = "\u0080\u041e";
|
||||
private final static Charset WINDOWS_1252 = Charset.forName("windows-1252");
|
||||
|
||||
/**
|
||||
* Verifies {@code uncheckedNewStringOrThrow()} throws a {@link CharacterCodingException}.
|
||||
* The method is invoked by {@code Files.readString()} method.
|
||||
*/
|
||||
@Test
|
||||
public void uncheckedNewStringOrThrowTest() throws IOException {
|
||||
var f = Files.createTempFile(null, null);
|
||||
try (var fos = Files.newOutputStream(f)) {
|
||||
fos.write(MALFORMED_UTF16);
|
||||
var read = Files.readString(f, UTF_16);
|
||||
throw new RuntimeException("Exception should be thrown for a malformed input. Bytes read: " +
|
||||
HexFormat.of()
|
||||
.withPrefix("x")
|
||||
.withUpperCase()
|
||||
.formatHex(read.getBytes(UTF_16)));
|
||||
} catch (CharacterCodingException cce) {
|
||||
// success
|
||||
} finally {
|
||||
Files.delete(f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies {@code uncheckedGetBytesOrThrow()} throws a {@link CharacterCodingException}.
|
||||
* The method is invoked by {@code Files.writeString()} method.
|
||||
*/
|
||||
@Test
|
||||
public void uncheckedGetBytesOrThrowTest() throws IOException {
|
||||
var f = Files.createTempFile(null, null);
|
||||
try {
|
||||
Files.writeString(f, MALFORMED_WINDOWS_1252, WINDOWS_1252);
|
||||
throw new RuntimeException("Exception should be thrown");
|
||||
} catch (CharacterCodingException cce) {
|
||||
// success
|
||||
} finally {
|
||||
Files.delete(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
98
test/jdk/java/lang/String/Regex.java
Normal file
98
test/jdk/java/lang/String/Regex.java
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2003, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4808962
|
||||
* @summary Unit tests for String regex methods
|
||||
*/
|
||||
|
||||
|
||||
public class Regex {
|
||||
|
||||
static void ck(boolean x, boolean ans) throws Exception {
|
||||
if (x != ans)
|
||||
throw new Exception("Test failed");
|
||||
}
|
||||
|
||||
static void ck(String x, String ans) throws Exception {
|
||||
if (!x.equals(ans))
|
||||
throw new Exception("Test failed");
|
||||
}
|
||||
|
||||
static void ck(String[] x, String[] ans) throws Exception {
|
||||
if (x.length != ans.length)
|
||||
throw new Exception("Test failed");
|
||||
for (int i = 0; i < x.length; i++) {
|
||||
if (!x[i].equals(ans[i]))
|
||||
throw new Exception("Test failed");
|
||||
}
|
||||
}
|
||||
|
||||
static void testLiteralReplacement() throws Exception {
|
||||
// Test straightforward replacement
|
||||
String data = "abcdefghi";
|
||||
String result = data.replace("def", "abc");
|
||||
if (!result.equals("abcabcghi"))
|
||||
throw new Exception("Test failed");
|
||||
|
||||
// Test replacement with target that has metacharacters
|
||||
data = "abc(def)?ghi";
|
||||
result = data.replace("(def)?", "abc");
|
||||
if (!result.equals("abcabcghi"))
|
||||
throw new Exception("Test failed");
|
||||
|
||||
// Test replacement with replacement that has metacharacters
|
||||
data = "abcdefghi";
|
||||
result = data.replace("def", "\\ab$c");
|
||||
if (!result.equals("abc\\ab$cghi"))
|
||||
throw new Exception("Test failed");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// These don't need to be thorough, they just need to check
|
||||
// that we're properly hooked up to java.util.regex
|
||||
|
||||
String foo = "boo:and:foo";
|
||||
|
||||
ck(foo.matches("b+"), false);
|
||||
ck(foo.matches("o+"), false);
|
||||
ck(foo.matches("b..:and:f.*"), true);
|
||||
|
||||
ck(foo.replaceAll("oo", "uu"), "buu:and:fuu");
|
||||
ck(foo.replaceAll("o+", "<$0>"), "b<oo>:and:f<oo>");
|
||||
|
||||
ck(foo.replaceFirst("oo", "uu"), "buu:and:foo");
|
||||
ck(foo.replaceFirst("o+", "<$0>"), "b<oo>:and:foo");
|
||||
|
||||
ck(foo.split(":"), new String[] { "boo", "and", "foo" });
|
||||
ck(foo.split("o"), new String[] { "b", "", ":and:f" });
|
||||
|
||||
ck(foo.split(":", 2), new String[] { "boo", "and:foo" });
|
||||
ck(foo.split("o", -2), new String[] { "b", "", ":and:f", "", "" });
|
||||
|
||||
testLiteralReplacement();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
56
test/jdk/java/lang/String/RegionMatches.java
Normal file
56
test/jdk/java/lang/String/RegionMatches.java
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2023, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 4016509 8316879
|
||||
* @summary test regionMatches corner cases
|
||||
* @run junit RegionMatches
|
||||
*/
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class RegionMatches {
|
||||
|
||||
private final String s1_LATIN1 = "abc";
|
||||
private final String s2_LATIN1 = "def";
|
||||
|
||||
private final String s1_UTF16 = "\u041e\u0434\u043d\u0430\u0436\u0434\u044b";
|
||||
private final String s2_UTF16 = "\u0432\u0441\u0442\u0443\u0434\u0435\u043d";
|
||||
|
||||
@Test
|
||||
public void TestLATIN1() {
|
||||
// Test for 4016509
|
||||
boolean result = s1_LATIN1.regionMatches(0, s2_LATIN1, 0, Integer.MIN_VALUE);
|
||||
assertTrue(result, "Integer overflow in RegionMatches when comparing LATIN1 strings");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestUTF16() throws UnsupportedEncodingException{
|
||||
// Test for 8316879
|
||||
boolean result = s1_UTF16.regionMatches(0, s2_UTF16, 0, Integer.MIN_VALUE + 1);
|
||||
assertTrue(result, "Integer overflow in RegionMatches when comparing UTF16 strings");
|
||||
}
|
||||
}
|
||||
50
test/jdk/java/lang/String/SBConstructor.java
Normal file
50
test/jdk/java/lang/String/SBConstructor.java
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4915187
|
||||
* @summary Test java.lang.String constructor that takes StringBuilder
|
||||
* @key randomness
|
||||
*/
|
||||
import java.util.*;
|
||||
|
||||
public class SBConstructor {
|
||||
private static Random rnd = new Random();
|
||||
public static void main (String[] argvs) throws Exception {
|
||||
for (int i=0; i<1000; i++) {
|
||||
int length = rnd.nextInt(20) + 1;
|
||||
StringBuffer testStringBuffer = new StringBuffer();
|
||||
StringBuilder testStringBuilder = new StringBuilder();
|
||||
for(int x=0; x<length; x++) {
|
||||
char aChar = (char)rnd.nextInt();
|
||||
testStringBuffer.append(aChar);
|
||||
testStringBuilder.append(aChar);
|
||||
}
|
||||
String testString1 = new String(testStringBuffer);
|
||||
String testString2 = new String(testStringBuilder);
|
||||
if (!testString1.equals(testString2))
|
||||
throw new RuntimeException("Test failure");
|
||||
}
|
||||
}
|
||||
}
|
||||
353
test/jdk/java/lang/String/SpecialCasingTest.java
Normal file
353
test/jdk/java/lang/String/SpecialCasingTest.java
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2022, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4397357 6565620 6959267 7070436 7198195 8041791 8032446 8072600
|
||||
* 8221431
|
||||
* @summary Confirm special case mappings are handled correctly.
|
||||
* @library /lib/testlibrary/java/lang
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class SpecialCasingTest {
|
||||
|
||||
private static boolean err = false;
|
||||
|
||||
// Locales which are used for testing
|
||||
private static List<Locale> locales = new ArrayList<>();
|
||||
static {
|
||||
locales.add(Locale.of("az"));
|
||||
locales.addAll(java.util.Arrays.asList(Locale.getAvailableLocales()));
|
||||
}
|
||||
|
||||
// Default locale
|
||||
private static String defaultLang;
|
||||
|
||||
// True if the default language is az, lt, or tr which has locale-specific
|
||||
// mappings.
|
||||
private static boolean specificLocale;
|
||||
|
||||
// Additional test cases
|
||||
// Pseudo-locales which are used here:
|
||||
// L1: locales other than lt
|
||||
// L2: locales other than az and tr
|
||||
// L3: locales other than az, lt and tr
|
||||
private static final String[] additionalTestData = {
|
||||
// Format:
|
||||
// <code>; <lower>; <title>; <upper>; (<condition_list>)
|
||||
|
||||
// Counterpart of Final_Sigma test case
|
||||
// 03A3; 03C2; 03A3; 03A3; Final_Sigma
|
||||
"03A3; 03C3; 03A3; 03A3; SunSpecific_Not_Final_Sigma1",
|
||||
"03A3; 03C3; 03A3; 03A3; SunSpecific_Not_Final_Sigma2",
|
||||
|
||||
// Counterpart of After_Soft_Dotted test case
|
||||
// 0307; 0307; ; ; lt After_Soft_Dotted
|
||||
"0307; 0307; 0307; 0307; L1 After_Soft_Dotted",
|
||||
"0307; 0307; 0307; 0307; lt SunSpecific_Not_After_Soft_Dotted",
|
||||
"0307; 0307; 0307; 0307; L1 SunSpecific_Not_After_Soft_Dotted",
|
||||
|
||||
// Counterpart of More_Above test cases
|
||||
// 0049; 0069 0307; 0049; 0049; lt More_Above
|
||||
"0049; 0131 ; 0049; 0049; az More_Above",
|
||||
"0049; 0131 ; 0049; 0049; tr More_Above",
|
||||
"0049; 0069 ; 0049; 0049; L3 More_Above",
|
||||
"0049; 0069 ; 0049; 0049; lt SunSpecific_Not_More_Above",
|
||||
"0049; 0131 ; 0049; 0049; az SunSpecific_Not_More_Above",
|
||||
"0049; 0131 ; 0049; 0049; tr SunSpecific_Not_More_Above",
|
||||
"0049; 0069 ; 0049; 0049; L3 SunSpecific_Not_More_Above",
|
||||
// 004A; 006A 0307; 004A; 004A; lt More_Above
|
||||
"004A; 006A ; 004A; 004A; L1 More_Above",
|
||||
"004A; 006A ; 004A; 004A; lt SunSpecific_Not_More_Above",
|
||||
"004A; 006A ; 004A; 004A; L1 SunSpecific_Not_More_Above",
|
||||
// 012E; 012F 0307; 012E; 012E; lt More_Above
|
||||
"012E; 012F ; 012E; 012E; L1 More_Above",
|
||||
"012E; 012F ; 012E; 012E; lt SunSpecific_Not_More_Above",
|
||||
"012E; 012F ; 012E; 012E; L1 SunSpecific_Not_More_Above",
|
||||
|
||||
// Counterpart of After_I test cases
|
||||
// 0307; ; 0307; 0307; tr After_I
|
||||
// 0307; ; 0307; 0307; az After_I
|
||||
"0307; 0307 0307; 0307; 0307; lt After_I",
|
||||
"0307; 0307 ; 0307; 0307; L3 After_I",
|
||||
"0307; 0307 ; 0307; 0307; tr SunSpecific_Not_After_I",
|
||||
"0307; 0307 ; 0307; 0307; az SunSpecific_Not_After_I",
|
||||
"0307; 0307 ; 0307; 0307; L2 SunSpecific_Not_After_I",
|
||||
|
||||
// Counterpart of Not_Before_Dot test cases
|
||||
// 0049; 0131 ; 0049; 0049; tr Not_Before_Dot
|
||||
// 0049; 0131 ; 0049; 0049; az Not_Before_Dot
|
||||
"0049; 0069 ; 0049; 0049; L2 Not_Before_Dot",
|
||||
"0049; 0069 ; 0049; 0049; tr SunSpecific_Before_Dot",
|
||||
"0049; 0069 ; 0049; 0049; az SunSpecific_Before_Dot",
|
||||
"0049; 0069 0307 0307; 0049; 0049; lt SunSpecific_Before_Dot",
|
||||
"0049; 0069 0307 ; 0049; 0049; L3 SunSpecific_Before_Dot",
|
||||
};
|
||||
|
||||
public static void main (String[] args) {
|
||||
SpecialCasingTest specialCasingTest = new SpecialCasingTest();
|
||||
specialCasingTest.test();
|
||||
}
|
||||
|
||||
private void test () {
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
BufferedReader in = null;
|
||||
|
||||
try {
|
||||
int locale_num = locales.size();
|
||||
for (int l = 0; l < locale_num; l++) {
|
||||
Locale locale = locales.get(l);
|
||||
Locale.setDefault(locale);
|
||||
System.out.println("Testing on " + locale + " locale....");
|
||||
|
||||
defaultLang = locale.getLanguage();
|
||||
if (defaultLang.equals("az") ||
|
||||
defaultLang.equals("lt") ||
|
||||
defaultLang.equals("tr")) {
|
||||
specificLocale = true;
|
||||
} else {
|
||||
specificLocale = false;
|
||||
}
|
||||
in = Files.newBufferedReader(UCDFiles.SPECIAL_CASING.toRealPath());
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
if (line.length() == 0 || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
test(line);
|
||||
}
|
||||
in.close();
|
||||
in = null;
|
||||
System.out.println("Testing with Sun original data....");
|
||||
for (String additionalTestData1 : additionalTestData) {
|
||||
test(additionalTestData1);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
err = true;
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
}
|
||||
Locale.setDefault(defaultLocale);
|
||||
if (err) {
|
||||
throw new RuntimeException("SpecialCasingTest failed.");
|
||||
} else {
|
||||
System.out.println("*** SpecialCasingTest passed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void test(String line) {
|
||||
int index = line.indexOf('#');
|
||||
if (index != -1) {
|
||||
line = line.substring(0, index);
|
||||
}
|
||||
|
||||
String lang = null;
|
||||
String condition = null;
|
||||
String[] fields = line.split("; ");
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (fields[i].length() != 0) {
|
||||
fields[i] = convert(fields[i]);
|
||||
}
|
||||
}
|
||||
if (fields.length != 4) {
|
||||
StringTokenizer st = new StringTokenizer(fields[4]);
|
||||
|
||||
while (st.hasMoreTokens()) {
|
||||
String token = st.nextToken();
|
||||
|
||||
if (token.equals("Final_Sigma")) {
|
||||
condition = "Final Sigma";
|
||||
fields[0] = "Abc" + fields[0];
|
||||
fields[1] = "abc" + fields[1];
|
||||
fields[3] = "ABC" + fields[3];
|
||||
} else if (token.equals("SunSpecific_Not_Final_Sigma1")) {
|
||||
condition = "*Sun Specific* Not Final Sigma 1";
|
||||
fields[0] = "Abc" + fields[0] + "xyz";
|
||||
fields[1] = "abc" + fields[1] + "xyz";
|
||||
fields[3] = "ABC" + fields[3] + "XYZ";
|
||||
} else if (token.equals("SunSpecific_Not_Final_Sigma2")) {
|
||||
condition = "*Sun Specific* Not Final Sigma 2";
|
||||
} else if (token.equals("After_Soft_Dotted")) {
|
||||
condition = "After Soft-Dotted";
|
||||
fields[0] = "\u1E2D" + fields[0];
|
||||
fields[1] = "\u1E2D" + fields[1];
|
||||
fields[3] = "\u1E2C" + fields[3];
|
||||
} else if (token.equals("SunSpecific_Not_After_Soft_Dotted")) {
|
||||
condition = "*Sun Specific* Not After Soft-Dotted";
|
||||
fields[0] = "Dot" + fields[0];
|
||||
fields[1] = "dot" + fields[1];
|
||||
fields[3] = "DOT" + fields[3];
|
||||
} else if (token.equals("More_Above")) {
|
||||
condition = "More Above";
|
||||
fields[0] = fields[0] + "\u0306";
|
||||
fields[1] = fields[1] + "\u0306";
|
||||
fields[3] = fields[3] + "\u0306";
|
||||
} else if (token.equals("SunSpecific_Not_More_Above")) {
|
||||
condition = "*Sun Specific* Not More Above";
|
||||
fields[0] = fields[0] + "breve";
|
||||
fields[1] = fields[1] + "breve";
|
||||
fields[3] = fields[3] + "BREVE";
|
||||
} else if (token.equals("After_I")) {
|
||||
condition = "After I";
|
||||
fields[0] = "I" + fields[0];
|
||||
fields[1] = "i" + fields[1];
|
||||
fields[3] = "I" + fields[3];
|
||||
} else if (token.equals("SunSpecific_Not_After_I")) {
|
||||
condition = "*Sun Specific* Not After I";
|
||||
fields[0] = "A" + fields[0];
|
||||
fields[1] = "a" + fields[1];
|
||||
fields[3] = "A" + fields[3];
|
||||
} else if (token.equals("Not_Before_Dot")) {
|
||||
condition = "Not Before Dot";
|
||||
fields[0] = fields[0] + "Z";
|
||||
fields[1] = fields[1] + "z";
|
||||
fields[3] = fields[3] + "Z";
|
||||
} else if (token.equals("SunSpecific_Before_Dot")) {
|
||||
condition = "*Sun Specific* Before Dot";
|
||||
fields[0] = fields[0] + "\u0307";
|
||||
fields[3] = fields[3] + "\u0307";
|
||||
} else if (token.length() == 2) {
|
||||
lang = token;
|
||||
|
||||
if (lang.equals("L1")) {
|
||||
if (defaultLang.equals("lt")) {
|
||||
lang = "en";
|
||||
} else {
|
||||
lang = defaultLang;
|
||||
}
|
||||
} else if (lang.equals("L2")) {
|
||||
if (defaultLang.equals("az") ||
|
||||
defaultLang.equals("tr")) {
|
||||
lang = "en";
|
||||
} else {
|
||||
lang = defaultLang;
|
||||
}
|
||||
} else if (lang.equals("L3")) {
|
||||
if (defaultLang.equals("az") ||
|
||||
defaultLang.equals("lt") ||
|
||||
defaultLang.equals("tr")) {
|
||||
lang = "en";
|
||||
} else {
|
||||
lang = defaultLang;
|
||||
}
|
||||
// I want to have another test case here for double-check.
|
||||
// Current implementation for Character and String considers
|
||||
// only az, lt, and tr locales. I want to detect if other
|
||||
// locales are specified.
|
||||
} else if (!lang.equals("az") &&
|
||||
!lang.equals("lt") &&
|
||||
!lang.equals("tr")) {
|
||||
throw new RuntimeException("Unsupported locale: " +
|
||||
lang + ". It may need to be considered in ConditionalSpecialCasing.java. Please confirm.");
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Unknown condition: " + token);
|
||||
}
|
||||
}
|
||||
} else if (fields[0].equals("\u0130")) {
|
||||
// special case for \u0130
|
||||
if (defaultLang.equals("az") ||
|
||||
defaultLang.equals("tr")) {
|
||||
lang = "en";
|
||||
} else {
|
||||
lang = defaultLang;
|
||||
}
|
||||
}
|
||||
testLowerCase(fields[0], fields[1], lang, condition);
|
||||
testUpperCase(fields[0], fields[3], lang, condition);
|
||||
}
|
||||
|
||||
private void testLowerCase(String orig, String expected,
|
||||
String lang, String condition) {
|
||||
String got = (lang == null) ?
|
||||
orig.toLowerCase() : orig.toLowerCase(Locale.of(lang));
|
||||
|
||||
if (!expected.equals(got)) {
|
||||
err = true;
|
||||
System.err.println("toLowerCase(lang=" + lang +
|
||||
") failed.\n\tOriginal: " + toString(orig) +
|
||||
"\n\tGot: " + toString(got) +
|
||||
"\n\tExpected: " + toString(expected) +
|
||||
((condition == null) ? "" : ("\n under condition(" +
|
||||
condition + ")")));
|
||||
}
|
||||
}
|
||||
|
||||
private void testUpperCase(String orig, String expected,
|
||||
String lang, String condition) {
|
||||
String got = (lang == null) ?
|
||||
orig.toUpperCase() : orig.toUpperCase(Locale.of(lang));
|
||||
|
||||
if (!expected.equals(got)) {
|
||||
err = true;
|
||||
System.err.println("toUpperCase(lang=" + lang +
|
||||
") failed.\n\tOriginal: " + toString(orig) +
|
||||
"\n\tGot: " + toString(got) +
|
||||
"\n\tExpected: " + toString(expected) +
|
||||
((condition == null) ? "" : ("\n under condition(" +
|
||||
condition + ")")));
|
||||
}
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
private String convert(String str) {
|
||||
sb.setLength(0);
|
||||
|
||||
String[] tokens = str.split(" ");
|
||||
for (String token : tokens) {
|
||||
sb.append((char) Integer.parseInt(token, 16));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String toString(String str) {
|
||||
sb.setLength(0);
|
||||
|
||||
int len = str.length();
|
||||
for (int i = 0; i < len; i++) {
|
||||
sb.append("0x").append(Integer.toHexString(str.charAt(i)).toUpperCase()).append(" ");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
133
test/jdk/java/lang/String/Split.java
Normal file
133
test/jdk/java/lang/String/Split.java
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2013, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6840246 6559590
|
||||
* @summary test String.split()
|
||||
* @key randomness
|
||||
*/
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
import java.util.regex.*;
|
||||
|
||||
public class Split {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String source = "0123456789";
|
||||
|
||||
for (int limit=-2; limit<3; limit++) {
|
||||
for (int x=0; x<10; x++) {
|
||||
String[] result = source.split(Integer.toString(x), limit);
|
||||
int expectedLength = limit < 1 ? 2 : limit;
|
||||
|
||||
if ((limit == 0) && (x == 9)) {
|
||||
// expected dropping of ""
|
||||
if (result.length != 1)
|
||||
throw new RuntimeException("String.split failure 1");
|
||||
if (!result[0].equals("012345678")) {
|
||||
throw new RuntimeException("String.split failure 2");
|
||||
}
|
||||
} else {
|
||||
if (result.length != expectedLength) {
|
||||
throw new RuntimeException("String.split failure 3");
|
||||
}
|
||||
if (!result[0].equals(source.substring(0,x))) {
|
||||
if (limit != 1) {
|
||||
throw new RuntimeException(
|
||||
"String.split failure 4");
|
||||
} else {
|
||||
if (!result[0].equals(source.substring(0,10))) {
|
||||
throw new RuntimeException(
|
||||
"String.split failure 10");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (expectedLength > 1) { // Check segment 2
|
||||
if (!result[1].equals(source.substring(x+1,10)))
|
||||
throw new RuntimeException("String.split failure 5");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check the case for no match found
|
||||
for (int limit=-2; limit<3; limit++) {
|
||||
String[] result = source.split("e", limit);
|
||||
if (result.length != 1)
|
||||
throw new RuntimeException("String.split failure 6");
|
||||
if (!result[0].equals(source))
|
||||
throw new RuntimeException("String.split failure 7");
|
||||
}
|
||||
// Check the case for limit == 0, source = "";
|
||||
// split() now returns 0-length for empty source "" see #6559590
|
||||
source = "";
|
||||
String[] result = source.split("e", 0);
|
||||
if (result.length != 1)
|
||||
throw new RuntimeException("String.split failure 8");
|
||||
if (!result[0].equals(source))
|
||||
throw new RuntimeException("String.split failure 9");
|
||||
|
||||
// check fastpath of String.split()
|
||||
source = "0123456789abcdefgABCDEFG";
|
||||
Random r = new Random();
|
||||
|
||||
for (boolean doEscape: new boolean[] {false, true}) {
|
||||
for (int cp = 0; cp < 0x11000; cp++) {
|
||||
Pattern p = null;
|
||||
String regex = new String(Character.toChars(cp));
|
||||
if (doEscape)
|
||||
regex = "\\" + regex;
|
||||
try {
|
||||
p = Pattern.compile(regex);
|
||||
} catch (PatternSyntaxException pse) {
|
||||
// illegal syntax
|
||||
try {
|
||||
"abc".split(regex);
|
||||
} catch (PatternSyntaxException pse0) {
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException("String.split failure 11");
|
||||
}
|
||||
int off = r.nextInt(source.length());
|
||||
String[] srcStrs = new String[] {
|
||||
"",
|
||||
source,
|
||||
regex + source,
|
||||
source + regex,
|
||||
source.substring(0, 3)
|
||||
+ regex + source.substring(3, 9)
|
||||
+ regex + source.substring(9, 15)
|
||||
+ regex + source.substring(15),
|
||||
source.substring(0, off) + regex + source.substring(off)
|
||||
};
|
||||
for (String src: srcStrs) {
|
||||
for (int limit=-2; limit<3; limit++) {
|
||||
if (!Arrays.equals(src.split(regex, limit),
|
||||
p.split(src, limit)))
|
||||
throw new RuntimeException("String.split failure 12");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
107
test/jdk/java/lang/String/StringContentEqualsBug.java
Normal file
107
test/jdk/java/lang/String/StringContentEqualsBug.java
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8014477
|
||||
* @summary test String.contentEquals(StringBuffer)
|
||||
*/
|
||||
public class StringContentEqualsBug {
|
||||
|
||||
abstract static class Task extends Thread {
|
||||
volatile StringBuffer sb;
|
||||
volatile Exception exception;
|
||||
|
||||
Task(StringBuffer sb) {
|
||||
this.sb = sb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
StringBuffer sb;
|
||||
while ((sb = this.sb) != null) {
|
||||
doWith(sb);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void doWith(StringBuffer sb);
|
||||
}
|
||||
|
||||
static class Tester extends Task {
|
||||
Tester(StringBuffer sb) {
|
||||
super(sb);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doWith(StringBuffer sb) {
|
||||
"AA".contentEquals(sb);
|
||||
}
|
||||
}
|
||||
|
||||
static class Disturber extends Task {
|
||||
Disturber(StringBuffer sb) {
|
||||
super(sb);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doWith(StringBuffer sb) {
|
||||
sb.setLength(0);
|
||||
sb.trimToSize();
|
||||
sb.append("AA");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
Task[] tasks = new Task[3];
|
||||
(tasks[0] = new Tester(sb)).start();
|
||||
for (int i = 1; i < tasks.length; i++) {
|
||||
(tasks[i] = new Disturber(sb)).start();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// wait at most 5 seconds for any of the threads to throw exception
|
||||
for (int i = 0; i < 20; i++) {
|
||||
for (Task task : tasks) {
|
||||
if (task.exception != null) {
|
||||
throw task.exception;
|
||||
}
|
||||
}
|
||||
Thread.sleep(250L);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
for (Task task : tasks) {
|
||||
task.sb = null;
|
||||
task.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
126
test/jdk/java/lang/String/StringJoinTest.java
Normal file
126
test/jdk/java/lang/String/StringJoinTest.java
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2021, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @test
|
||||
* @bug 5015163 8267529
|
||||
* @summary test String merge/join that is the inverse of String.split()
|
||||
* @run testng StringJoinTest
|
||||
* @author Jim Gish
|
||||
*/
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
@Test(groups = {"unit","string","lang","libs"})
|
||||
public class StringJoinTest {
|
||||
private static final String DASH = "-";
|
||||
private static final String BEGIN = "Hi there";
|
||||
private static final String JIM = "Jim";
|
||||
private static final String JOHN = "John";
|
||||
private static final String AND_JOE = "and Joe";
|
||||
private static final String BILL = "Bill";
|
||||
private static final String BOB = "Bob";
|
||||
private static final String AND_BO = "and Bo";
|
||||
private static final String ZEKE = "Zeke";
|
||||
private static final String ZACK = "Zack";
|
||||
private static final String AND_ZOE = "and Zoe";
|
||||
|
||||
/**
|
||||
* Tests the join() methods on String
|
||||
*/
|
||||
public void testJoinStringVarargs() {
|
||||
// check a non-null join of String array (var-args) elements
|
||||
String expectedResult = BEGIN + DASH + JIM + DASH + JOHN + DASH + AND_JOE;
|
||||
String result = String.join(DASH, BEGIN, JIM, JOHN, AND_JOE);
|
||||
|
||||
assertEquals(result, expectedResult, "BEGIN.join(DASH, JIM, JOHN, AND_JOE)");
|
||||
// test with just one element
|
||||
assertEquals(String.join(DASH, BEGIN), BEGIN);
|
||||
}
|
||||
|
||||
public void testJoinStringArray() {
|
||||
// check a non-null join of Object[] with String elements
|
||||
String[] theBs = {BILL, BOB, AND_BO};
|
||||
String result = String.join(DASH, theBs);
|
||||
String expectedResult = BILL + DASH + BOB + DASH + AND_BO;
|
||||
assertEquals(result, expectedResult, "String.join(DASH, theBs)");
|
||||
}
|
||||
|
||||
public void testJoinEmptyStringArray() {
|
||||
// check a non-null join of Object[] with String elements
|
||||
String[] empties = {};
|
||||
String result = String.join(DASH, empties);
|
||||
assertEquals(result, "", "String.join(DASH, empties)");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = {NullPointerException.class})
|
||||
public void testJoinNullStringArray() {
|
||||
// check a non-null join of Object[] with String elements
|
||||
String[] empties = null;
|
||||
String result = String.join(DASH, empties);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = {NullPointerException.class})
|
||||
public void testJoinNullIterableStringList() {
|
||||
// check join of an Iterables
|
||||
List<CharSequence> theZsList = null;
|
||||
String.join(DASH, theZsList);
|
||||
}
|
||||
|
||||
public void testJoinIterableStringList() {
|
||||
// check join of an Iterables
|
||||
List<CharSequence> theZsList = new ArrayList<>();
|
||||
theZsList.add(ZEKE);
|
||||
theZsList.add(ZACK);
|
||||
theZsList.add(AND_ZOE);
|
||||
assertEquals(String.join(DASH, theZsList), ZEKE + DASH + ZACK + DASH
|
||||
+ AND_ZOE, "String.join(DASH, theZsList))");
|
||||
}
|
||||
|
||||
public void testJoinNullStringList() {
|
||||
List<CharSequence> nullList = null;
|
||||
try {
|
||||
assertEquals( String.join( DASH, nullList ), "null" );
|
||||
fail("Null container should cause NPE");
|
||||
} catch (NullPointerException npe) {}
|
||||
assertEquals(String.join(DASH, null, null), "null" + DASH + "null");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = {NullPointerException.class})
|
||||
public void testJoinNullDelimiter() {
|
||||
String.join(null, JIM, JOHN);
|
||||
}
|
||||
|
||||
public void testIgnoreDelimiterCoderJoin() {
|
||||
// 8267529: Ensure that joining zero or one latin-1 Strings with a UTF-16
|
||||
// delimiter produce a String with a latin-1 coder, since the delimiter
|
||||
// is not added.
|
||||
assertEquals("", new StringJoiner("\u2013").toString());
|
||||
assertEquals("foo", new StringJoiner("\u2013").add("foo").toString());
|
||||
assertEquals("", String.join("\u2013"));
|
||||
assertEquals("foo", String.join("\u2013", "foo"));
|
||||
}
|
||||
}
|
||||
437
test/jdk/java/lang/String/StringRacyConstructor.java
Normal file
437
test/jdk/java/lang/String/StringRacyConstructor.java
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*
|
||||
* 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 test.java.lang.String;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIf;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8311906
|
||||
* @modules java.base/java.lang:open
|
||||
* @summary check String's racy constructors
|
||||
* @run junit/othervm -XX:+CompactStrings test.java.lang.String.StringRacyConstructor
|
||||
* @run junit/othervm -XX:-CompactStrings test.java.lang.String.StringRacyConstructor
|
||||
*/
|
||||
|
||||
public class StringRacyConstructor {
|
||||
private static final byte LATIN1 = 0;
|
||||
private static final byte UTF16 = 1;
|
||||
|
||||
private static final Field STRING_CODER_FIELD;
|
||||
private static final Field SB_CODER_FIELD;
|
||||
private static final boolean COMPACT_STRINGS;
|
||||
|
||||
static {
|
||||
try {
|
||||
STRING_CODER_FIELD = String.class.getDeclaredField("coder");
|
||||
STRING_CODER_FIELD.setAccessible(true);
|
||||
SB_CODER_FIELD = Class.forName("java.lang.AbstractStringBuilder").getDeclaredField("coder");
|
||||
SB_CODER_FIELD.setAccessible(true);
|
||||
COMPACT_STRINGS = isCompactStrings();
|
||||
} catch (NoSuchFieldException ex ) {
|
||||
throw new ExceptionInInitializerError(ex);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/* {@return true iff CompactStrings are enabled}
|
||||
*/
|
||||
public static boolean isCompactStrings() {
|
||||
try {
|
||||
Field compactStringField = String.class.getDeclaredField("COMPACT_STRINGS");
|
||||
compactStringField.setAccessible(true);
|
||||
return compactStringField.getBoolean(null);
|
||||
} catch (NoSuchFieldException ex) {
|
||||
throw new ExceptionInInitializerError(ex);
|
||||
} catch (IllegalAccessException iae) {
|
||||
throw new AssertionError(iae);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the coder for the String
|
||||
private static int coder(String s) {
|
||||
try {
|
||||
return STRING_CODER_FIELD.getByte(s);
|
||||
} catch (IllegalAccessException iae) {
|
||||
throw new AssertionError(iae);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the coder for the StringBuilder
|
||||
private static int sbCoder(StringBuilder sb) {
|
||||
try {
|
||||
return SB_CODER_FIELD.getByte(sb);
|
||||
} catch (IllegalAccessException iae) {
|
||||
throw new AssertionError(iae);
|
||||
}
|
||||
}
|
||||
|
||||
// Return a summary of the internals of the String
|
||||
// The coder and indicate if the coder matches the string contents
|
||||
private static String inspectString(String s) {
|
||||
try {
|
||||
char[] chars = s.toCharArray();
|
||||
String r = new String(chars);
|
||||
|
||||
boolean invalidCoder = coder(s) != coder(r);
|
||||
String coder = STRING_CODER_FIELD.getByte(s) == 0 ? "isLatin1" : "utf16";
|
||||
return (invalidCoder ? "INVALID CODER" : "" ) + " \"" + s + "\", coder: " + coder;
|
||||
} catch (IllegalAccessException ex ) {
|
||||
return "EXCEPTION: " + ex.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return true if the coder matches the presence/lack of UTF16 characters}
|
||||
* If it returns false, the coder and the contents have failed the precondition for string.
|
||||
* @param orig a string
|
||||
*/
|
||||
private static boolean validCoder(String orig) {
|
||||
if (!COMPACT_STRINGS) {
|
||||
assertEquals(UTF16, coder(orig), "Non-COMPACT STRINGS coder must be UTF16");
|
||||
}
|
||||
int accum = 0;
|
||||
for (int i = 0; i < orig.length(); i++)
|
||||
accum |= orig.charAt(i);
|
||||
byte expectedCoder = (accum < 256) ? LATIN1 : UTF16;
|
||||
return expectedCoder == coder(orig);
|
||||
}
|
||||
|
||||
// Check a StringBuilder for consistency of coder and latin1 vs UTF16
|
||||
private static boolean validCoder(StringBuilder orig) {
|
||||
int accum = 0;
|
||||
for (int i = 0; i < orig.length(); i++)
|
||||
accum |= orig.charAt(i);
|
||||
byte expectedCoder = (accum < 256) ? LATIN1 : UTF16;
|
||||
return expectedCoder == sbCoder(orig);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledIf("test.java.lang.String.StringRacyConstructor#isCompactStrings")
|
||||
public void checkStringRange() {
|
||||
char[] chars = {'a', 'b', 'c', 0xff21, 0xff22, 0xff23};
|
||||
String orig = new String(chars);
|
||||
char[] xx = orig.toCharArray();
|
||||
String stringFromChars = new String(xx);
|
||||
assertEquals(orig, stringFromChars, "mixed chars");
|
||||
assertTrue(validCoder(stringFromChars), "invalid coder"
|
||||
+ ", invalid coder: " + inspectString(stringFromChars));
|
||||
}
|
||||
|
||||
private static List<String> strings() {
|
||||
return List.of("01234", " ");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("strings")
|
||||
@EnabledIf("test.java.lang.String.StringRacyConstructor#isCompactStrings")
|
||||
public void racyString(String orig) {
|
||||
String racyString = racyStringConstruction(orig);
|
||||
// The contents are indeterminate due to the race
|
||||
assertTrue(validCoder(racyString), orig + " string invalid"
|
||||
+ ", racyString: " + inspectString(racyString));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("strings")
|
||||
@EnabledIf("test.java.lang.String.StringRacyConstructor#isCompactStrings")
|
||||
public void racyCodePoint(String orig) {
|
||||
String iffyString = racyStringConstructionCodepoints(orig);
|
||||
// The contents are indeterminate due to the race
|
||||
assertTrue(validCoder(iffyString), "invalid coder in non-deterministic string"
|
||||
+ ", orig:" + inspectString(orig)
|
||||
+ ", iffyString: " + inspectString(iffyString));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("strings")
|
||||
@EnabledIf("test.java.lang.String.StringRacyConstructor#isCompactStrings")
|
||||
public void racyCodePointSurrogates(String orig) {
|
||||
String iffyString = racyStringConstructionCodepointsSurrogates(orig);
|
||||
// The contents are indeterminate due to the race
|
||||
if (!orig.equals(iffyString))
|
||||
System.err.println("orig: " + orig + ", iffy: " + iffyString + Arrays.toString(iffyString.codePoints().toArray()));
|
||||
assertTrue(validCoder(iffyString), "invalid coder in non-deterministic string"
|
||||
+ ", orig:" + inspectString(orig)
|
||||
+ ", iffyString: " + inspectString(iffyString));
|
||||
}
|
||||
|
||||
// Test the private methods of StringUTF16 that compress and copy COMPRESSED_STRING
|
||||
// encoded byte arrays.
|
||||
@Test
|
||||
public void verifyUTF16CopyBytes()
|
||||
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
Class<?> stringUTF16 = Class.forName("java.lang.StringUTF16");
|
||||
Method mCompressChars = stringUTF16.getDeclaredMethod("compress",
|
||||
char[].class, int.class, byte[].class, int.class, int.class);
|
||||
mCompressChars.setAccessible(true);
|
||||
|
||||
// First warmup the intrinsic and check 1 case
|
||||
char[] chars = {'a', 'b', 'c', 0xff21, 0xff22, 0xff23};
|
||||
byte[] bytes = new byte[chars.length];
|
||||
int printWarningCount = 0;
|
||||
|
||||
for (int i = 0; i < 1_000_000; i++) { // repeat to get C2 to kick in
|
||||
// Copy only latin1 chars from UTF-16 converted prefix (3 chars -> 3 bytes)
|
||||
int intResult = (int) mCompressChars.invoke(null, chars, 0, bytes, 0, chars.length);
|
||||
if (intResult == 0) {
|
||||
if (printWarningCount == 0) {
|
||||
printWarningCount = 1;
|
||||
System.err.println("Intrinsic for StringUTF16.compress returned 0, may not have been updated.");
|
||||
}
|
||||
} else {
|
||||
assertEquals(3, intResult, "return length not-equal, iteration: " + i);
|
||||
}
|
||||
}
|
||||
|
||||
// Exhaustively check compress returning the correct index of the non-latin1 char.
|
||||
final int SIZE = 48;
|
||||
final byte FILL_BYTE = 'R';
|
||||
chars = new char[SIZE];
|
||||
bytes = new byte[chars.length];
|
||||
for (int i = 0; i < SIZE; i++) { // Every starting index
|
||||
for (int j = i; j < SIZE; j++) { // Every location of non-latin1
|
||||
Arrays.fill(chars, 'A');
|
||||
Arrays.fill(bytes, FILL_BYTE);
|
||||
chars[j] = 0xFF21;
|
||||
int intResult = (int) mCompressChars.invoke(null, chars, i, bytes, 0, chars.length - i);
|
||||
assertEquals(j - i, intResult, "compress found wrong index");
|
||||
assertEquals(FILL_BYTE, bytes[j], "extra character stored");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Check that a concatenated "hello" has a valid coder
|
||||
@Test
|
||||
@EnabledIf("test.java.lang.String.StringRacyConstructor#isCompactStrings")
|
||||
public void checkConcatAndIntern() {
|
||||
var helloWorld = "hello world";
|
||||
String helloToo = racyStringConstruction("hell".concat("o"));
|
||||
String o = helloToo.intern();
|
||||
var hello = "hello";
|
||||
assertTrue(validCoder(helloToo), "startsWith: "
|
||||
+ ", hell: " + inspectString(helloToo)
|
||||
+ ", o: " + inspectString(o)
|
||||
+ ", hello: " + inspectString(hello)
|
||||
+ ", hello world: " + inspectString(helloWorld));
|
||||
}
|
||||
|
||||
// Check that an empty string with racy construction has a valid coder
|
||||
@Test
|
||||
@EnabledIf("test.java.lang.String.StringRacyConstructor#isCompactStrings")
|
||||
public void racyEmptyString() {
|
||||
var space = racyStringConstruction(" ");
|
||||
var trimmed = space.trim();
|
||||
assertTrue(validCoder(trimmed), "empty string invalid coder"
|
||||
+ ", trimmed: " + inspectString(trimmed));
|
||||
}
|
||||
|
||||
// Check that an exception in a user implemented CharSequence doesn't result in
|
||||
// an invalid coder when appended to a StringBuilder
|
||||
@Test
|
||||
@EnabledIf("test.java.lang.String.StringRacyConstructor#isCompactStrings")
|
||||
void charSequenceException() {
|
||||
ThrowingCharSequence bs = new ThrowingCharSequence("A\u2030\uFFFD");
|
||||
var sb = new StringBuilder();
|
||||
try {
|
||||
sb.append(bs);
|
||||
fail("An IllegalArgumentException should have been thrown");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// ignore expected
|
||||
}
|
||||
assertTrue(validCoder(sb), "invalid coder in StringBuilder");
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a latin-1 String, attempt to create a copy that is
|
||||
* incorrectly encoded as UTF-16.
|
||||
*/
|
||||
public static String racyStringConstruction(String original) throws ConcurrentModificationException {
|
||||
if (original.chars().max().getAsInt() >= 256) {
|
||||
throw new IllegalArgumentException(
|
||||
"Only work with latin-1 Strings");
|
||||
}
|
||||
|
||||
char[] chars = original.toCharArray();
|
||||
|
||||
// In another thread, flip the first character back
|
||||
// and forth between being latin-1 or not
|
||||
Thread thread = new Thread(() -> {
|
||||
while (!Thread.interrupted()) {
|
||||
chars[0] ^= 256;
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
|
||||
// at the same time call the String constructor,
|
||||
// until we hit the race condition
|
||||
int i = 0;
|
||||
while (true) {
|
||||
i++;
|
||||
String s = new String(chars);
|
||||
if ((s.charAt(0) < 256 && !original.equals(s)) || i > 1_000_000) {
|
||||
thread.interrupt();
|
||||
try {
|
||||
thread.join();
|
||||
} catch (InterruptedException ie) {
|
||||
// ignore interrupt
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a latin-1 String, creates a copy that is
|
||||
* incorrectly encoded as UTF-16 using the APIs for Codepoints.
|
||||
*/
|
||||
public static String racyStringConstructionCodepoints(String original) throws ConcurrentModificationException {
|
||||
if (original.chars().max().getAsInt() >= 256) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can only work with latin-1 Strings");
|
||||
}
|
||||
|
||||
int len = original.length();
|
||||
int[] codePoints = new int[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
codePoints[i] = original.charAt(i);
|
||||
}
|
||||
|
||||
// In another thread, flip the first character back
|
||||
// and forth between being latin-1 or not
|
||||
Thread thread = new Thread(() -> {
|
||||
while (!Thread.interrupted()) {
|
||||
codePoints[0] ^= 256;
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
|
||||
// at the same time call the String constructor,
|
||||
// until we hit the race condition
|
||||
int i = 0;
|
||||
while (true) {
|
||||
i++;
|
||||
String s = new String(codePoints, 0, len);
|
||||
if ((s.charAt(0) < 256 && !original.equals(s)) || i > 1_000_000) {
|
||||
thread.interrupt();
|
||||
try {
|
||||
thread.join();
|
||||
} catch (InterruptedException ie) {
|
||||
// ignore interrupt
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string created from a codepoint array that has been racily
|
||||
* modified to contain high and low surrogates. The string is a different length
|
||||
* than the original due to the surrogate encoding.
|
||||
*/
|
||||
public static String racyStringConstructionCodepointsSurrogates(String original) throws ConcurrentModificationException {
|
||||
if (original.chars().max().getAsInt() >= 256) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can only work with latin-1 Strings");
|
||||
}
|
||||
|
||||
int len = original.length();
|
||||
int[] codePoints = new int[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
codePoints[i] = original.charAt(i);
|
||||
}
|
||||
|
||||
// In another thread, flip the first character back
|
||||
// and forth between being latin-1 or as a surrogate pair.
|
||||
Thread thread = new Thread(() -> {
|
||||
while (!Thread.interrupted()) {
|
||||
codePoints[0] ^= 0x10000;
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
|
||||
// at the same time call the String constructor,
|
||||
// until we hit the race condition
|
||||
int i = 0;
|
||||
while (true) {
|
||||
i++;
|
||||
String s = new String(codePoints, 0, len);
|
||||
if ((s.length() != original.length()) || i > 1_000_000) {
|
||||
thread.interrupt();
|
||||
try {
|
||||
thread.join();
|
||||
} catch (InterruptedException ie) {
|
||||
// ignore interrupt
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A CharSequence that returns characters from a string and throws IllegalArgumentException
|
||||
// when the character requested is 0xFFFD (the replacement character)
|
||||
// The string contents determine when the exception is thrown.
|
||||
static class ThrowingCharSequence implements CharSequence {
|
||||
private final String aString;
|
||||
|
||||
ThrowingCharSequence(String aString) {
|
||||
this.aString = aString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return aString.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char charAt(int index) {
|
||||
char ch = aString.charAt(index);
|
||||
if (ch == 0xFFFD) {
|
||||
throw new IllegalArgumentException("Replacement character at index " + index);
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
@Override
|
||||
// Not used; returns the entire string
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
146
test/jdk/java/lang/String/StringRepeat.java
Normal file
146
test/jdk/java/lang/String/StringRepeat.java
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2024, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary This exercises String#repeat patterns and limits.
|
||||
* @run main/othervm StringRepeat
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary This exercises String#repeat patterns with 16 * 1024 * 1024 repeats.
|
||||
* @requires os.maxMemory >= 2G
|
||||
* @requires vm.bits == "64"
|
||||
* @run main/othervm -Xmx2g StringRepeat 16777216
|
||||
*/
|
||||
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
public class StringRepeat {
|
||||
public static void main(String... args) {
|
||||
if (args.length > 0) {
|
||||
REPEATS = new int[args.length];
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
REPEATS[i] = Integer.parseInt(args[i]);
|
||||
}
|
||||
}
|
||||
test1();
|
||||
test2();
|
||||
}
|
||||
|
||||
/*
|
||||
* Default varitions of repeat count.
|
||||
*/
|
||||
static int[] REPEATS = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
32, 64, 128, 256, 512, 1024, 64 * 1024, 1024 * 1024
|
||||
};
|
||||
|
||||
/*
|
||||
* Varitions of Strings.
|
||||
*/
|
||||
static String[] STRINGS = new String[] {
|
||||
"", "\0", " ", "a", "$", "\u2022",
|
||||
"ab", "abc", "abcd", "abcde",
|
||||
"The quick brown fox jumps over the lazy dog."
|
||||
};
|
||||
|
||||
/*
|
||||
* Repeat String function tests.
|
||||
*/
|
||||
static void test1() {
|
||||
for (int repeat : REPEATS) {
|
||||
for (String string : STRINGS) {
|
||||
long limit = (long)string.length() * (long)repeat;
|
||||
|
||||
if ((long)(Integer.MAX_VALUE >> 1) <= limit) {
|
||||
break;
|
||||
}
|
||||
|
||||
verify(string.repeat(repeat), string, repeat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Repeat String exception tests.
|
||||
*/
|
||||
static void test2() {
|
||||
try {
|
||||
"abc".repeat(-1);
|
||||
throw new RuntimeException("No exception for negative repeat count");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Correct
|
||||
}
|
||||
|
||||
try {
|
||||
"abc".repeat(Integer.MAX_VALUE - 1);
|
||||
throw new RuntimeException("No exception for large repeat count");
|
||||
} catch (OutOfMemoryError ex) {
|
||||
// Correct
|
||||
}
|
||||
}
|
||||
|
||||
static String truncate(String string) {
|
||||
if (string.length() < 80) {
|
||||
return string;
|
||||
}
|
||||
return string.substring(0, 80) + "...";
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify string repeat patterns.
|
||||
*/
|
||||
static void verify(String result, String string, int repeat) {
|
||||
if (string.isEmpty() || repeat == 0) {
|
||||
if (!result.isEmpty()) {
|
||||
System.err.format("\"%s\".repeat(%d)%n", truncate(string), repeat);
|
||||
System.err.format("Result \"%s\"%n", truncate(result));
|
||||
System.err.format("Result expected to be empty, found string of length %d%n", result.length());
|
||||
throw new RuntimeException();
|
||||
}
|
||||
} else {
|
||||
int expected = 0;
|
||||
int count = 0;
|
||||
for (int offset = result.indexOf(string, expected);
|
||||
0 <= offset;
|
||||
offset = result.indexOf(string, expected)) {
|
||||
count++;
|
||||
if (offset != expected) {
|
||||
System.err.format("\"%s\".repeat(%d)%n", truncate(string), repeat);
|
||||
System.err.format("Result \"%s\"%n", truncate(result));
|
||||
System.err.format("Repeat expected at %d, found at = %d%n", expected, offset);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
expected += string.length();
|
||||
}
|
||||
if (count != repeat) {
|
||||
System.err.format("\"%s\".repeat(%d)%n", truncate(string), repeat);
|
||||
System.err.format("Result \"%s\"%n", truncate(result));
|
||||
System.err.format("Repeat count expected to be %d, found %d%n", repeat, count);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
101
test/jdk/java/lang/String/Strip.java
Normal file
101
test/jdk/java/lang/String/Strip.java
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Basic strip, stripLeading, stripTrailing functionality
|
||||
* @bug 8200377
|
||||
* @run main/othervm Strip
|
||||
*/
|
||||
|
||||
public class Strip {
|
||||
public static void main(String... arg) {
|
||||
testStrip();
|
||||
testWhitespace();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test basic stripping routines
|
||||
*/
|
||||
static void testStrip() {
|
||||
equal(" abc ".strip(), "abc");
|
||||
equal(" abc ".stripLeading(), "abc ");
|
||||
equal(" abc ".stripTrailing(), " abc");
|
||||
equal(" abc\u2022 ".strip(), "abc\u2022");
|
||||
equal(" abc\u2022 ".stripLeading(), "abc\u2022 ");
|
||||
equal(" abc\u2022 ".stripTrailing(), " abc\u2022");
|
||||
equal("".strip(), "");
|
||||
equal("".stripLeading(), "");
|
||||
equal("".stripTrailing(), "");
|
||||
equal("\b".strip(), "\b");
|
||||
equal("\b".stripLeading(), "\b");
|
||||
equal("\b".stripTrailing(), "\b");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test full whitespace range
|
||||
*/
|
||||
static void testWhitespace() {
|
||||
StringBuilder sb = new StringBuilder(64);
|
||||
IntStream.range(1, 0xFFFF).filter(c -> Character.isWhitespace(c))
|
||||
.forEach(c -> sb.append((char)c));
|
||||
String whiteSpace = sb.toString();
|
||||
|
||||
String testString = whiteSpace + "abc" + whiteSpace;
|
||||
equal(testString.strip(), "abc");
|
||||
equal(testString.stripLeading(), "abc" + whiteSpace);
|
||||
equal(testString.stripTrailing(), whiteSpace + "abc");
|
||||
}
|
||||
|
||||
/*
|
||||
* Report difference in result.
|
||||
*/
|
||||
static void report(String message, String inputTag, String input,
|
||||
String outputTag, String output) {
|
||||
System.err.println(message);
|
||||
System.err.println();
|
||||
System.err.println(inputTag);
|
||||
System.err.println(input.codePoints()
|
||||
.mapToObj(c -> (Integer)c)
|
||||
.collect(Collectors.toList()));
|
||||
System.err.println();
|
||||
System.err.println(outputTag);
|
||||
System.err.println(output.codePoints()
|
||||
.mapToObj(c -> (Integer)c)
|
||||
.collect(Collectors.toList()));
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/*
|
||||
* Raise an exception if the two inputs are not equivalent.
|
||||
*/
|
||||
static void equal(String input, String expected) {
|
||||
if (input == null || expected == null || !expected.equals(input)) {
|
||||
report("Failed equal", "Input:", input, "Expected:", expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
59
test/jdk/java/lang/String/StripIndent.java
Normal file
59
test/jdk/java/lang/String/StripIndent.java
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8223775
|
||||
* @summary This exercises String#stripIndent patterns and limits.
|
||||
* @compile StripIndent.java
|
||||
* @run main StripIndent
|
||||
*/
|
||||
|
||||
public class StripIndent {
|
||||
public static void main(String... arg) {
|
||||
test1();
|
||||
}
|
||||
|
||||
/*
|
||||
* Case combinations.
|
||||
*/
|
||||
static void test1() {
|
||||
verify("", "");
|
||||
verify("abc", "abc");
|
||||
verify(" abc", "abc");
|
||||
verify("abc ", "abc");
|
||||
verify(" abc\n def\n ", "abc\ndef\n");
|
||||
verify(" abc\n def\n", " abc\n def\n");
|
||||
verify(" abc\n def", "abc\ndef");
|
||||
verify(" abc\n def\n ", "abc\n def\n");
|
||||
}
|
||||
|
||||
static void verify(String a, String b) {
|
||||
if (!a.stripIndent().equals(b)) {
|
||||
System.err.format("\"%s\" not equal \"%s\"%n", a, b);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
693
test/jdk/java/lang/String/Supplementary.java
Normal file
693
test/jdk/java/lang/String/Supplementary.java
Normal file
|
|
@ -0,0 +1,693 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* @test
|
||||
* @bug 4533872 4915683 4922962 4985217 5017280 6242664 6588260
|
||||
* @summary Unit tests for supplementary character support (JSR-204)
|
||||
*/
|
||||
|
||||
public class Supplementary {
|
||||
|
||||
public static void main(String[] args) {
|
||||
test1(); // Test for codePointAt(int index)
|
||||
test2(); // Test for codePointBefore(int index)
|
||||
test3(); // Test for indexOf(int ch)
|
||||
test4(); // Test for indexOf(int ch, int fromIndex)
|
||||
test5(); // Test for lastIndexOf(int ch)
|
||||
test6(); // Test for lastIndexOf(int ch, int fromIndex)
|
||||
test7(); // Test for String(int[] codePoint, int offset, int count)
|
||||
test8(); // Test for codePointCount(int beginIndex, int endIndex)
|
||||
test9(); // Test for offsetByCodePoints(int index, int offset)
|
||||
test10(); // Test for offsetByCodePoints(int index, int offset)
|
||||
// To verify the fix for 6242664
|
||||
}
|
||||
|
||||
/* Text strings which are used as input data.
|
||||
* The comment above each text string means the index of each 16-bit char
|
||||
* for convenience.
|
||||
*/
|
||||
static final String[] input = {
|
||||
/* 111 1 111111 22222
|
||||
0123 4 5678 9 012 3 456789 01234 */
|
||||
"abc\uD800\uDC00def\uD800\uD800ab\uD800\uDC00cdefa\uDC00bcdef",
|
||||
/* 1 1111 1111 1 222
|
||||
0 12345 6789 0 1234 5678 9 012 */
|
||||
"\uD800defg\uD800hij\uD800\uDC00klm\uDC00nop\uDC00\uD800rt\uDC00",
|
||||
/* 11 1 1111 1 112 222
|
||||
0 12345 6 78901 2 3456 7 890 123 */
|
||||
"\uDC00abcd\uDBFF\uDFFFefgh\uD800\uDC009ik\uDC00\uDC00lm\uDC00no\uD800",
|
||||
/* 111 111111 1 22 2
|
||||
0 1 2345 678 9 012 345678 9 01 2 */
|
||||
"\uD800\uDC00!#$\uD800%&\uD800\uDC00;+\uDC00<>;=^\uDC00\\@\uD800\uDC00",
|
||||
|
||||
// includes an undefined supplementary character in Unicode 4.0.0
|
||||
/* 1 11 1 1111 1
|
||||
0 1 2345 6 789 0 12 3 4567 8 */
|
||||
"\uDB40\uDE00abc\uDE01\uDB40de\uDB40\uDE02f\uDB40\uDE03ghi\uDB40\uDE02",
|
||||
|
||||
// all supplementary characters
|
||||
/* 1 1
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 */
|
||||
"\uD800\uDC00\uD800\uDC01\uD800\uDC02\uD800\uDC03\uD800\uDC04\uD800\uDC05"+
|
||||
/* 1 1 1 1 1 1 1 1 2 2 2 2
|
||||
2 3 4 5 6 7 8 9 0 1 2 3 */
|
||||
"\uD800\uDC06\uD800\uDC07\uD800\uDC08\uD800\uDC08\uD800\uDC09\uD800\uDC0A"+
|
||||
/* 2 2 2 2 2 2 3 3 3 3 3 3
|
||||
4 5 6 7 8 9 0 1 2 3 4 5 */
|
||||
"\uD800\uDC0B\uD800\uDC0C\uD800\uDC0D\uD800\uDC0A\uD800\uDC0F\uD800\uDC10"
|
||||
};
|
||||
|
||||
|
||||
/* Expected results for:
|
||||
* test1(): for codePointAt()
|
||||
*
|
||||
* Each character in each array is the golden data for each text string
|
||||
* in the above input data. For example, the first data in each array is
|
||||
* for the first input string.
|
||||
*/
|
||||
static final int[][] golden1 = {
|
||||
{'a', 0xD800, 0xDC00, 0x10000, 0xE0200, 0x10000},// codePointAt(0)
|
||||
{0xD800, 0x10000, 'g', 0xDC00, 0xE0202, 0xDC04}, // codePointAt(9)
|
||||
{'f', 0xDC00, 0xD800, 0xDC00, 0xDE02, 0xDC10}, // codePointAt(length-1)
|
||||
{'f', 'p', 0xDC00, '^', 0xE0202, 0xDC08}, // codePointAt() for a substring
|
||||
};
|
||||
|
||||
/*
|
||||
* Test for codePointAt(int index) method
|
||||
*/
|
||||
static void test1() {
|
||||
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
String s = input[i];
|
||||
|
||||
/*
|
||||
* Normal case
|
||||
*/
|
||||
testCodePoint(At, s, 0, golden1[0][i]);
|
||||
testCodePoint(At, s, 9, golden1[1][i]);
|
||||
testCodePoint(At, s, s.length()-1, golden1[2][i]);
|
||||
testCodePoint(At, s.substring(17), 0, golden1[3][i]);
|
||||
|
||||
/*
|
||||
* Abnormal case - verify that an exception is thrown.
|
||||
*/
|
||||
testCodePoint(At, s, -1);
|
||||
testCodePoint(At, s, s.length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Expected results for:
|
||||
* test2(): for codePointBefore()
|
||||
*
|
||||
* Each character in each array is the golden data for each text string
|
||||
* in the above input data. For example, the first data in each array is
|
||||
* for the first input string.
|
||||
*/
|
||||
static final int[][] golden2 = {
|
||||
{'a', 0xD800, 0xDC00, 0xD800, 0xDB40, 0xD800}, // codePointBefore(1)
|
||||
{0xD800, 'l', 0x10000, 0xDC00, 0xDB40, 0xD800}, // codePointBefore(13)
|
||||
{'f', 0xDC00, 0xD800, 0x10000, 0xE0202, 0x10010},// codePointBefore(length)
|
||||
{'b', 'd', 'a', 0xDC00, 0xDE00, 0xDC00}, // codePointBefore() for a substring
|
||||
};
|
||||
|
||||
/*
|
||||
* Test for codePointBefore(int index) method
|
||||
*/
|
||||
static void test2() {
|
||||
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
String s = input[i];
|
||||
|
||||
/*
|
||||
* Normal case
|
||||
*/
|
||||
testCodePoint(Before, s, 1, golden2[0][i]);
|
||||
testCodePoint(Before, s, 13, golden2[1][i]);
|
||||
testCodePoint(Before, s, s.length(), golden2[2][i]);
|
||||
testCodePoint(Before, s.substring(1), 1, golden2[3][i]);
|
||||
|
||||
/*
|
||||
* Abnormal case - verify that an exception is thrown.
|
||||
*/
|
||||
testCodePoint(Before, s, 0);
|
||||
testCodePoint(Before, s, s.length()+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Expected results for:
|
||||
* test3(): for indexOf(int ch)
|
||||
* test4(): for indexOf(int ch, int fromIndex)
|
||||
* test5(): for lastIndexOf(int ch)
|
||||
* test6(): for lastIndexOf(int ch, int fromIndex)
|
||||
*
|
||||
* Unlike golden1 and golden2, golden3[m][] is the golden data for text
|
||||
* string in input[m].
|
||||
*
|
||||
* The meaning of each element in golden3[][n]
|
||||
* golden3[][0]: character which is searched.
|
||||
* golden3[][2]: the golden data for indexOf(int ch)
|
||||
* From golden3[][2] to golden3[][n-1]:
|
||||
* the golden data for indexOf(int ch, int fromIndex)
|
||||
* The golden3[][n-2]: the golden data for lastIndexOf(int ch)
|
||||
* From golden3[][1] to golden3[][n-2]:
|
||||
* the golden data for lastIndexOf(int ch, int fromIndex)
|
||||
*
|
||||
* In other words, the data format is
|
||||
* { ch, -1, index1, index2, ..., -1}
|
||||
* where index1, index2, ... are all indices of the ch occurrences.
|
||||
*/
|
||||
static final int[][] golden3 = {
|
||||
/* ch indices */
|
||||
{'b', -1, 1, 11, 20, -1},
|
||||
{0xD800, -1, 0, 5, 9, 19, -1},
|
||||
{0xDC00, -1, 0, 12, 16, 17, 20, -1},
|
||||
{0x10000, -1, 0, 8, 21, -1},
|
||||
{0xE0202, -1, 9, 17, -1},
|
||||
{0x1000A, -1, 22, 30, -1}
|
||||
};
|
||||
|
||||
/*
|
||||
* Test for indexOf(int ch) method
|
||||
*/
|
||||
static void test3() {
|
||||
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
String s = input[i];
|
||||
|
||||
/*
|
||||
* Normal case
|
||||
*/
|
||||
testIndexOf(s, golden3[i][0], golden3[i][2]);
|
||||
|
||||
/*
|
||||
* Abnormal case - char which isn't included in the string.
|
||||
*/
|
||||
testIndexOf(s, 'Z', -1);
|
||||
testIndexOf(s, 0xDB98, -1);
|
||||
testIndexOf(s, 0xDE76, -1);
|
||||
testIndexOf(s, 0x12345, -1);
|
||||
testIndexOf(s, -1, -1);
|
||||
testIndexOf(s, 0x110000, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test for indexOf(int ch, int fromIndex) method
|
||||
*/
|
||||
static void test4() {
|
||||
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
String s = input[i];
|
||||
int ch = golden3[i][0];
|
||||
|
||||
/*
|
||||
* Normal case
|
||||
*/
|
||||
int fromIndex = 0;
|
||||
for (int j = 2; j < golden3[i].length; j++) {
|
||||
fromIndex = testIndexOf(s, fromIndex, ch,
|
||||
golden3[i][j]) + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Abnormal case1 - char is included in the string but fromIndex
|
||||
* is incorrect.
|
||||
*/
|
||||
testIndexOf(s, -1, ch, golden3[i][2]);
|
||||
testIndexOf(s, s.length(), ch,
|
||||
golden3[i][golden3[i].length-1]);
|
||||
|
||||
/*
|
||||
* Abnormal case2 - char which isn't included in the string.
|
||||
*/
|
||||
testIndexOf(s, 0, 'Z', -1);
|
||||
testIndexOf(s, 0, 0xDB98, -1);
|
||||
testIndexOf(s, 0, 0xDE76, -1);
|
||||
testIndexOf(s, 0, 0x12345, -1);
|
||||
testIndexOf(s, 0, -1, -1);
|
||||
testIndexOf(s, 0, 0x110000, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test for lastIndexOf(int ch) method
|
||||
*/
|
||||
static void test5() {
|
||||
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
String s = input[i];
|
||||
|
||||
/*
|
||||
* Normal case
|
||||
*/
|
||||
testLastIndexOf(s, golden3[i][0],
|
||||
golden3[i][golden3[i].length-2]);
|
||||
|
||||
/*
|
||||
* Abnormal case - char which isn't included in the string.
|
||||
*/
|
||||
testLastIndexOf(s, 'Z', -1);
|
||||
testLastIndexOf(s, 0xDB98, -1);
|
||||
testLastIndexOf(s, 0xDE76, -1);
|
||||
testLastIndexOf(s, 0x12345, -1);
|
||||
testLastIndexOf(s, -1, -1);
|
||||
testLastIndexOf(s, 0x110000, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test for lastIndexOf(int ch, int fromIndex) method
|
||||
*/
|
||||
static void test6() {
|
||||
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
String s = input[i];
|
||||
int ch = golden3[i][0];
|
||||
int len = s.length();
|
||||
|
||||
/*
|
||||
* Normal case
|
||||
*/
|
||||
int fromIndex = len - 1;
|
||||
for (int j = golden3[i].length - 2; j > 0; j--) {
|
||||
fromIndex = testLastIndexOf(s, fromIndex, ch,
|
||||
golden3[i][j]) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Abnormal case1 - char is included in the string but fromIndex
|
||||
* is incorrect.
|
||||
*/
|
||||
testLastIndexOf(s, -1, ch, golden3[i][1]);
|
||||
testLastIndexOf(s, len, ch, golden3[i][golden3[i].length-2]);
|
||||
|
||||
/*
|
||||
* Abnormal case2 - char which isn't included in the string.
|
||||
*/
|
||||
testLastIndexOf(s, len, 'Z', -1);
|
||||
testLastIndexOf(s, len, 0xDB98, -1);
|
||||
testLastIndexOf(s, len, 0xDE76, -1);
|
||||
testLastIndexOf(s, len, 0x12345, -1);
|
||||
testLastIndexOf(s, len, -1, -1);
|
||||
testLastIndexOf(s, len, 0x110000, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for String(int[] codePoint, int offset, int count).
|
||||
*/
|
||||
static void test7() {
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
String s = input[i];
|
||||
int nCodePoints = 0;
|
||||
int c;
|
||||
for (int j = 0; j < s.length(); j += Character.charCount(c)) {
|
||||
c = s.codePointAt(j);
|
||||
nCodePoints++;
|
||||
}
|
||||
int[] codePoints = new int[nCodePoints];
|
||||
int count = 0, mid = 0, offset = 0;
|
||||
for (int j = 0; j < s.length(); j += Character.charCount(c)) {
|
||||
if (mid == 0 && j >= s.length()/2) {
|
||||
mid = j;
|
||||
offset = count;
|
||||
}
|
||||
c = s.codePointAt(j);
|
||||
codePoints[count++] = c;
|
||||
}
|
||||
|
||||
String cps = new String(codePoints, 0, count);
|
||||
check(!s.equals(cps), "new String(int[]...) with input[" + i + "]");
|
||||
|
||||
cps = new String(codePoints, 0, offset);
|
||||
check(!s.substring(0, mid).equals(cps),
|
||||
"first half: new String(int[]...) with input[" + i + "]");
|
||||
|
||||
cps = new String(codePoints, offset, count - offset);
|
||||
check(!s.substring(mid).equals(cps),
|
||||
"second half: new String(int[]...) with input[" + i + "]");
|
||||
|
||||
// test exceptions
|
||||
testNewString(null, 0, count, NullPointerException.class);
|
||||
testNewString(codePoints, -1, count, IndexOutOfBoundsException.class);
|
||||
testNewString(codePoints, 0, count+1, IndexOutOfBoundsException.class);
|
||||
testNewString(codePoints, offset, count, IndexOutOfBoundsException.class);
|
||||
testNewString(codePoints, offset, -1, IndexOutOfBoundsException.class);
|
||||
testNewString(codePoints, count, 1, IndexOutOfBoundsException.class);
|
||||
codePoints[offset] = -1;
|
||||
testNewString(codePoints, 0, count, IllegalArgumentException.class);
|
||||
codePoints[offset] = Character.MAX_CODE_POINT+1;
|
||||
testNewString(codePoints, 0, count, IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
{
|
||||
// 6588260: (str) ArrayIndexOutOfBoundsException when trying
|
||||
// to create a String from codePoints
|
||||
//int[] x = new int[Character.MAX_CODE_POINT+1];
|
||||
int[] x = new int[Character.MAX_CODE_POINT];
|
||||
for (int i = 0; i < x.length; i++)
|
||||
if (i != 0xdbff) // For round-trip safety
|
||||
x[i] = i;
|
||||
final String s = new String(x, 0, x.length);
|
||||
check(s.codePointCount(0, s.length()) != x.length,
|
||||
"s.codePointCount(0, s.length()) != x.length");
|
||||
check(s.length() <= x.length,
|
||||
"s.length() <= x.length");
|
||||
for (int i = 0, j = 0; i < x.length; i++) {
|
||||
int c = s.codePointAt(j);
|
||||
check(c != x[i], "c != x[i]");
|
||||
j += Character.charCount(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test codePointCount(int, int)
|
||||
*
|
||||
* This test case assumes that
|
||||
* Character.codePointCount(CharSequence, int, int) works
|
||||
* correctly.
|
||||
*/
|
||||
static void test8() {
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
String str = input[i];
|
||||
int length = str.length();
|
||||
for (int j = 0; j <= length; j++) {
|
||||
int result = str.codePointCount(j, length);
|
||||
int expected = Character.codePointCount(str, j, length);
|
||||
check(result != expected, "codePointCount(input["+i+"], "+j+", "+length+")",
|
||||
result, expected);
|
||||
// Create a substring of the text range. It shares the
|
||||
// underlying char[] of the String str.
|
||||
String substr = str.substring(j, length);
|
||||
result = substr.codePointCount(0, substr.length());
|
||||
check(result != expected, "substring:codePointCount(input["+i+"], "+j+", "+length+")",
|
||||
result, expected);
|
||||
}
|
||||
for (int j = length; j >= 0; j--) {
|
||||
int result = str.codePointCount(0, j);
|
||||
int expected = Character.codePointCount(str, 0, j);
|
||||
check(result != expected, "codePointCount(input["+i+"], 0, "+j+")",
|
||||
result, expected);
|
||||
String substr = str.substring(0, j);
|
||||
result = substr.codePointCount(0, substr.length());
|
||||
check(result != expected, "substring:codePointCount(input["+i+"], 0, "+j+")",
|
||||
result, expected);
|
||||
}
|
||||
|
||||
// test exceptions
|
||||
testCodePointCount(null, 0, 0, NullPointerException.class);
|
||||
testCodePointCount(str, -1, length, IndexOutOfBoundsException.class);
|
||||
testCodePointCount(str, 0, length+1, IndexOutOfBoundsException.class);
|
||||
testCodePointCount(str, length, length-1, IndexOutOfBoundsException.class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test offsetByCodePoints(int, int)
|
||||
*
|
||||
* This test case assumes that
|
||||
* Character.codePointCount(CharSequence, int, int) works
|
||||
* correctly.
|
||||
*/
|
||||
static void test9() {
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
String str = input[i];
|
||||
int length = str.length();
|
||||
for (int j = 0; j <= length; j++) {
|
||||
int nCodePoints = Character.codePointCount(str, j, length);
|
||||
int result = str.offsetByCodePoints(j, nCodePoints);
|
||||
check(result != length,
|
||||
"offsetByCodePoints(input["+i+"], "+j+", "+nCodePoints+")",
|
||||
result, length);
|
||||
result = str.offsetByCodePoints(length, -nCodePoints);
|
||||
int expected = j;
|
||||
if (j > 0 && j < length) {
|
||||
int cp = str.codePointBefore(j+1);
|
||||
if (Character.isSupplementaryCodePoint(cp)) {
|
||||
expected--;
|
||||
}
|
||||
}
|
||||
check(result != expected,
|
||||
"offsetByCodePoints(input["+i+"], "+j+", "+(-nCodePoints)+")",
|
||||
result, expected);
|
||||
}
|
||||
for (int j = length; j >= 0; j--) {
|
||||
int nCodePoints = Character.codePointCount(str, 0, j);
|
||||
int result = str.offsetByCodePoints(0, nCodePoints);
|
||||
int expected = j;
|
||||
if (j > 0 && j < length) {
|
||||
int cp = str.codePointAt(j-1);
|
||||
if (Character.isSupplementaryCodePoint(cp)) {
|
||||
expected++;
|
||||
}
|
||||
}
|
||||
check(result != expected,
|
||||
"offsetByCodePoints(input["+i+"], 0, "+nCodePoints+")",
|
||||
result, expected);
|
||||
result = str.offsetByCodePoints(j, -nCodePoints);
|
||||
check(result != 0,
|
||||
"offsetByCodePoints(input["+i+"], "+j+", "+(-nCodePoints)+")",
|
||||
result, 0);
|
||||
}
|
||||
|
||||
// test exceptions
|
||||
testOffsetByCodePoints(null, 0, 0, NullPointerException.class);
|
||||
testOffsetByCodePoints(str, -1, length, IndexOutOfBoundsException.class);
|
||||
testOffsetByCodePoints(str, 0, length+1, IndexOutOfBoundsException.class);
|
||||
testOffsetByCodePoints(str, 1, -2, IndexOutOfBoundsException.class);
|
||||
testOffsetByCodePoints(str, length, length-1, IndexOutOfBoundsException.class);
|
||||
testOffsetByCodePoints(str, length, -(length+1), IndexOutOfBoundsException.class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test offsetByCodePoints(int, int) - to verify the fix for 6242664
|
||||
*
|
||||
* This test case assumes that
|
||||
* Character.codePointCount(CharSequence, int, int) works
|
||||
* correctly.
|
||||
*/
|
||||
static void test10() {
|
||||
String header = "H\uD800e\uDFFFa\uDBFF\uDC00der<";
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
String wholeString = header + input[i];
|
||||
String str = wholeString.substring(header.length());
|
||||
int length = str.length();
|
||||
for (int j = 0; j <= length; j++) {
|
||||
int nCodePoints = Character.codePointCount(str, j, length);
|
||||
int result = str.offsetByCodePoints(j, nCodePoints);
|
||||
check(result != length,
|
||||
"offsetByCodePoints(input["+i+"], "+j+", "+nCodePoints+")",
|
||||
result, length);
|
||||
result = str.offsetByCodePoints(length, -nCodePoints);
|
||||
int expected = j;
|
||||
if (j > 0 && j < length) {
|
||||
int cp = str.codePointBefore(j+1);
|
||||
if (Character.isSupplementaryCodePoint(cp)) {
|
||||
expected--;
|
||||
}
|
||||
}
|
||||
check(result != expected,
|
||||
"offsetByCodePoints(input["+i+"], "+j+", "+(-nCodePoints)+")",
|
||||
result, expected);
|
||||
}
|
||||
for (int j = length; j >= 0; j--) {
|
||||
int nCodePoints = Character.codePointCount(str, 0, j);
|
||||
int result = str.offsetByCodePoints(0, nCodePoints);
|
||||
int expected = j;
|
||||
if (j > 0 && j < length) {
|
||||
int cp = str.codePointAt(j-1);
|
||||
if (Character.isSupplementaryCodePoint(cp)) {
|
||||
expected++;
|
||||
}
|
||||
}
|
||||
check(result != expected,
|
||||
"offsetByCodePoints(input["+i+"], 0, "+nCodePoints+")",
|
||||
result, expected);
|
||||
result = str.offsetByCodePoints(j, -nCodePoints);
|
||||
check(result != 0,
|
||||
"offsetByCodePoints(input["+i+"], "+j+", "+(-nCodePoints)+")",
|
||||
result, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static final boolean At = true, Before = false;
|
||||
static final boolean FIRST = true, LAST = false;
|
||||
|
||||
static void testCodePoint(boolean isAt, String s, int index, int expected) {
|
||||
int c = isAt ? s.codePointAt(index) : s.codePointBefore(index);
|
||||
|
||||
check(c != expected,
|
||||
"codePoint" + (isAt ? "At" : "Before") + "(" + index + ") for <"
|
||||
+ s + ">", c, expected);
|
||||
}
|
||||
|
||||
static void testCodePoint(boolean isAt, String s, int index) {
|
||||
boolean exceptionOccurred = false;
|
||||
|
||||
try {
|
||||
int c = isAt ? s.codePointAt(index) : s.codePointBefore(index);
|
||||
}
|
||||
catch (StringIndexOutOfBoundsException e) {
|
||||
exceptionOccurred = true;
|
||||
}
|
||||
check(!exceptionOccurred,
|
||||
"codePoint" + (isAt ? "At" : "Before") + "(" + index + ") for <"
|
||||
+ s + "> should throw StringIndexOutOfBoundsPointerException.");
|
||||
}
|
||||
|
||||
static void testIndexOf(String s, int c, int expected) {
|
||||
testIndexOf2(s, c, expected);
|
||||
if (s.indexOf(c) != -1) {
|
||||
testIndexOf2(s + (char) c, c, expected);
|
||||
if (Character.isSupplementaryCodePoint(c)) {
|
||||
char[] surrogates = Character.toChars(c);
|
||||
testIndexOf2(s + new String(surrogates), c, expected);
|
||||
testIndexOf2(s + surrogates[0], c, expected);
|
||||
testIndexOf2(s + surrogates[1], c, expected);
|
||||
testIndexOf2(new String(surrogates) + s, c, 0);
|
||||
testIndexOf2(surrogates[0] + s, c, expected + 1);
|
||||
testIndexOf2(surrogates[1] + s, c, expected + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void testIndexOf2(String s, int c, int expected) {
|
||||
int index = s.indexOf(c);
|
||||
|
||||
check(index != expected,
|
||||
"indexOf(" + toHexString(c) + ") for <" + s + ">",
|
||||
index, expected);
|
||||
}
|
||||
|
||||
static void testLastIndexOf(String s, int c, int expected) {
|
||||
testLastIndexOf2(s, c, expected);
|
||||
if (s.lastIndexOf(c) != -1) {
|
||||
testLastIndexOf2((char) c + s, c, expected + 1);
|
||||
if (Character.isSupplementaryCodePoint(c)) {
|
||||
char[] surrogates = Character.toChars(c);
|
||||
testLastIndexOf2(s + new String(surrogates), c, s.length());
|
||||
testLastIndexOf2(s + surrogates[0], c, expected);
|
||||
testLastIndexOf2(s + surrogates[1], c, expected);
|
||||
testLastIndexOf2(new String(surrogates) + s, c, expected + 2);
|
||||
testLastIndexOf2(surrogates[0] + s, c, expected + 1);
|
||||
testLastIndexOf2(surrogates[1] + s, c, expected + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void testLastIndexOf2(String s, int c, int expected) {
|
||||
int index = s.lastIndexOf(c);
|
||||
|
||||
check(index != expected,
|
||||
"lastIndexOf(" + toHexString(c) + ") for <" + s + ">",
|
||||
index, expected);
|
||||
}
|
||||
|
||||
static int testIndexOf(String s, int fromIndex, int c, int expected) {
|
||||
int index = s.indexOf(c, fromIndex);
|
||||
|
||||
check(index != expected,
|
||||
"indexOf(" + toHexString(c) + ", "
|
||||
+ fromIndex + ") for <" + s + ">",
|
||||
index, expected);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static int testLastIndexOf(String s, int fromIndex, int c, int expected) {
|
||||
int index = s.lastIndexOf(c, fromIndex);
|
||||
|
||||
check(index != expected,
|
||||
"lastIndexOf(" + toHexString(c) + ", "
|
||||
+ fromIndex + ") for <" + s + ">",
|
||||
index, expected);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static void testNewString(int[] codePoints, int offset, int count, Class expectedException) {
|
||||
try {
|
||||
String s = new String(codePoints, offset, count);
|
||||
} catch (Exception e) {
|
||||
if (expectedException.isInstance(e)) {
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Error: Unexpected exception", e);
|
||||
}
|
||||
check(true, "new String(int[]...) didn't throw " + expectedException.getName());
|
||||
}
|
||||
|
||||
static void testCodePointCount(String str, int beginIndex, int endIndex,
|
||||
Class expectedException) {
|
||||
try {
|
||||
int n = str.codePointCount(beginIndex, endIndex);
|
||||
} catch (Exception e) {
|
||||
if (expectedException.isInstance(e)) {
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Error: Unexpected exception", e);
|
||||
}
|
||||
check(true, "codePointCount() didn't throw " + expectedException.getName());
|
||||
}
|
||||
|
||||
static void testOffsetByCodePoints(String str, int index, int offset,
|
||||
Class expectedException) {
|
||||
try {
|
||||
int n = str.offsetByCodePoints(index, offset);
|
||||
} catch (Exception e) {
|
||||
if (expectedException.isInstance(e)) {
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Error: Unexpected exception", e);
|
||||
}
|
||||
check(true, "offsetByCodePoints() didn't throw " + expectedException.getName());
|
||||
}
|
||||
|
||||
static void check(boolean err, String msg) {
|
||||
if (err) {
|
||||
throw new RuntimeException("Error: " + msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void check(boolean err, String s, int got, int expected) {
|
||||
if (err) {
|
||||
throw new RuntimeException("Error: " + s
|
||||
+ " returned an unexpected value. got "
|
||||
+ toHexString(got)
|
||||
+ ", expected "
|
||||
+ toHexString(expected));
|
||||
}
|
||||
}
|
||||
|
||||
private static String toHexString(int c) {
|
||||
return "0x" + Integer.toHexString(c);
|
||||
}
|
||||
}
|
||||
1
test/jdk/java/lang/String/TEST.properties
Normal file
1
test/jdk/java/lang/String/TEST.properties
Normal file
|
|
@ -0,0 +1 @@
|
|||
allowSmartActionArgs=true
|
||||
193
test/jdk/java/lang/String/ToLowerCase.java
Normal file
193
test/jdk/java/lang/String/ToLowerCase.java
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2022, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
@test
|
||||
@bug 4217441 4533872 4900935 8020037 8032012 8041791 8042589 8054307
|
||||
@summary toLowerCase should lower-case Greek Sigma correctly depending
|
||||
on the context (final/non-final). Also it should handle
|
||||
Locale specific (lt, tr, and az) lowercasings and supplementary
|
||||
characters correctly.
|
||||
*/
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class ToLowerCase {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Locale turkish = Locale.of("tr", "TR");
|
||||
Locale lt = Locale.of("lt"); // Lithanian
|
||||
Locale az = Locale.of("az"); // Azeri
|
||||
|
||||
// Greek Sigma final/non-final tests
|
||||
test("\u03A3", Locale.US, "\u03C3");
|
||||
test("LAST\u03A3", Locale.US, "last\u03C2");
|
||||
test("MID\u03A3DLE", Locale.US, "mid\u03C3dle");
|
||||
test("WORD1 \u03A3 WORD3", Locale.US, "word1 \u03C3 word3");
|
||||
test("WORD1 LAST\u03A3 WORD3", Locale.US, "word1 last\u03C2 word3");
|
||||
test("WORD1 MID\u03A3DLE WORD3", Locale.US, "word1 mid\u03C3dle word3");
|
||||
test("\u0399\u0395\u03a3\u03a5\u03a3 \u03a7\u03a1\u0399\u03a3\u03a4\u039f\u03a3", Locale.US,
|
||||
"\u03b9\u03b5\u03c3\u03c5\u03c2 \u03c7\u03c1\u03b9\u03c3\u03c4\u03bf\u03c2"); // "IESUS XRISTOS"
|
||||
|
||||
// Explicit dot above for I's and J's whenever there are more accents above (Lithanian)
|
||||
test("I", lt, "i");
|
||||
test("I\u0300", lt, "i\u0307\u0300"); // "I" followed by COMBINING GRAVE ACCENT (cc==230)
|
||||
test("I\u0316", lt, "i\u0316"); // "I" followed by COMBINING GRAVE ACCENT BELOW (cc!=230)
|
||||
test("J", lt, "j");
|
||||
test("J\u0300", lt, "j\u0307\u0300"); // "J" followed by COMBINING GRAVE ACCENT (cc==230)
|
||||
test("J\u0316", lt, "j\u0316"); // "J" followed by COMBINING GRAVE ACCENT BELOW (cc!=230)
|
||||
test("\u012E", lt, "\u012F");
|
||||
test("\u012E\u0300", lt, "\u012F\u0307\u0300"); // "I (w/ OGONEK)" followed by COMBINING GRAVE ACCENT (cc==230)
|
||||
test("\u012E\u0316", lt, "\u012F\u0316"); // "I (w/ OGONEK)" followed by COMBINING GRAVE ACCENT BELOW (cc!=230)
|
||||
test("\u00CC", lt, "i\u0307\u0300");
|
||||
test("\u00CD", lt, "i\u0307\u0301");
|
||||
test("\u0128", lt, "i\u0307\u0303");
|
||||
test("I\u0300", Locale.US, "i\u0300"); // "I" followed by COMBINING GRAVE ACCENT (cc==230)
|
||||
test("J\u0300", Locale.US, "j\u0300"); // "J" followed by COMBINING GRAVE ACCENT (cc==230)
|
||||
test("\u012E\u0300", Locale.US, "\u012F\u0300"); // "I (w/ OGONEK)" followed by COMBINING GRAVE ACCENT (cc==230)
|
||||
test("\u00CC", Locale.US, "\u00EC");
|
||||
test("\u00CD", Locale.US, "\u00ED");
|
||||
test("\u0128", Locale.US, "\u0129");
|
||||
|
||||
// I-dot tests
|
||||
test("\u0130", turkish, "i");
|
||||
test("\u0130", az, "i");
|
||||
test("\u0130", lt, "\u0069\u0307");
|
||||
test("\u0130", Locale.US, "\u0069\u0307");
|
||||
test("\u0130", Locale.JAPAN, "\u0069\u0307");
|
||||
test("\u0130", Locale.ROOT, "\u0069\u0307");
|
||||
|
||||
// Remove dot_above in the sequence I + dot_above (Turkish and Azeri)
|
||||
test("I\u0307", turkish, "i");
|
||||
test("I\u0307", az, "i");
|
||||
test("J\u0307", turkish, "j\u0307");
|
||||
test("J\u0307", az, "j\u0307");
|
||||
|
||||
// Unless an I is before a dot_above, it turns into a dotless i (Turkish and Azeri)
|
||||
test("I", turkish, "\u0131");
|
||||
test("I", az, "\u0131");
|
||||
test("I", Locale.US, "i");
|
||||
test("IABC", turkish, "\u0131abc");
|
||||
test("IABC", az, "\u0131abc");
|
||||
test("IABC", Locale.US, "iabc");
|
||||
|
||||
// Supplementary character tests
|
||||
//
|
||||
// U+10400 ("\uD801\uDC00"): DESERET CAPITAL LETTER LONG I
|
||||
// U+10401 ("\uD801\uDC01"): DESERET CAPITAL LETTER LONG E
|
||||
// U+10402 ("\uD801\uDC02"): DESERET CAPITAL LETTER LONG A
|
||||
// U+10428 ("\uD801\uDC28"): DESERET SMALL LETTER LONG I
|
||||
// U+10429 ("\uD801\uDC29"): DESERET SMALL LETTER LONG E
|
||||
// U+1042A ("\uD801\uDC2A"): DESERET SMALL LETTER LONG A
|
||||
//
|
||||
// valid code point tests:
|
||||
test("\uD801\uDC00\uD801\uDC01\uD801\uDC02", Locale.US, "\uD801\uDC28\uD801\uDC29\uD801\uDC2A");
|
||||
test("\uD801\uDC00A\uD801\uDC01B\uD801\uDC02C", Locale.US, "\uD801\uDC28a\uD801\uDC29b\uD801\uDC2Ac");
|
||||
// invalid code point tests:
|
||||
test("\uD800\uD800\uD801A\uDC00\uDC00\uDC00B", Locale.US, "\uD800\uD800\uD801a\uDC00\uDC00\uDC00b");
|
||||
|
||||
// lower/uppercase + surrogates
|
||||
test("a\uD801\uDC1c", Locale.ROOT, "a\uD801\uDC44");
|
||||
test("A\uD801\uDC1c", Locale.ROOT, "a\uD801\uDC44");
|
||||
test("a\uD801\uDC00\uD801\uDC01\uD801\uDC02", Locale.US, "a\uD801\uDC28\uD801\uDC29\uD801\uDC2A");
|
||||
test("A\uD801\uDC00\uD801\uDC01\uD801\uDC02", Locale.US, "a\uD801\uDC28\uD801\uDC29\uD801\uDC2A");
|
||||
|
||||
// test bmp + supp1
|
||||
StringBuilder src = new StringBuilder(0x20000);
|
||||
StringBuilder exp = new StringBuilder(0x20000);
|
||||
for (int cp = 0; cp < 0x20000; cp++) {
|
||||
if (cp >= Character.MIN_HIGH_SURROGATE && cp <= Character.MAX_HIGH_SURROGATE) {
|
||||
continue;
|
||||
}
|
||||
if (cp == 0x0130) {
|
||||
// Although UnicodeData.txt has the lower case char as \u0069, it should be
|
||||
// handled with the rules in SpecialCasing.txt, i.e., \u0069\u0307 in
|
||||
// non Turkic locales.
|
||||
continue;
|
||||
}
|
||||
int lowerCase = Character.toLowerCase(cp);
|
||||
if (lowerCase == -1) { //Character.ERROR
|
||||
continue;
|
||||
}
|
||||
src.appendCodePoint(cp);
|
||||
exp.appendCodePoint(lowerCase);
|
||||
}
|
||||
test(src.toString(), Locale.US, exp.toString());
|
||||
|
||||
// test latin1
|
||||
src = new StringBuilder(0x100);
|
||||
exp = new StringBuilder(0x100);
|
||||
for (int cp = 0; cp < 0x100; cp++) {
|
||||
int lowerCase = Character.toLowerCase(cp);
|
||||
if (lowerCase == -1) { //Character.ERROR
|
||||
continue;
|
||||
}
|
||||
src.appendCodePoint(cp);
|
||||
exp.appendCodePoint(lowerCase);
|
||||
}
|
||||
test(src.toString(), Locale.US, exp.toString());
|
||||
|
||||
// test non-latin1 -> latin1
|
||||
src = new StringBuilder(0x100).append("abc");
|
||||
exp = new StringBuilder(0x100).append("abc");
|
||||
for (int cp = 0x100; cp < 0x10000; cp++) {
|
||||
int lowerCase = Character.toLowerCase(cp);
|
||||
if (lowerCase < 0x100 && cp != '\u0130') {
|
||||
src.appendCodePoint(cp);
|
||||
exp.appendCodePoint(lowerCase);
|
||||
}
|
||||
}
|
||||
test(src.toString(), Locale.US, exp.toString());
|
||||
}
|
||||
|
||||
static void test(String in, Locale locale, String expected) {
|
||||
test0(in, locale,expected);
|
||||
for (String[] ss : new String[][] {
|
||||
new String[] {"abc", "abc"},
|
||||
new String[] {"aBc", "abc"},
|
||||
new String[] {"ABC", "abc"},
|
||||
new String[] {"ab\u4e00", "ab\u4e00"},
|
||||
new String[] {"aB\u4e00", "ab\u4e00"},
|
||||
new String[] {"AB\u4e00", "ab\u4e00"},
|
||||
new String[] {"ab\uD800\uDC00", "ab\uD800\uDC00"},
|
||||
new String[] {"aB\uD800\uDC00", "ab\uD800\uDC00"},
|
||||
new String[] {"AB\uD800\uDC00", "ab\uD800\uDC00"},
|
||||
new String[] {"ab\uD801\uDC1C", "ab\uD801\uDC44"},
|
||||
new String[] {"aB\uD801\uDC1C", "ab\uD801\uDC44"},
|
||||
new String[] {"AB\uD801\uDC1C", "ab\uD801\uDC44"},
|
||||
|
||||
}) {
|
||||
test0(ss[0] + " " + in, locale, ss[1] + " " + expected);
|
||||
test0(in + " " + ss[0], locale, expected + " " + ss[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void test0(String in, Locale locale, String expected) {
|
||||
String result = in.toLowerCase(locale);
|
||||
if (!result.equals(expected)) {
|
||||
System.err.println("input: " + in + ", locale: " + locale +
|
||||
", expected: " + expected + ", actual: " + result);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
162
test/jdk/java/lang/String/ToUpperCase.java
Normal file
162
test/jdk/java/lang/String/ToUpperCase.java
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2022, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
@test
|
||||
@bug 4219630 4304573 4533872 4900935 8042589 8054307
|
||||
@summary toUpperCase should upper-case German sharp s correctly even if
|
||||
it's the only character in the string. should also uppercase
|
||||
all of the 1:M char mappings correctly. Also it should handle
|
||||
Locale specific (lt, tr, and az) uppercasings and supplementary
|
||||
characters correctly.
|
||||
*/
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class ToUpperCase {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Locale turkish = Locale.of("tr", "TR");
|
||||
Locale lt = Locale.of("lt"); // Lithanian
|
||||
Locale az = Locale.of("az"); // Azeri
|
||||
|
||||
test("\u00DF", turkish, "SS");
|
||||
test("a\u00DF", turkish, "ASS");
|
||||
test("i", turkish, "\u0130");
|
||||
test("i", az, "\u0130");
|
||||
test("\u0131", turkish, "I");
|
||||
test("\u00DF", Locale.GERMANY, "SS");
|
||||
test("a\u00DF", Locale.GERMANY, "ASS");
|
||||
test("i", Locale.GERMANY, "I");
|
||||
|
||||
// test some of the 1:M uppercase mappings
|
||||
test("abc\u00DF", Locale.US, "ABC\u0053\u0053");
|
||||
test("\u0149abc", Locale.US, "\u02BC\u004EABC");
|
||||
test("\u0149abc", turkish, "\u02BC\u004EABC");
|
||||
test("\u1F52", Locale.US, "\u03A5\u0313\u0300");
|
||||
test("\u0149\u1F52", Locale.US, "\u02BC\u004E\u03A5\u0313\u0300");
|
||||
test("\u1F54ZZZ", Locale.US, "\u03A5\u0313\u0301ZZZ");
|
||||
test("\u1F54ZZZ", turkish, "\u03A5\u0313\u0301ZZZ");
|
||||
test("a\u00DF\u1F56", Locale.US, "ASS\u03A5\u0313\u0342");
|
||||
test("\u1FAD", turkish, "\u1F6D\u0399");
|
||||
test("i\u1FC7", turkish, "\u0130\u0397\u0342\u0399");
|
||||
test("i\u1FC7", az, "\u0130\u0397\u0342\u0399");
|
||||
test("i\u1FC7", Locale.US, "I\u0397\u0342\u0399");
|
||||
test("\uFB04", Locale.US, "\u0046\u0046\u004C");
|
||||
test("\uFB17AbCdEfi", turkish, "\u0544\u053DABCDEF\u0130");
|
||||
test("\uFB17AbCdEfi", az, "\u0544\u053DABCDEF\u0130");
|
||||
|
||||
// Remove DOT ABOVE after "i" in Lithuanian
|
||||
test("i\u0307", lt, "I");
|
||||
test("\u0307", lt, "\u0307");
|
||||
test("\u0307i", lt, "\u0307I");
|
||||
test("j\u0307", lt, "J");
|
||||
test("abci\u0307def", lt, "ABCIDEF");
|
||||
test("a\u0307", lt, "A\u0307");
|
||||
test("abc\u0307def", lt, "ABC\u0307DEF");
|
||||
test("i\u0307", Locale.US, "I\u0307");
|
||||
test("i\u0307", turkish, "\u0130\u0307");
|
||||
|
||||
// Supplementary character tests
|
||||
//
|
||||
// U+10400 ("\uD801\uDC00"): DESERET CAPITAL LETTER LONG I
|
||||
// U+10401 ("\uD801\uDC01"): DESERET CAPITAL LETTER LONG E
|
||||
// U+10402 ("\uD801\uDC02"): DESERET CAPITAL LETTER LONG A
|
||||
// U+10428 ("\uD801\uDC28"): DESERET SMALL LETTER LONG I
|
||||
// U+10429 ("\uD801\uDC29"): DESERET SMALL LETTER LONG E
|
||||
// U+1042A ("\uD801\uDC2A"): DESERET SMALL LETTER LONG A
|
||||
//
|
||||
// valid code point tests:
|
||||
test("\uD801\uDC28\uD801\uDC29\uD801\uDC2A", Locale.US, "\uD801\uDC00\uD801\uDC01\uD801\uDC02");
|
||||
test("\uD801\uDC28a\uD801\uDC29b\uD801\uDC2Ac", Locale.US, "\uD801\uDC00A\uD801\uDC01B\uD801\uDC02C");
|
||||
// invalid code point tests:
|
||||
test("\uD800\uD800\uD801a\uDC00\uDC00\uDC00b", Locale.US, "\uD800\uD800\uD801A\uDC00\uDC00\uDC00B");
|
||||
|
||||
// lower/uppercase + surrogates
|
||||
test("a\uD801\uDC44", Locale.ROOT, "A\uD801\uDC1c");
|
||||
test("A\uD801\uDC44", Locale.ROOT, "A\uD801\uDC1c");
|
||||
test("a\uD801\uDC28\uD801\uDC29\uD801\uDC2A", Locale.US, "A\uD801\uDC00\uD801\uDC01\uD801\uDC02");
|
||||
test("A\uD801\uDC28a\uD801\uDC29b\uD801\uDC2Ac", Locale.US, "A\uD801\uDC00A\uD801\uDC01B\uD801\uDC02C");
|
||||
|
||||
// test latin1 only case
|
||||
StringBuilder src = new StringBuilder(0x100);
|
||||
StringBuilder exp = new StringBuilder(0x100);
|
||||
for (int cp = 0; cp < 0x100; cp++) {
|
||||
int upperCase = Character.toUpperCase(cp);
|
||||
if (upperCase == -1) { //Character.ERROR
|
||||
continue;
|
||||
}
|
||||
src.appendCodePoint(cp);
|
||||
if (cp == '\u00df') {
|
||||
exp.append("SS"); // need Character.toUpperCaseEx()
|
||||
} else {
|
||||
exp.appendCodePoint(upperCase);
|
||||
}
|
||||
}
|
||||
test(src.toString(), Locale.US, exp.toString());
|
||||
|
||||
// test non-latin1 -> latin1
|
||||
src = new StringBuilder(0x100).append("ABC");
|
||||
exp = new StringBuilder(0x100).append("ABC");
|
||||
for (int cp = 0x100; cp < 0x10000; cp++) {
|
||||
int upperCase = Character.toUpperCase(cp);
|
||||
if (upperCase < 0x100) {
|
||||
src.appendCodePoint(cp);
|
||||
exp.appendCodePoint(upperCase);
|
||||
}
|
||||
}
|
||||
test(src.toString(), Locale.US, exp.toString());
|
||||
|
||||
}
|
||||
|
||||
static void test(String in, Locale locale, String expected) {
|
||||
test0(in, locale,expected);
|
||||
// trigger different code paths
|
||||
for (String[] ss : new String[][] {
|
||||
new String[] {"abc", "ABC"},
|
||||
new String[] {"AbC", "ABC"},
|
||||
new String[] {"ABC", "ABC"},
|
||||
new String[] {"AB\u4e00", "AB\u4e00"},
|
||||
new String[] {"ab\u4e00", "AB\u4e00"},
|
||||
new String[] {"aB\u4e00", "AB\u4e00"},
|
||||
new String[] {"AB\uD800\uDC00", "AB\uD800\uDC00"},
|
||||
new String[] {"Ab\uD800\uDC00", "AB\uD800\uDC00"},
|
||||
new String[] {"ab\uD800\uDC00", "AB\uD800\uDC00"},
|
||||
new String[] {"AB\uD801\uDC44", "AB\uD801\uDC1C"},
|
||||
new String[] {"Ab\uD801\uDC44", "AB\uD801\uDC1C"},
|
||||
new String[] {"ab\uD801\uDC44", "AB\uD801\uDC1C"},
|
||||
}) {
|
||||
test0(ss[0] + " " + in, locale, ss[1] + " " + expected);
|
||||
test0(in + " " + ss[0], locale, expected + " " + ss[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void test0(String in, Locale locale, String expected) {
|
||||
String result = in.toUpperCase(locale);
|
||||
if (!result.equals(expected)) {
|
||||
System.err.println("input: " + in + ", locale: " + locale +
|
||||
", expected: " + expected + ", actual: " + result);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
73
test/jdk/java/lang/String/Transform.java
Normal file
73
test/jdk/java/lang/String/Transform.java
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Unit tests for String#transform(Function<String, R> f)
|
||||
* @run main Transform
|
||||
*/
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Transform {
|
||||
public static void main(String[] args) {
|
||||
test1();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test String#transform(Function<? super String, ? extends R> f) functionality.
|
||||
*/
|
||||
static void test1() {
|
||||
simpleTransform("toUpperCase", "abc", s -> s.toUpperCase());
|
||||
simpleTransform("toLowerCase", "ABC", s -> s.toLowerCase());
|
||||
simpleTransform("substring", "John Smith", s -> s.substring(0, 4));
|
||||
|
||||
String multiline = " This is line one\n" +
|
||||
" This is line two\n" +
|
||||
" This is line three\n";
|
||||
String expected = "This is line one!\n" +
|
||||
" This is line two!\n" +
|
||||
" This is line three!\n";
|
||||
check("multiline", multiline.transform(string -> {
|
||||
return string.lines()
|
||||
.map(s -> s.transform(t -> t.substring(4) + "!"))
|
||||
.collect(Collectors.joining("\n", "", "\n"));
|
||||
}), expected);
|
||||
}
|
||||
|
||||
static void simpleTransform(String test, String s, Function<String, String> f) {
|
||||
check(test, s.transform(f), f.apply(s));
|
||||
}
|
||||
|
||||
static void check(String test, Object output, Object expected) {
|
||||
if (output != expected && (output == null || !output.equals(expected))) {
|
||||
System.err.println("Testing " + test + ": unexpected result");
|
||||
System.err.println("Output:");
|
||||
System.err.println(output);
|
||||
System.err.println("Expected:");
|
||||
System.err.println(expected);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
125
test/jdk/java/lang/String/TranslateEscapes.java
Normal file
125
test/jdk/java/lang/String/TranslateEscapes.java
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8223780
|
||||
* @summary This exercises String#translateEscapes patterns and limits.
|
||||
* @compile TranslateEscapes.java
|
||||
* @run main TranslateEscapes
|
||||
*/
|
||||
|
||||
public class TranslateEscapes {
|
||||
public static void main(String... arg) {
|
||||
test1();
|
||||
test2();
|
||||
test3();
|
||||
test4();
|
||||
}
|
||||
|
||||
/*
|
||||
* Standard escapes.
|
||||
*/
|
||||
static void test1() {
|
||||
verifyEscape("b", '\b');
|
||||
verifyEscape("f", '\f');
|
||||
verifyEscape("n", '\n');
|
||||
verifyEscape("r", '\r');
|
||||
verifyEscape("s", '\s');
|
||||
verifyEscape("t", '\t');
|
||||
verifyEscape("'", '\'');
|
||||
verifyEscape("\"", '\"');
|
||||
verifyEscape("\\", '\\');
|
||||
}
|
||||
|
||||
/*
|
||||
* Octal escapes.
|
||||
*/
|
||||
static void test2() {
|
||||
verifyOctalEscape("0", 0);
|
||||
verifyOctalEscape("3", 03);
|
||||
verifyOctalEscape("7", 07);
|
||||
verifyOctalEscape("07", 07);
|
||||
verifyOctalEscape("17", 017);
|
||||
verifyOctalEscape("27", 027);
|
||||
verifyOctalEscape("37", 037);
|
||||
verifyOctalEscape("377", 0377);
|
||||
|
||||
verifyOctalEscape("777", 077);
|
||||
verifyOctalEscape("78", 07);
|
||||
}
|
||||
|
||||
/*
|
||||
* Exceptions.
|
||||
*/
|
||||
static void test3() {
|
||||
exceptionThrown("+");
|
||||
exceptionThrown("q");
|
||||
}
|
||||
|
||||
/*
|
||||
* Escape line terminator.
|
||||
*/
|
||||
static void test4() {
|
||||
verifyLineTerminator("\n");
|
||||
verifyLineTerminator("\r\n");
|
||||
verifyLineTerminator("\r");
|
||||
}
|
||||
|
||||
static void verifyEscape(String string, char ch) {
|
||||
String escapes = "\\" + string;
|
||||
if (escapes.translateEscapes().charAt(0) != ch) {
|
||||
System.err.format("\"%s\" not escape \"%s\"'%n", string, escapes);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
static void verifyOctalEscape(String string, int octal) {
|
||||
String escapes = "\\" + string;
|
||||
if (escapes.translateEscapes().charAt(0) != octal) {
|
||||
System.err.format("\"%s\" not octal %o%n", string, octal);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
static void exceptionThrown(String string) {
|
||||
String escapes = "\\" + string;
|
||||
try {
|
||||
escapes.translateEscapes();
|
||||
System.err.format("escape not thrown for %s%n", string);
|
||||
throw new RuntimeException();
|
||||
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// okay
|
||||
}
|
||||
}
|
||||
|
||||
static void verifyLineTerminator(String string) {
|
||||
String escapes = "\\" + string;
|
||||
if (!escapes.translateEscapes().isEmpty()) {
|
||||
System.err.format("escape for line terminator not handled %s%n",
|
||||
string.replace("\n", "\\n").replace("\r", "\\r"));
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
329
test/jdk/java/lang/String/UnicodeCaseFoldingTest.java
Normal file
329
test/jdk/java/lang/String/UnicodeCaseFoldingTest.java
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary tests unicode case-folding based String comparison and equality
|
||||
* @bug 4397357
|
||||
* @library /lib/testlibrary/java/lang
|
||||
* @modules java.base/jdk.internal.lang:+open
|
||||
* @run junit/othervm
|
||||
* UnicodeCaseFoldingTest
|
||||
*/
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import jdk.internal.lang.CaseFolding;
|
||||
|
||||
public class UnicodeCaseFoldingTest {
|
||||
|
||||
@Test
|
||||
void testAllCommnFullCodePointsListedInCaseFoldinigTxt() throws Throwable {
|
||||
var filter = "^.*; [CF]; .*$"; // C=common, F=full, for full case folding
|
||||
var results = Files.lines(UCDFiles.CASEFOLDING)
|
||||
.filter(line -> !line.startsWith("#") && line.matches(filter))
|
||||
.map(line -> {
|
||||
var fields = line.split("; ");
|
||||
var cp = Integer.parseInt(fields[0], 16);
|
||||
fields = fields[2].trim().split(" ");
|
||||
var folding = new int[fields.length];
|
||||
for (int i = 0; i < folding.length; i++) {
|
||||
folding[i] = Integer.parseInt(fields[i], 16);
|
||||
}
|
||||
var source = new String(Character.toChars(cp));
|
||||
var expected = new String(folding, 0, folding.length);
|
||||
// (1) Verify the folding result matches expected
|
||||
assertEquals(expected, foldCase(source), "CaseFolding.fold(): ");
|
||||
|
||||
// (2) Verify compareToFoldCase() result
|
||||
assertEquals(0, source.compareToFoldCase(expected), "source.compareToFoldCase(expected)");
|
||||
assertEquals(0, expected.compareToFoldCase(source), "expected.compareToFoldCase(source)");
|
||||
|
||||
// (3) Verify equalsFoldCase() result
|
||||
assertEquals(true, source.equalsFoldCase(expected), "source.equalsFoldCase(expected)");
|
||||
assertEquals(true, expected.equalsFoldCase(source), "expected.equalsFoldCase(source)");
|
||||
return null;
|
||||
})
|
||||
.filter(error -> error != null)
|
||||
.toArray();
|
||||
assertEquals(0, results.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAllSimpleCodePointsListedInCaseFoldinigTxt() throws Throwable {
|
||||
// S=simple, for simple case folding. The simple case folding should still matches
|
||||
var filter = "^.*; [S]; .*$";
|
||||
var results = Files.lines(UCDFiles.CASEFOLDING)
|
||||
.filter(line -> !line.startsWith("#") && line.matches(filter))
|
||||
.map(line -> {
|
||||
var fields = line.split("; ");
|
||||
var cp = Integer.parseInt(fields[0], 16);
|
||||
fields = fields[2].trim().split(" ");
|
||||
var folding = new int[fields.length];
|
||||
for (int i = 0; i < folding.length; i++) {
|
||||
folding[i] = Integer.parseInt(fields[i], 16);
|
||||
}
|
||||
var source = new String(Character.toChars(cp));
|
||||
var expected = new String(folding, 0, folding.length);
|
||||
|
||||
// (1) Verify compareToFoldCase() result
|
||||
assertEquals(0, source.compareToFoldCase(expected), "source.compareToFoldCase(expected)");
|
||||
assertEquals(0, expected.compareToFoldCase(source), "expected.compareToFoldCase(source)");
|
||||
|
||||
// (2) Verify equalsFoldCase() result
|
||||
assertEquals(true, source.equalsFoldCase(expected), "source.equalsFoldCase(expected)");
|
||||
assertEquals(true, expected.equalsFoldCase(source), "expected.equalsFoldCase(source)");
|
||||
return null;
|
||||
})
|
||||
.filter(error -> error != null)
|
||||
.toArray();
|
||||
assertEquals(0, results.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllCodePointsFoldToThemselvesIfNotListed() throws Exception {
|
||||
// Collect all code points that appear in CaseFolding.txt
|
||||
var listed = Files.lines(UCDFiles.CASEFOLDING)
|
||||
.filter(line -> !line.startsWith("#") && line.matches("^.*; [CF]; .*$"))
|
||||
.map(line -> Integer.parseInt(line.split("; ")[0], 16))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
var failures = new ArrayList<String>();
|
||||
|
||||
// Scan BMP + Supplementary Plane 1 (U+0000..U+1FFFF)
|
||||
for (int cp = Character.MIN_CODE_POINT; cp <= 0x1FFFF; cp++) {
|
||||
if (!Character.isDefined(cp)) {
|
||||
continue; // skip undefined
|
||||
}
|
||||
if (Character.isSurrogate((char) cp)) {
|
||||
continue; // skip surrogate code units
|
||||
}
|
||||
if (listed.contains(cp)) {
|
||||
continue; // already tested separately
|
||||
}
|
||||
String s = new String(Character.toChars(cp));
|
||||
String folded = foldCase(s);
|
||||
if (!s.equals(folded)) {
|
||||
failures.add(String.format("Unexpected folding: U+%04X '%s' → '%s'", cp, s, folded));
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(0, failures.size(),
|
||||
() -> "Some unlisted code points folded unexpectedly:\n"
|
||||
+ String.join("\n", failures));
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "CaseFold \"{0}\" → \"{1}\"")
|
||||
@MethodSource("caseFoldTestCases")
|
||||
void testIndividualCaseFolding(String input, String expected) {
|
||||
assertEquals(expected, foldCase(input));
|
||||
}
|
||||
|
||||
static Stream<Arguments> caseFoldTestCases() {
|
||||
return Stream.of(
|
||||
// ASCII simple cases
|
||||
Arguments.of("ABC", "abc"),
|
||||
Arguments.of("already", "already"),
|
||||
Arguments.of("MiXeD123", "mixed123"),
|
||||
// --- Latin-1 to non-Latin-1 fold ---
|
||||
Arguments.of("aBc\u00B5Efg", "abc\u03BCefg"), // "µ" → "μ"
|
||||
Arguments.of("test\u00B5\ud801\udc00X", "test\u03bc\ud801\udc28x"),
|
||||
// German Eszett
|
||||
Arguments.of("Stra\u00DFe", "strasse"), // "Straße"
|
||||
Arguments.of("\u1E9E", "ss"), // "ẞ" capital sharp S
|
||||
// Turkish dotted I / dotless i
|
||||
Arguments.of("I", "i"),
|
||||
Arguments.of("\u0130", "i\u0307"), // capital dotted I → "i + dot above"
|
||||
Arguments.of("\u0069\u0307", "i\u0307"), // small i + dot above remains
|
||||
Arguments.of("\u0131", "\u0131"), // "ı" (dotless i stays dotless)
|
||||
|
||||
// Greek special cases ---
|
||||
Arguments.of("\u039F\u03A3", "\u03BF\u03C3"), // "ΟΣ" → "οσ" final sigma always folds to normal sigma
|
||||
Arguments.of("\u1F88", "\u1F00\u03B9"), // "ᾈ" → "ἀι" Alpha with psili + ypogegrammeni
|
||||
Arguments.of("\u039C\u03AC\u03CA\u03BF\u03C2", "\u03BC\u03AC\u03CA\u03BF\u03C3"), // "Μάϊος" → "μάϊοσ"
|
||||
Arguments.of("\u1F08", "\u1F00"), // Ἀ (Capital Alpha with psili) → ἀ
|
||||
|
||||
// Supplementary Plane characters
|
||||
Arguments.of("\uD801\uDC00", "\uD801\uDC28"), // Deseret Capital Letter Long I → Small
|
||||
Arguments.of("\uD801\uDC01", "\uD801\uDC29"), // Deseret Capital Letter Long E → Small
|
||||
|
||||
// Supplementary inside ASCII
|
||||
Arguments.of("abc\uD801\uDC00def", "abc\uD801\uDC28def"),
|
||||
// Ligatures and compatibility folds
|
||||
Arguments.of("\uFB00", "ff"), // ff → ff
|
||||
Arguments.of("\uFB03", "ffi"), // ffi → ffi
|
||||
Arguments.of("\u212A", "k"), // Kelvin sign → k
|
||||
|
||||
Arguments.of("abc\uFB00def", "abcffdef"), // ff → ff
|
||||
Arguments.of("abc\uFB03def", "abcffidef"), // ffi → ffi
|
||||
Arguments.of("abc\u212Adef", "abckdef"), // Kelvin sign → k
|
||||
|
||||
// --- Fullwidth ---
|
||||
Arguments.of("\uFF21\uFF22\uFF23", "\uFF41\uFF42\uFF43"), // "ABC" → "abc"
|
||||
|
||||
// --- Armenian ---
|
||||
Arguments.of("\u0531", "\u0561"), // "Ա" → "ա"
|
||||
|
||||
// --- Cherokee ---
|
||||
Arguments.of("\u13A0", "\u13A0"), // Capital Cherokee A folds to itself
|
||||
Arguments.of("\uAB70", "\u13A0") // Small Cherokee A folds Capital Cherokee A
|
||||
);
|
||||
}
|
||||
|
||||
static Stream<Arguments> caseFoldEqualProvider() {
|
||||
return Stream.of(
|
||||
Arguments.of("abc", "ABC"),
|
||||
Arguments.of("aBcDe", "AbCdE"),
|
||||
Arguments.of("\u00C0\u00E7", "\u00E0\u00C7"), // Àç vs àÇ
|
||||
Arguments.of("straße", "STRASSE"), // ß → ss
|
||||
Arguments.of("\uD83C\uDDE6", "\uD83C\uDDE6"), // 🇦 vs 🇦
|
||||
Arguments.of("\u1E9E", "ss"), // ẞ (capital sharp S)
|
||||
Arguments.of("\u03A3", "\u03C3"), // Σ vs σ (Greek Sigma)
|
||||
Arguments.of("\u03C3", "\u03C2"), // σ vs ς (Greek sigma/final sigma)
|
||||
Arguments.of("\u212B", "\u00E5"), // Å (Angstrom sign) vs å
|
||||
Arguments.of("\uFB00", "ff"), // ff (ligature)
|
||||
Arguments.of("\u01C5", "\u01C5"), // Dž (Latin capital D with small z with caron)
|
||||
Arguments.of("Caf\u00E9", "CAF\u00C9"), // Café vs CAFÉ
|
||||
Arguments.of("\u03BA\u03B1\u03BB\u03B7\u03BC\u03AD\u03C1\u03B1", "\u039A\u0391\u039B\u0397\u039C\u0388\u03A1\u0391"), // καλημέρα vs ΚΑΛΗΜΕΡΑ
|
||||
Arguments.of("\u4E2D\u56FD", "\u4E2D\u56FD"), // 中国
|
||||
Arguments.of("\u03B1", "\u0391"), // α vs Α (Greek alpha)
|
||||
Arguments.of("\u212B", "\u00C5"), // Å vs Å
|
||||
// from StringCompareToIgnoreCase
|
||||
Arguments.of("\u0100\u0102\u0104\u0106\u0108", "\u0100\u0102\u0104\u0106\u0109"), // ĀĂĄĆĈ vs ĀĂĄĆĉ
|
||||
Arguments.of("\u0101\u0103\u0105\u0107\u0109", "\u0100\u0102\u0104\u0106\u0109"), // āăąćĉ vs ĀĂĄĆĉ
|
||||
Arguments.of("\ud801\udc00\ud801\udc01\ud801\udc02\ud801\udc03\ud801\udc04",
|
||||
"\ud801\udc00\ud801\udc01\ud801\udc02\ud801\udc03\ud801\udc2c"), // 𐐀𐐁𐐂𐐃𐐄 vs 𐐀𐐁𐐂𐐃𐐬
|
||||
Arguments.of("\ud801\udc28\ud801\udc29\ud801\udc2a\ud801\udc2b\ud801\udc2c",
|
||||
"\ud801\udc00\ud801\udc01\ud801\udc02\ud801\udc03\ud801\udc2c") // 𐐨𐐩𐐪𐐫𐐬 vs 𐐀𐐁𐐂𐐃𐐬
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("caseFoldEqualProvider")
|
||||
void testcompareToFoldCaseEquals(String s1, String s2) {
|
||||
assertEquals(0, s1.compareToFoldCase(s2));
|
||||
assertEquals(0, s2.compareToFoldCase(s1));
|
||||
assertEquals(true, s1.equalsFoldCase(s2));
|
||||
assertEquals(true, s2.equalsFoldCase(s1));
|
||||
assertEquals(foldCase(s1), foldCase(s2));
|
||||
}
|
||||
|
||||
static Stream<Arguments> caseFoldOrderingProvider() {
|
||||
return Stream.of(
|
||||
Arguments.of("asa", "aß", -1), // ß → ss → "asa" < "ass"
|
||||
Arguments.of("aß", "asa", +1),
|
||||
Arguments.of("a\u00DF", "ass", 0), // aß vs ass
|
||||
Arguments.of("\uFB03", "ffi", 0), // ffi (ligature)
|
||||
Arguments.of("\u00C5", "Z", 1), // Å vs Z
|
||||
Arguments.of("A", "\u00C0", -1), // A vs À
|
||||
Arguments.of("\u03A9", "\u03C9", 0), // Ω vs ω
|
||||
Arguments.of("\u03C2", "\u03C3", 0), // ς vs σ
|
||||
Arguments.of("\uD835\uDD23", "R", 1), // 𝔯 (fraktur r) vs R
|
||||
Arguments.of("\uFF26", "E", 1), // F (full-width F) vs E
|
||||
Arguments.of("\u00C9clair", "Eclair", 1), // Éclair vs Eclair
|
||||
Arguments.of("\u03bc\u00df", "\u00b5s", 1),
|
||||
Arguments.of("\u00b5s", "\u03bc\u00df", -1)
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("caseFoldOrderingProvider")
|
||||
void testcompareToFoldCaseOrdering(String s1, String s2, int expectedSign) {
|
||||
int cmp = s1.compareToFoldCase(s2);
|
||||
assertEquals(expectedSign, Integer.signum(cmp));
|
||||
}
|
||||
|
||||
static Stream<Arguments> roundTripProvider() {
|
||||
return Stream.of(
|
||||
Arguments.of("abc"),
|
||||
Arguments.of("ABC"),
|
||||
Arguments.of("straße"),
|
||||
Arguments.of("Àç"),
|
||||
Arguments.of("aß"),
|
||||
Arguments.of("\uFB02uff"), // fluff (ligature in "fluff")
|
||||
Arguments.of("\u00C9COLE") // ÉCOLE
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("roundTripProvider")
|
||||
void testCaseFoldRoundTrip(String s) {
|
||||
String folded = foldCase(s);
|
||||
assertEquals(0, s.compareToFoldCase(folded));
|
||||
assertEquals(0, folded.compareToFoldCase(s));
|
||||
assertEquals(true, s.equalsFoldCase(folded));
|
||||
assertEquals(true, folded.equalsFoldCase(s));
|
||||
}
|
||||
|
||||
// helper to test the integrity of folding mapping
|
||||
private static int[] longToFolding(long value) {
|
||||
int len = (int) (value >>> 48);
|
||||
if (len == 0) {
|
||||
return new int[]{(int) (value & 0xFFFFF)};
|
||||
} else {
|
||||
var folding = new int[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
folding[i] = (int) (value & 0xFFFF);
|
||||
value >>= 16;
|
||||
}
|
||||
return folding;
|
||||
}
|
||||
}
|
||||
|
||||
private static String foldCase(String s) {
|
||||
int first;
|
||||
int len = s.length();
|
||||
int cpCnt = 1;
|
||||
for (first = 0; first < len; first += cpCnt) {
|
||||
int cp = s.codePointAt(first);
|
||||
if (CaseFolding.isDefined(cp)) {
|
||||
break;
|
||||
}
|
||||
cpCnt = Character.charCount(cp);
|
||||
}
|
||||
if (first == len) {
|
||||
return s;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(len);
|
||||
sb.append(s, 0, first);
|
||||
for (int i = first; i < len; i += cpCnt) {
|
||||
int cp = s.codePointAt(i);
|
||||
int[] folded = longToFolding(CaseFolding.fold(cp));
|
||||
for (int f : folded) {
|
||||
sb.appendCodePoint(f);
|
||||
}
|
||||
cpCnt = Character.charCount(cp);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
229
test/jdk/java/lang/String/UnicodeCasingTest.java
Normal file
229
test/jdk/java/lang/String/UnicodeCasingTest.java
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2024, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4397357 6565620 6959267 7070436 7198195 8032446 8072600 8221431
|
||||
* @summary Confirm normal case mappings are handled correctly.
|
||||
* @library /lib/testlibrary/java/lang
|
||||
* @run main/timeout=200 UnicodeCasingTest
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class UnicodeCasingTest {
|
||||
|
||||
private static boolean err = false;
|
||||
|
||||
// Locales which are used for testing
|
||||
private static List<Locale> locales = new ArrayList<>();
|
||||
static {
|
||||
locales.add(Locale.of("az"));
|
||||
locales.addAll(java.util.Arrays.asList(Locale.getAvailableLocales()));
|
||||
}
|
||||
|
||||
// Default locale
|
||||
private static String defaultLang;
|
||||
|
||||
// List for Unicode characters whose mappings are included in
|
||||
// SpecialCasing.txt and mappings in UnicodeData.txt isn't applicable.
|
||||
private static Map<String, String> excludeList = new HashMap<>();
|
||||
|
||||
public static void main(String[] args) {
|
||||
UnicodeCasingTest specialCasingTest = new UnicodeCasingTest();
|
||||
specialCasingTest.test();
|
||||
}
|
||||
|
||||
private void test() {
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
// First, we create exclude lists of characters whose mappings exist
|
||||
// in SpecialCasing.txt and mapping rules in UnicodeData.txt aren't
|
||||
// applicable.
|
||||
in = Files.newBufferedReader(UCDFiles.SPECIAL_CASING.toRealPath());
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
if (line.length() == 0 || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
updateExcludeList(line);
|
||||
}
|
||||
in.close();
|
||||
in = null;
|
||||
int locale_num = locales.size();
|
||||
for (int l = 0; l < locale_num; l++) {
|
||||
Locale locale = locales.get(l);
|
||||
Locale.setDefault(locale);
|
||||
defaultLang = locale.getLanguage();
|
||||
System.err.println("Testing on " + locale + " locale....");
|
||||
in = Files.newBufferedReader(UCDFiles.UNICODE_DATA.toRealPath());
|
||||
while ((line = in.readLine()) != null) {
|
||||
if (line.length() == 0 || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
test(line);
|
||||
}
|
||||
in.close();
|
||||
in = null;
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
err = true;
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
Locale.setDefault(defaultLocale);
|
||||
|
||||
if (err) {
|
||||
throw new RuntimeException("UnicodeCasingTest failed.");
|
||||
} else {
|
||||
System.out.println("*** UnicodeCasingTest passed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateExcludeList(String line) {
|
||||
int index = line.indexOf('#');
|
||||
if (index != -1) {
|
||||
line = line.substring(0, index);
|
||||
}
|
||||
|
||||
String lang = null;
|
||||
String condition = null;
|
||||
String[] fields = line.split("; ");
|
||||
|
||||
// If the given character is mapped to multiple characters under the
|
||||
// normal condition, add it to the exclude list.
|
||||
if (fields.length == 4) {
|
||||
excludeList.put(fields[0], "all");
|
||||
} else if (fields.length == 5) {
|
||||
if (fields[4].length() == 2) { /// locale
|
||||
if (excludeList.get(fields[0]) == null) {
|
||||
excludeList.put(fields[0], fields[4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void test(String line) {
|
||||
String[] fields = line.split(";", 15);
|
||||
String orig = convert(fields[0]);
|
||||
|
||||
String lang = excludeList.get(fields[0]);
|
||||
if (!"all".equals(lang) && !defaultLang.equals(lang)) {
|
||||
if (fields[12].length() == 0) {
|
||||
testUpperCase(orig, convert(fields[0]));
|
||||
} else {
|
||||
testUpperCase(orig, convert(fields[12]));
|
||||
}
|
||||
|
||||
if (fields[13].length() == 0) {
|
||||
testLowerCase(orig, convert(fields[0]));
|
||||
} else {
|
||||
testLowerCase(orig, convert(fields[13]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void testUpperCase(String orig, String expected) {
|
||||
String got = orig.toUpperCase();
|
||||
|
||||
// Ugly workaround for special mappings for az and tr locales....
|
||||
if (orig.equals("\u0069") &&
|
||||
(defaultLang.equals("az") || defaultLang.equals("tr"))) {
|
||||
expected = "\u0130";
|
||||
}
|
||||
|
||||
if (!expected.equals(got)) {
|
||||
err = true;
|
||||
System.err.println("toUpperCase(" +
|
||||
") failed.\n\tOriginal: " + toString(orig) +
|
||||
"\n\tGot: " + toString(got) +
|
||||
"\n\tExpected: " + toString(expected));
|
||||
}
|
||||
}
|
||||
|
||||
private void testLowerCase(String orig, String expected) {
|
||||
String got = orig.toLowerCase();
|
||||
// Ugly workaround for special mappings for az and tr locales....
|
||||
if (orig.equals("\u0049") &&
|
||||
(defaultLang.equals("az") || defaultLang.equals("tr"))) {
|
||||
expected = "\u0131";
|
||||
}
|
||||
|
||||
if (!expected.equals(got)) {
|
||||
err = true;
|
||||
System.err.println("toLowerCase(" +
|
||||
") failed.\n\tOriginal: " + toString(orig) +
|
||||
"\n\tGot: " + toString(got) +
|
||||
"\n\tExpected: " + toString(expected));
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
private String convert(String str) {
|
||||
sb.setLength(0);
|
||||
|
||||
String[] tokens = str.split(" ");
|
||||
for (String token : tokens) {
|
||||
int j = Integer.parseInt(token, 16);
|
||||
if (j < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
|
||||
sb.append((char)j);
|
||||
} else {
|
||||
sb.append(Character.toChars(j));
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String toString(String str) {
|
||||
sb.setLength(0);
|
||||
|
||||
int len = str.length();
|
||||
for (int i = 0; i < len; i++) {
|
||||
sb.append("0x").append(Integer.toHexString(str.charAt(i)).toUpperCase()).append(" ");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary StringConcatFactory MH_INLINE_SIZED_EXACT strategy does not work with -XX:-CompactStrings
|
||||
* @bug 8148869
|
||||
*
|
||||
* @compile -XDstringConcat=indy CompactStringsInitialCoder.java
|
||||
* @run main/othervm -Xverify:all -XX:+CompactStrings CompactStringsInitialCoder
|
||||
*
|
||||
* @compile -XDstringConcat=indyWithConstants CompactStringsInitialCoder.java
|
||||
* @run main/othervm -Xverify:all -XX:+CompactStrings CompactStringsInitialCoder
|
||||
*
|
||||
* @compile -XDstringConcat=indy CompactStringsInitialCoder.java
|
||||
* @run main/othervm -Xverify:all -XX:-CompactStrings CompactStringsInitialCoder
|
||||
*
|
||||
* @compile -XDstringConcat=indyWithConstants CompactStringsInitialCoder.java
|
||||
* @run main/othervm -Xverify:all -XX:-CompactStrings CompactStringsInitialCoder
|
||||
*/
|
||||
import java.lang.StringBuilder;
|
||||
|
||||
public class CompactStringsInitialCoder {
|
||||
|
||||
static String strEmpty = "";
|
||||
static String strLatin1 = "\u0042";
|
||||
static String strUTF16 = "\u4242";
|
||||
static char charLatin1 = '\u0042';
|
||||
static char charUTF16 = '\u4242';
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
test("\u0042", "" + '\u0042');
|
||||
test("\u4242", "" + '\u4242');
|
||||
|
||||
test("\u0042", "" + charLatin1);
|
||||
test("\u4242", "" + charUTF16);
|
||||
|
||||
test("\u0042", strEmpty + '\u0042');
|
||||
test("\u4242", strEmpty + '\u4242');
|
||||
|
||||
test("\u0042\u0042", strLatin1 + '\u0042');
|
||||
test("\u0042\u4242", strLatin1 + '\u4242');
|
||||
test("\u4242\u0042", strUTF16 + '\u0042');
|
||||
test("\u4242\u4242", strUTF16 + '\u4242');
|
||||
|
||||
test("\u0042\u0042", "\u0042" + charLatin1);
|
||||
test("\u0042\u4242", "\u0042" + charUTF16);
|
||||
test("\u4242\u0042", "\u4242" + charLatin1);
|
||||
test("\u4242\u4242", "\u4242" + charUTF16);
|
||||
|
||||
test("\u0042\u0042", "" + charLatin1 + charLatin1);
|
||||
test("\u0042\u4242", "" + charLatin1 + charUTF16);
|
||||
test("\u4242\u0042", "" + charUTF16 + charLatin1);
|
||||
test("\u4242\u4242", "" + charUTF16 + charUTF16);
|
||||
}
|
||||
|
||||
public static void test(String expected, String actual) {
|
||||
if (!expected.equals(actual)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Expected = ");
|
||||
sb.append(expected);
|
||||
sb.append(", actual = ");
|
||||
sb.append(actual);
|
||||
throw new IllegalStateException(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
79
test/jdk/java/lang/String/concat/HiddenClassUnloading.java
Normal file
79
test/jdk/java/lang/String/concat/HiddenClassUnloading.java
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Alibaba Group Holding Limited. 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.lang.StringBuilder;
|
||||
|
||||
import java.lang.invoke.*;
|
||||
import java.lang.management.ManagementFactory;
|
||||
|
||||
import jdk.test.whitebox.WhiteBox;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Test whether the hidden class unloading of StringConcatFactory works
|
||||
*
|
||||
* @library /test/lib
|
||||
* @build jdk.test.whitebox.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @requires vm.flagless
|
||||
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
|
||||
* -Xverify:all HiddenClassUnloading
|
||||
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
|
||||
* -Xverify:all -XX:-CompactStrings HiddenClassUnloading
|
||||
*/
|
||||
public class HiddenClassUnloading {
|
||||
public static void main(String[] args) throws Throwable {
|
||||
var lookup = MethodHandles.lookup();
|
||||
var types = new Class<?>[] {
|
||||
int.class, long.class, double.class, float.class, char.class, boolean.class, String.class,
|
||||
};
|
||||
|
||||
long initUnloadedClassCount = ManagementFactory.getClassLoadingMXBean().getUnloadedClassCount();
|
||||
|
||||
for (int i = 0; i < 2000; i++) {
|
||||
int radix = types.length;
|
||||
String str = Integer.toString(i, radix);
|
||||
int length = str.length();
|
||||
var ptypes = new Class[length];
|
||||
for (int j = 0; j < length; j++) {
|
||||
int index = Integer.parseInt(str.substring(j, j + 1), radix);
|
||||
ptypes[j] = types[index];
|
||||
}
|
||||
StringConcatFactory.makeConcatWithConstants(
|
||||
lookup,
|
||||
"concat",
|
||||
MethodType.methodType(String.class, ptypes),
|
||||
"\1".repeat(length), // recipe
|
||||
new Object[0]
|
||||
);
|
||||
}
|
||||
|
||||
// Request GC which performs class unloading
|
||||
WhiteBox.getWhiteBox().fullGC();
|
||||
|
||||
long unloadedClassCount = ManagementFactory.getClassLoadingMXBean().getUnloadedClassCount();
|
||||
if (initUnloadedClassCount == unloadedClassCount) {
|
||||
throw new RuntimeException("unloadedClassCount is zero");
|
||||
}
|
||||
}
|
||||
}
|
||||
78
test/jdk/java/lang/String/concat/HugeConcatTest.java
Normal file
78
test/jdk/java/lang/String/concat/HugeConcatTest.java
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8356152
|
||||
* @summary Check that huge concatenations throw OutOfMemoryError
|
||||
* @requires os.maxMemory > 8G
|
||||
* @run junit/othervm -Xmx8G -XX:+CompactStrings -Dcompact=true HugeConcatTest
|
||||
* @run junit/othervm -Xmx8G -XX:-CompactStrings -Dcompact=false HugeConcatTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
public class HugeConcatTest {
|
||||
|
||||
private static final int HUGE_LENGTH_UTF16 = Integer.MAX_VALUE / 2 - 2;
|
||||
|
||||
private static String hugeLatin1;
|
||||
private static final String hugeUTF16 = "\u20AC".repeat(HUGE_LENGTH_UTF16);
|
||||
|
||||
@BeforeAll
|
||||
public static void initHugeLatin1() {
|
||||
String compact = System.getProperty("compact", "true");
|
||||
int hugeLatin1Length = Boolean.parseBoolean(compact)
|
||||
? Integer.MAX_VALUE - 2
|
||||
: HUGE_LENGTH_UTF16;
|
||||
hugeLatin1 = "a".repeat(hugeLatin1Length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcat_Latin1_Latin1() {
|
||||
assertThrows(OutOfMemoryError.class, () -> { var s = hugeLatin1 + hugeLatin1; });
|
||||
assertThrows(OutOfMemoryError.class, () -> hugeLatin1.concat(hugeLatin1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcat_Latin1_UTF16() {
|
||||
assertThrows(OutOfMemoryError.class, () -> { var s = hugeLatin1 + hugeUTF16; });
|
||||
assertThrows(OutOfMemoryError.class, () -> hugeLatin1.concat(hugeUTF16));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcat_UTF16_Latin1() {
|
||||
assertThrows(OutOfMemoryError.class, () -> { var s = hugeUTF16 + hugeLatin1; });
|
||||
assertThrows(OutOfMemoryError.class, () -> hugeUTF16.concat(hugeLatin1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConcat_UTF16_UTF16() {
|
||||
assertThrows(OutOfMemoryError.class, () -> { var s = hugeUTF16 + hugeUTF16; });
|
||||
assertThrows(OutOfMemoryError.class, () -> hugeUTF16.concat(hugeUTF16));
|
||||
}
|
||||
|
||||
}
|
||||
162
test/jdk/java/lang/String/concat/ImplicitStringConcat.java
Normal file
162
test/jdk/java/lang/String/concat/ImplicitStringConcat.java
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary test implicit String concatenations
|
||||
*
|
||||
* @compile ImplicitStringConcat.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcat
|
||||
*
|
||||
* @compile -XDstringConcat=inline ImplicitStringConcat.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcat
|
||||
*
|
||||
* @compile -XDstringConcat=indy ImplicitStringConcat.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcat
|
||||
*
|
||||
* @compile -XDstringConcat=indyWithConstants ImplicitStringConcat.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcat
|
||||
*/
|
||||
import java.lang.StringBuilder;
|
||||
|
||||
public class ImplicitStringConcat {
|
||||
|
||||
static boolean b = true;
|
||||
static byte by = 42;
|
||||
static short sh = 42;
|
||||
static char ch = 'a';
|
||||
static int i = 42;
|
||||
static float fl = 42.0f;
|
||||
static long l = 42;
|
||||
static double d = 42.0d;
|
||||
static String s = "foo";
|
||||
static String sNull = null;
|
||||
static Object o = "bar";
|
||||
static Object oNull = null;
|
||||
static CharSequence cs = "bar";
|
||||
static char[] chars = new char[] {'a'};
|
||||
|
||||
static MyClass myCl = new MyClass();
|
||||
static MyClassNull myClNull = new MyClassNull();
|
||||
static Object myCl2 = new MyClass();
|
||||
static Object[] myArr = new Object[] { myCl };
|
||||
static final Object[] s_myArr = new Object[] { myCl };
|
||||
|
||||
static StringBuffer sb = new StringBuffer("a");
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
test("footrue", s + b);
|
||||
test("foo42", s + by);
|
||||
test("foo42", s + sh);
|
||||
test("fooa", s + ch);
|
||||
test("foo42", s + i);
|
||||
test("foo42", s + l);
|
||||
test("foo42.0", s + fl);
|
||||
test("foo42.0", s + d);
|
||||
test("foofoo", s + s);
|
||||
test("foonull", s + sNull);
|
||||
test("foobar", s + o);
|
||||
test("foonull", s + oNull);
|
||||
test("foobar", s + cs);
|
||||
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("foo");
|
||||
sb.append(myArr.toString());
|
||||
test(sb.toString(), s + myArr);
|
||||
}
|
||||
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("foo");
|
||||
sb.append(s_myArr.toString());
|
||||
test(sb.toString(), s + s_myArr);
|
||||
}
|
||||
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("foo[C@");
|
||||
sb.append(Integer.toHexString(System.identityHashCode(chars)));
|
||||
test(sb.toString(), s + chars);
|
||||
}
|
||||
|
||||
test("fooa", s + ImplicitStringConcat.sb);
|
||||
test("foonull", s + null);
|
||||
test("fooMyClass", s + myCl);
|
||||
test("foonull", s + myClNull);
|
||||
test("fooMyClass", s + myCl2);
|
||||
|
||||
s = "foo"; s += b; test("footrue", s);
|
||||
s = "foo"; s += by; test("foo42", s);
|
||||
s = "foo"; s += sh; test("foo42", s);
|
||||
s = "foo"; s += ch; test("fooa", s);
|
||||
s = "foo"; s += i; test("foo42", s);
|
||||
s = "foo"; s += l; test("foo42", s);
|
||||
s = "foo"; s += fl; test("foo42.0", s);
|
||||
s = "foo"; s += d; test("foo42.0", s);
|
||||
s = "foo"; s += s; test("foofoo", s);
|
||||
s = "foo"; s += sNull; test("foonull", s);
|
||||
s = "foo"; s += o; test("foobar", s);
|
||||
s = "foo"; s += oNull; test("foonull", s);
|
||||
s = "foo"; s += cs; test("foobar", s);
|
||||
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("foo[C@");
|
||||
sb.append(Integer.toHexString(System.identityHashCode(chars)));
|
||||
s = "foo";
|
||||
s += chars;
|
||||
test(sb.toString(), s);
|
||||
}
|
||||
|
||||
s = "foo"; s += ImplicitStringConcat.sb; test("fooa", s);
|
||||
s = "foo"; s += null; test("foonull", s);
|
||||
s = "foo"; s += myCl; test("fooMyClass", s);
|
||||
s = "foo"; s += myCl2; test("fooMyClass", s);
|
||||
}
|
||||
|
||||
public static void test(String expected, String actual) {
|
||||
// Fingers crossed: String concat should work.
|
||||
if (!expected.equals(actual)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Expected = ");
|
||||
sb.append(expected);
|
||||
sb.append(", actual = ");
|
||||
sb.append(actual);
|
||||
throw new IllegalStateException(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
static class MyClass {
|
||||
public String toString() {
|
||||
return "MyClass";
|
||||
}
|
||||
}
|
||||
|
||||
static class MyClassNull {
|
||||
public String toString() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Test multiple number of arguments to concatenate.
|
||||
*
|
||||
* @compile ImplicitStringConcatArgCount.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatArgCount
|
||||
*
|
||||
* @compile -XDallowStringFolding=false -XDstringConcat=inline ImplicitStringConcatArgCount.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatArgCount
|
||||
*
|
||||
* @compile -XDallowStringFolding=false -XDstringConcat=indy ImplicitStringConcatArgCount.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatArgCount
|
||||
*
|
||||
* @compile -XDallowStringFolding=false -XDstringConcat=indyWithConstants ImplicitStringConcatArgCount.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatArgCount
|
||||
*/
|
||||
public class ImplicitStringConcatArgCount {
|
||||
static final String s = "f";
|
||||
static final String s1 = "o";
|
||||
static String s2 = "o";
|
||||
static int i = 7;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
test("fo", s + s1);
|
||||
test("foo", s + s1 + s2);
|
||||
test("foo7", s + s1 + s2 + i);
|
||||
test("foo77", s + s1 + s2 + i + i);
|
||||
test("foo777", s + s1 + s2 + i + i + i);
|
||||
test("foo7777", s + s1 + s2 + i + i + i + i);
|
||||
test("foo77777", s + s1 + s2 + i + i + i + i + i);
|
||||
test("foo777777", s + s1 + s2 + i + i + i + i + i + i);
|
||||
test("foo7777777", s + s1 + s2 + i + i + i + i + i + i + i);
|
||||
test("foo77777777", s + s1 + s2 + i + i + i + i + i + i + i + i);
|
||||
}
|
||||
|
||||
public static void test(String expected, String actual) {
|
||||
if (!expected.equals(actual)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Expected = ");
|
||||
sb.append(expected);
|
||||
sb.append(", actual = ");
|
||||
sb.append(actual);
|
||||
throw new IllegalStateException(sb.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary "+=" applied to String operands can provoke side effects
|
||||
* @bug 8204322
|
||||
*
|
||||
* @compile ImplicitStringConcatAssignLHS.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatAssignLHS
|
||||
*
|
||||
* @compile -XDstringConcat=inline ImplicitStringConcatAssignLHS.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatAssignLHS
|
||||
*
|
||||
* @compile -XDstringConcat=indy ImplicitStringConcatAssignLHS.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatAssignLHS
|
||||
*
|
||||
* @compile -XDstringConcat=indyWithConstants ImplicitStringConcatAssignLHS.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatAssignLHS
|
||||
*/
|
||||
import java.lang.StringBuilder;
|
||||
|
||||
public class ImplicitStringConcatAssignLHS {
|
||||
|
||||
static final int ARR_SIZE = 10; // enough padding to capture ill offsets
|
||||
|
||||
static int x;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
{
|
||||
x = 0;
|
||||
Object[] arr = new Object[ARR_SIZE];
|
||||
arr[x++] += "foo";
|
||||
check(1, "plain-plain Object[]");
|
||||
}
|
||||
|
||||
{
|
||||
x = 0;
|
||||
getObjArray()[x++] += "foo";
|
||||
check(2, "method-plain Object[]");
|
||||
}
|
||||
|
||||
{
|
||||
x = 0;
|
||||
getObjArray()[getIndex()] += "foo";
|
||||
check(2, "method-method Object[]");
|
||||
}
|
||||
|
||||
{
|
||||
x = 0;
|
||||
String[] arr = new String[ARR_SIZE];
|
||||
arr[x++] += "foo";
|
||||
check(1, "plain-plain String[]");
|
||||
}
|
||||
|
||||
{
|
||||
x = 0;
|
||||
getStringArray()[x++] += "foo";
|
||||
check(2, "method-plain String[]");
|
||||
}
|
||||
|
||||
{
|
||||
x = 0;
|
||||
getStringArray()[getIndex()] += "foo";
|
||||
check(2, "method-method String[]");
|
||||
}
|
||||
|
||||
{
|
||||
x = 0;
|
||||
CharSequence[] arr = new CharSequence[ARR_SIZE];
|
||||
arr[x++] += "foo";
|
||||
check(1, "plain-plain CharSequence[]");
|
||||
}
|
||||
|
||||
{
|
||||
x = 0;
|
||||
getCharSequenceArray()[x++] += "foo";
|
||||
check(2, "method-plain CharSequence[]");
|
||||
}
|
||||
|
||||
{
|
||||
x = 0;
|
||||
getCharSequenceArray()[getIndex()] += "foo";
|
||||
check(2, "method-method CharSequence[]");
|
||||
}
|
||||
|
||||
{
|
||||
x = 0;
|
||||
new MyClass().s += "foo";
|
||||
check(1, "MyClass::new (String)");
|
||||
}
|
||||
|
||||
{
|
||||
x = 0;
|
||||
getMyClass().s += "foo";
|
||||
check(1, "method MyClass::new (String)");
|
||||
}
|
||||
|
||||
{
|
||||
x = 0;
|
||||
new MyClass().o += "foo";
|
||||
check(1, "MyClass::new (object)");
|
||||
}
|
||||
|
||||
{
|
||||
x = 0;
|
||||
getMyClass().o += "foo";
|
||||
check(1, "method MyClass::new (object)");
|
||||
}
|
||||
}
|
||||
|
||||
public static void check(int expected, String label) {
|
||||
if (x != expected) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(label);
|
||||
sb.append(": ");
|
||||
sb.append("Expected = ");
|
||||
sb.append(expected);
|
||||
sb.append("actual = ");
|
||||
sb.append(x);
|
||||
throw new IllegalStateException(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static int getIndex() {
|
||||
return x++;
|
||||
}
|
||||
|
||||
public static class MyClass {
|
||||
Object o;
|
||||
String s;
|
||||
|
||||
public MyClass() {
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
public static MyClass getMyClass() {
|
||||
return new MyClass();
|
||||
}
|
||||
|
||||
public static Object[] getObjArray() {
|
||||
x++;
|
||||
return new Object[ARR_SIZE];
|
||||
}
|
||||
|
||||
public static String[] getStringArray() {
|
||||
x++;
|
||||
return new String[ARR_SIZE];
|
||||
}
|
||||
|
||||
public static CharSequence[] getCharSequenceArray() {
|
||||
x++;
|
||||
return new String[ARR_SIZE];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2021, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Test the boundary values for concatenation arguments.
|
||||
*
|
||||
* @compile ImplicitStringConcatBoundaries.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatBoundaries
|
||||
*
|
||||
* @compile -XDstringConcat=inline ImplicitStringConcatBoundaries.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatBoundaries
|
||||
*
|
||||
* @compile -XDstringConcat=indy ImplicitStringConcatBoundaries.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatBoundaries
|
||||
*
|
||||
* @compile -XDstringConcat=indyWithConstants ImplicitStringConcatBoundaries.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatBoundaries
|
||||
*/
|
||||
|
||||
public class ImplicitStringConcatBoundaries {
|
||||
|
||||
public static final boolean BOOL_TRUE_1 = true;
|
||||
public static boolean BOOL_TRUE_2 = true;
|
||||
public static final boolean BOOL_FALSE_1 = false;
|
||||
public static boolean BOOL_FALSE_2 = false;
|
||||
|
||||
public static final byte BYTE_MIN_1 = Byte.MIN_VALUE;
|
||||
public static byte BYTE_MIN_2 = Byte.MIN_VALUE;
|
||||
public static final byte BYTE_MAX_1 = Byte.MAX_VALUE;
|
||||
public static byte BYTE_MAX_2 = Byte.MAX_VALUE;
|
||||
|
||||
public static final short SHORT_MIN_1 = Short.MIN_VALUE;
|
||||
public static short SHORT_MIN_2 = Short.MIN_VALUE;
|
||||
public static final short SHORT_MAX_1 = Short.MAX_VALUE;
|
||||
public static short SHORT_MAX_2 = Short.MAX_VALUE;
|
||||
|
||||
public static final char CHAR_MIN_1 = Character.MIN_VALUE;
|
||||
public static char CHAR_MIN_2 = Character.MIN_VALUE;
|
||||
public static final char CHAR_MAX_1 = Character.MAX_VALUE;
|
||||
public static char CHAR_MAX_2 = Character.MAX_VALUE;
|
||||
|
||||
public static final int INT_MIN_1 = Integer.MIN_VALUE;
|
||||
public static int INT_MIN_2 = Integer.MIN_VALUE;
|
||||
public static final int INT_MAX_1 = Integer.MAX_VALUE;
|
||||
public static int INT_MAX_2 = Integer.MAX_VALUE;
|
||||
|
||||
public static final float FLOAT_MIN_EXP_1 = Float.MIN_EXPONENT;
|
||||
public static float FLOAT_MIN_EXP_2 = Float.MIN_EXPONENT;
|
||||
public static final float FLOAT_MIN_NORM_1 = Float.MIN_NORMAL;
|
||||
public static float FLOAT_MIN_NORM_2 = Float.MIN_NORMAL;
|
||||
public static final float FLOAT_MIN_1 = Float.MIN_VALUE;
|
||||
public static float FLOAT_MIN_2 = Float.MIN_VALUE;
|
||||
public static final float FLOAT_MAX_1 = Float.MAX_VALUE;
|
||||
public static float FLOAT_MAX_2 = Float.MAX_VALUE;
|
||||
|
||||
public static final long LONG_MIN_1 = Long.MIN_VALUE;
|
||||
public static long LONG_MIN_2 = Long.MIN_VALUE;
|
||||
public static final long LONG_MAX_1 = Long.MAX_VALUE;
|
||||
public static long LONG_MAX_2 = Long.MAX_VALUE;
|
||||
|
||||
public static final double DOUBLE_MIN_EXP_1 = Double.MIN_EXPONENT;
|
||||
public static double DOUBLE_MIN_EXP_2 = Double.MIN_EXPONENT;
|
||||
public static final double DOUBLE_MIN_NORM_1 = Double.MIN_NORMAL;
|
||||
public static double DOUBLE_MIN_NORM_2 = Double.MIN_NORMAL;
|
||||
public static final double DOUBLE_MIN_1 = Double.MIN_VALUE;
|
||||
public static double DOUBLE_MIN_2 = Double.MIN_VALUE;
|
||||
public static final double DOUBLE_MAX_1 = Double.MAX_VALUE;
|
||||
public static double DOUBLE_MAX_2 = Double.MAX_VALUE;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
test("foofalse", "foo" + BOOL_FALSE_1);
|
||||
test("foofalse", "foo" + BOOL_FALSE_2);
|
||||
test("footrue", "foo" + BOOL_TRUE_1);
|
||||
test("footrue", "foo" + BOOL_TRUE_2);
|
||||
|
||||
test("foo127", "foo" + BYTE_MAX_1);
|
||||
test("foo127", "foo" + BYTE_MAX_2);
|
||||
test("foo-128", "foo" + BYTE_MIN_1);
|
||||
test("foo-128", "foo" + BYTE_MIN_2);
|
||||
|
||||
test("foo32767", "foo" + SHORT_MAX_1);
|
||||
test("foo32767", "foo" + SHORT_MAX_2);
|
||||
test("foo-32768", "foo" + SHORT_MIN_1);
|
||||
test("foo-32768", "foo" + SHORT_MIN_2);
|
||||
|
||||
test("foo\u0000", "foo" + CHAR_MIN_1);
|
||||
test("foo\u0000", "foo" + CHAR_MIN_2);
|
||||
test("foo\uFFFF", "foo" + CHAR_MAX_1);
|
||||
test("foo\uFFFF", "foo" + CHAR_MAX_2);
|
||||
|
||||
test("foo2147483647", "foo" + INT_MAX_1);
|
||||
test("foo2147483647", "foo" + INT_MAX_2);
|
||||
test("foo-2147483648", "foo" + INT_MIN_1);
|
||||
test("foo-2147483648", "foo" + INT_MIN_2);
|
||||
|
||||
test("foo1.1754944E-38", "foo" + FLOAT_MIN_NORM_1);
|
||||
test("foo1.1754944E-38", "foo" + FLOAT_MIN_NORM_2);
|
||||
test("foo-126.0", "foo" + FLOAT_MIN_EXP_1);
|
||||
test("foo-126.0", "foo" + FLOAT_MIN_EXP_2);
|
||||
test("foo1.4E-45", "foo" + FLOAT_MIN_1);
|
||||
test("foo1.4E-45", "foo" + FLOAT_MIN_2);
|
||||
test("foo3.4028235E38", "foo" + FLOAT_MAX_1);
|
||||
test("foo3.4028235E38", "foo" + FLOAT_MAX_2);
|
||||
|
||||
test("foo-9223372036854775808", "foo" + LONG_MIN_1);
|
||||
test("foo-9223372036854775808", "foo" + LONG_MIN_2);
|
||||
test("foo9223372036854775807", "foo" + LONG_MAX_1);
|
||||
test("foo9223372036854775807", "foo" + LONG_MAX_2);
|
||||
|
||||
test("foo2.2250738585072014E-308", "foo" + DOUBLE_MIN_NORM_1);
|
||||
test("foo2.2250738585072014E-308", "foo" + DOUBLE_MIN_NORM_2);
|
||||
test("foo-1022.0", "foo" + DOUBLE_MIN_EXP_1);
|
||||
test("foo-1022.0", "foo" + DOUBLE_MIN_EXP_2);
|
||||
test("foo4.9E-324", "foo" + DOUBLE_MIN_1);
|
||||
test("foo4.9E-324", "foo" + DOUBLE_MIN_2);
|
||||
test("foo1.7976931348623157E308", "foo" + DOUBLE_MAX_1);
|
||||
test("foo1.7976931348623157E308", "foo" + DOUBLE_MAX_2);
|
||||
}
|
||||
|
||||
public static void test(String expected, String actual) {
|
||||
if (!expected.equals(actual)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Expected = ");
|
||||
sb.append(expected);
|
||||
sb.append(", actual = ");
|
||||
sb.append(actual);
|
||||
throw new IllegalStateException(sb.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
141
test/jdk/java/lang/String/concat/ImplicitStringConcatMany.java
Normal file
141
test/jdk/java/lang/String/concat/ImplicitStringConcatMany.java
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Test implicit String concatenations with lots of arguments.
|
||||
*
|
||||
* @compile ImplicitStringConcatMany.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatMany
|
||||
*
|
||||
* @compile -XDstringConcat=inline ImplicitStringConcatMany.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatMany
|
||||
*
|
||||
* @compile -XDstringConcat=indy ImplicitStringConcatMany.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatMany
|
||||
*
|
||||
* @compile -XDstringConcat=indyWithConstants ImplicitStringConcatMany.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatMany
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class ImplicitStringConcatMany {
|
||||
|
||||
static String s000, s001, s002, s003, s004, s005, s006, s007, s008, s009;
|
||||
static String s010, s011, s012, s013, s014, s015, s016, s017, s018, s019;
|
||||
static String s020, s021, s022, s023, s024, s025, s026, s027, s028, s029;
|
||||
static String s030, s031, s032, s033, s034, s035, s036, s037, s038, s039;
|
||||
static String s040, s041, s042, s043, s044, s045, s046, s047, s048, s049;
|
||||
static String s050, s051, s052, s053, s054, s055, s056, s057, s058, s059;
|
||||
static String s060, s061, s062, s063, s064, s065, s066, s067, s068, s069;
|
||||
static String s070, s071, s072, s073, s074, s075, s076, s077, s078, s079;
|
||||
static String s080, s081, s082, s083, s084, s085, s086, s087, s088, s089;
|
||||
static String s090, s091, s092, s093, s094, s095, s096, s097, s098, s099;
|
||||
|
||||
static String s100, s101, s102, s103, s104, s105, s106, s107, s108, s109;
|
||||
static String s110, s111, s112, s113, s114, s115, s116, s117, s118, s119;
|
||||
static String s120, s121, s122, s123, s124, s125, s126, s127, s128, s129;
|
||||
static String s130, s131, s132, s133, s134, s135, s136, s137, s138, s139;
|
||||
static String s140, s141, s142, s143, s144, s145, s146, s147, s148, s149;
|
||||
static String s150, s151, s152, s153, s154, s155, s156, s157, s158, s159;
|
||||
static String s160, s161, s162, s163, s164, s165, s166, s167, s168, s169;
|
||||
static String s170, s171, s172, s173, s174, s175, s176, s177, s178, s179;
|
||||
static String s180, s181, s182, s183, s184, s185, s186, s187, s188, s189;
|
||||
static String s190, s191, s192, s193, s194, s195, s196, s197, s198, s199;
|
||||
|
||||
static String s200, s201, s202, s203, s204, s205, s206, s207, s208, s209;
|
||||
static String s210, s211, s212, s213, s214, s215, s216, s217, s218, s219;
|
||||
static String s220, s221, s222, s223, s224, s225, s226, s227, s228, s229;
|
||||
static String s230, s231, s232, s233, s234, s235, s236, s237, s238, s239;
|
||||
static String s240, s241, s242, s243, s244, s245, s246, s247, s248, s249;
|
||||
static String s250, s251, s252, s253, s254, s255, s256, s257, s258, s259;
|
||||
static String s260, s261, s262, s263, s264, s265, s266, s267, s268, s269;
|
||||
static String s270, s271, s272, s273, s274, s275, s276, s277, s278, s279;
|
||||
static String s280, s281, s282, s283, s284, s285, s286, s287, s288, s289;
|
||||
static String s290, s291, s292, s293, s294, s295, s296, s297, s298, s299;
|
||||
|
||||
static {
|
||||
for (Field f : ImplicitStringConcatMany.class.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(f.getModifiers())) {
|
||||
String name = f.getName();
|
||||
try {
|
||||
f.set(null, name);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String res =
|
||||
s000 + s001 + s002 + s003 + s004 + s005 + s006 + s007 + s008 + s009 +
|
||||
s010 + s011 + s012 + s013 + s014 + s015 + s016 + s017 + s018 + s019 +
|
||||
s020 + s021 + s022 + s023 + s024 + s025 + s026 + s027 + s028 + s029 +
|
||||
s030 + s031 + s032 + s033 + s034 + s035 + s036 + s037 + s038 + s039 +
|
||||
s040 + s041 + s042 + s043 + s044 + s045 + s046 + s047 + s048 + s049 +
|
||||
s050 + s051 + s052 + s053 + s054 + s055 + s056 + s057 + s058 + s059 +
|
||||
s060 + s061 + s062 + s063 + s064 + s065 + s066 + s067 + s068 + s069 +
|
||||
s070 + s071 + s072 + s073 + s074 + s075 + s076 + s077 + s078 + s079 +
|
||||
s080 + s081 + s082 + s083 + s084 + s085 + s086 + s087 + s088 + s089 +
|
||||
s090 + s091 + s092 + s093 + s094 + s095 + s096 + s097 + s098 + s099 +
|
||||
|
||||
s100 + s101 + s102 + s103 + s104 + s105 + s106 + s107 + s108 + s109 +
|
||||
s110 + s111 + s112 + s113 + s114 + s115 + s116 + s117 + s118 + s119 +
|
||||
s120 + s121 + s122 + s123 + s124 + s125 + s126 + s127 + s128 + s129 +
|
||||
s130 + s131 + s132 + s133 + s134 + s135 + s136 + s137 + s138 + s139 +
|
||||
s140 + s141 + s142 + s143 + s144 + s145 + s146 + s147 + s148 + s149 +
|
||||
s150 + s151 + s152 + s153 + s154 + s155 + s156 + s157 + s158 + s159 +
|
||||
s160 + s161 + s162 + s163 + s164 + s165 + s166 + s167 + s168 + s169 +
|
||||
s170 + s171 + s172 + s173 + s174 + s175 + s176 + s177 + s178 + s179 +
|
||||
s180 + s181 + s182 + s183 + s184 + s185 + s186 + s187 + s188 + s189 +
|
||||
s190 + s191 + s192 + s193 + s194 + s195 + s196 + s197 + s198 + s199 +
|
||||
|
||||
s200 + s201 + s202 + s203 + s204 + s205 + s206 + s207 + s208 + s209 +
|
||||
s210 + s211 + s212 + s213 + s214 + s215 + s216 + s217 + s218 + s219 +
|
||||
s220 + s221 + s222 + s223 + s224 + s225 + s226 + s227 + s228 + s229 +
|
||||
s230 + s231 + s232 + s233 + s234 + s235 + s236 + s237 + s238 + s239 +
|
||||
s240 + s241 + s242 + s243 + s244 + s245 + s246 + s247 + s248 + s249 +
|
||||
s250 + s251 + s252 + s253 + s254 + s255 + s256 + s257 + s258 + s259 +
|
||||
s260 + s261 + s262 + s263 + s264 + s265 + s266 + s267 + s268 + s269 +
|
||||
s270 + s271 + s272 + s273 + s274 + s275 + s276 + s277 + s278 + s279 +
|
||||
s280 + s281 + s282 + s283 + s284 + s285 + s286 + s287 + s288 + s289 +
|
||||
s290 + s291 + s292 + s293 + s294 + s295 + s296 + s297 + s298 + s299;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int c = 0; c < 300; c++) {
|
||||
sb.append(String.format("s%03d", c));
|
||||
}
|
||||
test(sb.toString(), res);
|
||||
}
|
||||
|
||||
public static void test(String expected, String actual) {
|
||||
// Fingers crossed: String concat should work.
|
||||
if (!expected.equals(actual)) {
|
||||
throw new IllegalStateException("Expected = " + expected + ", actual = " + actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Test implicit String concatenations with lots of arguments (two-slot version)
|
||||
*
|
||||
* @compile ImplicitStringConcatManyLongs.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatManyLongs
|
||||
*
|
||||
* @compile -XDstringConcat=inline ImplicitStringConcatManyLongs.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatManyLongs
|
||||
*
|
||||
* @compile -XDstringConcat=indy ImplicitStringConcatManyLongs.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatManyLongs
|
||||
*
|
||||
* @compile -XDstringConcat=indyWithConstants ImplicitStringConcatManyLongs.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatManyLongs
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class ImplicitStringConcatManyLongs {
|
||||
|
||||
static long s000, s001, s002, s003, s004, s005, s006, s007, s008, s009;
|
||||
static long s010, s011, s012, s013, s014, s015, s016, s017, s018, s019;
|
||||
static long s020, s021, s022, s023, s024, s025, s026, s027, s028, s029;
|
||||
static long s030, s031, s032, s033, s034, s035, s036, s037, s038, s039;
|
||||
static long s040, s041, s042, s043, s044, s045, s046, s047, s048, s049;
|
||||
static long s050, s051, s052, s053, s054, s055, s056, s057, s058, s059;
|
||||
static long s060, s061, s062, s063, s064, s065, s066, s067, s068, s069;
|
||||
static long s070, s071, s072, s073, s074, s075, s076, s077, s078, s079;
|
||||
static long s080, s081, s082, s083, s084, s085, s086, s087, s088, s089;
|
||||
static long s090, s091, s092, s093, s094, s095, s096, s097, s098, s099;
|
||||
|
||||
static long s100, s101, s102, s103, s104, s105, s106, s107, s108, s109;
|
||||
static long s110, s111, s112, s113, s114, s115, s116, s117, s118, s119;
|
||||
static long s120, s121, s122, s123, s124, s125, s126, s127, s128, s129;
|
||||
static long s130, s131, s132, s133, s134, s135, s136, s137, s138, s139;
|
||||
static long s140, s141, s142, s143, s144, s145, s146, s147, s148, s149;
|
||||
static long s150, s151, s152, s153, s154, s155, s156, s157, s158, s159;
|
||||
static long s160, s161, s162, s163, s164, s165, s166, s167, s168, s169;
|
||||
static long s170, s171, s172, s173, s174, s175, s176, s177, s178, s179;
|
||||
static long s180, s181, s182, s183, s184, s185, s186, s187, s188, s189;
|
||||
static long s190, s191, s192, s193, s194, s195, s196, s197, s198, s199;
|
||||
|
||||
static long s200, s201, s202, s203, s204, s205, s206, s207, s208, s209;
|
||||
static long s210, s211, s212, s213, s214, s215, s216, s217, s218, s219;
|
||||
static long s220, s221, s222, s223, s224, s225, s226, s227, s228, s229;
|
||||
static long s230, s231, s232, s233, s234, s235, s236, s237, s238, s239;
|
||||
static long s240, s241, s242, s243, s244, s245, s246, s247, s248, s249;
|
||||
static long s250, s251, s252, s253, s254, s255, s256, s257, s258, s259;
|
||||
static long s260, s261, s262, s263, s264, s265, s266, s267, s268, s269;
|
||||
static long s270, s271, s272, s273, s274, s275, s276, s277, s278, s279;
|
||||
static long s280, s281, s282, s283, s284, s285, s286, s287, s288, s289;
|
||||
static long s290, s291, s292, s293, s294, s295, s296, s297, s298, s299;
|
||||
|
||||
static {
|
||||
for (Field f : ImplicitStringConcatManyLongs.class.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(f.getModifiers())) {
|
||||
String name = f.getName();
|
||||
try {
|
||||
f.set(null, Long.valueOf(name.substring(1)));
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String res = "" +
|
||||
s000 + s001 + s002 + s003 + s004 + s005 + s006 + s007 + s008 + s009 +
|
||||
s010 + s011 + s012 + s013 + s014 + s015 + s016 + s017 + s018 + s019 +
|
||||
s020 + s021 + s022 + s023 + s024 + s025 + s026 + s027 + s028 + s029 +
|
||||
s030 + s031 + s032 + s033 + s034 + s035 + s036 + s037 + s038 + s039 +
|
||||
s040 + s041 + s042 + s043 + s044 + s045 + s046 + s047 + s048 + s049 +
|
||||
s050 + s051 + s052 + s053 + s054 + s055 + s056 + s057 + s058 + s059 +
|
||||
s060 + s061 + s062 + s063 + s064 + s065 + s066 + s067 + s068 + s069 +
|
||||
s070 + s071 + s072 + s073 + s074 + s075 + s076 + s077 + s078 + s079 +
|
||||
s080 + s081 + s082 + s083 + s084 + s085 + s086 + s087 + s088 + s089 +
|
||||
s090 + s091 + s092 + s093 + s094 + s095 + s096 + s097 + s098 + s099 +
|
||||
|
||||
s100 + s101 + s102 + s103 + s104 + s105 + s106 + s107 + s108 + s109 +
|
||||
s110 + s111 + s112 + s113 + s114 + s115 + s116 + s117 + s118 + s119 +
|
||||
s120 + s121 + s122 + s123 + s124 + s125 + s126 + s127 + s128 + s129 +
|
||||
s130 + s131 + s132 + s133 + s134 + s135 + s136 + s137 + s138 + s139 +
|
||||
s140 + s141 + s142 + s143 + s144 + s145 + s146 + s147 + s148 + s149 +
|
||||
s150 + s151 + s152 + s153 + s154 + s155 + s156 + s157 + s158 + s159 +
|
||||
s160 + s161 + s162 + s163 + s164 + s165 + s166 + s167 + s168 + s169 +
|
||||
s170 + s171 + s172 + s173 + s174 + s175 + s176 + s177 + s178 + s179 +
|
||||
s180 + s181 + s182 + s183 + s184 + s185 + s186 + s187 + s188 + s189 +
|
||||
s190 + s191 + s192 + s193 + s194 + s195 + s196 + s197 + s198 + s199 +
|
||||
|
||||
s200 + s201 + s202 + s203 + s204 + s205 + s206 + s207 + s208 + s209 +
|
||||
s210 + s211 + s212 + s213 + s214 + s215 + s216 + s217 + s218 + s219 +
|
||||
s220 + s221 + s222 + s223 + s224 + s225 + s226 + s227 + s228 + s229 +
|
||||
s230 + s231 + s232 + s233 + s234 + s235 + s236 + s237 + s238 + s239 +
|
||||
s240 + s241 + s242 + s243 + s244 + s245 + s246 + s247 + s248 + s249 +
|
||||
s250 + s251 + s252 + s253 + s254 + s255 + s256 + s257 + s258 + s259 +
|
||||
s260 + s261 + s262 + s263 + s264 + s265 + s266 + s267 + s268 + s269 +
|
||||
s270 + s271 + s272 + s273 + s274 + s275 + s276 + s277 + s278 + s279 +
|
||||
s280 + s281 + s282 + s283 + s284 + s285 + s286 + s287 + s288 + s289 +
|
||||
s290 + s291 + s292 + s293 + s294 + s295 + s296 + s297 + s298 + s299;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int c = 0; c < 300; c++) {
|
||||
sb.append(c);
|
||||
}
|
||||
test(sb.toString(), res);
|
||||
}
|
||||
|
||||
public static void test(String expected, String actual) {
|
||||
// Fingers crossed: String concat should work.
|
||||
if (!expected.equals(actual)) {
|
||||
throw new IllegalStateException("Expected = " + expected + ", actual = " + actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
136
test/jdk/java/lang/String/concat/ImplicitStringConcatOOME.java
Normal file
136
test/jdk/java/lang/String/concat/ImplicitStringConcatOOME.java
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2022, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test 8297530
|
||||
* @summary This sanity tests that OOME is correctly thrown when
|
||||
* the length of the array to be allocated for a concatenation.
|
||||
* Before the fix for 8297530 an IllegalArgumentException could
|
||||
* erroneously be thrown when the length of the string is between
|
||||
* Integer.MAX_VALUE / 2 and Integer.MAX_VALUE and the String coder
|
||||
* is UTF16.
|
||||
*
|
||||
* @requires sun.arch.data.model == "64"
|
||||
* @run main/othervm -Xverify:all -Xmx4g ImplicitStringConcatOOME
|
||||
* @run main/othervm -Xverify:all -Xmx4g -XX:-CompactStrings ImplicitStringConcatOOME
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class ImplicitStringConcatOOME {
|
||||
|
||||
static String s000, s001, s002, s003, s004, s005, s006, s007, s008, s009;
|
||||
static String s010, s011, s012, s013, s014, s015, s016, s017, s018, s019;
|
||||
static String s020, s021, s022, s023, s024, s025, s026, s027, s028, s029;
|
||||
static String s030, s031, s032, s033, s034, s035, s036, s037, s038, s039;
|
||||
static String s040, s041, s042, s043, s044, s045, s046, s047, s048, s049;
|
||||
static String s050, s051, s052, s053, s054, s055, s056, s057, s058, s059;
|
||||
static String s060, s061, s062, s063, s064, s065, s066, s067, s068, s069;
|
||||
static String s070, s071, s072, s073, s074, s075, s076, s077, s078, s079;
|
||||
static String s080, s081, s082, s083, s084, s085, s086, s087, s088, s089;
|
||||
static String s090, s091, s092, s093, s094, s095, s096, s097, s098, s099;
|
||||
|
||||
static String s100, s101, s102, s103, s104, s105, s106, s107, s108, s109;
|
||||
static String s110, s111, s112, s113, s114, s115, s116, s117, s118, s119;
|
||||
static String s120, s121, s122, s123, s124, s125, s126, s127, s128, s129;
|
||||
static String s130, s131, s132, s133, s134, s135, s136, s137, s138, s139;
|
||||
static String s140, s141, s142, s143, s144, s145, s146, s147, s148, s149;
|
||||
static String s150, s151, s152, s153, s154, s155, s156, s157, s158, s159;
|
||||
static String s160, s161, s162, s163, s164, s165, s166, s167, s168, s169;
|
||||
static String s170, s171, s172, s173, s174, s175, s176, s177, s178, s179;
|
||||
static String s180, s181, s182, s183, s184, s185, s186, s187, s188, s189;
|
||||
static String s190, s191, s192, s193, s194, s195, s196, s197, s198, s199;
|
||||
|
||||
static String s_utf16;
|
||||
static {
|
||||
String s = "10 letters".repeat(1_073_742);
|
||||
for (Field f : ImplicitStringConcatOOME.class.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(f.getModifiers())) {
|
||||
try {
|
||||
f.set(null, s);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
s_utf16 = "\u0257";
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
try {
|
||||
String res =
|
||||
s000 + s001 + s002 + s003 + s004 + s005 + s006 + s007 + s008 + s009 +
|
||||
s010 + s011 + s012 + s013 + s014 + s015 + s016 + s017 + s018 + s019 +
|
||||
s020 + s021 + s022 + s023 + s024 + s025 + s026 + s027 + s028 + s029 +
|
||||
s030 + s031 + s032 + s033 + s034 + s035 + s036 + s037 + s038 + s039 +
|
||||
s040 + s041 + s042 + s043 + s044 + s045 + s046 + s047 + s048 + s049 +
|
||||
s050 + s051 + s052 + s053 + s054 + s055 + s056 + s057 + s058 + s059 +
|
||||
s060 + s061 + s062 + s063 + s064 + s065 + s066 + s067 + s068 + s069 +
|
||||
s070 + s071 + s072 + s073 + s074 + s075 + s076 + s077 + s078 + s079 +
|
||||
s080 + s081 + s082 + s083 + s084 + s085 + s086 + s087 + s088 + s089 +
|
||||
s090 + s091 + s092 + s093 + s094 + s095 + s096 + s097 + s098 + s099 +
|
||||
|
||||
s100 + s101 + s102 + s103 + s104 + s105 + s106 + s107 + s108 + s109 +
|
||||
s110 + s111 + s112 + s113 + s114 + s115 + s116 + s117 + s118 + s119 +
|
||||
s120 + s121 + s122 + s123 + s124 + s125 + s126 + s127 + s128 + s129 +
|
||||
s130 + s131 + s132 + s133 + s134 + s135 + s136 + s137 + s138 + s139 +
|
||||
s140 + s141 + s142 + s143 + s144 + s145 + s146 + s147 + s148 + s149 +
|
||||
s150 + s151 + s152 + s153 + s154 + s155 + s156 + s157 + s158 + s159 +
|
||||
s160 + s161 + s162 + s163 + s164 + s165 + s166 + s167 + s168 + s169 +
|
||||
s170 + s171 + s172 + s173 + s174 + s175 + s176 + s177 + s178 + s179 +
|
||||
s180 + s181 + s182 + s183 + s184 + s185 + s186 + s187 + s188 + s189 +
|
||||
s190 + s191 + s192 + s193 + s194 + s195 + s196 + s197 + s198 + s199;
|
||||
throw new IllegalStateException("Expected OOME");
|
||||
} catch (OutOfMemoryError e) {
|
||||
// Expected
|
||||
}
|
||||
try {
|
||||
// Compact Strings meant capacity for UTF16 strings were cut in
|
||||
// half, regardless of -XX:+CompactStrings setting
|
||||
String res =
|
||||
s000 + s001 + s002 + s003 + s004 + s005 + s006 + s007 + s008 + s009 +
|
||||
s010 + s011 + s012 + s013 + s014 + s015 + s016 + s017 + s018 + s019 +
|
||||
s020 + s021 + s022 + s023 + s024 + s025 + s026 + s027 + s028 + s029 +
|
||||
s030 + s031 + s032 + s033 + s034 + s035 + s036 + s037 + s038 + s039 +
|
||||
s040 + s041 + s042 + s043 + s044 + s045 + s046 + s047 + s048 + s049 +
|
||||
s050 + s051 + s052 + s053 + s054 + s055 + s056 + s057 + s058 + s059 +
|
||||
s060 + s061 + s062 + s063 + s064 + s065 + s066 + s067 + s068 + s069 +
|
||||
s070 + s071 + s072 + s073 + s074 + s075 + s076 + s077 + s078 + s079 +
|
||||
s080 + s081 + s082 + s083 + s084 + s085 + s086 + s087 + s088 + s089 +
|
||||
s090 + s091 + s092 + s093 + s094 + s095 + s096 + s097 + s098 + s099 +
|
||||
s_utf16;
|
||||
throw new IllegalStateException("Expected OOME");
|
||||
} catch (OutOfMemoryError e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
public static void test(String expected, String actual) {
|
||||
// Fingers crossed: String concat should work.
|
||||
if (!expected.equals(actual)) {
|
||||
throw new IllegalStateException("Expected = " + expected + ", actual = " + actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Test implicit string concat calls argument conversions in the right order
|
||||
* @bug 8200118
|
||||
*
|
||||
* @compile ImplicitStringConcatOrder.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatOrder
|
||||
*
|
||||
* @compile -XDstringConcat=inline ImplicitStringConcatOrder.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatOrder
|
||||
*
|
||||
* @compile -XDstringConcat=indy ImplicitStringConcatOrder.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatOrder
|
||||
*
|
||||
* @compile -XDstringConcat=indyWithConstants ImplicitStringConcatOrder.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatOrder
|
||||
*/
|
||||
import java.lang.StringBuilder;
|
||||
|
||||
public class ImplicitStringConcatOrder {
|
||||
|
||||
static MyClass c = new MyClass();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
test("foo123bar", "foo" + c + c + c + "bar");
|
||||
test("bazxyz456abc", "baz" + ("xyz" + c + c) + c + "abc");
|
||||
test("caf7eba89be", "caf" + c + ("eba" + c + c) + "be");
|
||||
}
|
||||
|
||||
public static void test(String expected, String actual) {
|
||||
if (!expected.equals(actual)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Expected = ");
|
||||
sb.append(expected);
|
||||
sb.append(", actual = ");
|
||||
sb.append(actual);
|
||||
throw new IllegalStateException(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
static class MyClass {
|
||||
int x;
|
||||
public String toString() {
|
||||
return String.valueOf(++x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2020, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Test implicit String concatenations, multiple shapes.
|
||||
* @bug 8148483 8245959 8247681
|
||||
*
|
||||
* @compile ImplicitStringConcatShapes.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatShapes
|
||||
*
|
||||
* @compile -XDstringConcat=inline ImplicitStringConcatShapes.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatShapes
|
||||
*
|
||||
* @compile -XDstringConcat=indy ImplicitStringConcatShapes.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatShapes
|
||||
*
|
||||
* @compile -XDstringConcat=indyWithConstants ImplicitStringConcatShapes.java
|
||||
* @run main/othervm -Xverify:all ImplicitStringConcatShapes
|
||||
*/
|
||||
public class ImplicitStringConcatShapes {
|
||||
public static void test(String expected, String actual) {
|
||||
// Fingers crossed: String concat should work.
|
||||
if (!expected.equals(actual)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Expected = ");
|
||||
sb.append(expected);
|
||||
sb.append(", actual = ");
|
||||
sb.append(actual);
|
||||
throw new IllegalStateException(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
static class MyClass {
|
||||
private final int i;
|
||||
|
||||
public MyClass(int i) {
|
||||
this.i = i;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new StringBuilder("C(").append(i).append(")").toString();
|
||||
}
|
||||
}
|
||||
|
||||
static class MyClassNullToString {
|
||||
public String toString() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new ImplicitStringConcatShapes().run();
|
||||
}
|
||||
17401
test/jdk/java/lang/String/concat/ImplicitStringConcatShapes.java
Normal file
17401
test/jdk/java/lang/String/concat/ImplicitStringConcatShapes.java
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,333 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2020, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
|
||||
public class ImplicitStringConcatShapesTestGen {
|
||||
public static String escapeToUnicode(String str) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (char c : str.toCharArray()) {
|
||||
if (c < 128) {
|
||||
b.append(c);
|
||||
} else {
|
||||
b.append("\\u").append(String.format("%04X", (int) c));
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public static void main(String... args) throws IOException {
|
||||
PrintWriter pw = new PrintWriter(System.out);
|
||||
|
||||
String[] types = {
|
||||
"boolean",
|
||||
"byte",
|
||||
"byteMinus",
|
||||
"char",
|
||||
"short",
|
||||
"shortMinus",
|
||||
"int",
|
||||
"intMinus",
|
||||
"integer",
|
||||
"integerNull",
|
||||
"float",
|
||||
"floatMinus",
|
||||
"long",
|
||||
"longMinus",
|
||||
"double",
|
||||
"doubleMinus",
|
||||
"object",
|
||||
"objectNull",
|
||||
"objectNullToString",
|
||||
"String",
|
||||
"StringUTF16",
|
||||
"StringU1",
|
||||
"StringU2",
|
||||
"intArrayNull",
|
||||
"objectArrayNull",
|
||||
};
|
||||
|
||||
for (String t : Files.readAllLines(Paths.get("ImplicitStringConcatShapes-head.template"))) {
|
||||
pw.println(t);
|
||||
}
|
||||
|
||||
Map<String, String> values = new HashMap<>();
|
||||
|
||||
Random current = new Random(12345);
|
||||
for (int mode = 0; mode <= 2; mode++) {
|
||||
for (String type : types) {
|
||||
int i = current.nextInt(100);
|
||||
boolean isStatic = (mode | 1) == 1;
|
||||
boolean isFinal = (mode | 2) == 2;
|
||||
String fieldName = (isStatic ? "s" : "") + (isFinal ? "f" : "") + "_" + typeSig(type);
|
||||
String value = initValue(type, i);
|
||||
String stringValue = stringValue(type, i);
|
||||
values.put(fieldName, stringValue);
|
||||
pw.printf(" %s %s %s %s = %s;%n", isStatic ? "static" : "", isFinal ? "final" : "", typeValue(type, i), fieldName, value);
|
||||
}
|
||||
}
|
||||
|
||||
pw.println();
|
||||
|
||||
List<String> lines = new ArrayList<>();
|
||||
List<String> l = new ArrayList<>(values.keySet());
|
||||
|
||||
for (String l1 : l) {
|
||||
lines.add(String.format("test(\"%s\", \"\" + %s);",
|
||||
escapeToUnicode(values.get(l1)),
|
||||
l1
|
||||
));
|
||||
lines.add(String.format("test(\"%s\", \"prefix\" + %s);",
|
||||
escapeToUnicode("prefix" + values.get(l1)),
|
||||
l1
|
||||
));
|
||||
lines.add(String.format("test(\"%s\", %s + \"suffix\");",
|
||||
escapeToUnicode(values.get(l1) + "suffix"),
|
||||
l1
|
||||
));
|
||||
lines.add(String.format("test(\"%s\", \"prefix\" + %s + \"suffix\");",
|
||||
escapeToUnicode("prefix" + values.get(l1) + "suffix"),
|
||||
l1
|
||||
));
|
||||
}
|
||||
|
||||
for (String l1 : l) {
|
||||
for (String l2 : l) {
|
||||
lines.add(String.format("test(\"%s\", \"\" + %s + %s);",
|
||||
escapeToUnicode(values.get(l1) + values.get(l2)),
|
||||
l1, l2
|
||||
));
|
||||
lines.add(String.format("test(\"%s\", \"\" + %s + %s + \"suffix\");",
|
||||
escapeToUnicode(values.get(l1) + values.get(l2) + "suffix"),
|
||||
l1, l2
|
||||
));
|
||||
lines.add(String.format("test(\"%s\", \"prefix\" + %s + \"suffix1\" + %s + \"suffix2\");",
|
||||
escapeToUnicode("prefix" + values.get(l1) + "suffix1" + values.get(l2) + "suffix2"),
|
||||
l1, l2
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
final int STRIDE = 1000;
|
||||
int strides = lines.size() / STRIDE + 1;
|
||||
|
||||
pw.println(" public void run() {");
|
||||
for (int c = 0; c < strides; c++) {
|
||||
pw.println(" run" + c + "();");
|
||||
}
|
||||
pw.println(" }");
|
||||
pw.println();
|
||||
|
||||
for (int c = 0; c < strides; c++) {
|
||||
pw.println(" public void run" + c + "() {");
|
||||
for (String line : lines.subList(c * STRIDE, Math.min(lines.size(), (c+1) * STRIDE))) {
|
||||
pw.println(" " + line);
|
||||
}
|
||||
pw.println(" }");
|
||||
pw.println();
|
||||
}
|
||||
|
||||
pw.println("}");
|
||||
|
||||
pw.flush();
|
||||
pw.close();
|
||||
}
|
||||
|
||||
private static String typeSig(String type) {
|
||||
switch (type) {
|
||||
case "boolean": return "bl";
|
||||
case "byte": return "b";
|
||||
case "byteMinus": return "bM";
|
||||
case "short": return "s";
|
||||
case "shortMinus": return "sM";
|
||||
case "char": return "c";
|
||||
case "int": return "i";
|
||||
case "intMinus": return "iM";
|
||||
case "integer": return "I";
|
||||
case "integerNull": return "IN";
|
||||
case "float": return "f";
|
||||
case "floatMinus": return "fM";
|
||||
case "long": return "l";
|
||||
case "longMinus": return "lM";
|
||||
case "double": return "d";
|
||||
case "doubleMinus": return "dM";
|
||||
case "String": return "str";
|
||||
case "StringUTF16": return "strU";
|
||||
case "StringU1": return "strU1";
|
||||
case "StringU2": return "strU2";
|
||||
case "object": return "o";
|
||||
case "objectNull": return "oN";
|
||||
case "objectNullToString": return "oNtS";
|
||||
case "intArrayNull": return "iAN";
|
||||
case "objectArrayNull": return "oAN";
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
private static String typeValue(String type, int i) {
|
||||
switch (type) {
|
||||
case "boolean":
|
||||
case "byte":
|
||||
case "byteMinus":
|
||||
case "char":
|
||||
case "short":
|
||||
case "shortMinus":
|
||||
case "int":
|
||||
case "intMinus":
|
||||
case "float":
|
||||
case "floatMinus":
|
||||
case "long":
|
||||
case "longMinus":
|
||||
case "double":
|
||||
case "doubleMinus":
|
||||
return type.replace("Minus", "");
|
||||
case "String":
|
||||
case "StringUTF16":
|
||||
case "StringU1":
|
||||
case "StringU2":
|
||||
return "String";
|
||||
case "object":
|
||||
case "objectNull":
|
||||
case "objectNullToString":
|
||||
return "Object";
|
||||
case "integer":
|
||||
case "integerNull":
|
||||
return "Integer";
|
||||
case "intArrayNull":
|
||||
return "int[]";
|
||||
case "objectArrayNull":
|
||||
return "Object[]";
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
private static String initValue(String type, int i) {
|
||||
switch (type) {
|
||||
case "boolean":
|
||||
return String.valueOf((i & 1) == 1);
|
||||
case "byte":
|
||||
return String.valueOf(i);
|
||||
case "byteMinus":
|
||||
return String.valueOf(-i);
|
||||
case "short":
|
||||
return String.valueOf(i*100);
|
||||
case "shortMinus":
|
||||
return String.valueOf(-i*100);
|
||||
case "intMinus":
|
||||
return String.valueOf(-i*1_000_000);
|
||||
case "int":
|
||||
case "integer":
|
||||
return String.valueOf(i*1_000_000);
|
||||
case "long":
|
||||
return String.valueOf(i*1_000_000_000) + "L";
|
||||
case "longMinus":
|
||||
return String.valueOf(-i*1_000_000_000) + "L";
|
||||
case "char":
|
||||
return "'" + (char)(i % 26 + 65) + "'";
|
||||
case "double":
|
||||
return String.valueOf(i) + ".0d";
|
||||
case "doubleMinus":
|
||||
return "-" + String.valueOf(i) + ".0d";
|
||||
case "float":
|
||||
return String.valueOf(i) + ".0f";
|
||||
case "floatMinus":
|
||||
return "-" + String.valueOf(i) + ".0f";
|
||||
case "object":
|
||||
return "new MyClass(" + i + ")";
|
||||
case "objectNullToString":
|
||||
return "new MyClassNullToString()";
|
||||
case "integerNull":
|
||||
case "objectNull":
|
||||
case "intArrayNull":
|
||||
case "objectArrayNull":
|
||||
return "null";
|
||||
case "String":
|
||||
return "\"" + i + "\"";
|
||||
case "StringUTF16":
|
||||
return "\"\\u0451" + i + "\"";
|
||||
case "StringU1":
|
||||
return "\"\\u0001" + i + "\"";
|
||||
case "StringU2":
|
||||
return "\"\\u0002" + i + "\"";
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
private static String stringValue(String type, int i) {
|
||||
switch (type) {
|
||||
case "boolean":
|
||||
return String.valueOf((i & 1) == 1);
|
||||
case "byte":
|
||||
return String.valueOf(i);
|
||||
case "byteMinus":
|
||||
return String.valueOf(-i);
|
||||
case "short":
|
||||
return String.valueOf(i*100);
|
||||
case "shortMinus":
|
||||
return String.valueOf(-i*100);
|
||||
case "intMinus":
|
||||
return String.valueOf(-i*1_000_000);
|
||||
case "int":
|
||||
case "integer":
|
||||
return String.valueOf(i*1_000_000);
|
||||
case "long":
|
||||
return String.valueOf(i*1_000_000_000);
|
||||
case "longMinus":
|
||||
return String.valueOf(-i*1_000_000_000);
|
||||
case "char":
|
||||
return String.valueOf((char) (i % 26 + 65));
|
||||
case "double":
|
||||
case "float":
|
||||
return String.valueOf(i) + ".0";
|
||||
case "doubleMinus":
|
||||
case "floatMinus":
|
||||
return "-" + String.valueOf(i) + ".0";
|
||||
case "object":
|
||||
return "C(" + i + ")";
|
||||
case "integerNull":
|
||||
case "objectNull":
|
||||
case "objectNullToString":
|
||||
case "intArrayNull":
|
||||
case "objectArrayNull":
|
||||
return "null";
|
||||
case "String":
|
||||
return "" + i;
|
||||
case "StringUTF16":
|
||||
return "\u0451" + i;
|
||||
case "StringU1":
|
||||
return "\u0001" + i;
|
||||
case "StringU2":
|
||||
return "\u0002" + i;
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
60
test/jdk/java/lang/String/concat/IntegerMinValue.java
Normal file
60
test/jdk/java/lang/String/concat/IntegerMinValue.java
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Red Hat, Inc. 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8267773
|
||||
* @summary Test
|
||||
*
|
||||
* @compile IntegerMinValue.java
|
||||
* @run main/othervm -Xverify:all -Xbatch IntegerMinValue
|
||||
*
|
||||
* @compile -XDstringConcat=inline IntegerMinValue.java
|
||||
* @run main/othervm -Xverify:all -Xbatch IntegerMinValue
|
||||
*
|
||||
* @compile -XDstringConcat=indy IntegerMinValue.java
|
||||
* @run main/othervm -Xverify:all -Xbatch IntegerMinValue
|
||||
*
|
||||
* @compile -XDstringConcat=indyWithConstants IntegerMinValue.java
|
||||
* @run main/othervm -Xverify:all -Xbatch IntegerMinValue
|
||||
*/
|
||||
|
||||
public class IntegerMinValue {
|
||||
|
||||
public void test() {
|
||||
int i = Integer.MIN_VALUE;
|
||||
String s = "" + i;
|
||||
if (!"-2147483648".equals(s)) {
|
||||
throw new IllegalStateException("Failed: " + s);
|
||||
}
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
public static void main(String[] strArr) {
|
||||
IntegerMinValue t = new IntegerMinValue();
|
||||
for (int i = 0; i < 100_000; i++ ) {
|
||||
t.test();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,361 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.invoke.*;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Test input invariants for StringConcatFactory
|
||||
* @bug 8246152 8247681
|
||||
*
|
||||
* @compile StringConcatFactoryInvariants.java
|
||||
*
|
||||
* @run main/othervm -Xverify:all StringConcatFactoryInvariants
|
||||
*
|
||||
*/
|
||||
public class StringConcatFactoryInvariants {
|
||||
|
||||
private static final char TAG_ARG = '\u0001';
|
||||
private static final char TAG_CONST = '\u0002';
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
String methodName = "foo";
|
||||
MethodType mt = MethodType.methodType(String.class, String.class, int.class);
|
||||
String recipe = "" + TAG_ARG + TAG_ARG + TAG_CONST;
|
||||
Object[][] constants = new Object[][] {
|
||||
new String[] { "" },
|
||||
new String[] { "bar" },
|
||||
new Integer[] { 1 },
|
||||
new Short[] { 2 },
|
||||
new Long[] { 3L },
|
||||
new Boolean[] { true },
|
||||
new Character[] { 'a' },
|
||||
new Byte[] { -128 },
|
||||
new Class[] { String.class },
|
||||
new MethodHandle[] { MethodHandles.constant(String.class, "constant") },
|
||||
new MethodType[] { MethodType.methodType(String.class) }
|
||||
};
|
||||
// The string representation that should end up if the corresponding
|
||||
// Object[] in constants is used as an argument to makeConcatWithConstants
|
||||
String[] constantString = new String[] {
|
||||
"",
|
||||
"bar",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"true",
|
||||
"a",
|
||||
"-128",
|
||||
"class java.lang.String",
|
||||
"MethodHandle()String",
|
||||
"()String"
|
||||
};
|
||||
|
||||
|
||||
final int LIMIT = 200;
|
||||
|
||||
// Simple factory: check for dynamic arguments overflow
|
||||
Class<?>[] underThreshold = new Class<?>[LIMIT - 1];
|
||||
Class<?>[] threshold = new Class<?>[LIMIT];
|
||||
Class<?>[] overThreshold = new Class<?>[LIMIT + 1];
|
||||
|
||||
StringBuilder sbUnderThreshold = new StringBuilder();
|
||||
sbUnderThreshold.append(TAG_CONST);
|
||||
for (int c = 0; c < LIMIT - 1; c++) {
|
||||
underThreshold[c] = int.class;
|
||||
threshold[c] = int.class;
|
||||
overThreshold[c] = int.class;
|
||||
sbUnderThreshold.append(TAG_ARG);
|
||||
}
|
||||
threshold[LIMIT - 1] = int.class;
|
||||
overThreshold[LIMIT - 1] = int.class;
|
||||
overThreshold[LIMIT] = int.class;
|
||||
|
||||
String recipeEmpty = "";
|
||||
String recipeUnderThreshold = sbUnderThreshold.toString();
|
||||
String recipeThreshold = sbUnderThreshold.append(TAG_ARG).toString();
|
||||
String recipeOverThreshold = sbUnderThreshold.append(TAG_ARG).toString();
|
||||
|
||||
MethodType mtEmpty = MethodType.methodType(String.class);
|
||||
MethodType mtUnderThreshold = MethodType.methodType(String.class, underThreshold);
|
||||
MethodType mtThreshold = MethodType.methodType(String.class, threshold);
|
||||
MethodType mtOverThreshold = MethodType.methodType(String.class, overThreshold);
|
||||
|
||||
|
||||
// Check the basic functionality is working
|
||||
{
|
||||
CallSite cs = StringConcatFactory.makeConcat(lookup, methodName, mt);
|
||||
test("foo42", (String) cs.getTarget().invokeExact("foo", 42));
|
||||
}
|
||||
|
||||
{
|
||||
for (int i = 0; i < constants.length; i++) {
|
||||
CallSite cs = StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, recipe, constants[i]);
|
||||
test("foo42".concat(constantString[i]), (String) cs.getTarget().invokeExact("foo", 42));
|
||||
}
|
||||
}
|
||||
|
||||
// Check unary expressions with pre- and postfix constants
|
||||
{
|
||||
String constArgRecipe = "" + TAG_CONST + TAG_ARG;
|
||||
String argConstRecipe = "" + TAG_ARG + TAG_CONST;
|
||||
MethodType unaryMt = MethodType.methodType(String.class, String.class);
|
||||
|
||||
for (int i = 0; i < constants.length; i++) {
|
||||
CallSite prefixCS = StringConcatFactory.makeConcatWithConstants(lookup, methodName, unaryMt, constArgRecipe, constants[i]);
|
||||
test(constantString[i].concat("foo"), (String) prefixCS.getTarget().invokeExact("foo"));
|
||||
|
||||
CallSite postfixCS = StringConcatFactory.makeConcatWithConstants(lookup, methodName, unaryMt, argConstRecipe, constants[i]);
|
||||
test("foo".concat(constantString[i]), (String) postfixCS.getTarget().invokeExact("foo"));
|
||||
}
|
||||
}
|
||||
|
||||
// Simple factory, check for nulls:
|
||||
failNPE("Lookup is null",
|
||||
() -> StringConcatFactory.makeConcat(null, methodName, mt));
|
||||
|
||||
failNPE("Method name is null",
|
||||
() -> StringConcatFactory.makeConcat(lookup, null, mt));
|
||||
|
||||
failNPE("MethodType is null",
|
||||
() -> StringConcatFactory.makeConcat(lookup, methodName, null));
|
||||
|
||||
// Advanced factory, check for nulls:
|
||||
for (int i = 0; i < constants.length; i++) {
|
||||
final Object[] consts = constants[i];
|
||||
|
||||
failNPE("Lookup is null",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(null, methodName, mt, recipe, consts));
|
||||
|
||||
failNPE("Method name is null",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, null, mt, recipe, consts));
|
||||
|
||||
failNPE("MethodType is null",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, null, recipe, consts));
|
||||
|
||||
failNPE("Recipe is null",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, null, consts));
|
||||
}
|
||||
|
||||
failNPE("Constants vararg is null",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, recipe, (Object[]) null));
|
||||
|
||||
failNPE("Constant argument is null",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mt, recipe, new Object[] { null }));
|
||||
|
||||
// Simple factory, check for return type
|
||||
fail("Return type: void",
|
||||
() -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(void.class, String.class, int.class)));
|
||||
|
||||
fail("Return type: int",
|
||||
() -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(int.class, String.class, int.class)));
|
||||
|
||||
fail("Return type: StringBuilder",
|
||||
() -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(StringBuilder.class, String.class, int.class)));
|
||||
|
||||
ok("Return type: Object",
|
||||
() -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(Object.class, String.class, int.class)));
|
||||
|
||||
ok("Return type: CharSequence",
|
||||
() -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(CharSequence.class, String.class, int.class)));
|
||||
|
||||
ok("Return type: Serializable",
|
||||
() -> StringConcatFactory.makeConcat(lookup, methodName, MethodType.methodType(Serializable.class, String.class, int.class)));
|
||||
|
||||
// Advanced factory, check for return types
|
||||
for (int i = 0; i < constants.length; i++) {
|
||||
final Object[] consts = constants[i];
|
||||
fail("Return type: void",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(void.class, String.class, int.class), recipe, consts));
|
||||
|
||||
fail("Return type: int",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(int.class, String.class, int.class), recipe, consts));
|
||||
|
||||
fail("Return type: StringBuilder",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(StringBuilder.class, String.class, int.class), recipe, consts));
|
||||
|
||||
ok("Return type: Object",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(Object.class, String.class, int.class), recipe, consts));
|
||||
|
||||
ok("Return type: CharSequence",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(CharSequence.class, String.class, int.class), recipe, consts));
|
||||
|
||||
ok("Return type: Serializable",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(Serializable.class, String.class, int.class), recipe, consts));
|
||||
}
|
||||
|
||||
// Simple factory: check for dynamic arguments overflow
|
||||
ok("Dynamic arguments is under limit",
|
||||
() -> StringConcatFactory.makeConcat(lookup, methodName, mtUnderThreshold));
|
||||
|
||||
ok("Dynamic arguments is at the limit",
|
||||
() -> StringConcatFactory.makeConcat(lookup, methodName, mtThreshold));
|
||||
|
||||
fail("Dynamic arguments is over the limit",
|
||||
() -> StringConcatFactory.makeConcat(lookup, methodName, mtOverThreshold));
|
||||
|
||||
// Advanced factory: check for dynamic arguments overflow
|
||||
ok("Dynamic arguments is under limit",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtUnderThreshold, recipeUnderThreshold, constants[0]));
|
||||
|
||||
ok("Dynamic arguments is at the limit",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, constants[0]));
|
||||
|
||||
fail("Dynamic arguments is over the limit",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtOverThreshold, recipeOverThreshold, constants[0]));
|
||||
|
||||
// Advanced factory: check for mismatched recipe and Constants
|
||||
ok("Static arguments and recipe match",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, "bar"));
|
||||
|
||||
fail("Static arguments and recipe mismatch: too few",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold));
|
||||
|
||||
fail("Static arguments and recipe mismatch: too many",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, "bar", "baz"));
|
||||
|
||||
failNPE("Static arguments and recipe mismatch, too many, overflowing constant is null",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, "bar", null));
|
||||
|
||||
// Advanced factory: check for mismatched recipe and dynamic arguments
|
||||
fail("Dynamic arguments and recipe mismatch",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeUnderThreshold, constants[0]));
|
||||
|
||||
ok("Dynamic arguments and recipe match",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeThreshold, constants[0]));
|
||||
|
||||
fail("Dynamic arguments and recipe mismatch",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtThreshold, recipeOverThreshold, constants[0]));
|
||||
|
||||
// Test passing array as constant
|
||||
{
|
||||
Object[] arg = {"boo", "bar"};
|
||||
|
||||
CallSite cs1 = StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(String.class, int.class), "" + TAG_ARG + TAG_CONST + TAG_CONST, arg);
|
||||
test("42boobar", (String) cs1.getTarget().invokeExact(42));
|
||||
}
|
||||
|
||||
// Test passing null constant
|
||||
ok("Can pass regular constants",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(String.class, int.class), "" + TAG_ARG + TAG_CONST, "foo"));
|
||||
|
||||
failNPE("Cannot pass null constants",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, MethodType.methodType(String.class, int.class), "" + TAG_ARG + TAG_CONST, new Object[]{null}));
|
||||
|
||||
// Simple factory: test empty arguments
|
||||
ok("Ok to pass empty arguments",
|
||||
() -> StringConcatFactory.makeConcat(lookup, methodName, mtEmpty));
|
||||
|
||||
// Advanced factory: test empty arguments
|
||||
ok("Ok to pass empty arguments",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(lookup, methodName, mtEmpty, recipeEmpty));
|
||||
|
||||
// Simple factory: public Lookup is rejected
|
||||
fail("Passing public Lookup",
|
||||
() -> StringConcatFactory.makeConcat(MethodHandles.publicLookup(), methodName, mtEmpty));
|
||||
|
||||
// Advanced factory: public Lookup is rejected
|
||||
fail("Passing public Lookup",
|
||||
() -> StringConcatFactory.makeConcatWithConstants(MethodHandles.publicLookup(), methodName, mtEmpty, recipeEmpty));
|
||||
|
||||
// Zero inputs
|
||||
{
|
||||
MethodType zero = MethodType.methodType(String.class);
|
||||
CallSite cs = StringConcatFactory.makeConcat(lookup, methodName, zero);
|
||||
test("", (String) cs.getTarget().invokeExact());
|
||||
|
||||
cs = StringConcatFactory.makeConcatWithConstants(lookup, methodName, zero, "");
|
||||
test("", (String) cs.getTarget().invokeExact());
|
||||
}
|
||||
|
||||
// One input
|
||||
{
|
||||
MethodType zero = MethodType.methodType(String.class);
|
||||
MethodType one = MethodType.methodType(String.class, String.class);
|
||||
CallSite cs = StringConcatFactory.makeConcat(lookup, methodName, one);
|
||||
test("A", (String) cs.getTarget().invokeExact("A"));
|
||||
|
||||
cs = StringConcatFactory.makeConcatWithConstants(lookup, methodName, one, "\1");
|
||||
test("A", (String) cs.getTarget().invokeExact("A"));
|
||||
|
||||
cs = StringConcatFactory.makeConcatWithConstants(lookup, methodName, zero, "\2", "A");
|
||||
test("A", (String) cs.getTarget().invokeExact());
|
||||
}
|
||||
}
|
||||
|
||||
public static void ok(String msg, Callable runnable) {
|
||||
try {
|
||||
runnable.call();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalStateException(msg + ", should have passed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void fail(String msg, Callable runnable) {
|
||||
boolean expected = false;
|
||||
try {
|
||||
runnable.call();
|
||||
} catch (StringConcatException e) {
|
||||
expected = true;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!expected) {
|
||||
throw new IllegalStateException(msg + ", should have failed with StringConcatException");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void failNPE(String msg, Callable runnable) {
|
||||
boolean expected = false;
|
||||
try {
|
||||
runnable.call();
|
||||
} catch (NullPointerException e) {
|
||||
expected = true;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!expected) {
|
||||
throw new IllegalStateException(msg + ", should have failed with NullPointerException");
|
||||
}
|
||||
}
|
||||
|
||||
public static void test(String expected, String actual) {
|
||||
// Fingers crossed: String concat should work.
|
||||
if (!expected.equals(actual)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Expected = ");
|
||||
sb.append(expected);
|
||||
sb.append(", actual = ");
|
||||
sb.append(actual);
|
||||
throw new IllegalStateException(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.invoke.StringConcatFactory;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary StringConcatFactory allow recipes with repeated constants, but this
|
||||
* is not expressible with java code and needs an explicit sanity test
|
||||
* @bug 8222852
|
||||
*
|
||||
* @compile StringConcatFactoryRepeatedConstants.java
|
||||
*
|
||||
* @run main/othervm -Xverify:all StringConcatFactoryRepeatedConstants
|
||||
*/
|
||||
public class StringConcatFactoryRepeatedConstants {
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
|
||||
CallSite site = StringConcatFactory.makeConcatWithConstants(
|
||||
MethodHandles.lookup(),
|
||||
"foo",
|
||||
MethodType.methodType(String.class),
|
||||
"\u0002\u0002",
|
||||
"foo", "bar"
|
||||
);
|
||||
String string = (String)site.dynamicInvoker().invoke();
|
||||
if (!"foobar".equals(string)) {
|
||||
throw new IllegalStateException("Expected: foobar, got: " + string);
|
||||
}
|
||||
|
||||
site = StringConcatFactory.makeConcatWithConstants(
|
||||
MethodHandles.lookup(),
|
||||
"foo",
|
||||
MethodType.methodType(String.class),
|
||||
"\u0002\u0002test\u0002\u0002",
|
||||
"foo", 17.0f, 4711L, "bar"
|
||||
);
|
||||
string = (String)site.dynamicInvoker().invoke();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("foo").append(17.0f).append("test").append(4711L).append("bar");
|
||||
if (!sb.toString().equals(string)) {
|
||||
throw new IllegalStateException("Expected: " + sb.toString() + ", got: " + string);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
26
test/jdk/java/lang/String/concat/update-tests.sh
Normal file
26
test/jdk/java/lang/String/concat/update-tests.sh
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# Copyright (c) 2015, 2016, 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.
|
||||
#
|
||||
# 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.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
javac ImplicitStringConcatShapesTestGen.java
|
||||
java ImplicitStringConcatShapesTestGen > ImplicitStringConcatShapes.java
|
||||
rm ImplicitStringConcatShapesTestGen.class
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 2025, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @requires !jdk.static
|
||||
* @run main/othervm/native -Xcheck:jni StringPlatformChars
|
||||
*/
|
||||
import java.util.Arrays;
|
||||
|
||||
public class StringPlatformChars {
|
||||
|
||||
private static final String JNU_ENCODING = System.getProperty("sun.jnu.encoding");
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
System.out.println("sun.jnu.encoding: " + JNU_ENCODING);
|
||||
System.loadLibrary("stringPlatformChars");
|
||||
|
||||
// Test varying lengths, provoking different allocation paths
|
||||
StringBuilder unicodeSb = new StringBuilder();
|
||||
StringBuilder asciiSb = new StringBuilder();
|
||||
StringBuilder latinSb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < 2000; i++) {
|
||||
unicodeSb.append('\uFEFE');
|
||||
testString(unicodeSb.toString());
|
||||
|
||||
asciiSb.append('x');
|
||||
testString(asciiSb.toString());
|
||||
|
||||
latinSb.append('\u00FE');
|
||||
testString(latinSb.toString());
|
||||
|
||||
testString(latinSb.toString() + asciiSb.toString() + unicodeSb.toString());
|
||||
}
|
||||
|
||||
// Exhaustively test simple Strings made up of all possible chars:
|
||||
for (char c = '\u0001'; c < Character.MAX_VALUE; c++) {
|
||||
testString(String.valueOf(c));
|
||||
}
|
||||
// Special case: \u0000 is treated as end-of-string in the native code,
|
||||
// so strings with it should be truncated:
|
||||
if (getBytes("\u0000abcdef").length != 0 ||
|
||||
getBytes("a\u0000bcdef").length != 1) {
|
||||
System.out.println("Mismatching values for strings including \\u0000");
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
private static void testString(String s) throws Exception {
|
||||
byte[] nativeBytes = getBytes(s);
|
||||
byte[] stringBytes = s.getBytes(JNU_ENCODING);
|
||||
|
||||
if (!Arrays.equals(nativeBytes, stringBytes)) {
|
||||
System.out.println("Mismatching values for: '" + s + "' " + Arrays.toString(s.chars().toArray()));
|
||||
System.out.println("Native: " + Arrays.toString(nativeBytes));
|
||||
System.out.println("String: " + Arrays.toString(stringBytes));
|
||||
throw new AssertionError(s);
|
||||
}
|
||||
|
||||
String javaNewS = new String(nativeBytes, JNU_ENCODING);
|
||||
String nativeNewS = newString(nativeBytes);
|
||||
if (!javaNewS.equals(nativeNewS)) {
|
||||
System.out.println("New string via native doesn't match via java: '" + javaNewS + "' and '" + nativeNewS + "'");
|
||||
throw new AssertionError(s);
|
||||
}
|
||||
}
|
||||
|
||||
static native byte[] getBytes(String string);
|
||||
|
||||
static native String newString(byte[] bytes);
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2025, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL
|
||||
Java_StringPlatformChars_getBytes(JNIEnv *env, jclass unused, jstring value)
|
||||
{
|
||||
const char* str;
|
||||
int len;
|
||||
jbyteArray bytes = NULL;
|
||||
|
||||
str = JNU_GetStringPlatformChars(env, value, NULL);
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
len = (int)strlen(str);
|
||||
bytes = (*env)->NewByteArray(env, len);
|
||||
if (bytes != 0) {
|
||||
jclass strClazz = JNU_ClassString(env);
|
||||
if (strClazz == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte *)str);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_StringPlatformChars_newString(JNIEnv *env, jclass unused, jbyteArray bytes)
|
||||
{
|
||||
char* str;
|
||||
int len = (*env)->GetArrayLength(env, bytes);
|
||||
int i;
|
||||
jbyte* jbytes = (*env)->GetPrimitiveArrayCritical(env, bytes, NULL);
|
||||
if (jbytes == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
str = (char*)malloc(len + 1);
|
||||
if (str == NULL) {
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, bytes, (void*)jbytes, 0);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
str[i] = (char)jbytes[i];
|
||||
}
|
||||
str[len] = '\0';
|
||||
(*env)->ReleasePrimitiveArrayCritical(env, bytes, (void*)jbytes, 0);
|
||||
|
||||
jstring res = JNU_NewStringPlatform(env, str);
|
||||
free(str);
|
||||
return res;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue