8277501: Revisit PathFileObject.getCharContent and friends
Reviewed-by: vromero, jjg
This commit is contained in:
parent
abfb900829
commit
8eb4e7e07e
@ -75,10 +75,12 @@ import com.sun.tools.javac.util.Options;
|
|||||||
* java.io.File or java.nio.file.Path.
|
* java.io.File or java.nio.file.Path.
|
||||||
*/
|
*/
|
||||||
public abstract class BaseFileManager implements JavaFileManager {
|
public abstract class BaseFileManager implements JavaFileManager {
|
||||||
|
|
||||||
|
private static final byte[] EMPTY_ARRAY = new byte[0];
|
||||||
|
|
||||||
@SuppressWarnings("this-escape")
|
@SuppressWarnings("this-escape")
|
||||||
protected BaseFileManager(Charset charset) {
|
protected BaseFileManager(Charset charset) {
|
||||||
this.charset = charset;
|
this.charset = charset;
|
||||||
byteBufferCache = new ByteBufferCache();
|
|
||||||
locations = createLocations();
|
locations = createLocations();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,56 +405,33 @@ public abstract class BaseFileManager implements JavaFileManager {
|
|||||||
|
|
||||||
// <editor-fold defaultstate="collapsed" desc="ByteBuffers">
|
// <editor-fold defaultstate="collapsed" desc="ByteBuffers">
|
||||||
/**
|
/**
|
||||||
* Make a byte buffer from an input stream.
|
* Make a {@link ByteBuffer} from an input stream.
|
||||||
* @param in the stream
|
* @param in the stream
|
||||||
* @return a byte buffer containing the contents of the stream
|
* @return a byte buffer containing the contents of the stream
|
||||||
* @throws IOException if an error occurred while reading the stream
|
* @throws IOException if an error occurred while reading the stream
|
||||||
*/
|
*/
|
||||||
public ByteBuffer makeByteBuffer(InputStream in)
|
public ByteBuffer makeByteBuffer(InputStream in) throws IOException {
|
||||||
throws IOException {
|
byte[] array;
|
||||||
int limit = in.available();
|
synchronized (this) {
|
||||||
if (limit < 1024) limit = 1024;
|
if ((array = byteArrayCache) != null)
|
||||||
ByteBuffer result = byteBufferCache.get(limit);
|
byteArrayCache = null;
|
||||||
int position = 0;
|
else
|
||||||
while (in.available() != 0) {
|
array = EMPTY_ARRAY;
|
||||||
if (position >= limit)
|
|
||||||
// expand buffer
|
|
||||||
result = ByteBuffer.
|
|
||||||
allocate(limit <<= 1).
|
|
||||||
put(result.flip());
|
|
||||||
int count = in.read(result.array(),
|
|
||||||
position,
|
|
||||||
limit - position);
|
|
||||||
if (count < 0) break;
|
|
||||||
result.position(position += count);
|
|
||||||
}
|
}
|
||||||
return result.flip();
|
com.sun.tools.javac.util.ByteBuffer buf = new com.sun.tools.javac.util.ByteBuffer(array);
|
||||||
|
buf.appendStream(in);
|
||||||
|
return buf.asByteBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void recycleByteBuffer(ByteBuffer bb) {
|
public void recycleByteBuffer(ByteBuffer buf) {
|
||||||
byteBufferCache.put(bb);
|
if (buf.hasArray()) {
|
||||||
}
|
synchronized (this) {
|
||||||
|
byteArrayCache = buf.array();
|
||||||
/**
|
}
|
||||||
* A single-element cache of direct byte buffers.
|
|
||||||
*/
|
|
||||||
private static class ByteBufferCache {
|
|
||||||
private ByteBuffer cached;
|
|
||||||
ByteBuffer get(int capacity) {
|
|
||||||
if (capacity < 20480) capacity = 20480;
|
|
||||||
ByteBuffer result =
|
|
||||||
(cached != null && cached.capacity() >= capacity)
|
|
||||||
? cached.clear()
|
|
||||||
: ByteBuffer.allocate(capacity);
|
|
||||||
cached = null;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
void put(ByteBuffer x) {
|
|
||||||
cached = x;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ByteBufferCache byteBufferCache;
|
private byte[] byteArrayCache;
|
||||||
// </editor-fold>
|
// </editor-fold>
|
||||||
|
|
||||||
// <editor-fold defaultstate="collapsed" desc="Content cache">
|
// <editor-fold defaultstate="collapsed" desc="Content cache">
|
||||||
|
@ -2741,7 +2741,9 @@ public class ClassReader {
|
|||||||
try {
|
try {
|
||||||
bp = 0;
|
bp = 0;
|
||||||
buf.reset();
|
buf.reset();
|
||||||
buf.appendStream(c.classfile.openInputStream());
|
try (InputStream input = c.classfile.openInputStream()) {
|
||||||
|
buf.appendStream(input);
|
||||||
|
}
|
||||||
readClassBuffer(c);
|
readClassBuffer(c);
|
||||||
if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) {
|
if (!missingTypeVariables.isEmpty() && !foundTypeVariables.isEmpty()) {
|
||||||
List<Type> missing = missingTypeVariables;
|
List<Type> missing = missingTypeVariables;
|
||||||
|
@ -56,8 +56,13 @@ public class ByteBuffer {
|
|||||||
* of given size.
|
* of given size.
|
||||||
*/
|
*/
|
||||||
public ByteBuffer(int initialSize) {
|
public ByteBuffer(int initialSize) {
|
||||||
elems = new byte[initialSize];
|
this(new byte[initialSize]);
|
||||||
length = 0;
|
}
|
||||||
|
|
||||||
|
/** Create a new byte buffer using the given array for storage.
|
||||||
|
*/
|
||||||
|
public ByteBuffer(byte[] elems) {
|
||||||
|
this.elems = elems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Append byte to this buffer.
|
/** Append byte to this buffer.
|
||||||
@ -147,30 +152,28 @@ public class ByteBuffer {
|
|||||||
appendBytes(name.getByteArray(), name.getByteOffset(), name.getByteLength());
|
appendBytes(name.getByteArray(), name.getByteOffset(), name.getByteLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Append the content of a given input stream, and then close the stream.
|
/** Append the content of the given input stream.
|
||||||
*/
|
*/
|
||||||
public void appendStream(InputStream is) throws IOException {
|
public void appendStream(InputStream input) throws IOException {
|
||||||
try (InputStream input = is) {
|
while (true) {
|
||||||
while (true) {
|
|
||||||
|
|
||||||
// Read another chunk of data, using size hint from available().
|
// Read another chunk of data, using size hint from available().
|
||||||
// If available() is accurate, the array size should be just right.
|
// If available() is accurate, the array size should be just right.
|
||||||
int amountToRead = Math.max(input.available(), 64);
|
int amountToRead = Math.max(input.available(), 64);
|
||||||
elems = ArrayUtils.ensureCapacity(elems, length + amountToRead);
|
elems = ArrayUtils.ensureCapacity(elems, length + amountToRead);
|
||||||
int amountRead = input.read(elems, length, amountToRead);
|
int amountRead = input.read(elems, length, amountToRead);
|
||||||
if (amountRead == -1)
|
if (amountRead == -1)
|
||||||
|
break;
|
||||||
|
length += amountRead;
|
||||||
|
|
||||||
|
// Check for the common case where input.available() returned the
|
||||||
|
// entire remaining input; in that case, avoid an extra array extension.
|
||||||
|
// Note we are guaranteed that elems.length >= length + 1 at this point.
|
||||||
|
if (amountRead == amountToRead) {
|
||||||
|
int byt = input.read();
|
||||||
|
if (byt == -1)
|
||||||
break;
|
break;
|
||||||
length += amountRead;
|
elems[length++] = (byte)byt;
|
||||||
|
|
||||||
// Check for the common case where input.available() returned the
|
|
||||||
// entire remaining input; in that case, avoid an extra array extension.
|
|
||||||
// Note we are guaranteed that elems.length >= length + 1 at this point.
|
|
||||||
if (amountRead == amountToRead) {
|
|
||||||
int byt = input.read();
|
|
||||||
if (byt == -1)
|
|
||||||
break;
|
|
||||||
elems[length++] = (byte)byt;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -292,6 +295,15 @@ public class ByteBuffer {
|
|||||||
throw new UnderflowException(length);
|
throw new UnderflowException(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Create a {@link java.nio.ByteBuffer} view of this instance.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* If this instance is modified, the returned buffer may no longer reflect it.
|
||||||
|
*/
|
||||||
|
public java.nio.ByteBuffer asByteBuffer() {
|
||||||
|
return java.nio.ByteBuffer.wrap(elems, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
// UnderflowException
|
// UnderflowException
|
||||||
|
|
||||||
/** Thrown when trying to read past the end of the buffer.
|
/** Thrown when trying to read past the end of the buffer.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user