Improved buffer copy method and added a copyInto and getStringAscii method. Added clamp to Math.kt.

This commit is contained in:
Daan Vanden Bosch 2021-07-31 21:52:23 +02:00
parent 1341dd76f5
commit 1d87b32986
5 changed files with 125 additions and 6 deletions

View File

@ -14,3 +14,10 @@ fun radToDeg(rad: Double): Double = rad * TO_DEG
* Converts degrees to radians.
*/
fun degToRad(deg: Double): Double = deg * TO_RAD
fun clamp(value: Int, min: Int, max: Int): Int =
when {
value < min -> min
value > max -> max
else -> value
}

View File

@ -50,6 +50,11 @@ expect class Buffer {
*/
fun getFloat(offset: Int): Float
/**
* Reads a ASCII-encoded string at the given offset.
*/
fun getStringAscii(offset: Int, maxByteLength: Int, nullTerminated: Boolean): String
/**
* Reads a UTF-16-encoded string at the given offset.
*/
@ -108,9 +113,17 @@ expect class Buffer {
fun toBase64(): String
/**
* Returns a copy of this buffer of the same size. The copy's capacity will equal its size.
* Returns a copy of this buffer. The copy's capacity will equal its size. If [size] is greater
* than this buffer's size, the remaining bytes will be zeroed out.
*/
fun copy(): Buffer
fun copy(offset: Int = 0, size: Int = this.size): Buffer
fun copyInto(
destination: Buffer,
destinationOffset: Int = 0,
offset: Int = 0,
size: Int = this.size,
)
companion object {
/**

View File

@ -101,4 +101,16 @@ class BufferTests : LibTestSuite {
assertEquals(-9, buf2.getByte(2))
assertEquals(base2, buf2.toBase64())
}
@Test
fun copy() {
val buf = Buffer.fromByteArray(byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
val copy = buf.copy(offset = 3, size = 4)
assertEquals(4, copy.size)
assertEquals(3, copy.getByte(0))
assertEquals(4, copy.getByte(1))
assertEquals(5, copy.getByte(2))
assertEquals(6, copy.getByte(3))
}
}

View File

@ -70,6 +70,23 @@ actual class Buffer private constructor(
return dataView.getFloat32(offset, littleEndian)
}
actual fun getStringAscii(
offset: Int,
maxByteLength: Int,
nullTerminated: Boolean,
): String =
buildString {
for (i in 0 until maxByteLength) {
val codePoint = (getByte(offset + i).toInt() and 0xFF).toChar()
if (nullTerminated && codePoint == '\u0000') {
break
}
append(codePoint)
}
}
actual fun getStringUtf16(
offset: Int,
maxByteLength: Int,
@ -157,8 +174,30 @@ actual class Buffer private constructor(
return self.btoa(str)
}
actual fun copy(): Buffer =
Buffer(arrayBuffer.slice(0, size), size, endianness)
actual fun copy(offset: Int, size: Int): Buffer {
val newBuffer = withSize(size, endianness)
copyInto(newBuffer, destinationOffset = 0, offset, size.coerceAtMost(this.size - offset))
return newBuffer
}
actual fun copyInto(destination: Buffer, destinationOffset: Int, offset: Int, size: Int) {
require(offset >= 0 && offset <= this.size) {
"Offset $offset is out of bounds."
}
require(destinationOffset >= 0 && destinationOffset <= this.size) {
"Destination offset $destinationOffset is out of bounds."
}
require(
size >= 0 &&
destinationOffset + size <= destination.size &&
offset + size <= this.size
) {
"Size $size is out of bounds."
}
Uint8Array(destination.arrayBuffer, destinationOffset)
.set(Uint8Array(arrayBuffer, offset, size))
}
/**
* Checks whether we can read [size] bytes at [offset].

View File

@ -27,6 +27,11 @@ actual class Buffer private constructor(
actual val capacity: Int
get() = buf.capacity()
/**
* The backing byte array. Changes to this array will be reflected by the buffer.
*/
val byteArray: ByteArray get() = buf.array()
init {
this.endianness = endianness
}
@ -66,6 +71,23 @@ actual class Buffer private constructor(
return buf.getFloat(offset)
}
actual fun getStringAscii(
offset: Int,
maxByteLength: Int,
nullTerminated: Boolean,
): String =
buildString {
for (i in 0 until maxByteLength) {
val codePoint = (buf.get(offset + i).toInt() and 0xFF).toChar()
if (nullTerminated && codePoint == '\u0000') {
break
}
append(codePoint)
}
}
actual fun getStringUtf16(
offset: Int,
maxByteLength: Int,
@ -154,8 +176,34 @@ actual class Buffer private constructor(
return str
}
actual fun copy(): Buffer =
fromByteArray(buf.array().copyOf(), endianness)
actual fun copy(offset: Int, size: Int): Buffer {
val newBuffer = withSize(size, endianness)
copyInto(newBuffer, destinationOffset = 0, offset, size.coerceAtMost(this.size - offset))
return newBuffer
}
actual fun copyInto(destination: Buffer, destinationOffset: Int, offset: Int, size: Int) {
require(offset >= 0 && offset <= this.size) {
"Offset $offset is out of bounds."
}
require(destinationOffset >= 0 && destinationOffset <= destination.size) {
"Destination offset $destinationOffset is out of bounds."
}
require(
size >= 0 &&
destinationOffset + size <= destination.size &&
offset + size <= this.size
) {
"Size $size is out of bounds."
}
byteArray.copyInto(
destination.byteArray,
destinationOffset,
startIndex = offset,
endIndex = offset + size,
)
}
/**
* Checks whether we can read [size] bytes at [offset].