mirror of
https://github.com/mamoe/mirai.git
synced 2025-04-25 13:03:35 +08:00
Make mirai-core-utils multiplatform
This commit is contained in:
parent
da06a19881
commit
924b65ba00
mirai-core-utils/src
commonMain/kotlin
Arrays.ktByteArrayPool.ktBytes.ktCheckableResult.ktCloseable.ktCollections.ktComputeOnNullMutableProperty.ktConversions.ktCoroutineUtils.ktEither.ktExceptionCollector.ktFiles.ktIO.ktLateinitMutableProperty.ktMiraiPlatformUtils.ktNumbers.ktRandomUtils.ktResources.ktResultExtensions.ktSerialization.ktSizedCache.ktStandardUtils.ktStrings.ktSymbol.ktTimeUtils.ktTypeSafeMap.ktUnsafeMutableNonNullProperty.ktsystemProp.kt
jvmBaseMain/kotlin
Collections.ktCoroutineUtils.ktCrypto.ktExceptionCollector.ktFile.ktJvmNioBuffer.ktReflections.ktResources.ktSecretsProtection.ktSerialization.ktStreams.ktThreadLocal.ktTimeUtils.ktWeakRef.ktpackage.ktsystemProp.kt
jvmBaseTest/kotlin
nativeMain/kotlin
@ -12,6 +12,9 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
public inline fun <A, reified B> Array<A>.mapToArray(block: (element: A) -> B): Array<B> {
|
||||
val result = arrayOfNulls<B>(size)
|
||||
this.forEachIndexed { index, element ->
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
@ -7,9 +7,6 @@
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("MiraiUtils")
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlinx.io.pool.DefaultPool
|
||||
|
@ -16,6 +16,10 @@ package net.mamoe.mirai.utils
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmOverloads
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
|
||||
@JvmOverloads
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
@ -11,6 +11,7 @@ package net.mamoe.mirai.utils
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import net.mamoe.mirai.utils.Either.Companion.fold
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.reflect.KType
|
||||
|
||||
@Suppress("PropertyName")
|
||||
|
17
mirai-core-utils/src/commonMain/kotlin/Closeable.kt
Normal file
17
mirai-core-utils/src/commonMain/kotlin/Closeable.kt
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
import kotlinx.io.errors.IOException
|
||||
|
||||
public expect interface Closeable {
|
||||
@Throws(IOException::class)
|
||||
public fun close()
|
||||
}
|
13
mirai-core-utils/src/commonMain/kotlin/Collections.kt
Normal file
13
mirai-core-utils/src/commonMain/kotlin/Collections.kt
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
@Suppress("FunctionName")
|
||||
public expect fun <K : Any, V> ConcurrentHashMap(): MutableMap<K, V>
|
@ -1,15 +1,17 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
* 此源代码的使用受 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
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlinx.atomicfu.atomic
|
||||
import kotlinx.atomicfu.locks.SynchronizedObject
|
||||
import kotlinx.atomicfu.locks.synchronized
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
public fun <T : Any> computeOnNullMutableProperty(initializer: () -> T): ComputeOnNullMutableProperty<T> =
|
||||
@ -28,10 +30,11 @@ private class ComputeOnNullMutablePropertyImpl<T : Any>(
|
||||
private val initializer: () -> T
|
||||
) : ComputeOnNullMutableProperty<T> {
|
||||
private val value = atomic<T?>(null)
|
||||
private val lock = SynchronizedObject()
|
||||
|
||||
override tailrec fun get(): T {
|
||||
return when (val v = this.value.value) {
|
||||
null -> synchronized(this) {
|
||||
null -> synchronized(lock) {
|
||||
if (this.value.value === null) {
|
||||
val value = this.initializer()
|
||||
// compiler inserts
|
||||
|
@ -14,6 +14,9 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/*
|
||||
* 类型转换 Utils.
|
||||
* 这些函数为内部函数, 可能会改变
|
||||
|
@ -7,8 +7,8 @@
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("MiraiUtils")
|
||||
|
||||
@file:JvmName("CoroutineUtils_common")
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
@ -17,25 +17,15 @@ import kotlinx.coroutines.sync.Semaphore
|
||||
import kotlinx.coroutines.sync.withPermit
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
@Suppress("unused", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "DeprecatedCallableAddReplaceWith")
|
||||
@Deprecated(
|
||||
message = "Use runBIO which delegates to `runInterruptible`. " +
|
||||
"Technically remove suspend call in `block` and remove CoroutineScope parameter usages.",
|
||||
level = DeprecationLevel.HIDDEN
|
||||
)
|
||||
@kotlin.internal.LowPriorityInOverloadResolution
|
||||
public suspend inline fun <R> runBIO(
|
||||
noinline block: suspend CoroutineScope.() -> R,
|
||||
): R = withContext(Dispatchers.IO, block)
|
||||
|
||||
public suspend inline fun <R> runBIO(
|
||||
public expect suspend inline fun <R> runBIO(
|
||||
noinline block: () -> R,
|
||||
): R = runInterruptible(context = Dispatchers.IO, block = block)
|
||||
): R
|
||||
|
||||
public suspend inline fun <T, R> T.runBIO(
|
||||
public expect suspend inline fun <T, R> T.runBIO(
|
||||
crossinline block: T.() -> R,
|
||||
): R = runInterruptible(context = Dispatchers.IO, block = { block() })
|
||||
): R
|
||||
|
||||
public inline fun CoroutineScope.launchWithPermit(
|
||||
semaphore: Semaphore,
|
||||
|
@ -11,6 +11,10 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlin.jvm.JvmField
|
||||
import kotlin.jvm.JvmInline
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
* Safe union of two types.
|
||||
*/
|
||||
|
@ -11,6 +11,8 @@ package net.mamoe.mirai.utils
|
||||
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.jvm.Synchronized
|
||||
import kotlin.jvm.Volatile
|
||||
|
||||
public open class ExceptionCollector {
|
||||
|
||||
@ -50,16 +52,6 @@ public open class ExceptionCollector {
|
||||
receiver.addSuppressed(e)
|
||||
}
|
||||
|
||||
private fun hash(e: Throwable): Long {
|
||||
return e.stackTrace.fold(0L) { acc, stackTraceElement ->
|
||||
acc * 31 + hash(stackTraceElement).toLongUnsigned()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hash(element: StackTraceElement): Int {
|
||||
return element.lineNumber.hashCode() xor element.className.hashCode() xor element.methodName.hashCode()
|
||||
}
|
||||
|
||||
public fun collectGet(e: Throwable?): Throwable {
|
||||
this.collect(e)
|
||||
return getLast()!!
|
||||
@ -90,7 +82,8 @@ public open class ExceptionCollector {
|
||||
@TestOnly // very slow
|
||||
public fun asSequence(): Sequence<Throwable> {
|
||||
fun Throwable.itr(): Iterator<Throwable> {
|
||||
return (sequenceOf(this) + this.suppressed.asSequence().flatMap { it.itr().asSequence() }).iterator()
|
||||
return (sequenceOf(this) + this.suppressedExceptions.asSequence()
|
||||
.flatMap { it.itr().asSequence() }).iterator()
|
||||
}
|
||||
|
||||
val last = getLast() ?: return emptySequence()
|
||||
@ -136,4 +129,6 @@ public inline fun <R> ExceptionCollector.withExceptionCollector(action: Exceptio
|
||||
collectThrow(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal expect fun hash(e: Throwable): Long
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
* 此源代码的使用受 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
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@ -12,6 +12,9 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
* 文件头和文件类型列表
|
||||
*/
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
* 此源代码的使用受 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
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@ -15,9 +15,11 @@
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlinx.io.charsets.Charset
|
||||
import kotlinx.io.charsets.Charsets
|
||||
import kotlinx.io.core.*
|
||||
import java.io.File
|
||||
import kotlin.text.String
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
public val EMPTY_BYTE_ARRAY: ByteArray = ByteArray(0)
|
||||
|
||||
@ -132,21 +134,3 @@ public inline fun Input.readString(length: Byte, charset: Charset = Charsets.UTF
|
||||
|
||||
public fun Input.readUShortLVString(): String = String(this.readUShortLVByteArray())
|
||||
public fun Input.readUShortLVByteArray(): ByteArray = this.readBytes(this.readUShort().toInt())
|
||||
|
||||
public fun File.createFileIfNotExists() {
|
||||
if (!this.exists()) {
|
||||
this.parentFile.mkdirs()
|
||||
this.createNewFile()
|
||||
}
|
||||
}
|
||||
|
||||
public fun File.resolveCreateFile(relative: String): File = this.resolve(relative).apply { createFileIfNotExists() }
|
||||
public fun File.resolveCreateFile(relative: File): File = this.resolve(relative).apply { createFileIfNotExists() }
|
||||
|
||||
public fun File.resolveMkdir(relative: String): File = this.resolve(relative).apply { mkdirs() }
|
||||
public fun File.resolveMkdir(relative: File): File = this.resolve(relative).apply { mkdirs() }
|
||||
|
||||
public fun File.touch(): File = apply {
|
||||
parentFile?.mkdirs()
|
||||
createNewFile()
|
||||
}
|
||||
|
@ -1,15 +1,17 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
* 此源代码的使用受 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
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlinx.atomicfu.atomic
|
||||
import kotlinx.atomicfu.locks.SynchronizedObject
|
||||
import kotlinx.atomicfu.locks.synchronized
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@ -24,7 +26,7 @@ public fun <T> lateinitMutableProperty(initializer: () -> T): ReadWriteProperty<
|
||||
|
||||
private class LateinitMutableProperty<T>(
|
||||
initializer: () -> T
|
||||
) : ReadWriteProperty<Any?, T> {
|
||||
) : ReadWriteProperty<Any?, T>, SynchronizedObject() {
|
||||
private val value = atomic(UNINITIALIZED)
|
||||
|
||||
private var initializer: (() -> T)? = initializer
|
||||
@ -39,7 +41,7 @@ private class LateinitMutableProperty<T>(
|
||||
this.initializer = null
|
||||
this.value.compareAndSet(UNINITIALIZED, value) // setValue prevails
|
||||
this.value.value.let {
|
||||
assert(it !== UNINITIALIZED)
|
||||
check(it !== UNINITIALIZED)
|
||||
return it as T
|
||||
}
|
||||
} else this.value.value as T
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
* 此源代码的使用受 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
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@ -12,117 +12,38 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlinx.io.core.Input
|
||||
import kotlinx.io.core.readAvailable
|
||||
import java.io.*
|
||||
import java.net.Inet4Address
|
||||
import java.security.MessageDigest
|
||||
import java.util.zip.Deflater
|
||||
import java.util.zip.GZIPInputStream
|
||||
import java.util.zip.GZIPOutputStream
|
||||
import java.util.zip.Inflater
|
||||
import kotlinx.io.core.Closeable
|
||||
import kotlinx.io.core.toByteArray
|
||||
import kotlinx.io.core.use
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
@JvmOverloads
|
||||
public fun ByteArray.unzip(offset: Int = 0, length: Int = size - offset): ByteArray {
|
||||
checkOffsetAndLength(offset, length)
|
||||
if (length == 0) return ByteArray(0)
|
||||
public expect val DEFAULT_BUFFER_SIZE: Int
|
||||
|
||||
val inflater = Inflater()
|
||||
inflater.reset()
|
||||
ByteArrayOutputStream().use { output ->
|
||||
inflater.setInput(this, offset, length)
|
||||
ByteArray(DEFAULT_BUFFER_SIZE).let {
|
||||
while (!inflater.finished()) {
|
||||
output.write(it, 0, inflater.inflate(it))
|
||||
}
|
||||
}
|
||||
public expect fun ByteArray.unzip(offset: Int = 0, length: Int = size - offset): ByteArray
|
||||
|
||||
inflater.end()
|
||||
return output.toByteArray()
|
||||
}
|
||||
}
|
||||
|
||||
public fun InputStream.md5(): ByteArray {
|
||||
return digest("md5")
|
||||
}
|
||||
|
||||
public fun InputStream.digest(algorithm: String): ByteArray {
|
||||
val digest = MessageDigest.getInstance(algorithm)
|
||||
digest.reset()
|
||||
use { input ->
|
||||
object : OutputStream() {
|
||||
override fun write(b: Int) {
|
||||
digest.update(b.toByte())
|
||||
}
|
||||
|
||||
override fun write(b: ByteArray, off: Int, len: Int) {
|
||||
digest.update(b, off, len)
|
||||
}
|
||||
}.use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
return digest.digest()
|
||||
}
|
||||
|
||||
public fun InputStream.sha1(): ByteArray {
|
||||
return digest("SHA-1")
|
||||
}
|
||||
|
||||
/**
|
||||
* Localhost 解析
|
||||
*/
|
||||
public fun localIpAddress(): String = runCatching {
|
||||
Inet4Address.getLocalHost().hostAddress
|
||||
}.getOrElse { "192.168.1.123" }
|
||||
public expect fun localIpAddress(): String
|
||||
|
||||
public fun String.md5(): ByteArray = toByteArray().md5()
|
||||
|
||||
@JvmOverloads
|
||||
public fun ByteArray.md5(offset: Int = 0, length: Int = size - offset): ByteArray {
|
||||
checkOffsetAndLength(offset, length)
|
||||
return MessageDigest.getInstance("MD5").apply { update(this@md5, offset, length) }.digest()
|
||||
}
|
||||
public expect fun ByteArray.md5(offset: Int = 0, length: Int = size - offset): ByteArray
|
||||
|
||||
public fun String.sha1(): ByteArray = toByteArray().sha1()
|
||||
|
||||
@JvmOverloads
|
||||
public fun ByteArray.sha1(offset: Int = 0, length: Int = size - offset): ByteArray {
|
||||
checkOffsetAndLength(offset, length)
|
||||
return MessageDigest.getInstance("SHA-1").apply { update(this@sha1, offset, length) }.digest()
|
||||
}
|
||||
public expect fun ByteArray.sha1(offset: Int = 0, length: Int = size - offset): ByteArray
|
||||
|
||||
@JvmOverloads
|
||||
public fun ByteArray.ungzip(offset: Int = 0, length: Int = size - offset): ByteArray {
|
||||
return GZIPInputStream(inputStream(offset, length)).use { it.readBytes() }
|
||||
}
|
||||
public expect fun ByteArray.ungzip(offset: Int = 0, length: Int = size - offset): ByteArray
|
||||
|
||||
@JvmOverloads
|
||||
public fun ByteArray.gzip(offset: Int = 0, length: Int = size - offset): ByteArray {
|
||||
ByteArrayOutputStream().use { buf ->
|
||||
GZIPOutputStream(buf).use { gzip ->
|
||||
inputStream(offset, length).use { t -> t.copyTo(gzip) }
|
||||
}
|
||||
buf.flush()
|
||||
return buf.toByteArray()
|
||||
}
|
||||
}
|
||||
public expect fun ByteArray.gzip(offset: Int = 0, length: Int = size - offset): ByteArray
|
||||
|
||||
@JvmOverloads
|
||||
public fun ByteArray.zip(offset: Int = 0, length: Int = size - offset): ByteArray {
|
||||
checkOffsetAndLength(offset, length)
|
||||
if (length == 0) return ByteArray(0)
|
||||
public expect fun ByteArray.zip(offset: Int = 0, length: Int = size - offset): ByteArray
|
||||
|
||||
val deflater = Deflater()
|
||||
deflater.setInput(this, offset, length)
|
||||
deflater.finish()
|
||||
|
||||
ByteArray(DEFAULT_BUFFER_SIZE).let {
|
||||
return it.take(deflater.deflate(it)).toByteArray().also { deflater.end() }
|
||||
}
|
||||
}
|
||||
|
||||
public inline fun <C : Closeable, R> C.withUse(block: C.() -> R): R {
|
||||
contract {
|
||||
@ -131,20 +52,6 @@ public inline fun <C : Closeable, R> C.withUse(block: C.() -> R): R {
|
||||
return use(block)
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
@JvmOverloads
|
||||
public fun Input.copyTo(out: OutputStream, bufferSize: Int = DEFAULT_BUFFER_SIZE): Long {
|
||||
var bytesCopied: Long = 0
|
||||
val buffer = ByteArray(bufferSize)
|
||||
var bytes = readAvailable(buffer)
|
||||
while (bytes >= 0) {
|
||||
out.write(buffer, 0, bytes)
|
||||
bytesCopied += bytes
|
||||
bytes = readAvailable(buffer)
|
||||
}
|
||||
return bytesCopied
|
||||
}
|
||||
|
||||
public inline fun <I : Closeable, O : Closeable, R> I.withOut(output: O, block: I.(output: O) -> R): R {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
|
@ -12,6 +12,9 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
public fun Int.toLongUnsigned(): Long = this.toLong().and(0xFFFF_FFFF)
|
||||
public fun Short.toIntUnsigned(): Int = this.toUShort().toInt()
|
||||
public fun Byte.toIntUnsigned(): Int = toInt() and 0xFF
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
* 此源代码的使用受 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
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@ -14,6 +14,8 @@
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.random.Random
|
||||
import kotlin.random.nextInt
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
@ -9,13 +9,7 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
|
||||
@TestOnly
|
||||
public fun readResource(url: String): String =
|
||||
Thread.currentThread().contextClassLoader.getResourceAsStream(url)?.readBytes()?.decodeToString()
|
||||
?: error("Could not find resource '$url'")
|
||||
import kotlinx.atomicfu.atomic
|
||||
|
||||
public class ResourceAccessLock {
|
||||
public companion object {
|
||||
@ -27,7 +21,7 @@ public class ResourceAccessLock {
|
||||
/*
|
||||
* status > 0 -> Number of holders using resource
|
||||
*/
|
||||
private val status = AtomicInteger(-1)
|
||||
private val status = atomic(-1)
|
||||
|
||||
/**
|
||||
* ```
|
||||
@ -54,7 +48,7 @@ public class ResourceAccessLock {
|
||||
public fun tryUse(): Boolean {
|
||||
val c = status
|
||||
while (true) {
|
||||
val v = c.get()
|
||||
val v = c.value
|
||||
if (v < 0) return false
|
||||
if (c.compareAndSet(v, v + 1)) return true
|
||||
}
|
||||
@ -63,7 +57,7 @@ public class ResourceAccessLock {
|
||||
public fun lockIfNotUsing(): Boolean {
|
||||
val count = this.status
|
||||
while (true) {
|
||||
val value = count.get()
|
||||
val value = count.value
|
||||
if (value != 0) return false
|
||||
if (count.compareAndSet(0, -2)) return true
|
||||
}
|
||||
@ -72,7 +66,7 @@ public class ResourceAccessLock {
|
||||
public fun release() {
|
||||
val count = this.status
|
||||
while (true) {
|
||||
val value = count.get()
|
||||
val value = count.value
|
||||
if (value < 1) throw IllegalStateException("Current resource not in using")
|
||||
|
||||
if (count.compareAndSet(value, value - 1)) return
|
||||
@ -84,11 +78,11 @@ public class ResourceAccessLock {
|
||||
}
|
||||
|
||||
public fun setInitialized() {
|
||||
status.set(INITIALIZED)
|
||||
status.value = INITIALIZED
|
||||
}
|
||||
|
||||
public fun setLocked() {
|
||||
status.set(LOCKED)
|
||||
status.value = LOCKED
|
||||
}
|
||||
|
||||
public fun setDisposed() {
|
||||
@ -96,13 +90,13 @@ public class ResourceAccessLock {
|
||||
}
|
||||
|
||||
public fun setUninitialized() {
|
||||
status.set(UNINITIALIZED)
|
||||
status.value = UNINITIALIZED
|
||||
}
|
||||
|
||||
public fun currentStatus(): Int = status.get()
|
||||
public fun currentStatus(): Int = status.value
|
||||
|
||||
override fun toString(): String {
|
||||
return when (val status = status.get()) {
|
||||
return when (val status = status.value) {
|
||||
0 -> "ResourceAccessLock(INITIALIZED)"
|
||||
-1 -> "ResourceAccessLock(UNINITIALIZED)"
|
||||
-2 -> "ResourceAccessLock(LOCKED)"
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
* 此源代码的使用受 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
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
|
@ -7,41 +7,12 @@
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("MiraiUtils")
|
||||
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlinx.serialization.BinaryFormat
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.StringFormat
|
||||
import kotlinx.serialization.descriptors.*
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import java.io.File
|
||||
|
||||
public fun <T> File.loadNotBlankAs(
|
||||
serializer: DeserializationStrategy<T>,
|
||||
stringFormat: StringFormat,
|
||||
): T? {
|
||||
if (!this.exists() || this.length() == 0L) {
|
||||
return null
|
||||
}
|
||||
return stringFormat.decodeFromString(serializer, this.readText())
|
||||
}
|
||||
|
||||
public fun <T> File.loadNotBlankAs(
|
||||
serializer: DeserializationStrategy<T>,
|
||||
binaryFormat: BinaryFormat,
|
||||
): T? {
|
||||
if (!this.exists() || this.length() == 0L) {
|
||||
return null
|
||||
}
|
||||
return binaryFormat.decodeFromByteArray(serializer, this.readBytes())
|
||||
}
|
||||
|
||||
|
||||
public fun SerialDescriptor.copy(newName: String): SerialDescriptor =
|
||||
buildClassSerialDescriptor(newName) { takeElementsFrom(this@copy) }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
@ -9,12 +9,13 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlinx.atomicfu.locks.ReentrantLock
|
||||
import kotlinx.atomicfu.locks.reentrantLock
|
||||
import kotlinx.atomicfu.locks.withLock
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
|
||||
@Suppress("unused", "UNCHECKED_CAST")
|
||||
public class SizedCache<T>(size: Int) : Iterable<T> {
|
||||
public val lock: ReentrantLock = ReentrantLock()
|
||||
public val lock: ReentrantLock = reentrantLock()
|
||||
public val data: Array<Any?> = arrayOfNulls(size)
|
||||
|
||||
public var filled: Boolean = false
|
||||
|
@ -12,9 +12,10 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import java.util.*
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
public inline fun <reified T> Any?.cast(): T {
|
||||
contract { returns() implies (this@cast is T) }
|
||||
@ -58,34 +59,6 @@ public inline fun <E> MutableList<E>.replaceAllKotlin(operator: (E) -> E) {
|
||||
}
|
||||
}
|
||||
|
||||
public fun <T> Collection<T>.asImmutable(): Collection<T> {
|
||||
return when (this) {
|
||||
is List<T> -> asImmutable()
|
||||
is Set<T> -> asImmutable()
|
||||
else -> Collections.unmodifiableCollection(this)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun <T> Collection<T>.asImmutableStrict(): Collection<T> {
|
||||
return Collections.unmodifiableCollection(this)
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun <T> List<T>.asImmutable(): List<T> {
|
||||
return Collections.unmodifiableList(this)
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun <T> Set<T>.asImmutable(): Set<T> {
|
||||
return Collections.unmodifiableSet(this)
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun <K, V> Map<K, V>.asImmutable(): Map<K, V> {
|
||||
return Collections.unmodifiableMap(this)
|
||||
}
|
||||
|
||||
public fun Throwable.getRootCause(maxDepth: Int = 20): Throwable {
|
||||
var depth = 0
|
||||
var rootCause: Throwable? = this
|
||||
@ -156,7 +129,7 @@ public inline fun Throwable.findCauseOrSelf(maxDepth: Int = 20, filter: (Throwab
|
||||
findCause(maxDepth, filter) ?: this
|
||||
|
||||
public fun String.capitalize(): String {
|
||||
return replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString() }
|
||||
return replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
|
||||
}
|
||||
|
||||
public fun String.truncated(length: Int, truncated: String = "..."): String {
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,14 +1,16 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
* 此源代码的使用受 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
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
public class Symbol private constructor(name: String) {
|
||||
private val str = "Symbol($name)"
|
||||
override fun toString(): String = str
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
* 此源代码的使用受 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
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@ -12,17 +12,15 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
import kotlin.math.floor
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.DurationUnit
|
||||
import kotlin.time.ExperimentalTime
|
||||
|
||||
/**
|
||||
* 时间戳
|
||||
*
|
||||
* @see System.currentTimeMillis
|
||||
*/
|
||||
public fun currentTimeMillis(): Long = System.currentTimeMillis()
|
||||
public expect fun currentTimeMillis(): Long
|
||||
|
||||
/**
|
||||
* 时间戳到秒
|
||||
|
@ -12,12 +12,12 @@
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.jvm.JvmInline
|
||||
|
||||
@Serializable
|
||||
@JvmInline
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
@ -9,6 +9,8 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlin.jvm.JvmField
|
||||
|
||||
public fun <T : Any> unsafeMutableNonNullPropertyOf(
|
||||
name: String = "<unknown>"
|
||||
): UnsafeMutableNonNullProperty<T> {
|
||||
@ -24,7 +26,7 @@ public class UnsafeMutableNonNullProperty<T : Any>(
|
||||
|
||||
public val isInitialized: Boolean get() = value0 !== null
|
||||
public var value: T
|
||||
get() = value0 ?: throw UninitializedPropertyAccessException("Property `$propertyName` not initialized")
|
||||
get() = value0 ?: throw IllegalStateException("Property `$propertyName` not initialized")
|
||||
set(value) {
|
||||
value0 = value
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
* 此源代码的使用受 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
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
|
||||
@ -13,18 +13,20 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
internal expect fun getProperty(name: String, default: String): String?
|
||||
|
||||
public fun systemProp(name: String, default: String): String =
|
||||
System.getProperty(name, default) ?: default
|
||||
getProperty(name, default) ?: default
|
||||
|
||||
public fun systemProp(name: String, default: Boolean): Boolean =
|
||||
System.getProperty(name, default.toString())?.toBoolean() ?: default
|
||||
getProperty(name, default.toString())?.toBoolean() ?: default
|
||||
|
||||
|
||||
public fun systemProp(name: String, default: Long): Long =
|
||||
System.getProperty(name, default.toString())?.toLongOrNull() ?: default
|
||||
getProperty(name, default.toString())?.toLongOrNull() ?: default
|
||||
|
||||
|
||||
private val debugProps = ConcurrentHashMap<String, Boolean>()
|
||||
|
46
mirai-core-utils/src/jvmBaseMain/kotlin/Collections.kt
Normal file
46
mirai-core-utils/src/jvmBaseMain/kotlin/Collections.kt
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
import java.util.*
|
||||
|
||||
|
||||
public fun <T> Collection<T>.asImmutable(): Collection<T> {
|
||||
return when (this) {
|
||||
is List<T> -> asImmutable()
|
||||
is Set<T> -> asImmutable()
|
||||
else -> Collections.unmodifiableCollection(this)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun <T> Collection<T>.asImmutableStrict(): Collection<T> {
|
||||
return Collections.unmodifiableCollection(this)
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun <T> List<T>.asImmutable(): List<T> {
|
||||
return Collections.unmodifiableList(this)
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun <T> Set<T>.asImmutable(): Set<T> {
|
||||
return Collections.unmodifiableSet(this)
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
public inline fun <K, V> Map<K, V>.asImmutable(): Map<K, V> {
|
||||
return Collections.unmodifiableMap(this)
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
public actual fun <K : Any, V> ConcurrentHashMap(): MutableMap<K, V> {
|
||||
return java.util.concurrent.ConcurrentHashMap()
|
||||
}
|
21
mirai-core-utils/src/jvmBaseMain/kotlin/CoroutineUtils.kt
Normal file
21
mirai-core-utils/src/jvmBaseMain/kotlin/CoroutineUtils.kt
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runInterruptible
|
||||
|
||||
public actual suspend inline fun <R> runBIO(
|
||||
noinline block: () -> R,
|
||||
): R = runInterruptible(context = Dispatchers.IO, block = block)
|
||||
|
||||
public actual suspend inline fun <T, R> T.runBIO(
|
||||
crossinline block: T.() -> R,
|
||||
): R = runInterruptible(context = Dispatchers.IO, block = { block() })
|
118
mirai-core-utils/src/jvmBaseMain/kotlin/Crypto.kt
Normal file
118
mirai-core-utils/src/jvmBaseMain/kotlin/Crypto.kt
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("MiraiUtils")
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlinx.io.core.use
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.net.Inet4Address
|
||||
import java.security.MessageDigest
|
||||
import java.util.zip.Deflater
|
||||
import java.util.zip.GZIPInputStream
|
||||
import java.util.zip.GZIPOutputStream
|
||||
import java.util.zip.Inflater
|
||||
|
||||
public actual val DEFAULT_BUFFER_SIZE: Int get() = kotlin.io.DEFAULT_BUFFER_SIZE
|
||||
|
||||
public actual fun ByteArray.unzip(offset: Int, length: Int): ByteArray {
|
||||
checkOffsetAndLength(offset, length)
|
||||
if (length == 0) return ByteArray(0)
|
||||
|
||||
val inflater = Inflater()
|
||||
inflater.reset()
|
||||
ByteArrayOutputStream().use { output ->
|
||||
inflater.setInput(this, offset, length)
|
||||
ByteArray(DEFAULT_BUFFER_SIZE).let {
|
||||
while (!inflater.finished()) {
|
||||
output.write(it, 0, inflater.inflate(it))
|
||||
}
|
||||
}
|
||||
|
||||
inflater.end()
|
||||
return output.toByteArray()
|
||||
}
|
||||
}
|
||||
|
||||
public actual fun localIpAddress(): String = runCatching {
|
||||
Inet4Address.getLocalHost().hostAddress
|
||||
}.getOrElse { "192.168.1.123" }
|
||||
|
||||
public fun InputStream.md5(): ByteArray {
|
||||
return digest("md5")
|
||||
}
|
||||
|
||||
public fun InputStream.digest(algorithm: String): ByteArray {
|
||||
val digest = MessageDigest.getInstance(algorithm)
|
||||
digest.reset()
|
||||
use { input ->
|
||||
object : OutputStream() {
|
||||
override fun write(b: Int) {
|
||||
digest.update(b.toByte())
|
||||
}
|
||||
|
||||
override fun write(b: ByteArray, off: Int, len: Int) {
|
||||
digest.update(b, off, len)
|
||||
}
|
||||
}.use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
return digest.digest()
|
||||
}
|
||||
|
||||
public fun InputStream.sha1(): ByteArray {
|
||||
return digest("SHA-1")
|
||||
}
|
||||
|
||||
public actual fun ByteArray.md5(offset: Int, length: Int): ByteArray {
|
||||
checkOffsetAndLength(offset, length)
|
||||
return MessageDigest.getInstance("MD5").apply { update(this@md5, offset, length) }.digest()
|
||||
}
|
||||
|
||||
|
||||
@JvmOverloads
|
||||
public actual fun ByteArray.sha1(offset: Int, length: Int): ByteArray {
|
||||
checkOffsetAndLength(offset, length)
|
||||
return MessageDigest.getInstance("SHA-1").apply { update(this@sha1, offset, length) }.digest()
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
public actual fun ByteArray.ungzip(offset: Int, length: Int): ByteArray {
|
||||
return GZIPInputStream(inputStream(offset, length)).use { it.readBytes() }
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
public actual fun ByteArray.gzip(offset: Int, length: Int): ByteArray {
|
||||
ByteArrayOutputStream().use { buf ->
|
||||
GZIPOutputStream(buf).use { gzip ->
|
||||
inputStream(offset, length).use { t -> t.copyTo(gzip) }
|
||||
}
|
||||
buf.flush()
|
||||
return buf.toByteArray()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
public actual fun ByteArray.zip(offset: Int, length: Int): ByteArray {
|
||||
checkOffsetAndLength(offset, length)
|
||||
if (length == 0) return ByteArray(0)
|
||||
|
||||
val deflater = Deflater()
|
||||
deflater.setInput(this, offset, length)
|
||||
deflater.finish()
|
||||
|
||||
ByteArray(DEFAULT_BUFFER_SIZE).let {
|
||||
return it.take(deflater.deflate(it)).toByteArray().also { deflater.end() }
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
internal actual fun hash(e: Throwable): Long {
|
||||
return e.stackTrace.fold(0L) { acc, stackTraceElement ->
|
||||
acc * 31 + hash(stackTraceElement).toLongUnsigned()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hash(element: StackTraceElement): Int {
|
||||
return element.lineNumber.hashCode() xor element.className.hashCode() xor element.methodName.hashCode()
|
||||
}
|
34
mirai-core-utils/src/jvmBaseMain/kotlin/File.kt
Normal file
34
mirai-core-utils/src/jvmBaseMain/kotlin/File.kt
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("MiraiUtils")
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import java.io.File
|
||||
|
||||
|
||||
public fun File.createFileIfNotExists() {
|
||||
if (!this.exists()) {
|
||||
this.parentFile.mkdirs()
|
||||
this.createNewFile()
|
||||
}
|
||||
}
|
||||
|
||||
public fun File.resolveCreateFile(relative: String): File = this.resolve(relative).apply { createFileIfNotExists() }
|
||||
public fun File.resolveCreateFile(relative: File): File = this.resolve(relative).apply { createFileIfNotExists() }
|
||||
|
||||
public fun File.resolveMkdir(relative: String): File = this.resolve(relative).apply { mkdirs() }
|
||||
public fun File.resolveMkdir(relative: File): File = this.resolve(relative).apply { mkdirs() }
|
||||
|
||||
public fun File.touch(): File = apply {
|
||||
parentFile?.mkdirs()
|
||||
createNewFile()
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
16
mirai-core-utils/src/jvmBaseMain/kotlin/Resources.kt
Normal file
16
mirai-core-utils/src/jvmBaseMain/kotlin/Resources.kt
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
|
||||
@TestOnly
|
||||
public fun readResource(url: String): String =
|
||||
Thread.currentThread().contextClassLoader.getResourceAsStream(url)?.readBytes()?.decodeToString()
|
||||
?: error("Could not find resource '$url'")
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
@ -13,7 +13,6 @@ import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.builtins.ByteArraySerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
import kotlinx.serialization.serializer
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.concurrent.ConcurrentLinkedDeque
|
||||
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater
|
37
mirai-core-utils/src/jvmBaseMain/kotlin/Serialization.kt
Normal file
37
mirai-core-utils/src/jvmBaseMain/kotlin/Serialization.kt
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
import kotlinx.serialization.BinaryFormat
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.StringFormat
|
||||
import java.io.File
|
||||
|
||||
|
||||
public fun <T> File.loadNotBlankAs(
|
||||
serializer: DeserializationStrategy<T>,
|
||||
stringFormat: StringFormat,
|
||||
): T? {
|
||||
if (!this.exists() || this.length() == 0L) {
|
||||
return null
|
||||
}
|
||||
return stringFormat.decodeFromString(serializer, this.readText())
|
||||
}
|
||||
|
||||
public fun <T> File.loadNotBlankAs(
|
||||
serializer: DeserializationStrategy<T>,
|
||||
binaryFormat: BinaryFormat,
|
||||
): T? {
|
||||
if (!this.exists() || this.length() == 0L) {
|
||||
return null
|
||||
}
|
||||
return binaryFormat.decodeFromByteArray(serializer, this.readBytes())
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
12
mirai-core-utils/src/jvmBaseMain/kotlin/TimeUtils.kt
Normal file
12
mirai-core-utils/src/jvmBaseMain/kotlin/TimeUtils.kt
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
public actual fun currentTimeMillis(): Long = System.currentTimeMillis()
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
* Copyright 2019-2022 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.
|
||||
* 此源代码的使用受 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
|
||||
* https://github.com/mamoe/mirai/blob/dev/LICENSE
|
||||
*/
|
||||
|
||||
@file:JvmMultifileClass
|
9
mirai-core-utils/src/jvmBaseMain/kotlin/package.kt
Normal file
9
mirai-core-utils/src/jvmBaseMain/kotlin/package.kt
Normal file
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
12
mirai-core-utils/src/jvmBaseMain/kotlin/systemProp.kt
Normal file
12
mirai-core-utils/src/jvmBaseMain/kotlin/systemProp.kt
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
internal actual fun getProperty(name: String, default: String): String? = System.getProperty(name, default)
|
10
mirai-core-utils/src/jvmBaseTest/kotlin/package.kt
Normal file
10
mirai-core-utils/src/jvmBaseTest/kotlin/package.kt
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
17
mirai-core-utils/src/nativeMain/kotlin/Closeable.kt
Normal file
17
mirai-core-utils/src/nativeMain/kotlin/Closeable.kt
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
import kotlinx.io.errors.IOException
|
||||
|
||||
public actual interface Closeable {
|
||||
@Throws(IOException::class)
|
||||
public actual fun close()
|
||||
}
|
15
mirai-core-utils/src/nativeMain/kotlin/ConcurrentHashMap.kt
Normal file
15
mirai-core-utils/src/nativeMain/kotlin/ConcurrentHashMap.kt
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
@Suppress("FunctionName")
|
||||
public actual fun <K : Any, V> ConcurrentHashMap(): MutableMap<K, V> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
70
mirai-core-utils/src/nativeMain/kotlin/CoroutineUtils.kt
Normal file
70
mirai-core-utils/src/nativeMain/kotlin/CoroutineUtils.kt
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
public actual suspend inline fun <R> runBIO(noinline block: () -> R): R {
|
||||
return block()
|
||||
}
|
||||
|
||||
public actual suspend inline fun <T, R> T.runBIO(crossinline block: T.() -> R): R {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
/**
|
||||
* For code
|
||||
* ```
|
||||
* try {
|
||||
* job(new)
|
||||
* } catch (e: Throwable) {
|
||||
* throw IllegalStateException("Exception in attached Job '$name'", e.unwrapCancellationException())
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Original stacktrace, you mainly see `StateSwitchingException` which is useless to locate the code where real cause `ForceOfflineException` is thrown.
|
||||
* ```
|
||||
* Exception in thread "DefaultDispatcher-worker-1 @BotInitProcessor.init#7" java.lang.IllegalStateException: Exception in attached Job 'BotInitProcessor.init'
|
||||
* at net.mamoe.mirai.internal.network.handler.state.JobAttachStateObserver$stateChanged0$1.invokeSuspend(JobAttachStateObserver.kt:40)
|
||||
* at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
|
||||
* at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
|
||||
* Caused by: StateSwitchingException(old=StateLoading, new=StateClosed, cause=net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException: Closed by MessageSvc.PushForceOffline: net.mamoe.mirai.internal.network.protocol.data.jce.RequestPushForceOffline@4abf6d30)
|
||||
* at net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport.setStateImpl$mirai_core(NetworkHandlerSupport.kt:258)
|
||||
* at net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandler.close(NettyNetworkHandler.kt:404)
|
||||
* ```
|
||||
*
|
||||
* Real stacktrace (with [unwrapCancellationException]), you directly have `ForceOfflineException`, also you wont lose information of `StateSwitchingException`
|
||||
* ```
|
||||
* Exception in thread "DefaultDispatcher-worker-2 @BotInitProcessor.init#7" java.lang.IllegalStateException: Exception in attached Job 'BotInitProcessor.init'
|
||||
* at net.mamoe.mirai.internal.network.handler.state.JobAttachStateObserver$stateChanged0$1.invokeSuspend(JobAttachStateObserver.kt:40)
|
||||
* at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
|
||||
* at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
|
||||
* at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
|
||||
* Caused by: net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException: Closed by MessageSvc.PushForceOffline: net.mamoe.mirai.internal.network.protocol.data.jce.RequestPushForceOffline@62f65f94
|
||||
* at net.mamoe.mirai.utils.MiraiUtils__CoroutineUtilsKt.unwrapCancellationException(CoroutineUtils.kt:141)
|
||||
* at net.mamoe.mirai.utils.MiraiUtils.unwrapCancellationException(Unknown Source)
|
||||
* ... 7 more
|
||||
* Suppressed: StateSwitchingException(old=StateLoading, new=StateClosed, cause=net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException: Closed by MessageSvc.PushForceOffline: net.mamoe.mirai.internal.network.protocol.data.jce.RequestPushForceOffline@62f65f94)
|
||||
* at net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport.setStateImpl$mirai_core(NetworkHandlerSupport.kt:258)
|
||||
* at net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandler.close(NettyNetworkHandler.kt:404)
|
||||
* ```
|
||||
*/
|
||||
@Suppress("unused")
|
||||
public actual inline fun <reified E> Throwable.unwrap(): Throwable {
|
||||
if (this !is E) return this
|
||||
return this.findCause { it !is E }
|
||||
?.also { it.addSuppressed(this) }
|
||||
?: this
|
||||
}
|
40
mirai-core-utils/src/nativeMain/kotlin/Crypto.kt
Normal file
40
mirai-core-utils/src/nativeMain/kotlin/Crypto.kt
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
|
||||
public actual fun ByteArray.unzip(offset: Int, length: Int): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
public actual fun localIpAddress(): String = "192.168.1.123"
|
||||
|
||||
|
||||
public actual fun ByteArray.md5(offset: Int, length: Int): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
public actual val DEFAULT_BUFFER_SIZE: Int get() = 8192
|
||||
|
||||
public actual fun ByteArray.sha1(offset: Int, length: Int): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
public actual fun ByteArray.ungzip(offset: Int, length: Int): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
public actual fun ByteArray.gzip(offset: Int, length: Int): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
public actual fun ByteArray.zip(offset: Int, length: Int): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
}
|
15
mirai-core-utils/src/nativeMain/kotlin/ExceptionCollector.kt
Normal file
15
mirai-core-utils/src/nativeMain/kotlin/ExceptionCollector.kt
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
internal actual fun hash(e: Throwable): Long {
|
||||
// Stacktrace analysis not available
|
||||
return e.hashCode().toLongUnsigned()
|
||||
}
|
19
mirai-core-utils/src/nativeMain/kotlin/currentTimeMillis.kt
Normal file
19
mirai-core-utils/src/nativeMain/kotlin/currentTimeMillis.kt
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
/**
|
||||
* 时间戳
|
||||
*
|
||||
* @see System.currentTimeMillis
|
||||
*/
|
||||
public actual fun currentTimeMillis(): Long {
|
||||
TODO("Not yet implemented")
|
||||
}
|
14
mirai-core-utils/src/nativeMain/kotlin/getProperty.kt
Normal file
14
mirai-core-utils/src/nativeMain/kotlin/getProperty.kt
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
internal actual fun getProperty(name: String, default: String): String? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
26
mirai-core-utils/src/nativeMain/kotlin/loadServiceOrNull.kt
Normal file
26
mirai-core-utils/src/nativeMain/kotlin/loadServiceOrNull.kt
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2019-2022 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.utils
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
public actual fun <T : Any> loadServiceOrNull(
|
||||
clazz: KClass<out T>,
|
||||
fallbackImplementation: String?
|
||||
): T? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
public actual fun <T : Any> loadService(
|
||||
clazz: KClass<out T>,
|
||||
fallbackImplementation: String?
|
||||
): T {
|
||||
TODO("Not yet implemented")
|
||||
}
|
Loading…
Reference in New Issue
Block a user