Class ClassfileReader

java.lang.Object
nonapi.io.github.classgraph.fileslice.reader.ClassfileReader
All Implemented Interfaces:
Closeable, AutoCloseable, RandomAccessReader, SequentialReader

public class ClassfileReader extends Object implements RandomAccessReader, SequentialReader, Closeable
A Slice reader that works as either a RandomAccessReader or a SequentialReader. 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[]
    Buffer.
    private int
    The number of bytes used in arr.
    private static final int
    Read this many bytes each time there is a buffer underrun.
    private int
    The length of the classfile if known (because it is not deflated), or -1 if unknown (because it is deflated).
    private int
    The current read index within the slice.
    private InputStream
    If slice is deflated, a wrapper for
    invalid reference
    InflateInputStream
    .
    private static final int
    Initial buffer size.
    If slice is not deflated, a RandomAccessReader for either the ArraySlice or FileSlice concrete subclass.
    private Resource
    The underlying resource to close when close() is called.
  • Constructor Summary

    Constructors
    Constructor
    Description
    ClassfileReader(InputStream inputStream, Resource resourceToClose)
    Constructor for reader of module InputStream (which is not deflated).
    ClassfileReader(Slice slice, Resource resourceToClose)
    Constructor.
  • Method Summary

    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
     
    int
    Curr pos.
    int
    read(long srcOffset, byte[] dstArr, int dstArrStart, int numBytes)
    Read bytes into a byte array.
    int
    read(long srcOffset, ByteBuffer dstBuf, int dstBufStart, int numBytes)
    Read bytes into a ByteBuffer.
    byte
    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
    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
    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
    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).
    readString(int numBytes)
    Reads the "modified UTF8" format defined in the Java classfile spec.
    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 ";".
    readString(long offset, int numBytes)
    Reads the "modified UTF8" format defined in the Java classfile spec.
    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
    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
    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
    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.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • resourceToClose

      private Resource resourceToClose
      The underlying resource to close when close() is called.
    • inflaterInputStream

      private InputStream inflaterInputStream
      If slice is deflated, a wrapper for
      invalid reference
      InflateInputStream
      .
    • randomAccessReader

      private RandomAccessReader randomAccessReader
      If slice is not deflated, a RandomAccessReader for either the ArraySlice or FileSlice 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:
    • 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:
  • Constructor Details

    • ClassfileReader

      public ClassfileReader(Slice slice, Resource resourceToClose) throws IOException
      Constructor.
      Parameters:
      slice - the Slice to read.
      resourceToClose - the resource to close when close() is called, or null.
      Throws:
      IOException - If an inflater cannot be opened on the Slice.
    • ClassfileReader

      public ClassfileReader(InputStream inputStream, Resource resourceToClose) throws IOException
      Constructor for reader of module InputStream (which is not deflated).
      Parameters:
      inputStream - the InputStream to read from.
      resourceToClose - the underlying resource to close when close() is called, or null.
      Throws:
      IOException - If an inflater cannot be opened on the Slice.
  • Method Details

    • 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 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 for arrUsed (i.e. the number of bytes that must be filled in the array)
      Throws:
      IOException - Signals that an I/O exception has occurred.
    • bufferTo

      public void bufferTo(int numBytes) throws 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:
      IOException - on EOF or if the bytes could not be read.
    • read

      public int read(long srcOffset, byte[] dstArr, int dstArrStart, int numBytes) throws IOException
      Description copied from interface: RandomAccessReader
      Read bytes into a byte array.
      Specified by:
      read in interface RandomAccessReader
      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:
      IOException - If there was an exception while reading.
    • read

      public int read(long srcOffset, ByteBuffer dstBuf, int dstBufStart, int numBytes) throws IOException
      Description copied from interface: RandomAccessReader
      Read bytes into a ByteBuffer.
      Specified by:
      read in interface RandomAccessReader
      Parameters:
      srcOffset - The offset to start reading from.
      dstBuf - The ByteBuffer 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:
      IOException - If there was an exception while reading.
    • readByte

      public byte readByte(long offset) throws IOException
      Description copied from interface: RandomAccessReader
      Read a byte at a specific offset (without changing the current cursor offset).
      Specified by:
      readByte in interface RandomAccessReader
      Parameters:
      offset - The buffer offset to read from.
      Returns:
      The byte at the offset.
      Throws:
      IOException - If there was an exception while reading.
    • readUnsignedByte

      public int readUnsignedByte(long offset) throws IOException
      Description copied from interface: RandomAccessReader
      Read an unsigned byte at a specific offset (without changing the current cursor offset).
      Specified by:
      readUnsignedByte in interface RandomAccessReader
      Parameters:
      offset - The buffer offset to read from.
      Returns:
      The unsigned byte at the offset.
      Throws:
      IOException - If there was an exception while reading.
    • readShort

      public short readShort(long offset) throws IOException
      Description copied from interface: RandomAccessReader
      Read a short at a specific offset (without changing the current cursor offset).
      Specified by:
      readShort in interface RandomAccessReader
      Parameters:
      offset - The buffer offset to read from.
      Returns:
      The short at the offset.
      Throws:
      IOException - If there was an exception while reading.
    • readUnsignedShort

      public int readUnsignedShort(long offset) throws IOException
      Description copied from interface: RandomAccessReader
      Read a unsigned short at a specific offset (without changing the current cursor offset).
      Specified by:
      readUnsignedShort in interface RandomAccessReader
      Parameters:
      offset - The buffer offset to read from.
      Returns:
      The unsigned short at the offset.
      Throws:
      IOException - If there was an exception while reading.
    • readInt

      public int readInt(long offset) throws IOException
      Description copied from interface: RandomAccessReader
      Read a int at a specific offset (without changing the current cursor offset).
      Specified by:
      readInt in interface RandomAccessReader
      Parameters:
      offset - The buffer offset to read from.
      Returns:
      The int at the offset.
      Throws:
      IOException - If there was an exception while reading.
    • readUnsignedInt

      public long readUnsignedInt(long offset) throws IOException
      Description copied from interface: RandomAccessReader
      Read a unsigned int at a specific offset (without changing the current cursor offset).
      Specified by:
      readUnsignedInt in interface RandomAccessReader
      Parameters:
      offset - The buffer offset to read from.
      Returns:
      The int at the offset, as a long.
      Throws:
      IOException - If there was an exception while reading.
    • readLong

      public long readLong(long offset) throws IOException
      Description copied from interface: RandomAccessReader
      Read a long at a specific offset (without changing the current cursor offset).
      Specified by:
      readLong in interface RandomAccessReader
      Parameters:
      offset - The buffer offset to read from.
      Returns:
      The long at the offset.
      Throws:
      IOException - If there was an exception while reading.
    • readByte

      public byte readByte() throws IOException
      Description copied from interface: SequentialReader
      Read a byte at the current cursor position.
      Specified by:
      readByte in interface SequentialReader
      Returns:
      The byte at the current cursor position.
      Throws:
      IOException - If there was an exception while reading.
    • readUnsignedByte

      public int readUnsignedByte() throws IOException
      Description copied from interface: SequentialReader
      Read an unsigned byte at the current cursor position.
      Specified by:
      readUnsignedByte in interface SequentialReader
      Returns:
      The unsigned byte at the current cursor position.
      Throws:
      IOException - If there was an exception while reading.
    • readShort

      public short readShort() throws IOException
      Description copied from interface: SequentialReader
      Read a short at the current cursor position.
      Specified by:
      readShort in interface SequentialReader
      Returns:
      The short at the current cursor position.
      Throws:
      IOException - If there was an exception while reading.
    • readUnsignedShort

      public int readUnsignedShort() throws IOException
      Description copied from interface: SequentialReader
      Read a unsigned short at the current cursor position.
      Specified by:
      readUnsignedShort in interface SequentialReader
      Returns:
      The unsigned shortat the current cursor position.
      Throws:
      IOException - If there was an exception while reading.
    • readInt

      public int readInt() throws IOException
      Description copied from interface: SequentialReader
      Read a int at the current cursor position.
      Specified by:
      readInt in interface SequentialReader
      Returns:
      The int at the current cursor position.
      Throws:
      IOException - If there was an exception while reading.
    • readUnsignedInt

      public long readUnsignedInt() throws IOException
      Description copied from interface: SequentialReader
      Read a unsigned int at the current cursor position.
      Specified by:
      readUnsignedInt in interface SequentialReader
      Returns:
      The int at the current cursor position, as a long.
      Throws:
      IOException - If there was an exception while reading.
    • readLong

      public long readLong() throws IOException
      Description copied from interface: SequentialReader
      Read a long at the current cursor position.
      Specified by:
      readLong in interface SequentialReader
      Returns:
      The long at the current cursor position.
      Throws:
      IOException - If there was an exception while reading.
    • skip

      public void skip(int bytesToSkip) throws IOException
      Description copied from interface: SequentialReader
      Skip the given number of bytes.
      Specified by:
      skip in interface SequentialReader
      Parameters:
      bytesToSkip - The number of bytes to skip.
      Throws:
      IOException - If there was an exception while reading.
    • readString

      public String readString(long offset, int numBytes, boolean replaceSlashWithDot, boolean stripLSemicolon) throws 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 interface RandomAccessReader
      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:
      IOException - If an I/O exception occurs.
    • readString

      public String readString(int numBytes, boolean replaceSlashWithDot, boolean stripLSemicolon) throws 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 interface SequentialReader
      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:
      IOException - If an I/O exception occurs.
    • readString

      public String readString(long offset, int numBytes) throws IOException
      Description copied from interface: RandomAccessReader
      Reads the "modified UTF8" format defined in the Java classfile spec.
      Specified by:
      readString in interface RandomAccessReader
      Parameters:
      offset - The start offset of the string.
      numBytes - The number of bytes of the UTF8 encoding of the string.
      Returns:
      The string.
      Throws:
      IOException - If an I/O exception occurs.
    • readString

      public String readString(int numBytes) throws IOException
      Description copied from interface: SequentialReader
      Reads the "modified UTF8" format defined in the Java classfile spec.
      Specified by:
      readString in interface SequentialReader
      Parameters:
      numBytes - The number of bytes of the UTF8 encoding of the string.
      Returns:
      The string.
      Throws:
      IOException - If an I/O exception occurs.
    • close

      public void close()
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable