Fix unresolved KDoc reference

This commit is contained in:
Him188 2019-11-15 10:41:26 +08:00
parent ee7d3a7e1a
commit 20ea49b090
8 changed files with 111 additions and 136 deletions

View File

@ -174,7 +174,7 @@ inline class Image(inline val id: ImageId) : Message {
* 对于好友, [value] 类似于 `/01ee6426-5ff1-4cf0-8278-e8634d2909ef`, 由服务器返回. * 对于好友, [value] 类似于 `/01ee6426-5ff1-4cf0-8278-e8634d2909ef`, 由服务器返回.
* *
* @see ExternalImage.groupImageId 群图片的 [ImageId] 获取 * @see ExternalImage.groupImageId 群图片的 [ImageId] 获取
* @see FriendImageIdRequestPacket.Response.imageId 好友图片的 [ImageId] 获取 * @see FriendImageIdRequestPacket.Response.RequireUpload.imageId 好友图片的 [ImageId] 获取
*/ */
inline class ImageId(inline val value: String) inline class ImageId(inline val value: String)

View File

@ -5,7 +5,9 @@ import kotlinx.io.core.IoBuffer
import kotlinx.io.pool.useInstance import kotlinx.io.pool.useInstance
import net.mamoe.mirai.network.protocol.tim.packet.Decrypter import net.mamoe.mirai.network.protocol.tim.packet.Decrypter
import net.mamoe.mirai.network.protocol.tim.packet.DecrypterByteArray import net.mamoe.mirai.network.protocol.tim.packet.DecrypterByteArray
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.ByteArrayPool
import net.mamoe.mirai.utils.io.toByteArray
import net.mamoe.mirai.utils.io.toUHexString
import kotlin.experimental.and import kotlin.experimental.and
import kotlin.experimental.xor import kotlin.experimental.xor
import kotlin.jvm.JvmStatic import kotlin.jvm.JvmStatic
@ -30,15 +32,6 @@ fun ByteArray.encryptBy(key: ByteArray, length: Int = this.size): ByteArray = TE
fun ByteArray.encryptBy(key: DecrypterByteArray, length: Int = this.size): ByteArray = TEA.encrypt(this, key.value, sourceLength = length) fun ByteArray.encryptBy(key: DecrypterByteArray, length: Int = this.size): ByteArray = TEA.encrypt(this, key.value, sourceLength = length)
/**
* 通过 [String.hexToBytes] [keyHex] 转为 [ByteArray] 后用它解密 [this].
* 将会使用 [HexCache]
*
* @param keyHex 长度至少为 16 bytes
* @throws DecryptionFailedException 解密错误时
*/
fun ByteArray.encryptBy(keyHex: String, length: Int = this.size): ByteArray = encryptBy(keyHex.hexToBytes(withCache = true), length = length)
/** /**
* [ByteArrayPool] 缓存 [this], 然后使用 [key] 加密. * [ByteArrayPool] 缓存 [this], 然后使用 [key] 加密.
* *
@ -83,15 +76,6 @@ fun ByteArray.decryptBy(key: IoBuffer, length: Int = this.size): ByteArray {
} }
} }
/**
* 通过 [String.hexToBytes] [keyHex] 转为 [ByteArray] 后用它解密 [this]
* 将会使用 [HexCache]
*
* @param keyHex 长度至少为 16 bytes
* @throws DecryptionFailedException 解密错误时
*/
fun ByteArray.decryptBy(keyHex: String, length: Int = this.size): ByteArray = decryptBy(keyHex.hexToBytes(withCache = true), length = length)
/** /**
* [ByteArrayPool] 缓存 [this], 然后使用 [key] 解密. * [ByteArrayPool] 缓存 [this], 然后使用 [key] 解密.
* *
@ -106,16 +90,6 @@ fun IoBuffer.decryptBy(key: ByteArray, offset: Int = 0, length: Int = readRemain
} }
} }
/**
* [ByteArrayPool] 缓存 [this], 然后使用 [keyHex] 解密.
*
* @param keyHex 长度至少为 16
* @throws DecryptionFailedException 解密错误时
*/
fun IoBuffer.decryptBy(keyHex: String, offset: Int = 0, length: Int = readRemaining - offset): ByteArray =
decryptBy(keyHex.hexToBytes(withCache = true), offset = offset, length = length)
// endregion // endregion
// region ByteReadPacket extension // region ByteReadPacket extension
@ -126,8 +100,6 @@ fun ByteReadPacket.decryptBy(key: IoBuffer): ByteReadPacket = decryptAsByteArray
fun ByteReadPacket.decryptBy(key: Decrypter): ByteReadPacket = key.decrypt(this) fun ByteReadPacket.decryptBy(key: Decrypter): ByteReadPacket = key.decrypt(this)
fun ByteReadPacket.decryptBy(keyHex: String): ByteReadPacket = decryptBy(keyHex.hexToBytes())
inline fun <R> ByteReadPacket.decryptAsByteArray(key: ByteArray, consumer: (ByteArray) -> R): R = inline fun <R> ByteReadPacket.decryptAsByteArray(key: ByteArray, consumer: (ByteArray) -> R): R =
ByteArrayPool.useInstance { ByteArrayPool.useInstance {
val length = remaining.toInt() val length = remaining.toInt()
@ -135,9 +107,6 @@ inline fun <R> ByteReadPacket.decryptAsByteArray(key: ByteArray, consumer: (Byte
consumer(it.decryptBy(key, length)) consumer(it.decryptBy(key, length))
}.also { close() } }.also { close() }
inline fun <R> ByteReadPacket.decryptAsByteArray(keyHex: String, consumer: (ByteArray) -> R): R =
this.decryptAsByteArray(keyHex.hexToBytes(), consumer)
inline fun <R> ByteReadPacket.decryptAsByteArray(key: IoBuffer, consumer: (ByteArray) -> R): R = inline fun <R> ByteReadPacket.decryptAsByteArray(key: IoBuffer, consumer: (ByteArray) -> R): R =
ByteArrayPool.useInstance { ByteArrayPool.useInstance {
val length = remaining.toInt() val length = remaining.toInt()

View File

@ -1,11 +1,12 @@
@file:Suppress("ObjectPropertyName", "MayBeConstant", "NonAsciiCharacters", "SpellCheckingInspection", "unused") @file:Suppress("ObjectPropertyName", "MayBeConstant", "NonAsciiCharacters", "SpellCheckingInspection", "unused")
package net.mamoe.mirai.utils.io package net.mamoe.mirai.utils.internal
import kotlinx.io.core.toByteArray import kotlinx.io.core.toByteArray
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.utils.io.toUHexString
import kotlin.math.max import kotlin.math.max
import kotlin.reflect.KProperty import kotlin.reflect.KProperty0
/** /**
* 匹配已知 hex 常量并格式化后打印到控制台. * 匹配已知 hex 常量并格式化后打印到控制台.
@ -19,7 +20,7 @@ internal fun String.printColorize(ignoreUntilFirstConst: Boolean): String = with
* *
* 低效率, 仅调试使用. * 低效率, 仅调试使用.
*/ */
internal fun printCompareHex(hex1s: String, hex2s: String): String = with(HexComparator) { compare(hex1s, hex2s) } fun printCompareHex(hex1s: String, hex2s: String): String = with(HexComparator) { compare(hex1s.toUpperCase(), hex2s.toUpperCase()) }
data class NamedHexElement( data class NamedHexElement(
val name: String, val name: String,
@ -35,8 +36,8 @@ private fun LinkedHashSet<NamedHexElement>.initConstFileds() {
TIMProtocol, TIMProtocol,
PacketIds PacketIds
).forEach { obj -> ).forEach { obj ->
obj::class.members.filterIsInstance<KProperty<*>>().forEach { property -> obj::class.members.filterIsInstance<KProperty0<*>>().forEach { property ->
add(NamedHexElement(property.name, property.getter.call().toString())) property.get()?.let { add(NamedHexElement(property.name, it.toString())) }
} }
} }
} }
@ -107,9 +108,14 @@ private object HexComparator {
private class Match internal constructor(val range: IntRange, val constName: String) private class Match internal constructor(val range: IntRange, val constName: String)
init { init {
TIMProtocol::class.members.filterIsInstance<KProperty<*>>().forEach { CONST_FIELDS.forEach { (name, value) ->
for (match in match(hex, it.getter.call().toString())) { for (match in match(hex, value)) {
matches.add(Match(match, it.getter.call().toString())) matches.add(Match(match, name))
}
}
TIMProtocol::class.members.filterIsInstance<KProperty0<*>>().mapNotNull { it()?.toString() }.forEach {
for (match in match(hex, it)) {
matches.add(Match(match, it))
} }
} }
} }
@ -118,10 +124,10 @@ private object HexComparator {
val CONST_FIELDS: Set<NamedHexElement> = linkedSetOf<NamedHexElement>().apply { initConstFileds() } val CONST_FIELDS: Set<NamedHexElement> = linkedSetOf<NamedHexElement>().apply { initConstFileds() }
} }
private fun match(hex: String, field: String): Set<IntRange> { private fun match(hex: String, value: String): Set<IntRange> {
val constValue: String val constValue: String
try { try {
constValue = field.trim { it <= ' ' } constValue = value.trim { it <= ' ' }
if (constValue.length / 3 <= 3) {//Minimum numbers of const hex bytes if (constValue.length / 3 <= 3) {//Minimum numbers of const hex bytes
return linkedSetOf() return linkedSetOf()
} }

View File

@ -3,6 +3,8 @@ package net.mamoe.mirai.utils.io
import kotlinx.io.core.* import kotlinx.io.core.*
import net.mamoe.mirai.utils.DefaultLogger import net.mamoe.mirai.utils.DefaultLogger
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.internal.printColorize
import net.mamoe.mirai.utils.internal.printCompareHex
internal object DebugLogger : MiraiLogger by DefaultLogger("Packet Debug") internal object DebugLogger : MiraiLogger by DefaultLogger("Packet Debug")
@ -62,7 +64,7 @@ internal fun BytePacketBuilder.debugPrintThis(name: String = "") {
} }
internal fun String.printStringFromHex() { internal fun String.printStringFromHex() {
println(this.hexToBytes().stringOfWitch()) println(this.hexToBytes().encodeToString())
} }
internal fun ByteArray.printColorizedHex(name: String = "", ignoreUntilFirstConst: Boolean = false, compareTo: String? = null) { internal fun ByteArray.printColorizedHex(name: String = "", ignoreUntilFirstConst: Boolean = false, compareTo: String? = null) {

View File

@ -3,6 +3,8 @@
package net.mamoe.mirai.utils.io package net.mamoe.mirai.utils.io
import kotlinx.io.core.* import kotlinx.io.core.*
import kotlinx.io.pool.useInstance
import kotlin.jvm.JvmName
fun ByteReadPacket.readRemainingBytes( fun ByteReadPacket.readRemainingBytes(
@ -23,8 +25,12 @@ fun Input.readIP(): String = buildString(4 + 3) {
} }
} }
fun Input.readUVarIntLVString(): String = String(this.readUVarIntByteArray())
fun Input.readUShortLVString(): String = String(this.readUShortLVByteArray()) fun Input.readUShortLVString(): String = String(this.readUShortLVByteArray())
fun Input.readUVarIntByteArray(): ByteArray = this.readBytes(this.readUVarInt().toInt())
fun Input.readUShortLVByteArray(): ByteArray = this.readBytes(this.readUShort().toInt()) fun Input.readUShortLVByteArray(): ByteArray = this.readBytes(this.readUShort().toInt())
private inline fun <R> inline(block: () -> R): R = block() private inline fun <R> inline(block: () -> R): R = block()
@ -63,7 +69,33 @@ fun Input.readTLVMap(expectingEOF: Boolean = false, tagSize: Int = 1): MutableMa
fun Map<*, ByteArray>.printTLVMap(name: String) = fun Map<*, ByteArray>.printTLVMap(name: String) =
debugPrintln("TLVMap $name= " + this.mapValues { (_, value) -> value.toUHexString() }) debugPrintln("TLVMap $name= " + this.mapValues { (_, value) -> value.toUHexString() })
fun Input.readString(length: Number): String = String(this.readBytes(length.toInt())) fun Input.readString(length: Int): String = String(this.readBytes(length))
fun Input.readString(length: Long): String = String(this.readBytes(length.toInt()))
fun Input.readString(length: Short): String = String(this.readBytes(length.toInt()))
fun Input.readString(length: UShort): String = String(this.readBytes(length.toInt()))
fun Input.readString(length: Byte): String = String(this.readBytes(length.toInt()))
fun Input.readStringUntil(stopSignalExclude: UByte, expectingEOF: Boolean = false): String = readStringUntil(stopSignalExclude.toByte(), expectingEOF)
// TODO 应标记 JvmSynthetic 但 kotlin 有bug
@JvmName("readStringUntil0")
fun Input.readStringUntil(stopSignalExclude: Byte, expectingEOF: Boolean = false): String {
ByteArrayPool.useInstance {
var count = 0
val buffer = byteArrayOf(1)
while (readAvailable(buffer, 1) == 1) {
if (buffer[0] == stopSignalExclude) {
return buffer.encodeToString()
}
it[count++] = buffer[0]
}
if (!expectingEOF) {
throw EOFException("Early EOF")
}
return buffer.encodeToString()
}
}
private const val TRUE_BYTE_VALUE: Byte = 1 private const val TRUE_BYTE_VALUE: Byte = 1
fun Input.readBoolean(): Boolean = this.readByte() == TRUE_BYTE_VALUE fun Input.readBoolean(): Boolean = this.readByte() == TRUE_BYTE_VALUE

View File

@ -29,38 +29,33 @@ fun BytePacketBuilder.writeShortLVByteArray(byteArray: ByteArray) {
this.writeFully(byteArray) this.writeFully(byteArray)
} }
fun BytePacketBuilder.writeShortLVPacket(tag: UByte? = null, lengthOffset: ((Long) -> Long)? = null, builder: BytePacketBuilder.() -> Unit) = fun BytePacketBuilder.writeShortLVPacket(tag: UByte? = null, lengthOffset: ((Long) -> Long)? = null, builder: BytePacketBuilder.() -> Unit) =
with(BytePacketBuilder().apply(builder).build()) { BytePacketBuilder().apply(builder).build().use {
if (tag != null) { if (tag != null) writeUByte(tag)
writeUByte(tag) writeUShort((lengthOffset?.invoke(it.remaining) ?: it.remaining).coerceAtMostOrFail(0xFFFFL).toUShort())
} writePacket(it)
writeUShort((lengthOffset?.invoke(remaining) ?: remaining).coerceAtMostOrFail(0xFFFFL).toUShort())
writePacket(this)
this.release()
} }
fun BytePacketBuilder.writeUVarintLVPacket(tag: UByte? = null, lengthOffset: ((Long) -> Long)? = null, builder: BytePacketBuilder.() -> Unit) = fun BytePacketBuilder.writeUVarIntLVPacket(tag: UByte? = null, lengthOffset: ((Long) -> Long)? = null, builder: BytePacketBuilder.() -> Unit) =
with(BytePacketBuilder().apply(builder).build()) { BytePacketBuilder().apply(builder).build().use {
if (tag != null) { if (tag != null) writeUByte(tag)
writeUByte(tag) writeUVarInt((lengthOffset?.invoke(it.remaining) ?: it.remaining).coerceAtMostOrFail(0xFFFFL))
} writePacket(it)
writeUVarInt((lengthOffset?.invoke(remaining) ?: remaining).coerceAtMostOrFail(0xFFFFL))
writePacket(this)
this.release()
} }
@Suppress("DEPRECATION") fun BytePacketBuilder.writeShortLVString(str: String) = writeShortLVByteArray(str.toByteArray())
fun BytePacketBuilder.writeShortLVString(str: String) = this.writeShortLVByteArray(str.toByteArray())
@Suppress("DEPRECATION")
fun BytePacketBuilder.writeLVHex(hex: String) = this.writeShortLVByteArray(hex.hexToBytes())
fun BytePacketBuilder.writeIP(ip: String) = writeFully(ip.trim().split(".").map { it.toUByte() }.toUByteArray()) fun BytePacketBuilder.writeIP(ip: String) = writeFully(ip.trim().split(".").map { it.toUByte() }.toUByteArray())
fun BytePacketBuilder.writeTime() = this.writeInt(currentTime.toInt()) fun BytePacketBuilder.writeTime() = this.writeInt(currentTime.toInt())
fun BytePacketBuilder.writeHex(uHex: String) = this.writeFully(uHex.hexToUBytes()) fun BytePacketBuilder.writeHex(uHex: String) {
uHex.split(" ").forEach {
if (it.isNotBlank()) {
writeUByte(it.toUByte(16))
}
}
}
fun BytePacketBuilder.writeTLV(tag: UByte, values: UByteArray) { fun BytePacketBuilder.writeTLV(tag: UByte, values: UByteArray) {
writeUByte(tag) writeUByte(tag)
@ -81,6 +76,11 @@ fun BytePacketBuilder.writeTHex(tag: UByte, uHex: String) {
fun BytePacketBuilder.writeTV(tagValue: UShort) = writeUShort(tagValue) fun BytePacketBuilder.writeTV(tagValue: UShort) = writeUShort(tagValue)
fun BytePacketBuilder.writeTV(tag: UByte, value: UByte) {
writeUByte(tag)
writeUByte(value)
}
fun BytePacketBuilder.writeTUbyte(tag: UByte, value: UByte) { fun BytePacketBuilder.writeTUbyte(tag: UByte, value: UByte) {
this.writeUByte(tag) this.writeUByte(tag)
this.writeUByte(value) this.writeUByte(value)
@ -124,7 +124,7 @@ fun BytePacketBuilder.writeTLV0006(qq: UInt, password: String, loginTime: Int, l
writeRandom(4) writeRandom(4)
writeHex("00 02") writeHex("00 02")
writeQQ(qq) writeQQ(qq)
writeHex(TIMProtocol.constantData2) writeFully(TIMProtocol.constantData2)
writeHex("00 00 01") writeHex("00 00 01")
writeFully(firstMD5) writeFully(firstMD5)
@ -151,5 +151,5 @@ fun BytePacketBuilder.writeDeviceName(random: Boolean) {
} }
this.writeShort((deviceName.length + 2).toShort()) this.writeShort((deviceName.length + 2).toShort())
this.writeShort(deviceName.length.toShort()) this.writeShort(deviceName.length.toShort())
this.writeStringUtf8(deviceName)//TODO TEST? this.writeStringUtf8(deviceName)
} }

View File

@ -5,7 +5,6 @@ package net.mamoe.mirai.utils.io
import kotlinx.io.core.IoBuffer import kotlinx.io.core.IoBuffer
import kotlinx.io.core.writeFully import kotlinx.io.core.writeFully
import kotlinx.io.pool.ObjectPool import kotlinx.io.pool.ObjectPool
import kotlin.jvm.Synchronized
import kotlin.random.Random import kotlin.random.Random
import kotlin.random.nextInt import kotlin.random.nextInt
@ -75,9 +74,8 @@ fun Byte.toUHexString(): String = this.toUByte().toString(16).toUpperCase().let
/** /**
* 将无符号 Hex 转为 [ByteArray], 有根据 hex [hashCode] 建立的缓存. * 将无符号 Hex 转为 [ByteArray], 有根据 hex [hashCode] 建立的缓存.
*/ */
fun String.hexToBytes(withCache: Boolean = true): ByteArray = fun String.hexToBytes(): ByteArray =
if (withCache) HexCache.getCacheOrConvert(this) this.split(" ")
else this.split(" ")
.filterNot { it.isEmpty() } .filterNot { it.isEmpty() }
.map { s -> s.toUByte(16).toByte() } .map { s -> s.toUByte(16).toByte() }
.toByteArray() .toByteArray()
@ -85,9 +83,8 @@ fun String.hexToBytes(withCache: Boolean = true): ByteArray =
/** /**
* 将无符号 Hex 转为 [UByteArray], 有根据 hex [hashCode] 建立的缓存. * 将无符号 Hex 转为 [UByteArray], 有根据 hex [hashCode] 建立的缓存.
*/ */
fun String.hexToUBytes(withCache: Boolean = true): UByteArray = fun String.hexToUBytes(): UByteArray =
if (withCache) HexCache.getUCacheOrConvert(this) this.split(" ")
else this.split(" ")
.filterNot { it.isEmpty() } .filterNot { it.isEmpty() }
.map { s -> s.toUByte(16) } .map { s -> s.toUByte(16) }
.toUByteArray() .toUByteArray()
@ -130,37 +127,3 @@ fun ByteArray.toUInt(): UInt =
* 注意回收 ([ObjectPool.recycle]) * 注意回收 ([ObjectPool.recycle])
*/ */
fun ByteArray.toIoBuffer(): IoBuffer = IoBuffer.Pool.borrow().let { it.writeFully(this); it } fun ByteArray.toIoBuffer(): IoBuffer = IoBuffer.Pool.borrow().let { it.writeFully(this); it }
/**
* Hex 转换 [ByteArray] [UByteArray] 缓存.
* [net.mamoe.mirai.network.protocol.tim.TIMProtocol] hex 常量使用
*/
internal object HexCache {
private val hexToByteArrayCacheMap: MutableMap<Int, ByteArray> = mutableMapOf()
@Synchronized
internal fun getCacheOrConvert(hex: String): ByteArray = hex.hashCode().let { id ->
if (hexToByteArrayCacheMap.containsKey(id)) {
return hexToByteArrayCacheMap[id]!!
} else {
hex.hexToBytes(withCache = false).let {
hexToByteArrayCacheMap[id] = it
return it
}
}
}
private val hexToUByteArrayCacheMap: MutableMap<Int, UByteArray> = mutableMapOf()
@Synchronized
internal fun getUCacheOrConvert(hex: String): UByteArray = hex.hashCode().let { id ->
if (hexToUByteArrayCacheMap.containsKey(id)) {
return hexToUByteArrayCacheMap[id]!!
} else {
hex.hexToUBytes(withCache = false).let {
hexToUByteArrayCacheMap[id] = it
return it
}
}
}
}

View File

@ -1,12 +1,13 @@
@file:JvmName("Varint") @file:JvmName("Varint")
@file:Suppress("EXPERIMENTAL_API_USAGE") @file:Suppress("EXPERIMENTAL_API_USAGE")
package net.mamoe.mirai.utils package net.mamoe.mirai.utils.io
import kotlinx.io.core.BytePacketBuilder import kotlinx.io.core.Input
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.Output
import kotlin.experimental.or import kotlin.experimental.or
import kotlin.jvm.JvmName import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
/** /**
* Tool class for VarInt or VarLong operations. * Tool class for VarInt or VarLong operations.
@ -17,70 +18,72 @@ import kotlin.jvm.JvmName
* @author lmlstarqaq of Nukkit Project * @author lmlstarqaq of Nukkit Project
*/ */
fun encodeZigZag32(signedInt: Int): Long { internal fun encodeZigZag32(signedInt: Int): Long {
return (signedInt shl 1 xor (signedInt shr 31)).toLong() return (signedInt shl 1 xor (signedInt shr 31)).toLong()
} }
@JvmSynthetic
//@JvmSynthetic internal fun decodeZigZag32(uint: UInt): Int {
fun decodeZigZag32(uint: UInt): Int {
return decodeZigZag32(uint.toLong()) return decodeZigZag32(uint.toLong())
} }
fun decodeZigZag32(uint: Long): Int { internal fun decodeZigZag32(uint: Long): Int {
return (uint shr 1).toInt() xor -(uint and 1).toInt() return (uint shr 1).toInt() xor -(uint and 1).toInt()
} }
fun encodeZigZag64(signedLong: Long): Long { internal fun encodeZigZag64(signedLong: Long): Long {
return signedLong shl 1 xor (signedLong shr 63) return signedLong shl 1 xor (signedLong shr 63)
} }
fun decodeZigZag64(signedLong: Long): Long { internal fun decodeZigZag64(signedLong: Long): Long {
return signedLong.ushr(1) xor -(signedLong and 1) return signedLong.ushr(1) xor -(signedLong and 1)
} }
fun ByteReadPacket.readVarInt(): Int { fun Input.readVarInt(): Int {
return decodeZigZag32(this.readUnsignedVarInt()) return decodeZigZag32(this.readUVarInt())
} }
fun ByteReadPacket.readUnsignedVarInt(): UInt { @JvmSynthetic
fun Input.readUVarInt(): UInt {
return read(this, 5).toUInt() return read(this, 5).toUInt()
} }
fun ByteReadPacket.readVarLong(): Long { fun Input.readVarLong(): Long {
return decodeZigZag64(readUnsignedVarLong().toLong()) return decodeZigZag64(readUVarLong().toLong())
} }
fun ByteReadPacket.readUnsignedVarLong(): ULong { @JvmSynthetic
fun Input.readUVarLong(): ULong {
return read(this, 10).toULong() return read(this, 10).toULong()
} }
fun BytePacketBuilder.writeVarInt(signedInt: Int) { fun Output.writeVarInt(signedInt: Int) {
this.writeUVarInt(encodeZigZag32(signedInt)) this.writeUVarInt(encodeZigZag32(signedInt))
} }
fun BytePacketBuilder.writeUVarInt(uint: UInt) { @JvmSynthetic
fun Output.writeUVarInt(uint: UInt) {
return writeUVarInt(uint.toLong()) return writeUVarInt(uint.toLong())
} }
fun BytePacketBuilder.writeUVarInt(uint: Long) { fun Output.writeUVarInt(uint: Long) {
this.write0(uint) this.write0(uint)
} }
fun BytePacketBuilder.writeVarLong(signedLong: Long) { fun Output.writeVarLong(signedLong: Long) {
this.writeUVarLong(encodeZigZag64(signedLong)) this.writeUVarLong(encodeZigZag64(signedLong))
} }
fun BytePacketBuilder.writeUVarLong(ulong: Long) { fun Output.writeUVarLong(ulong: Long) {
this.write0(ulong) this.write0(ulong)
} }
private fun BytePacketBuilder.write0(long: Long) { private fun Output.write0(long: Long) {
var value = long var value = long
do { do {
var temp = (value and 127).toByte() var temp = (value and 127).toByte()
@ -92,7 +95,7 @@ private fun BytePacketBuilder.write0(long: Long) {
} while (value != 0L) } while (value != 0L)
} }
private fun read(stream: ByteReadPacket, maxSize: Int): Long { private fun read(stream: Input, maxSize: Int): Long {
var value: Long = 0 var value: Long = 0
var size = 0 var size = 0
var b = stream.readByte().toInt() var b = stream.readByte().toInt()