|
|
@@ -0,0 +1,185 @@
|
|
|
+/*
|
|
|
+ * Copyright 2020 Mamoe Technologies and contributors.
|
|
|
+ *
|
|
|
+ * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
|
|
+ * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
|
|
+ *
|
|
|
+ * https://github.com/mamoe/mirai/blob/master/LICENSE
|
|
|
+ */
|
|
|
+
|
|
|
+package net.mamoe.mirai.qqandroid
|
|
|
+
|
|
|
+import io.ktor.utils.io.ByteReadChannel
|
|
|
+import io.ktor.utils.io.consumeEachBufferRange
|
|
|
+import io.ktor.utils.io.core.Input
|
|
|
+import io.ktor.utils.io.core.readBytes
|
|
|
+import kotlinx.coroutines.io.*
|
|
|
+import kotlinx.io.core.*
|
|
|
+import kotlinx.io.pool.useInstance
|
|
|
+import net.mamoe.mirai.qqandroid.utils.ByteArrayPool
|
|
|
+import net.mamoe.mirai.qqandroid.utils.toReadPacket
|
|
|
+import net.mamoe.mirai.utils.MiraiInternalAPI
|
|
|
+import java.nio.ByteBuffer
|
|
|
+
|
|
|
+@OptIn(MiraiInternalAPI::class)
|
|
|
+@Suppress("DEPRECATION")
|
|
|
+internal actual fun ByteReadChannel.toKotlinByteReadChannel(): kotlinx.coroutines.io.ByteReadChannel {
|
|
|
+ return object : kotlinx.coroutines.io.ByteReadChannel {
|
|
|
+ override val availableForRead: Int
|
|
|
+ get() = [email protected]
|
|
|
+ override val isClosedForRead: Boolean
|
|
|
+ get() = [email protected]
|
|
|
+ override val isClosedForWrite: Boolean
|
|
|
+ get() = [email protected]
|
|
|
+
|
|
|
+ @Suppress("DEPRECATION_ERROR", "OverridingDeprecatedMember")
|
|
|
+ override var readByteOrder: ByteOrder
|
|
|
+ get() = when ([email protected]) {
|
|
|
+ io.ktor.utils.io.core.ByteOrder.BIG_ENDIAN -> ByteOrder.BIG_ENDIAN
|
|
|
+ io.ktor.utils.io.core.ByteOrder.LITTLE_ENDIAN -> ByteOrder.LITTLE_ENDIAN
|
|
|
+ }
|
|
|
+ set(value) {
|
|
|
+ [email protected] = when (value) {
|
|
|
+ ByteOrder.BIG_ENDIAN -> io.ktor.utils.io.core.ByteOrder.BIG_ENDIAN
|
|
|
+ ByteOrder.LITTLE_ENDIAN -> io.ktor.utils.io.core.ByteOrder.LITTLE_ENDIAN
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Suppress("DEPRECATION_ERROR", "DEPRECATION", "OverridingDeprecatedMember")
|
|
|
+ override val totalBytesRead: Long
|
|
|
+ get() = [email protected]
|
|
|
+
|
|
|
+ override fun cancel(cause: Throwable?): Boolean = [email protected](cause)
|
|
|
+ override suspend fun consumeEachBufferRange(visitor: ConsumeEachBufferVisitor) =
|
|
|
+ [email protected](visitor)
|
|
|
+
|
|
|
+ override suspend fun discard(max: Long): Long = [email protected](max)
|
|
|
+
|
|
|
+ @Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_OVERRIDE")
|
|
|
+ @ExperimentalIoApi
|
|
|
+ override fun <R> lookAhead(visitor: LookAheadSession.() -> R): R {
|
|
|
+ return [email protected] l@{
|
|
|
+ visitor(object : LookAheadSession {
|
|
|
+ override fun consumed(n: Int) {
|
|
|
+ return [email protected](n)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun request(skip: Int, atLeast: Int): ByteBuffer? {
|
|
|
+ return [email protected](skip, atLeast)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_OVERRIDE")
|
|
|
+ @ExperimentalIoApi
|
|
|
+ override suspend fun <R> lookAheadSuspend(visitor: suspend LookAheadSuspendSession.() -> R): R =
|
|
|
+ [email protected] l@{
|
|
|
+ visitor(object : LookAheadSuspendSession {
|
|
|
+ override suspend fun awaitAtLeast(n: Int): Boolean {
|
|
|
+ return [email protected](n)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun consumed(n: Int) {
|
|
|
+ return [email protected](n)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun request(skip: Int, atLeast: Int): ByteBuffer? {
|
|
|
+ return [email protected](skip, atLeast)
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ override suspend fun read(min: Int, consumer: (ByteBuffer) -> Unit) =
|
|
|
+ [email protected](min, consumer)
|
|
|
+
|
|
|
+ override suspend fun readAvailable(dst: ByteBuffer): Int = [email protected](dst)
|
|
|
+ override suspend fun readAvailable(dst: ByteArray, offset: Int, length: Int): Int =
|
|
|
+ [email protected](dst, offset, length)
|
|
|
+
|
|
|
+ override suspend fun readAvailable(dst: IoBuffer): Int {
|
|
|
+ ByteArrayPool.useInstance {
|
|
|
+ val read = [email protected](it, 0, it.size)
|
|
|
+ dst.writeFully(it, 0, read)
|
|
|
+ return read
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override suspend fun readBoolean(): Boolean = [email protected]()
|
|
|
+ override suspend fun readByte(): Byte = [email protected]()
|
|
|
+ override suspend fun readDouble(): Double = [email protected]()
|
|
|
+ override suspend fun readFloat(): Float = [email protected]()
|
|
|
+ override suspend fun readFully(dst: ByteBuffer): Int {
|
|
|
+ TODO("not implemented")
|
|
|
+ }
|
|
|
+
|
|
|
+ override suspend fun readFully(dst: ByteArray, offset: Int, length: Int) =
|
|
|
+ [email protected](dst, offset, length)
|
|
|
+
|
|
|
+ override suspend fun readFully(dst: IoBuffer, n: Int) {
|
|
|
+ ByteArrayPool.useInstance {
|
|
|
+ dst.writeFully(it, 0, this.readAvailable(it, 0, it.size))
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override suspend fun readInt(): Int = [email protected]()
|
|
|
+ override suspend fun readLong(): Long = [email protected]()
|
|
|
+ override suspend fun readPacket(size: Int, headerSizeHint: Int): ByteReadPacket {
|
|
|
+ return [email protected](size, headerSizeHint).readBytes().toReadPacket()
|
|
|
+ }
|
|
|
+
|
|
|
+ override suspend fun readRemaining(limit: Long, headerSizeHint: Int): ByteReadPacket {
|
|
|
+ return [email protected](limit, headerSizeHint).readBytes().toReadPacket()
|
|
|
+ }
|
|
|
+
|
|
|
+ @OptIn(ExperimentalIoApi::class)
|
|
|
+ @ExperimentalIoApi
|
|
|
+ override fun readSession(consumer: ReadSession.() -> Unit) {
|
|
|
+ @Suppress("DEPRECATION")
|
|
|
+ [email protected] lambda@{
|
|
|
+ consumer(object : ReadSession {
|
|
|
+ override val availableForRead: Int
|
|
|
+ get() = [email protected]
|
|
|
+
|
|
|
+ override fun discard(n: Int): Int = [email protected](n)
|
|
|
+
|
|
|
+ override fun request(atLeast: Int): IoBuffer? {
|
|
|
+ val ioBuffer: io.ktor.utils.io.core.IoBuffer = [email protected](atLeast) ?: return null
|
|
|
+ val buffer = IoBuffer.Pool.borrow()
|
|
|
+ val bytes = (ioBuffer as Input).readBytes()
|
|
|
+ buffer.writeFully(bytes)
|
|
|
+ return buffer
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override suspend fun readShort(): Short = [email protected]()
|
|
|
+
|
|
|
+ @Suppress("EXPERIMENTAL_OVERRIDE", "EXPERIMENTAL_API_USAGE")
|
|
|
+ @ExperimentalIoApi
|
|
|
+ override suspend fun readSuspendableSession(consumer: suspend SuspendableReadSession.() -> Unit) =
|
|
|
+ [email protected] l@{
|
|
|
+ consumer(object : SuspendableReadSession {
|
|
|
+ override val availableForRead: Int
|
|
|
+ get() = [email protected]
|
|
|
+
|
|
|
+ override suspend fun await(atLeast: Int): Boolean = [email protected](atLeast)
|
|
|
+ override fun discard(n: Int): Int = [email protected](n)
|
|
|
+ override fun request(atLeast: Int): IoBuffer? {
|
|
|
+ @Suppress("DuplicatedCode") val ioBuffer: io.ktor.utils.io.core.IoBuffer =
|
|
|
+ [email protected](atLeast) ?: return null
|
|
|
+ val buffer = IoBuffer.Pool.borrow()
|
|
|
+ val bytes = (ioBuffer as Input).readBytes()
|
|
|
+ buffer.writeFully(bytes)
|
|
|
+ return buffer
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ override suspend fun readUTF8Line(limit: Int): String? = [email protected](limit)
|
|
|
+ override suspend fun <A : Appendable> readUTF8LineTo(out: A, limit: Int): Boolean =
|
|
|
+ [email protected](out, limit)
|
|
|
+ }
|
|
|
+}
|