mirai/mirai-console/frontend/mirai-console-terminal/src/BufferedOutputStream.kt

85 lines
2.2 KiB
Kotlin

/*
* Copyright 2019-2021 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/dev/LICENSE
*/
package net.mamoe.mirai.console.terminal
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,
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
}
}