Class ByteBufferKaitaiStream
- java.lang.Object
-
- io.kaitai.struct.KaitaiStream
-
- io.kaitai.struct.ByteBufferKaitaiStream
-
- All Implemented Interfaces:
Closeable,AutoCloseable
public class ByteBufferKaitaiStream extends KaitaiStream
An implementation ofKaitaiStreambacked by aByteBuffer. Any underlying implementation of ByteBuffer can be used, for example:- ByteBuffer returned as result of
ByteBuffer.wrap(byte[], int, int), wrapping a byte array into a buffer. MappedByteBufferbacked byFileChannel
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from class io.kaitai.struct.KaitaiStream
KaitaiStream.KaitaiStructError, KaitaiStream.UndecidedEndiannessError, KaitaiStream.UnexpectedDataError, KaitaiStream.ValidationExprError, KaitaiStream.ValidationFailedError, KaitaiStream.ValidationGreaterThanError, KaitaiStream.ValidationLessThanError, KaitaiStream.ValidationNotAnyOfError, KaitaiStream.ValidationNotEqualError, KaitaiStream.WriteBackHandler
-
-
Field Summary
-
Fields inherited from class io.kaitai.struct.KaitaiStream
bits, bitsLe, bitsLeft, bitsWriteMode, childStreams, writeBackHandler
-
-
Constructor Summary
Constructors Constructor Description ByteBufferKaitaiStream(byte[] arr)Initializes a stream that will get data from the given array on read and put data into the array on write.ByteBufferKaitaiStream(long size)Initializes a stream that will write data into a fixed byte buffer in memory.ByteBufferKaitaiStream(String fileName)Initializes a stream, reading from a local file with specifiedfileName.ByteBufferKaitaiStream(ByteBuffer buffer)Initializes a stream that will get data from givenByteBufferon read and put data into it on write.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description ByteBufferasRoBuffer()Provide a read-only version of theByteBufferbacking the data of this instance.voidclose()Closes the stream safely, writing the buffered bits to the underlying byte stream first (if applicable).booleanisEof()Check if stream pointer is at the end of stream.intpos()Get current position of a stream pointer.byte[]readBytesFull()Reads all the remaining bytes in a stream as byte array.protected byte[]readBytesNotAligned(long n)Internal method to read the specified number of bytes from the stream.byte[]readBytesTerm(byte term, boolean includeTerm, boolean consumeTerm, boolean eosError)floatreadF4be()floatreadF4le()doublereadF8be()doublereadF8le()bytereadS1()Reads one signed 1-byte integer, returning it properly as Java's "byte" type.shortreadS2be()shortreadS2le()intreadS4be()intreadS4le()longreadS8be()longreadS8le()intreadU1()intreadU2be()intreadU2le()longreadU4be()longreadU4le()voidseek(int newPos)Set stream pointer to designated position (int).voidseek(long newPos)Set stream pointer to designated position (long).longsize()Get total size of the stream in bytes.KaitaiStreamsubstream(long n)Reserves next `n` bytes from current stream as a KaitaiStream-compatible substream.protected voidwriteBytesNotAligned(byte[] buf)Internal method to write the given byte array to the stream.voidwriteF4be(float v)voidwriteF4le(float v)voidwriteF8be(double v)voidwriteF8le(double v)voidwriteS1(byte v)Writes one signed 1-byte integer.voidwriteS2be(short v)voidwriteS2le(short v)voidwriteS4be(int v)voidwriteS4le(int v)voidwriteS8be(long v)voidwriteS8le(long v)-
Methods inherited from class io.kaitai.struct.KaitaiStream
addChildStream, alignToByte, byteArrayCompare, byteArrayIndexOf, byteArrayMax, byteArrayMin, bytesStripRight, bytesTerminate, ensureBytesLeftToWrite, ensureFixedContents, mod, mod, processRotateLeft, processXor, processXor, processZlib, readBitsInt, readBitsIntBe, readBitsIntLe, readBytes, readU8be, readU8le, setWriteBackHandler, toByteArray, toByteArrayLength, unprocessZlib, writeAlignToByte, writeBack, writeBackChildStreams, writeBackChildStreams, writeBitsIntBe, writeBitsIntLe, writeBytes, writeBytesLimit, writeStream, writeU1, writeU2be, writeU2le, writeU4be, writeU4le, writeU8be, writeU8le
-
-
-
-
Constructor Detail
-
ByteBufferKaitaiStream
public ByteBufferKaitaiStream(String fileName) throws IOException
Initializes a stream, reading from a local file with specifiedfileName. Internally,FileChannel+MappedByteBufferwill 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 the given array on read and put data into the array on write. Internally, aByteBufferis used to wrap the given array.- Parameters:
arr- byte array to read from or write to
-
ByteBufferKaitaiStream
public ByteBufferKaitaiStream(ByteBuffer buffer)
Initializes a stream that will get data from givenByteBufferon read and put data into it on write.- Parameters:
buffer-ByteBufferto read from or write to
-
ByteBufferKaitaiStream
public ByteBufferKaitaiStream(long size)
Initializes a stream that will write data into a fixed byte buffer in memory.- Parameters:
size- size of buffer in bytes
-
-
Method Detail
-
asRoBuffer
public ByteBuffer asRoBuffer()
Provide a read-only version of theByteBufferbacking 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
ByteBuffermight contain the data of all parent types and such as well and not only the one the caller is actually interested in.The returned
ByteBufferis 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
ByteBufferto access raw data for the associated type.
-
close
public void close() throws IOExceptionCloses the stream safely, writing the buffered bits to the underlying byte stream first (if applicable). If there was an open file associated with the stream, closes that file.If the last read/write/seek operation in the stream was
KaitaiStream.writeBitsIntBe(int, long)orKaitaiStream.writeBitsIntLe(int, long)and the stream ended at an unaligned bit position (i.e. not at a byte boundary), writes a final byte with buffered bits to the underlying stream before closing the stream.Regardless of whether the closure is successful or not, always relinquishes the underlying resources. In accordance with
Closeable.close(), subsequent calls have no effect. Once this method has been called, read and write operations, seeking or accessing the state usingpos(),size()orisEof()on this stream will typically throw aNullPointerException.- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable- Specified by:
closein classKaitaiStream- Implementation Note:
Unfortunately, there is no simple way to close memory-mapped
ByteBufferin Java and unmap underlying file. AsMappedByteBufferdocumentation 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 subsequentread..methods withNullPointerException. Afterwards, a call toSystem.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: How to unmap a file from memory mapped using FileChannel in java?
- Throws:
IOException- ifFileChannelcan't be closed
-
isEof
public boolean isEof()
Description copied from class:KaitaiStreamCheck if stream pointer is at the end of stream.- Specified by:
isEofin classKaitaiStream- Returns:
- true if we are located at the end of the stream
-
seek
public void seek(int newPos)
Description copied from class:KaitaiStreamSet stream pointer to designated position (int).- Specified by:
seekin classKaitaiStream- Parameters:
newPos- new position (offset in bytes from the beginning of the stream)
-
seek
public void seek(long newPos)
Description copied from class:KaitaiStreamSet stream pointer to designated position (long).- Specified by:
seekin classKaitaiStream- Parameters:
newPos- new position (offset in bytes from the beginning of the stream)
-
pos
public int pos()
Description copied from class:KaitaiStreamGet current position of a stream pointer.- Specified by:
posin classKaitaiStream- Returns:
- pointer position, number of bytes from the beginning of the stream
-
size
public long size()
Description copied from class:KaitaiStreamGet total size of the stream in bytes.- Specified by:
sizein classKaitaiStream- 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:
readS1in classKaitaiStream- Returns:
- 1-byte integer read from a stream
-
readS2be
public short readS2be()
- Specified by:
readS2bein classKaitaiStream
-
readS4be
public int readS4be()
- Specified by:
readS4bein classKaitaiStream
-
readS8be
public long readS8be()
- Specified by:
readS8bein classKaitaiStream
-
readS2le
public short readS2le()
- Specified by:
readS2lein classKaitaiStream
-
readS4le
public int readS4le()
- Specified by:
readS4lein classKaitaiStream
-
readS8le
public long readS8le()
- Specified by:
readS8lein classKaitaiStream
-
readU1
public int readU1()
- Specified by:
readU1in classKaitaiStream
-
readU2be
public int readU2be()
- Specified by:
readU2bein classKaitaiStream
-
readU4be
public long readU4be()
- Specified by:
readU4bein classKaitaiStream
-
readU2le
public int readU2le()
- Specified by:
readU2lein classKaitaiStream
-
readU4le
public long readU4le()
- Specified by:
readU4lein classKaitaiStream
-
readF4be
public float readF4be()
- Specified by:
readF4bein classKaitaiStream
-
readF8be
public double readF8be()
- Specified by:
readF8bein classKaitaiStream
-
readF4le
public float readF4le()
- Specified by:
readF4lein classKaitaiStream
-
readF8le
public double readF8le()
- Specified by:
readF8lein classKaitaiStream
-
readBytesNotAligned
protected byte[] readBytesNotAligned(long n)
Description copied from class:KaitaiStreamInternal method to read the specified number of bytes from the stream. UnlikeKaitaiStream.readBytes(long), it doesn't align the bit position to the next byte boundary.- Specified by:
readBytesNotAlignedin classKaitaiStream- Parameters:
n- number of bytes to read- Returns:
- read bytes as a byte array
-
readBytesFull
public byte[] readBytesFull()
Reads all the remaining bytes in a stream as byte array.- Specified by:
readBytesFullin classKaitaiStream- Returns:
- all remaining bytes in a stream as byte array
-
readBytesTerm
public byte[] readBytesTerm(byte term, boolean includeTerm, boolean consumeTerm, boolean eosError)- Specified by:
readBytesTermin classKaitaiStream
-
substream
public KaitaiStream substream(long n)
Description copied from class:KaitaiStreamReserves next `n` bytes from current stream as a KaitaiStream-compatible substream. Substream has its own pointer and addressing in the range of [0, n) bytes. This stream's pointer is advanced to the position right after this substream.- Specified by:
substreamin classKaitaiStream- Parameters:
n- number of bytes to reserve for a substream- Returns:
- substream covering n bytes from the current position
-
writeS1
public void writeS1(byte v)
Writes one signed 1-byte integer.- Specified by:
writeS1in classKaitaiStream
-
writeS2be
public void writeS2be(short v)
- Specified by:
writeS2bein classKaitaiStream
-
writeS4be
public void writeS4be(int v)
- Specified by:
writeS4bein classKaitaiStream
-
writeS8be
public void writeS8be(long v)
- Specified by:
writeS8bein classKaitaiStream
-
writeS2le
public void writeS2le(short v)
- Specified by:
writeS2lein classKaitaiStream
-
writeS4le
public void writeS4le(int v)
- Specified by:
writeS4lein classKaitaiStream
-
writeS8le
public void writeS8le(long v)
- Specified by:
writeS8lein classKaitaiStream
-
writeF4be
public void writeF4be(float v)
- Specified by:
writeF4bein classKaitaiStream
-
writeF8be
public void writeF8be(double v)
- Specified by:
writeF8bein classKaitaiStream
-
writeF4le
public void writeF4le(float v)
- Specified by:
writeF4lein classKaitaiStream
-
writeF8le
public void writeF8le(double v)
- Specified by:
writeF8lein classKaitaiStream
-
writeBytesNotAligned
protected void writeBytesNotAligned(byte[] buf)
Description copied from class:KaitaiStreamInternal method to write the given byte array to the stream. UnlikeKaitaiStream.writeBytes(byte[]), it doesn't align the bit position to the next byte boundary.- Specified by:
writeBytesNotAlignedin classKaitaiStream- Parameters:
buf- byte array to write
-
-