Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 2 additions & 11 deletions src/java.base/share/classes/java/io/Reader.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 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
Expand Down Expand Up @@ -193,16 +193,7 @@ public int read(char[] cbuf, int off, int len) throws IOException {
if (next >= length)
return -1;
int n = Math.min(length - next, len);
switch (cs) {
case String s -> s.getChars(next, next + n, cbuf, off);
case StringBuilder sb -> sb.getChars(next, next + n, cbuf, off);
case StringBuffer sb -> sb.getChars(next, next + n, cbuf, off);
case CharBuffer cb -> cb.get(next, cbuf, off, n);
default -> {
for (int i = 0; i < n; i++)
cbuf[off + i] = cs.charAt(next + i);
}
}
cs.getChars(next, next + n, cbuf, off);
next += n;
return n;
}
Expand Down
28 changes: 2 additions & 26 deletions src/java.base/share/classes/java/lang/AbstractStringBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -488,33 +488,9 @@ public int offsetByCodePoints(int index, int codePointOffset) {
}

/**
* Characters are copied from this sequence into the
* destination character array {@code dst}. The first character to
* be copied is at index {@code srcBegin}; the last character to
* be copied is at index {@code srcEnd-1}. The total number of
* characters to be copied is {@code srcEnd-srcBegin}. The
* characters are copied into the subarray of {@code dst} starting
* at index {@code dstBegin} and ending at index:
* <pre>{@code
* dstbegin + (srcEnd-srcBegin) - 1
* }</pre>
*
* @param srcBegin start copying at this offset.
* @param srcEnd stop copying at this offset.
* @param dst the array to copy the data into.
* @param dstBegin offset into {@code dst}.
* @throws IndexOutOfBoundsException if any of the following is true:
* <ul>
* <li>{@code srcBegin} is negative
* <li>{@code dstBegin} is negative
* <li>the {@code srcBegin} argument is greater than
* the {@code srcEnd} argument.
* <li>{@code srcEnd} is greater than
* {@code this.length()}.
* <li>{@code dstBegin+srcEnd-srcBegin} is greater than
* {@code dst.length}
* </ul>
* {@inheritDoc CharSequence}
*/
@Override
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
{
Preconditions.checkFromToIndex(srcBegin, srcEnd, count, Preconditions.SIOOBE_FORMATTER); // compatible to old version
Expand Down
45 changes: 44 additions & 1 deletion src/java.base/share/classes/java/lang/CharSequence.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
Expand Down Expand Up @@ -302,4 +302,47 @@ public static int compare(CharSequence cs1, CharSequence cs2) {
return cs1.length() - cs2.length();
}

/**
* Copies characters from this sequence into the given destination array.
* The first character to be copied is at index {@code srcBegin}; the last
* character to be copied is at index {@code srcEnd-1}. The total number of
* characters to be copied is {@code srcEnd-srcBegin}. The
* characters are copied into the subarray of {@code dst} starting
* at index {@code dstBegin} and ending at index:
* <pre>{@code
* dstbegin + (srcEnd-srcBegin) - 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be dstBegin?

* dstBegin + (srcEnd-srcBegin) - 1

Copy link
Member

@jaikiran jaikiran May 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello Andrey, what you note is right. This and the other change you have proposed to this text seems reasonable. Do you want to create a JBS issue and raise a PR proposing this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also simply include it in the PR for https://bugs.openjdk.org/browse/JDK-8356679 to reduce organizational overhead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello Markus, it's OK to do this text change as part of JDK-8356679. Like Roger noted in the corresponding core-libs-dev mailing list, it would be good to do the 8356679 changes in smaller pieces and include this change in one of those.

* }</pre>
*
* @param srcBegin start copying at this offset.
* @param srcEnd stop copying at this offset.
* @param dst the array to copy the data into.
* @param dstBegin offset into {@code dst}.
* @throws IndexOutOfBoundsException if any of the following is true:
* <ul>
* <li>{@code srcBegin} is negative
* <li>{@code dstBegin} is negative
* <li>the {@code srcBegin} argument is greater than
* the {@code srcEnd} argument.
* <li>{@code srcEnd} is greater than
* {@code this.length()}.
* <li>{@code dstBegin+srcEnd-srcBegin} is greater than
* {@code dst.length}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have . at the end of each case. Now it's inconsistent

* </ul>
* @throws NullPointerException if {@code dst} is {@code null}
*
* @implSpec
* The default implementation invokes {@link #charAt(int index)} in a loop
* iterating {@code index} from {@code srcBegin} to {@code srcEnd-1}.
* Concurrent truncation of this character sequence can throw
* {@code IndexOutOfBoundsException}. In this case, some characters, but not
* all, may be already transferred.
*
* @since 25
*/
public default void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) {
Objects.checkFromToIndex(srcBegin, srcEnd, length());
Objects.checkIndex(dstBegin, dst.length - (srcEnd - srcBegin) + 1);
while (srcBegin < srcEnd)
dst[dstBegin++] = charAt(srcBegin++);
}
}
35 changes: 7 additions & 28 deletions src/java.base/share/classes/java/lang/String.java
Original file line number Diff line number Diff line change
Expand Up @@ -1739,35 +1739,14 @@ public int offsetByCodePoints(int index, int codePointOffset) {
}

/**
* Copies characters from this string into the destination character
* array.
* <p>
* The first character to be copied is at index {@code srcBegin};
* the last character to be copied is at index {@code srcEnd-1}
* (thus the total number of characters to be copied is
* {@code srcEnd-srcBegin}). The characters are copied into the
* subarray of {@code dst} starting at index {@code dstBegin}
* and ending at index:
* <blockquote><pre>
* dstBegin + (srcEnd-srcBegin) - 1
* </pre></blockquote>
*
* @param srcBegin index of the first character in the string
* to copy.
* @param srcEnd index after the last character in the string
* to copy.
* @param dst the destination array.
* @param dstBegin the start offset in the destination array.
* @throws IndexOutOfBoundsException If any of the following
* is true:
* <ul><li>{@code srcBegin} is negative.
* <li>{@code srcBegin} is greater than {@code srcEnd}
* <li>{@code srcEnd} is greater than the length of this
* string
* <li>{@code dstBegin} is negative
* <li>{@code dstBegin+(srcEnd-srcBegin)} is larger than
* {@code dst.length}</ul>
* {@inheritDoc CharSequence}
* @param srcBegin {@inheritDoc CharSequence}
* @param srcEnd {@inheritDoc CharSequence}
* @param dst {@inheritDoc CharSequence}
* @param dstBegin {@inheritDoc CharSequence}
* @throws IndexOutOfBoundsException {@inheritDoc CharSequence}
*/
@Override
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) {
checkBoundsBeginEnd(srcBegin, srcEnd, length());
checkBoundsOffCount(dstBegin, srcEnd - srcBegin, dst.length);
Expand Down
5 changes: 1 addition & 4 deletions src/java.base/share/classes/java/lang/StringBuffer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 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
Expand Down Expand Up @@ -279,9 +279,6 @@ public synchronized int offsetByCodePoints(int index, int codePointOffset) {
return super.offsetByCodePoints(index, codePointOffset);
}

/**
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
@Override
public synchronized void getChars(int srcBegin, int srcEnd, char[] dst,
int dstBegin)
Expand Down
40 changes: 39 additions & 1 deletion src/java.base/share/classes/java/nio/X-Buffer.java.template
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
Expand Down Expand Up @@ -1896,6 +1896,44 @@ public abstract sealed class $Type$Buffer

#if[char]

/**
* Absolute bulk <i>get</i> method.
*
* <p> This method transfers {@code srcEnd-srcBegin} characters from this
* buffer into the given array, starting at index {@code srcBegin} in this
* buffer and at offset {@code dstBegin} in the array. The position of this
* buffer is unchanged.
*
* @param srcBegin
* The index in this buffer from which the first character will be
* read; must be non-negative and less than {@code limit()}
*
* @param srcEnd
* The index in this buffer directly before the last character to
* read; must be non-negative and less or equal than {@code limit()}
* and must be greater or equal than {@code srcBegin}
*
* @param dst
* The destination array
*
* @param dstBegin
* The offset within the array of the first character to be
* written; must be non-negative and less than {@code dst.length}
*
* @throws IndexOutOfBoundsException
* If the preconditions on the {@code srcBegin}, {@code srcEnd},
* and {@code dstBegin} parameters do not hold
*
* @implSpec This method is equivalent to
* {@code get(srcBegin, dst, dstBegin, srcEnd - srcBegin)}.
*
* @since 25
*/
@Override
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) {
get(srcBegin, dst, dstBegin, srcEnd - srcBegin);
}

/**
* Returns a string containing the characters in this buffer.
*
Expand Down
109 changes: 109 additions & 0 deletions test/jdk/java/lang/CharSequence/GetChars.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* 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.
*/

import org.testng.Assert;
import org.testng.annotations.Test;

/**
* @test
* @bug 8343110
* @summary Check for expected behavior of default implementation of
* CharSequence.getChars().
* @run testng GetChars
*/
public class GetChars {
private static CharSequence CS = new CharSequence() {
@Override
public int length() {
return 4;
}

@Override
public char charAt(int index) {
return "Test".charAt(index);
}

@Override
public CharSequence subSequence(int start, int end) {
throw new UnsupportedOperationException();
}
};

@Test
public void testExactCopy() {
var dst = new char[4];
CS.getChars(0, 4, dst, 0);
Assert.assertEquals(dst, new char[] {'T', 'e', 's', 't'});
}

@Test
public void testPartialCopy() {
var dst = new char[2];
CS.getChars(1, 3, dst, 0);
Assert.assertEquals(dst, new char[] {'e', 's'});
}

@Test
public void testPositionedCopy() {
var dst = new char[] {1, 2, 3, 4, 5, 6};
CS.getChars(0, 4, dst, 1);
Assert.assertEquals(dst, new char[] {1, 'T', 'e', 's', 't', 6});
}

@Test
public void testSrcBeginIsNegative() {
Assert.assertThrows(IndexOutOfBoundsException.class,
() -> CS.getChars(-1, 3, new char[4], 0));
}

@Test
public void testDstBeginIsNegative() {
Assert.assertThrows(IndexOutOfBoundsException.class,
() -> CS.getChars(0, 4, new char[4], -1));
}

@Test
public void testSrcBeginIsGreaterThanSrcEnd() {
Assert.assertThrows(IndexOutOfBoundsException.class,
() -> CS.getChars(4, 0, new char[4], 0));
}

@Test
public void testSrcEndIsGreaterThanSequenceLength() {
Assert.assertThrows(IndexOutOfBoundsException.class,
() -> CS.getChars(0, 5, new char[4], 0));
}

@Test
public void testRequestedLengthIsGreaterThanDstLength() {
Assert.assertThrows(IndexOutOfBoundsException.class,
() -> CS.getChars(0, 4, new char[3], 0));
}

@Test
public void testDstIsNull() {
Assert.assertThrows(NullPointerException.class,
() -> CS.getChars(0, 4, null, 0));
}

}
Loading