|
@@ -7,6 +7,8 @@
|
|
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
|
|
+@file:Suppress("NOTHING_TO_INLINE")
|
|
|
|
|
+
|
|
|
package net.mamoe.mirai.utils
|
|
package net.mamoe.mirai.utils
|
|
|
|
|
|
|
|
import io.ktor.client.HttpClient
|
|
import io.ktor.client.HttpClient
|
|
@@ -15,88 +17,93 @@ import io.ktor.util.KtorExperimentalAPI
|
|
|
import kotlinx.io.pool.useInstance
|
|
import kotlinx.io.pool.useInstance
|
|
|
import net.mamoe.mirai.utils.io.ByteArrayPool
|
|
import net.mamoe.mirai.utils.io.ByteArrayPool
|
|
|
import java.io.ByteArrayOutputStream
|
|
import java.io.ByteArrayOutputStream
|
|
|
-import java.io.DataInput
|
|
|
|
|
-import java.io.EOFException
|
|
|
|
|
import java.io.InputStream
|
|
import java.io.InputStream
|
|
|
import java.net.InetAddress
|
|
import java.net.InetAddress
|
|
|
import java.security.MessageDigest
|
|
import java.security.MessageDigest
|
|
|
|
|
+import java.util.zip.Deflater
|
|
|
import java.util.zip.Inflater
|
|
import java.util.zip.Inflater
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * Ktor HttpClient. 不同平台使用不同引擎.
|
|
|
|
|
|
|
+ * 时间戳
|
|
|
*/
|
|
*/
|
|
|
-@OptIn(KtorExperimentalAPI::class)
|
|
|
|
|
-actual val Http: HttpClient
|
|
|
|
|
- get() = HttpClient(CIO)
|
|
|
|
|
|
|
+actual val currentTimeMillis: Long get() = System.currentTimeMillis()
|
|
|
|
|
|
|
|
-/**
|
|
|
|
|
- * Localhost 解析
|
|
|
|
|
- */
|
|
|
|
|
-actual fun localIpAddress(): String = runCatching {
|
|
|
|
|
- InetAddress.getLocalHost().hostAddress
|
|
|
|
|
-}.getOrElse { "192.168.1.123" }
|
|
|
|
|
|
|
+@MiraiInternalAPI
|
|
|
|
|
+actual object MiraiPlatformUtils {
|
|
|
|
|
+ actual fun unzip(data: ByteArray, offset: Int, length: Int): ByteArray {
|
|
|
|
|
+ data.checkOffsetAndLength(offset, length)
|
|
|
|
|
+ if (length == 0) return ByteArray(0)
|
|
|
|
|
|
|
|
-/**
|
|
|
|
|
- * MD5 算法
|
|
|
|
|
- *
|
|
|
|
|
- * @return 16 bytes
|
|
|
|
|
- */
|
|
|
|
|
-actual fun md5(byteArray: ByteArray, offset: Int, length: Int): ByteArray =
|
|
|
|
|
- MessageDigest.getInstance("MD5").apply { update(byteArray, offset, length) }.digest()
|
|
|
|
|
-
|
|
|
|
|
-fun InputStream.md5(): ByteArray {
|
|
|
|
|
- val digest = MessageDigest.getInstance("md5")
|
|
|
|
|
- digest.reset()
|
|
|
|
|
- this.readInSequence {
|
|
|
|
|
- digest.update(it.toByte())
|
|
|
|
|
- }
|
|
|
|
|
- return digest.digest()
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-fun DataInput.md5(): ByteArray {
|
|
|
|
|
- val digest = MessageDigest.getInstance("md5")
|
|
|
|
|
- digest.reset()
|
|
|
|
|
- val buffer = byteArrayOf(1)
|
|
|
|
|
- while (true) {
|
|
|
|
|
- try {
|
|
|
|
|
- this.readFully(buffer)
|
|
|
|
|
- } catch (e: EOFException) {
|
|
|
|
|
- break
|
|
|
|
|
|
|
+ val inflater = Inflater()
|
|
|
|
|
+ inflater.reset()
|
|
|
|
|
+ ByteArrayOutputStream().use { output ->
|
|
|
|
|
+ inflater.setInput(data, offset, length)
|
|
|
|
|
+ ByteArrayPool.useInstance {
|
|
|
|
|
+ while (!inflater.finished()) {
|
|
|
|
|
+ output.write(it, 0, inflater.inflate(it))
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ inflater.end()
|
|
|
|
|
+ return output.toByteArray()
|
|
|
}
|
|
}
|
|
|
- digest.update(buffer[0])
|
|
|
|
|
}
|
|
}
|
|
|
- return digest.digest()
|
|
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
-private inline fun InputStream.readInSequence(block: (Int) -> Unit) {
|
|
|
|
|
- var read: Int
|
|
|
|
|
- while (this.read().also { read = it } != -1) {
|
|
|
|
|
- block(read)
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-@OptIn(MiraiInternalAPI::class)
|
|
|
|
|
-actual fun ByteArray.unzip(offset: Int, length: Int): ByteArray {
|
|
|
|
|
- this.checkOffsetAndLength(offset, length)
|
|
|
|
|
- if (length == 0) return ByteArray(0)
|
|
|
|
|
-
|
|
|
|
|
- val inflater = Inflater()
|
|
|
|
|
- inflater.reset()
|
|
|
|
|
- ByteArrayOutputStream().use { output ->
|
|
|
|
|
- inflater.setInput(this, offset, length)
|
|
|
|
|
- ByteArrayPool.useInstance {
|
|
|
|
|
- while (!inflater.finished()) {
|
|
|
|
|
- output.write(it, 0, inflater.inflate(it))
|
|
|
|
|
|
|
+ actual fun zip(data: ByteArray, offset: Int, length: Int): ByteArray {
|
|
|
|
|
+ data.checkOffsetAndLength(offset, length)
|
|
|
|
|
+ if (length == 0) return ByteArray(0)
|
|
|
|
|
+
|
|
|
|
|
+ val inflater = Deflater()
|
|
|
|
|
+ inflater.reset()
|
|
|
|
|
+ ByteArrayOutputStream().use { output ->
|
|
|
|
|
+ inflater.setInput(data, offset, length)
|
|
|
|
|
+ ByteArrayPool.useInstance {
|
|
|
|
|
+ while (!inflater.finished()) {
|
|
|
|
|
+ output.write(it, 0, inflater.deflate(it))
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ inflater.end()
|
|
|
|
|
+ return output.toByteArray()
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- inflater.end()
|
|
|
|
|
- return output.toByteArray()
|
|
|
|
|
|
|
+ actual fun md5(data: ByteArray, offset: Int, length: Int): ByteArray {
|
|
|
|
|
+ data.checkOffsetAndLength(offset, length)
|
|
|
|
|
+ return MessageDigest.getInstance("MD5").apply { update(data, offset, length) }.digest()
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
-/**
|
|
|
|
|
- * 时间戳
|
|
|
|
|
- */
|
|
|
|
|
-actual val currentTimeMillis: Long get() = System.currentTimeMillis()
|
|
|
|
|
|
|
+ actual inline fun md5(str: String): ByteArray = md5(str.toByteArray())
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Ktor HttpClient. 不同平台使用不同引擎.
|
|
|
|
|
+ */
|
|
|
|
|
+ @OptIn(KtorExperimentalAPI::class)
|
|
|
|
|
+ actual val Http: HttpClient
|
|
|
|
|
+ get() = HttpClient(CIO)
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Localhost 解析
|
|
|
|
|
+ */
|
|
|
|
|
+ actual fun localIpAddress(): String = runCatching {
|
|
|
|
|
+ InetAddress.getLocalHost().hostAddress
|
|
|
|
|
+ }.getOrElse { "192.168.1.123" }
|
|
|
|
|
+
|
|
|
|
|
+ fun md5(stream: InputStream): ByteArray {
|
|
|
|
|
+ val digest = MessageDigest.getInstance("md5")
|
|
|
|
|
+ digest.reset()
|
|
|
|
|
+ stream.readInSequence {
|
|
|
|
|
+ digest.update(it.toByte())
|
|
|
|
|
+ }
|
|
|
|
|
+ return digest.digest()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ private inline fun InputStream.readInSequence(block: (Int) -> Unit) {
|
|
|
|
|
+ var read: Int
|
|
|
|
|
+ while (this.read().also { read = it } != -1) {
|
|
|
|
|
+ block(read)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|