Class ByteBufferKaitaiStream

    • Constructor Detail

      • ByteBufferKaitaiStream

        public ByteBufferKaitaiStream​(String fileName)
                               throws IOException
        Initializes a stream, reading from a local file with specified fileName. Internally, FileChannel + MappedByteBuffer will be used.
        Parameters:
        fileName - file to read
        Throws:
        IOException - if file can't be read
      • ByteBufferKaitaiStream

        public ByteBufferKaitaiStream​(byte[] arr)
        Initializes a stream that will get data from given byte array when read. Internally, ByteBuffer wrapping given array will be used.
        Parameters:
        arr - byte array to read
      • ByteBufferKaitaiStream

        public ByteBufferKaitaiStream​(ByteBuffer buffer)
        Initializes a stream that will get data from given ByteBuffer when read.
        Parameters:
        buffer - ByteBuffer to read
    • Method Detail

      • asRoBuffer

        public ByteBuffer asRoBuffer()
        Provide a read-only version of the ByteBuffer backing the data of this instance.

        This way one can access the underlying raw bytes associated with this structure, but it is important to note that the caller needs to know what this raw data is: Depending on the hierarchy of user types, how the format has been described and how a user type is actually used, it might be that one accesses all data of some format or only a special substream view of it. We can't know currently, so one needs to keep that in mind when authoring a KSY and e.g. use substreams with user types whenever such a type most likely needs to access its underlying raw data. Using a substream in KSY and directly passing some raw data to a user type outside of normal KS parse order is equivalent and will provide the same results. If no substream is used instead, the here provided data might differ depending on the context in which the associated type was parsed, because the underlying ByteBuffer might contain the data of all parent types and such as well and not only the one the caller is actually interested in.

        The returned ByteBuffer is always rewinded to position 0, because this stream was most likely used to parse a type already, in which case the former position would have been at the end of the buffer. Such a position doesn't help a common reading user much and that fact can easily be forgotten, repositioning to another index than the start is pretty easy as well. Rewinding/repositioning doesn't even harm performance in any way.

        Returns:
        read-only ByteBuffer to access raw data for the associated type.
      • close

        public void close()
                   throws IOException
        Closes the stream safely. If there was an open file associated with it, closes that file. For streams that were reading from in-memory array, does nothing.

        Specified by:
        close in interface AutoCloseable
        Specified by:
        close in interface Closeable
        Specified by:
        close in class KaitaiStream
        Implementation Note:
        Unfortunately, there is no simple way to close memory-mapped ByteBuffer in Java and unmap underlying file. As MappedByteBuffer documentation suggests, "mapped byte buffer and the file mapping that it represents remain valid until the buffer itself is garbage-collected". Thus, the best we can do is to delete all references to it, which breaks all subsequent read.. methods with NullPointerException. Afterwards, a call to System.gc() will typically release the mmap, if garbage collection will be triggered.

        There is a JDK-4724038 request for adding unmap method filed at Java bugtracker since 2002, but as of 2018, it is still unresolved.

        A couple of unsafe approaches (such as using JNI, or using reflection to invoke JVM internal APIs) have been suggested and used with some success, but these are either unportable or dangerous (may crash JVM), so we're not using them in this general purpose code.

        For more examples and suggestions, see: https://stackoverflow.com/questions/2972986/how-to-unmap-a-file-from-memory-mapped-using-filechannel-in-java

        Throws:
        IOException - if FileChannel can't be closed
      • isEof

        public boolean isEof()
        Description copied from class: KaitaiStream
        Check if stream pointer is at the end of stream.
        Specified by:
        isEof in class KaitaiStream
        Returns:
        true if we are located at the end of the stream
      • seek

        public void seek​(int newPos)
        Description copied from class: KaitaiStream
        Set stream pointer to designated position (int).
        Specified by:
        seek in class KaitaiStream
        Parameters:
        newPos - new position (offset in bytes from the beginning of the stream)
      • seek

        public void seek​(long newPos)
        Description copied from class: KaitaiStream
        Set stream pointer to designated position (long).
        Specified by:
        seek in class KaitaiStream
        Parameters:
        newPos - new position (offset in bytes from the beginning of the stream)
      • pos

        public int pos()
        Description copied from class: KaitaiStream
        Get current position of a stream pointer.
        Specified by:
        pos in class KaitaiStream
        Returns:
        pointer position, number of bytes from the beginning of the stream
      • size

        public long size()
        Description copied from class: KaitaiStream
        Get total size of the stream in bytes.
        Specified by:
        size in class KaitaiStream
        Returns:
        size of the stream in bytes
      • readS1

        public byte readS1()
        Reads one signed 1-byte integer, returning it properly as Java's "byte" type.
        Specified by:
        readS1 in class KaitaiStream
        Returns:
        1-byte integer read from a stream
      • readBytes

        public byte[] readBytes​(long n)
        Reads designated number of bytes from the stream.
        Specified by:
        readBytes in class KaitaiStream
        Parameters:
        n - number of bytes to read
        Returns:
        read bytes as byte array
      • readBytesFull

        public byte[] readBytesFull()
        Reads all the remaining bytes in a stream as byte array.
        Specified by:
        readBytesFull in class KaitaiStream
        Returns:
        all remaining bytes in a stream as byte array
      • readBytesTerm

        public byte[] readBytesTerm​(int term,
                                    boolean includeTerm,
                                    boolean consumeTerm,
                                    boolean eosError)
        Specified by:
        readBytesTerm in class KaitaiStream