Class ClassfileReader
- java.lang.Object
-
- nonapi.io.github.classgraph.fileslice.reader.ClassfileReader
-
- All Implemented Interfaces:
java.io.Closeable
,java.lang.AutoCloseable
,RandomAccessReader
,SequentialReader
public class ClassfileReader extends java.lang.Object implements RandomAccessReader, SequentialReader, java.io.Closeable
ASlice
reader that works as either aRandomAccessReader
or aSequentialReader
. The file is buffered up to the point it has been read so far. Reads in big endian order, as required by the classfile format.
-
-
Field Summary
Fields Modifier and Type Field Description private byte[]
arr
Buffer.private int
arrUsed
The number of bytes used in arr.private static int
BUF_CHUNK_SIZE
Read this many bytes each time there is a buffer underrun.private int
classfileLengthHint
The length of the classfile if known (because it is not deflated), or -1 if unknown (because it is deflated).private int
currIdx
The current read index within the slice.private java.io.InputStream
inflaterInputStream
If slice is deflated, a wrapper forInflateInputStream
.private static int
INITIAL_BUF_SIZE
Initial buffer size.private RandomAccessReader
randomAccessReader
If slice is not deflated, aRandomAccessReader
for either theArraySlice
orFileSlice
concrete subclass.private Resource
resourceToClose
The underlying resource to close whenclose()
is called.
-
Constructor Summary
Constructors Constructor Description ClassfileReader(java.io.InputStream inputStream, Resource resourceToClose)
Constructor for reader of moduleInputStream
(which is not deflated).ClassfileReader(Slice slice, Resource resourceToClose)
Constructor.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description byte[]
buf()
Buf.void
bufferTo(int numBytes)
Ensure that the given number of bytes have been read into the buffer from the beginning of the slice.void
close()
int
currPos()
Curr pos.int
read(long srcOffset, byte[] dstArr, int dstArrStart, int numBytes)
Read bytes into a byte array.int
read(long srcOffset, java.nio.ByteBuffer dstBuf, int dstBufStart, int numBytes)
Read bytes into aByteBuffer
.byte
readByte()
Read a byte at the current cursor position.byte
readByte(long offset)
Read a byte at a specific offset (without changing the current cursor offset).int
readInt()
Read a int at the current cursor position.int
readInt(long offset)
Read a int at a specific offset (without changing the current cursor offset).long
readLong()
Read a long at the current cursor position.long
readLong(long offset)
Read a long at a specific offset (without changing the current cursor offset).short
readShort()
Read a short at the current cursor position.short
readShort(long offset)
Read a short at a specific offset (without changing the current cursor offset).java.lang.String
readString(int numBytes)
Reads the "modified UTF8" format defined in the Java classfile spec.java.lang.String
readString(int numBytes, boolean replaceSlashWithDot, boolean stripLSemicolon)
Reads the "modified UTF8" format defined in the Java classfile spec, optionally replacing '/' with '.', and optionally removing the prefix "L" and the suffix ";".java.lang.String
readString(long offset, int numBytes)
Reads the "modified UTF8" format defined in the Java classfile spec.java.lang.String
readString(long offset, int numBytes, boolean replaceSlashWithDot, boolean stripLSemicolon)
Reads the "modified UTF8" format defined in the Java classfile spec, optionally replacing '/' with '.', and optionally removing the prefix "L" and the suffix ";".private void
readTo(int targetArrUsed)
Called when there is a buffer underrun to ensure there are sufficient bytes available in the array to read the given number of bytes at the given start index.int
readUnsignedByte()
Read an unsigned byte at the current cursor position.int
readUnsignedByte(long offset)
Read an unsigned byte at a specific offset (without changing the current cursor offset).long
readUnsignedInt()
Read a unsigned int at the current cursor position.long
readUnsignedInt(long offset)
Read a unsigned int at a specific offset (without changing the current cursor offset).int
readUnsignedShort()
Read a unsigned short at the current cursor position.int
readUnsignedShort(long offset)
Read a unsigned short at a specific offset (without changing the current cursor offset).void
skip(int bytesToSkip)
Skip the given number of bytes.
-
-
-
Field Detail
-
resourceToClose
private Resource resourceToClose
The underlying resource to close whenclose()
is called.
-
inflaterInputStream
private java.io.InputStream inflaterInputStream
If slice is deflated, a wrapper forInflateInputStream
.
-
randomAccessReader
private RandomAccessReader randomAccessReader
If slice is not deflated, aRandomAccessReader
for either theArraySlice
orFileSlice
concrete subclass.
-
arr
private byte[] arr
Buffer.
-
arrUsed
private int arrUsed
The number of bytes used in arr.
-
currIdx
private int currIdx
The current read index within the slice.
-
classfileLengthHint
private int classfileLengthHint
The length of the classfile if known (because it is not deflated), or -1 if unknown (because it is deflated).
-
INITIAL_BUF_SIZE
private static final int INITIAL_BUF_SIZE
Initial buffer size. For most classfiles, only the first 16-64kb needs to be read (we don't read the bytecodes).- See Also:
- Constant Field Values
-
BUF_CHUNK_SIZE
private static final int BUF_CHUNK_SIZE
Read this many bytes each time there is a buffer underrun. This is smaller than 8k by 8 bytes to prevent the doubling of the array size when the last chunk doesn't quite fit within the 16kb of INITIAL_BUF_SIZE, since the number of bytes that can be requested is up to 8 (for longs). Otherwise we could request to read to (8kb * 2 + 8), which would double the size of the buffer to 32kb, but if we only need to read between 8kb and 16kb, then we unnecessarily copied the buffer content one extra time.- See Also:
- Constant Field Values
-
-
Constructor Detail
-
ClassfileReader
public ClassfileReader(Slice slice, Resource resourceToClose) throws java.io.IOException
Constructor.
-
ClassfileReader
public ClassfileReader(java.io.InputStream inputStream, Resource resourceToClose) throws java.io.IOException
Constructor for reader of moduleInputStream
(which is not deflated).
-
-
Method Detail
-
currPos
public int currPos()
Curr pos.- Returns:
- the current read position.
-
buf
public byte[] buf()
Buf.- Returns:
- the buffer.
-
readTo
private void readTo(int targetArrUsed) throws java.io.IOException
Called when there is a buffer underrun to ensure there are sufficient bytes available in the array to read the given number of bytes at the given start index.- Parameters:
targetArrUsed
- the target value forarrUsed
(i.e. the number of bytes that must be filled in the array)- Throws:
java.io.IOException
- Signals that an I/O exception has occurred.
-
bufferTo
public void bufferTo(int numBytes) throws java.io.IOException
Ensure that the given number of bytes have been read into the buffer from the beginning of the slice.- Parameters:
numBytes
- the number of bytes to ensure have been buffered- Throws:
java.io.IOException
- on EOF or if the bytes could not be read.
-
read
public int read(long srcOffset, byte[] dstArr, int dstArrStart, int numBytes) throws java.io.IOException
Description copied from interface:RandomAccessReader
Read bytes into a byte array.- Specified by:
read
in interfaceRandomAccessReader
- Parameters:
srcOffset
- The offset to start reading from.dstArr
- The byte array to write into.dstArrStart
- The offset within the destination array to start writing at.numBytes
- The number of bytes to read.- Returns:
- The number of bytes actually read, or -1 if no more bytes could be read.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
read
public int read(long srcOffset, java.nio.ByteBuffer dstBuf, int dstBufStart, int numBytes) throws java.io.IOException
Description copied from interface:RandomAccessReader
Read bytes into aByteBuffer
.- Specified by:
read
in interfaceRandomAccessReader
- Parameters:
srcOffset
- The offset to start reading from.dstBuf
- TheByteBuffer
to write into.dstBufStart
- The offset within the destination buffer to start writing at.numBytes
- The number of bytes to read.- Returns:
- The number of bytes actually read, or -1 if no more bytes could be read.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readByte
public byte readByte(long offset) throws java.io.IOException
Description copied from interface:RandomAccessReader
Read a byte at a specific offset (without changing the current cursor offset).- Specified by:
readByte
in interfaceRandomAccessReader
- Parameters:
offset
- The buffer offset to read from.- Returns:
- The byte at the offset.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readUnsignedByte
public int readUnsignedByte(long offset) throws java.io.IOException
Description copied from interface:RandomAccessReader
Read an unsigned byte at a specific offset (without changing the current cursor offset).- Specified by:
readUnsignedByte
in interfaceRandomAccessReader
- Parameters:
offset
- The buffer offset to read from.- Returns:
- The unsigned byte at the offset.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readShort
public short readShort(long offset) throws java.io.IOException
Description copied from interface:RandomAccessReader
Read a short at a specific offset (without changing the current cursor offset).- Specified by:
readShort
in interfaceRandomAccessReader
- Parameters:
offset
- The buffer offset to read from.- Returns:
- The short at the offset.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readUnsignedShort
public int readUnsignedShort(long offset) throws java.io.IOException
Description copied from interface:RandomAccessReader
Read a unsigned short at a specific offset (without changing the current cursor offset).- Specified by:
readUnsignedShort
in interfaceRandomAccessReader
- Parameters:
offset
- The buffer offset to read from.- Returns:
- The unsigned short at the offset.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readInt
public int readInt(long offset) throws java.io.IOException
Description copied from interface:RandomAccessReader
Read a int at a specific offset (without changing the current cursor offset).- Specified by:
readInt
in interfaceRandomAccessReader
- Parameters:
offset
- The buffer offset to read from.- Returns:
- The int at the offset.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readUnsignedInt
public long readUnsignedInt(long offset) throws java.io.IOException
Description copied from interface:RandomAccessReader
Read a unsigned int at a specific offset (without changing the current cursor offset).- Specified by:
readUnsignedInt
in interfaceRandomAccessReader
- Parameters:
offset
- The buffer offset to read from.- Returns:
- The int at the offset, as a long.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readLong
public long readLong(long offset) throws java.io.IOException
Description copied from interface:RandomAccessReader
Read a long at a specific offset (without changing the current cursor offset).- Specified by:
readLong
in interfaceRandomAccessReader
- Parameters:
offset
- The buffer offset to read from.- Returns:
- The long at the offset.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readByte
public byte readByte() throws java.io.IOException
Description copied from interface:SequentialReader
Read a byte at the current cursor position.- Specified by:
readByte
in interfaceSequentialReader
- Returns:
- The byte at the current cursor position.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readUnsignedByte
public int readUnsignedByte() throws java.io.IOException
Description copied from interface:SequentialReader
Read an unsigned byte at the current cursor position.- Specified by:
readUnsignedByte
in interfaceSequentialReader
- Returns:
- The unsigned byte at the current cursor position.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readShort
public short readShort() throws java.io.IOException
Description copied from interface:SequentialReader
Read a short at the current cursor position.- Specified by:
readShort
in interfaceSequentialReader
- Returns:
- The short at the current cursor position.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readUnsignedShort
public int readUnsignedShort() throws java.io.IOException
Description copied from interface:SequentialReader
Read a unsigned short at the current cursor position.- Specified by:
readUnsignedShort
in interfaceSequentialReader
- Returns:
- The unsigned shortat the current cursor position.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readInt
public int readInt() throws java.io.IOException
Description copied from interface:SequentialReader
Read a int at the current cursor position.- Specified by:
readInt
in interfaceSequentialReader
- Returns:
- The int at the current cursor position.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readUnsignedInt
public long readUnsignedInt() throws java.io.IOException
Description copied from interface:SequentialReader
Read a unsigned int at the current cursor position.- Specified by:
readUnsignedInt
in interfaceSequentialReader
- Returns:
- The int at the current cursor position, as a long.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
readLong
public long readLong() throws java.io.IOException
Description copied from interface:SequentialReader
Read a long at the current cursor position.- Specified by:
readLong
in interfaceSequentialReader
- Returns:
- The long at the current cursor position.
- Throws:
java.io.IOException
- If there was an exception while reading.
-
skip
public void skip(int bytesToSkip) throws java.io.IOException
Description copied from interface:SequentialReader
Skip the given number of bytes.- Specified by:
skip
in interfaceSequentialReader
- Parameters:
bytesToSkip
- The number of bytes to skip.- Throws:
java.io.IOException
- If there was an exception while reading.
-
readString
public java.lang.String readString(long offset, int numBytes, boolean replaceSlashWithDot, boolean stripLSemicolon) throws java.io.IOException
Description copied from interface:RandomAccessReader
Reads the "modified UTF8" format defined in the Java classfile spec, optionally replacing '/' with '.', and optionally removing the prefix "L" and the suffix ";".- Specified by:
readString
in interfaceRandomAccessReader
- Parameters:
offset
- The start offset of the string.numBytes
- The number of bytes of the UTF8 encoding of the string.replaceSlashWithDot
- If true, replace '/' with '.'.stripLSemicolon
- If true, string final ';' character.- Returns:
- The string.
- Throws:
java.io.IOException
- If an I/O exception occurs.
-
readString
public java.lang.String readString(int numBytes, boolean replaceSlashWithDot, boolean stripLSemicolon) throws java.io.IOException
Description copied from interface:SequentialReader
Reads the "modified UTF8" format defined in the Java classfile spec, optionally replacing '/' with '.', and optionally removing the prefix "L" and the suffix ";".- Specified by:
readString
in interfaceSequentialReader
- Parameters:
numBytes
- The number of bytes of the UTF8 encoding of the string.replaceSlashWithDot
- If true, replace '/' with '.'.stripLSemicolon
- If true, string final ';' character.- Returns:
- The string.
- Throws:
java.io.IOException
- If an I/O exception occurs.
-
readString
public java.lang.String readString(long offset, int numBytes) throws java.io.IOException
Description copied from interface:RandomAccessReader
Reads the "modified UTF8" format defined in the Java classfile spec.- Specified by:
readString
in interfaceRandomAccessReader
- Parameters:
offset
- The start offset of the string.numBytes
- The number of bytes of the UTF8 encoding of the string.- Returns:
- The string.
- Throws:
java.io.IOException
- If an I/O exception occurs.
-
readString
public java.lang.String readString(int numBytes) throws java.io.IOException
Description copied from interface:SequentialReader
Reads the "modified UTF8" format defined in the Java classfile spec.- Specified by:
readString
in interfaceSequentialReader
- Parameters:
numBytes
- The number of bytes of the UTF8 encoding of the string.- Returns:
- The string.
- Throws:
java.io.IOException
- If an I/O exception occurs.
-
close
public void close()
- Specified by:
close
in interfacejava.lang.AutoCloseable
- Specified by:
close
in interfacejava.io.Closeable
-
-