Foreign Memory.kt implementation #98
@ -0,0 +1,51 @@
|
|||||||
|
package scientifik.memory.foreign
|
||||||
|
|
||||||
|
import jdk.incubator.foreign.MemoryHandles
|
||||||
|
import jdk.incubator.foreign.MemorySegment
|
||||||
|
import scientifik.memory.Memory
|
||||||
|
import scientifik.memory.MemoryReader
|
||||||
|
import scientifik.memory.MemoryWriter
|
||||||
|
import java.lang.invoke.VarHandle
|
||||||
|
import java.nio.ByteOrder
|
||||||
|
|
||||||
|
fun Memory.Companion.allocateForeign(length: Int): Memory {
|
||||||
|
return ForeignMemory(MemorySegment.allocateNative(length.toLong()))
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ForeignMemory(val scope: MemorySegment) : Memory, AutoCloseable {
|
||||||
|
override val size: Int
|
||||||
|
get() = scope.byteSize().toInt()
|
||||||
|
|
||||||
|
private val writer: MemoryWriter = ForeignWriter(this)
|
||||||
|
private val reader: MemoryReader = ForeignReader(this)
|
||||||
|
|
||||||
|
override fun view(offset: Int, length: Int): ForeignMemory =
|
||||||
|
ForeignMemory(scope.asSlice(offset.toLong(), length.toLong()))
|
||||||
|
|
||||||
|
override fun copy(): Memory {
|
||||||
|
val bytes = scope.toByteArray()
|
||||||
|
val newScope = MemorySegment.allocateNative(scope.byteSize())!!
|
||||||
|
|
||||||
|
var point = newScope.baseAddress()
|
||||||
|
|
||||||
|
bytes.forEach {
|
||||||
|
byteHandle.set(point, it)
|
||||||
|
point = point.addOffset(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ForeignMemory(newScope)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reader(): MemoryReader = reader
|
||||||
|
override fun writer(): MemoryWriter = writer
|
||||||
|
override fun close(): Unit = scope.close()
|
||||||
|
|
||||||
|
internal companion object {
|
||||||
|
internal val doubleHandle: VarHandle = MemoryHandles.varHandle(java.lang.Double.TYPE, ByteOrder.nativeOrder())!!
|
||||||
|
internal val floatHandle: VarHandle = MemoryHandles.varHandle(java.lang.Float.TYPE, ByteOrder.nativeOrder())!!
|
||||||
|
internal val byteHandle: VarHandle = MemoryHandles.varHandle(java.lang.Byte.TYPE, ByteOrder.nativeOrder())!!
|
||||||
|
internal val shortHandle: VarHandle = MemoryHandles.varHandle(java.lang.Short.TYPE, ByteOrder.nativeOrder())!!
|
||||||
|
internal val intHandle: VarHandle = MemoryHandles.varHandle(Integer.TYPE, ByteOrder.nativeOrder())!!
|
||||||
|
internal val longHandle: VarHandle = MemoryHandles.varHandle(java.lang.Long.TYPE, ByteOrder.nativeOrder())!!
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package scientifik.memory.foreign
|
||||||
|
|
||||||
|
import jdk.incubator.foreign.MemorySegment
|
||||||
|
import scientifik.memory.MemoryReader
|
||||||
|
|
||||||
|
internal class ForeignReader(override val memory: ForeignMemory) : MemoryReader {
|
||||||
|
private val scope: MemorySegment
|
||||||
|
get() = memory.scope.asReadOnly()
|
||||||
|
|
||||||
|
override fun readDouble(offset: Int): Double = with(scope) {
|
||||||
|
ForeignMemory.doubleHandle.get(baseAddress().addOffset(offset.toLong())) as Double
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun readFloat(offset: Int): Float = with(scope) {
|
||||||
|
ForeignMemory.floatHandle.get(baseAddress().addOffset(offset.toLong())) as Float
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun readByte(offset: Int): Byte = with(scope) {
|
||||||
|
ForeignMemory.byteHandle.get(baseAddress().addOffset(offset.toLong())) as Byte
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun readShort(offset: Int): Short = with(scope) {
|
||||||
|
ForeignMemory.shortHandle.get(baseAddress().addOffset(offset.toLong())) as Short
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun readInt(offset: Int): Int = with(scope) {
|
||||||
|
ForeignMemory.intHandle.get(baseAddress().addOffset(offset.toLong())) as Int
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun readLong(offset: Int): Long = with(scope) {
|
||||||
|
ForeignMemory.longHandle.get(baseAddress().addOffset(offset.toLong())) as Long
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun release(): Unit = memory.close()
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package scientifik.memory.foreign
|
||||||
|
|
||||||
|
import jdk.incubator.foreign.MemorySegment
|
||||||
|
import scientifik.memory.MemoryWriter
|
||||||
|
|
||||||
|
internal class ForeignWriter(override val memory: ForeignMemory) : MemoryWriter {
|
||||||
|
private val scope: MemorySegment
|
||||||
|
get() = memory.scope
|
||||||
|
|
||||||
|
override fun writeDouble(offset: Int, value: Double): Unit = with(scope) {
|
||||||
|
ForeignMemory.doubleHandle.set(baseAddress().addOffset(offset.toLong()), value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeFloat(offset: Int, value: Float): Unit = with(scope) {
|
||||||
|
ForeignMemory.floatHandle.set(baseAddress().addOffset(offset.toLong()), value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeByte(offset: Int, value: Byte): Unit = with(scope) {
|
||||||
|
ForeignMemory.byteHandle.set(baseAddress().addOffset(offset.toLong()), value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeShort(offset: Int, value: Short): Unit = with(scope) {
|
||||||
|
ForeignMemory.shortHandle.set(baseAddress().addOffset(offset.toLong()), value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeInt(offset: Int, value: Int): Unit = with(scope) {
|
||||||
|
ForeignMemory.intHandle.set(baseAddress().addOffset(offset.toLong()), value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeLong(offset: Int, value: Long): Unit = with(scope) {
|
||||||
|
ForeignMemory.longHandle.set(baseAddress().addOffset(offset.toLong()), value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun release(): Unit = memory.close()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user