Skip to content

Commit

Permalink
Draft: CharArrayReader
Browse files Browse the repository at this point in the history
  • Loading branch information
mkarg committed Oct 23, 2024
1 parent 97e3144 commit e17d33e
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 2 deletions.
6 changes: 5 additions & 1 deletion src/java.base/share/classes/java/io/CharArrayReader.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 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
Expand Down Expand Up @@ -32,6 +32,10 @@
* This class implements a character buffer that can be used as a
* character-input stream.
*
* @apiNote
* {@link Reader#of(char[])} provides a method to read from a char array
* that may be more efficient than {@code CharArrayReader}.
*
* @author Herb Jellinek
* @since 1.1
*/
Expand Down
160 changes: 160 additions & 0 deletions src/java.base/share/classes/java/io/Reader.java
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,166 @@ public void close() {
};
}

/**
* Returns a {@code Reader} that reads characters from an array of chars.
* The reader is initially open and reading starts at index 0.
*
* <p> The returned reader supports the {@link #mark mark()} and
* {@link #reset reset()} operations.
*
* <p> The resulting reader is not safe for use by multiple
* concurrent threads. If the reader is to be used by more than one
* thread it should be controlled by appropriate synchronization.
*
* <p> If the array content changes while the reader is open, the behavior
* is undefined.
*
* @param ca {@code char[]} providing the character stream (not copied)
* @return a {@code Reader} which reads characters from {@code ca}
* @throws NullPointerException if {@code ca} is {@code null}
*
* @since 24
*/
public static Reader of(char[] ca) {
return Reader.of(ca, 0, ca.length);
}

/**
* Returns a {@code Reader} that reads characters from an array of chars.
* The reader is initially open and reading starts at {@code offset}.
*
* <p> The returned reader supports the {@link #mark mark()} and
* {@link #reset reset()} operations.
*
* <p> The resulting reader is not safe for use by multiple
* concurrent threads. If the reader is to be used by more than one
* thread it should be controlled by appropriate synchronization.
*
* <p> If the array content changes while the reader is open, the behavior
* is undefined.
*
* @param ca {@code char[]} providing the character stream (not copied)
* @param offset Offset of the first char to read
* @param length Number of chars to read
* @return a {@code Reader} which reads characters from {@code ca}
* @throws NullPointerException if {@code ca} is {@code null}
* @throws IllegalArgumentException if {@code offset} is negative or
* greater than {@code ca.length}, or if {@code length} is
* negative, or if the sum of these two values is negative.
*
* @since 24
*/
public static Reader of(final char[] ca, int offset, int length) {
if ((offset < 0) || (offset > ca.length) || (length < 0) ||
((offset + length) < 0)) {
throw new IllegalArgumentException();
}

return new Reader() {
private boolean isClosed;
private int pos = offset;
private int markedPos = offset;
private int count = Math.min(offset + length, ca.length);

/** Checks to make sure that the stream has not been closed */
private void ensureOpen() throws IOException {
if (isClosed)
throw new IOException("Stream closed");
}

@Override
public int read() throws IOException {
ensureOpen();
if (pos >= count)
return -1;
else
return ca[pos++];
}

@Override
public int read(char[] cbuf, int off, int len) throws IOException {
ensureOpen();
Objects.checkFromIndexSize(off, len, cbuf.length);
if (len == 0) {
return 0;
}

if (pos >= count) {
return -1;
}

int avail = count - pos;
if (len > avail) {
len = avail;
}
if (len <= 0) {
return 0;
}
System.arraycopy(ca, pos, cbuf, off, len);
pos += len;
return len;
}

@Override
public int read(CharBuffer target) throws IOException {
ensureOpen();

if (pos >= count) {
return -1;
}

int avail = count - pos;
int len = Math.min(avail, target.remaining());
target.put(ca, pos, len);
pos += len;
return len;
}

@Override
public long skip(long n) throws IOException {
ensureOpen();

long avail = count - pos;
if (n > avail) {
n = avail;
}
if (n < 0) {
return 0;
}
pos += (int) n;
return n;
}

@Override
public boolean ready() throws IOException {
ensureOpen();
return (count - pos) > 0;
}

@Override
public boolean markSupported() {
return true;
}

@Override
public void mark(int readAheadLimit) throws IOException {
ensureOpen();
markedPos = pos;
}

@Override
public void reset() throws IOException {
ensureOpen();
pos = markedPos;
}

@Override
public void close() {
isClosed = true;
}
};
}

/**
* The object used to synchronize operations on this stream. For
* efficiency, a character-stream object may use an object other than
Expand Down
6 changes: 5 additions & 1 deletion test/jdk/java/io/Reader/Of.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*/

import java.io.Reader;
import java.io.CharArrayReader;
import java.io.StringReader;
import java.io.IOException;
import java.io.StringWriter;
Expand Down Expand Up @@ -77,7 +78,10 @@ public String toString() {
// Reader.Of's result SHALL NOT convert to String
throw new UnsupportedOperationException();
}
})
}),
new CharArrayReader(CONTENT.toCharArray()),
Reader.of(CONTENT.toCharArray()),
Reader.of(CONTENT.toCharArray(), 0, CONTENT.length())
};
}

Expand Down

0 comments on commit e17d33e

Please sign in to comment.