Skip to content

Commit d580b8c

Browse files
committed
Merge master HEAD into openj9-staging
Signed-off-by: J9 Build <[email protected]>
2 parents 26e9b54 + 0b05716 commit d580b8c

File tree

54 files changed

+4293
-100188
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+4293
-100188
lines changed

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

+114-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1996, 2024, 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
@@ -140,6 +140,119 @@ public void close() {
140140
};
141141
}
142142

143+
/**
144+
* Returns a {@code Reader} that reads characters from a
145+
* {@code CharSequence}. The reader is initially open and reading starts at
146+
* the first character in the sequence.
147+
*
148+
* <p> The returned reader supports the {@link #mark mark()} and
149+
* {@link #reset reset()} operations.
150+
*
151+
* <p> The resulting reader is not safe for use by multiple
152+
* concurrent threads. If the reader is to be used by more than one
153+
* thread it should be controlled by appropriate synchronization.
154+
*
155+
* <p> If the sequence changes while the reader is open, e.g. the length
156+
* changes, the behavior is undefined.
157+
*
158+
* @param cs {@code CharSequence} providing the character stream.
159+
* @return a {@code Reader} which reads characters from {@code cs}
160+
* @throws NullPointerException if {@code cs} is {@code null}
161+
*
162+
* @since 24
163+
*/
164+
public static Reader of(final CharSequence cs) {
165+
Objects.requireNonNull(cs);
166+
167+
return new Reader() {
168+
private boolean isClosed;
169+
private int next = 0;
170+
private int mark = 0;
171+
172+
/** Check to make sure that the stream has not been closed */
173+
private void ensureOpen() throws IOException {
174+
if (isClosed)
175+
throw new IOException("Stream closed");
176+
}
177+
178+
@Override
179+
public int read() throws IOException {
180+
ensureOpen();
181+
if (next >= cs.length())
182+
return -1;
183+
return cs.charAt(next++);
184+
}
185+
186+
@Override
187+
public int read(char[] cbuf, int off, int len) throws IOException {
188+
ensureOpen();
189+
Objects.checkFromIndexSize(off, len, cbuf.length);
190+
if (len == 0) {
191+
return 0;
192+
}
193+
int length = cs.length();
194+
if (next >= length)
195+
return -1;
196+
int n = Math.min(length - next, len);
197+
switch (cs) {
198+
case String s -> s.getChars(next, next + n, cbuf, off);
199+
case StringBuilder sb -> sb.getChars(next, next + n, cbuf, off);
200+
case StringBuffer sb -> sb.getChars(next, next + n, cbuf, off);
201+
case CharBuffer cb -> cb.get(next, cbuf, off, n);
202+
default -> {
203+
for (int i = 0; i < n; i++)
204+
cbuf[off + i] = cs.charAt(next + i);
205+
}
206+
}
207+
next += n;
208+
return n;
209+
}
210+
211+
@Override
212+
public long skip(long n) throws IOException {
213+
ensureOpen();
214+
if (next >= cs.length())
215+
return 0;
216+
// Bound skip by beginning and end of the source
217+
long r = Math.min(cs.length() - next, n);
218+
r = Math.max(-next, r);
219+
next += (int)r;
220+
return r;
221+
}
222+
223+
@Override
224+
public boolean ready() throws IOException {
225+
ensureOpen();
226+
return true;
227+
}
228+
229+
@Override
230+
public boolean markSupported() {
231+
return true;
232+
}
233+
234+
@Override
235+
public void mark(int readAheadLimit) throws IOException {
236+
if (readAheadLimit < 0){
237+
throw new IllegalArgumentException("Read-ahead limit < 0");
238+
}
239+
ensureOpen();
240+
mark = next;
241+
}
242+
243+
@Override
244+
public void reset() throws IOException {
245+
ensureOpen();
246+
next = mark;
247+
}
248+
249+
@Override
250+
public void close() {
251+
isClosed = true;
252+
}
253+
};
254+
}
255+
143256
/**
144257
* The object used to synchronize operations on this stream. For
145258
* efficiency, a character-stream object may use an object other than

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

+18-46
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1996, 2024, 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
@@ -30,31 +30,25 @@
3030
/**
3131
* A character stream whose source is a string.
3232
*
33+
* @apiNote
34+
* {@link Reader#of(CharSequence)} provides a method to read from any
35+
* {@link CharSequence} that may be more efficient than {@code StringReader}.
36+
*
3337
* @author Mark Reinhold
3438
* @since 1.1
3539
*/
3640

3741
public class StringReader extends Reader {
3842

39-
private final int length;
40-
private String str;
41-
private int next = 0;
42-
private int mark = 0;
43+
private final Reader r;
4344

4445
/**
4546
* Creates a new string reader.
4647
*
4748
* @param s String providing the character stream.
4849
*/
4950
public StringReader(String s) {
50-
this.length = s.length();
51-
this.str = s;
52-
}
53-
54-
/** Check to make sure that the stream has not been closed */
55-
private void ensureOpen() throws IOException {
56-
if (str == null)
57-
throw new IOException("Stream closed");
51+
r = Reader.of(s);
5852
}
5953

6054
/**
@@ -67,10 +61,7 @@ private void ensureOpen() throws IOException {
6761
*/
6862
public int read() throws IOException {
6963
synchronized (lock) {
70-
ensureOpen();
71-
if (next >= length)
72-
return -1;
73-
return str.charAt(next++);
64+
return r.read();
7465
}
7566
}
7667

@@ -94,17 +85,7 @@ public int read() throws IOException {
9485
*/
9586
public int read(char[] cbuf, int off, int len) throws IOException {
9687
synchronized (lock) {
97-
ensureOpen();
98-
Objects.checkFromIndexSize(off, len, cbuf.length);
99-
if (len == 0) {
100-
return 0;
101-
}
102-
if (next >= length)
103-
return -1;
104-
int n = Math.min(length - next, len);
105-
str.getChars(next, next + n, cbuf, off);
106-
next += n;
107-
return n;
88+
return r.read(cbuf, off, len);
10889
}
10990
}
11091

@@ -130,14 +111,7 @@ public int read(char[] cbuf, int off, int len) throws IOException {
130111
*/
131112
public long skip(long n) throws IOException {
132113
synchronized (lock) {
133-
ensureOpen();
134-
if (next >= length)
135-
return 0;
136-
// Bound skip by beginning and end of the source
137-
long r = Math.min(length - next, n);
138-
r = Math.max(-next, r);
139-
next += (int)r;
140-
return r;
114+
return r.skip(n);
141115
}
142116
}
143117

@@ -150,8 +124,7 @@ public long skip(long n) throws IOException {
150124
*/
151125
public boolean ready() throws IOException {
152126
synchronized (lock) {
153-
ensureOpen();
154-
return true;
127+
return r.ready();
155128
}
156129
}
157130

@@ -176,12 +149,8 @@ public boolean markSupported() {
176149
* @throws IOException If an I/O error occurs
177150
*/
178151
public void mark(int readAheadLimit) throws IOException {
179-
if (readAheadLimit < 0){
180-
throw new IllegalArgumentException("Read-ahead limit < 0");
181-
}
182152
synchronized (lock) {
183-
ensureOpen();
184-
mark = next;
153+
r.mark(readAheadLimit);
185154
}
186155
}
187156

@@ -193,8 +162,7 @@ public void mark(int readAheadLimit) throws IOException {
193162
*/
194163
public void reset() throws IOException {
195164
synchronized (lock) {
196-
ensureOpen();
197-
next = mark;
165+
r.reset();
198166
}
199167
}
200168

@@ -207,7 +175,11 @@ public void reset() throws IOException {
207175
*/
208176
public void close() {
209177
synchronized (lock) {
210-
str = null;
178+
try {
179+
r.close();
180+
} catch (IOException e) {
181+
throw new UncheckedIOException(e);
182+
}
211183
}
212184
}
213185
}

0 commit comments

Comments
 (0)