From eb8fcc3797606f9da1386cd13e2398fd5ad0b2cf Mon Sep 17 00:00:00 2001 From: soywiz Date: Wed, 27 Sep 2023 01:57:25 +0200 Subject: [PATCH 1/7] Improved Buffer implementation being cleaner and replacing typed arrays --- .../commonMain/kotlin/korlibs/ffi/FFILib.kt | 4 +- .../kotlin/korlibs/image/format/WEBP.kt | 4 +- .../FFIGdiNativeImageFormatProvider.kt | 4 +- .../kotlin/korlibs/wasm/WasmRuntime.kt | 42 +- .../korlibs/wasm/WasmCodeVisitorTest.kt | 6 +- .../commonMain/kotlin/korlibs/math/Math.kt | 3 + .../kotlin/korlibs/memory/Buffer.kt | 504 ++++++++++++------ .../kotlin/korlibs/memory/NBufferTest.kt | 10 +- .../kotlin/korlibs/memory/NBufferTest2.kt | 6 +- .../kotlin/korlibs/memory/BufferNative.kt | 92 ++-- .../jsMain/kotlin/korlibs/memory/Buffer.js.kt | 103 ++++ .../jsMain/kotlin/korlibs/memory/BufferJs.kt | 92 ---- .../kotlin/korlibs/memory/Buffer.jvm.kt | 131 +++++ .../kotlin/korlibs/memory/BufferJvm.kt | 177 ------ .../kotlin/korlibs/memory/Buffer.wasm.kt | 107 ++++ .../kotlin/korlibs/memory/BufferWasm.kt | 93 ---- .../kotlin/korlibs/graphics/gl/AGOpengl.kt | 2 +- .../korlibs/graphics/shader/UniformBlock.kt | 38 +- .../korlibs/graphics/AGUniformBlockTest.kt | 2 +- .../kotlin/korlibs/kgl/KmlGlJsCanvas.kt | 4 +- .../kotlin/korlibs/kgl/KmlGlWasmCanvas.kt | 4 +- 21 files changed, 802 insertions(+), 626 deletions(-) create mode 100644 korge-foundation/src/jsMain/kotlin/korlibs/memory/Buffer.js.kt delete mode 100644 korge-foundation/src/jsMain/kotlin/korlibs/memory/BufferJs.kt create mode 100644 korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/Buffer.jvm.kt delete mode 100644 korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/BufferJvm.kt create mode 100644 korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/Buffer.wasm.kt delete mode 100644 korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/BufferWasm.kt diff --git a/korge-core/src/commonMain/kotlin/korlibs/ffi/FFILib.kt b/korge-core/src/commonMain/kotlin/korlibs/ffi/FFILib.kt index 917bf9cab7..246af8b79e 100644 --- a/korge-core/src/commonMain/kotlin/korlibs/ffi/FFILib.kt +++ b/korge-core/src/commonMain/kotlin/korlibs/ffi/FFILib.kt @@ -102,10 +102,10 @@ fun Buffer.setFFIPointer(offset: Int, value: FFIPointer?) { } fun Buffer.getUnalignedFFIPointer(offset: Int): FFIPointer? { - return CreateFFIPointer(if (FFI_POINTER_SIZE == 8) getUnalignedInt64(offset) else getUnalignedInt32(offset).toLong()) + return CreateFFIPointer(if (FFI_POINTER_SIZE == 8) getS64(offset) else getS32(offset).toLong()) } fun Buffer.setUnalignedFFIPointer(offset: Int, value: FFIPointer?) { - if (FFI_POINTER_SIZE == 8) setUnalignedInt64(offset, value.address) else setUnalignedInt32(offset, value.address.toInt()) + if (FFI_POINTER_SIZE == 8) set64(offset, value.address) else set32(offset, value.address.toInt()) } expect fun FFILibSym(lib: FFILib): FFILibSym diff --git a/korge-core/src/commonMain/kotlin/korlibs/image/format/WEBP.kt b/korge-core/src/commonMain/kotlin/korlibs/image/format/WEBP.kt index 2c180d5e3a..638ceafba6 100644 --- a/korge-core/src/commonMain/kotlin/korlibs/image/format/WEBP.kt +++ b/korge-core/src/commonMain/kotlin/korlibs/image/format/WEBP.kt @@ -44,8 +44,8 @@ private class WebpWASM(bytes: ByteArray) : korlibs.wasm.WASMLib(bytes) { val infoPtr = get_info(dataPtr, bytes.size) val buffer = Buffer(readBytes(infoPtr, 12)) freeBytes(dataPtr) - val success = buffer.getUnalignedInt32(0) - return if (success != 0) SizeInt(buffer.getUnalignedInt32(4), buffer.getUnalignedInt32(8)) else null + val success = buffer.getS32(0) + return if (success != 0) SizeInt(buffer.getS32(4), buffer.getS32(8)) else null } fun decodeWebpBytes(bytes: ByteArray): Bitmap32? { diff --git a/korge-core/src/commonMain/kotlin/korlibs/image/format/provider/FFIGdiNativeImageFormatProvider.kt b/korge-core/src/commonMain/kotlin/korlibs/image/format/provider/FFIGdiNativeImageFormatProvider.kt index efc2154dd0..8174b5e258 100644 --- a/korge-core/src/commonMain/kotlin/korlibs/image/format/provider/FFIGdiNativeImageFormatProvider.kt +++ b/korge-core/src/commonMain/kotlin/korlibs/image/format/provider/FFIGdiNativeImageFormatProvider.kt @@ -73,7 +73,7 @@ object FFIGdiNativeImageFormatProvider : BaseNativeImageFormatProvider() { //val bitmapData = IntArray(32) val bmpData = Buffer(4 * 32) val res2 = Gdiplus.GdipBitmapLockBits(pimage[0], rect, ImageLockModeRead, if (premultiplied) Format32bppPArgb else Format32bppArgb, bmpData) - val strideS = bmpData.getUnalignedInt32(8) + val strideS = bmpData.getS32(8) val stride = strideS.absoluteValue val ptr = bmpData.getUnalignedFFIPointer(16) @@ -98,4 +98,4 @@ object FFIGdiNativeImageFormatProvider : BaseNativeImageFormatProvider() { ((col and 0xFF) shl 16) or // Swap R ((col shr 16) and 0xFF) // Swap B } -} \ No newline at end of file +} diff --git a/korge-core/src/commonMain/kotlin/korlibs/wasm/WasmRuntime.kt b/korge-core/src/commonMain/kotlin/korlibs/wasm/WasmRuntime.kt index 436360a267..aae2af6b17 100644 --- a/korge-core/src/commonMain/kotlin/korlibs/wasm/WasmRuntime.kt +++ b/korge-core/src/commonMain/kotlin/korlibs/wasm/WasmRuntime.kt @@ -62,12 +62,12 @@ open class WasmRuntime(module: WasmModule, val memSize: Int, val memMax: Int) { fun strlen(ptr: Int): Int { var n = 0 - while (memory.getUnalignedInt8(ptr + n) != 0.toByte()) n++ + while (memory.getS8(ptr + n) != 0.toByte()) n++ return n } fun strlen16(ptr: Int): Int { var n = 0 - while (memory.getUnalignedInt16(ptr + n) != 0.toShort()) n += 2 + while (memory.getS16(ptr + n) != 0.toShort()) n += 2 return n / 2 } @@ -80,7 +80,7 @@ open class WasmRuntime(module: WasmModule, val memSize: Int, val memMax: Int) { var out = "" var n = 0 while (true) { - val v = memory.getUnalignedInt16(ptr + n).toInt() and 0xFFFF + val v = memory.getS16(ptr + n).toInt() and 0xFFFF if (v == 0) break out += v.toChar() n += 2 @@ -171,29 +171,29 @@ open class WasmRuntime(module: WasmModule, val memSize: Int, val memMax: Int) { } } - @JvmStatic fun Op_i32_load(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getUnalignedInt32(checkAddr(addr, offset, runtime)) - @JvmStatic fun Op_i32_load8_s(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getUnalignedInt8(checkAddr(addr, offset, runtime)).toInt() + @JvmStatic fun Op_i32_load(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getS32(checkAddr(addr, offset, runtime)) + @JvmStatic fun Op_i32_load8_s(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getS8(checkAddr(addr, offset, runtime)).toInt() @JvmStatic fun Op_i32_load8_u(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getUnalignedUInt8(checkAddr(addr, offset, runtime)).toInt() - @JvmStatic fun Op_i32_load16_s(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getUnalignedInt16(checkAddr(addr, offset, runtime)).toInt() + @JvmStatic fun Op_i32_load16_s(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getS16(checkAddr(addr, offset, runtime)).toInt() @JvmStatic fun Op_i32_load16_u(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getUnalignedUInt16(checkAddr(addr, offset, runtime)).toInt() - @JvmStatic fun Op_i64_load(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getUnalignedInt64(checkAddr(addr, offset, runtime)) - @JvmStatic fun Op_i64_load8_s(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getUnalignedInt8(checkAddr(addr, offset, runtime)).toLong() + @JvmStatic fun Op_i64_load(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getS64(checkAddr(addr, offset, runtime)) + @JvmStatic fun Op_i64_load8_s(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getS8(checkAddr(addr, offset, runtime)).toLong() @JvmStatic fun Op_i64_load8_u(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getUnalignedUInt8(checkAddr(addr, offset, runtime)).toLong() - @JvmStatic fun Op_i64_load16_s(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getUnalignedInt16(checkAddr(addr, offset, runtime)).toLong() + @JvmStatic fun Op_i64_load16_s(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getS16(checkAddr(addr, offset, runtime)).toLong() @JvmStatic fun Op_i64_load16_u(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getUnalignedUInt16(checkAddr(addr, offset, runtime)).toLong() - @JvmStatic fun Op_i64_load32_s(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getUnalignedInt32(checkAddr(addr, offset, runtime)).toLong() - @JvmStatic fun Op_i64_load32_u(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getUnalignedInt32(checkAddr(addr, offset, runtime)).toUInt().toLong() - @JvmStatic fun Op_f32_load(addr: Int, offset: Int, runtime: WasmRuntime): Float = runtime.memory.getUnalignedFloat32(checkAddr(addr, offset, runtime)) - @JvmStatic fun Op_f64_load(addr: Int, offset: Int, runtime: WasmRuntime): Double = runtime.memory.getUnalignedFloat64(checkAddr(addr, offset, runtime)) - @JvmStatic fun Op_i32_store(addr: Int, value: Int, offset: Int, runtime: WasmRuntime) = runtime.memory.setUnalignedInt32(checkAddr(addr, offset, runtime), value) + @JvmStatic fun Op_i64_load32_s(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getS32(checkAddr(addr, offset, runtime)).toLong() + @JvmStatic fun Op_i64_load32_u(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getS32(checkAddr(addr, offset, runtime)).toUInt().toLong() + @JvmStatic fun Op_f32_load(addr: Int, offset: Int, runtime: WasmRuntime): Float = runtime.memory.getF32(checkAddr(addr, offset, runtime)) + @JvmStatic fun Op_f64_load(addr: Int, offset: Int, runtime: WasmRuntime): Double = runtime.memory.getF64(checkAddr(addr, offset, runtime)) + @JvmStatic fun Op_i32_store(addr: Int, value: Int, offset: Int, runtime: WasmRuntime) = runtime.memory.set32(checkAddr(addr, offset, runtime), value) @JvmStatic fun Op_i32_store8(addr: Int, value: Int, offset: Int, runtime: WasmRuntime) = runtime.memory.setUnalignedInt8(checkAddr(addr, offset, runtime), value) - @JvmStatic fun Op_i32_store16(addr: Int, value: Int, offset: Int, runtime: WasmRuntime) = runtime.memory.setUnalignedInt16(checkAddr(addr, offset, runtime), value.toShort()) - @JvmStatic fun Op_i64_store(addr: Int, value: Long, offset: Int, runtime: WasmRuntime) = runtime.memory.setUnalignedInt64(checkAddr(addr, offset, runtime), value) + @JvmStatic fun Op_i32_store16(addr: Int, value: Int, offset: Int, runtime: WasmRuntime) = runtime.memory.set16(checkAddr(addr, offset, runtime), value.toShort()) + @JvmStatic fun Op_i64_store(addr: Int, value: Long, offset: Int, runtime: WasmRuntime) = runtime.memory.set64(checkAddr(addr, offset, runtime), value) @JvmStatic fun Op_i64_store8(addr: Int, value: Long, offset: Int, runtime: WasmRuntime) = runtime.memory.setUnalignedInt8(checkAddr(addr, offset, runtime), value.toInt()) - @JvmStatic fun Op_i64_store16(addr: Int, value: Long, offset: Int, runtime: WasmRuntime) = runtime.memory.setUnalignedInt16(checkAddr(addr, offset, runtime), value.toShort()) - @JvmStatic fun Op_i64_store32(addr: Int, value: Long, offset: Int, runtime: WasmRuntime) = runtime.memory.setUnalignedInt32(checkAddr(addr, offset, runtime), value.toInt()) - @JvmStatic fun Op_f32_store(addr: Int, value: Float, offset: Int, runtime: WasmRuntime) = runtime.memory.setUnalignedFloat32(checkAddr(addr, offset, runtime), value) - @JvmStatic fun Op_f64_store(addr: Int, value: Double, offset: Int, runtime: WasmRuntime) = runtime.memory.setUnalignedFloat64(checkAddr(addr, offset, runtime), value) + @JvmStatic fun Op_i64_store16(addr: Int, value: Long, offset: Int, runtime: WasmRuntime) = runtime.memory.set16(checkAddr(addr, offset, runtime), value.toShort()) + @JvmStatic fun Op_i64_store32(addr: Int, value: Long, offset: Int, runtime: WasmRuntime) = runtime.memory.set32(checkAddr(addr, offset, runtime), value.toInt()) + @JvmStatic fun Op_f32_store(addr: Int, value: Float, offset: Int, runtime: WasmRuntime) = runtime.memory.setF32(checkAddr(addr, offset, runtime), value) + @JvmStatic fun Op_f64_store(addr: Int, value: Double, offset: Int, runtime: WasmRuntime) = runtime.memory.setF64(checkAddr(addr, offset, runtime), value) @JvmStatic fun Op_i32_eqz(value: Int): Int = (value == 0).toInt() @JvmStatic fun Op_i32_eq(l: Int, r: Int): Int = (l == r).toInt() @JvmStatic fun Op_i32_ne(l: Int, r: Int): Int = (l != r).toInt() @@ -340,7 +340,7 @@ open class WasmRuntime(module: WasmModule, val memSize: Int, val memMax: Int) { @JvmStatic fun Op_memory_copy(dst: Int, src: Int, count: Int, runtime: WasmRuntime) { val mem = runtime.memory for (n in 0 until count) { - mem.setUnalignedInt8(dst + n, mem.getUnalignedInt8(src + n)) + mem.set8(dst + n, mem.getS8(src + n)) } } @JvmStatic fun Op_memory_fill(dst: Int, value: Int, count: Int, runtime: WasmRuntime) { diff --git a/korge-core/src/commonTest/kotlin/korlibs/wasm/WasmCodeVisitorTest.kt b/korge-core/src/commonTest/kotlin/korlibs/wasm/WasmCodeVisitorTest.kt index bcadf77cf4..adc7d68a7d 100644 --- a/korge-core/src/commonTest/kotlin/korlibs/wasm/WasmCodeVisitorTest.kt +++ b/korge-core/src/commonTest/kotlin/korlibs/wasm/WasmCodeVisitorTest.kt @@ -31,9 +31,9 @@ class WasmCodeVisitorTest { //repeat(100) { run { val infoPtr = newInterpreter.invoke("get_info", ptr, webpBytes.size) as Int - val success = newInterpreter.memory.getUnalignedInt32(infoPtr + 0) - val width = newInterpreter.memory.getUnalignedInt32(infoPtr + 4) - val height = newInterpreter.memory.getUnalignedInt32(infoPtr + 8) + val success = newInterpreter.memory.getS32(infoPtr + 0) + val width = newInterpreter.memory.getS32(infoPtr + 4) + val height = newInterpreter.memory.getS32(infoPtr + 8) assertEquals("1,32x32", "$success,${width}x${height}") } } diff --git a/korge-foundation/src/commonMain/kotlin/korlibs/math/Math.kt b/korge-foundation/src/commonMain/kotlin/korlibs/math/Math.kt index cf2b1c9156..a38a51ae55 100644 --- a/korge-foundation/src/commonMain/kotlin/korlibs/math/Math.kt +++ b/korge-foundation/src/commonMain/kotlin/korlibs/math/Math.kt @@ -202,6 +202,9 @@ public fun Long.toIntSafe(): Int = if (this in Int.MIN_VALUE.toLong()..Int.MAX_V /** Returns an [Int] representing this [Byte] as if it was unsigned 0x00..0xFF */ public inline val Byte.unsigned: Int get() = this.toInt() and 0xFF +/** Returns an [Int] representing this [Short] as if it was unsigned 0x0000..0xFFFF */ +public inline val Short.unsigned: Int get() = this.toInt() and 0xFFFF + /** Returns a [Long] representing this [Int] as if it was unsigned 0x00000000L..0xFFFFFFFFL */ public inline val Int.unsigned: Long get() = this.toLong() and 0xFFFFFFFFL diff --git a/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt b/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt index ba9b1033ff..97d27f0897 100644 --- a/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt +++ b/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt @@ -5,12 +5,74 @@ package korlibs.memory import korlibs.math.* import kotlin.jvm.* +//typealias Buffer = NDataView + +//expect class NDataView { + +// @TODO: slice -> subarray expect class Buffer { + constructor(size: Int, direct: Boolean = false) + constructor(array: ByteArray, offset: Int = 0, size: Int = array.size - offset) + + val byteOffset: Int + val sizeInBytes: Int + internal fun sliceInternal(start: Int, end: Int): Buffer + + fun transferBytes(bufferOffset: Int, array: ByteArray, arrayOffset: Int, len: Int, toArray: Boolean): Unit + + fun getS8(byteOffset: Int): Byte + fun getS16LE(byteOffset: Int): Short + fun getS32LE(byteOffset: Int): Int + fun getS64LE(byteOffset: Int): Long + fun getF32LE(byteOffset: Int): Float + fun getF64LE(byteOffset: Int): Double + fun getS16BE(byteOffset: Int): Short + fun getS32BE(byteOffset: Int): Int + fun getS64BE(byteOffset: Int): Long + fun getF32BE(byteOffset: Int): Float + fun getF64BE(byteOffset: Int): Double + + fun set8(byteOffset: Int, value: Byte) + fun set16LE(byteOffset: Int, value: Short) + fun set32LE(byteOffset: Int, value: Int) + fun set64LE(byteOffset: Int, value: Long) + fun setF32LE(byteOffset: Int, value: Float) + fun setF64LE(byteOffset: Int, value: Double) + fun set16BE(byteOffset: Int, value: Short) + fun set32BE(byteOffset: Int, value: Int) + fun set64BE(byteOffset: Int, value: Long) + fun setF32BE(byteOffset: Int, value: Float) + fun setF64BE(byteOffset: Int, value: Double) + companion object { fun copy(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int) fun equals(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int): Boolean } } + +internal fun Buffer.Companion.hashCodeCommon( + buffer: Buffer +): Int { + var h = 1 + val len = buffer.sizeInBytes + for (n in 0 until (len / 4)) { + h = 31 * h + buffer.getS32LE(n * 4) + } + val offset = (len / 4) * 4 + for (n in 0 until len % 4) { + h = 31 * h + buffer.getInt8(offset + n) + } + return h +} + +internal fun Buffer.Companion.equalsCommon( + that: Buffer, + other: Any? +): Boolean { + if (other !is Buffer || that.size != other.size) return false + return Buffer.equals(that, 0, other, 0, that.sizeInBytes) +} + internal fun Buffer.Companion.equalsCommon( src: Buffer, srcPosBytes: Int, @@ -33,8 +95,8 @@ internal fun Buffer.Companion.equalsCommon( val words = remaining / WORD remaining %= WORD for (n in 0 until words) { - val v0 = src.getUnalignedInt64(srcPosBytes + offset + n * WORD) - val v1 = dst.getUnalignedInt64(dstPosBytes + offset + n * WORD) + val v0 = src.getS64LE(srcPosBytes + offset + n * WORD) + val v1 = dst.getS64LE(dstPosBytes + offset + n * WORD) if (v0 != v1) { return false } @@ -46,8 +108,8 @@ internal fun Buffer.Companion.equalsCommon( val words = remaining / WORD remaining %= WORD for (n in 0 until words) { - val v0 = src.getUnalignedInt32(srcPosBytes + offset + n * WORD) - val v1 = dst.getUnalignedInt32(dstPosBytes + offset + n * WORD) + val v0 = src.getS32LE(srcPosBytes + offset + n * WORD) + val v1 = dst.getS32LE(dstPosBytes + offset + n * WORD) if (v0 != v1) { return false } @@ -57,8 +119,8 @@ internal fun Buffer.Companion.equalsCommon( if (true) { for (n in 0 until remaining) { - val v0 = src.getUnalignedInt8(srcPosBytes + offset + n) - val v1 = dst.getUnalignedInt8(dstPosBytes + offset + n) + val v0 = src.getS8(srcPosBytes + offset + n) + val v1 = dst.getS8(dstPosBytes + offset + n) if (v0 != v1) { return false } @@ -67,19 +129,19 @@ internal fun Buffer.Companion.equalsCommon( return true } -val Buffer.size: Int get() = sizeInBytes internal fun NBuffer_toString(buffer: Buffer): String = "Buffer(size=${buffer.size})" -internal fun checkNBufferSize(size: Int) { +internal fun checkNBufferSize(size: Int): Int { if (size < 0) throw IllegalArgumentException("invalid size $size") + return size } -internal fun checkNBufferWrap(array: ByteArray, offset: Int, size: Int) { +internal fun checkNBufferWrap(array: ByteArray, offset: Int, size: Int): ByteArray { val end = offset + size if (size < 0 || offset !in 0..array.size || end !in 0..array.size) { throw IllegalArgumentException("invalid arguments offset=$offset, size=$size for array.size=${array.size}") } + return array } -expect fun Buffer(size: Int, direct: Boolean = false): Buffer -expect fun Buffer(array: ByteArray, offset: Int = 0, size: Int = array.size - offset): Buffer +val Buffer.size: Int get() = sizeInBytes fun Buffer.Companion.allocDirect(size: Int): Buffer = Buffer(size, direct = true) fun Buffer.Companion.allocNoDirect(size: Int): Buffer = Buffer(size, direct = false) @@ -94,8 +156,6 @@ fun Buffer.clone(direct: Boolean = false): Buffer { return out } -expect val Buffer.byteOffset: Int -expect val Buffer.sizeInBytes: Int private fun Int.hexChar(): Char = when (this) { in 0..9 -> '0' + this in 10..26 -> 'a' + (this - 10) @@ -108,91 +168,196 @@ fun Buffer.hex(): String = buildString(sizeInBytes * 2) { append(value.extract4(0).hexChar()) } } -internal expect fun Buffer.sliceInternal(start: Int, end: Int): Buffer -fun Buffer.sliceWithSize(start: Int, size: Int): Buffer = slice(start, start + size) -fun Buffer.slice(start: Int = 0, end: Int = sizeInBytes): Buffer { +fun Buffer.sliceWithSize(start: Int, size: Int): Buffer = _slice(start, start + size) +fun Buffer._slice(start: Int = 0, end: Int = sizeInBytes): Buffer { if (start > end || start !in 0 .. sizeInBytes || end !in 0 .. sizeInBytes) { throw IllegalArgumentException("invalid slice start:$start, end:$end not in 0..$sizeInBytes") } return sliceInternal(start, end) } +// Basic functions + +fun Buffer.getU8(byteOffset: Int): Int = getS8(byteOffset).unsigned +fun Buffer.getU16LE(byteOffset: Int): Int = getS16LE(byteOffset).unsigned +fun Buffer.getU32LE(byteOffset: Int): Long = getS32LE(byteOffset).unsigned +fun Buffer.getU16BE(byteOffset: Int): Int = getS16BE(byteOffset).unsigned +fun Buffer.getU32BE(byteOffset: Int): Long = getS32BE(byteOffset).unsigned + +inline fun Buffer.getU8(byteOffset: Int, littleEndian: Boolean = true): Int = getU8(byteOffset) +inline fun Buffer.getU16(byteOffset: Int, littleEndian: Boolean = true): Int = if (littleEndian) getU16LE(byteOffset) else getU16BE(byteOffset) +inline fun Buffer.getU32(byteOffset: Int, littleEndian: Boolean = true): Long = if (littleEndian) getU32LE(byteOffset) else getU32BE(byteOffset) + +inline fun Buffer.getS16(byteOffset: Int, littleEndian: Boolean = true): Short = if (littleEndian) getS16LE(byteOffset) else getS16BE(byteOffset) +inline fun Buffer.getS32(byteOffset: Int, littleEndian: Boolean = true): Int = if (littleEndian) getS32LE(byteOffset) else getS32BE(byteOffset) +inline fun Buffer.getS64(byteOffset: Int, littleEndian: Boolean = true): Long = if (littleEndian) getS64LE(byteOffset) else getS64BE(byteOffset) +inline fun Buffer.getF32(byteOffset: Int, littleEndian: Boolean = true): Float = if (littleEndian) getF32LE(byteOffset) else getF32BE(byteOffset) +inline fun Buffer.getF64(byteOffset: Int, littleEndian: Boolean = true): Double = if (littleEndian) getF64LE(byteOffset) else getF64BE(byteOffset) + +inline fun Buffer.set16(byteOffset: Int, value: Short, littleEndian: Boolean = true): Unit = if (littleEndian) set16LE(byteOffset, value) else set16BE(byteOffset, value) +inline fun Buffer.set32(byteOffset: Int, value: Int, littleEndian: Boolean = true): Unit = if (littleEndian) set32LE(byteOffset, value) else set32BE(byteOffset, value) +inline fun Buffer.set64(byteOffset: Int, value: Long, littleEndian: Boolean = true): Unit = if (littleEndian) set64LE(byteOffset, value) else set64BE(byteOffset, value) +inline fun Buffer.setF32(byteOffset: Int, value: Float, littleEndian: Boolean = true): Unit = if (littleEndian) setF32LE(byteOffset, value) else setF32BE(byteOffset, value) +inline fun Buffer.setF64(byteOffset: Int, value: Double, littleEndian: Boolean = true): Unit = if (littleEndian) setF64LE(byteOffset, value) else setF64BE(byteOffset, value) + +fun Buffer.set8Clamped(byteOffset: Int, value: Int): Unit = set8(byteOffset, value.clampUByte().toByte()) +fun Buffer.set16LEClamped(byteOffset: Int, value: Int): Unit = set16LE(byteOffset, value.clampUShort().toShort()) +fun Buffer.set16BEClamped(byteOffset: Int, value: Int): Unit = set16BE(byteOffset, value.clampUShort().toShort()) +inline fun Buffer.set16Clamped(byteOffset: Int, value: Int, littleEndian: Boolean = true): Unit = if (littleEndian) set16LEClamped(byteOffset, value) else set16BEClamped(byteOffset, value) + +@Deprecated("", ReplaceWith("getS8(byteOffset)")) +fun Buffer.getUnalignedInt8(byteOffset: Int): Byte = getS8(byteOffset) +@Deprecated("", ReplaceWith("getS16LE(byteOffset)")) +fun Buffer.getUnalignedInt16(byteOffset: Int): Short = getS16LE(byteOffset) +@Deprecated("", ReplaceWith("getS32LE(byteOffset)")) +fun Buffer.getUnalignedInt32(byteOffset: Int): Int = getS32LE(byteOffset) +@Deprecated("", ReplaceWith("getS64LE(byteOffset)")) +fun Buffer.getUnalignedInt64(byteOffset: Int): Long = getS64LE(byteOffset) +@Deprecated("", ReplaceWith("getF32LE(byteOffset)")) +fun Buffer.getUnalignedFloat32(byteOffset: Int): Float = getF32LE(byteOffset) +@Deprecated("", ReplaceWith("getF64LE(byteOffset)")) +fun Buffer.getUnalignedFloat64(byteOffset: Int): Double = getF64LE(byteOffset) +@Deprecated("", ReplaceWith("set8(byteOffset, value)")) +fun Buffer.setUnalignedInt8(byteOffset: Int, value: Byte): Unit = set8(byteOffset, value) +@Deprecated("", ReplaceWith("set16LE(byteOffset, value)")) +fun Buffer.setUnalignedInt16(byteOffset: Int, value: Short): Unit = set16LE(byteOffset, value) +@Deprecated("", ReplaceWith("set32LE(byteOffset, value)")) +fun Buffer.setUnalignedInt32(byteOffset: Int, value: Int): Unit = set32LE(byteOffset, value) +@Deprecated("", ReplaceWith("set64LE(byteOffset, value)")) +fun Buffer.setUnalignedInt64(byteOffset: Int, value: Long): Unit = set64LE(byteOffset, value) +@Deprecated("", ReplaceWith("setF32LE(byteOffset, value)")) +fun Buffer.setUnalignedFloat32(byteOffset: Int, value: Float): Unit = setF32LE(byteOffset, value) +@Deprecated("", ReplaceWith("setF64LE(byteOffset, value)")) +fun Buffer.setUnalignedFloat64(byteOffset: Int, value: Double): Unit = setF64LE(byteOffset, value) + // Unaligned versions -fun Buffer.getUnalignedUInt8(byteOffset: Int): Int = getUnalignedInt8(byteOffset).toInt() and 0xFF -fun Buffer.getUnalignedUInt16(byteOffset: Int): Int = getUnalignedInt16(byteOffset).toInt() and 0xFFFF -expect fun Buffer.getUnalignedInt8(byteOffset: Int): Byte -expect fun Buffer.getUnalignedInt16(byteOffset: Int): Short -expect fun Buffer.getUnalignedInt32(byteOffset: Int): Int -expect fun Buffer.getUnalignedInt64(byteOffset: Int): Long -expect fun Buffer.getUnalignedFloat32(byteOffset: Int): Float -expect fun Buffer.getUnalignedFloat64(byteOffset: Int): Double - -fun Buffer.setUnalignedUInt8(byteOffset: Int, value: Int) = setUnalignedInt8(byteOffset, value.toByte()) -fun Buffer.setUnalignedUInt8Clamped(byteOffset: Int, value: Int) = setUnalignedInt8(byteOffset, value.clampUByte().toByte()) -fun Buffer.setUnalignedUInt16(byteOffset: Int, value: Int) = setUnalignedInt16(byteOffset, value.toShort()) -expect fun Buffer.setUnalignedInt8(byteOffset: Int, value: Byte) -fun Buffer.setUnalignedInt8(byteOffset: Int, value: Int) = setUnalignedInt8(byteOffset, value.toByte()) -expect fun Buffer.setUnalignedInt16(byteOffset: Int, value: Short) -expect fun Buffer.setUnalignedInt32(byteOffset: Int, value: Int) -expect fun Buffer.setUnalignedInt64(byteOffset: Int, value: Long) -expect fun Buffer.setUnalignedFloat32(byteOffset: Int, value: Float) -expect fun Buffer.setUnalignedFloat64(byteOffset: Int, value: Double) +@Deprecated("", ReplaceWith("getU8(byteOffset)")) +fun Buffer.getUnalignedUInt8(byteOffset: Int): Int = getU8(byteOffset) +@Deprecated("", ReplaceWith("getU16LE(byteOffset)")) +fun Buffer.getUnalignedUInt16(byteOffset: Int): Int = getU16LE(byteOffset) + +@Deprecated("", ReplaceWith("set8(byteOffset, value.toByte())")) +fun Buffer.setUnalignedUInt8(byteOffset: Int, value: Int) = set8(byteOffset, value.toByte()) +@Deprecated("", ReplaceWith("set8Clamped(byteOffset, value)")) +fun Buffer.setUnalignedUInt8Clamped(byteOffset: Int, value: Int) = set8Clamped(byteOffset, value) +@Deprecated("", ReplaceWith("set16LE(byteOffset, value.toShort())")) +fun Buffer.setUnalignedUInt16(byteOffset: Int, value: Int) = set16LE(byteOffset, value.toShort()) +@Deprecated("", ReplaceWith("set8(byteOffset, value.toByte())")) +fun Buffer.setUnalignedInt8(byteOffset: Int, value: Int) = set8(byteOffset, value.toByte()) // Array versions -fun Buffer.getUnalignedArrayInt8(byteOffset: Int, out: ByteArray, offset: Int = 0, size: Int = out.size - offset): ByteArray { for (n in 0 until size) out[offset + n] = getUnalignedInt8(byteOffset + n * 1); return out } -fun Buffer.getUnalignedArrayInt16(byteOffset: Int, out: ShortArray, offset: Int = 0, size: Int = out.size - offset): ShortArray { for (n in 0 until size) out[offset + n] = getUnalignedInt16(byteOffset + n * 2); return out } -fun Buffer.getUnalignedArrayInt32(byteOffset: Int, out: IntArray, offset: Int = 0, size: Int = out.size - offset): IntArray { for (n in 0 until size) out[offset + n] = getUnalignedInt32(byteOffset + n * 4); return out } -fun Buffer.getUnalignedArrayInt64(byteOffset: Int, out: LongArray, offset: Int = 0, size: Int = out.size - offset): LongArray { for (n in 0 until size) out[offset + n] = getUnalignedInt64(byteOffset + n * 8); return out } -fun Buffer.getUnalignedArrayFloat32(byteOffset: Int, out: FloatArray, offset: Int = 0, size: Int = out.size - offset): FloatArray { for (n in 0 until size) out[offset + n] = getUnalignedFloat32(byteOffset + n * 4); return out } -fun Buffer.getUnalignedArrayFloat64(byteOffset: Int, out: DoubleArray, offset: Int = 0, size: Int = out.size - offset): DoubleArray { for (n in 0 until size) out[offset + n] = getUnalignedFloat64(byteOffset + n * 8); return out } - -fun Buffer.setUnalignedArrayInt8(byteOffset: Int, inp: ByteArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) setUnalignedInt8(byteOffset + n * 1, inp[offset + n]) } -fun Buffer.setUnalignedArrayInt16(byteOffset: Int, inp: ShortArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) setUnalignedInt16(byteOffset + n * 2, inp[offset + n]) } -fun Buffer.setUnalignedArrayInt32(byteOffset: Int, inp: IntArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) setUnalignedInt32(byteOffset + n * 4, inp[offset + n]) } -fun Buffer.setUnalignedArrayInt64(byteOffset: Int, inp: LongArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) setUnalignedInt64(byteOffset + n * 8, inp[offset + n]) } -fun Buffer.setUnalignedArrayFloat32(byteOffset: Int, inp: FloatArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) setUnalignedFloat32(byteOffset + n * 4, inp[offset + n]) } -fun Buffer.setUnalignedArrayFloat64(byteOffset: Int, inp: DoubleArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) setUnalignedFloat64(byteOffset + n * 8, inp[offset + n]) } - -fun Buffer.getUInt8(index: Int): Int = getUnalignedUInt8(index) -fun Buffer.getUInt16(index: Int): Int = getUnalignedUInt16(index * 2) and 0xFFFF -fun Buffer.getInt8(index: Int): Byte = getUnalignedInt8(index) -fun Buffer.getInt16(index: Int): Short = getUnalignedInt16(index * 2) -fun Buffer.getInt32(index: Int): Int = getUnalignedInt32(index * 4) -fun Buffer.getInt64(index: Int): Long = getUnalignedInt64(index * 8) -fun Buffer.getFloat32(index: Int): Float = getUnalignedFloat32(index * 4) -fun Buffer.getFloat64(index: Int): Double = getUnalignedFloat64(index * 8) - -fun Buffer.setUInt8(index: Int, value: Int) = setUnalignedUInt8(index, value) -fun Buffer.setUInt8Clamped(index: Int, value: Int) = setUnalignedUInt8Clamped(index, value) -fun Buffer.setUInt16(index: Int, value: Int) = setUnalignedUInt16(index * 2, value) -fun Buffer.setInt8(index: Int, value: Byte) = setUnalignedInt8(index, value) -fun Buffer.setInt8(index: Int, value: Int) = setUnalignedInt8(index, value) -fun Buffer.setInt16(index: Int, value: Short) = setUnalignedInt16(index * 2, value) -fun Buffer.setInt32(index: Int, value: Int) = setUnalignedInt32(index * 4, value) -fun Buffer.setInt64(index: Int, value: Long) = setUnalignedInt64(index * 8, value) -fun Buffer.setFloat32(index: Int, value: Float) = setUnalignedFloat32(index * 4, value) -fun Buffer.setFloat64(index: Int, value: Double) = setUnalignedFloat64(index * 8, value) +@Deprecated("") +fun Buffer.getUnalignedArrayInt8(byteOffset: Int, out: ByteArray, offset: Int = 0, size: Int = out.size - offset): ByteArray { for (n in 0 until size) out[offset + n] = + getS8(byteOffset + n * 1); return out } +@Deprecated("") +fun Buffer.getUnalignedArrayInt16(byteOffset: Int, out: ShortArray, offset: Int = 0, size: Int = out.size - offset): ShortArray { for (n in 0 until size) out[offset + n] = + getS16LE(byteOffset + n * 2); return out } +@Deprecated("") +fun Buffer.getUnalignedArrayInt32(byteOffset: Int, out: IntArray, offset: Int = 0, size: Int = out.size - offset): IntArray { for (n in 0 until size) out[offset + n] = + getS32LE(byteOffset + n * 4); return out } +@Deprecated("") +fun Buffer.getUnalignedArrayInt64(byteOffset: Int, out: LongArray, offset: Int = 0, size: Int = out.size - offset): LongArray { for (n in 0 until size) out[offset + n] = + getS64LE(byteOffset + n * 8); return out } +@Deprecated("") +fun Buffer.getUnalignedArrayFloat32(byteOffset: Int, out: FloatArray, offset: Int = 0, size: Int = out.size - offset): FloatArray { for (n in 0 until size) out[offset + n] = + getF32LE(byteOffset + n * 4); return out } +@Deprecated("") +fun Buffer.getUnalignedArrayFloat64(byteOffset: Int, out: DoubleArray, offset: Int = 0, size: Int = out.size - offset): DoubleArray { for (n in 0 until size) out[offset + n] = + getF64LE(byteOffset + n * 8); return out } + +@Deprecated("") +fun Buffer.setUnalignedArrayInt8(byteOffset: Int, inp: ByteArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) set8(byteOffset + n * 1, inp[offset + n]) +} +@Deprecated("") +fun Buffer.setUnalignedArrayInt16(byteOffset: Int, inp: ShortArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) set16LE(byteOffset + n * 2, inp[offset + n]) +} +@Deprecated("") +fun Buffer.setUnalignedArrayInt32(byteOffset: Int, inp: IntArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) set32LE(byteOffset + n * 4, inp[offset + n]) +} +@Deprecated("") +fun Buffer.setUnalignedArrayInt64(byteOffset: Int, inp: LongArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) set64LE(byteOffset + n * 8, inp[offset + n]) +} +@Deprecated("") +fun Buffer.setUnalignedArrayFloat32(byteOffset: Int, inp: FloatArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) setF32LE(byteOffset + n * 4, inp[offset + n]) +} +@Deprecated("") +fun Buffer.setUnalignedArrayFloat64(byteOffset: Int, inp: DoubleArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) setF64LE(byteOffset + n * 8, inp[offset + n]) +} + +@Deprecated("", ReplaceWith("getU8(index)")) +fun Buffer.getUInt8(index: Int): Int = getU8(index) +@Deprecated("", ReplaceWith("getU16LE(index * Short.SIZE_BYTES)")) +fun Buffer.getUInt16(index: Int): Int = getU16LE(index * Short.SIZE_BYTES) +@Deprecated("", ReplaceWith("getS8(index)")) +fun Buffer.getInt8(index: Int): Byte = getS8(index) +@Deprecated("", ReplaceWith("getS16LE(index * Short.SIZE_BYTES)")) +fun Buffer.getInt16(index: Int): Short = getS16LE(index * Short.SIZE_BYTES) +@Deprecated("", ReplaceWith("getS32LE(index * Int.SIZE_BYTES)")) +fun Buffer.getInt32(index: Int): Int = getS32LE(index * Int.SIZE_BYTES) +@Deprecated("", ReplaceWith("getS64LE(index * Long.SIZE_BYTES)")) +fun Buffer.getInt64(index: Int): Long = getS64LE(index * Long.SIZE_BYTES) +@Deprecated("", ReplaceWith("getF32LE(index * Float.SIZE_BYTES)")) +fun Buffer.getFloat32(index: Int): Float = getF32LE(index * Float.SIZE_BYTES) +@Deprecated("", ReplaceWith("getF64LE(index * Double.SIZE_BYTES)")) +fun Buffer.getFloat64(index: Int): Double = getF64LE(index * Double.SIZE_BYTES) + +@Deprecated("", ReplaceWith("set8(index, value.toByte())")) +fun Buffer.setUInt8(index: Int, value: Int) = set8(index, value.toByte()) +@Deprecated("", ReplaceWith("set8Clamped(index, value)")) +fun Buffer.setUInt8Clamped(index: Int, value: Int) = set8Clamped(index, value) +@Deprecated("", ReplaceWith("set16LE(index * Short.SIZE_BYTES, value.toShort())")) +fun Buffer.setUInt16(index: Int, value: Int) = set16LE(index * Short.SIZE_BYTES, value.toShort()) +@Deprecated("", ReplaceWith("set8(index, value)")) +fun Buffer.setInt8(index: Int, value: Byte) = set8(index, value) +@Deprecated("", ReplaceWith("set16LE(index, value.toShort())")) +fun Buffer.setInt8(index: Int, value: Int) = set16LE(index, value.toShort()) +@Deprecated("", ReplaceWith("set16LE(index * Short.SIZE_BYTES, value)")) +fun Buffer.setInt16(index: Int, value: Short) = set16LE(index * Short.SIZE_BYTES, value) +@Deprecated("", ReplaceWith("set32LE(index * Int.SIZE_BYTES, value)")) +fun Buffer.setInt32(index: Int, value: Int) = set32LE(index * Int.SIZE_BYTES, value) +@Deprecated("", ReplaceWith("set64LE(index * Long.SIZE_BYTES, value)")) +fun Buffer.setInt64(index: Int, value: Long) = set64LE(index * Long.SIZE_BYTES, value) +@Deprecated("", ReplaceWith("setF32LE(index * Float.SIZE_BYTES, value)")) +fun Buffer.setFloat32(index: Int, value: Float) = setF32LE(index * Float.SIZE_BYTES, value) +@Deprecated("", ReplaceWith("setF64LE(index * Double.SIZE_BYTES, value)")) +fun Buffer.setFloat64(index: Int, value: Double) = setF64LE(index * Double.SIZE_BYTES, value) // ALIGNED ARRAYS +@Deprecated("") fun Buffer.getArrayUInt8(index: Int, out: UByteArrayInt, offset: Int = 0, size: Int = out.size - offset): UByteArrayInt = UByteArrayInt(getUnalignedArrayInt8(index * 1, out.data, offset, size)) +@Deprecated("") fun Buffer.getArrayUInt16(index: Int, out: UShortArrayInt, offset: Int = 0, size: Int = out.size - offset): UShortArrayInt = UShortArrayInt(getUnalignedArrayInt16(index * 2, out.data, offset, size)) +@Deprecated("") fun Buffer.getArrayInt8(index: Int, out: ByteArray, offset: Int = 0, size: Int = out.size - offset): ByteArray = getUnalignedArrayInt8(index * 1, out, offset, size) +@Deprecated("") fun Buffer.getArrayInt16(index: Int, out: ShortArray, offset: Int = 0, size: Int = out.size - offset): ShortArray = getUnalignedArrayInt16(index * 2, out, offset, size) +@Deprecated("") fun Buffer.getArrayInt32(index: Int, out: IntArray, offset: Int = 0, size: Int = out.size - offset): IntArray = getUnalignedArrayInt32(index * 4, out, offset, size) +@Deprecated("") fun Buffer.getArrayInt64(index: Int, out: LongArray, offset: Int = 0, size: Int = out.size - offset): LongArray = getUnalignedArrayInt64(index * 8, out, offset, size) +@Deprecated("") fun Buffer.getArrayFloat32(index: Int, out: FloatArray, offset: Int = 0, size: Int = out.size - offset): FloatArray = getUnalignedArrayFloat32(index * 4, out, offset, size) +@Deprecated("") fun Buffer.getArrayFloat64(index: Int, out: DoubleArray, offset: Int = 0, size: Int = out.size - offset): DoubleArray = getUnalignedArrayFloat64(index * 8, out, offset, size) +@Deprecated("") fun Buffer.setArrayUInt8(index: Int, inp: UByteArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayInt8(index * 1, inp.data, offset, size) +@Deprecated("") fun Buffer.setArrayUInt16(index: Int, inp: UShortArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayInt16(index * 2, inp.data, offset, size) +@Deprecated("") fun Buffer.setArrayInt8(index: Int, inp: ByteArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayInt8(index * 1, inp, offset, size) +@Deprecated("") fun Buffer.setArrayInt16(index: Int, inp: ShortArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayInt16(index * 2, inp, offset, size) +@Deprecated("") fun Buffer.setArrayInt32(index: Int, inp: IntArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayInt32(index * 4, inp, offset, size) +@Deprecated("") fun Buffer.setArrayInt64(index: Int, inp: LongArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayInt64(index * 8, inp, offset, size) +@Deprecated("") fun Buffer.setArrayFloat32(index: Int, inp: FloatArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayFloat32(index * 4, inp, offset, size) +@Deprecated("") fun Buffer.setArrayFloat64(index: Int, inp: DoubleArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayFloat64(index * 8, inp, offset, size) interface BaseBuffer { @@ -201,6 +366,8 @@ interface BaseBuffer { interface TypedBuffer : BaseBuffer { val buffer: Buffer + override val size: Int get() = buffer.sizeInBytes / elementSizeInBytes + val elementSizeInBytes: Int } interface BaseIntBuffer : BaseBuffer { @@ -232,188 +399,213 @@ value class FloatArrayBuffer(val array: FloatArray) : BaseFloatBuffer { @JvmInline value class Int8Buffer(override val buffer: Buffer) : TypedBuffer { - constructor(size: Int, direct: Boolean = false) : this(Buffer(size * 1, direct)) - constructor(data: ByteArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * 1).also { it.setArrayInt8(0, data, offset, size) }) + companion object { + const val ELEMENT_SIZE_IN_BYTES = 1 + } + constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) + constructor(data: ByteArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayInt8(0, data, offset, size) }) - override val size: Int get() = buffer.sizeInBytes + override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES operator fun get(index: Int): Byte = buffer.getInt8(index) operator fun set(index: Int, value: Byte) = buffer.setInt8(index, value) fun getArray(index: Int, out: ByteArray, offset: Int = 0, size: Int = out.size - offset): ByteArray = buffer.getArrayInt8(index, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): ByteArray = getArray(index, ByteArray(size)) fun setArray(index: Int, inp: ByteArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayInt8(index, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Int8Buffer = Int8Buffer(buffer.slice(start, end)) - fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int8Buffer = - Int8Buffer(buffer.sliceWithSize(start, size)) + fun slice(start: Int = 0, end: Int = this.size): Int8Buffer = Int8Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int8Buffer = slice(start, start + size) } @JvmInline value class Int16Buffer(override val buffer: Buffer) : TypedBuffer { - constructor(size: Int, direct: Boolean = false) : this(Buffer(size * 2, direct)) - constructor(data: ShortArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * 2).also { it.setArrayInt16(0, data, offset, size) }) + companion object { + const val ELEMENT_SIZE_IN_BYTES = 2 + } + constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) + constructor(data: ShortArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayInt16(0, data, offset, size) }) - override val size: Int get() = buffer.sizeInBytes / 2 - operator fun get(index: Int): Short = buffer.getInt16(index) - operator fun set(index: Int, value: Short) = buffer.setInt16(index, value) + override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES + operator fun get(index: Int): Short = buffer.getS16LE(index * ELEMENT_SIZE_IN_BYTES) + operator fun set(index: Int, value: Short) = buffer.set16LE(index * ELEMENT_SIZE_IN_BYTES, value) fun getArray(index: Int, out: ShortArray, offset: Int = 0, size: Int = out.size - offset): ShortArray = buffer.getArrayInt16(index, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): ShortArray = getArray(index, ShortArray(size)) fun setArray(index: Int, inp: ShortArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayInt16(index, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Int16Buffer = Int16Buffer(buffer.slice(start * 2, end * 2)) - fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int16Buffer = - Int16Buffer(buffer.sliceWithSize(start * 2, size * 2)) + fun slice(start: Int = 0, end: Int = this.size): Int16Buffer = Int16Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int16Buffer = slice(start, start + size) } @JvmInline value class Uint8Buffer(override val buffer: Buffer) : TypedBuffer, BaseIntBuffer { - constructor(size: Int, direct: Boolean = false) : this(Buffer(size * 1, direct)) - constructor(data: UByteArrayInt, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size).also { it.setArrayUInt8(0, data, offset, size) }) companion object { + const val ELEMENT_SIZE_IN_BYTES = 1 operator fun invoke(data: ByteArray) = Uint8Buffer(UByteArrayInt(data)) operator fun invoke(data: UByteArray) = Uint8Buffer(UByteArrayInt(data.toByteArray())) } + constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) + constructor(data: UByteArrayInt, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size).also { it.setArrayUInt8(0, data, offset, size) }) - override val size: Int get() = buffer.sizeInBytes - override operator fun get(index: Int): Int = buffer.getUInt8(index) - override operator fun set(index: Int, value: Int) = buffer.setUInt8(index, value) + override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES + override operator fun get(index: Int): Int = buffer.getU8(index) + override operator fun set(index: Int, value: Int) = buffer.set8(index, value.toByte()) fun getArray(index: Int, out: UByteArrayInt, offset: Int = 0, size: Int = out.size - offset): UByteArrayInt = buffer.getArrayUInt8(index, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): UByteArrayInt = getArray(index, UByteArrayInt(size)) fun setArray(index: Int, inp: UByteArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayUInt8(index, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Uint8Buffer = Uint8Buffer(buffer.slice(start, end)) - fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint8Buffer = Uint8Buffer(buffer.sliceWithSize(start, size)) + fun slice(start: Int = 0, end: Int = this.size): Uint8Buffer = Uint8Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint8Buffer = slice(start, start + size) } - @JvmInline value class Uint8ClampedBuffer(override val buffer: Buffer) : TypedBuffer, BaseIntBuffer { - constructor(size: Int, direct: Boolean = false) : this(Buffer(size * 1, direct)) - constructor(data: UByteArrayInt, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size).also { it.setArrayUInt8(0, data, offset, size) }) companion object { + const val ELEMENT_SIZE_IN_BYTES = 1 operator fun invoke(data: ByteArray) = Uint8ClampedBuffer(UByteArrayInt(data)) } + constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) + constructor(data: UByteArrayInt, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size).also { it.setArrayUInt8(0, data, offset, size) }) - override val size: Int get() = buffer.sizeInBytes - override operator fun get(index: Int): Int = buffer.getUInt8(index) - override operator fun set(index: Int, value: Int) = buffer.setUInt8Clamped(index, value) + override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES + override operator fun get(index: Int): Int = buffer.getU8(index) + override operator fun set(index: Int, value: Int) = buffer.set8Clamped(index, value) - fun slice(start: Int = 0, end: Int = this.size): Uint8ClampedBuffer = - Uint8ClampedBuffer(buffer.slice(start, end)) - fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint8ClampedBuffer = - Uint8ClampedBuffer(buffer.sliceWithSize(start, size)) + fun slice(start: Int = 0, end: Int = this.size): Uint8ClampedBuffer = Uint8ClampedBuffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint8ClampedBuffer = slice(start, start + size) } @JvmInline value class Uint16Buffer(override val buffer: Buffer) : TypedBuffer, BaseIntBuffer { - constructor(size: Int, direct: Boolean = false) : this(Buffer(size * 2, direct)) - constructor(data: UShortArrayInt, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * 2).also { it.setArrayUInt16(0, data, offset, size) }) + companion object { + const val ELEMENT_SIZE_IN_BYTES = 2 + operator fun invoke(data: ByteArray) = Uint8ClampedBuffer(UByteArrayInt(data)) + } + constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) + constructor(data: UShortArrayInt, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayUInt16(0, data, offset, size) }) - override val size: Int get() = buffer.sizeInBytes / 2 - override operator fun get(index: Int): Int = buffer.getUInt16(index) - override operator fun set(index: Int, value: Int) = buffer.setUInt16(index, value) + override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES + override operator fun get(index: Int): Int = buffer.getU16LE(index * ELEMENT_SIZE_IN_BYTES) + override operator fun set(index: Int, value: Int) = buffer.set16LE(index * ELEMENT_SIZE_IN_BYTES, value.toShort()) fun getArray(index: Int, out: UShortArrayInt, offset: Int = 0, size: Int = out.size - offset): UShortArrayInt = buffer.getArrayUInt16(index, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): UShortArrayInt = getArray(index, UShortArrayInt(size)) fun setArray(index: Int, inp: UShortArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayUInt16(index, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Uint16Buffer = Uint16Buffer(buffer.slice(start * 2, end * 2)) - fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint16Buffer = Uint16Buffer(buffer.sliceWithSize(start * 2, size * 2)) + fun slice(start: Int = 0, end: Int = this.size): Uint16Buffer = Uint16Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint16Buffer = slice(start, start + size) } @JvmInline value class Int32Buffer(override val buffer: Buffer) : TypedBuffer, BaseIntBuffer { - constructor(size: Int, direct: Boolean = false) : this(Buffer(size * 4, direct)) - constructor(data: IntArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * 4).also { it.setArrayInt32(0, data, offset, size) }) + companion object { + const val ELEMENT_SIZE_IN_BYTES = 4 + } + constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) + constructor(data: IntArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayInt32(0, data, offset, size) }) - override val size: Int get() = buffer.sizeInBytes / 4 - override operator fun get(index: Int): Int = buffer.getInt32(index) - override operator fun set(index: Int, value: Int) = buffer.setInt32(index, value) + override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES + override operator fun get(index: Int): Int = buffer.getS32LE(index * ELEMENT_SIZE_IN_BYTES) + override operator fun set(index: Int, value: Int) = buffer.set32LE(index * ELEMENT_SIZE_IN_BYTES, value) fun getArray(index: Int, out: IntArray, offset: Int = 0, size: Int = out.size - offset): IntArray = buffer.getArrayInt32(index, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): IntArray = getArray(index, IntArray(size)) fun setArray(index: Int, inp: IntArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayInt32(index, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Int32Buffer = Int32Buffer(buffer.slice(start * 4, end * 4)) - fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int32Buffer = - Int32Buffer(buffer.sliceWithSize(start * 4, size * 4)) + fun slice(start: Int = 0, end: Int = this.size): Int32Buffer = Int32Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int32Buffer = slice(start, start + size) } @JvmInline value class Uint32Buffer(override val buffer: Buffer) : TypedBuffer { - constructor(size: Int, direct: Boolean = false) : this(Buffer(size * 4, direct)) - constructor(data: UIntArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * 4).also { it.setArrayInt32(0, data.toIntArray(), offset, size) }) + companion object { + const val ELEMENT_SIZE_IN_BYTES = 4 + } + constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) + constructor(data: UIntArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayInt32(0, data.toIntArray(), offset, size) }) - override val size: Int get() = buffer.sizeInBytes / 4 - operator fun get(index: Int): UInt = buffer.getInt32(index).toUInt() - operator fun set(index: Int, value: UInt) = buffer.setInt32(index, value.toInt()) - operator fun set(index: Int, value: Int) = buffer.setInt32(index, value) + override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES + operator fun get(index: Int): UInt = buffer.getS32LE(index * ELEMENT_SIZE_IN_BYTES).toUInt() + operator fun set(index: Int, value: UInt) = buffer.set32LE(index * ELEMENT_SIZE_IN_BYTES, value.toInt()) + operator fun set(index: Int, value: Int) = buffer.set32LE(index * ELEMENT_SIZE_IN_BYTES, value) fun getArray(index: Int, out: UIntArray, offset: Int = 0, size: Int = out.size - offset): UIntArray = buffer.getArrayInt32(index, out.asIntArray(), offset, size).asUIntArray() fun getArray(index: Int = 0, size: Int = this.size - index): UIntArray = getArray(index, UIntArray(size)) fun setArray(index: Int, inp: UIntArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayInt32(index, inp.asIntArray(), offset, size) - fun slice(start: Int = 0, end: Int = this.size): Int32Buffer = Int32Buffer(buffer.slice(start * 4, end * 4)) - fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int32Buffer = - Int32Buffer(buffer.sliceWithSize(start * 4, size * 4)) + fun slice(start: Int = 0, end: Int = this.size): Uint32Buffer = Uint32Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint32Buffer = slice(start, start + size) } @JvmInline value class Int64Buffer(override val buffer: Buffer) : TypedBuffer { - constructor(size: Int, direct: Boolean = false) : this(Buffer(size * 8, direct)) - constructor(data: LongArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * 8).also { it.setArrayInt64(0, data, offset, size) }) + companion object { + const val ELEMENT_SIZE_IN_BYTES = 8 + } + constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) + constructor(data: LongArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayInt64(0, data, offset, size) }) - override val size: Int get() = buffer.sizeInBytes / 8 - operator fun get(index: Int): Long = buffer.getInt64(index) - operator fun set(index: Int, value: Long) = buffer.setInt64(index, value) + override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES + operator fun get(index: Int): Long = buffer.getS64LE(index * ELEMENT_SIZE_IN_BYTES) + operator fun set(index: Int, value: Long) = buffer.set64LE(index * ELEMENT_SIZE_IN_BYTES, value) fun getArray(index: Int, out: LongArray, offset: Int = 0, size: Int = out.size - offset): LongArray = buffer.getArrayInt64(index, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): LongArray = getArray(index, LongArray(size)) fun setArray(index: Int, inp: LongArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayInt64(index, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Int64Buffer = Int64Buffer(buffer.slice(start * 8, end * 8)) - fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int64Buffer = Int64Buffer(buffer.sliceWithSize(start * 8, size * 8)) + fun slice(start: Int = 0, end: Int = this.size): Int64Buffer = Int64Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int64Buffer = slice(start, start + size) } @JvmInline value class Float32Buffer(override val buffer: Buffer) : TypedBuffer, BaseFloatBuffer { - constructor(size: Int, direct: Boolean = false) : this(Buffer(size * 4, direct)) - constructor(data: FloatArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * 4).also { it.setArrayFloat32(0, data, offset, size) }) + companion object { + const val ELEMENT_SIZE_IN_BYTES = 4 + } + constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) + constructor(data: FloatArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayFloat32(0, data, offset, size) }) - override val size: Int get() = buffer.sizeInBytes / 4 - override operator fun get(index: Int): Float = buffer.getFloat32(index) - override operator fun set(index: Int, value: Float) = buffer.setFloat32(index, value) + override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES + override operator fun get(index: Int): Float = buffer.getF32LE(index * ELEMENT_SIZE_IN_BYTES) + override operator fun set(index: Int, value: Float) = buffer.setF32LE(index * ELEMENT_SIZE_IN_BYTES, value) fun getArray(index: Int, out: FloatArray, offset: Int = 0, size: Int = out.size - offset): FloatArray = buffer.getArrayFloat32(index, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): FloatArray = getArray(index, FloatArray(size)) fun setArray(index: Int, inp: FloatArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayFloat32(index, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Float32Buffer = - Float32Buffer(buffer.slice(start * 4, end * 4)) - fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Float32Buffer = - Float32Buffer(buffer.sliceWithSize(start * 4, size * 4)) + fun slice(start: Int = 0, end: Int = this.size): Float32Buffer = Float32Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Float32Buffer = slice(start, start + size) } @JvmInline value class Float64Buffer(override val buffer: Buffer) : TypedBuffer { - constructor(size: Int, direct: Boolean = false) : this(Buffer(size * 8, direct)) - constructor(data: DoubleArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * 8).also { it.setArrayFloat64(0, data, offset, size) }) + companion object { + const val ELEMENT_SIZE_IN_BYTES = 8 + } + constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) + constructor(data: DoubleArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayFloat64(0, data, offset, size) }) - override val size: Int get() = buffer.sizeInBytes / 8 - operator fun get(index: Int): Double = buffer.getFloat64(index) - operator fun set(index: Int, value: Double) = buffer.setFloat64(index, value) + override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES + operator fun get(index: Int): Double = buffer.getF64LE(index * ELEMENT_SIZE_IN_BYTES) + operator fun set(index: Int, value: Double) = buffer.setF64LE(index * ELEMENT_SIZE_IN_BYTES, value) fun getArray(index: Int, out: DoubleArray, offset: Int = 0, size: Int = out.size - offset): DoubleArray = buffer.getArrayFloat64(index, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): DoubleArray = getArray(index, DoubleArray(size)) fun setArray(index: Int, inp: DoubleArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayFloat64(index, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Float64Buffer = - Float64Buffer(buffer.slice(start * 8, end * 8)) - fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Float64Buffer = - Float64Buffer(buffer.sliceWithSize(start * 8, size * 8)) + fun slice(start: Int = 0, end: Int = this.size): Float64Buffer = Float64Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Float64Buffer = slice(start, start + size) } -val Buffer.u8: Uint8Buffer get() = Uint8Buffer(this) -val Buffer.u16: Uint16Buffer get() = Uint16Buffer(this) -val Buffer.i8: Int8Buffer get() = Int8Buffer(this) -val Buffer.i16: Int16Buffer get() = Int16Buffer(this) -val Buffer.i32: Int32Buffer get() = Int32Buffer(this) -val Buffer.i64: Int64Buffer get() = Int64Buffer(this) -val Buffer.f32: Float32Buffer get() = Float32Buffer(this) -val Buffer.f64: Float64Buffer get() = Float64Buffer(this) +@Deprecated("", ReplaceWith("asUInt8()")) val Buffer.u8: Uint8Buffer get() = asUInt8() +@Deprecated("", ReplaceWith("asUInt16()")) val Buffer.u16: Uint16Buffer get() = asUInt16() +@Deprecated("", ReplaceWith("asInt8()")) val Buffer.i8: Int8Buffer get() = asInt8() +@Deprecated("", ReplaceWith("asInt16()")) val Buffer.i16: Int16Buffer get() = asInt16() +@Deprecated("", ReplaceWith("asInt32()")) val Buffer.i32: Int32Buffer get() = asInt32() +@Deprecated("", ReplaceWith("asInt64()")) val Buffer.i64: Int64Buffer get() = asInt64() +@Deprecated("", ReplaceWith("asFloat32()")) val Buffer.f32: Float32Buffer get() = asFloat32() +@Deprecated("", ReplaceWith("asFloat64()")) val Buffer.f64: Float64Buffer get() = asFloat64() + +fun Buffer.asUInt8(): Uint8Buffer = Uint8Buffer(this) +fun Buffer.asUInt16(): Uint16Buffer = Uint16Buffer(this) +fun Buffer.asInt8(): Int8Buffer = Int8Buffer(this) +fun Buffer.asInt16(): Int16Buffer = Int16Buffer(this) +fun Buffer.asInt32(): Int32Buffer = Int32Buffer(this) +fun Buffer.asInt64(): Int64Buffer = Int64Buffer(this) +fun Buffer.asFloat32(): Float32Buffer = Float32Buffer(this) +fun Buffer.asFloat64(): Float64Buffer = Float64Buffer(this) fun TypedBuffer.asUInt8(): Uint8Buffer = this.buffer.u8 fun TypedBuffer.asUInt16(): Uint16Buffer = this.buffer.u16 diff --git a/korge-foundation/src/commonTest/kotlin/korlibs/memory/NBufferTest.kt b/korge-foundation/src/commonTest/kotlin/korlibs/memory/NBufferTest.kt index 83dbd1b60c..31071e197e 100644 --- a/korge-foundation/src/commonTest/kotlin/korlibs/memory/NBufferTest.kt +++ b/korge-foundation/src/commonTest/kotlin/korlibs/memory/NBufferTest.kt @@ -428,7 +428,7 @@ open class NBufferTestBase { @Test fun testCopy() { val bufferBase = Buffer(ByteArray(16) { it.toByte() }) - val buffer = bufferBase.slice(1) + val buffer = bufferBase._slice(1) val buffer2 = Buffer(14, direct) Buffer.copy(buffer, 2, buffer2, 5, 7) assertEquals("0000000000030405060708090000", buffer2.hex()) @@ -440,7 +440,7 @@ open class NBufferTestBase { for (direct2 in listOf(false, true)) { val bufferBase = Buffer(16, direct1) for (n in 0 until 16) bufferBase.setUnalignedUInt8(n, n) - val buffer = bufferBase.slice(1) + val buffer = bufferBase._slice(1) val buffer2 = Buffer(14, direct2) Buffer.copy(buffer, 2, buffer2, 5, 7) assertEquals("0000000000030405060708090000", buffer2.hex()) @@ -454,9 +454,9 @@ open class NBufferTestBase { for (direct2 in listOf(false, true)) { val bufferBase = Buffer(16, direct1) for (n in 0 until 16) bufferBase.setUnalignedUInt8(n, n) - val buffer = bufferBase.slice(1) - val buffer2 = buffer.slice(2) - Buffer.copy(buffer.slice(1), 2, buffer2, 5, 7) + val buffer = bufferBase._slice(1) + val buffer2 = buffer._slice(2) + Buffer.copy(buffer._slice(1), 2, buffer2, 5, 7) assertEquals("03040506070405060708090a0f", buffer2.hex()) } } diff --git a/korge-foundation/src/commonTest/kotlin/korlibs/memory/NBufferTest2.kt b/korge-foundation/src/commonTest/kotlin/korlibs/memory/NBufferTest2.kt index 5d37d9b03e..0376875ab0 100644 --- a/korge-foundation/src/commonTest/kotlin/korlibs/memory/NBufferTest2.kt +++ b/korge-foundation/src/commonTest/kotlin/korlibs/memory/NBufferTest2.kt @@ -69,8 +69,8 @@ class NBufferTest2 { assertEquals(0x03020100, mem.getInt32(0)) assertEquals(0x07060504, mem.getInt32(1)) - assertEquals(0x03020100, mem.getUnalignedInt32(0)) - assertEquals(0x04030201, mem.getUnalignedInt32(1)) - assertEquals(0x05040302, mem.getUnalignedInt32(2)) + assertEquals(0x03020100, mem.getS32(0)) + assertEquals(0x04030201, mem.getS32(1)) + assertEquals(0x05040302, mem.getS32(2)) } } diff --git a/korge-foundation/src/darwinMain/kotlin/korlibs/memory/BufferNative.kt b/korge-foundation/src/darwinMain/kotlin/korlibs/memory/BufferNative.kt index 5b8f9b81f5..f3729b20ea 100644 --- a/korge-foundation/src/darwinMain/kotlin/korlibs/memory/BufferNative.kt +++ b/korge-foundation/src/darwinMain/kotlin/korlibs/memory/BufferNative.kt @@ -1,14 +1,59 @@ -@file:OptIn(ExperimentalNativeApi::class, ExperimentalNativeApi::class) - package korlibs.memory import kotlinx.cinterop.* import platform.posix.* import kotlin.experimental.* +@OptIn(ExperimentalNativeApi::class) actual class Buffer(val data: ByteArray, val offset: Int, val size: Int, dummy: Unit) { + actual constructor(size: Int, direct: Boolean) : this(ByteArray(checkNBufferSize(size)), 0, size, Unit) + actual constructor(array: ByteArray, offset: Int, size: Int): this(checkNBufferWrap(array, offset, size), offset, size, Unit) + actual val byteOffset: Int get() = offset + actual val sizeInBytes: Int get() = size + val end: Int = offset + size + internal actual fun sliceInternal(start: Int, end: Int): Buffer = Buffer(data, offset + start, end - start) + + actual fun getS8(byteOffset: Int): Byte = data[offset + byteOffset] + actual fun getS16LE(byteOffset: Int): Short = data.getShortAt(offset + byteOffset) + actual fun getS32LE(byteOffset: Int): Int = data.getIntAt(offset + byteOffset) + actual fun getS64LE(byteOffset: Int): Long = data.getLongAt(offset + byteOffset) + actual fun getF32LE(byteOffset: Int): Float = data.getFloatAt(offset + byteOffset) + actual fun getF64LE(byteOffset: Int): Double = data.getDoubleAt(offset + byteOffset) + + actual fun getS16BE(byteOffset: Int): Short = getS16LE(byteOffset).reverseBytes() + actual fun getS32BE(byteOffset: Int): Int = getS32LE(byteOffset).reverseBytes() + actual fun getS64BE(byteOffset: Int): Long = getS64LE(byteOffset).reverseBytes() + actual fun getF32BE(byteOffset: Int): Float = getS32BE(byteOffset).reinterpretAsFloat() + actual fun getF64BE(byteOffset: Int): Double = getS64BE(byteOffset).reinterpretAsDouble() + + actual fun set8(byteOffset: Int, value: Byte) { data[offset + byteOffset] = value } + actual fun set16LE(byteOffset: Int, value: Short) { data.setShortAt(offset + byteOffset, value) } + actual fun set32LE(byteOffset: Int, value: Int) { data.setIntAt(offset + byteOffset, value) } + actual fun set64LE(byteOffset: Int, value: Long) { data.setLongAt(offset + byteOffset, value) } + actual fun setF32LE(byteOffset: Int, value: Float) { data.setFloatAt(offset + byteOffset, value) } + actual fun setF64LE(byteOffset: Int, value: Double) { data.setDoubleAt(offset + byteOffset, value) } + + actual fun set16BE(byteOffset: Int, value: Short) { set16LE(byteOffset, value.reverseBytes()) } + actual fun set32BE(byteOffset: Int, value: Int) { set32LE(byteOffset, value.reverseBytes()) } + actual fun set64BE(byteOffset: Int, value: Long) { set64LE(byteOffset, value.reverseBytes()) } + actual fun setF32BE(byteOffset: Int, value: Float) { set32BE(byteOffset, value.reinterpretAsInt()) } + actual fun setF64BE(byteOffset: Int, value: Double) { set64BE(byteOffset, value.reinterpretAsLong()) } + + + override fun hashCode(): Int = hashCodeCommon(this) + override fun equals(other: Any?): Boolean = equalsCommon(this, other) override fun toString(): String = NBuffer_toString(this) + + actual fun transferBytes(bufferOffset: Int, array: ByteArray, arrayOffset: Int, len: Int, toArray: Boolean) { + val bufOffset = this.byteOffset + bufferOffset + if (toArray) { + arraycopy(this.data, bufOffset, array, arrayOffset, len) + } else { + arraycopy(array, arrayOffset, this.data, bufOffset, len) + } + } + actual companion object { actual fun equals(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int): Boolean { check(srcPosBytes + sizeInBytes <= src.sizeInBytes) @@ -27,50 +72,7 @@ actual class Buffer(val data: ByteArray, val offset: Int, val size: Int, dummy: ) } } - - // @TODO: Optimize by using words instead o bytes - override fun hashCode(): Int { - var h = 1 - for (n in 0 until size) h = 31 * h + data[offset + n] - return h - } - - // @TODO: Optimize by using words instead o bytes - override fun equals(other: Any?): Boolean { - if (other !is Buffer || this.size != other.size) return false - val t = this.data - val o = other.data - for (n in 0 until size) if (t[this.offset + n] != o[other.offset + n]) return false - return true - } } -actual fun Buffer(size: Int, direct: Boolean): Buffer { - checkNBufferSize(size) - return Buffer(ByteArray(size), 0, size, Unit) -} -actual fun Buffer(array: ByteArray, offset: Int, size: Int): Buffer { - checkNBufferWrap(array, offset, size) - return Buffer(array, offset, size, Unit) -} -actual val Buffer.byteOffset: Int get() = offset -actual val Buffer.sizeInBytes: Int get() = size -internal actual fun Buffer.sliceInternal(start: Int, end: Int): Buffer = Buffer(data, offset + start, end - start) - -// Unaligned versions - -actual fun Buffer.getUnalignedInt8(byteOffset: Int): Byte = data[offset + byteOffset] -actual fun Buffer.getUnalignedInt16(byteOffset: Int): Short = data.getShortAt(offset + byteOffset) -actual fun Buffer.getUnalignedInt32(byteOffset: Int): Int = data.getIntAt(offset + byteOffset) -actual fun Buffer.getUnalignedInt64(byteOffset: Int): Long = data.getLongAt(offset + byteOffset) -actual fun Buffer.getUnalignedFloat32(byteOffset: Int): Float = data.getFloatAt(offset + byteOffset) -actual fun Buffer.getUnalignedFloat64(byteOffset: Int): Double = data.getDoubleAt(offset + byteOffset) - -actual fun Buffer.setUnalignedInt8(byteOffset: Int, value: Byte) { data[offset + byteOffset] = value } -actual fun Buffer.setUnalignedInt16(byteOffset: Int, value: Short) { data.setShortAt(offset + byteOffset, value) } -actual fun Buffer.setUnalignedInt32(byteOffset: Int, value: Int) { data.setIntAt(offset + byteOffset, value) } -actual fun Buffer.setUnalignedInt64(byteOffset: Int, value: Long) { data.setLongAt(offset + byteOffset, value) } -actual fun Buffer.setUnalignedFloat32(byteOffset: Int, value: Float) { data.setFloatAt(offset + byteOffset, value) } -actual fun Buffer.setUnalignedFloat64(byteOffset: Int, value: Double) { data.setDoubleAt(offset + byteOffset, value) } class NBufferTempAddress { val pool = arrayListOf>() diff --git a/korge-foundation/src/jsMain/kotlin/korlibs/memory/Buffer.js.kt b/korge-foundation/src/jsMain/kotlin/korlibs/memory/Buffer.js.kt new file mode 100644 index 0000000000..de280fba7f --- /dev/null +++ b/korge-foundation/src/jsMain/kotlin/korlibs/memory/Buffer.js.kt @@ -0,0 +1,103 @@ +package korlibs.memory + +import korlibs.platform.* +import org.khronos.webgl.* + +actual class Buffer(val dataView: DataView) { + actual constructor(size: Int, direct: Boolean) : this(DataView(ArrayBuffer(checkNBufferSize(size)))) + actual constructor(array: ByteArray, offset: Int, size: Int) : this(DataView(checkNBufferWrap(array, offset, size).unsafeCast().buffer, offset, size)) + + actual val byteOffset: Int get() = this.dataView.byteOffset + actual val sizeInBytes: Int get() = this.dataView.byteLength + + actual fun sliceInternal(start: Int, end: Int): Buffer = + Buffer(DataView(this.buffer, this.byteOffset + start, end - start)) + + fun sliceUint8Array(offset: Int = 0, size: Int = dataView.byteLength - offset): Uint8Array = + Uint8Array(buffer, dataView.byteOffset + offset, size) + + actual fun transferBytes(bufferOffset: Int, array: ByteArray, arrayOffset: Int, len: Int, toArray: Boolean) { + val bufferSlice = Int8Array(this.dataView.buffer, this.dataView.byteOffset + bufferOffset, len) + val arraySlice = array.unsafeCast().subarray(arrayOffset, arrayOffset + len) + if (toArray) { + arraySlice.set(bufferSlice, 0) + } else { + bufferSlice.set(arraySlice, 0) + } + } + + actual fun getS8(byteOffset: Int): Byte = dataView.getInt8(byteOffset) + actual fun getS16LE(byteOffset: Int): Short = dataView.getInt16(byteOffset, true) + actual fun getS32LE(byteOffset: Int): Int = dataView.getInt32(byteOffset, true) + actual fun getS64LE(byteOffset: Int): Long { + val v0 = getS32LE(byteOffset).toLong() and 0xFFFFFFFFL + val v1 = getS32LE(byteOffset + 4).toLong() and 0xFFFFFFFFL + return if (currentIsLittleEndian) (v1 shl 32) or v0 else (v0 shl 32) or v1 + } + actual fun getF32LE(byteOffset: Int): Float = dataView.getFloat32(byteOffset, true) + actual fun getF64LE(byteOffset: Int): Double = dataView.getFloat64(byteOffset, true) + actual fun getS16BE(byteOffset: Int): Short = dataView.getInt16(byteOffset, false) + actual fun getS32BE(byteOffset: Int): Int = dataView.getInt32(byteOffset, false) + actual fun getS64BE(byteOffset: Int): Long { + val v0 = getS32BE(byteOffset).toLong() and 0xFFFFFFFFL + val v1 = getS32BE(byteOffset + 4).toLong() and 0xFFFFFFFFL + return (v0 shl 32) or v1 + } + actual fun getF32BE(byteOffset: Int): Float = dataView.getFloat32(byteOffset, false) + actual fun getF64BE(byteOffset: Int): Double = dataView.getFloat64(byteOffset, false) + + actual fun set8(byteOffset: Int, value: Byte) = dataView.setInt8(byteOffset, value) + actual fun set16LE(byteOffset: Int, value: Short) = dataView.setInt16(byteOffset, value, true) + actual fun set32LE(byteOffset: Int, value: Int) = dataView.setInt32(byteOffset, value, true) + actual fun set64LE(byteOffset: Int, value: Long) { + set32LE(byteOffset, value.toInt()) + set32LE(byteOffset + 4, (value ushr 32).toInt()) + } + actual fun setF32LE(byteOffset: Int, value: Float) = dataView.setFloat32(byteOffset, value, true) + actual fun setF64LE(byteOffset: Int, value: Double) = dataView.setFloat64(byteOffset, value, true) + + actual fun set16BE(byteOffset: Int, value: Short) = dataView.setInt16(byteOffset, value, false) + actual fun set32BE(byteOffset: Int, value: Int) = dataView.setInt32(byteOffset, value, false) + actual fun set64BE(byteOffset: Int, value: Long) { + set32BE(byteOffset, (value ushr 32).toInt()) + set32BE(byteOffset + 4, value.toInt()) + } + actual fun setF32BE(byteOffset: Int, value: Float) = dataView.setFloat32(byteOffset, value, false) + actual fun setF64BE(byteOffset: Int, value: Double) = dataView.setFloat64(byteOffset, value, false) + + override fun hashCode(): Int = hashCodeCommon(this) + override fun equals(other: Any?): Boolean = equalsCommon(this, other) + override fun toString(): String = NBuffer_toString(this) + + actual companion object { + actual fun copy(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int) { + dst.sliceUint8Array(dstPosBytes, sizeInBytes).set(src.sliceUint8Array(srcPosBytes, sizeInBytes), 0) + } + + actual fun equals(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int): Boolean = equalsCommon(src, srcPosBytes, dst, dstPosBytes, sizeInBytes, use64 = false) + } +} + +val Buffer.buffer: ArrayBuffer get() = dataView.buffer + +fun ArrayBuffer.asUint8ClampedArray(): Uint8ClampedArray = Uint8ClampedArray(this) +fun ArrayBuffer.asUint8Array(): Uint8Array = Uint8Array(this) +fun ArrayBuffer.asInt8Array(): Int8Array = Int8Array(this) +fun ArrayBuffer.asInt16Array(): Int16Array = Int16Array(this) +fun ArrayBuffer.asInt32Array(): Int32Array = Int32Array(this) +fun ArrayBuffer.asFloat32Array(): Float32Array = Float32Array(this) +fun ArrayBuffer.asFloat64Array(): Float64Array = Float64Array(this) + +fun ArrayBuffer.asUByteArray(): UByteArray = asUint8Array().unsafeCast().asUByteArray() +fun ArrayBuffer.asByteArray(): ByteArray = asInt8Array().unsafeCast() +fun ArrayBuffer.asShortArray(): ShortArray = asInt16Array().unsafeCast() +fun ArrayBuffer.asIntArray(): IntArray = asInt32Array().unsafeCast() +fun ArrayBuffer.asFloatArray(): FloatArray = asFloat32Array().unsafeCast() +fun ArrayBuffer.asDoubleArray(): DoubleArray = asFloat64Array().unsafeCast() + +val Buffer.arrayUByte: Uint8Array get() = Uint8Array(this.buffer, byteOffset, sizeInBytes) +val Buffer.arrayByte: Int8Array get() = Int8Array(buffer, byteOffset, sizeInBytes) +val Buffer.arrayShort: Int16Array get() = Int16Array(buffer, byteOffset, sizeInBytes / 2) +val Buffer.arrayInt: Int32Array get() = Int32Array(buffer, byteOffset, sizeInBytes / 4) +val Buffer.arrayFloat: Float32Array get() = Float32Array(buffer, byteOffset, sizeInBytes / 4) +val Buffer.arrayDouble: Float64Array get() = Float64Array(buffer, byteOffset, sizeInBytes / 8) diff --git a/korge-foundation/src/jsMain/kotlin/korlibs/memory/BufferJs.kt b/korge-foundation/src/jsMain/kotlin/korlibs/memory/BufferJs.kt deleted file mode 100644 index 809c7df645..0000000000 --- a/korge-foundation/src/jsMain/kotlin/korlibs/memory/BufferJs.kt +++ /dev/null @@ -1,92 +0,0 @@ -package korlibs.memory - -import korlibs.platform.* -import org.khronos.webgl.* - -actual class Buffer(val dataView: DataView) { - val buffer: ArrayBuffer get() = dataView.buffer - - fun sliceUint8Array(offset: Int = 0, size: Int = dataView.byteLength - offset): Uint8Array = - Uint8Array(buffer, dataView.byteOffset + offset, size) - override fun toString(): String = NBuffer_toString(this) - actual companion object { - actual fun copy(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int) { - dst.sliceUint8Array(dstPosBytes, sizeInBytes).set(src.sliceUint8Array(srcPosBytes, sizeInBytes), 0) - } - - actual fun equals(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int): Boolean = equalsCommon(src, srcPosBytes, dst, dstPosBytes, sizeInBytes, use64 = false) - } - - - // @TODO: Optimize by using words instead o bytes - override fun hashCode(): Int { - var h = 1 - for (n in 0 until size) h = 31 * h + dataView.getInt8(n) - return h - } - - // @TODO: Optimize by using words instead o bytes - override fun equals(other: Any?): Boolean { - if (other !is Buffer || this.size != other.size) return false - val t = this.dataView - val o = other.dataView - for (n in 0 until size) if (t.getInt8(n) != o.getInt8(n)) return false - return true - } -} -actual fun Buffer(size: Int, direct: Boolean): Buffer { - checkNBufferSize(size) - return Buffer(DataView(ArrayBuffer(size))) -} -actual fun Buffer(array: ByteArray, offset: Int, size: Int): Buffer { - checkNBufferWrap(array, offset, size) - return Buffer(DataView(array.unsafeCast().buffer, offset, size)) -} -actual val Buffer.byteOffset: Int get() = this.dataView.byteOffset -actual val Buffer.sizeInBytes: Int get() = this.dataView.byteLength -actual fun Buffer.sliceInternal(start: Int, end: Int): Buffer = Buffer(DataView(this.buffer, this.byteOffset + start, end - start)) - -// Unaligned versions - -actual fun Buffer.getUnalignedInt8(byteOffset: Int): Byte = dataView.getInt8(byteOffset) -actual fun Buffer.getUnalignedInt16(byteOffset: Int): Short = dataView.getInt16(byteOffset, currentIsLittleEndian) -actual fun Buffer.getUnalignedInt32(byteOffset: Int): Int = dataView.getInt32(byteOffset, currentIsLittleEndian) -actual fun Buffer.getUnalignedInt64(byteOffset: Int): Long { - val v0 = getUnalignedInt32(byteOffset).toLong() and 0xFFFFFFFFL - val v1 = getUnalignedInt32(byteOffset + 4).toLong() and 0xFFFFFFFFL - return if (currentIsLittleEndian) (v1 shl 32) or v0 else (v0 shl 32) or v1 -} -actual fun Buffer.getUnalignedFloat32(byteOffset: Int): Float = dataView.getFloat32(byteOffset, currentIsLittleEndian) -actual fun Buffer.getUnalignedFloat64(byteOffset: Int): Double = dataView.getFloat64(byteOffset, currentIsLittleEndian) - -actual fun Buffer.setUnalignedInt8(byteOffset: Int, value: Byte) = dataView.setInt8(byteOffset, value) -actual fun Buffer.setUnalignedInt16(byteOffset: Int, value: Short) = dataView.setInt16(byteOffset, value, currentIsLittleEndian) -actual fun Buffer.setUnalignedInt32(byteOffset: Int, value: Int) = dataView.setInt32(byteOffset, value, currentIsLittleEndian) -actual fun Buffer.setUnalignedInt64(byteOffset: Int, value: Long) { - setUnalignedInt32(byteOffset, if (currentIsLittleEndian) value.toInt() else (value ushr 32).toInt()) - setUnalignedInt32(byteOffset + 4, if (!currentIsLittleEndian) value.toInt() else (value ushr 32).toInt()) -} -actual fun Buffer.setUnalignedFloat32(byteOffset: Int, value: Float) = dataView.setFloat32(byteOffset, value, currentIsLittleEndian) -actual fun Buffer.setUnalignedFloat64(byteOffset: Int, value: Double) = dataView.setFloat64(byteOffset, value, currentIsLittleEndian) - -fun ArrayBuffer.asUint8ClampedArray(): Uint8ClampedArray = Uint8ClampedArray(this) -fun ArrayBuffer.asUint8Array(): Uint8Array = Uint8Array(this) -fun ArrayBuffer.asInt8Array(): Int8Array = Int8Array(this) -fun ArrayBuffer.asInt16Array(): Int16Array = Int16Array(this) -fun ArrayBuffer.asInt32Array(): Int32Array = Int32Array(this) -fun ArrayBuffer.asFloat32Array(): Float32Array = Float32Array(this) -fun ArrayBuffer.asFloat64Array(): Float64Array = Float64Array(this) - -fun ArrayBuffer.asUByteArray(): UByteArray = asUint8Array().unsafeCast().asUByteArray() -fun ArrayBuffer.asByteArray(): ByteArray = asInt8Array().unsafeCast() -fun ArrayBuffer.asShortArray(): ShortArray = asInt16Array().unsafeCast() -fun ArrayBuffer.asIntArray(): IntArray = asInt32Array().unsafeCast() -fun ArrayBuffer.asFloatArray(): FloatArray = asFloat32Array().unsafeCast() -fun ArrayBuffer.asDoubleArray(): DoubleArray = asFloat64Array().unsafeCast() - -val Buffer.arrayUByte: Uint8Array get() = Uint8Array(this.buffer, byteOffset, sizeInBytes) -val Buffer.arrayByte: Int8Array get() = Int8Array(buffer, byteOffset, sizeInBytes) -val Buffer.arrayShort: Int16Array get() = Int16Array(buffer, byteOffset, sizeInBytes / 2) -val Buffer.arrayInt: Int32Array get() = Int32Array(buffer, byteOffset, sizeInBytes / 4) -val Buffer.arrayFloat: Float32Array get() = Float32Array(buffer, byteOffset, sizeInBytes / 4) -val Buffer.arrayDouble: Float64Array get() = Float64Array(buffer, byteOffset, sizeInBytes / 8) diff --git a/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/Buffer.jvm.kt b/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/Buffer.jvm.kt new file mode 100644 index 0000000000..7a42ba55f1 --- /dev/null +++ b/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/Buffer.jvm.kt @@ -0,0 +1,131 @@ +package korlibs.memory + +import java.nio.* + +actual class Buffer(val buffer: ByteBuffer) { + val bufferLE = buffer.duplicate().order(ByteOrder.LITTLE_ENDIAN) + val bufferBE = buffer.duplicate().order(ByteOrder.BIG_ENDIAN) + actual val byteOffset: Int = buffer.position() + actual val sizeInBytes: Int = buffer.limit() - buffer.position() + + actual constructor(size: Int, direct: Boolean) : this( + (if (direct) ByteBuffer.allocateDirect(checkNBufferSize(size)) else ByteBuffer.wrap(ByteArray(checkNBufferSize(size)))).order(ByteOrder.nativeOrder()) + ) + actual constructor(array: ByteArray, offset: Int, size: Int) : this( + ByteBuffer.wrap(checkNBufferWrap(array, offset, size), offset, size).order(ByteOrder.nativeOrder()) + .also { it.positionSafe(offset); it.limitSafe(offset + size) } + ) + + actual fun sliceInternal(start: Int, end: Int): Buffer = Buffer(slicedBuffer(start, end - start)) + actual fun transferBytes(bufferOffset: Int, array: ByteArray, arrayOffset: Int, len: Int, toArray: Boolean): Unit { + val temp = slicedBuffer(bufferOffset) + if (toArray) { + temp.get(array, arrayOffset, len) + } else { + temp.put(array, arrayOffset, len) + } + } + + fun slicedBuffer(roffset: Int = 0, rsize: Int = this.size - roffset): ByteBuffer { + val pos = this.byteOffset + roffset + return buffer.duplicate().also { + it.order(ByteOrder.nativeOrder()) + it.positionSafe(pos) + it.limitSafe(pos + rsize) + } + } + + actual fun getS8(byteOffset: Int): Byte = bufferLE.get(this.byteOffset + byteOffset) + actual fun getS16LE(byteOffset: Int): Short = bufferLE.getShort(this.byteOffset + byteOffset) + actual fun getS32LE(byteOffset: Int): Int = bufferLE.getInt(this.byteOffset + byteOffset) + actual fun getS64LE(byteOffset: Int): Long = bufferLE.getLong(this.byteOffset + byteOffset) + actual fun getF32LE(byteOffset: Int): Float = bufferLE.getFloat(this.byteOffset + byteOffset) + actual fun getF64LE(byteOffset: Int): Double = bufferLE.getDouble(this.byteOffset + byteOffset) + actual fun getS16BE(byteOffset: Int): Short = bufferBE.getShort(this.byteOffset + byteOffset) + actual fun getS32BE(byteOffset: Int): Int = bufferBE.getInt(this.byteOffset + byteOffset) + actual fun getS64BE(byteOffset: Int): Long = bufferBE.getLong(this.byteOffset + byteOffset) + actual fun getF32BE(byteOffset: Int): Float = bufferBE.getFloat(this.byteOffset + byteOffset) + actual fun getF64BE(byteOffset: Int): Double = bufferBE.getDouble(this.byteOffset + byteOffset) + + + actual fun set8(byteOffset: Int, value: Byte) { bufferLE.put(this.byteOffset + byteOffset, value) } + actual fun set16LE(byteOffset: Int, value: Short) { bufferLE.putShort(this.byteOffset + byteOffset, value) } + actual fun set32LE(byteOffset: Int, value: Int) { bufferLE.putInt(this.byteOffset + byteOffset, value) } + actual fun set64LE(byteOffset: Int, value: Long) { bufferLE.putLong(this.byteOffset + byteOffset, value) } + actual fun setF32LE(byteOffset: Int, value: Float) { bufferLE.putFloat(this.byteOffset + byteOffset, value) } + actual fun setF64LE(byteOffset: Int, value: Double) { bufferLE.putDouble(this.byteOffset + byteOffset, value) } + actual fun set16BE(byteOffset: Int, value: Short) { bufferBE.putShort(this.byteOffset + byteOffset, value) } + actual fun set32BE(byteOffset: Int, value: Int) { bufferBE.putInt(this.byteOffset + byteOffset, value) } + actual fun set64BE(byteOffset: Int, value: Long) { bufferBE.putLong(this.byteOffset + byteOffset, value) } + actual fun setF32BE(byteOffset: Int, value: Float) { bufferBE.putFloat(this.byteOffset + byteOffset, value) } + actual fun setF64BE(byteOffset: Int, value: Double) { bufferBE.putDouble(this.byteOffset + byteOffset, value) } + + override fun hashCode(): Int = hashCodeCommon(this) + override fun equals(other: Any?): Boolean = equalsCommon(this, other) + override fun toString(): String = NBuffer_toString(this) + + actual companion object { + actual fun equals(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int): Boolean = + src.slicedBuffer(srcPosBytes, sizeInBytes) == dst.slicedBuffer(dstPosBytes, sizeInBytes) + actual fun copy(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int) { + val srcBuf = src.buffer + val dstBuf = dst.buffer + val srcPos = srcPosBytes + val dstPos = dstPosBytes + val size = sizeInBytes + if (!srcBuf.isDirect && !dstBuf.isDirect) { + System.arraycopy(srcBuf.array(), srcBuf.position() + srcPos, dstBuf.array(), dstBuf.position() + dstPos, size) + return + } + //if (srcBuf === dstBuf) { + // arraycopy(size, srcBuf, srcPosBytes, dstBuf, dstPosBytes, { it, value -> dst.setUnalignedUInt8(it, value) }, { src.getUnalignedUInt8(it) }) + // return + //} + dst.slicedBuffer(dstPosBytes, sizeInBytes).put(src.slicedBuffer(srcPosBytes, sizeInBytes)) + } + + } +} + +@PublishedApi +internal fun java.nio.Buffer.checkSliceBounds(offset: Int, size: Int) { + //val end = offset + size - 1 + //if (offset !in 0 until this.capacity()) error("offset=$offset, size=$size not inside ${this.capacity()}") + //if (end !in 0 until this.capacity()) error("offset=$offset, size=$size not inside ${this.capacity()}") +} + +fun java.nio.Buffer.positionSafe(newPosition: Int) { + position(newPosition) +} + +fun java.nio.Buffer.limitSafe(newLimit: Int) { + limit(newLimit) +} + +fun java.nio.Buffer.flipSafe() { + flip() +} + +fun java.nio.Buffer.clearSafe() { + clear() +} + +inline fun T._slice(offset: Int, size: Int, dup: (T) -> T): T { + checkSliceBounds(offset, size) + val out = dup(this) + val start = this.position() + offset + val end = start + size + out.positionSafe(start) + out.limitSafe(end) + return out +} + +fun ByteBuffer._slice(offset: Int, size: Int): ByteBuffer = this._slice(offset, size) { it.duplicate() } +fun ShortBuffer._slice(offset: Int, size: Int): ShortBuffer = this._slice(offset, size) { it.duplicate() } +fun IntBuffer._slice(offset: Int, size: Int): IntBuffer = this._slice(offset, size) { it.duplicate() } +fun FloatBuffer._slice(offset: Int, size: Int): FloatBuffer = this._slice(offset, size) { it.duplicate() } +fun DoubleBuffer._slice(offset: Int, size: Int): DoubleBuffer = this._slice(offset, size) { it.duplicate() } + +val Buffer.nioBuffer: java.nio.ByteBuffer get() = this.slicedBuffer() +val Buffer.nioIntBuffer: java.nio.IntBuffer get() = this.slicedBuffer().asIntBuffer() +val Buffer.nioFloatBuffer: java.nio.FloatBuffer get() = this.slicedBuffer().asFloatBuffer() diff --git a/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/BufferJvm.kt b/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/BufferJvm.kt deleted file mode 100644 index 3a0d3777b3..0000000000 --- a/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/BufferJvm.kt +++ /dev/null @@ -1,177 +0,0 @@ -package korlibs.memory - -import java.nio.* - -actual class Buffer(val buffer: ByteBuffer, val offset: Int, val size: Int) { - fun slicedBuffer(roffset: Int = 0, rsize: Int = this.size - roffset): ByteBuffer { - val pos = this.offset + roffset - return buffer.duplicate().also { - it.order(ByteOrder.nativeOrder()) - it.positionSafe(pos) - it.limitSafe(pos + rsize) - } - } - - override fun toString(): String = NBuffer_toString(this) - - // @TODO: Optimize by using words instead o bytes - override fun hashCode(): Int { - var h = 1 - for (n in 0 until size) h = 31 * h + buffer[offset + n] - return h - } - - // @TODO: Optimize by using words instead o bytes - override fun equals(other: Any?): Boolean { - if (other !is Buffer || this.size != other.size) return false - val t = this.buffer - val o = other.buffer - for (n in 0 until size) if (t[this.offset + n] != o[other.offset + n]) return false - return true - } - - actual companion object { - actual fun equals(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int): Boolean = - src.slicedBuffer(srcPosBytes, sizeInBytes) == dst.slicedBuffer(dstPosBytes, sizeInBytes) - actual fun copy(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int) { - - //val srcBuf = src.buffer - //val dstBuf = dst.buffer - //val size = sizeInBytes - //val srcPos = src.offset + srcPosBytes - //val dstPos = dst.offset + dstPosBytes - //dstBuf.keepPositionLimit { - // srcBuf.keepPositionLimit { - // dstBuf.positionSafe(dstPos) - // srcBuf.positionSafe(srcPos) - // srcBuf.limitSafe(srcPos + size) - // dstBuf.put(srcBuf) - // } - //} - val srcBuf = src.buffer - val dstBuf = dst.buffer - val srcPos = src.offset + srcPosBytes - val dstPos = dst.offset + dstPosBytes - val size = sizeInBytes - - if (!srcBuf.isDirect && !dstBuf.isDirect) { - System.arraycopy(srcBuf.array(), srcPos, dstBuf.array(), dstPos, size) - return - } - - if (srcBuf === dstBuf) { - arraycopy(size, srcBuf, srcPosBytes, dstBuf, dstPosBytes, { it, value -> dst.setUnalignedUInt8(it, value) }, { src.getUnalignedUInt8(it) }) - return - } - - dst.slicedBuffer(dstPosBytes, sizeInBytes).put(src.slicedBuffer(srcPosBytes, sizeInBytes)) - } - - } -} - -actual fun Buffer(size: Int, direct: Boolean): Buffer { - checkNBufferSize(size) - return Buffer( - if (direct) ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()) else ByteBuffer.wrap(ByteArray(size)).order(ByteOrder.nativeOrder()), - 0, size - ) -} - -actual fun Buffer(array: ByteArray, offset: Int, size: Int): Buffer { - checkNBufferWrap(array, offset, size) - return Buffer(ByteBuffer.wrap(array, offset, size).order(ByteOrder.nativeOrder()), offset, size) -} - -actual val Buffer.byteOffset: Int get() = offset -actual val Buffer.sizeInBytes: Int get() = size -actual fun Buffer.sliceInternal(start: Int, end: Int): Buffer = - Buffer(buffer, offset + start, end - start) - - -//internal inline fun java.nio.ByteBuffer.keepPositionLimit(block: () -> T): T { -// val oldPos = this.position() -// val oldLimit = this.limit() -// try { -// return block() -// } finally { -// this.limitSafe(oldLimit) -// this.positionSafe(oldPos) -// } -//} - -// Unaligned versions - -actual fun Buffer.getUnalignedInt8(byteOffset: Int): Byte = buffer.get(offset + byteOffset) -actual fun Buffer.getUnalignedInt16(byteOffset: Int): Short = buffer.getShort(offset + byteOffset) -actual fun Buffer.getUnalignedInt32(byteOffset: Int): Int = buffer.getInt(offset + byteOffset) -actual fun Buffer.getUnalignedInt64(byteOffset: Int): Long = buffer.getLong(offset + byteOffset) -actual fun Buffer.getUnalignedFloat32(byteOffset: Int): Float = buffer.getFloat(offset + byteOffset) -actual fun Buffer.getUnalignedFloat64(byteOffset: Int): Double = buffer.getDouble(offset + byteOffset) - -actual fun Buffer.setUnalignedInt8(byteOffset: Int, value: Byte) { - buffer.put(offset + byteOffset, value) -} - -actual fun Buffer.setUnalignedInt16(byteOffset: Int, value: Short) { - buffer.putShort(offset + byteOffset, value) -} - -actual fun Buffer.setUnalignedInt32(byteOffset: Int, value: Int) { - buffer.putInt(offset + byteOffset, value) -} - -actual fun Buffer.setUnalignedInt64(byteOffset: Int, value: Long) { - buffer.putLong(offset + byteOffset, value) -} - -actual fun Buffer.setUnalignedFloat32(byteOffset: Int, value: Float) { - buffer.putFloat(offset + byteOffset, value) -} - -actual fun Buffer.setUnalignedFloat64(byteOffset: Int, value: Double) { - buffer.putDouble(offset + byteOffset, value) -} - -@PublishedApi -internal fun java.nio.Buffer.checkSliceBounds(offset: Int, size: Int) { - //val end = offset + size - 1 - //if (offset !in 0 until this.capacity()) error("offset=$offset, size=$size not inside ${this.capacity()}") - //if (end !in 0 until this.capacity()) error("offset=$offset, size=$size not inside ${this.capacity()}") -} - -fun java.nio.Buffer.positionSafe(newPosition: Int) { - position(newPosition) -} - -fun java.nio.Buffer.limitSafe(newLimit: Int) { - limit(newLimit) -} - -fun java.nio.Buffer.flipSafe() { - flip() -} - -fun java.nio.Buffer.clearSafe() { - clear() -} - -inline fun T._slice(offset: Int, size: Int, dup: (T) -> T): T { - checkSliceBounds(offset, size) - val out = dup(this) - val start = this.position() + offset - val end = start + size - out.positionSafe(start) - out.limitSafe(end) - return out -} - -fun ByteBuffer.slice(offset: Int, size: Int): ByteBuffer = _slice(offset, size) { it.duplicate() } -fun ShortBuffer.slice(offset: Int, size: Int): ShortBuffer = _slice(offset, size) { it.duplicate() } -fun IntBuffer.slice(offset: Int, size: Int): IntBuffer = _slice(offset, size) { it.duplicate() } -fun FloatBuffer.slice(offset: Int, size: Int): FloatBuffer = _slice(offset, size) { it.duplicate() } -fun DoubleBuffer.slice(offset: Int, size: Int): DoubleBuffer = _slice(offset, size) { it.duplicate() } - -val Buffer.nioBuffer: java.nio.ByteBuffer get() = this.slicedBuffer() -val Buffer.nioIntBuffer: java.nio.IntBuffer get() = this.slicedBuffer().asIntBuffer() -val Buffer.nioFloatBuffer: java.nio.FloatBuffer get() = this.slicedBuffer().asFloatBuffer() diff --git a/korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/Buffer.wasm.kt b/korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/Buffer.wasm.kt new file mode 100644 index 0000000000..17520779c1 --- /dev/null +++ b/korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/Buffer.wasm.kt @@ -0,0 +1,107 @@ +package korlibs.memory + +import korlibs.memory.wasm.* +import korlibs.platform.* +import org.khronos.webgl.* + +actual class Buffer(val dataView: DataView) { + actual constructor(size: Int, direct: Boolean) : this(DataView(ArrayBuffer(checkNBufferSize(size)))) + actual constructor(array: ByteArray, offset: Int, size: Int) : this( + //DataView(checkNBufferWrap(array, offset, size).unsafeCast().buffer, offset, size) + // @TODO: Can't wrap, so we perform a copy + DataView(array.toInt8Array().buffer, offset, size) + ) + + actual val byteOffset: Int get() = this.dataView.byteOffset + actual val sizeInBytes: Int get() = this.dataView.byteLength + + actual fun sliceInternal(start: Int, end: Int): Buffer = + Buffer(DataView(this.buffer, this.byteOffset + start, end - start)) + + fun sliceUint8Array(offset: Int = 0, size: Int = dataView.byteLength - offset): Uint8Array = + Uint8Array(buffer, dataView.byteOffset + offset, size) + + actual fun transferBytes(bufferOffset: Int, array: ByteArray, arrayOffset: Int, len: Int, toArray: Boolean) { + if (toArray) { + for (n in 0 until len) array[arrayOffset + n] = this.getS8(bufferOffset + n) + } else { + for (n in 0 until len) this.set8(bufferOffset + n, array[arrayOffset + n]) + } + } + + actual fun getS8(byteOffset: Int): Byte = dataView.getInt8(byteOffset) + actual fun getS16LE(byteOffset: Int): Short = dataView.getInt16(byteOffset, true) + actual fun getS32LE(byteOffset: Int): Int = dataView.getInt32(byteOffset, true) + actual fun getS64LE(byteOffset: Int): Long { + val v0 = getS32LE(byteOffset).toLong() and 0xFFFFFFFFL + val v1 = getS32LE(byteOffset + 4).toLong() and 0xFFFFFFFFL + return if (currentIsLittleEndian) (v1 shl 32) or v0 else (v0 shl 32) or v1 + } + actual fun getF32LE(byteOffset: Int): Float = dataView.getFloat32(byteOffset, true) + actual fun getF64LE(byteOffset: Int): Double = dataView.getFloat64(byteOffset, true) + actual fun getS16BE(byteOffset: Int): Short = dataView.getInt16(byteOffset, false) + actual fun getS32BE(byteOffset: Int): Int = dataView.getInt32(byteOffset, false) + actual fun getS64BE(byteOffset: Int): Long { + val v0 = getS32BE(byteOffset).toLong() and 0xFFFFFFFFL + val v1 = getS32BE(byteOffset + 4).toLong() and 0xFFFFFFFFL + return (v0 shl 32) or v1 + } + actual fun getF32BE(byteOffset: Int): Float = dataView.getFloat32(byteOffset, false) + actual fun getF64BE(byteOffset: Int): Double = dataView.getFloat64(byteOffset, false) + + actual fun set8(byteOffset: Int, value: Byte) = dataView.setInt8(byteOffset, value) + actual fun set16LE(byteOffset: Int, value: Short) = dataView.setInt16(byteOffset, value, true) + actual fun set32LE(byteOffset: Int, value: Int) = dataView.setInt32(byteOffset, value, true) + actual fun set64LE(byteOffset: Int, value: Long) { + set32LE(byteOffset, value.toInt()) + set32LE(byteOffset + 4, (value ushr 32).toInt()) + } + actual fun setF32LE(byteOffset: Int, value: Float) = dataView.setFloat32(byteOffset, value, true) + actual fun setF64LE(byteOffset: Int, value: Double) = dataView.setFloat64(byteOffset, value, true) + + actual fun set16BE(byteOffset: Int, value: Short) = dataView.setInt16(byteOffset, value, false) + actual fun set32BE(byteOffset: Int, value: Int) = dataView.setInt32(byteOffset, value, false) + actual fun set64BE(byteOffset: Int, value: Long) { + set32BE(byteOffset, (value ushr 32).toInt()) + set32BE(byteOffset + 4, value.toInt()) + } + actual fun setF32BE(byteOffset: Int, value: Float) = dataView.setFloat32(byteOffset, value, false) + actual fun setF64BE(byteOffset: Int, value: Double) = dataView.setFloat64(byteOffset, value, false) + + override fun hashCode(): Int = hashCodeCommon(this) + override fun equals(other: Any?): Boolean = equalsCommon(this, other) + override fun toString(): String = NBuffer_toString(this) + + actual companion object { + actual fun copy(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int) { + dst.sliceUint8Array(dstPosBytes, sizeInBytes).set(src.sliceUint8Array(srcPosBytes, sizeInBytes), 0) + } + + actual fun equals(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int): Boolean = equalsCommon(src, srcPosBytes, dst, dstPosBytes, sizeInBytes, use64 = false) + } +} + +val Buffer.buffer: ArrayBuffer get() = dataView.buffer + + +fun ArrayBuffer.asUint8ClampedArray(): Uint8ClampedArray = Uint8ClampedArray(this) +fun ArrayBuffer.asUint8Array(): Uint8Array = Uint8Array(this) +fun ArrayBuffer.asInt8Array(): Int8Array = Int8Array(this) +fun ArrayBuffer.asInt16Array(): Int16Array = Int16Array(this) +fun ArrayBuffer.asInt32Array(): Int32Array = Int32Array(this) +fun ArrayBuffer.asFloat32Array(): Float32Array = Float32Array(this) +fun ArrayBuffer.asFloat64Array(): Float64Array = Float64Array(this) + +fun ArrayBuffer.toUByteArray(): UByteArray = asUint8Array().toByteArray().asUByteArray() +fun ArrayBuffer.toByteArray(): ByteArray = asInt8Array().toByteArray() +fun ArrayBuffer.toShortArray(): ShortArray = asInt16Array().toShortArray() +fun ArrayBuffer.toIntArray(): IntArray = asInt32Array().toIntArray() +fun ArrayBuffer.toFloatArray(): FloatArray = asFloat32Array().toFloatArray() +fun ArrayBuffer.toDoubleArray(): DoubleArray = asFloat64Array().toDoubleArray() + +val Buffer.arrayUByte: Uint8Array get() = Uint8Array(this.buffer, byteOffset, sizeInBytes) +val Buffer.arrayByte: Int8Array get() = Int8Array(buffer, byteOffset, sizeInBytes) +val Buffer.arrayShort: Int16Array get() = Int16Array(buffer, byteOffset, sizeInBytes / 2) +val Buffer.arrayInt: Int32Array get() = Int32Array(buffer, byteOffset, sizeInBytes / 4) +val Buffer.arrayFloat: Float32Array get() = Float32Array(buffer, byteOffset, sizeInBytes / 4) +val Buffer.arrayDouble: Float64Array get() = Float64Array(buffer, byteOffset, sizeInBytes / 8) diff --git a/korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/BufferWasm.kt b/korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/BufferWasm.kt deleted file mode 100644 index c986d4741e..0000000000 --- a/korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/BufferWasm.kt +++ /dev/null @@ -1,93 +0,0 @@ -package korlibs.memory - -import korlibs.memory.wasm.* -import korlibs.platform.* -import org.khronos.webgl.* - -actual class Buffer(val dataView: DataView) { - val buffer: ArrayBuffer get() = dataView.buffer - - fun sliceUint8Array(offset: Int = 0, size: Int = dataView.byteLength - offset): Uint8Array = - Uint8Array(buffer, dataView.byteOffset + offset, size) - override fun toString(): String = NBuffer_toString(this) - actual companion object { - actual fun copy(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int) { - dst.sliceUint8Array(dstPosBytes, sizeInBytes).set(src.sliceUint8Array(srcPosBytes, sizeInBytes), 0) - } - - actual fun equals(src: Buffer, srcPosBytes: Int, dst: Buffer, dstPosBytes: Int, sizeInBytes: Int): Boolean = equalsCommon(src, srcPosBytes, dst, dstPosBytes, sizeInBytes, use64 = false) - } - - - // @TODO: Optimize by using words instead o bytes - override fun hashCode(): Int { - var h = 1 - for (n in 0 until size) h = 31 * h + dataView.getInt8(n) - return h - } - - // @TODO: Optimize by using words instead o bytes - override fun equals(other: Any?): Boolean { - if (other !is Buffer || this.size != other.size) return false - val t = this.dataView - val o = other.dataView - for (n in 0 until size) if (t.getInt8(n) != o.getInt8(n)) return false - return true - } -} -actual fun Buffer(size: Int, direct: Boolean): Buffer { - checkNBufferSize(size) - return Buffer(DataView(ArrayBuffer(size))) -} -actual fun Buffer(array: ByteArray, offset: Int, size: Int): Buffer { - checkNBufferWrap(array, offset, size) - return Buffer(DataView(array.toInt8Array().buffer, offset, size)) -} -actual val Buffer.byteOffset: Int get() = this.dataView.byteOffset -actual val Buffer.sizeInBytes: Int get() = this.dataView.byteLength -actual fun Buffer.sliceInternal(start: Int, end: Int): Buffer = Buffer(DataView(this.buffer, this.byteOffset + start, end - start)) - -// Unaligned versions - -actual fun Buffer.getUnalignedInt8(byteOffset: Int): Byte = dataView.getInt8(byteOffset) -actual fun Buffer.getUnalignedInt16(byteOffset: Int): Short = dataView.getInt16(byteOffset, currentIsLittleEndian) -actual fun Buffer.getUnalignedInt32(byteOffset: Int): Int = dataView.getInt32(byteOffset, currentIsLittleEndian) -actual fun Buffer.getUnalignedInt64(byteOffset: Int): Long { - val v0 = getUnalignedInt32(byteOffset).toLong() and 0xFFFFFFFFL - val v1 = getUnalignedInt32(byteOffset + 4).toLong() and 0xFFFFFFFFL - return if (currentIsLittleEndian) (v1 shl 32) or v0 else (v0 shl 32) or v1 -} -actual fun Buffer.getUnalignedFloat32(byteOffset: Int): Float = dataView.getFloat32(byteOffset, currentIsLittleEndian) -actual fun Buffer.getUnalignedFloat64(byteOffset: Int): Double = dataView.getFloat64(byteOffset, currentIsLittleEndian) - -actual fun Buffer.setUnalignedInt8(byteOffset: Int, value: Byte) = dataView.setInt8(byteOffset, value) -actual fun Buffer.setUnalignedInt16(byteOffset: Int, value: Short) = dataView.setInt16(byteOffset, value, currentIsLittleEndian) -actual fun Buffer.setUnalignedInt32(byteOffset: Int, value: Int) = dataView.setInt32(byteOffset, value, currentIsLittleEndian) -actual fun Buffer.setUnalignedInt64(byteOffset: Int, value: Long) { - setUnalignedInt32(byteOffset, if (currentIsLittleEndian) value.toInt() else (value ushr 32).toInt()) - setUnalignedInt32(byteOffset + 4, if (!currentIsLittleEndian) value.toInt() else (value ushr 32).toInt()) -} -actual fun Buffer.setUnalignedFloat32(byteOffset: Int, value: Float) = dataView.setFloat32(byteOffset, value, currentIsLittleEndian) -actual fun Buffer.setUnalignedFloat64(byteOffset: Int, value: Double) = dataView.setFloat64(byteOffset, value, currentIsLittleEndian) - -fun ArrayBuffer.asUint8ClampedArray(): Uint8ClampedArray = Uint8ClampedArray(this) -fun ArrayBuffer.asUint8Array(): Uint8Array = Uint8Array(this) -fun ArrayBuffer.asInt8Array(): Int8Array = Int8Array(this) -fun ArrayBuffer.asInt16Array(): Int16Array = Int16Array(this) -fun ArrayBuffer.asInt32Array(): Int32Array = Int32Array(this) -fun ArrayBuffer.asFloat32Array(): Float32Array = Float32Array(this) -fun ArrayBuffer.asFloat64Array(): Float64Array = Float64Array(this) - -fun ArrayBuffer.toUByteArray(): UByteArray = asUint8Array().toByteArray().asUByteArray() -fun ArrayBuffer.toByteArray(): ByteArray = asInt8Array().toByteArray() -fun ArrayBuffer.toShortArray(): ShortArray = asInt16Array().toShortArray() -fun ArrayBuffer.toIntArray(): IntArray = asInt32Array().toIntArray() -fun ArrayBuffer.toFloatArray(): FloatArray = asFloat32Array().toFloatArray() -fun ArrayBuffer.toDoubleArray(): DoubleArray = asFloat64Array().toDoubleArray() - -val Buffer.arrayUByte: Uint8Array get() = Uint8Array(this.buffer, byteOffset, sizeInBytes) -val Buffer.arrayByte: Int8Array get() = Int8Array(buffer, byteOffset, sizeInBytes) -val Buffer.arrayShort: Int16Array get() = Int16Array(buffer, byteOffset, sizeInBytes / 2) -val Buffer.arrayInt: Int32Array get() = Int32Array(buffer, byteOffset, sizeInBytes / 4) -val Buffer.arrayFloat: Float32Array get() = Float32Array(buffer, byteOffset, sizeInBytes / 4) -val Buffer.arrayDouble: Float64Array get() = Float64Array(buffer, byteOffset, sizeInBytes / 8) diff --git a/korge/src/commonMain/kotlin/korlibs/graphics/gl/AGOpengl.kt b/korge/src/commonMain/kotlin/korlibs/graphics/gl/AGOpengl.kt index 0e23a8d24f..cf55a31a0f 100644 --- a/korge/src/commonMain/kotlin/korlibs/graphics/gl/AGOpengl.kt +++ b/korge/src/commonMain/kotlin/korlibs/graphics/gl/AGOpengl.kt @@ -643,7 +643,7 @@ class AGOpengl(val gl: KmlGl, var context: KmlGlContext? = null) : AG() { writeUniform( uniform.uniform, glProgramInfo, - currentMem.slice(uniform.voffset, uniform.voffset + uniform.totalBytes), + currentMem._slice(uniform.voffset, uniform.voffset + uniform.totalBytes), "blockUniformSet", ) } diff --git a/korge/src/commonMain/kotlin/korlibs/graphics/shader/UniformBlock.kt b/korge/src/commonMain/kotlin/korlibs/graphics/shader/UniformBlock.kt index 96939906eb..c1d43b18cc 100644 --- a/korge/src/commonMain/kotlin/korlibs/graphics/shader/UniformBlock.kt +++ b/korge/src/commonMain/kotlin/korlibs/graphics/shader/UniformBlock.kt @@ -155,15 +155,15 @@ class UniformsRef( } // @TODO: Remaining get functions - operator fun get(uniform: TypedUniform): Int = getOffset(uniform).let { buffer.getUnalignedInt32(it) } - operator fun get(uniform: TypedUniform): Float = getOffset(uniform).let { buffer.getUnalignedFloat32(it + 0) } - operator fun get(uniform: TypedUniform): Vector2F = getOffset(uniform).let { Vector2F(buffer.getUnalignedFloat32(it + 0), buffer.getUnalignedFloat32(it + 4)) } - operator fun get(uniform: TypedUniform): Vector3F = getOffset(uniform).let { Vector3F(buffer.getUnalignedFloat32(it + 0), buffer.getUnalignedFloat32(it + 4), buffer.getUnalignedFloat32(it + 8)) } - operator fun get(uniform: TypedUniform): Vector4F = getOffset(uniform).let { Vector4F(buffer.getUnalignedFloat32(it + 0), buffer.getUnalignedFloat32(it + 4), buffer.getUnalignedFloat32(it + 8), buffer.getUnalignedFloat32(it + 12)) } + operator fun get(uniform: TypedUniform): Int = getOffset(uniform).let { buffer.getS32(it) } + operator fun get(uniform: TypedUniform): Float = getOffset(uniform).let { buffer.getF32(it + 0) } + operator fun get(uniform: TypedUniform): Vector2F = getOffset(uniform).let { Vector2F(buffer.getF32(it + 0), buffer.getF32(it + 4)) } + operator fun get(uniform: TypedUniform): Vector3F = getOffset(uniform).let { Vector3F(buffer.getF32(it + 0), buffer.getF32(it + 4), buffer.getF32(it + 8)) } + operator fun get(uniform: TypedUniform): Vector4F = getOffset(uniform).let { Vector4F(buffer.getF32(it + 0), buffer.getF32(it + 4), buffer.getF32(it + 8), buffer.getF32(it + 12)) } //operator fun get(uniform: TypedUniform): Matrix4 = TODO() operator fun set(uniform: TypedUniform, value: Int) { - getOffset(uniform).also { buffer.setUnalignedInt32(it, value) } + getOffset(uniform).also { buffer.set32(it, value) } } operator fun set(uniform: TypedUniform, value: Boolean) = set(uniform, if (value) 1f else 0f) operator fun set(uniform: TypedUniform, value: Double) = set(uniform, value.toFloat()) @@ -202,7 +202,7 @@ class UniformsRef( } operator fun set(uniform: TypedUniform, value: Float) { getOffset(uniform).also { - buffer.setUnalignedFloat32(it + 0, value) + buffer.setF32(it + 0, value) } } //operator fun set(uniform: TypedUniform, x: Double, y: Double) { getOffset(uniform).also { bufferSetFloat2(it, x.toFloat(), y.toFloat()) } } @@ -216,28 +216,28 @@ class UniformsRef( fun bufferSetFloat1(index: Int, v: Float) { - buffer.setUnalignedFloat32(index + 0, v) + buffer.setF32(index + 0, v) } fun bufferSetFloat2(index: Int, v: Vector2F) = bufferSetFloat2(index, v.x, v.y) fun bufferSetFloat2(index: Int, x: Float, y: Float) { - buffer.setUnalignedFloat32(index + 0, x) - buffer.setUnalignedFloat32(index + 4, y) + buffer.setF32(index + 0, x) + buffer.setF32(index + 4, y) } fun bufferSetFloat3(index: Int, v: Vector3F) = bufferSetFloat3(index, v.x, v.y, v.z) fun bufferSetFloat3(index: Int, x: Float, y: Float, z: Float) { - buffer.setUnalignedFloat32(index + 0, x) - buffer.setUnalignedFloat32(index + 4, y) - buffer.setUnalignedFloat32(index + 8, z) + buffer.setF32(index + 0, x) + buffer.setF32(index + 4, y) + buffer.setF32(index + 8, z) } fun bufferSetFloat4(index: Int, v: Vector4F) = bufferSetFloat4(index, v.x, v.y, v.z, v.w) fun bufferSetFloat4(index: Int, x: Float, y: Float, z: Float, w: Float) { - buffer.setUnalignedFloat32(index + 0, x) - buffer.setUnalignedFloat32(index + 4, y) - buffer.setUnalignedFloat32(index + 8, z) - buffer.setUnalignedFloat32(index + 12, w) + buffer.setF32(index + 0, x) + buffer.setF32(index + 4, y) + buffer.setF32(index + 8, z) + buffer.setF32(index + 12, w) } fun bufferSetFloat16(index: Int, value: Matrix4, indices: IntArray = Matrix4.INDICES_BY_COLUMNS_4x4) { @@ -246,12 +246,12 @@ class UniformsRef( fun bufferSetFloatN(index: Int, floats: FloatArray, size: Int, offset: Int = 0) { for (n in 0 until size) { - buffer.setUnalignedFloat32(index + (n * 4), floats[offset + n]) + buffer.setF32(index + (n * 4), floats[offset + n]) } } inline fun bufferSetFloatNIndexed(index: Int, indices: IntArray, max: Int = indices.size, value: (Int) -> Float) { - for (n in 0 until max) buffer.setUnalignedFloat32(index + (n * 4), value(indices[n])) + for (n in 0 until max) buffer.setF32(index + (n * 4), value(indices[n])) } fun bufferSetFloatNIndexed(index: Int, indices: IntArray, value: FloatArray, max: Int = indices.size) { diff --git a/korge/src/commonTest/kotlin/korlibs/graphics/AGUniformBlockTest.kt b/korge/src/commonTest/kotlin/korlibs/graphics/AGUniformBlockTest.kt index 9bb776bec3..04abb49883 100644 --- a/korge/src/commonTest/kotlin/korlibs/graphics/AGUniformBlockTest.kt +++ b/korge/src/commonTest/kotlin/korlibs/graphics/AGUniformBlockTest.kt @@ -49,7 +49,7 @@ class AGUniformBlockTest { assertEquals( listOf(0.0, 1.0, 2.0, 3.0, 10.0, 11.0, 12.0, 13.0, 20.0, 21.0, 22.0, 23.0, 33.0, 33.0, 33.0, 33.0).map { it.toFloat() }, - ubb.buffer.slice(0, ubb.blockSizeNoGlAlign).f32.toFloatArray().toList() + ubb.buffer._slice(0, ubb.blockSizeNoGlAlign).f32.toFloatArray().toList() ) val str = FragmentShader { diff --git a/korge/src/jsMain/kotlin/korlibs/kgl/KmlGlJsCanvas.kt b/korge/src/jsMain/kotlin/korlibs/kgl/KmlGlJsCanvas.kt index 9e4aead483..44bd0fecd4 100644 --- a/korge/src/jsMain/kotlin/korlibs/kgl/KmlGlJsCanvas.kt +++ b/korge/src/jsMain/kotlin/korlibs/kgl/KmlGlJsCanvas.kt @@ -76,8 +76,8 @@ class KmlGlJsCanvas(val canvas: HTMLCanvasElement, val glOpts: dynamic) : KmlGl( override fun blendEquationSeparate(modeRGB: Int, modeAlpha: Int): Unit = gl.blendEquationSeparate(modeRGB, modeAlpha) override fun blendFunc(sfactor: Int, dfactor: Int): Unit = gl.blendFunc(sfactor, dfactor) override fun blendFuncSeparate(sfactorRGB: Int, dfactorRGB: Int, sfactorAlpha: Int, dfactorAlpha: Int): Unit = gl.blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha) - override fun bufferData(target: Int, size: Int, data: Buffer, usage: Int): Unit = gl.bufferData(target, data.slice(0, size).arrayUByte, usage) - override fun bufferSubData(target: Int, offset: Int, size: Int, data: Buffer): Unit = gl.bufferSubData(target, offset, data.slice(0, size).arrayUByte) + override fun bufferData(target: Int, size: Int, data: Buffer, usage: Int): Unit = gl.bufferData(target, data._slice(0, size).arrayUByte, usage) + override fun bufferSubData(target: Int, offset: Int, size: Int, data: Buffer): Unit = gl.bufferSubData(target, offset, data._slice(0, size).arrayUByte) override fun checkFramebufferStatus(target: Int): Int = gl.checkFramebufferStatus(target) override fun clear(mask: Int): Unit = gl.clear(mask) override fun clearColor(red: Float, green: Float, blue: Float, alpha: Float): Unit = gl.clearColor(red, green, blue, alpha) diff --git a/korge/src/wasmJsMain/kotlin/korlibs/kgl/KmlGlWasmCanvas.kt b/korge/src/wasmJsMain/kotlin/korlibs/kgl/KmlGlWasmCanvas.kt index 1d1112cd78..9408e41bcb 100644 --- a/korge/src/wasmJsMain/kotlin/korlibs/kgl/KmlGlWasmCanvas.kt +++ b/korge/src/wasmJsMain/kotlin/korlibs/kgl/KmlGlWasmCanvas.kt @@ -105,8 +105,8 @@ class KmlGlWasmCanvas(val canvas: HTMLCanvasElement, val glOpts: JsAny) : KmlGl( override fun blendEquationSeparate(modeRGB: Int, modeAlpha: Int): Unit = gl.blendEquationSeparate(modeRGB, modeAlpha) override fun blendFunc(sfactor: Int, dfactor: Int): Unit = gl.blendFunc(sfactor, dfactor) override fun blendFuncSeparate(sfactorRGB: Int, dfactorRGB: Int, sfactorAlpha: Int, dfactorAlpha: Int): Unit = gl.blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha) - override fun bufferData(target: Int, size: Int, data: Buffer, usage: Int): Unit = gl.bufferData(target, data.slice(0, size).arrayUByte, usage) - override fun bufferSubData(target: Int, offset: Int, size: Int, data: Buffer): Unit = gl.bufferSubData(target, offset, data.slice(0, size).arrayUByte) + override fun bufferData(target: Int, size: Int, data: Buffer, usage: Int): Unit = gl.bufferData(target, data._slice(0, size).arrayUByte, usage) + override fun bufferSubData(target: Int, offset: Int, size: Int, data: Buffer): Unit = gl.bufferSubData(target, offset, data._slice(0, size).arrayUByte) override fun checkFramebufferStatus(target: Int): Int = gl.checkFramebufferStatus(target) override fun clear(mask: Int): Unit = gl.clear(mask) override fun clearColor(red: Float, green: Float, blue: Float, alpha: Float): Unit = gl.clearColor(red, green, blue, alpha) From 2b68b24ade7d0cac39a452d021776f46f0832674 Mon Sep 17 00:00:00 2001 From: soywiz Date: Wed, 27 Sep 2023 02:06:54 +0200 Subject: [PATCH 2/7] Removed typed arrays --- .../kotlin/korlibs/memory/TypedArrays.kt | 322 ------------------ .../korlibs/memory/arrays/TypedArraysTest.kt | 218 ------------ .../kotlin/korlibs/memory/TypedArrays.js.kt | 81 ----- .../kotlin/korlibs/memory/TypedArrays.jvm.kt | 137 -------- .../korlibs/memory/TypedArrays.wasmJs.kt | 101 ------ 5 files changed, 859 deletions(-) delete mode 100644 korge-foundation/src/commonMain/kotlin/korlibs/memory/TypedArrays.kt delete mode 100644 korge-foundation/src/commonTest/kotlin/korlibs/memory/arrays/TypedArraysTest.kt delete mode 100644 korge-foundation/src/jsMain/kotlin/korlibs/memory/TypedArrays.js.kt delete mode 100644 korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/TypedArrays.jvm.kt delete mode 100644 korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/TypedArrays.wasmJs.kt diff --git a/korge-foundation/src/commonMain/kotlin/korlibs/memory/TypedArrays.kt b/korge-foundation/src/commonMain/kotlin/korlibs/memory/TypedArrays.kt deleted file mode 100644 index 9880d13d9c..0000000000 --- a/korge-foundation/src/commonMain/kotlin/korlibs/memory/TypedArrays.kt +++ /dev/null @@ -1,322 +0,0 @@ -@file:Suppress("RemoveRedundantCallsOfConversionMethods", "PackageDirectoryMismatch") - -package korlibs.memory.arrays - -import korlibs.math.* -import korlibs.memory.* - -expect interface BufferDataSource - -expect class ArrayBuffer(length: Int) : BufferDataSource { - val byteLength: Int -} -//fun ArrayBuffer.subArray(begin: Int, end: Int = byteLength): ArrayBuffer { -// TODO() -//} - -expect interface ArrayBufferView : BufferDataSource { - val buffer: ArrayBuffer - val byteOffset: Int - val byteLength: Int -} - -fun ArrayBuffer(size: Int, direct: Boolean): ArrayBuffer = if (direct) ArrayBufferDirect(size) else ArrayBuffer(size) -expect fun ArrayBufferDirect(size: Int): ArrayBuffer -expect fun ArrayBufferWrap(data: ByteArray): ArrayBuffer -internal expect fun ArrayBuffer_copy(src: ArrayBuffer, srcPos: Int, dst: ArrayBuffer, dstPos: Int, length: Int) -fun arraycopy(src: ArrayBuffer, srcPos: Int, dst: ArrayBuffer, dstPos: Int, length: Int) { - ArrayBuffer_copy(src, srcPos, dst, dstPos, length) -} -fun arraycopy(src: ByteArray, srcPos: Int, dst: ArrayBuffer, dstPos: Int, length: Int) { - ArrayBuffer_copy(ArrayBufferWrap(src), srcPos, dst, dstPos, length) -} -fun arraycopy(src: ArrayBuffer, srcPos: Int, dst: ByteArray, dstPos: Int, length: Int) { - ArrayBuffer_copy(src, srcPos, ArrayBufferWrap(dst), dstPos, length) -} - -fun ArrayBuffer.readBytes(start: Int = 0, length: Int = byteLength - start, outOffset: Int = 0, out: ByteArray = ByteArray(outOffset + length)): ByteArray { - arraycopy(this, start, out, outOffset, length) - return out -} - -fun ArrayBufferView.setByteOffset(typedArray: ArrayBufferView, targetOffsetBytes: Int = 0) = - ArrayBuffer_copy(typedArray.buffer, typedArray.byteOffset, this.buffer, this.byteOffset + targetOffsetBytes, typedArray.byteLength) - -fun Uint8ClampedArray.set(typedArray: ArrayBufferView, targetOffset: Int = 0) = setByteOffset(typedArray, targetOffset * 1) -fun Uint8Array.set(typedArray: ArrayBufferView, targetOffset: Int = 0) = setByteOffset(typedArray, targetOffset * 1) -fun Uint16Array.set(typedArray: ArrayBufferView, targetOffset: Int = 0) = setByteOffset(typedArray, targetOffset * 2) -fun Int8Array.set(typedArray: ArrayBufferView, targetOffset: Int = 0) = setByteOffset(typedArray, targetOffset * 1) -fun Int16Array.set(typedArray: ArrayBufferView, targetOffset: Int = 0) = setByteOffset(typedArray, targetOffset * 2) -fun Int32Array.set(typedArray: ArrayBufferView, targetOffset: Int = 0) = setByteOffset(typedArray, targetOffset * 4) -fun Int64Array.set(typedArray: ArrayBufferView, targetOffset: Int = 0) = setByteOffset(typedArray, targetOffset * 8) -fun Float32Array.set(typedArray: ArrayBufferView, targetOffset: Int = 0) = setByteOffset(typedArray, targetOffset * 4) -fun Float64Array.set(typedArray: ArrayBufferView, targetOffset: Int = 0) = setByteOffset(typedArray, targetOffset * 8) - -fun Uint8ClampedArray.subarray(begin: Int = 0, end: Int = length): Uint8ClampedArray = Uint8ClampedArray(buffer, byteOffset + begin * 1, end - begin) -fun Uint8Array.subarray(begin: Int = 0, end: Int = length): Uint8Array = Uint8Array(buffer, byteOffset + begin * 1, end - begin) -fun Uint16Array.subarray(begin: Int = 0, end: Int = length): Uint16Array = Uint16Array(buffer, byteOffset + begin * 2, end - begin) -fun Int8Array.subarray(begin: Int = 0, end: Int = length): Int8Array = Int8Array(buffer, byteOffset + begin * 1, end - begin) -fun Int16Array.subarray(begin: Int = 0, end: Int = length): Int16Array = Int16Array(buffer, byteOffset + begin * 2, end - begin) -fun Int32Array.subarray(begin: Int = 0, end: Int = length): Int32Array = Int32Array(buffer, byteOffset + begin * 4, end - begin) -fun Float32Array.subarray(begin: Int = 0, end: Int = length): Float32Array = Float32Array(buffer, byteOffset + begin * 4, end - begin) -fun Float64Array.subarray(begin: Int = 0, end: Int = length): Float64Array = Float64Array(buffer, byteOffset + begin * 8, end - begin) - -fun ArrayBuffer.clone(): ArrayBuffer = ArrayBufferWrap(readBytes()) -fun Uint8ClampedArray.clone(): Uint8ClampedArray = Uint8ClampedArray(ArrayBufferWrap(buffer.readBytes(byteOffset, byteLength))) -fun Uint8Array.clone(): Uint8Array = Uint8Array(ArrayBufferWrap(buffer.readBytes(byteOffset, byteLength))) -fun Uint16Array.clone(): Uint16Array = Uint16Array(ArrayBufferWrap(buffer.readBytes(byteOffset, byteLength))) -fun Int8Array.clone(): Int8Array = Int8Array(ArrayBufferWrap(buffer.readBytes(byteOffset, byteLength))) -fun Int16Array.clone(): Int16Array = Int16Array(ArrayBufferWrap(buffer.readBytes(byteOffset, byteLength))) -fun Int32Array.clone(): Int32Array = Int32Array(ArrayBufferWrap(buffer.readBytes(byteOffset, byteLength))) -fun Float32Array.clone(): Float32Array = Float32Array(ArrayBufferWrap(buffer.readBytes(byteOffset, byteLength))) -fun Float64Array.clone(): Float64Array = Float64Array(ArrayBufferWrap(buffer.readBytes(byteOffset, byteLength))) - -fun Uint8ClampedArray.subarraySize(begin: Int = 0, size: Int = length - begin): Uint8ClampedArray = subarray(begin, begin + size) -fun Uint8Array.subarraySize(begin: Int = 0, size: Int = length - begin): Uint8Array = subarray(begin, begin + size) -fun Uint16Array.subarraySize(begin: Int = 0, size: Int = length - begin): Uint16Array = subarray(begin, begin + size) -fun Int8Array.subarraySize(begin: Int = 0, size: Int = length - begin): Int8Array = subarray(begin, begin + size) -fun Int16Array.subarraySize(begin: Int = 0, size: Int = length - begin): Int16Array = subarray(begin, begin + size) -fun Int32Array.subarraySize(begin: Int = 0, size: Int = length - begin): Int32Array = subarray(begin, begin + size) -fun Float32Array.subarraySize(begin: Int = 0, size: Int = length - begin): Float32Array = subarray(begin, begin + size) -fun Float64Array.subarraySize(begin: Int = 0, size: Int = length - begin): Float64Array = subarray(begin, begin + size) - -fun ArrayBufferView.asUint8ClampedArray(): Uint8ClampedArray = Uint8ClampedArray(buffer, byteOffset, byteLength / 1) -fun ArrayBufferView.asUint8Array(): Uint8Array = Uint8Array(buffer, byteOffset, byteLength / 1) -fun ArrayBufferView.asUint16Array(): Uint16Array = Uint16Array(buffer, byteOffset, byteLength / 2) -fun ArrayBufferView.asInt8Array(): Int8Array = Int8Array(buffer, byteOffset, byteLength / 1) -fun ArrayBufferView.asInt16Array(): Int16Array = Int16Array(buffer, byteOffset, byteLength / 2) -fun ArrayBufferView.asInt32Array(): Int32Array = Int32Array(buffer, byteOffset, byteLength / 4) -fun ArrayBufferView.asFloat32Array(): Float32Array = Float32Array(buffer, byteOffset, byteLength / 4) -fun ArrayBufferView.asFloat64Array(): Float64Array = Float64Array(buffer, byteOffset, byteLength / 8) - -private fun ArrayBufferView._offsetS(index: Int, size: Int): Int { - val roffset = index * size - if (roffset !in 0 .. (byteLength - size)) error("Out of bounds") - return (byteOffset + roffset) -} -@PublishedApi internal fun Uint8ClampedArray.byteOffset(index: Int): Int = _offsetS(index, 1) -@PublishedApi internal fun Uint8Array.byteOffset(index: Int): Int = _offsetS(index, 1) -@PublishedApi internal fun Uint16Array.byteOffset(index: Int): Int = _offsetS(index, 2) -@PublishedApi internal fun Int8Array.byteOffset(index: Int): Int = _offsetS(index, 1) -@PublishedApi internal fun Int16Array.byteOffset(index: Int): Int = _offsetS(index, 2) -@PublishedApi internal fun Int32Array.byteOffset(index: Int): Int = _offsetS(index, 4) -@PublishedApi internal fun Float32Array.byteOffset(index: Int): Int = _offsetS(index, 4) -@PublishedApi internal fun Float64Array.byteOffset(index: Int): Int = _offsetS(index, 8) -@PublishedApi internal fun DataView.byteOffset(offset: Int, size: Int): Int { - if (offset < 0 || offset + size > byteLength) error("Offset is outside the bounds of the DataView") - return byteOffset + offset -} - -expect inline fun ArrayBuffer.uint8ClampedArray(byteOffset: Int = 0, length: Int = this.byteLength - byteOffset): Uint8ClampedArray -expect inline fun ArrayBuffer.uint8Array(byteOffset: Int = 0, length: Int = this.byteLength - byteOffset): Uint8Array -expect inline fun ArrayBuffer.uint16Array(byteOffset: Int = 0, length: Int = (this.byteLength - byteOffset) / 2): Uint16Array -expect inline fun ArrayBuffer.int8Array(byteOffset: Int = 0, length: Int = this.byteLength - byteOffset): Int8Array -expect inline fun ArrayBuffer.int16Array(byteOffset: Int = 0, length: Int = (this.byteLength - byteOffset) / 2): Int16Array -expect inline fun ArrayBuffer.int32Array(byteOffset: Int = 0, length: Int = (this.byteLength - byteOffset) / 4): Int32Array -expect inline fun ArrayBuffer.float32Array(byteOffset: Int = 0, length: Int = (this.byteLength - byteOffset) / 4): Float32Array -expect inline fun ArrayBuffer.float64Array(byteOffset: Int = 0, length: Int = (this.byteLength - byteOffset) / 8): Float64Array -expect inline fun ArrayBuffer.dataView(byteOffset: Int = 0, length: Int = this.byteLength - byteOffset): DataView - -expect class Int8Array : ArrayBufferView { - constructor(length: Int) - val length: Int -} -expect class Int16Array : ArrayBufferView { - constructor(length: Int) - val length: Int -} -expect class Int32Array : ArrayBufferView { - constructor(length: Int) - val length: Int -} -expect class Float32Array : ArrayBufferView { - constructor(length: Int) - val length: Int -} -expect class Float64Array : ArrayBufferView { - constructor(length: Int) - val length: Int -} -expect class Uint8ClampedArray : ArrayBufferView { - constructor(length: Int) - val length: Int -} -expect class Uint8Array : ArrayBufferView { - constructor(length: Int) - val length: Int -} -expect class Uint16Array : ArrayBufferView { - constructor(length: Int) - val length: Int -} -expect class DataView : ArrayBufferView - -expect fun DataView.getInt8(byteOffset: Int): Byte -expect fun DataView.getInt16(byteOffset: Int, littleEndian: Boolean): Short -expect fun DataView.getInt32(byteOffset: Int, littleEndian: Boolean): Int -expect fun DataView.getFloat32(byteOffset: Int, littleEndian: Boolean): Float -expect fun DataView.getFloat64(byteOffset: Int, littleEndian: Boolean): Double -expect fun DataView.setInt8(byteOffset: Int, value: Byte) -expect fun DataView.setInt16(byteOffset: Int, value: Short, littleEndian: Boolean) -expect fun DataView.setInt32(byteOffset: Int, value: Int, littleEndian: Boolean) -expect fun DataView.setFloat32(byteOffset: Int, value: Float, littleEndian: Boolean) -expect fun DataView.setFloat64(byteOffset: Int, value: Double, littleEndian: Boolean) - -expect operator fun Int8Array.get(index: Int): Byte -expect operator fun Int16Array.get(index: Int): Short -expect operator fun Int32Array.get(index: Int): Int -expect operator fun Float32Array.get(index: Int): Float -expect operator fun Float64Array.get(index: Int): Double -expect operator fun Uint8ClampedArray.get(index: Int): Int -expect operator fun Uint8Array.get(index: Int): Int -expect operator fun Uint16Array.get(index: Int): Int - -expect operator fun Int8Array.set(index: Int, value: Byte) -expect operator fun Int16Array.set(index: Int, value: Short) -expect operator fun Int32Array.set(index: Int, value: Int) -expect operator fun Float32Array.set(index: Int, value: Float) -expect operator fun Float64Array.set(index: Int, value: Double) -expect operator fun Uint8ClampedArray.set(index: Int, value: Int) -expect operator fun Uint8Array.set(index: Int, value: Int) -expect operator fun Uint16Array.set(index: Int, value: Int) - -operator fun Int64Array.get(index: Int): Long { - return Long.fromLowHigh(ints[index * 2 + 0], ints[index * 2 + 1]) -} -operator fun Int64Array.set(index: Int, value: Long) { - ints[index * 2 + 0] = value.low - ints[index * 2 + 1] = value.high -} - -class Int64Array(override val buffer: ArrayBuffer, override val byteOffset: Int = 0, val length: Int = (buffer.byteLength - byteOffset) / 8, unit: Unit = Unit) : ArrayBufferView { - val ints = Int32Array(buffer, byteOffset, length * 2) - override val byteLength: Int = length * 8 - constructor(length: Int) : this(ArrayBuffer(length * 8)) -} - -fun Int8Array(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = (buffer.byteLength - byteOffset) / 1, unit: Unit = Unit): Int8Array = buffer.int8Array(byteOffset, length) -fun Int16Array(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = (buffer.byteLength - byteOffset) / 2, unit: Unit = Unit): Int16Array = buffer.int16Array(byteOffset, length) -fun Int32Array(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = (buffer.byteLength - byteOffset) / 4, unit: Unit = Unit): Int32Array = buffer.int32Array(byteOffset, length) -fun Float32Array(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = (buffer.byteLength - byteOffset) / 4, unit: Unit = Unit): Float32Array = buffer.float32Array(byteOffset, length) -fun Float64Array(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = (buffer.byteLength - byteOffset) / 8, unit: Unit = Unit): Float64Array = buffer.float64Array(byteOffset, length) -fun Uint8ClampedArray(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = (buffer.byteLength - byteOffset) / 1, unit: Unit = Unit): Uint8ClampedArray = buffer.uint8ClampedArray(byteOffset, length) -fun Uint8Array(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = (buffer.byteLength - byteOffset) / 1, unit: Unit = Unit): Uint8Array = buffer.uint8Array(byteOffset, length) -fun Uint16Array(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = (buffer.byteLength - byteOffset) / 2, unit: Unit = Unit): Uint16Array = buffer.uint16Array(byteOffset, length) - -fun DataView(size: Int): DataView { - check(size.isMultipleOf(8)) { "size=$size not multiple of 8"} - return DataView(ArrayBuffer(size)) -} -fun DataView(buffer: ArrayBuffer, byteOffset: Int = 0, byteLength: Int = buffer.byteLength - byteOffset, unit: Unit = Unit): DataView = buffer.dataView(byteOffset, byteLength) - -fun DataView.getUint8(byteOffset: Int): Int = getInt8(byteOffset).toInt() and 0xFF -fun DataView.getUint16(byteOffset: Int, littleEndian: Boolean): Int = getInt16(byteOffset, littleEndian).toInt() and 0xFFFF -fun DataView.getUint32(byteOffset: Int, littleEndian: Boolean): UInt = getInt32(byteOffset, littleEndian).toUInt() - -fun DataView.setUint8(byteOffset: Int, value: Int) = setInt8(byteOffset, value.toByte()) -fun DataView.setUint16(byteOffset: Int, value: Int, littleEndian: Boolean) = setInt16(byteOffset, value.toShort(), littleEndian) -fun DataView.setUint32(byteOffset: Int, value: UInt, littleEndian: Boolean) = setInt32(byteOffset, value.toInt(), littleEndian) - -fun DataView.setS8(byteOffset: Int, value: Byte) = setInt8(byteOffset, value.toByte()) -fun DataView.setS8(byteOffset: Int, value: Int) = setInt8(byteOffset, value.toByte()) -fun DataView.setU8(byteOffset: Int, value: Int) = setInt8(byteOffset, value.toByte()) - -fun DataView.getS8(byteOffset: Int): Byte = getInt8(byteOffset) -fun DataView.getU8(byteOffset: Int): Int = getUint8(byteOffset).toInt() - -fun DataView.getS16LE(byteOffset: Int): Short = getInt16(byteOffset, true) -fun DataView.getU16LE(byteOffset: Int): Int = getUint16(byteOffset, true).toInt() -fun DataView.getS32LE(byteOffset: Int): Int = getInt32(byteOffset, true) -fun DataView.getU32LE(byteOffset: Int): UInt = getUint32(byteOffset, true).toUInt() -fun DataView.getF32LE(byteOffset: Int): Float = getFloat32(byteOffset, true) -fun DataView.getF64LE(byteOffset: Int): Double = getFloat64(byteOffset, true) -fun DataView.getS16BE(byteOffset: Int): Short = getInt16(byteOffset, false) -fun DataView.getU16BE(byteOffset: Int): Int = getUint16(byteOffset, false).toInt() -fun DataView.getS32BE(byteOffset: Int): Int = getInt32(byteOffset, false) -fun DataView.getU32BE(byteOffset: Int): UInt = getUint32(byteOffset, false).toUInt() -fun DataView.getF32BE(byteOffset: Int): Float = getFloat32(byteOffset, false) -fun DataView.getF64BE(byteOffset: Int): Double = getFloat64(byteOffset, false) - -fun DataView.setS16LE(byteOffset: Int, value: Short) { setInt16(byteOffset, value, true) } -fun DataView.setU16LE(byteOffset: Int, value: Int) { setUint16(byteOffset, value, true) } -fun DataView.setS32LE(byteOffset: Int, value: Int) { setInt32(byteOffset, value, true) } -fun DataView.setU32LE(byteOffset: Int, value: UInt) { setUint32(byteOffset, value, true) } -fun DataView.setF32LE(byteOffset: Int, value: Float) { setFloat32(byteOffset, value, true) } -fun DataView.setF64LE(byteOffset: Int, value: Double) { setFloat64(byteOffset, value, true) } -fun DataView.setS16BE(byteOffset: Int, value: Short) { setInt16(byteOffset, value, false) } -fun DataView.setU16BE(byteOffset: Int, value: Int) { setUint16(byteOffset, value, false) } -fun DataView.setS32BE(byteOffset: Int, value: Int) { setInt32(byteOffset, value, false) } -fun DataView.setU32BE(byteOffset: Int, value: UInt) { setUint32(byteOffset, value, false) } -fun DataView.setF32BE(byteOffset: Int, value: Float) { setFloat32(byteOffset, value, false) } -fun DataView.setF64BE(byteOffset: Int, value: Double) { setFloat64(byteOffset, value, false) } - -fun DataView.setS64LE(byteOffset: Int, value: Long) { - setS32LE(byteOffset + 0, value.low) - setS32LE(byteOffset + 4, value.high) -} -fun DataView.setS64BE(byteOffset: Int, value: Long) { - setS32BE(byteOffset + 0, value.high) - setS32BE(byteOffset + 4, value.low) -} - -fun DataView.getS64LE(byteOffset: Int): Long = Long.fromLowHigh(getS32LE(byteOffset + 0), getS32LE(byteOffset + 4)) -fun DataView.getS64BE(byteOffset: Int): Long = Long.fromLowHigh(getS32BE(byteOffset + 4), getS32BE(byteOffset + 0)) - -fun Uint8ClampedArray(size: Int, direct: Boolean): Uint8ClampedArray = Uint8ClampedArray(ArrayBuffer(size * 1, direct)) -fun Uint8Array(size: Int, direct: Boolean): Uint8Array = Uint8Array(ArrayBuffer(size * 1, direct)) -fun Uint16Array(size: Int, direct: Boolean): Uint16Array = Uint16Array(ArrayBuffer(size * 2, direct)) -fun Int8Array(size: Int, direct: Boolean): Int8Array = Int8Array(ArrayBuffer(size * 1, direct)) -fun Int16Array(size: Int, direct: Boolean): Int16Array = Int16Array(ArrayBuffer(size * 2, direct)) -fun Int32Array(size: Int, direct: Boolean): Int32Array = Int32Array(ArrayBuffer(size * 4, direct)) -fun Int64Array(size: Int, direct: Boolean): Int64Array = Int64Array(ArrayBuffer(size * 8, direct)) -fun Float32Array(size: Int, direct: Boolean): Float32Array = Float32Array(ArrayBuffer(size * 4, direct)) -fun Float64Array(size: Int, direct: Boolean): Float64Array = Float64Array(ArrayBuffer(size * 8, direct)) - -inline fun Uint8ClampedArray(size: Int, direct: Boolean = false, block: (Int) -> Int): Uint8ClampedArray = Uint8ClampedArray(size, direct).also { for (n in 0 until size) it[n] = block(n) } -inline fun Uint8Array(size: Int, direct: Boolean = false, block: (Int) -> Int): Uint8Array = Uint8Array(size, direct).also { for (n in 0 until size) it[n] = block(n) } -inline fun Uint16Array(size: Int, direct: Boolean = false, block: (Int) -> Int): Uint16Array = Uint16Array(size, direct).also { for (n in 0 until size) it[n] = block(n) } -inline fun Int8Array(size: Int, direct: Boolean = false, block: (Int) -> Byte): Int8Array = Int8Array(size, direct).also { for (n in 0 until size) it[n] = block(n) } -inline fun Int16Array(size: Int, direct: Boolean = false, block: (Int) -> Short): Int16Array = Int16Array(size, direct).also { for (n in 0 until size) it[n] = block(n) } -inline fun Int32Array(size: Int, direct: Boolean = false, block: (Int) -> Int): Int32Array = Int32Array(size, direct).also { for (n in 0 until size) it[n] = block(n) } -inline fun Int64Array(size: Int, direct: Boolean = false, block: (Int) -> Long): Int64Array = Int64Array(size, direct).also { for (n in 0 until size) it[n] = block(n) } -inline fun Float32Array(size: Int, direct: Boolean = false, block: (Int) -> Float): Float32Array = Float32Array(size, direct).also { for (n in 0 until size) it[n] = block(n) } -inline fun Float64Array(size: Int, direct: Boolean = false, block: (Int) -> Double): Float64Array = Float64Array(size, direct).also { for (n in 0 until size) it[n] = block(n) } - -fun ByteArray.toInt8Array(): Int8Array = ArrayBufferWrap(this.copyOf()).int8Array() -fun Int8Array.toByteArray(): ByteArray = buffer.readBytes(byteOffset, byteLength) - -fun UByteArray.toUint8ClampedArray(direct: Boolean = false): Uint8ClampedArray = Uint8ClampedArray(size, direct) { this[it].toInt() } -fun UByteArray.toUint8Array(direct: Boolean = false): Uint8Array = Uint8Array(size, direct) { this[it].toInt() } -fun UShortArray.toUint16Array(direct: Boolean = false): Uint16Array = Uint16Array(size, direct) { this[it].toInt() } -fun ShortArray.toInt16Array(direct: Boolean = false): Int16Array = Int16Array(size, direct) { this[it] } -fun IntArray.toInt32Array(direct: Boolean = false): Int32Array = Int32Array(size, direct) { this[it] } -fun LongArray.toInt64Array(direct: Boolean = false): Int64Array = Int64Array(size, direct) { this[it] } -fun FloatArray.toFloat32Array(direct: Boolean = false): Float32Array = Float32Array(size, direct) { this[it] } -fun DoubleArray.toFloat64Array(direct: Boolean = false): Float64Array = Float64Array(size, direct) { this[it] } - -fun Uint8ClampedArray.toList(): List = toUByteArray().toList() -fun Uint8Array.toList(): List = toUByteArray().toList() -fun Uint16Array.toList(): List = toUShortArray().toList() -fun Int8Array.toList(): List = toByteArray().toList() -fun Int16Array.toList(): List = toShortArray().toList() -fun Int32Array.toList(): List = toIntArray().toList() -fun Float32Array.toList(): List = toFloatArray().toList() -fun Float64Array.toList(): List = toDoubleArray().toList() - -fun Uint8ClampedArray.toUByteArray(): UByteArray = UByteArray(length) { this[it].toUByte() } -fun Uint8Array.toUByteArray(): UByteArray = UByteArray(length) { this[it].toUByte() } -fun Uint16Array.toUShortArray(): UShortArray = UShortArray(length) { this[it].toUShort() } -fun Int16Array.toShortArray(): ShortArray = ShortArray(length) { this[it].toShort() } -fun Int32Array.toIntArray(): IntArray = IntArray(length) { this[it].toInt() } -fun Int64Array.toLongArray(): LongArray = LongArray(length) { this[it].toLong() } -fun Float32Array.toFloatArray(): FloatArray = FloatArray(length) { this[it].toFloat() } -fun Float64Array.toDoubleArray(): DoubleArray = DoubleArray(length) { this[it].toDouble() } - -//fun Uint8ClampedArray.toUByteArray(): UByteArray = asInt8Array().toByteArray().asUByteArray() -//fun Uint8Array.toUByteArray(): UByteArray = asInt8Array().toByteArray().asUByteArray() -//fun Uint16Array.toUShortArray(): UShortArray = UShortArray(length) { this[it].toUShort() } -//fun Int16Array.toShortArray(): ShortArray = ShortArray(length) { this[it] } -//fun Int32Array.toIntArray(): IntArray = IntArray(length) { this[it] } -//fun Int64Array.toLongArray(): LongArray = LongArray(length) { this[it] } -//fun Float32Array.toFloatArray(): FloatArray = FloatArray(length) { this[it] } -//fun Float64Array.toDoubleArray(): DoubleArray = DoubleArray(length) { this[it] } diff --git a/korge-foundation/src/commonTest/kotlin/korlibs/memory/arrays/TypedArraysTest.kt b/korge-foundation/src/commonTest/kotlin/korlibs/memory/arrays/TypedArraysTest.kt deleted file mode 100644 index c8d8edff94..0000000000 --- a/korge-foundation/src/commonTest/kotlin/korlibs/memory/arrays/TypedArraysTest.kt +++ /dev/null @@ -1,218 +0,0 @@ -@file:Suppress("PackageDirectoryMismatch") - -package korlibs.memory.arrays - -import korlibs.encoding.* -import kotlin.test.* - -class TypedArraysTest { - @Test - fun test() { - val data = Int8Array(10) - val data2 = data.buffer.int8Array(1) - for (n in 0 until 10) data[n] = (1 + n).toByte() - for (n in 0 until 10) assertEquals((1 + n).toByte(), data[n]) - for (n in 0 until 9) assertEquals((2 + n).toByte(), data2[n]) - assertEquals(0, data.byteOffset) - assertEquals(10, data.byteLength) - assertEquals(10, data.length) - assertEquals(1, data2.byteOffset) - assertEquals(9, data2.byteLength) - assertEquals(9, data2.length) - } - - @Test - fun test2() { - val data = Int8Array(16) - val data2 = Int8Array(data.buffer, 4 + 3).subarray(2) - val data3 = data.buffer.int16Array(6 + 2, 3) - val dataView = DataView(data.buffer, 4, 6) - data3[0] = 10 - data3[1] = 12 - data2[2] = 7 - assertEquals("00000000000000000a000c0700000000", data.bytes.hex) - assertEquals(1804, data3[1]) - assertEquals("0/16", data.info) - assertEquals("9/7", data2.info) - assertEquals("8/6", data3.info) - assertEquals(0, dataView.getS32LE(0)) - assertEquals(167772160, dataView.getS32LE(1)) - assertEquals(655360, dataView.getS32LE(2)) - } - - @Test - fun test3() { - val data = Int8Array(80) - val view = data.buffer.dataView(1) - var offset = 0 - fun offset(size: Int) = offset.also { offset += size } - view.setU8(offset(1), -1) - view.setS8(offset(1), -2) - view.setU16LE(offset(2), -3) - view.setS16LE(offset(2), -4) - view.setU32LE(offset(4), (-5).toUInt()) - view.setS32LE(offset(4), -6) - view.setS64LE(offset(8), -7) - view.setF32LE(offset(4), -8f) - view.setF64LE(offset(8), -9.0) - view.setU16BE(offset(2), -10) - view.setS16BE(offset(2), -11) - view.setU32BE(offset(4), (-12).toUInt()) - view.setS32BE(offset(4), -13) - view.setS64BE(offset(8), -14) - view.setF32BE(offset(4), -15f) - view.setF64BE(offset(8), -16.0) - - assertEquals("00fffefdfffcfffbfffffffafffffff9ffffffffffffff000000c100000000000022c0fff6fff5fffffff4fffffff3fffffffffffffff2c1700000c03000000000000000000000000000000000000000", data.bytes.hex) - offset = 0 - assertEquals(255, view.getU8(offset(1))) - assertEquals(-2, view.getS8(offset(1))) - assertEquals(65533, view.getU16LE(offset(2))) - assertEquals(-4, view.getS16LE(offset(2))) - assertEquals(4294967291L.toInt(), view.getU32LE(offset(4)).toLong().toInt()) - assertEquals(-6, view.getS32LE(offset(4))) - assertEquals(-7, view.getS64LE(offset(8))) - assertEquals(-8f, view.getF32LE(offset(4))) - assertEquals(-9.0, view.getF64LE(offset(8))) - assertEquals(65526, view.getU16BE(offset(2))) - assertEquals(-11, view.getS16BE(offset(2))) - assertEquals(-12, view.getU32BE(offset(4)).toLong().toInt()) - assertEquals(-13, view.getS32BE(offset(4))) - assertEquals(-14, view.getS64BE(offset(8))) - assertEquals(-15f, view.getF32BE(offset(4))) - assertEquals(-16.0, view.getF64BE(offset(8))) - } - - @Test - fun testLong() { - val data = Int8Array(16) - val view = data.buffer.dataView(0) - view.setS64LE(0, 1L) - view.setS64BE(8, 1L) - assertEquals(1L, view.getS64LE(0)) - assertEquals(1L, view.getS64BE(8)) - assertEquals("01000000000000000000000000000001", data.bytes.hex) - } - - @Test - fun testUIntClamped() { - val data = Uint8ClampedArray(7) - data[0] = 1000 - data[1] = 255 - data[2] = 254 - data[3] = 10 - data[4] = 0 - data[5] = -100 - data[6] = -1000 - assertEquals("fffffe0a000000", Int8Array(data.buffer).bytes.hex) - } - - @Test - fun testUInt8() { - val data = Uint8Array(7) - data[0] = 1000 - data[1] = 255 - data[2] = 254 - data[3] = 10 - data[4] = 0 - data[5] = -100 - data[6] = -1000 - assertEquals("e8fffe0a009c18", Int8Array(data.buffer).bytes.hex) - } - - @Test - fun testInt64Array() { - val values = Int64Array(2) - val data = DataView(values.buffer) - val v0 = -1L - val v1 = 1100277060986L - values[0] = v0 - assertEquals(v0, values[0]) - assertEquals(v0, data.getS64LE(0)) - values[1] = v1 - assertEquals(v1, values[1]) - assertEquals(v1, data.getS64LE(8)) - } - - @Test - fun testAs() { - val values = Int64Array(2) - val ints = values.asInt8Array().subarray(4).asInt32Array() - ints[1] = -2 - ints[2] = -1 - assertEquals(0L, values[0]) - assertEquals(-2L, values[1]) - } - - @Test - fun testSet() { - val values = Int64Array(2) - val ints = values.asInt8Array().subarray(4).asInt32Array() - ints[1] = -2 - ints[2] = -1 - assertEquals(0L, values[0]) - assertEquals(-2L, values[1]) - } - - @Test - fun testArrays() { - val buffer = ArrayBuffer(24) - val s8 = Int8Array(buffer, 1) - val s16 = Int16Array(buffer, 2) - val s32 = Int32Array(buffer, 4) - val s64 = Int64Array(buffer, 8) - val f32 = Float32Array(buffer, 4) - val f64 = Float64Array(buffer, 0) - f64[0] = 1.0 - s64[1] = 2L - f32[2] = 3f - s32[3] = 4 - s16[7] = 5 - s8[9] = 6 - assertEquals("000000000000f03f00000600000040400500000000000000", buffer.int8Array().toByteArray().hex) - } - - @Test - fun testExtract() { - assertEquals(ubyteArrayOf(1u, 2u, 3u, 4u).toList(), ubyteArrayOf(1u, 2u, 3u, 4u).toUint8ClampedArray().toUByteArray().toList()) - assertEquals(ubyteArrayOf(1u, 2u, 3u, 4u).toList(), ubyteArrayOf(1u, 2u, 3u, 4u).toUint8Array().toUByteArray().toList()) - assertEquals(ushortArrayOf(1u, 2u, 3u, 4u).toList(), ushortArrayOf(1u, 2u, 3u, 4u).toUint16Array().toUShortArray().toList()) - assertEquals(byteArrayOf(1, 2, 3, 4).toList(), byteArrayOf(1, 2, 3, 4).toInt8Array().toByteArray().toList()) - assertEquals(shortArrayOf(1, 2, 3, 4).toList(), shortArrayOf(1, 2, 3, 4).toInt16Array().toShortArray().toList()) - assertEquals(intArrayOf(1, 2, 3, 4).toList(), intArrayOf(1, 2, 3, 4).toInt32Array().toIntArray().toList()) - assertEquals(longArrayOf(1, 2, 3, 4).toList(), longArrayOf(1, 2, 3, 4).toInt64Array().toLongArray().toList()) - assertEquals(floatArrayOf(1f, 2f, 3f, 4f).toList(), floatArrayOf(1f, 2f, 3f, 4f).toFloat32Array().toFloatArray().toList()) - assertEquals(doubleArrayOf(1.0, 2.0, 3.0, 4.0).toList(), doubleArrayOf(1.0, 2.0, 3.0, 4.0).toFloat64Array().toDoubleArray().toList()) - } - - @Test - fun testCopy() { - val src = Int8Array(4, direct = true) { (10 + it).toByte() } - val dst = ArrayBufferDirect(16).int16Array() - dst.set(src.subarray(1), 3) - assertEquals("0000000000000b0c0d00000000000000", dst.asInt8Array().toByteArray().hex) - } - - @Test - fun testClone() { - run { - val dataA = Int8Array(4) { (10 + it).toByte() }.subarray(1) - val dataB = dataA.clone() - dataA[1] = -22 - dataB[1] = -11 - assertEquals("0bea0d", dataA.bytes.hex) - assertEquals("0bf50d", dataB.bytes.hex) - } - run { - val dataA = Int16Array(4) { (10 + it).toShort() }.subarray(1) - val dataB = dataA.clone() - dataA[1] = -22 - dataB[1] = -11 - assertEquals("0b00eaff0d00", dataA.asInt8Array().bytes.hex) - assertEquals("0b00f5ff0d00", dataB.asInt8Array().bytes.hex) - } - } - - val Int8Array.bytes: ByteArray get() = toByteArray() - val ArrayBufferView.info: String get() = "$byteOffset/$byteLength" -} diff --git a/korge-foundation/src/jsMain/kotlin/korlibs/memory/TypedArrays.js.kt b/korge-foundation/src/jsMain/kotlin/korlibs/memory/TypedArrays.js.kt deleted file mode 100644 index da77091038..0000000000 --- a/korge-foundation/src/jsMain/kotlin/korlibs/memory/TypedArrays.js.kt +++ /dev/null @@ -1,81 +0,0 @@ -@file:Suppress("PackageDirectoryMismatch") - -package korlibs.memory.arrays - -actual typealias BufferDataSource = org.khronos.webgl.BufferDataSource -actual typealias ArrayBuffer = org.khronos.webgl.ArrayBuffer -actual typealias ArrayBufferView = org.khronos.webgl.ArrayBufferView - -actual fun ArrayBufferDirect(size: Int): ArrayBuffer = ArrayBuffer(size) -actual fun ArrayBufferWrap(data: ByteArray): ArrayBuffer { - val int8Array = data.unsafeCast() - check(int8Array.byteOffset == 0) - return int8Array.buffer -} -internal actual fun ArrayBuffer_copy(src: ArrayBuffer, srcPos: Int, dst: ArrayBuffer, dstPos: Int, length: Int) { - Int8Array(dst, dstPos, length).set(Int8Array(src, srcPos, length), 0) -} - -actual inline fun ArrayBuffer.uint8ClampedArray(byteOffset: Int, length: Int): Uint8ClampedArray = org.khronos.webgl.Uint8ClampedArray(this, byteOffset, length) -actual inline fun ArrayBuffer.uint8Array(byteOffset: Int, length: Int): Uint8Array = org.khronos.webgl.Uint8Array(this, byteOffset, length) -actual inline fun ArrayBuffer.uint16Array(byteOffset: Int, length: Int): Uint16Array = org.khronos.webgl.Uint16Array(this, byteOffset, length) -actual inline fun ArrayBuffer.int8Array(byteOffset: Int, length: Int): Int8Array = org.khronos.webgl.Int8Array(this, byteOffset, length) -actual inline fun ArrayBuffer.int16Array(byteOffset: Int, length: Int): Int16Array = org.khronos.webgl.Int16Array(this, byteOffset, length) -actual inline fun ArrayBuffer.int32Array(byteOffset: Int, length: Int): Int32Array = org.khronos.webgl.Int32Array(this, byteOffset, length) -actual inline fun ArrayBuffer.float32Array(byteOffset: Int, length: Int): Float32Array = org.khronos.webgl.Float32Array(this, byteOffset, length) -actual inline fun ArrayBuffer.float64Array(byteOffset: Int, length: Int): Float64Array = org.khronos.webgl.Float64Array(this, byteOffset, length) -actual inline fun ArrayBuffer.dataView(byteOffset: Int, length: Int): DataView = org.khronos.webgl.DataView(this, byteOffset, length) - -actual typealias Int8Array = org.khronos.webgl.Int8Array -actual typealias Int16Array = org.khronos.webgl.Int16Array -actual typealias Int32Array = org.khronos.webgl.Int32Array -actual typealias Float32Array = org.khronos.webgl.Float32Array -actual typealias Float64Array = org.khronos.webgl.Float64Array -actual typealias Uint8ClampedArray = org.khronos.webgl.Uint8ClampedArray -actual typealias Uint8Array = org.khronos.webgl.Uint8Array -actual typealias Uint16Array = org.khronos.webgl.Uint16Array - -actual typealias DataView = org.khronos.webgl.DataView - -actual inline fun DataView.getInt8(byteOffset: Int): Byte = (this.unsafeCast().getInt8(byteOffset)) -actual inline fun DataView.getInt16(byteOffset: Int, littleEndian: Boolean): Short = (this.unsafeCast().getInt16(byteOffset, littleEndian)) -actual inline fun DataView.getInt32(byteOffset: Int, littleEndian: Boolean): Int = (this.unsafeCast().getInt32(byteOffset, littleEndian)) -actual inline fun DataView.getFloat32(byteOffset: Int, littleEndian: Boolean): Float = (this.unsafeCast().getFloat32(byteOffset, littleEndian)) -actual inline fun DataView.getFloat64(byteOffset: Int, littleEndian: Boolean): Double = (this.unsafeCast().getFloat64(byteOffset, littleEndian)) -actual inline fun DataView.setInt8(byteOffset: Int, value: Byte) { (this.unsafeCast().setInt8(byteOffset, value)) } -actual inline fun DataView.setInt16(byteOffset: Int, value: Short, littleEndian: Boolean) { (this.unsafeCast().setInt16(byteOffset, value, littleEndian)) } -actual inline fun DataView.setInt32(byteOffset: Int, value: Int, littleEndian: Boolean) { (this.unsafeCast().setInt32(byteOffset, value, littleEndian)) } -actual inline fun DataView.setFloat32(byteOffset: Int, value: Float, littleEndian: Boolean) { (this.unsafeCast().setFloat32(byteOffset, value, littleEndian)) } -actual inline fun DataView.setFloat64(byteOffset: Int, value: Double, littleEndian: Boolean) { (this.unsafeCast().setFloat64(byteOffset, value, littleEndian)) } - -actual inline operator fun Int8Array.get(index: Int): Byte = asDynamic()[index] -actual inline operator fun Int16Array.get(index: Int): Short = asDynamic()[index] -actual inline operator fun Int32Array.get(index: Int): Int = asDynamic()[index] -actual inline operator fun Float32Array.get(index: Int): Float = asDynamic()[index] -actual inline operator fun Float64Array.get(index: Int): Double = asDynamic()[index] -actual inline operator fun Uint8ClampedArray.get(index: Int): Int = asDynamic()[index] -actual inline operator fun Uint8Array.get(index: Int): Int = asDynamic()[index] -actual inline operator fun Uint16Array.get(index: Int): Int = asDynamic()[index] - -actual inline operator fun Int8Array.set(index: Int, value: Byte) { asDynamic()[index] = value } -actual inline operator fun Int16Array.set(index: Int, value: Short) { asDynamic()[index] = value } -actual inline operator fun Int32Array.set(index: Int, value: Int) { asDynamic()[index] = value } -actual inline operator fun Float32Array.set(index: Int, value: Float) { asDynamic()[index] = value } -actual inline operator fun Float64Array.set(index: Int, value: Double) { asDynamic()[index] = value } -actual inline operator fun Uint8ClampedArray.set(index: Int, value: Int) { asDynamic()[index] = value } -actual inline operator fun Uint8Array.set(index: Int, value: Int) { asDynamic()[index] = value } -actual inline operator fun Uint16Array.set(index: Int, value: Int) { asDynamic()[index] = value } - -fun Int8Array.asByteArray(): ByteArray = unsafeCast() -fun Int16Array.asShortArray(): ShortArray = unsafeCast() -fun Int32Array.asIntArray(): IntArray = unsafeCast() -fun Float32Array.asFloatArray(): FloatArray = unsafeCast() -fun Float64Array.asDoubleArray(): DoubleArray = unsafeCast() -fun Uint16Array.asCharArray(): CharArray = unsafeCast() - -fun ByteArray.asInt8Array(): Int8Array = unsafeCast() -fun ShortArray.asInt16Array(): Int16Array = unsafeCast() -fun IntArray.asInt32Array(): Int32Array = unsafeCast() -fun FloatArray.asFloat32Array(): Float32Array = unsafeCast() -fun DoubleArray.asFloat64Array(): Float64Array = unsafeCast() -fun CharArray.asUint16Array(): Uint16Array = unsafeCast() diff --git a/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/TypedArrays.jvm.kt b/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/TypedArrays.jvm.kt deleted file mode 100644 index 9bf0d336e9..0000000000 --- a/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/TypedArrays.jvm.kt +++ /dev/null @@ -1,137 +0,0 @@ -@file:Suppress("PackageDirectoryMismatch", "NOTHING_TO_INLINE") - -package korlibs.memory.arrays - -import korlibs.math.* -import java.nio.* - -actual interface BufferDataSource - -// Invariants: mark <= position <= limit <= capacity -actual class ArrayBuffer(val buffer: ByteBuffer) : BufferDataSource { - init { buffer.order(ByteOrder.LITTLE_ENDIAN) } - actual constructor(length: Int) : this(ByteBuffer.allocate(length)) - actual val byteLength: Int get() = buffer.limit() - buffer.position() -} - -actual interface ArrayBufferView : BufferDataSource { - actual val buffer: ArrayBuffer - actual val byteOffset: Int - actual val byteLength: Int -} - -private fun java.nio.Buffer.positionSafe(newPosition: Int) { - position(newPosition) -} - -private fun java.nio.Buffer.limitSafe(newLimit: Int) { - limit(newLimit) -} - -private fun java.nio.Buffer.flipSafe() { - flip() -} - -private fun java.nio.Buffer.clearSafe() { - clear() -} - -private fun java.nio.ByteBuffer.slicedBuffer(offset: Int, size: Int): ByteBuffer { - return this.duplicate().also { - it.order(ByteOrder.nativeOrder()) - it.positionSafe(offset) - it.limitSafe(offset + size) - } -} - -actual fun ArrayBufferDirect(size: Int): ArrayBuffer = ArrayBuffer(ByteBuffer.allocateDirect(size)) -actual fun ArrayBufferWrap(data: ByteArray): ArrayBuffer = ArrayBuffer(ByteBuffer.wrap(data)) -internal actual fun ArrayBuffer_copy(src: ArrayBuffer, srcPos: Int, dst: ArrayBuffer, dstPos: Int, length: Int) { - val srcBuf = src.buffer - val dstBuf = dst.buffer - - if (!srcBuf.isDirect && !dstBuf.isDirect) { - System.arraycopy(srcBuf.array(), srcPos, dstBuf.array(), dstPos, length) - return - } - dst.buffer.slicedBuffer(dstPos, length).put(src.buffer.slicedBuffer(srcPos, length)) -} - -val ArrayBufferView.jbuffer: ByteBuffer get() = buffer.buffer - -actual inline fun ArrayBuffer.uint8ClampedArray(byteOffset: Int, length: Int): Uint8ClampedArray = Uint8ClampedArray(this, byteOffset, length) -actual inline fun ArrayBuffer.uint8Array(byteOffset: Int, length: Int): Uint8Array = Uint8Array(this, byteOffset, length) -actual inline fun ArrayBuffer.uint16Array(byteOffset: Int, length: Int): Uint16Array = Uint16Array(this, byteOffset, length) -actual inline fun ArrayBuffer.int8Array(byteOffset: Int, length: Int): Int8Array = Int8Array(this, byteOffset, length) -actual inline fun ArrayBuffer.int16Array(byteOffset: Int, length: Int): Int16Array = Int16Array(this, byteOffset, length) -actual inline fun ArrayBuffer.int32Array(byteOffset: Int, length: Int): Int32Array = Int32Array(this, byteOffset, length) -actual inline fun ArrayBuffer.float32Array(byteOffset: Int, length: Int): Float32Array = Float32Array(this, byteOffset, length) -actual inline fun ArrayBuffer.float64Array(byteOffset: Int, length: Int): Float64Array = Float64Array(this, byteOffset, length) -actual inline fun ArrayBuffer.dataView(byteOffset: Int, length: Int): DataView = DataView(this, byteOffset, length) - -actual class Int8Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 1 - actual constructor(length: Int) : this(ArrayBuffer(length), 0, length) -} -actual class Int16Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 2 - actual constructor(length: Int) : this(ArrayBuffer(length * 2), 0, length) -} -actual class Int32Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 4 - actual constructor(length: Int) : this(ArrayBuffer(length * 4), 0, length) -} -actual class Float32Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 4 - actual constructor(length: Int) : this(ArrayBuffer(length * 4), 0, length) -} -actual class Float64Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 8 - actual constructor(length: Int) : this(ArrayBuffer(length * 8), 0, length) -} -actual class Uint8ClampedArray(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 1 - actual constructor(length: Int) : this(ArrayBuffer(length * 1), 0, length) -} -actual class Uint8Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 1 - actual constructor(length: Int) : this(ArrayBuffer(length * 1), 0, length) -} -actual class Uint16Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 2 - actual constructor(length: Int) : this(ArrayBuffer(length * 2), 0, length) -} -actual class DataView(override val buffer: ArrayBuffer, override val byteOffset: Int, override val byteLength: Int) : ArrayBufferView { - val bufferLE = jbuffer.slice().order(ByteOrder.LITTLE_ENDIAN) - val bufferBE = jbuffer.slice().order(ByteOrder.BIG_ENDIAN) - fun jbuffer(littleEndian: Boolean): ByteBuffer = if (littleEndian) bufferLE else bufferBE -} - -actual inline fun DataView.getInt8(byteOffset: Int): Byte = bufferLE.get(byteOffset(byteOffset, 1)) -actual inline fun DataView.getInt16(byteOffset: Int, littleEndian: Boolean): Short = jbuffer(littleEndian).getShort(byteOffset(byteOffset, 2)) -actual inline fun DataView.getInt32(byteOffset: Int, littleEndian: Boolean): Int = jbuffer(littleEndian).getInt(byteOffset(byteOffset, 4)) -actual inline fun DataView.getFloat32(byteOffset: Int, littleEndian: Boolean): Float = jbuffer(littleEndian).getFloat(byteOffset(byteOffset, 4)) -actual inline fun DataView.getFloat64(byteOffset: Int, littleEndian: Boolean): Double = jbuffer(littleEndian).getDouble(byteOffset(byteOffset, 8)) -actual inline fun DataView.setInt8(byteOffset: Int, value: Byte) { bufferLE.put(byteOffset(byteOffset, 1), value) } -actual inline fun DataView.setInt16(byteOffset: Int, value: Short, littleEndian: Boolean) { jbuffer(littleEndian).putShort(byteOffset(byteOffset, 2), value) } -actual inline fun DataView.setInt32(byteOffset: Int, value: Int, littleEndian: Boolean) { jbuffer(littleEndian).putInt(byteOffset(byteOffset, 4), value) } -actual inline fun DataView.setFloat32(byteOffset: Int, value: Float, littleEndian: Boolean) { jbuffer(littleEndian).putFloat(byteOffset(byteOffset, 4), value) } -actual inline fun DataView.setFloat64(byteOffset: Int, value: Double, littleEndian: Boolean) { jbuffer(littleEndian).putDouble(byteOffset(byteOffset, 8), value) } - -actual operator fun Int8Array.get(index: Int): Byte = jbuffer.get(byteOffset(index)) -actual operator fun Int16Array.get(index: Int): Short = jbuffer.getShort(byteOffset(index)) -actual operator fun Int32Array.get(index: Int): Int = jbuffer.getInt(byteOffset(index)) -actual operator fun Float32Array.get(index: Int): Float = jbuffer.getFloat(byteOffset(index)) -actual operator fun Float64Array.get(index: Int): Double = jbuffer.getDouble(byteOffset(index)) -actual operator fun Uint8ClampedArray.get(index: Int): Int = jbuffer.get(byteOffset(index)).toInt() and 0xFF -actual operator fun Uint8Array.get(index: Int): Int = jbuffer.get(byteOffset(index)).toInt() and 0xFF -actual operator fun Uint16Array.get(index: Int): Int = jbuffer.getShort(byteOffset(index)).toInt() and 0xFFFF - -actual operator fun Int8Array.set(index: Int, value: Byte) { jbuffer.put(byteOffset(index), value) } -actual operator fun Int16Array.set(index: Int, value: Short) { jbuffer.putShort(byteOffset(index), value) } -actual operator fun Int32Array.set(index: Int, value: Int) { jbuffer.putInt(byteOffset(index), value) } -actual operator fun Float32Array.set(index: Int, value: Float) { jbuffer.putFloat(byteOffset(index), value) } -actual operator fun Float64Array.set(index: Int, value: Double) { jbuffer.putDouble(byteOffset(index), value) } -actual operator fun Uint8ClampedArray.set(index: Int, value: Int) { jbuffer.put(byteOffset(index), value.clamp(0, 255).toByte()) } -actual operator fun Uint8Array.set(index: Int, value: Int) { jbuffer.put(byteOffset(index), value.toByte()) } -actual operator fun Uint16Array.set(index: Int, value: Int) { jbuffer.putShort(byteOffset(index), value.toShort()) } diff --git a/korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/TypedArrays.wasmJs.kt b/korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/TypedArrays.wasmJs.kt deleted file mode 100644 index acdedf74ff..0000000000 --- a/korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/TypedArrays.wasmJs.kt +++ /dev/null @@ -1,101 +0,0 @@ -@file:Suppress("PackageDirectoryMismatch") - -package korlibs.memory.arrays - -import korlibs.math.* -import korlibs.memory.* - -actual interface BufferDataSource - -actual class ArrayBuffer(val data: ByteArray) : BufferDataSource { - actual constructor(length: Int) : this(ByteArray(length)) - actual val byteLength: Int get() = data.size -} - -actual interface ArrayBufferView : BufferDataSource { - actual val buffer: ArrayBuffer - actual val byteOffset: Int - actual val byteLength: Int -} - -val ArrayBufferView.data: ByteArray get() = buffer.data - -actual fun ArrayBufferDirect(size: Int): ArrayBuffer = ArrayBuffer(size) -actual fun ArrayBufferWrap(data: ByteArray): ArrayBuffer = ArrayBuffer(data) -internal actual fun ArrayBuffer_copy(src: ArrayBuffer, srcPos: Int, dst: ArrayBuffer, dstPos: Int, length: Int) { - arraycopy(src.data, srcPos, dst.data, dstPos, length) -} - -actual inline fun ArrayBuffer.uint8ClampedArray(byteOffset: Int, length: Int): Uint8ClampedArray = Uint8ClampedArray(this, byteOffset, length) -actual inline fun ArrayBuffer.uint8Array(byteOffset: Int, length: Int): Uint8Array = Uint8Array(this, byteOffset, length) -actual inline fun ArrayBuffer.uint16Array(byteOffset: Int, length: Int): Uint16Array = Uint16Array(this, byteOffset, length) -actual inline fun ArrayBuffer.int8Array(byteOffset: Int, length: Int): Int8Array = Int8Array(this, byteOffset, length) -actual inline fun ArrayBuffer.int16Array(byteOffset: Int, length: Int): Int16Array = Int16Array(this, byteOffset, length) -actual inline fun ArrayBuffer.int32Array(byteOffset: Int, length: Int): Int32Array = Int32Array(this, byteOffset, length) -actual inline fun ArrayBuffer.float32Array(byteOffset: Int, length: Int): Float32Array = Float32Array(this, byteOffset, length) -actual inline fun ArrayBuffer.float64Array(byteOffset: Int, length: Int): Float64Array = Float64Array(this, byteOffset, length) -actual inline fun ArrayBuffer.dataView(byteOffset: Int, length: Int): DataView = DataView(this, byteOffset, length) - -actual class Int8Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 1 - actual constructor(length: Int) : this(ArrayBuffer(length), 0, length) -} -actual class Int16Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 2 - actual constructor(length: Int) : this(ArrayBuffer(length * 2), 0, length) -} -actual class Int32Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 4 - actual constructor(length: Int) : this(ArrayBuffer(length * 4), 0, length) -} -actual class Float32Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 4 - actual constructor(length: Int) : this(ArrayBuffer(length * 4), 0, length) -} -actual class Float64Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 8 - actual constructor(length: Int) : this(ArrayBuffer(length * 8), 0, length) -} -actual class Uint8ClampedArray(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 1 - actual constructor(length: Int) : this(ArrayBuffer(length * 1), 0, length) -} -actual class Uint8Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 1 - actual constructor(length: Int) : this(ArrayBuffer(length * 1), 0, length) -} -actual class Uint16Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 2 - actual constructor(length: Int) : this(ArrayBuffer(length * 2), 0, length) -} -actual class DataView(override val buffer: ArrayBuffer, override val byteOffset: Int, override val byteLength: Int) : ArrayBufferView { -} - -actual fun DataView.getInt8(byteOffset: Int): Byte = data.getS8(byteOffset(byteOffset, 1)).toByte() -actual fun DataView.getInt16(byteOffset: Int, littleEndian: Boolean): Short = data.getS16(byteOffset(byteOffset, 2), littleEndian).toShort() -actual fun DataView.getInt32(byteOffset: Int, littleEndian: Boolean): Int = data.getS32(byteOffset(byteOffset, 4), littleEndian) -actual fun DataView.getFloat32(byteOffset: Int, littleEndian: Boolean): Float = data.getF32(byteOffset(byteOffset, 4), littleEndian) -actual fun DataView.getFloat64(byteOffset: Int, littleEndian: Boolean): Double = data.getF64(byteOffset(byteOffset, 8), littleEndian) -actual fun DataView.setInt8(byteOffset: Int, value: Byte) { data.set8(byteOffset(byteOffset, 1), value.toInt()) } -actual fun DataView.setInt16(byteOffset: Int, value: Short, littleEndian: Boolean) { data.set16(byteOffset(byteOffset, 2), value.toInt(), littleEndian) } -actual fun DataView.setInt32(byteOffset: Int, value: Int, littleEndian: Boolean) { data.set32(byteOffset(byteOffset, 4), value, littleEndian) } -actual fun DataView.setFloat32(byteOffset: Int, value: Float, littleEndian: Boolean) { data.setF32(byteOffset(byteOffset, 4), value, littleEndian) } -actual fun DataView.setFloat64(byteOffset: Int, value: Double, littleEndian: Boolean) { data.setF64(byteOffset(byteOffset, 8), value, littleEndian) } - -actual operator fun Int8Array.get(index: Int): Byte = data[byteOffset(index)] -actual operator fun Int16Array.get(index: Int): Short = data.getS16LE(byteOffset(index)).toShort() -actual operator fun Int32Array.get(index: Int): Int = data.getS32LE(byteOffset(index)) -actual operator fun Float32Array.get(index: Int): Float = data.getF32LE(byteOffset(index)) -actual operator fun Float64Array.get(index: Int): Double = data.getF64LE(byteOffset(index)) -actual operator fun Uint8ClampedArray.get(index: Int): Int = data[byteOffset(index)].toInt() and 0xFF -actual operator fun Uint8Array.get(index: Int): Int = data[byteOffset(index)].toInt() and 0xFF -actual operator fun Uint16Array.get(index: Int): Int = data.getS16LE(byteOffset(index)) and 0xFFFF - -actual operator fun Int8Array.set(index: Int, value: Byte) { data[byteOffset(index)] = value } -actual operator fun Int16Array.set(index: Int, value: Short) { data.set16LE(byteOffset(index), value.toInt()) } -actual operator fun Int32Array.set(index: Int, value: Int) { data.set32LE(byteOffset(index), value) } -actual operator fun Float32Array.set(index: Int, value: Float) { data.setF32LE(byteOffset(index), value) } -actual operator fun Float64Array.set(index: Int, value: Double) { data.setF64LE(byteOffset(index), value) } -actual operator fun Uint8ClampedArray.set(index: Int, value: Int) { data.set(byteOffset(index), value.clamp(0, 255).toByte()) } -actual operator fun Uint8Array.set(index: Int, value: Int) { data.set(byteOffset(index), value.toByte()) } -actual operator fun Uint16Array.set(index: Int, value: Int) { data.set16LE(byteOffset(index), value) } From 08e729ee26313e4bbb88cb1af51e8b7846051405 Mon Sep 17 00:00:00 2001 From: soywiz Date: Wed, 27 Sep 2023 02:07:54 +0200 Subject: [PATCH 3/7] Some cleanups --- .../src/jsMain/kotlin/korlibs/ffi/FFILib.js.kt | 5 +++-- .../kotlin/korlibs/audio/sound/impl/jna/AL.kt | 1 - .../src/commonMain/kotlin/korlibs/memory/Buffer.kt | 13 +++++++++---- .../memory/{BufferNative.kt => Buffer.native.kt} | 0 .../src/jsMain/kotlin/korlibs/memory/Buffer.js.kt | 4 ++-- .../memory/{Buffer.wasm.kt => Buffer.wasmJs.kt} | 8 ++++---- .../src/commonMain/kotlin/korlibs/kgl/KmlGlProxy.kt | 1 - .../src/jsMain/kotlin/korlibs/kgl/KmlGlJsCanvas.kt | 1 + .../kotlin/korlibs/kgl/KmlGlWasmCanvas.kt | 1 + 9 files changed, 20 insertions(+), 14 deletions(-) rename korge-foundation/src/darwinMain/kotlin/korlibs/memory/{BufferNative.kt => Buffer.native.kt} (100%) rename korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/{Buffer.wasm.kt => Buffer.wasmJs.kt} (94%) diff --git a/korge-core/src/jsMain/kotlin/korlibs/ffi/FFILib.js.kt b/korge-core/src/jsMain/kotlin/korlibs/ffi/FFILib.js.kt index 92ff052fe6..f606e95888 100644 --- a/korge-core/src/jsMain/kotlin/korlibs/ffi/FFILib.js.kt +++ b/korge-core/src/jsMain/kotlin/korlibs/ffi/FFILib.js.kt @@ -5,6 +5,7 @@ import korlibs.io.* import korlibs.io.runtime.deno.* import korlibs.js.* import korlibs.memory.* +import korlibs.memory.Buffer import kotlinx.coroutines.* import org.khronos.webgl.* import kotlin.js.Promise @@ -189,8 +190,8 @@ actual val FFIPointer?.address: Long get() { actual fun CreateFFIPointer(ptr: Long): FFIPointer? = if (ptr == 0L) null else Deno.UnsafePointer.create(ptr.toJsBigInt()) actual val FFIPointer?.str: String get() = if (this == null) "Pointer(null)" else "Pointer($value)" -fun FFIPointer.getDataView(offset: Int, size: Int): DataView { - return DataView(Deno.UnsafePointerView(this).getArrayBuffer(size, offset)) +fun FFIPointer.getDataView(offset: Int, size: Int): org.khronos.webgl.DataView { + return org.khronos.webgl.DataView(Deno.UnsafePointerView(this).getArrayBuffer(size, offset)) } actual fun FFIPointer.getUnalignedI8(offset: Int): Byte = Deno.UnsafePointerView(this).getInt8(offset) diff --git a/korge-core/src/jvmMain/kotlin/korlibs/audio/sound/impl/jna/AL.kt b/korge-core/src/jvmMain/kotlin/korlibs/audio/sound/impl/jna/AL.kt index 6621c37bc0..cedfe16506 100644 --- a/korge-core/src/jvmMain/kotlin/korlibs/audio/sound/impl/jna/AL.kt +++ b/korge-core/src/jvmMain/kotlin/korlibs/audio/sound/impl/jna/AL.kt @@ -1,7 +1,6 @@ package korlibs.audio.sound.impl.jna import korlibs.logger.Logger -import korlibs.memory.* import korlibs.io.lang.Environment import korlibs.io.time.traceTime import com.sun.jna.Native diff --git a/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt b/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt index 97d27f0897..ed7b43355f 100644 --- a/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt +++ b/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt @@ -5,11 +5,8 @@ package korlibs.memory import korlibs.math.* import kotlin.jvm.* -//typealias Buffer = NDataView +typealias DataView = Buffer -//expect class NDataView { - -// @TODO: slice -> subarray expect class Buffer { constructor(size: Int, direct: Boolean = false) constructor(array: ByteArray, offset: Int = 0, size: Int = array.size - offset) @@ -145,6 +142,14 @@ val Buffer.size: Int get() = sizeInBytes fun Buffer.Companion.allocDirect(size: Int): Buffer = Buffer(size, direct = true) fun Buffer.Companion.allocNoDirect(size: Int): Buffer = Buffer(size, direct = false) +fun arraycopy(src: Buffer, srcPos: Int, dst: ByteArray, dstPos: Int, size: Int) { + src.transferBytes(srcPos, dst, dstPos, size, toArray = true) +} + +fun arraycopy(src: ByteArray, srcPos: Int, dst: Buffer, dstPos: Int, size: Int) { + dst.transferBytes(dstPos, src, srcPos, size, toArray = false) +} + fun Buffer.copyOf(newSize: Int): Buffer { val out = Buffer(newSize) arraycopy(this, 0, out, 0, kotlin.math.min(this.sizeInBytes, newSize)) diff --git a/korge-foundation/src/darwinMain/kotlin/korlibs/memory/BufferNative.kt b/korge-foundation/src/darwinMain/kotlin/korlibs/memory/Buffer.native.kt similarity index 100% rename from korge-foundation/src/darwinMain/kotlin/korlibs/memory/BufferNative.kt rename to korge-foundation/src/darwinMain/kotlin/korlibs/memory/Buffer.native.kt diff --git a/korge-foundation/src/jsMain/kotlin/korlibs/memory/Buffer.js.kt b/korge-foundation/src/jsMain/kotlin/korlibs/memory/Buffer.js.kt index de280fba7f..f2f8d10306 100644 --- a/korge-foundation/src/jsMain/kotlin/korlibs/memory/Buffer.js.kt +++ b/korge-foundation/src/jsMain/kotlin/korlibs/memory/Buffer.js.kt @@ -3,7 +3,7 @@ package korlibs.memory import korlibs.platform.* import org.khronos.webgl.* -actual class Buffer(val dataView: DataView) { +actual class Buffer(val dataView: org.khronos.webgl.DataView) { actual constructor(size: Int, direct: Boolean) : this(DataView(ArrayBuffer(checkNBufferSize(size)))) actual constructor(array: ByteArray, offset: Int, size: Int) : this(DataView(checkNBufferWrap(array, offset, size).unsafeCast().buffer, offset, size)) @@ -11,7 +11,7 @@ actual class Buffer(val dataView: DataView) { actual val sizeInBytes: Int get() = this.dataView.byteLength actual fun sliceInternal(start: Int, end: Int): Buffer = - Buffer(DataView(this.buffer, this.byteOffset + start, end - start)) + Buffer(DataView(buffer, byteOffset + start, end - start)) fun sliceUint8Array(offset: Int = 0, size: Int = dataView.byteLength - offset): Uint8Array = Uint8Array(buffer, dataView.byteOffset + offset, size) diff --git a/korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/Buffer.wasm.kt b/korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/Buffer.wasmJs.kt similarity index 94% rename from korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/Buffer.wasm.kt rename to korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/Buffer.wasmJs.kt index 17520779c1..5278b4bbe0 100644 --- a/korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/Buffer.wasm.kt +++ b/korge-foundation/src/wasmJsMain/kotlin/korlibs/memory/Buffer.wasmJs.kt @@ -4,19 +4,19 @@ import korlibs.memory.wasm.* import korlibs.platform.* import org.khronos.webgl.* -actual class Buffer(val dataView: DataView) { - actual constructor(size: Int, direct: Boolean) : this(DataView(ArrayBuffer(checkNBufferSize(size)))) +actual class Buffer(val dataView: org.khronos.webgl.DataView) { + actual constructor(size: Int, direct: Boolean) : this(org.khronos.webgl.DataView(ArrayBuffer(checkNBufferSize(size)))) actual constructor(array: ByteArray, offset: Int, size: Int) : this( //DataView(checkNBufferWrap(array, offset, size).unsafeCast().buffer, offset, size) // @TODO: Can't wrap, so we perform a copy - DataView(array.toInt8Array().buffer, offset, size) + org.khronos.webgl.DataView(array.toInt8Array().buffer, offset, size) ) actual val byteOffset: Int get() = this.dataView.byteOffset actual val sizeInBytes: Int get() = this.dataView.byteLength actual fun sliceInternal(start: Int, end: Int): Buffer = - Buffer(DataView(this.buffer, this.byteOffset + start, end - start)) + Buffer(org.khronos.webgl.DataView(buffer, byteOffset + start, end - start)) fun sliceUint8Array(offset: Int = 0, size: Int = dataView.byteLength - offset): Uint8Array = Uint8Array(buffer, dataView.byteOffset + offset, size) diff --git a/korge/src/commonMain/kotlin/korlibs/kgl/KmlGlProxy.kt b/korge/src/commonMain/kotlin/korlibs/kgl/KmlGlProxy.kt index 9bebab50bd..1288b06553 100644 --- a/korge/src/commonMain/kotlin/korlibs/kgl/KmlGlProxy.kt +++ b/korge/src/commonMain/kotlin/korlibs/kgl/KmlGlProxy.kt @@ -9,7 +9,6 @@ import korlibs.graphics.* import korlibs.graphics.shader.gl.* import korlibs.image.bitmap.* import korlibs.io.lang.* -import korlibs.io.util.* import korlibs.logger.* import korlibs.memory.* import korlibs.number.* diff --git a/korge/src/jsMain/kotlin/korlibs/kgl/KmlGlJsCanvas.kt b/korge/src/jsMain/kotlin/korlibs/kgl/KmlGlJsCanvas.kt index 44bd0fecd4..2e5d5a78d9 100644 --- a/korge/src/jsMain/kotlin/korlibs/kgl/KmlGlJsCanvas.kt +++ b/korge/src/jsMain/kotlin/korlibs/kgl/KmlGlJsCanvas.kt @@ -10,6 +10,7 @@ import korlibs.image.bitmap.* import korlibs.image.format.* import korlibs.math.* import korlibs.memory.* +import korlibs.memory.Buffer import kotlinx.browser.* import org.khronos.webgl.* import org.w3c.dom.* diff --git a/korge/src/wasmJsMain/kotlin/korlibs/kgl/KmlGlWasmCanvas.kt b/korge/src/wasmJsMain/kotlin/korlibs/kgl/KmlGlWasmCanvas.kt index 9408e41bcb..cee0e3fa24 100644 --- a/korge/src/wasmJsMain/kotlin/korlibs/kgl/KmlGlWasmCanvas.kt +++ b/korge/src/wasmJsMain/kotlin/korlibs/kgl/KmlGlWasmCanvas.kt @@ -10,6 +10,7 @@ import korlibs.image.bitmap.* import korlibs.image.format.* import korlibs.io.wasm.* import korlibs.memory.* +import korlibs.memory.Buffer import kotlinx.browser.* import org.khronos.webgl.* import org.w3c.dom.* From a0a9958e2926cacce9f84ba429943853ef9c8e8d Mon Sep 17 00:00:00 2001 From: soywiz Date: Wed, 27 Sep 2023 02:58:47 +0200 Subject: [PATCH 4/7] Some unification on read/write naming --- .../kotlin/korlibs/image/format/ASE.kt | 4 +- .../kotlin/korlibs/image/format/EXIF.kt | 4 +- .../kotlin/korlibs/io/stream/AsyncStream.kt | 24 +- .../io/stream/FastByteArrayInputStream.kt | 24 +- .../kotlin/korlibs/io/stream/SyncStream.kt | 24 +- .../kotlin/korlibs/wasm/WasmRuntime.kt | 12 +- .../io/compression/CompressionJvmTest.kt | 4 +- .../korlibs/io/compression/CompressionTest.kt | 2 +- .../kotlin/korlibs/wasm/WasmJVMTest.kt | 2 +- .../kotlin/korlibs/memory/Arrays.kt | 6 + .../kotlin/korlibs/memory/Buffer.kt | 338 ++++++++++-------- .../kotlin/korlibs/memory/ByteArrayGetSet.kt | 73 ++-- .../korlibs/memory/ByteArrayReadWriteOld.kt | 24 +- .../korlibs/memory/ByteArrayReadWriteTest.kt | 8 +- .../kotlin/korlibs/memory/Buffer.jvm.kt | 1 - 15 files changed, 299 insertions(+), 251 deletions(-) diff --git a/korge-core/src/commonMain/kotlin/korlibs/image/format/ASE.kt b/korge-core/src/commonMain/kotlin/korlibs/image/format/ASE.kt index 8fcbba44c4..db100c1d55 100644 --- a/korge-core/src/commonMain/kotlin/korlibs/image/format/ASE.kt +++ b/korge-core/src/commonMain/kotlin/korlibs/image/format/ASE.kt @@ -412,7 +412,7 @@ object ASE : ImageFormatWithContainer("ase") { val compressedData = cs.readAvailable() .uncompress(ZLib, tilesWidth * tilesHeight * bytesPerTile) val data = when (bitsPerTile) { - 32 -> compressedData.getS32LEArray(0, tilesWidth * tilesHeight) + 32 -> compressedData.getS32ArrayLE(0, tilesWidth * tilesHeight) else -> TODO("Only supported 32-bits per tile") } AseTilemapCell( @@ -580,7 +580,7 @@ object ASE : ImageFormatWithContainer("ase") { val compressedData = cs.readBytesExact(compressedDataLength) // (Tile Width) x (Tile Height x Number of Tiles) val data = compressedData.uncompress(ZLib) - val ints = data.getS32LEArray(0, tileWidth * tileHeight * ntiles) + val ints = data.getS32ArrayLE(0, tileWidth * tileHeight * ntiles) val bitmap = Bitmap32(tileWidth, tileHeight * ntiles, RgbaArray(ints)).also { if (props.premultipliedSure) it.premultiplyInplaceIfRequired() diff --git a/korge-core/src/commonMain/kotlin/korlibs/image/format/EXIF.kt b/korge-core/src/commonMain/kotlin/korlibs/image/format/EXIF.kt index 912f3f81bf..5e437aedc9 100644 --- a/korge-core/src/commonMain/kotlin/korlibs/image/format/EXIF.kt +++ b/korge-core/src/commonMain/kotlin/korlibs/image/format/EXIF.kt @@ -110,8 +110,8 @@ object EXIF { } val data: ByteArray = s.readBytesExact(dataFormat.indexBytes(nComponent)) - fun readUShort(index: Int): Int = data.getU16(index * 2, little = endian.isLittle) - fun readInt(index: Int): Int = data.getS32(index * 4, little = endian.isLittle) + fun readUShort(index: Int): Int = data.getU16(index * 2, littleEndian = endian.isLittle) + fun readInt(index: Int): Int = data.getS32(index * 4, littleEndian = endian.isLittle) if (debug) { if (dataFormat == DataFormat.STRING) { diff --git a/korge-core/src/commonMain/kotlin/korlibs/io/stream/AsyncStream.kt b/korge-core/src/commonMain/kotlin/korlibs/io/stream/AsyncStream.kt index 1623112e08..359efde290 100644 --- a/korge-core/src/commonMain/kotlin/korlibs/io/stream/AsyncStream.kt +++ b/korge-core/src/commonMain/kotlin/korlibs/io/stream/AsyncStream.kt @@ -597,32 +597,32 @@ suspend fun AsyncInputStream.skip(count: Int) { } suspend fun AsyncInputStream.readUByteArray(count: Int): UByteArray = readBytesExact(count).asUByteArray() -suspend fun AsyncInputStream.readShortArrayLE(count: Int): ShortArray = readBytesExact(count * 2).getS16LEArray( +suspend fun AsyncInputStream.readShortArrayLE(count: Int): ShortArray = readBytesExact(count * 2).getS16ArrayLE( 0, count ) -suspend fun AsyncInputStream.readShortArrayBE(count: Int): ShortArray = readBytesExact(count * 2).getS16BEArray( +suspend fun AsyncInputStream.readShortArrayBE(count: Int): ShortArray = readBytesExact(count * 2).getS16ArrayBE( 0, count ) -suspend fun AsyncInputStream.readCharArrayLE(count: Int): CharArray = readBytesExact(count * 2).getU16LEArray(0, count) -suspend fun AsyncInputStream.readCharArrayBE(count: Int): CharArray = readBytesExact(count * 2).getU16BEArray(0, count) -suspend fun AsyncInputStream.readIntArrayLE(count: Int): IntArray = readBytesExact(count * 4).getS32LEArray(0, count) -suspend fun AsyncInputStream.readIntArrayBE(count: Int): IntArray = readBytesExact(count * 4).getS32BEArray(0, count) -suspend fun AsyncInputStream.readLongArrayLE(count: Int): LongArray = readBytesExact(count * 8).getS64LEArray(0, count) -suspend fun AsyncInputStream.readLongArrayBE(count: Int): LongArray = readBytesExact(count * 8).getS64LEArray(0, count) -suspend fun AsyncInputStream.readFloatArrayLE(count: Int): FloatArray = readBytesExact(count * 4).getF32LEArray( +suspend fun AsyncInputStream.readCharArrayLE(count: Int): CharArray = readBytesExact(count * 2).getU16ArrayLE(0, count) +suspend fun AsyncInputStream.readCharArrayBE(count: Int): CharArray = readBytesExact(count * 2).getU16ArrayBE(0, count) +suspend fun AsyncInputStream.readIntArrayLE(count: Int): IntArray = readBytesExact(count * 4).getS32ArrayLE(0, count) +suspend fun AsyncInputStream.readIntArrayBE(count: Int): IntArray = readBytesExact(count * 4).getS32ArrayBE(0, count) +suspend fun AsyncInputStream.readLongArrayLE(count: Int): LongArray = readBytesExact(count * 8).getS64ArrayLE(0, count) +suspend fun AsyncInputStream.readLongArrayBE(count: Int): LongArray = readBytesExact(count * 8).getS64ArrayLE(0, count) +suspend fun AsyncInputStream.readFloatArrayLE(count: Int): FloatArray = readBytesExact(count * 4).getF32ArrayLE( 0, count ) -suspend fun AsyncInputStream.readFloatArrayBE(count: Int): FloatArray = readBytesExact(count * 4).getF32BEArray( +suspend fun AsyncInputStream.readFloatArrayBE(count: Int): FloatArray = readBytesExact(count * 4).getF32ArrayBE( 0, count ) suspend fun AsyncInputStream.readDoubleArrayLE(count: Int): DoubleArray = - readBytesExact(count * 8).getF64LEArray(0, count) + readBytesExact(count * 8).getF64ArrayLE(0, count) suspend fun AsyncInputStream.readDoubleArrayBE(count: Int): DoubleArray = - readBytesExact(count * 8).getF64BEArray(0, count) + readBytesExact(count * 8).getF64ArrayBE(0, count) suspend fun AsyncInputStream.readShortArray(count: Int, endian: Endian): ShortArray = if (endian.isLittle) readShortArrayLE(count) else readShortArrayBE(count) suspend fun AsyncInputStream.readCharArray(count: Int, endian: Endian): CharArray = if (endian.isLittle) readCharArrayLE(count) else readCharArrayBE(count) diff --git a/korge-core/src/commonMain/kotlin/korlibs/io/stream/FastByteArrayInputStream.kt b/korge-core/src/commonMain/kotlin/korlibs/io/stream/FastByteArrayInputStream.kt index b9e21e7bc9..6637845090 100644 --- a/korge-core/src/commonMain/kotlin/korlibs/io/stream/FastByteArrayInputStream.kt +++ b/korge-core/src/commonMain/kotlin/korlibs/io/stream/FastByteArrayInputStream.kt @@ -115,23 +115,23 @@ class FastByteArrayInputStream(val ba: ByteArray, offset: Int = 0, val start: In fun readBytes(count: Int) = ba.getS8Array(offset(count), count) // Arrays - fun readShortArrayLE(count: Int): ShortArray = ba.getS16LEArray(offset(count * 2), count) - fun readShortArrayBE(count: Int): ShortArray = ba.getS16BEArray(offset(count * 2), count) + fun readShortArrayLE(count: Int): ShortArray = ba.getS16ArrayLE(offset(count * 2), count) + fun readShortArrayBE(count: Int): ShortArray = ba.getS16ArrayBE(offset(count * 2), count) - fun readCharArrayLE(count: Int): CharArray = ba.getU16LEArray(offset(count * 2), count) - fun readCharArrayBE(count: Int): CharArray = ba.getU16BEArray(offset(count * 2), count) + fun readCharArrayLE(count: Int): CharArray = ba.getU16ArrayLE(offset(count * 2), count) + fun readCharArrayBE(count: Int): CharArray = ba.getU16ArrayBE(offset(count * 2), count) - fun readIntArrayLE(count: Int): IntArray = ba.getS32LEArray(offset(count * 4), count) - fun readIntArrayBE(count: Int): IntArray = ba.getS32BEArray(offset(count * 4), count) + fun readIntArrayLE(count: Int): IntArray = ba.getS32ArrayLE(offset(count * 4), count) + fun readIntArrayBE(count: Int): IntArray = ba.getS32ArrayBE(offset(count * 4), count) - fun readLongArrayLE(count: Int): LongArray = ba.getS64LEArray(offset(count * 8), count) - fun readLongArrayBE(count: Int): LongArray = ba.getS64BEArray(offset(count * 8), count) + fun readLongArrayLE(count: Int): LongArray = ba.getS64ArrayLE(offset(count * 8), count) + fun readLongArrayBE(count: Int): LongArray = ba.getS64ArrayBE(offset(count * 8), count) - fun readFloatArrayLE(count: Int): FloatArray = ba.getF32LEArray(offset(count * 4), count) - fun readFloatArrayBE(count: Int): FloatArray = ba.getF32BEArray(offset(count * 4), count) + fun readFloatArrayLE(count: Int): FloatArray = ba.getF32ArrayLE(offset(count * 4), count) + fun readFloatArrayBE(count: Int): FloatArray = ba.getF32ArrayBE(offset(count * 4), count) - fun readDoubleArrayLE(count: Int): DoubleArray = ba.getF64LEArray(offset(count * 8), count) - fun readDoubleArrayBE(count: Int): DoubleArray = ba.getF64BEArray(offset(count * 8), count) + fun readDoubleArrayLE(count: Int): DoubleArray = ba.getF64ArrayLE(offset(count * 8), count) + fun readDoubleArrayBE(count: Int): DoubleArray = ba.getF64ArrayBE(offset(count * 8), count) // Variable Length fun readU_VL(): Int { diff --git a/korge-core/src/commonMain/kotlin/korlibs/io/stream/SyncStream.kt b/korge-core/src/commonMain/kotlin/korlibs/io/stream/SyncStream.kt index 4844a52ffd..bada61c99c 100644 --- a/korge-core/src/commonMain/kotlin/korlibs/io/stream/SyncStream.kt +++ b/korge-core/src/commonMain/kotlin/korlibs/io/stream/SyncStream.kt @@ -510,23 +510,23 @@ fun SyncStream.readAll(): ByteArray = readBytes(available.toInt()) fun SyncInputStream.readUByteArray(count: Int): UByteArray = readBytesExact(count).asUByteArray() -fun SyncInputStream.readShortArrayLE(count: Int): ShortArray = readBytesExact(count * 2).getS16LEArray(0, count) -fun SyncInputStream.readShortArrayBE(count: Int): ShortArray = readBytesExact(count * 2).getS16BEArray(0, count) +fun SyncInputStream.readShortArrayLE(count: Int): ShortArray = readBytesExact(count * 2).getS16ArrayLE(0, count) +fun SyncInputStream.readShortArrayBE(count: Int): ShortArray = readBytesExact(count * 2).getS16ArrayBE(0, count) -fun SyncInputStream.readCharArrayLE(count: Int): CharArray = readBytesExact(count * 2).getU16LEArray(0, count) -fun SyncInputStream.readCharArrayBE(count: Int): CharArray = readBytesExact(count * 2).getU16BEArray(0, count) +fun SyncInputStream.readCharArrayLE(count: Int): CharArray = readBytesExact(count * 2).getU16ArrayLE(0, count) +fun SyncInputStream.readCharArrayBE(count: Int): CharArray = readBytesExact(count * 2).getU16ArrayBE(0, count) -fun SyncInputStream.readIntArrayLE(count: Int): IntArray = readBytesExact(count * 4).getS32LEArray(0, count) -fun SyncInputStream.readIntArrayBE(count: Int): IntArray = readBytesExact(count * 4).getS32BEArray(0, count) +fun SyncInputStream.readIntArrayLE(count: Int): IntArray = readBytesExact(count * 4).getS32ArrayLE(0, count) +fun SyncInputStream.readIntArrayBE(count: Int): IntArray = readBytesExact(count * 4).getS32ArrayBE(0, count) -fun SyncInputStream.readLongArrayLE(count: Int): LongArray = readBytesExact(count * 8).getS64LEArray(0, count) -fun SyncInputStream.readLongArrayBE(count: Int): LongArray = readBytesExact(count * 8).getS64BEArray(0, count) +fun SyncInputStream.readLongArrayLE(count: Int): LongArray = readBytesExact(count * 8).getS64ArrayLE(0, count) +fun SyncInputStream.readLongArrayBE(count: Int): LongArray = readBytesExact(count * 8).getS64ArrayBE(0, count) -fun SyncInputStream.readFloatArrayLE(count: Int): FloatArray = readBytesExact(count * 4).getF32LEArray(0, count) -fun SyncInputStream.readFloatArrayBE(count: Int): FloatArray = readBytesExact(count * 4).getF32BEArray(0, count) +fun SyncInputStream.readFloatArrayLE(count: Int): FloatArray = readBytesExact(count * 4).getF32ArrayLE(0, count) +fun SyncInputStream.readFloatArrayBE(count: Int): FloatArray = readBytesExact(count * 4).getF32ArrayBE(0, count) -fun SyncInputStream.readDoubleArrayLE(count: Int): DoubleArray = readBytesExact(count * 8).getF64LEArray(0, count) -fun SyncInputStream.readDoubleArrayBE(count: Int): DoubleArray = readBytesExact(count * 8).getF64BEArray(0, count) +fun SyncInputStream.readDoubleArrayLE(count: Int): DoubleArray = readBytesExact(count * 8).getF64ArrayLE(0, count) +fun SyncInputStream.readDoubleArrayBE(count: Int): DoubleArray = readBytesExact(count * 8).getF64ArrayBE(0, count) fun SyncOutputStream.write8(v: Int): Unit = write(v) diff --git a/korge-core/src/commonMain/kotlin/korlibs/wasm/WasmRuntime.kt b/korge-core/src/commonMain/kotlin/korlibs/wasm/WasmRuntime.kt index aae2af6b17..887961127e 100644 --- a/korge-core/src/commonMain/kotlin/korlibs/wasm/WasmRuntime.kt +++ b/korge-core/src/commonMain/kotlin/korlibs/wasm/WasmRuntime.kt @@ -173,23 +173,23 @@ open class WasmRuntime(module: WasmModule, val memSize: Int, val memMax: Int) { @JvmStatic fun Op_i32_load(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getS32(checkAddr(addr, offset, runtime)) @JvmStatic fun Op_i32_load8_s(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getS8(checkAddr(addr, offset, runtime)).toInt() - @JvmStatic fun Op_i32_load8_u(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getUnalignedUInt8(checkAddr(addr, offset, runtime)).toInt() + @JvmStatic fun Op_i32_load8_u(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getU8(checkAddr(addr, offset, runtime)).toInt() @JvmStatic fun Op_i32_load16_s(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getS16(checkAddr(addr, offset, runtime)).toInt() - @JvmStatic fun Op_i32_load16_u(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getUnalignedUInt16(checkAddr(addr, offset, runtime)).toInt() + @JvmStatic fun Op_i32_load16_u(addr: Int, offset: Int, runtime: WasmRuntime): Int = runtime.memory.getU16(checkAddr(addr, offset, runtime)).toInt() @JvmStatic fun Op_i64_load(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getS64(checkAddr(addr, offset, runtime)) @JvmStatic fun Op_i64_load8_s(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getS8(checkAddr(addr, offset, runtime)).toLong() - @JvmStatic fun Op_i64_load8_u(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getUnalignedUInt8(checkAddr(addr, offset, runtime)).toLong() + @JvmStatic fun Op_i64_load8_u(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getU8(checkAddr(addr, offset, runtime)).toLong() @JvmStatic fun Op_i64_load16_s(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getS16(checkAddr(addr, offset, runtime)).toLong() - @JvmStatic fun Op_i64_load16_u(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getUnalignedUInt16(checkAddr(addr, offset, runtime)).toLong() + @JvmStatic fun Op_i64_load16_u(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getU16(checkAddr(addr, offset, runtime)).toLong() @JvmStatic fun Op_i64_load32_s(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getS32(checkAddr(addr, offset, runtime)).toLong() @JvmStatic fun Op_i64_load32_u(addr: Int, offset: Int, runtime: WasmRuntime): Long = runtime.memory.getS32(checkAddr(addr, offset, runtime)).toUInt().toLong() @JvmStatic fun Op_f32_load(addr: Int, offset: Int, runtime: WasmRuntime): Float = runtime.memory.getF32(checkAddr(addr, offset, runtime)) @JvmStatic fun Op_f64_load(addr: Int, offset: Int, runtime: WasmRuntime): Double = runtime.memory.getF64(checkAddr(addr, offset, runtime)) @JvmStatic fun Op_i32_store(addr: Int, value: Int, offset: Int, runtime: WasmRuntime) = runtime.memory.set32(checkAddr(addr, offset, runtime), value) - @JvmStatic fun Op_i32_store8(addr: Int, value: Int, offset: Int, runtime: WasmRuntime) = runtime.memory.setUnalignedInt8(checkAddr(addr, offset, runtime), value) + @JvmStatic fun Op_i32_store8(addr: Int, value: Int, offset: Int, runtime: WasmRuntime) = runtime.memory.set8(checkAddr(addr, offset, runtime), value.toByte()) @JvmStatic fun Op_i32_store16(addr: Int, value: Int, offset: Int, runtime: WasmRuntime) = runtime.memory.set16(checkAddr(addr, offset, runtime), value.toShort()) @JvmStatic fun Op_i64_store(addr: Int, value: Long, offset: Int, runtime: WasmRuntime) = runtime.memory.set64(checkAddr(addr, offset, runtime), value) - @JvmStatic fun Op_i64_store8(addr: Int, value: Long, offset: Int, runtime: WasmRuntime) = runtime.memory.setUnalignedInt8(checkAddr(addr, offset, runtime), value.toInt()) + @JvmStatic fun Op_i64_store8(addr: Int, value: Long, offset: Int, runtime: WasmRuntime) = runtime.memory.set8(checkAddr(addr, offset, runtime), value.toInt().toByte()) @JvmStatic fun Op_i64_store16(addr: Int, value: Long, offset: Int, runtime: WasmRuntime) = runtime.memory.set16(checkAddr(addr, offset, runtime), value.toShort()) @JvmStatic fun Op_i64_store32(addr: Int, value: Long, offset: Int, runtime: WasmRuntime) = runtime.memory.set32(checkAddr(addr, offset, runtime), value.toInt()) @JvmStatic fun Op_f32_store(addr: Int, value: Float, offset: Int, runtime: WasmRuntime) = runtime.memory.setF32(checkAddr(addr, offset, runtime), value) diff --git a/korge-core/src/commonTest/kotlin/korlibs/io/compression/CompressionJvmTest.kt b/korge-core/src/commonTest/kotlin/korlibs/io/compression/CompressionJvmTest.kt index e71114f131..bb93c6fa81 100644 --- a/korge-core/src/commonTest/kotlin/korlibs/io/compression/CompressionJvmTest.kt +++ b/korge-core/src/commonTest/kotlin/korlibs/io/compression/CompressionJvmTest.kt @@ -31,7 +31,7 @@ class CompressionJvmTest { fun gzip() { val data = compressedData val res = data.uncompress(GZIPNoCrc) - val res2 = res.getS32LEArray(0, 4096 / 4) + val res2 = res.getS32ArrayLE(0, 4096 / 4) val actualData = res2.toList().joinToString("") if (expectedData != actualData) { println("EX: $expectedData") @@ -44,7 +44,7 @@ class CompressionJvmTest { fun gzip2() { val data = compressedData val res = data.uncompress(GZIPNoCrc) - val res2 = res.getS32LEArray(0, 4096 / 4) + val res2 = res.getS32ArrayLE(0, 4096 / 4) assertEquals(expectedData, res2.toList().joinToString("")) } diff --git a/korge-core/src/commonTest/kotlin/korlibs/io/compression/CompressionTest.kt b/korge-core/src/commonTest/kotlin/korlibs/io/compression/CompressionTest.kt index 14b2e875e8..ef4f65bb2d 100644 --- a/korge-core/src/commonTest/kotlin/korlibs/io/compression/CompressionTest.kt +++ b/korge-core/src/commonTest/kotlin/korlibs/io/compression/CompressionTest.kt @@ -15,7 +15,7 @@ class CompressionTest { val data = "H4sIAAAAAAAAA+3SsREAEBSD4WcFm2ACTID9dxGFxgDcub/4mjQpEmdmDuYPKwsSJT3qz1KkXu7fWZMu4/IGr78AAAAAAD+a6ywcnAAQAAA=".fromBase64() val res = data.uncompress(GZIP) - val res2 = res.getS32LEArray(0, 4096 / 4) + val res2 = res.getS32ArrayLE(0, 4096 / 4) assertEquals( "" + "1111111111111111111111111111111111111111111111111111111111111111111818181814950511111111111111111111111111818181816566671111111" + diff --git a/korge-core/src/jvmTest/kotlin/korlibs/wasm/WasmJVMTest.kt b/korge-core/src/jvmTest/kotlin/korlibs/wasm/WasmJVMTest.kt index 8f72ab0f54..a07df93279 100644 --- a/korge-core/src/jvmTest/kotlin/korlibs/wasm/WasmJVMTest.kt +++ b/korge-core/src/jvmTest/kotlin/korlibs/wasm/WasmJVMTest.kt @@ -50,7 +50,7 @@ open class WasmTest { val samplesData = module.stackAlloc(MINIMP3_MAX_SAMPLES_PER_FRAME * 2) val info = module.stackAlloc(6 * 4) val result = module("mp3dec_decode_frame", decoder, mp3Data, mp3Bytes.size, samplesData, info) as Int - val infos = module.readBytes(info, 6 * 4).getS32LEArray(0, 6).toList() + val infos = module.readBytes(info, 6 * 4).getS32ArrayLE(0, 6).toList() println("mp3dec_decode_frame(decoder=$decoder, mp3Data=$mp3Data, mp3Bytes.size=${mp3Bytes.size}, samplesData=$samplesData, info=$info) ::: result=$result, infos=$infos") module.stackRestore(stack) } diff --git a/korge-foundation/src/commonMain/kotlin/korlibs/memory/Arrays.kt b/korge-foundation/src/commonMain/kotlin/korlibs/memory/Arrays.kt index 73cbd1f5da..aa7ae88b83 100644 --- a/korge-foundation/src/commonMain/kotlin/korlibs/memory/Arrays.kt +++ b/korge-foundation/src/commonMain/kotlin/korlibs/memory/Arrays.kt @@ -141,6 +141,12 @@ public inline fun arraycopy(size: Int, src: Any?, srcPos: Int, dst: Any?, ds } // Buffer variants +fun arraycopy(src: Buffer, srcPos: Int, dst: ByteArray, dstPos: Int, size: Int) { + src.transferBytes(srcPos, dst, dstPos, size, toArray = true) +} +fun arraycopy(src: ByteArray, srcPos: Int, dst: Buffer, dstPos: Int, size: Int) { + dst.transferBytes(dstPos, src, srcPos, size, toArray = false) +} fun arraycopy(src: Buffer, srcPos: Int, dst: Buffer, dstPos: Int, size: Int) { Buffer.copy(src, srcPos, dst, dstPos, size) } diff --git a/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt b/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt index ed7b43355f..f48ef434bf 100644 --- a/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt +++ b/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt @@ -57,7 +57,7 @@ internal fun Buffer.Companion.hashCodeCommon( } val offset = (len / 4) * 4 for (n in 0 until len % 4) { - h = 31 * h + buffer.getInt8(offset + n) + h = 31 * h + buffer.getS8(offset + n) } return h } @@ -142,14 +142,6 @@ val Buffer.size: Int get() = sizeInBytes fun Buffer.Companion.allocDirect(size: Int): Buffer = Buffer(size, direct = true) fun Buffer.Companion.allocNoDirect(size: Int): Buffer = Buffer(size, direct = false) -fun arraycopy(src: Buffer, srcPos: Int, dst: ByteArray, dstPos: Int, size: Int) { - src.transferBytes(srcPos, dst, dstPos, size, toArray = true) -} - -fun arraycopy(src: ByteArray, srcPos: Int, dst: Buffer, dstPos: Int, size: Int) { - dst.transferBytes(dstPos, src, srcPos, size, toArray = false) -} - fun Buffer.copyOf(newSize: Int): Buffer { val out = Buffer(newSize) arraycopy(this, 0, out, 0, kotlin.math.min(this.sizeInBytes, newSize)) @@ -210,86 +202,136 @@ fun Buffer.set16LEClamped(byteOffset: Int, value: Int): Unit = set16LE(byteOffse fun Buffer.set16BEClamped(byteOffset: Int, value: Int): Unit = set16BE(byteOffset, value.clampUShort().toShort()) inline fun Buffer.set16Clamped(byteOffset: Int, value: Int, littleEndian: Boolean = true): Unit = if (littleEndian) set16LEClamped(byteOffset, value) else set16BEClamped(byteOffset, value) +inline private fun _getArray(byteOffset: Int, out: T, start: Int, size: Int, elementBytes: Int, set: (Int, Int) -> Unit): T { + for (n in 0 until size) set(start + n, byteOffset + n * elementBytes) + return out +} + +fun Buffer.getS8Array(byteOffset: Int, out: ByteArray, start: Int = 0, size: Int = out.size - start): ByteArray = out.also { arraycopy(this, byteOffset, out, start, size) } +fun Buffer.getS16ArrayLE(byteOffset: Int, out: ShortArray, start: Int = 0, size: Int = out.size - start): ShortArray = _getArray(byteOffset, out, start, size, 2) { index, offset -> out[index] = getS16LE(offset) } +fun Buffer.getS32ArrayLE(byteOffset: Int, out: IntArray, start: Int = 0, size: Int = out.size - start): IntArray = _getArray(byteOffset, out, start, size, 4) { index, offset -> out[index] = getS32LE(offset) } +fun Buffer.getS64ArrayLE(byteOffset: Int, out: LongArray, start: Int = 0, size: Int = out.size - start): LongArray = _getArray(byteOffset, out, start, size, 8) { index, offset -> out[index] = getS64LE(offset) } +fun Buffer.getF32ArrayLE(byteOffset: Int, out: FloatArray, start: Int = 0, size: Int = out.size - start): FloatArray = _getArray(byteOffset, out, start, size, 4) { index, offset -> out[index] = getF32LE(offset) } +fun Buffer.getF64ArrayLE(byteOffset: Int, out: DoubleArray, start: Int = 0, size: Int = out.size - start): DoubleArray = _getArray(byteOffset, out, start, size, 8) { index, offset -> out[index] = getF64LE(offset) } +fun Buffer.getS16ArrayBE(byteOffset: Int, out: ShortArray, start: Int = 0, size: Int = out.size - start): ShortArray = _getArray(byteOffset, out, start, size, 2) { index, offset -> out[index] = getS16BE(offset) } +fun Buffer.getS32ArrayBE(byteOffset: Int, out: IntArray, start: Int = 0, size: Int = out.size - start): IntArray = _getArray(byteOffset, out, start, size, 4) { index, offset -> out[index] = getS32BE(offset) } +fun Buffer.getS64ArrayBE(byteOffset: Int, out: LongArray, start: Int = 0, size: Int = out.size - start): LongArray = _getArray(byteOffset, out, start, size, 8) { index, offset -> out[index] = getS64BE(offset) } +fun Buffer.getF32ArrayBE(byteOffset: Int, out: FloatArray, start: Int = 0, size: Int = out.size - start): FloatArray = _getArray(byteOffset, out, start, size, 4) { index, offset -> out[index] = getF32BE(offset) } +fun Buffer.getF64ArrayBE(byteOffset: Int, out: DoubleArray, start: Int = 0, size: Int = out.size - start): DoubleArray = _getArray(byteOffset, out, start, size, 8) { index, offset -> out[index] = getF64BE(offset) } +fun Buffer.getS16Array(byteOffset: Int, out: ShortArray, start: Int = 0, size: Int = out.size - start, littleEndian: Boolean = true): ShortArray = if (littleEndian) getS16ArrayLE(byteOffset, out, start, size) else getS16ArrayBE(byteOffset, out, start, size) +fun Buffer.getS32Array(byteOffset: Int, out: IntArray, start: Int = 0, size: Int = out.size - start, littleEndian: Boolean = true): IntArray = if (littleEndian) getS32ArrayLE(byteOffset, out, start, size) else getS32ArrayBE(byteOffset, out, start, size) +fun Buffer.getS64Array(byteOffset: Int, out: LongArray, start: Int = 0, size: Int = out.size - start, littleEndian: Boolean = true): LongArray = if (littleEndian) getS64ArrayLE(byteOffset, out, start, size) else getS64ArrayBE(byteOffset, out, start, size) +fun Buffer.getF32Array(byteOffset: Int, out: FloatArray, start: Int = 0, size: Int = out.size - start, littleEndian: Boolean = true): FloatArray = if (littleEndian) getF32ArrayLE(byteOffset, out, start, size) else getF32ArrayBE(byteOffset, out, start, size) +fun Buffer.getF64Array(byteOffset: Int, out: DoubleArray, start: Int = 0, size: Int = out.size - start, littleEndian: Boolean = true): DoubleArray = if (littleEndian) getF64ArrayLE(byteOffset, out, start, size) else getF64ArrayBE(byteOffset, out, start, size) + +fun Buffer.getS8Array(byteOffset: Int, size: Int): ByteArray = getS8Array(byteOffset, ByteArray(size)) +fun Buffer.getS16ArrayLE(byteOffset: Int, size: Int): ShortArray = getS16ArrayLE(byteOffset, ShortArray(size)) +fun Buffer.getS32ArrayLE(byteOffset: Int, size: Int): IntArray = getS32ArrayLE(byteOffset, IntArray(size)) +fun Buffer.getS64ArrayLE(byteOffset: Int, size: Int): LongArray = getS64ArrayLE(byteOffset, LongArray(size)) +fun Buffer.getF32ArrayLE(byteOffset: Int, size: Int): FloatArray = getF32ArrayLE(byteOffset, FloatArray(size)) +fun Buffer.getF64ArrayLE(byteOffset: Int, size: Int): DoubleArray = getF64ArrayLE(byteOffset, DoubleArray(size)) +fun Buffer.getS16ArrayBE(byteOffset: Int, size: Int): ShortArray = getS16ArrayBE(byteOffset, ShortArray(size)) +fun Buffer.getS32ArrayBE(byteOffset: Int, size: Int): IntArray = getS32ArrayBE(byteOffset, IntArray(size)) +fun Buffer.getS64ArrayBE(byteOffset: Int, size: Int): LongArray = getS64ArrayBE(byteOffset, LongArray(size)) +fun Buffer.getF32ArrayBE(byteOffset: Int, size: Int): FloatArray = getF32ArrayBE(byteOffset, FloatArray(size)) +fun Buffer.getF64ArrayBE(byteOffset: Int, size: Int): DoubleArray = getF64ArrayBE(byteOffset, DoubleArray(size)) +fun Buffer.getS16Array(byteOffset: Int, size: Int, littleEndian: Boolean = true): ShortArray = if (littleEndian) getS16ArrayLE(byteOffset, size) else getS16ArrayBE(byteOffset, size) +fun Buffer.getS32Array(byteOffset: Int, size: Int, littleEndian: Boolean = true): IntArray = if (littleEndian) getS32ArrayLE(byteOffset, size) else getS32ArrayBE(byteOffset, size) +fun Buffer.getS64Array(byteOffset: Int, size: Int, littleEndian: Boolean = true): LongArray = if (littleEndian) getS64ArrayLE(byteOffset, size) else getS64ArrayBE(byteOffset, size) +fun Buffer.getF32Array(byteOffset: Int, size: Int, littleEndian: Boolean = true): FloatArray = if (littleEndian) getF32ArrayLE(byteOffset, size) else getF32ArrayBE(byteOffset, size) +fun Buffer.getF64Array(byteOffset: Int, size: Int, littleEndian: Boolean = true): DoubleArray = if (littleEndian) getF64ArrayLE(byteOffset, size) else getF64ArrayBE(byteOffset, size) + +private inline fun _setArray(byteOffset: Int, start: Int, size: Int, elementBytes: Int, set: (Int, Int) -> Unit) { + for (n in 0 until size) { + set(byteOffset + n * elementBytes, start + n) + } +} + +fun Buffer.setArray(byteOffset: Int, data: ByteArray, start: Int = 0, size: Int = data.size - start): Unit { arraycopy(data, start, this, byteOffset, size) } +fun Buffer.setArrayLE(byteOffset: Int, data: ShortArray, start: Int = 0, size: Int = data.size - start): Unit = _setArray(byteOffset, start, size, 2) { offset, index -> set16LE(offset, data[index]) } +fun Buffer.setArrayLE(byteOffset: Int, data: IntArray, start: Int = 0, size: Int = data.size - start): Unit = _setArray(byteOffset, start, size, 4) { offset, index -> set32LE(offset, data[index]) } +fun Buffer.setArrayLE(byteOffset: Int, data: LongArray, start: Int = 0, size: Int = data.size - start): Unit = _setArray(byteOffset, start, size, 8) { offset, index -> set64LE(offset, data[index]) } +fun Buffer.setArrayLE(byteOffset: Int, data: FloatArray, start: Int = 0, size: Int = data.size - start): Unit = _setArray(byteOffset, start, size, 4) { offset, index -> setF32LE(offset, data[index]) } +fun Buffer.setArrayLE(byteOffset: Int, data: DoubleArray, start: Int = 0, size: Int = data.size - start): Unit = _setArray(byteOffset, start, size, 8) { offset, index -> setF64LE(offset, data[index]) } +fun Buffer.setArrayBE(byteOffset: Int, data: ShortArray, start: Int = 0, size: Int = data.size - start): Unit = _setArray(byteOffset, start, size, 2) { offset, index -> set16BE(offset, data[index]) } +fun Buffer.setArrayBE(byteOffset: Int, data: IntArray, start: Int = 0, size: Int = data.size - start): Unit = _setArray(byteOffset, start, size, 4) { offset, index -> set32BE(offset, data[index]) } +fun Buffer.setArrayBE(byteOffset: Int, data: LongArray, start: Int = 0, size: Int = data.size - start): Unit = _setArray(byteOffset, start, size, 8) { offset, index -> set64BE(offset, data[index]) } +fun Buffer.setArrayBE(byteOffset: Int, data: FloatArray, start: Int = 0, size: Int = data.size - start): Unit = _setArray(byteOffset, start, size, 4) { offset, index -> setF32BE(offset, data[index]) } +fun Buffer.setArrayBE(byteOffset: Int, data: DoubleArray, start: Int = 0, size: Int = data.size - start): Unit = _setArray(byteOffset, start, size, 8) { offset, index -> setF64BE(offset, data[index]) } +fun Buffer.setArray(byteOffset: Int, data: ShortArray, start: Int = 0, size: Int = data.size - start, littleEndian: Boolean = true): Unit = if (littleEndian) setArrayLE(byteOffset, data, start, size) else setArrayBE(byteOffset, data, start, size) +fun Buffer.setArray(byteOffset: Int, data: IntArray, start: Int = 0, size: Int = data.size - start, littleEndian: Boolean = true): Unit = if (littleEndian) setArrayLE(byteOffset, data, start, size) else setArrayBE(byteOffset, data, start, size) +fun Buffer.setArray(byteOffset: Int, data: LongArray, start: Int = 0, size: Int = data.size - start, littleEndian: Boolean = true): Unit = if (littleEndian) setArrayLE(byteOffset, data, start, size) else setArrayBE(byteOffset, data, start, size) +fun Buffer.setArray(byteOffset: Int, data: FloatArray, start: Int = 0, size: Int = data.size - start, littleEndian: Boolean = true): Unit = if (littleEndian) setArrayLE(byteOffset, data, start, size) else setArrayBE(byteOffset, data, start, size) +fun Buffer.setArray(byteOffset: Int, data: DoubleArray, start: Int = 0, size: Int = data.size - start, littleEndian: Boolean = true): Unit = if (littleEndian) setArrayLE(byteOffset, data, start, size) else setArrayBE(byteOffset, data, start, size) + @Deprecated("", ReplaceWith("getS8(byteOffset)")) fun Buffer.getUnalignedInt8(byteOffset: Int): Byte = getS8(byteOffset) -@Deprecated("", ReplaceWith("getS16LE(byteOffset)")) -fun Buffer.getUnalignedInt16(byteOffset: Int): Short = getS16LE(byteOffset) -@Deprecated("", ReplaceWith("getS32LE(byteOffset)")) -fun Buffer.getUnalignedInt32(byteOffset: Int): Int = getS32LE(byteOffset) -@Deprecated("", ReplaceWith("getS64LE(byteOffset)")) -fun Buffer.getUnalignedInt64(byteOffset: Int): Long = getS64LE(byteOffset) -@Deprecated("", ReplaceWith("getF32LE(byteOffset)")) -fun Buffer.getUnalignedFloat32(byteOffset: Int): Float = getF32LE(byteOffset) -@Deprecated("", ReplaceWith("getF64LE(byteOffset)")) -fun Buffer.getUnalignedFloat64(byteOffset: Int): Double = getF64LE(byteOffset) +@Deprecated("", ReplaceWith("getS16(byteOffset)")) +fun Buffer.getUnalignedInt16(byteOffset: Int): Short = getS16(byteOffset) +@Deprecated("", ReplaceWith("getS32(byteOffset)")) +fun Buffer.getUnalignedInt32(byteOffset: Int): Int = getS32(byteOffset) +@Deprecated("", ReplaceWith("getS64(byteOffset)")) +fun Buffer.getUnalignedInt64(byteOffset: Int): Long = getS64(byteOffset) +@Deprecated("", ReplaceWith("getF32(byteOffset)")) +fun Buffer.getUnalignedFloat32(byteOffset: Int): Float = getF32(byteOffset) +@Deprecated("", ReplaceWith("getF64(byteOffset)")) +fun Buffer.getUnalignedFloat64(byteOffset: Int): Double = getF64(byteOffset) @Deprecated("", ReplaceWith("set8(byteOffset, value)")) fun Buffer.setUnalignedInt8(byteOffset: Int, value: Byte): Unit = set8(byteOffset, value) -@Deprecated("", ReplaceWith("set16LE(byteOffset, value)")) -fun Buffer.setUnalignedInt16(byteOffset: Int, value: Short): Unit = set16LE(byteOffset, value) -@Deprecated("", ReplaceWith("set32LE(byteOffset, value)")) -fun Buffer.setUnalignedInt32(byteOffset: Int, value: Int): Unit = set32LE(byteOffset, value) -@Deprecated("", ReplaceWith("set64LE(byteOffset, value)")) -fun Buffer.setUnalignedInt64(byteOffset: Int, value: Long): Unit = set64LE(byteOffset, value) -@Deprecated("", ReplaceWith("setF32LE(byteOffset, value)")) -fun Buffer.setUnalignedFloat32(byteOffset: Int, value: Float): Unit = setF32LE(byteOffset, value) -@Deprecated("", ReplaceWith("setF64LE(byteOffset, value)")) -fun Buffer.setUnalignedFloat64(byteOffset: Int, value: Double): Unit = setF64LE(byteOffset, value) +@Deprecated("", ReplaceWith("set16(byteOffset, value)")) +fun Buffer.setUnalignedInt16(byteOffset: Int, value: Short): Unit = set16(byteOffset, value) +@Deprecated("", ReplaceWith("set32(byteOffset, value)")) +fun Buffer.setUnalignedInt32(byteOffset: Int, value: Int): Unit = set32(byteOffset, value) +@Deprecated("", ReplaceWith("set64(byteOffset, value)")) +fun Buffer.setUnalignedInt64(byteOffset: Int, value: Long): Unit = set64(byteOffset, value) +@Deprecated("", ReplaceWith("setF32(byteOffset, value)")) +fun Buffer.setUnalignedFloat32(byteOffset: Int, value: Float): Unit = setF32(byteOffset, value) +@Deprecated("", ReplaceWith("setF64(byteOffset, value)")) +fun Buffer.setUnalignedFloat64(byteOffset: Int, value: Double): Unit = setF64(byteOffset, value) // Unaligned versions @Deprecated("", ReplaceWith("getU8(byteOffset)")) fun Buffer.getUnalignedUInt8(byteOffset: Int): Int = getU8(byteOffset) -@Deprecated("", ReplaceWith("getU16LE(byteOffset)")) -fun Buffer.getUnalignedUInt16(byteOffset: Int): Int = getU16LE(byteOffset) +@Deprecated("", ReplaceWith("getU16(byteOffset)")) +fun Buffer.getUnalignedUInt16(byteOffset: Int): Int = getU16(byteOffset) @Deprecated("", ReplaceWith("set8(byteOffset, value.toByte())")) fun Buffer.setUnalignedUInt8(byteOffset: Int, value: Int) = set8(byteOffset, value.toByte()) @Deprecated("", ReplaceWith("set8Clamped(byteOffset, value)")) fun Buffer.setUnalignedUInt8Clamped(byteOffset: Int, value: Int) = set8Clamped(byteOffset, value) -@Deprecated("", ReplaceWith("set16LE(byteOffset, value.toShort())")) -fun Buffer.setUnalignedUInt16(byteOffset: Int, value: Int) = set16LE(byteOffset, value.toShort()) +@Deprecated("", ReplaceWith("set16(byteOffset, value.toShort())")) +fun Buffer.setUnalignedUInt16(byteOffset: Int, value: Int) = set16(byteOffset, value.toShort()) @Deprecated("", ReplaceWith("set8(byteOffset, value.toByte())")) fun Buffer.setUnalignedInt8(byteOffset: Int, value: Int) = set8(byteOffset, value.toByte()) // Array versions -@Deprecated("") -fun Buffer.getUnalignedArrayInt8(byteOffset: Int, out: ByteArray, offset: Int = 0, size: Int = out.size - offset): ByteArray { for (n in 0 until size) out[offset + n] = - getS8(byteOffset + n * 1); return out } -@Deprecated("") -fun Buffer.getUnalignedArrayInt16(byteOffset: Int, out: ShortArray, offset: Int = 0, size: Int = out.size - offset): ShortArray { for (n in 0 until size) out[offset + n] = - getS16LE(byteOffset + n * 2); return out } -@Deprecated("") -fun Buffer.getUnalignedArrayInt32(byteOffset: Int, out: IntArray, offset: Int = 0, size: Int = out.size - offset): IntArray { for (n in 0 until size) out[offset + n] = - getS32LE(byteOffset + n * 4); return out } -@Deprecated("") -fun Buffer.getUnalignedArrayInt64(byteOffset: Int, out: LongArray, offset: Int = 0, size: Int = out.size - offset): LongArray { for (n in 0 until size) out[offset + n] = - getS64LE(byteOffset + n * 8); return out } -@Deprecated("") -fun Buffer.getUnalignedArrayFloat32(byteOffset: Int, out: FloatArray, offset: Int = 0, size: Int = out.size - offset): FloatArray { for (n in 0 until size) out[offset + n] = - getF32LE(byteOffset + n * 4); return out } -@Deprecated("") -fun Buffer.getUnalignedArrayFloat64(byteOffset: Int, out: DoubleArray, offset: Int = 0, size: Int = out.size - offset): DoubleArray { for (n in 0 until size) out[offset + n] = - getF64LE(byteOffset + n * 8); return out } - -@Deprecated("") -fun Buffer.setUnalignedArrayInt8(byteOffset: Int, inp: ByteArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) set8(byteOffset + n * 1, inp[offset + n]) -} -@Deprecated("") -fun Buffer.setUnalignedArrayInt16(byteOffset: Int, inp: ShortArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) set16LE(byteOffset + n * 2, inp[offset + n]) -} -@Deprecated("") -fun Buffer.setUnalignedArrayInt32(byteOffset: Int, inp: IntArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) set32LE(byteOffset + n * 4, inp[offset + n]) -} -@Deprecated("") -fun Buffer.setUnalignedArrayInt64(byteOffset: Int, inp: LongArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) set64LE(byteOffset + n * 8, inp[offset + n]) -} -@Deprecated("") -fun Buffer.setUnalignedArrayFloat32(byteOffset: Int, inp: FloatArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) setF32LE(byteOffset + n * 4, inp[offset + n]) -} -@Deprecated("") -fun Buffer.setUnalignedArrayFloat64(byteOffset: Int, inp: DoubleArray, offset: Int = 0, size: Int = inp.size - offset) { for (n in 0 until size) setF64LE(byteOffset + n * 8, inp[offset + n]) -} +@Deprecated("", ReplaceWith("getS8Array(byteOffset, out, offset, size)")) +fun Buffer.getUnalignedArrayInt8(byteOffset: Int, out: ByteArray, offset: Int = 0, size: Int = out.size - offset): ByteArray = getS8Array(byteOffset, out, offset, size) +@Deprecated("", ReplaceWith("getS16Array(byteOffset, out, offset, size)")) +fun Buffer.getUnalignedArrayInt16(byteOffset: Int, out: ShortArray, offset: Int = 0, size: Int = out.size - offset): ShortArray = getS16Array(byteOffset, out, offset, size) +@Deprecated("", ReplaceWith("getS32Array(byteOffset, out, offset, size)")) +fun Buffer.getUnalignedArrayInt32(byteOffset: Int, out: IntArray, offset: Int = 0, size: Int = out.size - offset): IntArray = getS32Array(byteOffset, out, offset, size) +@Deprecated("", ReplaceWith("getS64Array(byteOffset, out, offset, size)")) +fun Buffer.getUnalignedArrayInt64(byteOffset: Int, out: LongArray, offset: Int = 0, size: Int = out.size - offset): LongArray = getS64Array(byteOffset, out, offset, size) +@Deprecated("", ReplaceWith("getF32Array(byteOffset, out, offset, size)")) +fun Buffer.getUnalignedArrayFloat32(byteOffset: Int, out: FloatArray, offset: Int = 0, size: Int = out.size - offset): FloatArray = getF32Array(byteOffset, out, offset, size) +@Deprecated("", ReplaceWith("getF64Array(byteOffset, out, offset, size)")) +fun Buffer.getUnalignedArrayFloat64(byteOffset: Int, out: DoubleArray, offset: Int = 0, size: Int = out.size - offset): DoubleArray = getF64Array(byteOffset, out, offset, size) + +@Deprecated("", ReplaceWith("setArray(byteOffset, inp, offset, size)")) +fun Buffer.setUnalignedArrayInt8(byteOffset: Int, inp: ByteArray, offset: Int = 0, size: Int = inp.size - offset) = setArray(byteOffset, inp, offset, size) +@Deprecated("", ReplaceWith("setArray(byteOffset, inp, offset, size)")) +fun Buffer.setUnalignedArrayInt16(byteOffset: Int, inp: ShortArray, offset: Int = 0, size: Int = inp.size - offset) = setArray(byteOffset, inp, offset, size) +@Deprecated("", ReplaceWith("setArray(byteOffset, inp, offset, size)")) +fun Buffer.setUnalignedArrayInt32(byteOffset: Int, inp: IntArray, offset: Int = 0, size: Int = inp.size - offset) = setArray(byteOffset, inp, offset, size) +@Deprecated("", ReplaceWith("setArray(byteOffset, inp, offset, size)")) +fun Buffer.setUnalignedArrayInt64(byteOffset: Int, inp: LongArray, offset: Int = 0, size: Int = inp.size - offset) = setArray(byteOffset, inp, offset, size) +@Deprecated("", ReplaceWith("setArray(byteOffset, inp, offset, size)")) +fun Buffer.setUnalignedArrayFloat32(byteOffset: Int, inp: FloatArray, offset: Int = 0, size: Int = inp.size - offset) = setArray(byteOffset, inp, offset, size) +@Deprecated("", ReplaceWith("setArray(byteOffset, inp, offset, size)")) +fun Buffer.setUnalignedArrayFloat64(byteOffset: Int, inp: DoubleArray, offset: Int = 0, size: Int = inp.size - offset) = setArray(byteOffset, inp, offset, size) @Deprecated("", ReplaceWith("getU8(index)")) fun Buffer.getUInt8(index: Int): Int = getU8(index) @@ -331,39 +373,39 @@ fun Buffer.setFloat64(index: Int, value: Double) = setF64LE(index * Double.SIZE_ // ALIGNED ARRAYS -@Deprecated("") -fun Buffer.getArrayUInt8(index: Int, out: UByteArrayInt, offset: Int = 0, size: Int = out.size - offset): UByteArrayInt = UByteArrayInt(getUnalignedArrayInt8(index * 1, out.data, offset, size)) -@Deprecated("") -fun Buffer.getArrayUInt16(index: Int, out: UShortArrayInt, offset: Int = 0, size: Int = out.size - offset): UShortArrayInt = UShortArrayInt(getUnalignedArrayInt16(index * 2, out.data, offset, size)) -@Deprecated("") -fun Buffer.getArrayInt8(index: Int, out: ByteArray, offset: Int = 0, size: Int = out.size - offset): ByteArray = getUnalignedArrayInt8(index * 1, out, offset, size) -@Deprecated("") -fun Buffer.getArrayInt16(index: Int, out: ShortArray, offset: Int = 0, size: Int = out.size - offset): ShortArray = getUnalignedArrayInt16(index * 2, out, offset, size) -@Deprecated("") -fun Buffer.getArrayInt32(index: Int, out: IntArray, offset: Int = 0, size: Int = out.size - offset): IntArray = getUnalignedArrayInt32(index * 4, out, offset, size) -@Deprecated("") -fun Buffer.getArrayInt64(index: Int, out: LongArray, offset: Int = 0, size: Int = out.size - offset): LongArray = getUnalignedArrayInt64(index * 8, out, offset, size) -@Deprecated("") -fun Buffer.getArrayFloat32(index: Int, out: FloatArray, offset: Int = 0, size: Int = out.size - offset): FloatArray = getUnalignedArrayFloat32(index * 4, out, offset, size) -@Deprecated("") -fun Buffer.getArrayFloat64(index: Int, out: DoubleArray, offset: Int = 0, size: Int = out.size - offset): DoubleArray = getUnalignedArrayFloat64(index * 8, out, offset, size) - -@Deprecated("") -fun Buffer.setArrayUInt8(index: Int, inp: UByteArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayInt8(index * 1, inp.data, offset, size) -@Deprecated("") -fun Buffer.setArrayUInt16(index: Int, inp: UShortArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayInt16(index * 2, inp.data, offset, size) -@Deprecated("") -fun Buffer.setArrayInt8(index: Int, inp: ByteArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayInt8(index * 1, inp, offset, size) -@Deprecated("") -fun Buffer.setArrayInt16(index: Int, inp: ShortArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayInt16(index * 2, inp, offset, size) -@Deprecated("") -fun Buffer.setArrayInt32(index: Int, inp: IntArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayInt32(index * 4, inp, offset, size) -@Deprecated("") -fun Buffer.setArrayInt64(index: Int, inp: LongArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayInt64(index * 8, inp, offset, size) -@Deprecated("") -fun Buffer.setArrayFloat32(index: Int, inp: FloatArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayFloat32(index * 4, inp, offset, size) -@Deprecated("") -fun Buffer.setArrayFloat64(index: Int, inp: DoubleArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setUnalignedArrayFloat64(index * 8, inp, offset, size) +@Deprecated("", ReplaceWith("UByteArrayInt(getS8Array(index * Byte.SIZE_BYTES, out.data, offset, size))", "korlibs.memory.UByteArrayInt")) +fun Buffer.getArrayUInt8(index: Int, out: UByteArrayInt, offset: Int = 0, size: Int = out.size - offset): UByteArrayInt = UByteArrayInt(getS8Array(index * Byte.SIZE_BYTES, out.data, offset, size)) +@Deprecated("", ReplaceWith("UShortArrayInt(getS16Array(index * Short.SIZE_BYTES, out.data, offset, size))", "korlibs.memory.UShortArrayInt")) +fun Buffer.getArrayUInt16(index: Int, out: UShortArrayInt, offset: Int = 0, size: Int = out.size - offset): UShortArrayInt = UShortArrayInt(getS16Array(index * Short.SIZE_BYTES, out.data, offset, size)) +@Deprecated("", ReplaceWith("getS8Array(index * Byte.SIZE_BYTES, out, offset, size)")) +fun Buffer.getArrayInt8(index: Int, out: ByteArray, offset: Int = 0, size: Int = out.size - offset): ByteArray = getS8Array(index * Byte.SIZE_BYTES, out, offset, size) +@Deprecated("", ReplaceWith("getS16Array(index * Short.SIZE_BYTES, out, offset, size)")) +fun Buffer.getArrayInt16(index: Int, out: ShortArray, offset: Int = 0, size: Int = out.size - offset): ShortArray = getS16Array(index * Short.SIZE_BYTES, out, offset, size) +@Deprecated("", ReplaceWith("getS32Array(index * Int.SIZE_BYTES, out, offset, size)")) +fun Buffer.getArrayInt32(index: Int, out: IntArray, offset: Int = 0, size: Int = out.size - offset): IntArray = getS32Array(index * Int.SIZE_BYTES, out, offset, size) +@Deprecated("", ReplaceWith("getS64Array(index * Long.SIZE_BYTES, out, offset, size)")) +fun Buffer.getArrayInt64(index: Int, out: LongArray, offset: Int = 0, size: Int = out.size - offset): LongArray = getS64Array(index * Long.SIZE_BYTES, out, offset, size) +@Deprecated("", ReplaceWith("getF32Array(index * Float.SIZE_BYTES, out, offset, size)")) +fun Buffer.getArrayFloat32(index: Int, out: FloatArray, offset: Int = 0, size: Int = out.size - offset): FloatArray = getF32Array(index * Float.SIZE_BYTES, out, offset, size) +@Deprecated("", ReplaceWith("getF64Array(index * Double.SIZE_BYTES, out, offset, size)")) +fun Buffer.getArrayFloat64(index: Int, out: DoubleArray, offset: Int = 0, size: Int = out.size - offset): DoubleArray = getF64Array(index * Double.SIZE_BYTES, out, offset, size) + +@Deprecated("", ReplaceWith("setArray(index * Byte.SIZE_BYTES, inp.data, offset, size)")) +fun Buffer.setArrayUInt8(index: Int, inp: UByteArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = setArray(index * Byte.SIZE_BYTES, inp.data, offset, size) +@Deprecated("", ReplaceWith("setArray(index * Short.SIZE_BYTES, inp.data, offset, size)")) +fun Buffer.setArrayUInt16(index: Int, inp: UShortArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = setArray(index * Short.SIZE_BYTES, inp.data, offset, size) +@Deprecated("", ReplaceWith("setArray(index * Byte.SIZE_BYTES, inp, offset, size)")) +fun Buffer.setArrayInt8(index: Int, inp: ByteArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setArray(index * Byte.SIZE_BYTES, inp, offset, size) +@Deprecated("", ReplaceWith("setArray(index * Short.SIZE_BYTES, inp, offset, size)")) +fun Buffer.setArrayInt16(index: Int, inp: ShortArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setArray(index * Short.SIZE_BYTES, inp, offset, size) +@Deprecated("", ReplaceWith("setArray(index * Int.SIZE_BYTES, inp, offset, size)")) +fun Buffer.setArrayInt32(index: Int, inp: IntArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setArray(index * Int.SIZE_BYTES, inp, offset, size) +@Deprecated("", ReplaceWith("setArray(index * Long.SIZE_BYTES, inp, offset, size)")) +fun Buffer.setArrayInt64(index: Int, inp: LongArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setArray(index * Long.SIZE_BYTES, inp, offset, size) +@Deprecated("", ReplaceWith("setArray(index * Float.SIZE_BYTES, inp, offset, size)")) +fun Buffer.setArrayFloat32(index: Int, inp: FloatArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setArray(index * Float.SIZE_BYTES, inp, offset, size) +@Deprecated("", ReplaceWith("setArray(index * Double.SIZE_BYTES, inp, offset, size)")) +fun Buffer.setArrayFloat64(index: Int, inp: DoubleArray, offset: Int = 0, size: Int = inp.size - offset): Unit = setArray(index * Double.SIZE_BYTES, inp, offset, size) interface BaseBuffer { val size: Int @@ -408,14 +450,14 @@ value class Int8Buffer(override val buffer: Buffer) : TypedBuffer { const val ELEMENT_SIZE_IN_BYTES = 1 } constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) - constructor(data: ByteArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayInt8(0, data, offset, size) }) + constructor(data: ByteArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArray(0, data, offset, size) }) override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES - operator fun get(index: Int): Byte = buffer.getInt8(index) - operator fun set(index: Int, value: Byte) = buffer.setInt8(index, value) - fun getArray(index: Int, out: ByteArray, offset: Int = 0, size: Int = out.size - offset): ByteArray = buffer.getArrayInt8(index, out, offset, size) + operator fun get(index: Int): Byte = buffer.getS8(index) + operator fun set(index: Int, value: Byte) = buffer.set8(index, value) + fun getArray(index: Int, out: ByteArray, offset: Int = 0, size: Int = out.size - offset): ByteArray = buffer.getS8Array(index * ELEMENT_SIZE_IN_BYTES, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): ByteArray = getArray(index, ByteArray(size)) - fun setArray(index: Int, inp: ByteArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayInt8(index, inp, offset, size) + fun setArray(index: Int, inp: ByteArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp, offset, size) fun slice(start: Int = 0, end: Int = this.size): Int8Buffer = Int8Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int8Buffer = slice(start, start + size) @@ -427,14 +469,14 @@ value class Int16Buffer(override val buffer: Buffer) : TypedBuffer { const val ELEMENT_SIZE_IN_BYTES = 2 } constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) - constructor(data: ShortArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayInt16(0, data, offset, size) }) + constructor(data: ShortArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArray(0, data, offset, size) }) override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES - operator fun get(index: Int): Short = buffer.getS16LE(index * ELEMENT_SIZE_IN_BYTES) - operator fun set(index: Int, value: Short) = buffer.set16LE(index * ELEMENT_SIZE_IN_BYTES, value) - fun getArray(index: Int, out: ShortArray, offset: Int = 0, size: Int = out.size - offset): ShortArray = buffer.getArrayInt16(index, out, offset, size) + operator fun get(index: Int): Short = buffer.getS16(index * ELEMENT_SIZE_IN_BYTES) + operator fun set(index: Int, value: Short) = buffer.set16(index * ELEMENT_SIZE_IN_BYTES, value) + fun getArray(index: Int, out: ShortArray, offset: Int = 0, size: Int = out.size - offset): ShortArray = buffer.getS16Array(index * Short.SIZE_BYTES, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): ShortArray = getArray(index, ShortArray(size)) - fun setArray(index: Int, inp: ShortArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayInt16(index, inp, offset, size) + fun setArray(index: Int, inp: ShortArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * Short.SIZE_BYTES, inp, offset, size) fun slice(start: Int = 0, end: Int = this.size): Int16Buffer = Int16Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int16Buffer = slice(start, start + size) @@ -448,14 +490,14 @@ value class Uint8Buffer(override val buffer: Buffer) : TypedBuffer, BaseIntBuffe operator fun invoke(data: UByteArray) = Uint8Buffer(UByteArrayInt(data.toByteArray())) } constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) - constructor(data: UByteArrayInt, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size).also { it.setArrayUInt8(0, data, offset, size) }) + constructor(data: UByteArrayInt, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size).also { it.setArray(0, data.data, offset, size) }) override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES override operator fun get(index: Int): Int = buffer.getU8(index) override operator fun set(index: Int, value: Int) = buffer.set8(index, value.toByte()) - fun getArray(index: Int, out: UByteArrayInt, offset: Int = 0, size: Int = out.size - offset): UByteArrayInt = buffer.getArrayUInt8(index, out, offset, size) + fun getArray(index: Int, out: UByteArrayInt, offset: Int = 0, size: Int = out.size - offset): UByteArrayInt = UByteArrayInt(buffer.getS8Array(index * ELEMENT_SIZE_IN_BYTES, out.data, offset, size)) fun getArray(index: Int = 0, size: Int = this.size - index): UByteArrayInt = getArray(index, UByteArrayInt(size)) - fun setArray(index: Int, inp: UByteArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayUInt8(index, inp, offset, size) + fun setArray(index: Int, inp: UByteArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp.data, offset, size) fun slice(start: Int = 0, end: Int = this.size): Uint8Buffer = Uint8Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint8Buffer = slice(start, start + size) @@ -468,7 +510,7 @@ value class Uint8ClampedBuffer(override val buffer: Buffer) : TypedBuffer, BaseI operator fun invoke(data: ByteArray) = Uint8ClampedBuffer(UByteArrayInt(data)) } constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) - constructor(data: UByteArrayInt, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size).also { it.setArrayUInt8(0, data, offset, size) }) + constructor(data: UByteArrayInt, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size).also { it.setArray(0, data.data, offset, size) }) override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES override operator fun get(index: Int): Int = buffer.getU8(index) @@ -485,14 +527,14 @@ value class Uint16Buffer(override val buffer: Buffer) : TypedBuffer, BaseIntBuff operator fun invoke(data: ByteArray) = Uint8ClampedBuffer(UByteArrayInt(data)) } constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) - constructor(data: UShortArrayInt, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayUInt16(0, data, offset, size) }) + constructor(data: UShortArrayInt, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArray(0, data.data, offset, size) }) override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES - override operator fun get(index: Int): Int = buffer.getU16LE(index * ELEMENT_SIZE_IN_BYTES) - override operator fun set(index: Int, value: Int) = buffer.set16LE(index * ELEMENT_SIZE_IN_BYTES, value.toShort()) - fun getArray(index: Int, out: UShortArrayInt, offset: Int = 0, size: Int = out.size - offset): UShortArrayInt = buffer.getArrayUInt16(index, out, offset, size) + override operator fun get(index: Int): Int = buffer.getU16(index * ELEMENT_SIZE_IN_BYTES) + override operator fun set(index: Int, value: Int) = buffer.set16(index * ELEMENT_SIZE_IN_BYTES, value.toShort()) + fun getArray(index: Int, out: UShortArrayInt, offset: Int = 0, size: Int = out.size - offset): UShortArrayInt = UShortArrayInt(buffer.getS16Array(index * ELEMENT_SIZE_IN_BYTES, out.data, offset, size)) fun getArray(index: Int = 0, size: Int = this.size - index): UShortArrayInt = getArray(index, UShortArrayInt(size)) - fun setArray(index: Int, inp: UShortArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayUInt16(index, inp, offset, size) + fun setArray(index: Int, inp: UShortArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp.data, offset, size) fun slice(start: Int = 0, end: Int = this.size): Uint16Buffer = Uint16Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint16Buffer = slice(start, start + size) @@ -504,14 +546,14 @@ value class Int32Buffer(override val buffer: Buffer) : TypedBuffer, BaseIntBuffe const val ELEMENT_SIZE_IN_BYTES = 4 } constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) - constructor(data: IntArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayInt32(0, data, offset, size) }) + constructor(data: IntArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArray(0, data, offset, size) }) override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES - override operator fun get(index: Int): Int = buffer.getS32LE(index * ELEMENT_SIZE_IN_BYTES) - override operator fun set(index: Int, value: Int) = buffer.set32LE(index * ELEMENT_SIZE_IN_BYTES, value) - fun getArray(index: Int, out: IntArray, offset: Int = 0, size: Int = out.size - offset): IntArray = buffer.getArrayInt32(index, out, offset, size) + override operator fun get(index: Int): Int = buffer.getS32(index * ELEMENT_SIZE_IN_BYTES) + override operator fun set(index: Int, value: Int) = buffer.set32(index * ELEMENT_SIZE_IN_BYTES, value) + fun getArray(index: Int, out: IntArray, offset: Int = 0, size: Int = out.size - offset): IntArray = buffer.getS32Array(index * ELEMENT_SIZE_IN_BYTES, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): IntArray = getArray(index, IntArray(size)) - fun setArray(index: Int, inp: IntArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayInt32(index, inp, offset, size) + fun setArray(index: Int, inp: IntArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp, offset, size) fun slice(start: Int = 0, end: Int = this.size): Int32Buffer = Int32Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int32Buffer = slice(start, start + size) @@ -523,15 +565,15 @@ value class Uint32Buffer(override val buffer: Buffer) : TypedBuffer { const val ELEMENT_SIZE_IN_BYTES = 4 } constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) - constructor(data: UIntArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayInt32(0, data.toIntArray(), offset, size) }) + constructor(data: UIntArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArray(0, data.toIntArray(), offset, size) }) override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES - operator fun get(index: Int): UInt = buffer.getS32LE(index * ELEMENT_SIZE_IN_BYTES).toUInt() - operator fun set(index: Int, value: UInt) = buffer.set32LE(index * ELEMENT_SIZE_IN_BYTES, value.toInt()) - operator fun set(index: Int, value: Int) = buffer.set32LE(index * ELEMENT_SIZE_IN_BYTES, value) - fun getArray(index: Int, out: UIntArray, offset: Int = 0, size: Int = out.size - offset): UIntArray = buffer.getArrayInt32(index, out.asIntArray(), offset, size).asUIntArray() + operator fun get(index: Int): UInt = buffer.getS32(index * ELEMENT_SIZE_IN_BYTES).toUInt() + operator fun set(index: Int, value: UInt) = buffer.set32(index * ELEMENT_SIZE_IN_BYTES, value.toInt()) + operator fun set(index: Int, value: Int) = buffer.set32(index * ELEMENT_SIZE_IN_BYTES, value) + fun getArray(index: Int, out: UIntArray, offset: Int = 0, size: Int = out.size - offset): UIntArray = buffer.getS32Array(index * ELEMENT_SIZE_IN_BYTES, out.asIntArray(), offset, size).asUIntArray() fun getArray(index: Int = 0, size: Int = this.size - index): UIntArray = getArray(index, UIntArray(size)) - fun setArray(index: Int, inp: UIntArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayInt32(index, inp.asIntArray(), offset, size) + fun setArray(index: Int, inp: UIntArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp.asIntArray(), offset, size) fun slice(start: Int = 0, end: Int = this.size): Uint32Buffer = Uint32Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint32Buffer = slice(start, start + size) @@ -543,14 +585,14 @@ value class Int64Buffer(override val buffer: Buffer) : TypedBuffer { const val ELEMENT_SIZE_IN_BYTES = 8 } constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) - constructor(data: LongArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayInt64(0, data, offset, size) }) + constructor(data: LongArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArray(0, data, offset, size) }) override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES - operator fun get(index: Int): Long = buffer.getS64LE(index * ELEMENT_SIZE_IN_BYTES) - operator fun set(index: Int, value: Long) = buffer.set64LE(index * ELEMENT_SIZE_IN_BYTES, value) - fun getArray(index: Int, out: LongArray, offset: Int = 0, size: Int = out.size - offset): LongArray = buffer.getArrayInt64(index, out, offset, size) + operator fun get(index: Int): Long = buffer.getS64(index * ELEMENT_SIZE_IN_BYTES) + operator fun set(index: Int, value: Long) = buffer.set64(index * ELEMENT_SIZE_IN_BYTES, value) + fun getArray(index: Int, out: LongArray, offset: Int = 0, size: Int = out.size - offset): LongArray = buffer.getS64Array(index * ELEMENT_SIZE_IN_BYTES, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): LongArray = getArray(index, LongArray(size)) - fun setArray(index: Int, inp: LongArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayInt64(index, inp, offset, size) + fun setArray(index: Int, inp: LongArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp, offset, size) fun slice(start: Int = 0, end: Int = this.size): Int64Buffer = Int64Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int64Buffer = slice(start, start + size) @@ -562,14 +604,14 @@ value class Float32Buffer(override val buffer: Buffer) : TypedBuffer, BaseFloatB const val ELEMENT_SIZE_IN_BYTES = 4 } constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) - constructor(data: FloatArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayFloat32(0, data, offset, size) }) + constructor(data: FloatArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArray(0, data, offset, size) }) override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES - override operator fun get(index: Int): Float = buffer.getF32LE(index * ELEMENT_SIZE_IN_BYTES) - override operator fun set(index: Int, value: Float) = buffer.setF32LE(index * ELEMENT_SIZE_IN_BYTES, value) - fun getArray(index: Int, out: FloatArray, offset: Int = 0, size: Int = out.size - offset): FloatArray = buffer.getArrayFloat32(index, out, offset, size) + override operator fun get(index: Int): Float = buffer.getF32(index * ELEMENT_SIZE_IN_BYTES) + override operator fun set(index: Int, value: Float) = buffer.setF32(index * ELEMENT_SIZE_IN_BYTES, value) + fun getArray(index: Int, out: FloatArray, offset: Int = 0, size: Int = out.size - offset): FloatArray = buffer.getF32Array(index * ELEMENT_SIZE_IN_BYTES, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): FloatArray = getArray(index, FloatArray(size)) - fun setArray(index: Int, inp: FloatArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayFloat32(index, inp, offset, size) + fun setArray(index: Int, inp: FloatArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp, offset, size) fun slice(start: Int = 0, end: Int = this.size): Float32Buffer = Float32Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Float32Buffer = slice(start, start + size) @@ -581,14 +623,14 @@ value class Float64Buffer(override val buffer: Buffer) : TypedBuffer { const val ELEMENT_SIZE_IN_BYTES = 8 } constructor(size: Int, direct: Boolean = false) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES, direct)) - constructor(data: DoubleArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArrayFloat64(0, data, offset, size) }) + constructor(data: DoubleArray, offset: Int = 0, size: Int = data.size - offset) : this(Buffer(size * ELEMENT_SIZE_IN_BYTES).also { it.setArray(0, data, offset, size) }) override val elementSizeInBytes: Int get() = ELEMENT_SIZE_IN_BYTES - operator fun get(index: Int): Double = buffer.getF64LE(index * ELEMENT_SIZE_IN_BYTES) - operator fun set(index: Int, value: Double) = buffer.setF64LE(index * ELEMENT_SIZE_IN_BYTES, value) - fun getArray(index: Int, out: DoubleArray, offset: Int = 0, size: Int = out.size - offset): DoubleArray = buffer.getArrayFloat64(index, out, offset, size) + operator fun get(index: Int): Double = buffer.getF64(index * ELEMENT_SIZE_IN_BYTES) + operator fun set(index: Int, value: Double) = buffer.setF64(index * ELEMENT_SIZE_IN_BYTES, value) + fun getArray(index: Int, out: DoubleArray, offset: Int = 0, size: Int = out.size - offset): DoubleArray = buffer.getF64Array(index * ELEMENT_SIZE_IN_BYTES, out, offset, size) fun getArray(index: Int = 0, size: Int = this.size - index): DoubleArray = getArray(index, DoubleArray(size)) - fun setArray(index: Int, inp: DoubleArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArrayFloat64(index, inp, offset, size) + fun setArray(index: Int, inp: DoubleArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp, offset, size) fun slice(start: Int = 0, end: Int = this.size): Float64Buffer = Float64Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Float64Buffer = slice(start, start + size) diff --git a/korge-foundation/src/commonMain/kotlin/korlibs/memory/ByteArrayGetSet.kt b/korge-foundation/src/commonMain/kotlin/korlibs/memory/ByteArrayGetSet.kt index 6736bdca01..0756d78e34 100644 --- a/korge-foundation/src/commonMain/kotlin/korlibs/memory/ByteArrayGetSet.kt +++ b/korge-foundation/src/commonMain/kotlin/korlibs/memory/ByteArrayGetSet.kt @@ -46,41 +46,41 @@ public fun ByteArray.getF32BE(offset: Int): Float = Float.fromBits(get32BE(offse public fun ByteArray.getF64BE(offset: Int): Double = Double.fromBits(get64BE(offset)) // Custom Endian -public fun ByteArray.getU16(offset: Int, little: Boolean): Int = if (little) getU16LE(offset) else getU16BE(offset) -public fun ByteArray.getU24(offset: Int, little: Boolean): Int = if (little) getU24LE(offset) else getU24BE(offset) -public fun ByteArray.getU32(offset: Int, little: Boolean): Long = if (little) getU32LE(offset) else getU32BE(offset) -public fun ByteArray.getS16(offset: Int, little: Boolean): Int = if (little) getS16LE(offset) else getS16BE(offset) -public fun ByteArray.getS24(offset: Int, little: Boolean): Int = if (little) getS24LE(offset) else getS24BE(offset) -public fun ByteArray.getS32(offset: Int, little: Boolean): Int = if (little) getS32LE(offset) else getS32BE(offset) -public fun ByteArray.getS64(offset: Int, little: Boolean): Long = if (little) getS64LE(offset) else getS64BE(offset) -public fun ByteArray.getF16(offset: Int, little: Boolean): Half = if (little) getF16LE(offset) else getF16BE(offset) -public fun ByteArray.getF32(offset: Int, little: Boolean): Float = if (little) getF32LE(offset) else getF32BE(offset) -public fun ByteArray.getF64(offset: Int, little: Boolean): Double = if (little) getF64LE(offset) else getF64BE(offset) +public fun ByteArray.getU16(offset: Int, littleEndian: Boolean): Int = if (littleEndian) getU16LE(offset) else getU16BE(offset) +public fun ByteArray.getU24(offset: Int, littleEndian: Boolean): Int = if (littleEndian) getU24LE(offset) else getU24BE(offset) +public fun ByteArray.getU32(offset: Int, littleEndian: Boolean): Long = if (littleEndian) getU32LE(offset) else getU32BE(offset) +public fun ByteArray.getS16(offset: Int, littleEndian: Boolean): Int = if (littleEndian) getS16LE(offset) else getS16BE(offset) +public fun ByteArray.getS24(offset: Int, littleEndian: Boolean): Int = if (littleEndian) getS24LE(offset) else getS24BE(offset) +public fun ByteArray.getS32(offset: Int, littleEndian: Boolean): Int = if (littleEndian) getS32LE(offset) else getS32BE(offset) +public fun ByteArray.getS64(offset: Int, littleEndian: Boolean): Long = if (littleEndian) getS64LE(offset) else getS64BE(offset) +public fun ByteArray.getF16(offset: Int, littleEndian: Boolean): Half = if (littleEndian) getF16LE(offset) else getF16BE(offset) +public fun ByteArray.getF32(offset: Int, littleEndian: Boolean): Float = if (littleEndian) getF32LE(offset) else getF32BE(offset) +public fun ByteArray.getF64(offset: Int, littleEndian: Boolean): Double = if (littleEndian) getF64LE(offset) else getF64BE(offset) private inline fun ByteArray.getTypedArray(offset: Int, count: Int, elementSize: Int, array: T, crossinline get: ByteArray.(array: T, n: Int, pos: Int) -> Unit): T = array.also { for (n in 0 until count) get(this, array, n, offset + n * elementSize) } public fun ByteArray.getS8Array(offset: Int, count: Int): ByteArray = this.copyOfRange(offset, offset + count) -public fun ByteArray.getS16LEArray(offset: Int, count: Int): ShortArray = this.getTypedArray(offset, count, 2, ShortArray(count)) { array, n, pos -> array[n] = getS16LE(pos).toShort() } -public fun ByteArray.getU16LEArray(offset: Int, count: Int): CharArray = this.getTypedArray(offset, count, 2, kotlin.CharArray(count)) { array, n, pos -> array[n] = getS16LE(pos).toChar() } -public fun ByteArray.getS32LEArray(offset: Int, count: Int): IntArray = this.getTypedArray(offset, count, 4, IntArray(count)) { array, n, pos -> array[n] = getS32LE(pos) } -public fun ByteArray.getS64LEArray(offset: Int, count: Int): LongArray = this.getTypedArray(offset, count, 8, LongArray(count)) { array, n, pos -> array[n] = getS64LE(pos) } -public fun ByteArray.getF32LEArray(offset: Int, count: Int): FloatArray = this.getTypedArray(offset, count, 4, FloatArray(count)) { array, n, pos -> array[n] = getF32LE(pos) } -public fun ByteArray.getF64LEArray(offset: Int, count: Int): DoubleArray = this.getTypedArray(offset, count, 8, DoubleArray(count)) { array, n, pos -> array[n] = getF64LE(pos) } -public fun ByteArray.getS16BEArray(offset: Int, count: Int): ShortArray = this.getTypedArray(offset, count, 2, ShortArray(count)) { array, n, pos -> array[n] = getS16BE(pos).toShort() } -public fun ByteArray.getU16BEArray(offset: Int, count: Int): CharArray = this.getTypedArray(offset, count, 2, kotlin.CharArray(count)) { array, n, pos -> array[n] = getS16BE(pos).toChar() } -public fun ByteArray.getS32BEArray(offset: Int, count: Int): IntArray = this.getTypedArray(offset, count, 4, IntArray(count)) { array, n, pos -> array[n] = getS32BE(pos) } -public fun ByteArray.getS64BEArray(offset: Int, count: Int): LongArray = this.getTypedArray(offset, count, 8, LongArray(count)) { array, n, pos -> array[n] = getS64BE(pos) } -public fun ByteArray.getF32BEArray(offset: Int, count: Int): FloatArray = this.getTypedArray(offset, count, 4, FloatArray(count)) { array, n, pos -> array[n] = getF32BE(pos) } -public fun ByteArray.getF64BEArray(offset: Int, count: Int): DoubleArray = this.getTypedArray(offset, count, 8, DoubleArray(count)) { array, n, pos -> array[n] = getF64BE(pos) } - -public fun ByteArray.getS16Array(offset: Int, count: Int, little: Boolean): ShortArray = if (little) getS16LEArray(offset, count) else getS16BEArray(offset, count) -public fun ByteArray.getU16Array(offset: Int, count: Int, little: Boolean): CharArray = if (little) getU16LEArray(offset, count) else getU16BEArray(offset, count) -public fun ByteArray.getS32Array(offset: Int, count: Int, little: Boolean): IntArray = if (little) getS32LEArray(offset, count) else getS32BEArray(offset, count) -public fun ByteArray.getS64Array(offset: Int, count: Int, little: Boolean): LongArray = if (little) getS64LEArray(offset, count) else getS64BEArray(offset, count) -public fun ByteArray.getF32Array(offset: Int, count: Int, little: Boolean): FloatArray = if (little) getF32LEArray(offset, count) else getF32BEArray(offset, count) -public fun ByteArray.getF64Array(offset: Int, count: Int, little: Boolean): DoubleArray = if (little) getF64LEArray(offset, count) else getF64BEArray(offset, count) +public fun ByteArray.getS16ArrayLE(offset: Int, count: Int): ShortArray = this.getTypedArray(offset, count, 2, ShortArray(count)) { array, n, pos -> array[n] = getS16LE(pos).toShort() } +public fun ByteArray.getU16ArrayLE(offset: Int, count: Int): CharArray = this.getTypedArray(offset, count, 2, kotlin.CharArray(count)) { array, n, pos -> array[n] = getS16LE(pos).toChar() } +public fun ByteArray.getS32ArrayLE(offset: Int, count: Int): IntArray = this.getTypedArray(offset, count, 4, IntArray(count)) { array, n, pos -> array[n] = getS32LE(pos) } +public fun ByteArray.getS64ArrayLE(offset: Int, count: Int): LongArray = this.getTypedArray(offset, count, 8, LongArray(count)) { array, n, pos -> array[n] = getS64LE(pos) } +public fun ByteArray.getF32ArrayLE(offset: Int, count: Int): FloatArray = this.getTypedArray(offset, count, 4, FloatArray(count)) { array, n, pos -> array[n] = getF32LE(pos) } +public fun ByteArray.getF64ArrayLE(offset: Int, count: Int): DoubleArray = this.getTypedArray(offset, count, 8, DoubleArray(count)) { array, n, pos -> array[n] = getF64LE(pos) } +public fun ByteArray.getS16ArrayBE(offset: Int, count: Int): ShortArray = this.getTypedArray(offset, count, 2, ShortArray(count)) { array, n, pos -> array[n] = getS16BE(pos).toShort() } +public fun ByteArray.getU16ArrayBE(offset: Int, count: Int): CharArray = this.getTypedArray(offset, count, 2, kotlin.CharArray(count)) { array, n, pos -> array[n] = getS16BE(pos).toChar() } +public fun ByteArray.getS32ArrayBE(offset: Int, count: Int): IntArray = this.getTypedArray(offset, count, 4, IntArray(count)) { array, n, pos -> array[n] = getS32BE(pos) } +public fun ByteArray.getS64ArrayBE(offset: Int, count: Int): LongArray = this.getTypedArray(offset, count, 8, LongArray(count)) { array, n, pos -> array[n] = getS64BE(pos) } +public fun ByteArray.getF32ArrayBE(offset: Int, count: Int): FloatArray = this.getTypedArray(offset, count, 4, FloatArray(count)) { array, n, pos -> array[n] = getF32BE(pos) } +public fun ByteArray.getF64ArrayBE(offset: Int, count: Int): DoubleArray = this.getTypedArray(offset, count, 8, DoubleArray(count)) { array, n, pos -> array[n] = getF64BE(pos) } + +public fun ByteArray.getS16Array(offset: Int, count: Int, littleEndian: Boolean): ShortArray = if (littleEndian) getS16ArrayLE(offset, count) else getS16ArrayBE(offset, count) +public fun ByteArray.getU16Array(offset: Int, count: Int, littleEndian: Boolean): CharArray = if (littleEndian) getU16ArrayLE(offset, count) else getU16ArrayBE(offset, count) +public fun ByteArray.getS32Array(offset: Int, count: Int, littleEndian: Boolean): IntArray = if (littleEndian) getS32ArrayLE(offset, count) else getS32ArrayBE(offset, count) +public fun ByteArray.getS64Array(offset: Int, count: Int, littleEndian: Boolean): LongArray = if (littleEndian) getS64ArrayLE(offset, count) else getS64ArrayBE(offset, count) +public fun ByteArray.getF32Array(offset: Int, count: Int, littleEndian: Boolean): FloatArray = if (littleEndian) getF32ArrayLE(offset, count) else getF32ArrayBE(offset, count) +public fun ByteArray.getF64Array(offset: Int, count: Int, littleEndian: Boolean): DoubleArray = if (littleEndian) getF64ArrayLE(offset, count) else getF64ArrayBE(offset, count) ///////////////////////////////////////// ///////////////////////////////////////// @@ -88,13 +88,13 @@ public fun ByteArray.getF64Array(offset: Int, count: Int, little: Boolean): Doub public fun ByteArray.set8(offset: Int, value: Int) { this[offset] = value.toByte() } public fun ByteArray.set8(offset: Int, value: Long) { this[offset] = value.toByte() } -public fun ByteArray.set16(offset: Int, value: Int, little: Boolean) { if (little) set16LE(offset, value) else set16BE(offset, value) } -public fun ByteArray.set24(offset: Int, value: Int, little: Boolean) { if (little) set24LE(offset, value) else set24BE(offset, value) } -public fun ByteArray.set32(offset: Int, value: Int, little: Boolean) { if (little) set32LE(offset, value) else set32BE(offset, value) } -public fun ByteArray.set64(offset: Int, value: Long, little: Boolean) { if (little) set64LE(offset, value) else set64BE(offset, value) } -public fun ByteArray.setF16(offset: Int, value: Half, little: Boolean) { if (little) setF16LE(offset, value) else setF16BE(offset, value) } -public fun ByteArray.setF32(offset: Int, value: Float, little: Boolean) { if (little) setF32LE(offset, value) else setF32BE(offset, value) } -public fun ByteArray.setF64(offset: Int, value: Double, little: Boolean) { if (little) setF64LE(offset, value) else setF64BE(offset, value) } +public fun ByteArray.set16(offset: Int, value: Int, littleEndian: Boolean) { if (littleEndian) set16LE(offset, value) else set16BE(offset, value) } +public fun ByteArray.set24(offset: Int, value: Int, littleEndian: Boolean) { if (littleEndian) set24LE(offset, value) else set24BE(offset, value) } +public fun ByteArray.set32(offset: Int, value: Int, littleEndian: Boolean) { if (littleEndian) set32LE(offset, value) else set32BE(offset, value) } +public fun ByteArray.set64(offset: Int, value: Long, littleEndian: Boolean) { if (littleEndian) set64LE(offset, value) else set64BE(offset, value) } +public fun ByteArray.setF16(offset: Int, value: Half, littleEndian: Boolean) { if (littleEndian) setF16LE(offset, value) else setF16BE(offset, value) } +public fun ByteArray.setF32(offset: Int, value: Float, littleEndian: Boolean) { if (littleEndian) setF32LE(offset, value) else setF32BE(offset, value) } +public fun ByteArray.setF64(offset: Int, value: Double, littleEndian: Boolean) { if (littleEndian) setF64LE(offset, value) else setF64BE(offset, value) } public fun ByteArray.set16LE(offset: Int, value: Int) { this[offset + 0] = value.extractByte(0); this[offset + 1] = value.extractByte(8) } public fun ByteArray.set24LE(offset: Int, value: Int) { this[offset + 0] = value.extractByte(0); this[offset + 1] = value.extractByte(8); this[offset + 2] = value.extractByte(16) } @@ -118,6 +118,7 @@ public fun ByteArray.setBytes(offset: Int, bytes: ByteArray): Unit = arraycopy(b private inline fun wa(offset: Int, elementSize: Int, size: Int, set: (p: Int, n: Int) -> Unit) { for (n in 0 until size) set(offset + n * elementSize, n) } +public fun ByteArray.setArray(offset: Int, bytes: ByteArray): Unit = arraycopy(bytes, 0, this, offset, bytes.size) public fun ByteArray.setArrayLE(offset: Int, array: CharArray): Unit = wa(offset, 2, array.size) { p, n -> set16LE(p, array[n].toInt()) } public fun ByteArray.setArrayLE(offset: Int, array: ShortArray): Unit = wa(offset, 2, array.size) { p, n -> set16LE(p, array[n].toInt()) } public fun ByteArray.setArrayLE(offset: Int, array: IntArray): Unit = wa(offset, 4, array.size) { p, n -> set32LE(p, array[n]) } diff --git a/korge-foundation/src/commonMain/kotlin/korlibs/memory/ByteArrayReadWriteOld.kt b/korge-foundation/src/commonMain/kotlin/korlibs/memory/ByteArrayReadWriteOld.kt index 33360e260f..20ad95f87e 100644 --- a/korge-foundation/src/commonMain/kotlin/korlibs/memory/ByteArrayReadWriteOld.kt +++ b/korge-foundation/src/commonMain/kotlin/korlibs/memory/ByteArrayReadWriteOld.kt @@ -45,18 +45,18 @@ import korlibs.number.* @Deprecated("", ReplaceWith("getF64(o, little)")) public fun ByteArray.readF64(o: Int, little: Boolean): Double = getF64(o, little) @Deprecated("", ReplaceWith("getS8Array(o, count)")) public fun ByteArray.readByteArray(o: Int, count: Int): ByteArray = getS8Array(o, count) -@Deprecated("", ReplaceWith("getS16LEArray(o, count)")) public fun ByteArray.readShortArrayLE(o: Int, count: Int): ShortArray = getS16LEArray(o, count) -@Deprecated("", ReplaceWith("getU16LEArray(o, count)")) public fun ByteArray.readCharArrayLE(o: Int, count: Int): CharArray = getU16LEArray(o, count) -@Deprecated("", ReplaceWith("getS32LEArray(o, count)")) public fun ByteArray.readIntArrayLE(o: Int, count: Int): IntArray = getS32LEArray(o, count) -@Deprecated("", ReplaceWith("getS64LEArray(o, count)")) public fun ByteArray.readLongArrayLE(o: Int, count: Int): LongArray = getS64LEArray(o, count) -@Deprecated("", ReplaceWith("getF32LEArray(o, count)")) public fun ByteArray.readFloatArrayLE(o: Int, count: Int): FloatArray = getF32LEArray(o, count) -@Deprecated("", ReplaceWith("getF64LEArray(o, count)")) public fun ByteArray.readDoubleArrayLE(o: Int, count: Int): DoubleArray = getF64LEArray(o, count) -@Deprecated("", ReplaceWith("getS16BEArray(o, count)")) public fun ByteArray.readShortArrayBE(o: Int, count: Int): ShortArray = getS16BEArray(o, count) -@Deprecated("", ReplaceWith("getU16BEArray(o, count)")) public fun ByteArray.readCharArrayBE(o: Int, count: Int): CharArray = getU16BEArray(o, count) -@Deprecated("", ReplaceWith("getS32BEArray(o, count)")) public fun ByteArray.readIntArrayBE(o: Int, count: Int): IntArray = getS32BEArray(o, count) -@Deprecated("", ReplaceWith("getS64BEArray(o, count)")) public fun ByteArray.readLongArrayBE(o: Int, count: Int): LongArray = getS64BEArray(o, count) -@Deprecated("", ReplaceWith("getF32BEArray(o, count)")) public fun ByteArray.readFloatArrayBE(o: Int, count: Int): FloatArray = getF32BEArray(o, count) -@Deprecated("", ReplaceWith("getF64BEArray(o, count)")) public fun ByteArray.readDoubleArrayBE(o: Int, count: Int): DoubleArray = getF64BEArray(o, count) +@Deprecated("", ReplaceWith("getS16LEArray(o, count)")) public fun ByteArray.readShortArrayLE(o: Int, count: Int): ShortArray = getS16ArrayLE(o, count) +@Deprecated("", ReplaceWith("getU16LEArray(o, count)")) public fun ByteArray.readCharArrayLE(o: Int, count: Int): CharArray = getU16ArrayLE(o, count) +@Deprecated("", ReplaceWith("getS32LEArray(o, count)")) public fun ByteArray.readIntArrayLE(o: Int, count: Int): IntArray = getS32ArrayLE(o, count) +@Deprecated("", ReplaceWith("getS64LEArray(o, count)")) public fun ByteArray.readLongArrayLE(o: Int, count: Int): LongArray = getS64ArrayLE(o, count) +@Deprecated("", ReplaceWith("getF32LEArray(o, count)")) public fun ByteArray.readFloatArrayLE(o: Int, count: Int): FloatArray = getF32ArrayLE(o, count) +@Deprecated("", ReplaceWith("getF64LEArray(o, count)")) public fun ByteArray.readDoubleArrayLE(o: Int, count: Int): DoubleArray = getF64ArrayLE(o, count) +@Deprecated("", ReplaceWith("getS16BEArray(o, count)")) public fun ByteArray.readShortArrayBE(o: Int, count: Int): ShortArray = getS16ArrayBE(o, count) +@Deprecated("", ReplaceWith("getU16BEArray(o, count)")) public fun ByteArray.readCharArrayBE(o: Int, count: Int): CharArray = getU16ArrayBE(o, count) +@Deprecated("", ReplaceWith("getS32BEArray(o, count)")) public fun ByteArray.readIntArrayBE(o: Int, count: Int): IntArray = getS32ArrayBE(o, count) +@Deprecated("", ReplaceWith("getS64BEArray(o, count)")) public fun ByteArray.readLongArrayBE(o: Int, count: Int): LongArray = getS64ArrayBE(o, count) +@Deprecated("", ReplaceWith("getF32BEArray(o, count)")) public fun ByteArray.readFloatArrayBE(o: Int, count: Int): FloatArray = getF32ArrayBE(o, count) +@Deprecated("", ReplaceWith("getF64BEArray(o, count)")) public fun ByteArray.readDoubleArrayBE(o: Int, count: Int): DoubleArray = getF64ArrayBE(o, count) @Deprecated("", ReplaceWith("getS16Array(o, count, little)")) public fun ByteArray.readShortArray(o: Int, count: Int, little: Boolean): ShortArray = getS16Array(o, count, little) @Deprecated("", ReplaceWith("getU16Array(o, count, little)")) public fun ByteArray.readCharArray(o: Int, count: Int, little: Boolean): CharArray = getU16Array(o, count, little) diff --git a/korge-foundation/src/commonTest/kotlin/korlibs/memory/ByteArrayReadWriteTest.kt b/korge-foundation/src/commonTest/kotlin/korlibs/memory/ByteArrayReadWriteTest.kt index 5bb645b755..6272fc080d 100644 --- a/korge-foundation/src/commonTest/kotlin/korlibs/memory/ByteArrayReadWriteTest.kt +++ b/korge-foundation/src/commonTest/kotlin/korlibs/memory/ByteArrayReadWriteTest.kt @@ -10,16 +10,16 @@ class ByteArrayReadWriteTest { assertEquals(-2, byteArrayOf(-1, -2, -3).getS8(1)) assertEquals(0x9145, byteArrayOf(-1, 0x45, 0x91).getU16LE(1)) - assertEquals(0x9145, byteArrayOf(-1, 0x45, 0x91).getU16(1, little = true)) + assertEquals(0x9145, byteArrayOf(-1, 0x45, 0x91).getU16(1, littleEndian = true)) assertEquals(0x9145, byteArrayOf(-1, 0x91, 0x45).getU16BE(1)) - assertEquals(0x9145, byteArrayOf(-1, 0x91, 0x45).getU16(1, little = false)) + assertEquals(0x9145, byteArrayOf(-1, 0x91, 0x45).getU16(1, littleEndian = false)) assertEquals(0x914533, byteArrayOf(-1, 0x33, 0x45, 0x91).getU24LE(1)) - assertEquals(0x914533, byteArrayOf(-1, 0x33, 0x45, 0x91).getU24(1, little = true)) + assertEquals(0x914533, byteArrayOf(-1, 0x33, 0x45, 0x91).getU24(1, littleEndian = true)) assertEquals(0x914533, byteArrayOf(-1, 0x91, 0x45, 0x33).getU24BE(1)) - assertEquals(0x914533, byteArrayOf(-1, 0x91, 0x45, 0x33).getU24(1, little = false)) + assertEquals(0x914533, byteArrayOf(-1, 0x91, 0x45, 0x33).getU24(1, littleEndian = false)) } @Test diff --git a/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/Buffer.jvm.kt b/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/Buffer.jvm.kt index 7a42ba55f1..c2300097f9 100644 --- a/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/Buffer.jvm.kt +++ b/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/Buffer.jvm.kt @@ -83,7 +83,6 @@ actual class Buffer(val buffer: ByteBuffer) { //} dst.slicedBuffer(dstPosBytes, sizeInBytes).put(src.slicedBuffer(srcPosBytes, sizeInBytes)) } - } } From 00ebf0a02494d147e0fab74e6f961bacbd39dbbd Mon Sep 17 00:00:00 2001 From: soywiz Date: Wed, 27 Sep 2023 04:20:12 +0200 Subject: [PATCH 5/7] Removed TypedArrays.native --- .../korlibs/memory/TypedArrays.native.kt | 100 ------------------ 1 file changed, 100 deletions(-) delete mode 100644 korge-foundation/src/nativeMain/kotlin/korlibs/memory/TypedArrays.native.kt diff --git a/korge-foundation/src/nativeMain/kotlin/korlibs/memory/TypedArrays.native.kt b/korge-foundation/src/nativeMain/kotlin/korlibs/memory/TypedArrays.native.kt deleted file mode 100644 index 06e9625d91..0000000000 --- a/korge-foundation/src/nativeMain/kotlin/korlibs/memory/TypedArrays.native.kt +++ /dev/null @@ -1,100 +0,0 @@ -@file:Suppress("PackageDirectoryMismatch") - -package korlibs.memory.arrays - -import korlibs.math.* -import korlibs.memory.* - -actual interface BufferDataSource - -actual class ArrayBuffer(val data: ByteArray) : BufferDataSource { - actual constructor(length: Int) : this(ByteArray(length)) - actual val byteLength: Int get() = data.size -} - -actual interface ArrayBufferView : BufferDataSource { - actual val buffer: ArrayBuffer - actual val byteOffset: Int - actual val byteLength: Int -} - -val ArrayBufferView.data: ByteArray get() = buffer.data - -actual fun ArrayBufferDirect(size: Int): ArrayBuffer = ArrayBuffer(size) -actual fun ArrayBufferWrap(data: ByteArray): ArrayBuffer = ArrayBuffer(data) -internal actual fun ArrayBuffer_copy(src: ArrayBuffer, srcPos: Int, dst: ArrayBuffer, dstPos: Int, length: Int) { - arraycopy(src.data, srcPos, dst.data, dstPos, length) -} - -actual inline fun ArrayBuffer.uint8ClampedArray(byteOffset: Int, length: Int): Uint8ClampedArray = Uint8ClampedArray(this, byteOffset, length) -actual inline fun ArrayBuffer.uint8Array(byteOffset: Int, length: Int): Uint8Array = Uint8Array(this, byteOffset, length) -actual inline fun ArrayBuffer.uint16Array(byteOffset: Int, length: Int): Uint16Array = Uint16Array(this, byteOffset, length) -actual inline fun ArrayBuffer.int8Array(byteOffset: Int, length: Int): Int8Array = Int8Array(this, byteOffset, length) -actual inline fun ArrayBuffer.int16Array(byteOffset: Int, length: Int): Int16Array = Int16Array(this, byteOffset, length) -actual inline fun ArrayBuffer.int32Array(byteOffset: Int, length: Int): Int32Array = Int32Array(this, byteOffset, length) -actual inline fun ArrayBuffer.float32Array(byteOffset: Int, length: Int): Float32Array = Float32Array(this, byteOffset, length) -actual inline fun ArrayBuffer.float64Array(byteOffset: Int, length: Int): Float64Array = Float64Array(this, byteOffset, length) -actual inline fun ArrayBuffer.dataView(byteOffset: Int, length: Int): DataView = DataView(this, byteOffset, length) - -actual class Int8Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 1 - actual constructor(length: Int) : this(ArrayBuffer(length), 0, length) -} -actual class Int16Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 2 - actual constructor(length: Int) : this(ArrayBuffer(length * 2), 0, length) -} -actual class Int32Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 4 - actual constructor(length: Int) : this(ArrayBuffer(length * 4), 0, length) -} -actual class Float32Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 4 - actual constructor(length: Int) : this(ArrayBuffer(length * 4), 0, length) -} -actual class Float64Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 8 - actual constructor(length: Int) : this(ArrayBuffer(length * 8), 0, length) -} -actual class Uint8ClampedArray(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 1 - actual constructor(length: Int) : this(ArrayBuffer(length * 1), 0, length) -} -actual class Uint8Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 1 - actual constructor(length: Int) : this(ArrayBuffer(length * 1), 0, length) -} -actual class Uint16Array(override val buffer: ArrayBuffer, override val byteOffset: Int, actual val length: Int) : ArrayBufferView { - override val byteLength: Int get() = length * 2 - actual constructor(length: Int) : this(ArrayBuffer(length * 2), 0, length) -} -actual class DataView(override val buffer: ArrayBuffer, override val byteOffset: Int, override val byteLength: Int) : ArrayBufferView - -actual fun DataView.getInt8(byteOffset: Int): Byte = data.getS8(byteOffset(byteOffset, 1)).toByte() -actual fun DataView.getInt16(byteOffset: Int, littleEndian: Boolean): Short = data.getS16(byteOffset(byteOffset, 2), littleEndian).toShort() -actual fun DataView.getInt32(byteOffset: Int, littleEndian: Boolean): Int = data.getS32(byteOffset(byteOffset, 4), littleEndian) -actual fun DataView.getFloat32(byteOffset: Int, littleEndian: Boolean): Float = data.getF32(byteOffset(byteOffset, 4), littleEndian) -actual fun DataView.getFloat64(byteOffset: Int, littleEndian: Boolean): Double = data.getF64(byteOffset(byteOffset, 8), littleEndian) -actual fun DataView.setInt8(byteOffset: Int, value: Byte) { data.set8(byteOffset(byteOffset, 1), value.toInt()) } -actual fun DataView.setInt16(byteOffset: Int, value: Short, littleEndian: Boolean) { data.set16(byteOffset(byteOffset, 2), value.toInt(), littleEndian) } -actual fun DataView.setInt32(byteOffset: Int, value: Int, littleEndian: Boolean) { data.set32(byteOffset(byteOffset, 4), value, littleEndian) } -actual fun DataView.setFloat32(byteOffset: Int, value: Float, littleEndian: Boolean) { data.setF32(byteOffset(byteOffset, 4), value, littleEndian) } -actual fun DataView.setFloat64(byteOffset: Int, value: Double, littleEndian: Boolean) { data.setF64(byteOffset(byteOffset, 8), value, littleEndian) } - -actual operator fun Int8Array.get(index: Int): Byte = data[byteOffset(index)] -actual operator fun Int16Array.get(index: Int): Short = data.getS16LE(byteOffset(index)).toShort() -actual operator fun Int32Array.get(index: Int): Int = data.getS32LE(byteOffset(index)) -actual operator fun Float32Array.get(index: Int): Float = data.getF32LE(byteOffset(index)) -actual operator fun Float64Array.get(index: Int): Double = data.getF64LE(byteOffset(index)) -actual operator fun Uint8ClampedArray.get(index: Int): Int = data[byteOffset(index)].toInt() and 0xFF -actual operator fun Uint8Array.get(index: Int): Int = data[byteOffset(index)].toInt() and 0xFF -actual operator fun Uint16Array.get(index: Int): Int = data.getS16LE(byteOffset(index)) and 0xFFFF - -actual operator fun Int8Array.set(index: Int, value: Byte) { data[byteOffset(index)] = value } -actual operator fun Int16Array.set(index: Int, value: Short) { data.set16LE(byteOffset(index), value.toInt()) } -actual operator fun Int32Array.set(index: Int, value: Int) { data.set32LE(byteOffset(index), value) } -actual operator fun Float32Array.set(index: Int, value: Float) { data.setF32LE(byteOffset(index), value) } -actual operator fun Float64Array.set(index: Int, value: Double) { data.setF64LE(byteOffset(index), value) } -actual operator fun Uint8ClampedArray.set(index: Int, value: Int) { data.set(byteOffset(index), value.clamp(0, 255).toByte()) } -actual operator fun Uint8Array.set(index: Int, value: Int) { data.set(byteOffset(index), value.toByte()) } -actual operator fun Uint16Array.set(index: Int, value: Int) { data.set16LE(byteOffset(index), value) } From 4769f2d19715d82a13bfa41799859dffe28baa4a Mon Sep 17 00:00:00 2001 From: soywiz Date: Wed, 27 Sep 2023 04:21:06 +0200 Subject: [PATCH 6/7] Try to fix JVM target --- .../kotlin/korlibs/memory/Buffer.kt | 24 +++++++++---------- .../kotlin/korlibs/memory/NBufferTest.kt | 10 ++++---- .../kotlin/korlibs/memory/Buffer.jvm.kt | 12 +++++----- .../kotlin/korlibs/graphics/gl/AGOpengl.kt | 2 +- .../korlibs/graphics/AGUniformBlockTest.kt | 2 +- .../kotlin/korlibs/kgl/KmlGlJsCanvas.kt | 4 ++-- .../korlibs/render/platform/NativeKgl.kt | 6 ++--- .../kotlin/korlibs/kgl/KmlGlWasmCanvas.kt | 4 ++-- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt b/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt index f48ef434bf..337a0f4fef 100644 --- a/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt +++ b/korge-foundation/src/commonMain/kotlin/korlibs/memory/Buffer.kt @@ -165,8 +165,8 @@ fun Buffer.hex(): String = buildString(sizeInBytes * 2) { append(value.extract4(0).hexChar()) } } -fun Buffer.sliceWithSize(start: Int, size: Int): Buffer = _slice(start, start + size) -fun Buffer._slice(start: Int = 0, end: Int = sizeInBytes): Buffer { +fun Buffer.sliceWithSize(start: Int, size: Int): Buffer = sliceBuffer(start, start + size) +fun Buffer.sliceBuffer(start: Int = 0, end: Int = sizeInBytes): Buffer { if (start > end || start !in 0 .. sizeInBytes || end !in 0 .. sizeInBytes) { throw IllegalArgumentException("invalid slice start:$start, end:$end not in 0..$sizeInBytes") } @@ -459,7 +459,7 @@ value class Int8Buffer(override val buffer: Buffer) : TypedBuffer { fun getArray(index: Int = 0, size: Int = this.size - index): ByteArray = getArray(index, ByteArray(size)) fun setArray(index: Int, inp: ByteArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Int8Buffer = Int8Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun slice(start: Int = 0, end: Int = this.size): Int8Buffer = Int8Buffer(buffer.sliceBuffer(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int8Buffer = slice(start, start + size) } @@ -478,7 +478,7 @@ value class Int16Buffer(override val buffer: Buffer) : TypedBuffer { fun getArray(index: Int = 0, size: Int = this.size - index): ShortArray = getArray(index, ShortArray(size)) fun setArray(index: Int, inp: ShortArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * Short.SIZE_BYTES, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Int16Buffer = Int16Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun slice(start: Int = 0, end: Int = this.size): Int16Buffer = Int16Buffer(buffer.sliceBuffer(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int16Buffer = slice(start, start + size) } @@ -499,7 +499,7 @@ value class Uint8Buffer(override val buffer: Buffer) : TypedBuffer, BaseIntBuffe fun getArray(index: Int = 0, size: Int = this.size - index): UByteArrayInt = getArray(index, UByteArrayInt(size)) fun setArray(index: Int, inp: UByteArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp.data, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Uint8Buffer = Uint8Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun slice(start: Int = 0, end: Int = this.size): Uint8Buffer = Uint8Buffer(buffer.sliceBuffer(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint8Buffer = slice(start, start + size) } @@ -516,7 +516,7 @@ value class Uint8ClampedBuffer(override val buffer: Buffer) : TypedBuffer, BaseI override operator fun get(index: Int): Int = buffer.getU8(index) override operator fun set(index: Int, value: Int) = buffer.set8Clamped(index, value) - fun slice(start: Int = 0, end: Int = this.size): Uint8ClampedBuffer = Uint8ClampedBuffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun slice(start: Int = 0, end: Int = this.size): Uint8ClampedBuffer = Uint8ClampedBuffer(buffer.sliceBuffer(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint8ClampedBuffer = slice(start, start + size) } @@ -536,7 +536,7 @@ value class Uint16Buffer(override val buffer: Buffer) : TypedBuffer, BaseIntBuff fun getArray(index: Int = 0, size: Int = this.size - index): UShortArrayInt = getArray(index, UShortArrayInt(size)) fun setArray(index: Int, inp: UShortArrayInt, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp.data, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Uint16Buffer = Uint16Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun slice(start: Int = 0, end: Int = this.size): Uint16Buffer = Uint16Buffer(buffer.sliceBuffer(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint16Buffer = slice(start, start + size) } @@ -555,7 +555,7 @@ value class Int32Buffer(override val buffer: Buffer) : TypedBuffer, BaseIntBuffe fun getArray(index: Int = 0, size: Int = this.size - index): IntArray = getArray(index, IntArray(size)) fun setArray(index: Int, inp: IntArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Int32Buffer = Int32Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun slice(start: Int = 0, end: Int = this.size): Int32Buffer = Int32Buffer(buffer.sliceBuffer(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int32Buffer = slice(start, start + size) } @@ -575,7 +575,7 @@ value class Uint32Buffer(override val buffer: Buffer) : TypedBuffer { fun getArray(index: Int = 0, size: Int = this.size - index): UIntArray = getArray(index, UIntArray(size)) fun setArray(index: Int, inp: UIntArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp.asIntArray(), offset, size) - fun slice(start: Int = 0, end: Int = this.size): Uint32Buffer = Uint32Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun slice(start: Int = 0, end: Int = this.size): Uint32Buffer = Uint32Buffer(buffer.sliceBuffer(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Uint32Buffer = slice(start, start + size) } @@ -594,7 +594,7 @@ value class Int64Buffer(override val buffer: Buffer) : TypedBuffer { fun getArray(index: Int = 0, size: Int = this.size - index): LongArray = getArray(index, LongArray(size)) fun setArray(index: Int, inp: LongArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Int64Buffer = Int64Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun slice(start: Int = 0, end: Int = this.size): Int64Buffer = Int64Buffer(buffer.sliceBuffer(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Int64Buffer = slice(start, start + size) } @@ -613,7 +613,7 @@ value class Float32Buffer(override val buffer: Buffer) : TypedBuffer, BaseFloatB fun getArray(index: Int = 0, size: Int = this.size - index): FloatArray = getArray(index, FloatArray(size)) fun setArray(index: Int, inp: FloatArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Float32Buffer = Float32Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun slice(start: Int = 0, end: Int = this.size): Float32Buffer = Float32Buffer(buffer.sliceBuffer(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Float32Buffer = slice(start, start + size) } @@ -632,7 +632,7 @@ value class Float64Buffer(override val buffer: Buffer) : TypedBuffer { fun getArray(index: Int = 0, size: Int = this.size - index): DoubleArray = getArray(index, DoubleArray(size)) fun setArray(index: Int, inp: DoubleArray, offset: Int = 0, size: Int = inp.size - offset): Unit = buffer.setArray(index * ELEMENT_SIZE_IN_BYTES, inp, offset, size) - fun slice(start: Int = 0, end: Int = this.size): Float64Buffer = Float64Buffer(buffer._slice(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) + fun slice(start: Int = 0, end: Int = this.size): Float64Buffer = Float64Buffer(buffer.sliceBuffer(start * ELEMENT_SIZE_IN_BYTES, end * ELEMENT_SIZE_IN_BYTES)) fun sliceWithSize(start: Int = 0, size: Int = this.size - start): Float64Buffer = slice(start, start + size) } diff --git a/korge-foundation/src/commonTest/kotlin/korlibs/memory/NBufferTest.kt b/korge-foundation/src/commonTest/kotlin/korlibs/memory/NBufferTest.kt index 31071e197e..b9b651aa67 100644 --- a/korge-foundation/src/commonTest/kotlin/korlibs/memory/NBufferTest.kt +++ b/korge-foundation/src/commonTest/kotlin/korlibs/memory/NBufferTest.kt @@ -428,7 +428,7 @@ open class NBufferTestBase { @Test fun testCopy() { val bufferBase = Buffer(ByteArray(16) { it.toByte() }) - val buffer = bufferBase._slice(1) + val buffer = bufferBase.sliceBuffer(1) val buffer2 = Buffer(14, direct) Buffer.copy(buffer, 2, buffer2, 5, 7) assertEquals("0000000000030405060708090000", buffer2.hex()) @@ -440,7 +440,7 @@ open class NBufferTestBase { for (direct2 in listOf(false, true)) { val bufferBase = Buffer(16, direct1) for (n in 0 until 16) bufferBase.setUnalignedUInt8(n, n) - val buffer = bufferBase._slice(1) + val buffer = bufferBase.sliceBuffer(1) val buffer2 = Buffer(14, direct2) Buffer.copy(buffer, 2, buffer2, 5, 7) assertEquals("0000000000030405060708090000", buffer2.hex()) @@ -454,9 +454,9 @@ open class NBufferTestBase { for (direct2 in listOf(false, true)) { val bufferBase = Buffer(16, direct1) for (n in 0 until 16) bufferBase.setUnalignedUInt8(n, n) - val buffer = bufferBase._slice(1) - val buffer2 = buffer._slice(2) - Buffer.copy(buffer._slice(1), 2, buffer2, 5, 7) + val buffer = bufferBase.sliceBuffer(1) + val buffer2 = buffer.sliceBuffer(2) + Buffer.copy(buffer.sliceBuffer(1), 2, buffer2, 5, 7) assertEquals("03040506070405060708090a0f", buffer2.hex()) } } diff --git a/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/Buffer.jvm.kt b/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/Buffer.jvm.kt index c2300097f9..95cd4dd0fe 100644 --- a/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/Buffer.jvm.kt +++ b/korge-foundation/src/jvmAndroidMain/kotlin/korlibs/memory/Buffer.jvm.kt @@ -109,7 +109,7 @@ fun java.nio.Buffer.clearSafe() { clear() } -inline fun T._slice(offset: Int, size: Int, dup: (T) -> T): T { +inline fun T.sliceBuffer(offset: Int, size: Int, dup: (T) -> T): T { checkSliceBounds(offset, size) val out = dup(this) val start = this.position() + offset @@ -119,11 +119,11 @@ inline fun T._slice(offset: Int, size: Int, dup: (T) -> T) return out } -fun ByteBuffer._slice(offset: Int, size: Int): ByteBuffer = this._slice(offset, size) { it.duplicate() } -fun ShortBuffer._slice(offset: Int, size: Int): ShortBuffer = this._slice(offset, size) { it.duplicate() } -fun IntBuffer._slice(offset: Int, size: Int): IntBuffer = this._slice(offset, size) { it.duplicate() } -fun FloatBuffer._slice(offset: Int, size: Int): FloatBuffer = this._slice(offset, size) { it.duplicate() } -fun DoubleBuffer._slice(offset: Int, size: Int): DoubleBuffer = this._slice(offset, size) { it.duplicate() } +fun ByteBuffer.sliceBuffer(offset: Int, size: Int): ByteBuffer = this.sliceBuffer(offset, size) { it.duplicate() } +fun ShortBuffer.sliceBuffer(offset: Int, size: Int): ShortBuffer = this.sliceBuffer(offset, size) { it.duplicate() } +fun IntBuffer.sliceBuffer(offset: Int, size: Int): IntBuffer = this.sliceBuffer(offset, size) { it.duplicate() } +fun FloatBuffer.sliceBuffer(offset: Int, size: Int): FloatBuffer = this.sliceBuffer(offset, size) { it.duplicate() } +fun DoubleBuffer.sliceBuffer(offset: Int, size: Int): DoubleBuffer = this.sliceBuffer(offset, size) { it.duplicate() } val Buffer.nioBuffer: java.nio.ByteBuffer get() = this.slicedBuffer() val Buffer.nioIntBuffer: java.nio.IntBuffer get() = this.slicedBuffer().asIntBuffer() diff --git a/korge/src/commonMain/kotlin/korlibs/graphics/gl/AGOpengl.kt b/korge/src/commonMain/kotlin/korlibs/graphics/gl/AGOpengl.kt index cf55a31a0f..d70f5bc4a5 100644 --- a/korge/src/commonMain/kotlin/korlibs/graphics/gl/AGOpengl.kt +++ b/korge/src/commonMain/kotlin/korlibs/graphics/gl/AGOpengl.kt @@ -643,7 +643,7 @@ class AGOpengl(val gl: KmlGl, var context: KmlGlContext? = null) : AG() { writeUniform( uniform.uniform, glProgramInfo, - currentMem._slice(uniform.voffset, uniform.voffset + uniform.totalBytes), + currentMem.sliceBuffer(uniform.voffset, uniform.voffset + uniform.totalBytes), "blockUniformSet", ) } diff --git a/korge/src/commonTest/kotlin/korlibs/graphics/AGUniformBlockTest.kt b/korge/src/commonTest/kotlin/korlibs/graphics/AGUniformBlockTest.kt index 04abb49883..0181a01f35 100644 --- a/korge/src/commonTest/kotlin/korlibs/graphics/AGUniformBlockTest.kt +++ b/korge/src/commonTest/kotlin/korlibs/graphics/AGUniformBlockTest.kt @@ -49,7 +49,7 @@ class AGUniformBlockTest { assertEquals( listOf(0.0, 1.0, 2.0, 3.0, 10.0, 11.0, 12.0, 13.0, 20.0, 21.0, 22.0, 23.0, 33.0, 33.0, 33.0, 33.0).map { it.toFloat() }, - ubb.buffer._slice(0, ubb.blockSizeNoGlAlign).f32.toFloatArray().toList() + ubb.buffer.sliceBuffer(0, ubb.blockSizeNoGlAlign).f32.toFloatArray().toList() ) val str = FragmentShader { diff --git a/korge/src/jsMain/kotlin/korlibs/kgl/KmlGlJsCanvas.kt b/korge/src/jsMain/kotlin/korlibs/kgl/KmlGlJsCanvas.kt index 2e5d5a78d9..dd6072dcaa 100644 --- a/korge/src/jsMain/kotlin/korlibs/kgl/KmlGlJsCanvas.kt +++ b/korge/src/jsMain/kotlin/korlibs/kgl/KmlGlJsCanvas.kt @@ -77,8 +77,8 @@ class KmlGlJsCanvas(val canvas: HTMLCanvasElement, val glOpts: dynamic) : KmlGl( override fun blendEquationSeparate(modeRGB: Int, modeAlpha: Int): Unit = gl.blendEquationSeparate(modeRGB, modeAlpha) override fun blendFunc(sfactor: Int, dfactor: Int): Unit = gl.blendFunc(sfactor, dfactor) override fun blendFuncSeparate(sfactorRGB: Int, dfactorRGB: Int, sfactorAlpha: Int, dfactorAlpha: Int): Unit = gl.blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha) - override fun bufferData(target: Int, size: Int, data: Buffer, usage: Int): Unit = gl.bufferData(target, data._slice(0, size).arrayUByte, usage) - override fun bufferSubData(target: Int, offset: Int, size: Int, data: Buffer): Unit = gl.bufferSubData(target, offset, data._slice(0, size).arrayUByte) + override fun bufferData(target: Int, size: Int, data: Buffer, usage: Int): Unit = gl.bufferData(target, data.sliceBuffer(0, size).arrayUByte, usage) + override fun bufferSubData(target: Int, offset: Int, size: Int, data: Buffer): Unit = gl.bufferSubData(target, offset, data.sliceBuffer(0, size).arrayUByte) override fun checkFramebufferStatus(target: Int): Int = gl.checkFramebufferStatus(target) override fun clear(mask: Int): Unit = gl.clear(mask) override fun clearColor(red: Float, green: Float, blue: Float, alpha: Float): Unit = gl.clearColor(red, green, blue, alpha) diff --git a/korge/src/jvmMain/kotlin/korlibs/render/platform/NativeKgl.kt b/korge/src/jvmMain/kotlin/korlibs/render/platform/NativeKgl.kt index 550cce7bf2..c9aa5cc8b6 100644 --- a/korge/src/jvmMain/kotlin/korlibs/render/platform/NativeKgl.kt +++ b/korge/src/jvmMain/kotlin/korlibs/render/platform/NativeKgl.kt @@ -141,9 +141,9 @@ open class NativeKgl constructor(private val gl: INativeGL) : KmlGl() { override fun uniform4fv(location: Int, count: Int, value: Buffer): Unit = gl.glUniform4fv(location, count, value.directFloatBuffer) override fun uniform4i(location: Int, v0: Int, v1: Int, v2: Int, v3: Int): Unit = gl.glUniform4i(location, v0, v1, v2, v3) override fun uniform4iv(location: Int, count: Int, value: Buffer): Unit = gl.glUniform4iv(location, count, value.directIntBuffer) - override fun uniformMatrix2fv(location: Int, count: Int, transpose: Boolean, value: Buffer): Unit = gl.glUniformMatrix2fv(location, count, transpose.toByte(), value.directFloatBuffer.slice(0, 4 * count)) - override fun uniformMatrix3fv(location: Int, count: Int, transpose: Boolean, value: Buffer): Unit = gl.glUniformMatrix3fv(location, count, transpose.toByte(), value.directFloatBuffer.slice(0, 9 * count)) - override fun uniformMatrix4fv(location: Int, count: Int, transpose: Boolean, value: Buffer): Unit = gl.glUniformMatrix4fv(location, count, transpose.toByte(), value.directFloatBuffer.slice(0, 16 * count)) + override fun uniformMatrix2fv(location: Int, count: Int, transpose: Boolean, value: Buffer): Unit = gl.glUniformMatrix2fv(location, count, transpose.toByte(), value.directFloatBuffer.sliceBuffer(0, 4 * count)) + override fun uniformMatrix3fv(location: Int, count: Int, transpose: Boolean, value: Buffer): Unit = gl.glUniformMatrix3fv(location, count, transpose.toByte(), value.directFloatBuffer.sliceBuffer(0, 9 * count)) + override fun uniformMatrix4fv(location: Int, count: Int, transpose: Boolean, value: Buffer): Unit = gl.glUniformMatrix4fv(location, count, transpose.toByte(), value.directFloatBuffer.sliceBuffer(0, 16 * count)) override fun useProgram(program: Int): Unit = gl.glUseProgram(program) override fun validateProgram(program: Int): Unit = gl.glValidateProgram(program) override fun vertexAttrib1f(index: Int, x: Float): Unit = gl.glVertexAttrib1f(index, x) diff --git a/korge/src/wasmJsMain/kotlin/korlibs/kgl/KmlGlWasmCanvas.kt b/korge/src/wasmJsMain/kotlin/korlibs/kgl/KmlGlWasmCanvas.kt index cee0e3fa24..0c93c42d67 100644 --- a/korge/src/wasmJsMain/kotlin/korlibs/kgl/KmlGlWasmCanvas.kt +++ b/korge/src/wasmJsMain/kotlin/korlibs/kgl/KmlGlWasmCanvas.kt @@ -106,8 +106,8 @@ class KmlGlWasmCanvas(val canvas: HTMLCanvasElement, val glOpts: JsAny) : KmlGl( override fun blendEquationSeparate(modeRGB: Int, modeAlpha: Int): Unit = gl.blendEquationSeparate(modeRGB, modeAlpha) override fun blendFunc(sfactor: Int, dfactor: Int): Unit = gl.blendFunc(sfactor, dfactor) override fun blendFuncSeparate(sfactorRGB: Int, dfactorRGB: Int, sfactorAlpha: Int, dfactorAlpha: Int): Unit = gl.blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha) - override fun bufferData(target: Int, size: Int, data: Buffer, usage: Int): Unit = gl.bufferData(target, data._slice(0, size).arrayUByte, usage) - override fun bufferSubData(target: Int, offset: Int, size: Int, data: Buffer): Unit = gl.bufferSubData(target, offset, data._slice(0, size).arrayUByte) + override fun bufferData(target: Int, size: Int, data: Buffer, usage: Int): Unit = gl.bufferData(target, data.sliceBuffer(0, size).arrayUByte, usage) + override fun bufferSubData(target: Int, offset: Int, size: Int, data: Buffer): Unit = gl.bufferSubData(target, offset, data.sliceBuffer(0, size).arrayUByte) override fun checkFramebufferStatus(target: Int): Int = gl.checkFramebufferStatus(target) override fun clear(mask: Int): Unit = gl.clear(mask) override fun clearColor(red: Float, green: Float, blue: Float, alpha: Float): Unit = gl.clearColor(red, green, blue, alpha) From 52ce1baa6503c23c543d38ea68ae4fb607c6d4a5 Mon Sep 17 00:00:00 2001 From: soywiz Date: Wed, 27 Sep 2023 04:46:40 +0200 Subject: [PATCH 7/7] Fixes iOS target --- .../src/darwinMain/kotlin/korlibs/memory/Buffer.native.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/korge-foundation/src/darwinMain/kotlin/korlibs/memory/Buffer.native.kt b/korge-foundation/src/darwinMain/kotlin/korlibs/memory/Buffer.native.kt index f3729b20ea..a99dee7eea 100644 --- a/korge-foundation/src/darwinMain/kotlin/korlibs/memory/Buffer.native.kt +++ b/korge-foundation/src/darwinMain/kotlin/korlibs/memory/Buffer.native.kt @@ -60,7 +60,7 @@ actual class Buffer(val data: ByteArray, val offset: Int, val size: Int, dummy: check(dstPosBytes + sizeInBytes <= dst.sizeInBytes) src.data.usePinned { srcPin -> dst.data.usePinned { dstPin -> - return memcmp(srcPin.startAddressOf + srcPosBytes, dstPin.startAddressOf + dstPosBytes, sizeInBytes.convert()) == 0 + return memcmp(srcPin.startAddressOf + src.offset + srcPosBytes, dstPin.startAddressOf + dst.offset + dstPosBytes, sizeInBytes.convert()) == 0 } } }