Skip to content

Commit 7642556

Browse files
mkargjaikiran
authored andcommitted
8343110: Add getChars(int, int, char[], int) to CharSequence and CharBuffer
Reviewed-by: liach, jpai, rriggs
1 parent 493ac93 commit 7642556

File tree

8 files changed

+411
-71
lines changed

8 files changed

+411
-71
lines changed

src/java.base/share/classes/java/io/Reader.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -193,16 +193,7 @@ public int read(char[] cbuf, int off, int len) throws IOException {
193193
if (next >= length)
194194
return -1;
195195
int n = Math.min(length - next, len);
196-
switch (cs) {
197-
case String s -> s.getChars(next, next + n, cbuf, off);
198-
case StringBuilder sb -> sb.getChars(next, next + n, cbuf, off);
199-
case StringBuffer sb -> sb.getChars(next, next + n, cbuf, off);
200-
case CharBuffer cb -> cb.get(next, cbuf, off, n);
201-
default -> {
202-
for (int i = 0; i < n; i++)
203-
cbuf[off + i] = cs.charAt(next + i);
204-
}
205-
}
196+
cs.getChars(next, next + n, cbuf, off);
206197
next += n;
207198
return n;
208199
}

src/java.base/share/classes/java/lang/AbstractStringBuilder.java

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -488,33 +488,9 @@ public int offsetByCodePoints(int index, int codePointOffset) {
488488
}
489489

490490
/**
491-
* Characters are copied from this sequence into the
492-
* destination character array {@code dst}. The first character to
493-
* be copied is at index {@code srcBegin}; the last character to
494-
* be copied is at index {@code srcEnd-1}. The total number of
495-
* characters to be copied is {@code srcEnd-srcBegin}. The
496-
* characters are copied into the subarray of {@code dst} starting
497-
* at index {@code dstBegin} and ending at index:
498-
* <pre>{@code
499-
* dstbegin + (srcEnd-srcBegin) - 1
500-
* }</pre>
501-
*
502-
* @param srcBegin start copying at this offset.
503-
* @param srcEnd stop copying at this offset.
504-
* @param dst the array to copy the data into.
505-
* @param dstBegin offset into {@code dst}.
506-
* @throws IndexOutOfBoundsException if any of the following is true:
507-
* <ul>
508-
* <li>{@code srcBegin} is negative
509-
* <li>{@code dstBegin} is negative
510-
* <li>the {@code srcBegin} argument is greater than
511-
* the {@code srcEnd} argument.
512-
* <li>{@code srcEnd} is greater than
513-
* {@code this.length()}.
514-
* <li>{@code dstBegin+srcEnd-srcBegin} is greater than
515-
* {@code dst.length}
516-
* </ul>
491+
* {@inheritDoc CharSequence}
517492
*/
493+
@Override
518494
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
519495
{
520496
Preconditions.checkFromToIndex(srcBegin, srcEnd, count, Preconditions.SIOOBE_FORMATTER); // compatible to old version

src/java.base/share/classes/java/lang/CharSequence.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -302,4 +302,47 @@ public static int compare(CharSequence cs1, CharSequence cs2) {
302302
return cs1.length() - cs2.length();
303303
}
304304

305+
/**
306+
* Copies characters from this sequence into the given destination array.
307+
* The first character to be copied is at index {@code srcBegin}; the last
308+
* character to be copied is at index {@code srcEnd-1}. The total number of
309+
* characters to be copied is {@code srcEnd-srcBegin}. The
310+
* characters are copied into the subarray of {@code dst} starting
311+
* at index {@code dstBegin} and ending at index:
312+
* <pre>{@code
313+
* dstbegin + (srcEnd-srcBegin) - 1
314+
* }</pre>
315+
*
316+
* @param srcBegin start copying at this offset.
317+
* @param srcEnd stop copying at this offset.
318+
* @param dst the array to copy the data into.
319+
* @param dstBegin offset into {@code dst}.
320+
* @throws IndexOutOfBoundsException if any of the following is true:
321+
* <ul>
322+
* <li>{@code srcBegin} is negative
323+
* <li>{@code dstBegin} is negative
324+
* <li>the {@code srcBegin} argument is greater than
325+
* the {@code srcEnd} argument.
326+
* <li>{@code srcEnd} is greater than
327+
* {@code this.length()}.
328+
* <li>{@code dstBegin+srcEnd-srcBegin} is greater than
329+
* {@code dst.length}
330+
* </ul>
331+
* @throws NullPointerException if {@code dst} is {@code null}
332+
*
333+
* @implSpec
334+
* The default implementation invokes {@link #charAt(int index)} in a loop
335+
* iterating {@code index} from {@code srcBegin} to {@code srcEnd-1}.
336+
* Concurrent truncation of this character sequence can throw
337+
* {@code IndexOutOfBoundsException}. In this case, some characters, but not
338+
* all, may be already transferred.
339+
*
340+
* @since 25
341+
*/
342+
public default void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) {
343+
Objects.checkFromToIndex(srcBegin, srcEnd, length());
344+
Objects.checkIndex(dstBegin, dst.length - (srcEnd - srcBegin) + 1);
345+
while (srcBegin < srcEnd)
346+
dst[dstBegin++] = charAt(srcBegin++);
347+
}
305348
}

src/java.base/share/classes/java/lang/String.java

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,35 +1739,14 @@ public int offsetByCodePoints(int index, int codePointOffset) {
17391739
}
17401740

17411741
/**
1742-
* Copies characters from this string into the destination character
1743-
* array.
1744-
* <p>
1745-
* The first character to be copied is at index {@code srcBegin};
1746-
* the last character to be copied is at index {@code srcEnd-1}
1747-
* (thus the total number of characters to be copied is
1748-
* {@code srcEnd-srcBegin}). The characters are copied into the
1749-
* subarray of {@code dst} starting at index {@code dstBegin}
1750-
* and ending at index:
1751-
* <blockquote><pre>
1752-
* dstBegin + (srcEnd-srcBegin) - 1
1753-
* </pre></blockquote>
1754-
*
1755-
* @param srcBegin index of the first character in the string
1756-
* to copy.
1757-
* @param srcEnd index after the last character in the string
1758-
* to copy.
1759-
* @param dst the destination array.
1760-
* @param dstBegin the start offset in the destination array.
1761-
* @throws IndexOutOfBoundsException If any of the following
1762-
* is true:
1763-
* <ul><li>{@code srcBegin} is negative.
1764-
* <li>{@code srcBegin} is greater than {@code srcEnd}
1765-
* <li>{@code srcEnd} is greater than the length of this
1766-
* string
1767-
* <li>{@code dstBegin} is negative
1768-
* <li>{@code dstBegin+(srcEnd-srcBegin)} is larger than
1769-
* {@code dst.length}</ul>
1742+
* {@inheritDoc CharSequence}
1743+
* @param srcBegin {@inheritDoc CharSequence}
1744+
* @param srcEnd {@inheritDoc CharSequence}
1745+
* @param dst {@inheritDoc CharSequence}
1746+
* @param dstBegin {@inheritDoc CharSequence}
1747+
* @throws IndexOutOfBoundsException {@inheritDoc CharSequence}
17701748
*/
1749+
@Override
17711750
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) {
17721751
checkBoundsBeginEnd(srcBegin, srcEnd, length());
17731752
checkBoundsOffCount(dstBegin, srcEnd - srcBegin, dst.length);

src/java.base/share/classes/java/lang/StringBuffer.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1994, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -279,9 +279,6 @@ public synchronized int offsetByCodePoints(int index, int codePointOffset) {
279279
return super.offsetByCodePoints(index, codePointOffset);
280280
}
281281

282-
/**
283-
* @throws IndexOutOfBoundsException {@inheritDoc}
284-
*/
285282
@Override
286283
public synchronized void getChars(int srcBegin, int srcEnd, char[] dst,
287284
int dstBegin)

src/java.base/share/classes/java/nio/X-Buffer.java.template

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -1896,6 +1896,44 @@ public abstract sealed class $Type$Buffer
18961896

18971897
#if[char]
18981898

1899+
/**
1900+
* Absolute bulk <i>get</i> method.
1901+
*
1902+
* <p> This method transfers {@code srcEnd-srcBegin} characters from this
1903+
* buffer into the given array, starting at index {@code srcBegin} in this
1904+
* buffer and at offset {@code dstBegin} in the array. The position of this
1905+
* buffer is unchanged.
1906+
*
1907+
* @param srcBegin
1908+
* The index in this buffer from which the first character will be
1909+
* read; must be non-negative and less than {@code limit()}
1910+
*
1911+
* @param srcEnd
1912+
* The index in this buffer directly before the last character to
1913+
* read; must be non-negative and less or equal than {@code limit()}
1914+
* and must be greater or equal than {@code srcBegin}
1915+
*
1916+
* @param dst
1917+
* The destination array
1918+
*
1919+
* @param dstBegin
1920+
* The offset within the array of the first character to be
1921+
* written; must be non-negative and less than {@code dst.length}
1922+
*
1923+
* @throws IndexOutOfBoundsException
1924+
* If the preconditions on the {@code srcBegin}, {@code srcEnd},
1925+
* and {@code dstBegin} parameters do not hold
1926+
*
1927+
* @implSpec This method is equivalent to
1928+
* {@code get(srcBegin, dst, dstBegin, srcEnd - srcBegin)}.
1929+
*
1930+
* @since 25
1931+
*/
1932+
@Override
1933+
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) {
1934+
get(srcBegin, dst, dstBegin, srcEnd - srcBegin);
1935+
}
1936+
18991937
/**
19001938
* Returns a string containing the characters in this buffer.
19011939
*
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
import org.testng.Assert;
25+
import org.testng.annotations.Test;
26+
27+
/**
28+
* @test
29+
* @bug 8343110
30+
* @summary Check for expected behavior of default implementation of
31+
* CharSequence.getChars().
32+
* @run testng GetChars
33+
*/
34+
public class GetChars {
35+
private static CharSequence CS = new CharSequence() {
36+
@Override
37+
public int length() {
38+
return 4;
39+
}
40+
41+
@Override
42+
public char charAt(int index) {
43+
return "Test".charAt(index);
44+
}
45+
46+
@Override
47+
public CharSequence subSequence(int start, int end) {
48+
throw new UnsupportedOperationException();
49+
}
50+
};
51+
52+
@Test
53+
public void testExactCopy() {
54+
var dst = new char[4];
55+
CS.getChars(0, 4, dst, 0);
56+
Assert.assertEquals(dst, new char[] {'T', 'e', 's', 't'});
57+
}
58+
59+
@Test
60+
public void testPartialCopy() {
61+
var dst = new char[2];
62+
CS.getChars(1, 3, dst, 0);
63+
Assert.assertEquals(dst, new char[] {'e', 's'});
64+
}
65+
66+
@Test
67+
public void testPositionedCopy() {
68+
var dst = new char[] {1, 2, 3, 4, 5, 6};
69+
CS.getChars(0, 4, dst, 1);
70+
Assert.assertEquals(dst, new char[] {1, 'T', 'e', 's', 't', 6});
71+
}
72+
73+
@Test
74+
public void testSrcBeginIsNegative() {
75+
Assert.assertThrows(IndexOutOfBoundsException.class,
76+
() -> CS.getChars(-1, 3, new char[4], 0));
77+
}
78+
79+
@Test
80+
public void testDstBeginIsNegative() {
81+
Assert.assertThrows(IndexOutOfBoundsException.class,
82+
() -> CS.getChars(0, 4, new char[4], -1));
83+
}
84+
85+
@Test
86+
public void testSrcBeginIsGreaterThanSrcEnd() {
87+
Assert.assertThrows(IndexOutOfBoundsException.class,
88+
() -> CS.getChars(4, 0, new char[4], 0));
89+
}
90+
91+
@Test
92+
public void testSrcEndIsGreaterThanSequenceLength() {
93+
Assert.assertThrows(IndexOutOfBoundsException.class,
94+
() -> CS.getChars(0, 5, new char[4], 0));
95+
}
96+
97+
@Test
98+
public void testRequestedLengthIsGreaterThanDstLength() {
99+
Assert.assertThrows(IndexOutOfBoundsException.class,
100+
() -> CS.getChars(0, 4, new char[3], 0));
101+
}
102+
103+
@Test
104+
public void testDstIsNull() {
105+
Assert.assertThrows(NullPointerException.class,
106+
() -> CS.getChars(0, 4, null, 0));
107+
}
108+
109+
}

0 commit comments

Comments
 (0)