From 41fb08f3f1c4abbe940b3fa814ac2e491912c4d4 Mon Sep 17 00:00:00 2001 From: Him188 Date: Wed, 29 Apr 2020 19:36:55 +0800 Subject: [PATCH] `FileCacheStrategy`, `ReusableInput` fundamental --- .../kotlin/net.mamoe.mirai/Mirai.kt | 46 +++++++++++++++++++ .../net.mamoe.mirai/utils/ExternalImage.kt | 25 +++++++--- .../utils/internal/asReusableInput.common.kt | 23 ++++++++++ .../jvmMain/kotlin/net/mamoe/mirai/Mirai.kt | 15 ++++++ .../utils/internal/asReusableInput.jvm.kt | 18 ++++++++ 5 files changed, 120 insertions(+), 7 deletions(-) create mode 100644 mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Mirai.kt create mode 100644 mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/internal/asReusableInput.common.kt create mode 100644 mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Mirai.kt create mode 100644 mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/internal/asReusableInput.jvm.kt diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Mirai.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Mirai.kt new file mode 100644 index 000000000..32edf24bb --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Mirai.kt @@ -0,0 +1,46 @@ +/* + * 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 + +import io.ktor.utils.io.ByteReadChannel +import kotlinx.io.core.Input +import net.mamoe.mirai.utils.ExternalImage +import net.mamoe.mirai.utils.MiraiExperimentalAPI +import net.mamoe.mirai.utils.SinceMirai +import net.mamoe.mirai.utils.internal.InputStream +import kotlin.jvm.JvmStatic + +/** + * Mirai 全局环境. + */ +@SinceMirai("1.0.0") +expect object Mirai { + + @JvmStatic + var fileCacheStrategy: FileCacheStrategy + + /** + * 缓存策略. + * + * 图片上传时默认使用文件缓存. + */ + interface FileCacheStrategy { + @MiraiExperimentalAPI + fun newImageCache(input: Input): ExternalImage + + @MiraiExperimentalAPI + fun newImageCache(input: ByteReadChannel): ExternalImage + + @MiraiExperimentalAPI + fun newImageCache(input: InputStream): ExternalImage + + companion object Default : FileCacheStrategy + } +} \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt index 49f3e1af3..036632d62 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt @@ -24,6 +24,7 @@ import net.mamoe.mirai.message.data.Image import net.mamoe.mirai.message.data.OfflineImage import net.mamoe.mirai.message.data.sendTo import net.mamoe.mirai.message.data.toLongUnsigned +import net.mamoe.mirai.utils.internal.asReusableInput import kotlin.jvm.JvmSynthetic /** @@ -34,33 +35,43 @@ import kotlin.jvm.JvmSynthetic * @see ExternalImage.sendTo 上传图片并以纯图片消息发送给联系人 * @See ExternalImage.upload 上传图片并得到 [Image] 消息 */ -class ExternalImage private constructor( +@OptIn(MiraiInternalAPI::class) +class ExternalImage internal constructor( val md5: ByteArray, - val input: Any, // Input from kotlinx.io, InputStream from kotlinx.io MPP, ByteReadChannel from ktor - val inputSize: Long // dont be greater than Int.MAX + @Suppress("EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR") + @MiraiInternalAPI("unstable API") + val input: ReusableInput, // Input from kotlinx.io, InputStream from kotlinx.io MPP, ByteReadChannel from ktor + @MiraiInternalAPI("unstable API") + val inputSize: Int // dont be greater than Int.MAX ) { + @SinceMirai("1.0.0") + internal interface ReusableInput { + fun input(): Input + } + + constructor( md5: ByteArray, input: ByteReadChannel, inputSize: Long // dont be greater than Int.MAX - ) : this(md5, input as Any, inputSize) + ) : this(md5, input.asReusableInput(), inputSize.coerceAtMost(Int.MAX_VALUE.toLongUnsigned()).toInt()) constructor( md5: ByteArray, input: Input, inputSize: Long // dont be greater than Int.MAX - ) : this(md5, input as Any, inputSize) + ) : this(md5, input.asReusableInput(), inputSize.coerceAtMost(Int.MAX_VALUE.toLongUnsigned()).toInt()) constructor( md5: ByteArray, input: ByteReadPacket - ) : this(md5, input as Any, input.remaining) + ) : this(md5, input.asReusableInput(), input.remaining.coerceAtMost(Int.MAX_VALUE.toLongUnsigned()).toInt()) @OptIn(InternalSerializationApi::class) constructor( md5: ByteArray, input: InputStream - ) : this(md5, input as Any, input.available().toLongUnsigned()) + ) : this(md5, input.asReusableInput(), input.available()) init { require(inputSize < 30L * 1024 * 1024) { "file is too big. Maximum is about 20MB" } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/internal/asReusableInput.common.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/internal/asReusableInput.common.kt new file mode 100644 index 000000000..c6cd87f5a --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/internal/asReusableInput.common.kt @@ -0,0 +1,23 @@ +/* + * 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.utils.internal + +import kotlinx.coroutines.io.ByteReadChannel +import kotlinx.io.InputStream +import kotlinx.io.core.Input +import kotlinx.serialization.InternalSerializationApi +import net.mamoe.mirai.utils.ExternalImage + + +internal expect fun ByteReadChannel.asReusableInput(): ExternalImage.ReusableInput +internal expect fun Input.asReusableInput(): ExternalImage.ReusableInput + +@OptIn(InternalSerializationApi::class) +internal expect fun InputStream.asReusableInput(): ExternalImage.ReusableInput diff --git a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Mirai.kt b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Mirai.kt new file mode 100644 index 000000000..b210a61d3 --- /dev/null +++ b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Mirai.kt @@ -0,0 +1,15 @@ +package net.mamoe.mirai + +/** + * Mirai 全局环境. + */ +actual object Mirai { + actual var fileCacheStrategy: FileCacheStrategy + get() = TODO("Not yet implemented") + set(value) {} + + actual interface FileCacheStrategy { + + } + +} \ No newline at end of file diff --git a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/internal/asReusableInput.jvm.kt b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/internal/asReusableInput.jvm.kt new file mode 100644 index 000000000..22af57641 --- /dev/null +++ b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/internal/asReusableInput.jvm.kt @@ -0,0 +1,18 @@ +package net.mamoe.mirai.utils.internal + +import kotlinx.coroutines.io.ByteReadChannel +import kotlinx.io.core.Input +import net.mamoe.mirai.utils.ExternalImage +import java.io.InputStream + +internal actual fun ByteReadChannel.asReusableInput(): ExternalImage.ReusableInput { + TODO("Not yet implemented") +} + +internal actual fun Input.asReusableInput(): ExternalImage.ReusableInput { + TODO("Not yet implemented") +} + +internal actual fun InputStream.asReusableInput(): ExternalImage.ReusableInput { + TODO("Not yet implemented") +} \ No newline at end of file