From c9f8bef00dd91c1afa68c0be9d6e6ae6ee9298a5 Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sat, 11 Jul 2020 12:07:52 +0800 Subject: [PATCH] Optimize Pure output --- .../console/pure/BufferedOutputStream.kt | 85 +++++++++++++++++++ .../mirai/console/pure/MiraiConsolePure.kt | 2 +- .../console/pure/MiraiConsolePureLoader.kt | 20 +++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/BufferedOutputStream.kt diff --git a/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/BufferedOutputStream.kt b/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/BufferedOutputStream.kt new file mode 100644 index 000000000..744a062c0 --- /dev/null +++ b/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/BufferedOutputStream.kt @@ -0,0 +1,85 @@ +/* + * 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.console.pure + +import java.io.ByteArrayOutputStream +import java.io.OutputStream + +private const val LN = 10.toByte() + +internal class BufferedOutputStream @JvmOverloads constructor( + private val size: Int = 1024 * 1024 * 1024, + private val logger: (String?) -> Unit +) : ByteArrayOutputStream(size + 1) { + override fun write(b: Int) { + if (this.count >= size) { + flush() + } + if (b == 10) { + flush() + } else { + super.write(b) + } + } + + override fun write(b: ByteArray) { + write(b, 0, b.size) + } + + private fun ByteArray.findSplitter(off: Int, end: Int): Int { + var o = off + while (o < end) { + if (get(o) == LN) { + return o + } + o++ + } + return -1 + } + + override fun write(b: ByteArray, off: Int, len: Int) { + val ed = off + len + if (ed > b.size || ed < 0) { + throw ArrayIndexOutOfBoundsException() + } + write0(b, off, ed) + } + + private fun write0(b: ByteArray, off: Int, end: Int) { + val size = end - off + if (size < 1) return + val spl = b.findSplitter(off, end) + if (spl == -1) { + val over = this.size - (size + count) + if (over < 0) { + // cutting + write0(b, off, end + over) + flush() + write0(b, off - over, end) + } else { + super.write(b, off, size) + } + } else { + write0(b, off, spl) + flush() + write0(b, spl + 1, end) + } + } + + override fun writeTo(out: OutputStream?) { + throw UnsupportedOperationException() + } + + override fun flush() { + logger(String(buf, 0, count, Charsets.UTF_8)) + count = 0 + } +} diff --git a/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsolePure.kt b/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsolePure.kt index f65275e19..eebb794d6 100644 --- a/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsolePure.kt +++ b/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsolePure.kt @@ -65,7 +65,7 @@ class MiraiConsolePure @JvmOverloads constructor( @JvmStatic fun MiraiConsolePure.start() = synchronized(this) { check(!started) { "mirai-console is already started and can't be restarted." } - MiraiConsoleInitializer.init(MiraiConsolePure()) + MiraiConsoleInitializer.init(this) started = true } } diff --git a/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsolePureLoader.kt b/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsolePureLoader.kt index 9db4d67b7..645e8d048 100644 --- a/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsolePureLoader.kt +++ b/frontend/mirai-console-pure/src/main/kotlin/net/mamoe/mirai/console/pure/MiraiConsolePureLoader.kt @@ -29,6 +29,7 @@ import net.mamoe.mirai.console.utils.ConsoleInternalAPI import net.mamoe.mirai.message.data.Message import net.mamoe.mirai.message.data.content import net.mamoe.mirai.utils.DefaultLogger +import java.io.PrintStream import kotlin.concurrent.thread /** @@ -43,10 +44,29 @@ object MiraiConsolePureLoader { internal fun startup() { + DefaultLogger = { MiraiConsoleFrontEndPure.loggerFor(it) } + overrideSTD() MiraiConsolePure().start() startConsoleThread() } +internal fun overrideSTD() { + System.setOut( + PrintStream( + BufferedOutputStream( + logger = DefaultLogger("sout").run { ({ line: String? -> info(line) }) } + ) + ) + ) + System.setErr( + PrintStream( + BufferedOutputStream( + logger = DefaultLogger("serr").run { ({ line: String? -> warning(line) }) } + ) + ) + ) +} + internal fun startConsoleThread() { thread(name = "Console Input") { val consoleLogger = DefaultLogger("Console")