Asynchronous I/O library for Kotlin multiplatform providing channels, streams, and byte manipulation utilities optimized for watchOS ARM64
npx @tessl/cli install tessl/maven-io-ktor--ktor-io-watchosarm64@2.3.0Ktor I/O is a comprehensive asynchronous I/O library for Kotlin multiplatform, specifically compiled for the watchOS ARM64 platform. It provides coroutine-based non-blocking byte channels, stream operations, memory management utilities, and character encoding support optimized for Apple Watch devices.
build.gradle.kts dependencies:
implementation("io.ktor:ktor-io-watchosarm64:2.3.13")import io.ktor.utils.io.*
import io.ktor.utils.io.core.*
import io.ktor.utils.io.bits.*
import io.ktor.utils.io.pool.*
import io.ktor.utils.io.charsets.*import io.ktor.utils.io.*
import io.ktor.utils.io.core.*
import io.ktor.utils.io.bits.*
import kotlinx.coroutines.*
// Create channels for async I/O
val readChannel = ByteReadChannel("Hello, watchOS!".toByteArray())
val writeChannel = ByteChannel(autoFlush = true) // Note: ByteChannel is deprecated
// Read data asynchronously
runBlocking {
val text = readChannel.readUTF8Line()
val remainingPacket = readChannel.readRemaining()
println("Text: $text")
}
// Write data to channel
runBlocking {
writeChannel.writeStringUtf8("Hello, watchOS!")
writeChannel.writeByte(42)
writeChannel.close()
}
// Work with byte packets (immutable)
val packet = buildPacket {
writeText("Packet data")
writeInt(12345)
}
// Read from packet
val text = packet.readText()
val number = packet.readInt()
// Memory operations with temporary allocation
withMemory(1024) { memory ->
memory.storeAt(0, 0xFF.toByte())
val value = memory.loadAt(0)
println("Stored and loaded: ${value.toUByte()}")
}Ktor I/O is built around several key components:
ByteReadChannel and ByteWriteChannel interfaces for coroutine-based non-blocking I/OByteReadPacket and mutable BytePacketBuilder for structured data handlingMemory API for direct byte manipulation with platform-specific optimizationsObjectPool interface for efficient resource management and memory reuseCore asynchronous I/O functionality providing single-reader/single-writer channels for non-blocking byte operations with coroutine integration.
interface ByteReadChannel {
val availableForRead: Int
val isClosedForRead: Boolean
suspend fun readByte(): Byte
suspend fun readAvailable(dst: ByteArray, offset: Int, length: Int): Int
}
interface ByteWriteChannel {
val availableForWrite: Int
val isClosedForWrite: Boolean
suspend fun writeByte(b: Byte)
suspend fun writeAvailable(src: ByteArray, offset: Int, length: Int): Int
}Immutable byte packets and builders for structured data handling with automatic memory management and efficient serialization.
class ByteReadPacket : Input {
fun copy(): ByteReadPacket
companion object {
val Empty: ByteReadPacket
}
}
class BytePacketBuilder : Output {
val size: Int
fun build(): ByteReadPacket
fun append(value: Char): BytePacketBuilder
}
fun buildPacket(block: BytePacketBuilder.() -> Unit): ByteReadPacketLow-level memory operations providing direct byte access, primitive type loading/storing, and platform-optimized memory utilities.
expect class Memory {
val size: Long
fun loadAt(index: Int): Byte
fun storeAt(index: Int, value: Byte)
fun slice(offset: Int, length: Int): Memory
operator fun get(index: Int): Byte
operator fun set(index: Int, value: Byte)
}Resource management system providing efficient object reuse patterns with configurable capacity and lifecycle management.
interface ObjectPool<T> : Closeable {
val capacity: Int
fun borrow(): T
fun recycle(instance: T)
}
object ByteArrayPool : ObjectPool<ByteArray>
inline fun <T : Any, R> ObjectPool<T>.useInstance(block: (T) -> R): RCharacter encoding and decoding support with UTF-8 and ISO-8859-1 charsets, providing encoder/decoder abstractions for text processing.
abstract class Charset {
val name: String
abstract fun newEncoder(): CharsetEncoder
abstract fun newDecoder(): CharsetDecoder
}
object Charsets {
val UTF_8: Charset
val ISO_8859_1: Charset
}Byte order manipulation and primitive type conversion utilities supporting both big-endian and little-endian operations.
fun Short.reverseByteOrder(): Short
fun Int.reverseByteOrder(): Int
fun Long.reverseByteOrder(): Long
fun Float.reverseByteOrder(): Float
fun Double.reverseByteOrder(): Double
val Short.highByte: Byte
val Short.lowByte: Byte
val Int.highShort: Short
val Int.lowShort: Shortinterface ByteReadChannel {
val availableForRead: Int
val isClosedForRead: Boolean
val isClosedForWrite: Boolean
val closedCause: Throwable?
val totalBytesRead: Long
suspend fun readAvailable(dst: ByteArray, offset: Int, length: Int): Int
suspend fun readFully(dst: ByteArray, offset: Int, length: Int)
suspend fun readByte(): Byte
suspend fun readShort(): Short
suspend fun readInt(): Int
suspend fun readLong(): Long
suspend fun readFloat(): Float
suspend fun readDouble(): Double
suspend fun readBoolean(): Boolean
suspend fun readUTF8Line(limit: Int = Int.MAX_VALUE): String?
suspend fun readPacket(size: Int): ByteReadPacket
suspend fun discard(max: Long = Long.MAX_VALUE): Long
fun cancel(cause: Throwable? = null): Boolean
companion object {
val Empty: ByteReadChannel
}
}
interface ByteWriteChannel {
val availableForWrite: Int
val isClosedForWrite: Boolean
val autoFlush: Boolean
val totalBytesWritten: Long
val closedCause: Throwable?
suspend fun writeAvailable(src: ByteArray, offset: Int, length: Int): Int
suspend fun writeFully(src: ByteArray, offset: Int, length: Int)
suspend fun writeByte(b: Byte)
suspend fun writeShort(s: Short)
suspend fun writeInt(i: Int)
suspend fun writeLong(l: Long)
suspend fun writeFloat(f: Float)
suspend fun writeDouble(d: Double)
suspend fun writePacket(packet: ByteReadPacket)
fun close(cause: Throwable? = null): Boolean
fun flush()
suspend fun awaitFreeSpace()
}
@Deprecated("Use ByteReadChannel and ByteWriteChannel instead")
interface ByteChannel : ByteReadChannel, ByteWriteChannelclass ByteReadPacket : Input {
val remaining: Long
val endOfInput: Boolean
fun copy(): ByteReadPacket
companion object {
val Empty: ByteReadPacket
}
}
class BytePacketBuilder : Output, Appendable {
val size: Int
val isEmpty: Boolean
val isNotEmpty: Boolean
fun build(): ByteReadPacket
override fun append(value: Char): BytePacketBuilder
override fun append(value: CharSequence?): BytePacketBuilder
}expect class Memory {
val size: Long
val size32: Int
fun loadAt(index: Int): Byte
fun loadAt(index: Long): Byte
fun storeAt(index: Int, value: Byte)
fun storeAt(index: Long, value: Byte)
fun slice(offset: Int, length: Int): Memory
fun slice(offset: Long, length: Long): Memory
fun copyTo(destination: Memory, offset: Int, length: Int, destinationOffset: Int)
fun copyTo(destination: ByteArray, offset: Int, length: Int, destinationOffset: Int)
operator fun get(index: Int): Byte
operator fun get(index: Long): Byte
operator fun set(index: Int, value: Byte)
operator fun set(index: Long, value: Byte)
fun fill(offset: Int, count: Int, value: Byte)
fun fill(offset: Long, count: Long, value: Byte)
companion object {
val Empty: Memory
}
}expect open class IOException(message: String, cause: Throwable? = null) : Exception
expect open class EOFException(message: String) : IOException
class ClosedWriteChannelException(message: String? = null) : CancellationException(message)
class InsufficientSpaceException(message: String) : Exception(message)
abstract class MalformedInputException(message: String) : Throwable(message)
class TooLongLineException(message: String) : MalformedInputException(message)