A kotlin multiplatform library that allows you to allocate and modify byte[] natively using an API similar to Java's ByteBuffer API.
Report Bug
·
Request Feature
Table of Contents
Allocating and managing a chunk of memory can be slightly different based on each platform. This project aims to make it easier to manage buffers in a cross platform way using kotlin multiplatform. This was originally created as a side project for a kotlin multiplatform mqtt data sync solution.
Implementation notes:
JVM
+Android
delegate to direct ByteBuffers to avoid memory copies when possible.- Apple targets use NSData or NSMutableData
JS
targets use Uint8Array.Native
platforms use standard byte arrays to manage memory.
- None
- All Kotlin Multiplatform supported OS's.
Platform | Wrapped Type |
---|---|
JVM 1.8 |
ByteBuffer |
Node.js |
Uint8Array including SharedArrayBuffer |
Browser (Chrome) |
Uint8Array including SharedArrayBuffer |
Android |
ByteBuffer including SharedMemory |
iOS |
NSData |
WatchOS |
NSData |
TvOS |
NSData |
MacOS |
NSData |
Linux X64 |
kotlin ByteArray |
Windows X64 |
TODO |
val buffer = PlatformBuffer.allocate(
byteSize,
zone = AllocationZone.Direct,
byteOrder = ByteOrder.BIG_ENDIAN
)
val byteArray = byteArrayOf(1, 2, 3, 4, 5)
val buffer = PlatformBuffer.wrap(byteArray, byteOrder = ByteOrder.BIG_ENDIAN)
Allocation zones allow you to change where the buffer is allocated.
AllocationZone.Custom
-> Allows you to override the underlying buffer. This can be helpful for memory mapped structures.AllocationZone.Heap
-> On JVM platforms, allocates a HeapByteBuffer, otherwise a native byte arrayAllocationZone.Direct
-> On JVM platforms, allocates a DirectByteBuffer, otherwise a native byte arrayAllocationZone.SharedMemory
-> On JS Platforms this will populate thesharedArrayBuffer
parameter inJsBuffer
. On API 27+ it allocates a Shared Memory instance, otherwise will pipe the data during parcel using ParcelFileDescriptor and java.nio.Channel api. ForJS
platforms it will allocate aSharedArrayBuffer
. If the proper security requirements are not set, it will fallback to a standardArrayBuffer
.
Android: All
JvmBuffer
s areParcelable
. To avoid extra memory copies when using IPC, always chooseAllocationZone.SharedMemory
.
Browser JS: To enable SharedArrayBuffer, add the appropriate headers for the JS server in a gradle project by adding any file to a directory
webpack.config.d
next to thesrc
directory containing:if (config.devServer != null) { config.devServer.headers = { "Cross-Origin-Opener-Policy": "same-origin", "Cross-Origin-Embedder-Policy": "require-corp" } }
Byte order defaults to big endian but can be specified when creating the buffer
with ByteOrder.BIG_ENDIAN
or ByteOrder.LITTLE_ENDIAN
The byte order of a buffer can be checked with buffer.byteOrder
val buffer: WriteBuffer
// write signed byte
buffer.writeByte(5.toByte())
// write unsigned byte
buffer.writeUByte(5.toUByte())
// write short
buffer.writeShort(5.toShort())
// write unsigned short
buffer.writeUShort(5.toUShort())
// write int
buffer.writeInt(5)
// write unsigned int
buffer.writeUInt(5.toUInt())
// write long
buffer.writeLong(5L)
// write unsigned long
buffer.writeULong(5uL)
// write float
buffer.writeFloat(123.456f)
// write double
buffer.writeDouble(123.456)
// write text
buffer.writeString("5", Charset.UTF8)
// copy buffer into this one
buffer.write(otherBuffer)
// write byte array
buffer.writeBytes(byteArrayOf(1, 2, 3, 4))
// write partial byte array
buffer.writeBytes(byteArrayOf(1, 2, 3, 4, 5), offset, length)
val buffer: WriteBuffer
// set signed byte
buffer[index] = 5.toByte()
// set unsigned byte
buffer[index] = 5.toUByte()
// set short
buffer[index] = 5.toByte()
// set unsigned short
buffer[index] = 5.toUShort()
// set int
buffer[index] = 5
// set unsigned int
buffer[index] = 5.toUInt()
// set long
buffer[index] = 5L
// set unsigned long
buffer[index] = 5uL
// set float
buffer[index] = 123.456f
// set double
buffer[index] = 123.456
val buffer: ReadBuffer
// read signed byte
val b = buffer.readByte()
// read unsigned byte
val uByte = buffer.readUnsignedByte()
// read short
val short = buffer.readShort()
// read unsigned short
val uShort = buffer.readUnsignedShort()
// read int
val intValue = buffer.readInt()
// read unsigned int
val uIntValue = buffer.readUnsignedInt()
// read long
val longValue = buffer.readLong()
// read unsigned long
val uLongValue = buffer.readUnsignedLong()
// read float
val float = buffer.readFloat()
// read double
val double = buffer.readDouble()
// read text
val string = buffer.readUtf8(numOfBytesToRead)
// read byte array
val byteArray = buffer.readByteArray(numOfBytesToRead)
// read a shared subsequence read buffer (changes to the original reflect here)
val readBuffer = buffer.readBytes(numOfBytesForBuffer)
val buffer: ReadBuffer
// get signed byte
val b = buffer.get(index) // or buffer[index]
// get unsigned byte
val uByte = buffer.getUnsignedByte(index)
// get short
val short = buffer.getShort(index)
// get unsigned short
val uShort = buffer.getUnsignedShort(index)
// get int
val intValue = buffer.getInt(index)
// get unsigned int
val uIntValue = buffer.getUnsignedInt(index)
// get long
val longValue = buffer.getLong(index)
// get unsigned long
val uLongValue = buffer.getUnsignedLong(index)
// get float
val float = buffer.getFloat(index)
// get double
val double = buffer.getDouble(index)
// slice the buffer without adjusting the position or limit (changes to the original reflect here)
val slicedBuffer = buffer.slice()
git clone [email protected]:DitchOoM/buffer.git
- Open cloned directory with Intellij IDEA.
- Be sure to open with gradle
See the open issues for a list of proposed features ( and known issues).
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the Apache 2.0 License. See LICENSE
for more information.