Author: Adam <git@apiote.xyz>
wip
%!v(PANIC=String method: strings: negative Repeat count)
diff --git a/fruchtfleisch/build.gradle b/fruchtfleisch/build.gradle index 730e890c34aca32c1cf7c79d430c86a9f204929a..be38b28605a975098a3066d50f66403bb032ff82 100644 --- a/fruchtfleisch/build.gradle +++ b/fruchtfleisch/build.gradle @@ -4,9 +4,14 @@ id 'org.jetbrains.kotlin.jvm' } dependencies { - //implementation 'org.jetbrains.kotlin:kotlin-reflect:1.8.10' + implementation "org.jetbrains.kotlin:kotlin-reflect:1.8.20" + testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2' } java { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 +} + +tasks.withType(Test) { + useJUnitPlatform() } \ No newline at end of file diff --git a/fruchtfleisch/src/main/java/xyz/apiote/fruchtfleisch/Reader.kt b/fruchtfleisch/src/main/java/xyz/apiote/fruchtfleisch/Reader.kt index 1f22ccb5807e8f6cf8c60ad24e3dfa1a42aaef88..4c3e69d605c71b55c8ed96a497813400620b1200 100644 --- a/fruchtfleisch/src/main/java/xyz/apiote/fruchtfleisch/Reader.kt +++ b/fruchtfleisch/src/main/java/xyz/apiote/fruchtfleisch/Reader.kt @@ -4,13 +4,66 @@ import java.io.EOFException import java.io.InputStream import java.lang.Double.longBitsToDouble import java.lang.Float.intBitsToFloat +import kotlin.reflect.KClass +import kotlin.reflect.KMutableProperty +import kotlin.reflect.full.declaredMemberProperties -data class IntVar(private val v: Long) { +class IntVar(private val v: Long) { fun toLong() = v } -data class UIntVar(private val v: ULong) { +class UIntVar(private val v: ULong) { fun toULong() = v } + +fun readClass(obj: Any?, stream: InputStream): Any? { + // class must have all params var and with defaults + when (obj) { + null -> {} // Unit? + is KClass<*> -> { + // todo read union tag + // todo get registered Unions + /*unions.forEach { union -> // union is {cls: KClass<*>, map[tag]Class + if (obj == union.cls) { + val v = union.tags[tag].createInstance() + return readClass(v, stream) + } + }*/ + println("Is KClass") + } + is IntVar -> return Reader(stream).readInt().toLong().toInt() + is UIntVar -> return Reader(stream).readUInt().toULong().toUInt() + + is Byte -> return Reader(stream).readI8() + is Short -> return Reader(stream).readI16() + is Int -> return Reader(stream).readI32() + is Long -> return Reader(stream).readI64() + + is UByte -> return Reader(stream).readU8() + is UShort -> return Reader(stream).readU16() + is UInt -> return Reader(stream).readU32() + is ULong -> return Reader(stream).readU64() + // and so on + else -> { + if (obj::class.isData) { + obj::class.declaredMemberProperties.forEach { + if (it is KMutableProperty<*>) { + val v = readClass(it.getter.call(obj), stream) + it.setter.call(obj, v) + } else { + // todo debug + } + } + println("Is data class") + return obj + } else { + // todo error + } + } + } + return null +} + + @Suppress("MemberVisibilityCanBePrivate", "unused", "BooleanMethodIsAlwaysInverted") class Reader(private val stream: InputStream) { diff --git a/fruchtfleisch/src/test/kotlin/xyz/apiote/fruchtfleisch/ReaderKtTest.kt b/fruchtfleisch/src/test/kotlin/xyz/apiote/fruchtfleisch/ReaderKtTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..654f919ba947f3012e9ff9b6ce27ba497dd48509 --- /dev/null +++ b/fruchtfleisch/src/test/kotlin/xyz/apiote/fruchtfleisch/ReaderKtTest.kt @@ -0,0 +1,24 @@ +package xyz.apiote.fruchtfleisch + +import org.junit.jupiter.api.Test + +data class C(var x: Byte = 0) + +internal class ReflectReaderTest { + + @Test + fun readInt() { + val b = byteArrayOf(0x02) + var i: Byte = 0 + i = readClass(i, b.inputStream()) as Byte + assert(i.toInt() == 2) + } + + @Test + fun readClass() { + val b = byteArrayOf(0x02) + val i = C() + readClass(i, b.inputStream()) + assert(i.x.toInt() == 2) + } +} \ No newline at end of file