Commit 115ccec9 authored by Him188's avatar Him188

Rearrange classes

parent d8c64286
package net.mamoe.mirai.qqandroid.io.serialization
import io.ktor.utils.io.core.Input
import io.ktor.utils.io.core.Output
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerialFormat
import kotlinx.serialization.SerializationStrategy
interface IOFormat : SerialFormat {
fun <T> dump(serializer: SerializationStrategy<T>, input: Input): ByteArray
fun <T> load(deserializer: DeserializationStrategy<T>, output: Output): T
}
......@@ -21,6 +21,7 @@ import kotlinx.serialization.modules.SerialModule
import kotlinx.serialization.protobuf.ProtoId
import net.mamoe.mirai.qqandroid.io.JceStruct
import net.mamoe.mirai.qqandroid.io.ProtoBuf
import net.mamoe.mirai.qqandroid.io.serialization.jce.JceHead
import net.mamoe.mirai.utils.io.readString
import net.mamoe.mirai.utils.io.toReadPacket
......@@ -588,7 +589,10 @@ class Jce private constructor(private val charset: JceCharset, override val cont
}
tag = readUByte().toUInt()
}
currentJceHead = JceHead(tag = tag.toInt(), type = type.toByte())
currentJceHead = JceHead(
tag = tag.toInt(),
type = type.toByte()
)
// println("doReadHead: $currentJceHead")
return currentJceHead
}
......
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.qqandroid.io.serialization.jce
import kotlinx.serialization.*
import kotlinx.serialization.internal.TaggedDecoder
import kotlinx.serialization.modules.SerialModule
import kotlinx.serialization.protobuf.ProtoId
@OptIn(InternalSerializationApi::class) // 将来 kotlinx 修改后再复制过来 mirai.
private class JceDecoder(
val jce: JceInput, override val context: SerialModule
) : TaggedDecoder<JceTag>() {
override val updateMode: UpdateMode
get() = UpdateMode.BANNED
override fun SerialDescriptor.getTag(index: Int): JceTag {
val annotations = this.getElementAnnotations(index)
val id = (annotations.asSequence().filterIsInstance<JceId>().firstOrNull()?.id
?: annotations.asSequence().filterIsInstance<ProtoId>().firstOrNull()?.id) // 旧版本兼容
?: error("cannot find @JceId or @ProtoId for ${this.getElementName(index)} in ${this.serialName}")
return JceTag(
id,
this.getElementDescriptor(index).isNullable
)
}
override fun beginStructure(descriptor: SerialDescriptor, vararg typeParams: KSerializer<*>): CompositeDecoder {
TODO("Not yet implemented")
}
override fun decodeElementIndex(descriptor: SerialDescriptor): Int {
TODO("Not yet implemented")
}
override fun decodeTaggedInt(tag: JceTag): Int =
jce.skipToTagAndUseIfPossibleOrFail(tag.id) { jce.readJceIntValue(it) }
override fun decodeTaggedByte(tag: JceTag): Byte =
jce.skipToTagAndUseIfPossibleOrFail(tag.id) { jce.readJceByteValue(it) }
override fun decodeTaggedBoolean(tag: JceTag): Boolean =
jce.skipToTagAndUseIfPossibleOrFail(tag.id) { jce.readJceBooleanValue(it) }
override fun decodeTaggedFloat(tag: JceTag): Float =
jce.skipToTagAndUseIfPossibleOrFail(tag.id) { jce.readJceFloatValue(it) }
override fun decodeTaggedDouble(tag: JceTag): Double =
jce.skipToTagAndUseIfPossibleOrFail(tag.id) { jce.readJceDoubleValue(it) }
override fun decodeTaggedShort(tag: JceTag): Short =
jce.skipToTagAndUseIfPossibleOrFail(tag.id) { jce.readJceShortValue(it) }
override fun decodeTaggedLong(tag: JceTag): Long =
jce.skipToTagAndUseIfPossibleOrFail(tag.id) { jce.readJceLongValue(it) }
override fun decodeTaggedString(tag: JceTag): String =
jce.skipToTagAndUseIfPossibleOrFail(tag.id) { jce.readJceStringValue(it) }
override fun decodeTaggedEnum(tag: JceTag, enumDescription: SerialDescriptor): Int {
return super.decodeTaggedEnum(tag, enumDescription)
}
override fun decodeTaggedChar(tag: JceTag): Char {
return super.decodeTaggedChar(tag)
}
override fun decodeTaggedNotNullMark(tag: JceTag): Boolean {
println("!! decodeTaggedNotNullMark: $tag")
return super.decodeTaggedNotNullMark(tag)
}
}
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.qqandroid.io.serialization.jce
import io.ktor.utils.io.core.*
import kotlinx.serialization.*
import kotlinx.serialization.internal.TaggedDecoder
import kotlinx.serialization.modules.EmptyModule
import kotlinx.serialization.modules.SerialModule
import kotlinx.serialization.protobuf.ProtoId
import net.mamoe.mirai.qqandroid.io.serialization.IOFormat
import net.mamoe.mirai.qqandroid.io.serialization.Jce
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.BYTE
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.DOUBLE
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.FLOAT
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.INT
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.LIST
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.LONG
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.MAP
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.SHORT
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.SIMPLE_LIST
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.STRING1
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.STRING4
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.STRUCT_BEGIN
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.STRUCT_END
import net.mamoe.mirai.qqandroid.io.serialization.Jce.Companion.ZERO_TYPE
import net.mamoe.mirai.qqandroid.io.serialization.JceCharset
import net.mamoe.mirai.utils.io.readString
/**
* Jce 数据结构序列化和反序列化器.
*
* @author Him188
*/
class JceNew(
override val context: SerialModule
) : SerialFormat, IOFormat {
companion object Default : IOFormat by JceNew(
EmptyModule
)
override fun <T> dump(serializer: SerializationStrategy<T>, input: Input): ByteArray {
TODO("Not yet implemented")
}
override fun <T> load(deserializer: DeserializationStrategy<T>, output: Output): T {
TODO("Not yet implemented")
}
}
\ No newline at end of file
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.qqandroid.io.serialization.jce
import kotlinx.serialization.SerialInfo
import net.mamoe.mirai.qqandroid.io.serialization.Jce
/**
* 标注 JCE 序列化时使用的 ID
*/
@SerialInfo
annotation class JceId(val id: Int)
/**
* 类中元素的 tag
*
* 保留这个结构, 为将来增加功能的兼容性.
*/
internal data class JceTag(
val id: Int,
val isNullable: Boolean
)
@OptIn(ExperimentalUnsignedTypes::class)
inline class JceHead(private val value: Long) {
constructor(tag: Int, type: Byte) : this(tag.toLong().shl(32) or type.toLong())
val tag: Int get() = (value ushr 32).toInt()
val type: Byte get() = value.toUInt().toByte()
override fun toString(): String {
val typeString = when (type) {
Jce.BYTE -> "Byte"
Jce.DOUBLE -> "Double"
Jce.FLOAT -> "Float"
Jce.INT -> "Int"
Jce.LIST -> "List"
Jce.LONG -> "Long"
Jce.MAP -> "Map"
Jce.SHORT -> "Short"
Jce.SIMPLE_LIST -> "SimpleList"
Jce.STRING1 -> "String1"
Jce.STRING4 -> "String4"
Jce.STRUCT_BEGIN -> "StructBegin"
Jce.STRUCT_END -> "StructEnd"
Jce.ZERO_TYPE -> "Zero"
else -> error("illegal jce type: $type")
}
return "JceHead(tag=$tag, type=$type($typeString))"
}
}
\ No newline at end of file
@file:Suppress("unused")
package net.mamoe.mirai.qqandroid.io.serialization
import io.ktor.utils.io.core.Output
import io.ktor.utils.io.core.buildPacket
import io.ktor.utils.io.core.writeInt
import net.mamoe.mirai.qqandroid.io.serialization.jce.JceInput
import kotlin.test.Test
import kotlin.test.assertEquals
internal const val BYTE: Byte = 0
internal const val DOUBLE: Byte = 5
internal const val FLOAT: Byte = 4
internal const val INT: Byte = 2
internal const val JCE_MAX_STRING_LENGTH = 104857600
internal const val LIST: Byte = 9
internal const val LONG: Byte = 3
internal const val MAP: Byte = 8
internal const val SHORT: Byte = 1
internal const val SIMPLE_LIST: Byte = 13
internal const val STRING1: Byte = 6
internal const val STRING4: Byte = 7
internal const val STRUCT_BEGIN: Byte = 10
internal const val STRUCT_END: Byte = 11
internal const val ZERO_TYPE: Byte = 12
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@Suppress("INVISIBLE_MEMBER") // bug
internal class JceInputTest {
@Test
fun testHeadStack() {
}
@Test
fun testReadInt() {
val input = JceInput(buildPacket {
writeHead(INT, 0)
writeInt(123456)
}, JceCharset.UTF8)
assertEquals(123456, input.readJceIntValue(input.nextHead()))
}
@PublishedApi
internal fun Output.writeHead(type: Byte, tag: Int) {
if (tag < 15) {
writeByte(((tag shl 4) or type.toInt()).toByte())
return
}
if (tag < 256) {
writeByte((type.toInt() or 0xF0).toByte())
writeByte(tag.toByte())
return
}
error("tag is too large: $tag")
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment