mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-09 18:00:33 +08:00
Fix shadowed struct elements
This commit is contained in:
parent
4c6e427d12
commit
948658c9ec
@ -181,9 +181,9 @@ internal class JceDecoder(
|
||||
|
||||
companion object {
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
val debuggingMode: Boolean by lazy { false }
|
||||
var debuggingMode: Boolean = false
|
||||
|
||||
private var structureHierarchy: Int = 0
|
||||
var structureHierarchy: Int = 0
|
||||
|
||||
inline fun println(value: () -> String) {
|
||||
if (debuggingMode) {
|
||||
@ -258,7 +258,10 @@ internal class JceDecoder(
|
||||
|
||||
override fun decodeSequentially(): Boolean = false
|
||||
override fun decodeElementIndex(descriptor: SerialDescriptor): Int {
|
||||
var jceHead = jce.currentHeadOrNull ?: return CompositeDecoder.READ_DONE
|
||||
var jceHead = jce.currentHeadOrNull ?: kotlin.run {
|
||||
println("decodeElementIndex: currentHead == null")
|
||||
return CompositeDecoder.READ_DONE
|
||||
}
|
||||
|
||||
println { "decodeElementIndex: ${jce.currentHead}" }
|
||||
while (!jce.input.endOfInput) {
|
||||
|
@ -116,62 +116,69 @@ internal class JceInput(
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
@PublishedApi
|
||||
internal fun skipField(type: Byte): Unit = when (type) {
|
||||
Jce.BYTE -> this.input.discardExact(1)
|
||||
Jce.SHORT -> this.input.discardExact(2)
|
||||
Jce.INT -> this.input.discardExact(4)
|
||||
Jce.LONG -> this.input.discardExact(8)
|
||||
Jce.FLOAT -> this.input.discardExact(4)
|
||||
Jce.DOUBLE -> this.input.discardExact(8)
|
||||
Jce.STRING1 -> this.input.discardExact(this.input.readUByte().toInt())
|
||||
Jce.STRING4 -> this.input.discardExact(this.input.readInt())
|
||||
Jce.MAP -> { // map
|
||||
//println("skip map!")
|
||||
nextHead()
|
||||
repeat(skipToHeadAndUseIfPossibleOrFail(0, message = { "tag 0 not found when skipping map" }) {
|
||||
readJceIntValue(it)
|
||||
} * 2) {
|
||||
val currentHead = currentHead
|
||||
prepareNextHead()
|
||||
skipField(currentHead.type)
|
||||
internal fun skipField(type: Byte): Unit {
|
||||
JceDecoder.println { "skipping ${JceHead.findJceTypeName(type)}" }
|
||||
when (type) {
|
||||
Jce.BYTE -> this.input.discardExact(1)
|
||||
Jce.SHORT -> this.input.discardExact(2)
|
||||
Jce.INT -> println("readInt=" + this.input.readInt())
|
||||
Jce.LONG -> this.input.discardExact(8)
|
||||
Jce.FLOAT -> this.input.discardExact(4)
|
||||
Jce.DOUBLE -> this.input.discardExact(8)
|
||||
Jce.STRING1 -> this.input.discardExact(this.input.readUByte().toInt())
|
||||
Jce.STRING4 -> this.input.discardExact(this.input.readInt())
|
||||
Jce.MAP -> { // map
|
||||
JceDecoder.structureHierarchy++
|
||||
var count: Int = 0
|
||||
nextHead() // avoid shadowing, don't remove
|
||||
repeat(skipToHeadAndUseIfPossibleOrFail(0, message = { "tag 0 not found when skipping map" }) {
|
||||
readJceIntValue(it).also { count = it * 2 }
|
||||
} * 2) {
|
||||
skipField(currentHead.type)
|
||||
if (it != count - 1) { // don't read last head
|
||||
nextHead()
|
||||
}
|
||||
}
|
||||
JceDecoder.structureHierarchy--
|
||||
}
|
||||
}
|
||||
Jce.LIST -> { // list
|
||||
JceDecoder.println {"skip list!"}
|
||||
nextHead()
|
||||
repeat(skipToHeadAndUseIfPossibleOrFail(0, message = { "tag 0 not found when skipping list" }) {
|
||||
readJceIntValue(it)
|
||||
}) {
|
||||
val currentHead = currentHead
|
||||
prepareNextHead()
|
||||
skipField(currentHead.type)
|
||||
Jce.LIST -> { // list
|
||||
JceDecoder.structureHierarchy++
|
||||
var count: Int = 0
|
||||
nextHead() // avoid shadowing, don't remove
|
||||
repeat(skipToHeadAndUseIfPossibleOrFail(0, message = { "tag 0 not found when skipping list" }) { head ->
|
||||
readJceIntValue(head).also { count = it }
|
||||
}) {
|
||||
skipField(currentHead.type)
|
||||
if (it != count - 1) { // don't read last head
|
||||
nextHead()
|
||||
}
|
||||
}
|
||||
JceDecoder.structureHierarchy--
|
||||
}
|
||||
}
|
||||
Jce.STRUCT_BEGIN -> {
|
||||
JceDecoder.println {"skip struct!"}
|
||||
fun skipToStructEnd() {
|
||||
Jce.STRUCT_BEGIN -> {
|
||||
JceDecoder.structureHierarchy++
|
||||
var head: JceHead
|
||||
do {
|
||||
head = nextHead()
|
||||
skipField(head.type)
|
||||
} while (head.type != Jce.STRUCT_END)
|
||||
JceDecoder.structureHierarchy--
|
||||
}
|
||||
skipToStructEnd()
|
||||
}
|
||||
Jce.STRUCT_END, Jce.ZERO_TYPE -> {
|
||||
Unit
|
||||
}
|
||||
Jce.SIMPLE_LIST -> {
|
||||
JceDecoder.println { "skip simple list!" }
|
||||
var head = nextHead()
|
||||
check(head.type == Jce.BYTE) { "bad simple list element type: " + head.type }
|
||||
check(head.tag == 0) { "simple list element tag must be 0, but was ${head.tag}" }
|
||||
Jce.STRUCT_END, Jce.ZERO_TYPE -> {
|
||||
}
|
||||
Jce.SIMPLE_LIST -> {
|
||||
JceDecoder.structureHierarchy++
|
||||
var head = nextHead()
|
||||
check(head.type == Jce.BYTE) { "bad simple list element type: " + head.type }
|
||||
check(head.tag == 0) { "simple list element tag must be 0, but was ${head.tag}" }
|
||||
|
||||
head = nextHead()
|
||||
check(head.tag == 0) { "tag for size for simple list must be 0, but was ${head.tag}" }
|
||||
this.input.discardExact(readJceIntValue(head))
|
||||
head = nextHead()
|
||||
check(head.tag == 0) { "tag for size for simple list must be 0, but was ${head.tag}" }
|
||||
this.input.discardExact(readJceIntValue(head))
|
||||
JceDecoder.structureHierarchy--
|
||||
}
|
||||
else -> error("invalid type: $type")
|
||||
}
|
||||
else -> error("invalid type: $type")
|
||||
}
|
||||
|
||||
// region readers
|
||||
|
@ -8,10 +8,7 @@ import kotlinx.io.core.writeFully
|
||||
import kotlinx.serialization.MissingFieldException
|
||||
import kotlinx.serialization.Serializable
|
||||
import net.mamoe.mirai.qqandroid.io.JceStruct
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.jce.Jce
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.jce.JceId
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.jce.JceInput
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.jce.writeJceHead
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.jce.*
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
@ -42,6 +39,9 @@ internal const val ZERO_TYPE: Byte = 12
|
||||
*/
|
||||
@Suppress("INVISIBLE_MEMBER") // bug
|
||||
internal class JceInputTest {
|
||||
init {
|
||||
JceDecoder.debuggingMode = true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIntToStructMap() {
|
||||
@ -109,31 +109,33 @@ internal class JceInputTest {
|
||||
val input = buildPacket {
|
||||
writeJceHead(MAP, 0) // TestSerializableClassB
|
||||
writeJceHead(BYTE, 0)
|
||||
writeByte(1)
|
||||
writeByte(1);
|
||||
|
||||
writeJceHead(STRUCT_BEGIN, 0);
|
||||
{
|
||||
writeJceHead(INT, 0)
|
||||
writeInt(123)
|
||||
writeJceHead(STRUCT_BEGIN, 0);
|
||||
{
|
||||
writeJceHead(INT, 0)
|
||||
writeInt(123)
|
||||
|
||||
writeJceHead(STRUCT_BEGIN, 123); // TestSerializableClassC
|
||||
writeJceHead(STRUCT_BEGIN, 123); // TestSerializableClassC
|
||||
{
|
||||
writeJceHead(INT, 5)
|
||||
writeInt(123123)
|
||||
}()
|
||||
writeJceHead(STRUCT_END, 0)
|
||||
|
||||
writeJceHead(INT, 5)
|
||||
writeInt(9)
|
||||
}()
|
||||
writeJceHead(STRUCT_END, 0)
|
||||
|
||||
writeJceHead(STRUCT_BEGIN, 1);
|
||||
{
|
||||
writeJceHead(INT, 5)
|
||||
writeInt(123123)
|
||||
}()
|
||||
writeJceHead(STRUCT_END, 0)
|
||||
|
||||
writeJceHead(INT, 5)
|
||||
writeInt(9)
|
||||
}()
|
||||
writeJceHead(STRUCT_END, 0)
|
||||
|
||||
writeJceHead(STRUCT_BEGIN, 1);
|
||||
{
|
||||
writeJceHead(INT, 5)
|
||||
writeInt(123123)
|
||||
}()
|
||||
writeJceHead(STRUCT_END, 0)
|
||||
|
||||
writeJceHead(STRING1, 1)
|
||||
writeByte(1)
|
||||
|
Loading…
Reference in New Issue
Block a user