nativeMain.com.arkivanov.mvikotlin.timetravel.proto.internal.io.ReaderThread.kt Maven / Gradle / Ivy
package com.arkivanov.mvikotlin.timetravel.proto.internal.io
import com.arkivanov.mvikotlin.timetravel.proto.internal.data.ProtoObject
import com.arkivanov.mvikotlin.timetravel.proto.internal.thread.Thread
import kotlinx.cinterop.Arena
import kotlinx.cinterop.ByteVar
import kotlinx.cinterop.allocArray
import kotlinx.cinterop.convert
import kotlinx.cinterop.readBytes
import platform.posix.close
import platform.posix.read
class ReaderThread(
private val socket: Int,
private val onRead: (T) -> Unit,
private val onDisconnected: () -> Unit = {},
private val onError: (Throwable) -> Unit = {}
) : Thread() {
override fun run() {
val protoDecoder = ProtoDecoder()
val protoFrameDecoder =
ProtoFrameDecoder { data ->
val protoObject = protoDecoder.decode(data)
@Suppress("UNCHECKED_CAST")
onRead(protoObject as T)
}
val arena = Arena()
try {
val buffer = arena.allocArray(length = BUFFER_SIZE)
while (!isInterrupted) {
val len: Int = read(socket, buffer, BUFFER_SIZE.convert()).convert()
if (len <= 0) {
break
}
protoFrameDecoder.accept(buffer.readBytes(len), len)
}
} catch (e: Throwable) {
onError(e)
} finally {
arena.clear()
close(socket)
onDisconnected()
}
}
private companion object {
private const val BUFFER_SIZE = 32768
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy