An open API service indexing awesome lists of open source software.

https://github.com/DitchOoM/buffer

Kotlin Multiplatform bytebuffer/byte[] wrapper
https://github.com/DitchOoM/buffer

Last synced: 5 months ago
JSON representation

Kotlin Multiplatform bytebuffer/byte[] wrapper

Awesome Lists containing this project

README

        

[![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
[![Stargazers][stars-shield]][stars-url]
[![Issues][issues-shield]][issues-url]
[![MIT License][license-shield]][license-url]
[![LinkedIn][linkedin-shield]][linkedin-url]




ByteBuffer


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



  1. About The Project



  2. Installation


  3. Usage



  4. Building Locally

  5. Getting Started

  6. Roadmap

  7. Contributing

  8. License

## About The Project

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][byte-buffer-api] 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.

### Runtime Dependencies

* None

### [Supported Platforms](https://kotlinlang.org/docs/reference/mpp-supported-platforms.html)

* All Kotlin Multiplatform supported OS's.

| Platform | Wrapped Type |
|:------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
| `JVM` 1.8 | [ByteBuffer](https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/nio/ByteBuffer.html) |
| `Node.js` | [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) including SharedArrayBuffer |
| `Browser` (Chrome) | [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) including SharedArrayBuffer |
| `Android` | [ByteBuffer](https://developer.android.com/reference/java/nio/ByteBuffer) including [SharedMemory](https://developer.android.com/reference/android/os/SharedMemory) |
| `iOS` | [NSData](https://developer.apple.com/documentation/foundation/nsdata?language=objc) |
| `WatchOS` | [NSData](https://developer.apple.com/documentation/foundation/nsdata?language=objc) |
| `TvOS` | [NSData](https://developer.apple.com/documentation/foundation/nsdata?language=objc) |
| `MacOS` | [NSData](https://developer.apple.com/documentation/foundation/nsdata?language=objc) |
| `Linux X64` | kotlin ByteArray |
| `Windows X64` | TODO |

## Installation

### Gradle

- [Add `implementation("com.ditchoom:buffer:$version")` to your `build.gradle` dependencies](https://search.maven.org/artifact/com.ditchoom/buffer)

## Usage

### Allocate a new platform agnostic buffer

```kotlin
val buffer = PlatformBuffer.allocate(
byteSize,
zone = AllocationZone.Direct,
byteOrder = ByteOrder.BIG_ENDIAN
)
```

### Wrap an existing byte array into a platform agnostic buffer

```kotlin
val byteArray = byteArrayOf(1, 2, 3, 4, 5)
val buffer = PlatformBuffer.wrap(byteArray, byteOrder = ByteOrder.BIG_ENDIAN)
```

### Allocation Zones

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
array
- `AllocationZone.Direct` -> On JVM platforms, allocates a DirectByteBuffer, otherwise a native byte
array
- `AllocationZone.SharedMemory` -> On JS Platforms this will populate the `sharedArrayBuffer` parameter in `JsBuffer`.
On API 27+ it allocates
a [Shared Memory](https://developer.android.com/reference/android/os/SharedMemory) instance,
otherwise will pipe the data during parcel using ParcelFileDescriptor and java.nio.Channel api. For `JS` platforms it
will allocate
a [`SharedArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer).
If the
proper [security requirements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements)
are not set, it will fallback to a standard `ArrayBuffer`.

> **Android**: All `JvmBuffer`s are `Parcelable`. To avoid extra memory copies when using IPC, always choose `AllocationZone.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 the `src` directory containing:
>```
>if (config.devServer != null) {
> config.devServer.headers = {
> "Cross-Origin-Opener-Policy": "same-origin",
> "Cross-Origin-Embedder-Policy": "require-corp"
> }
>}
>```

### Byte order

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`

### Relative write data into platform agnostic buffer

```kotlin
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)
```

### Absolute write data into platform agnostic buffer

```kotlin
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
```

### Relative read data into platform agnostic buffer

```kotlin
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)
```

### Absolute read data into platform agnostic buffer

```kotlin
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()
```

## Building Locally

- `git clone [email protected]:DitchOoM/buffer.git`
- Open cloned directory with [Intellij IDEA](https://www.jetbrains.com/idea/download).
- Be sure
to [open with gradle](https://www.jetbrains.com/help/idea/gradle.html#gradle_import_project_start)

## Roadmap

See the [open issues](https://github.com/DitchOoM/buffer/issues) for a list of proposed features (
and known issues).

## Contributing

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**.

1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

## License

Distributed under the Apache 2.0 License. See `LICENSE` for more information.

[contributors-shield]: https://img.shields.io/github/contributors/DitchOoM/buffer.svg?style=for-the-badge

[contributors-url]: https://github.com/DitchOoM/buffer/graphs/contributors

[forks-shield]: https://img.shields.io/github/forks/DitchOoM/buffer.svg?style=for-the-badge

[forks-url]: https://github.com/DitchOoM/buffer/network/members

[stars-shield]: https://img.shields.io/github/stars/DitchOoM/buffer.svg?style=for-the-badge

[stars-url]: https://github.com/DitchOoM/buffer/stargazers

[issues-shield]: https://img.shields.io/github/issues/DitchOoM/buffer.svg?style=for-the-badge

[issues-url]: https://github.com/DitchOoM/buffer/issues

[license-shield]: https://img.shields.io/github/license/DitchOoM/buffer.svg?style=for-the-badge

[license-url]: https://github.com/DitchOoM/buffer/blob/master/LICENSE.md

[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555

[linkedin-url]: https://www.linkedin.com/in/thebehera

[byte-buffer-api]: https://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html

[maven-central]: https://search.maven.org/search?q=com.ditchoom

[npm]: https://www.npmjs.com/search?q=ditchoom-buffer

[cocoapods]: https://cocoapods.org/pods/DitchOoM-buffer

[apt]: https://packages.ubuntu.com/search?keywords=ditchoom&searchon=names&suite=groovy&section=all

[yum]: https://pkgs.org/search/?q=DitchOoM-buffer

[chocolately]: https://chocolatey.org/packages?q=DitchOoM-buffer