Browse Source

Add automatically-generated ByteBuf extensions

Signed-off-by: Graham <gpe@openrs2.org>
pull/132/head
Graham 6 months ago
parent
commit
9bb511369d
  1. 15
      .idea/runConfigurations/GenerateBuffer.xml
  2. 1
      all/build.gradle.kts
  3. 2
      all/src/main/kotlin/org/openrs2/Command.kt
  4. 33
      buffer-generator/build.gradle.kts
  5. 6
      buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/ArrayOrder.kt
  6. 582
      buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/ByteBufExtensionGenerator.kt
  7. 33
      buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/ByteOrder.kt
  8. 17
      buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/GenerateBufferCommand.kt
  9. 24
      buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/IntType.kt
  10. 6
      buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/Signedness.kt
  11. 13
      buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/Transformation.kt
  12. 1719
      buffer/src/main/kotlin/org/openrs2/buffer/GeneratedByteBufExtensions.kt
  13. 1
      gradle/libs.versions.toml
  14. 1
      settings.gradle.kts

15
.idea/runConfigurations/GenerateBuffer.xml

@ -0,0 +1,15 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="GenerateBuffer" type="JetRunConfigurationType">
<module name="openrs2.buffer-generator.main" />
<option name="VM_PARAMETERS" value="" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="MAIN_CLASS_NAME" value="org.openrs2.buffer.generator.GenerateBufferCommandKt" />
<option name="WORKING_DIRECTORY" value="" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

1
all/build.gradle.kts

@ -16,6 +16,7 @@ application {
dependencies {
implementation(projects.archive)
implementation(projects.bufferGenerator)
implementation(projects.compressCli)
implementation(projects.crc32)
implementation(projects.deob)

2
all/src/main/kotlin/org/openrs2/Command.kt

@ -3,6 +3,7 @@ package org.openrs2
import com.github.ajalt.clikt.core.NoOpCliktCommand
import com.github.ajalt.clikt.core.subcommands
import org.openrs2.archive.ArchiveCommand
import org.openrs2.buffer.generator.GenerateBufferCommand
import org.openrs2.compress.cli.CompressCommand
import org.openrs2.crc32.Crc32Command
import org.openrs2.deob.DeobfuscateCommand
@ -19,6 +20,7 @@ public class Command : NoOpCliktCommand(name = "openrs2") {
Crc32Command(),
DeobfuscateCommand(),
GameCommand(),
GenerateBufferCommand(),
PatchCommand()
)
}

33
buffer-generator/build.gradle.kts

@ -0,0 +1,33 @@
plugins {
`maven-publish`
application
kotlin("jvm")
}
application {
mainClass.set("org.openrs2.buffer.generator.GenerateBufferCommand")
}
dependencies {
api(libs.clikt)
implementation(libs.kotlinPoet)
implementation(libs.netty.buffer)
}
publishing {
publications.create<MavenPublication>("maven") {
from(components["java"])
pom {
packaging = "jar"
name.set("OpenRS2 Buffer Generator")
description.set(
"""
Tool for generating Jagex-specific ByteBuf extension methods
automatically.
""".trimIndent()
)
}
}
}

6
buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/ArrayOrder.kt

@ -0,0 +1,6 @@
package org.openrs2.buffer.generator
public enum class ArrayOrder(public val suffix: String) {
FORWARD(""),
REVERSE("Reverse")
}

582
buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/ByteBufExtensionGenerator.kt

@ -0,0 +1,582 @@
package org.openrs2.buffer.generator
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import io.netty.buffer.ByteBuf
import io.netty.buffer.Unpooled
public class ByteBufExtensionGenerator {
public fun generate(): String {
val builder = FileSpec.builder("org.openrs2.buffer", "GeneratedByteBufExtensions")
builder.indent(" ")
builder.addComment("This file is generated automatically. DO NOT EDIT.")
for (type in IntType.values()) {
for (order in ByteOrder.values()) {
for (transformation in Transformation.values()) {
// only integers can be middle-endian
if (type != IntType.INT && (order == ByteOrder.ALT3 || order == ByteOrder.ALT3_REVERSE)) {
continue
}
// only bytes and shorts can be transformed
if (type != IntType.BYTE && type != IntType.SHORT && transformation != Transformation.IDENTITY) {
continue
}
// supplied by Netty
if (
(order == ByteOrder.LITTLE || order == ByteOrder.BIG) &&
transformation == Transformation.IDENTITY
) {
continue
}
// byte order doesn't make sense for individual bytes
if (type == IntType.BYTE && order != ByteOrder.BIG) {
continue
}
for (signedness in Signedness.values()) {
// unsigned integers not supported
if (type == IntType.INT && signedness == Signedness.UNSIGNED) {
continue
}
builder.addFunction(createGetIntFunction(type, order, transformation, signedness))
builder.addFunction(createReadIntFunction(type, order, transformation, signedness))
}
builder.addFunction(createSetIntFunction(type, order, transformation))
builder.addFunction(createWriteIntFunction(type, order, transformation))
}
}
}
for (order in ArrayOrder.values()) {
for (transformation in Transformation.values()) {
// supplied by Netty
if (order == ArrayOrder.FORWARD && transformation == Transformation.IDENTITY) {
continue
}
builder.addFunction(createGetArrayFunction(order, transformation))
builder.addFunction(createGetArrayIndexLenFunction(order, transformation))
builder.addFunction(createGetByteBufFunction(order, transformation))
builder.addFunction(createGetByteBufLenFunction(order, transformation))
builder.addFunction(createGetByteBufIndexLenFunction(order, transformation))
builder.addFunction(createReadArrayFunction(order, transformation))
builder.addFunction(createReadArrayIndexLenFunction(order, transformation))
builder.addFunction(createReadByteBufFunction(order, transformation))
builder.addFunction(createReadByteBufLenFunction(order, transformation))
builder.addFunction(createReadByteBufIndexLenFunction(order, transformation))
builder.addFunction(createReadByteBufAllocFunction(order, transformation))
builder.addFunction(createSetArrayFunction(order, transformation))
builder.addFunction(createSetArrayIndexLenFunction(order, transformation))
builder.addFunction(createSetByteBufFunction(order, transformation))
builder.addFunction(createSetByteBufLenFunction(order, transformation))
builder.addFunction(createSetByteBufIndexLenFunction(order, transformation))
builder.addFunction(createWriteArrayFunction(order, transformation))
builder.addFunction(createWriteArrayIndexLenFunction(order, transformation))
builder.addFunction(createWriteByteBufFunction(order, transformation))
builder.addFunction(createWriteByteBufLenFunction(order, transformation))
builder.addFunction(createWriteByteBufIndexLenFunction(order, transformation))
}
}
for (transformation in Transformation.values()) {
// supplied by Netty
if (transformation == Transformation.IDENTITY) {
continue
}
builder.addFunction(createGetBooleanFunction(transformation))
builder.addFunction(createReadBooleanFunction(transformation))
builder.addFunction(createSetBooleanFunction(transformation))
builder.addFunction(createWriteBooleanFunction(transformation))
}
val file = builder.build()
return file.toString()
.replace("import kotlin.Boolean\n", "")
.replace("import kotlin.Byte\n", "")
.replace("import kotlin.ByteArray\n", "")
.replace("import kotlin.Int\n", "")
.replace("import kotlin.Short\n", "")
.replace("import kotlin.Unit\n", "")
.replace(": Unit {", " {")
}
private fun createGetIntFunction(
type: IntType,
order: ByteOrder,
transformation: Transformation,
signedness: Signedness
): FunSpec {
val name = "${signedness.prefix}${type.prettyName}${order.suffix}${transformation.suffix}"
val builder = FunSpec.builder("get$name")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
val readType = type.getReadType(signedness)
builder.returns(readType)
builder.addStatement("var value = 0")
for (i in 0 until type.width) {
val shift = order.getShift(i, type.width)
val pre: String
val post: String
if (shift == 0) {
pre = transformation.preTransform
post = transformation.postReadTransform
} else {
pre = ""
post = ""
}
builder.addStatement(
"value = value or (((${pre}getByte(index + %L).toInt()$post) and 0xFF) shl %L)",
i,
shift
)
}
builder.addStatement("return value.%N()", "to${readType.simpleName}")
return builder.build()
}
private fun createReadIntFunction(
type: IntType,
order: ByteOrder,
transformation: Transformation,
signedness: Signedness
): FunSpec {
val name = "${signedness.prefix}${type.prettyName}${order.suffix}${transformation.suffix}"
val builder = FunSpec.builder("read$name")
builder.receiver(ByteBuf::class)
builder.returns(type.getReadType(signedness))
builder.addStatement("val index = readerIndex()")
builder.addStatement("val result = %N(index)", "get$name")
builder.addStatement("readerIndex(index + %L)", type.width)
builder.addStatement("return result")
return builder.build()
}
private fun createSetIntFunction(type: IntType, order: ByteOrder, transformation: Transformation): FunSpec {
val name = "${type.prettyName}${order.suffix}${transformation.suffix}"
val builder = FunSpec.builder("set$name")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
builder.addParameter("value", type.writeType)
for (i in 0 until type.width) {
val shift = order.getShift(i, type.width)
val pre: String
val post: String
if (shift == 0) {
pre = transformation.preTransform
post = transformation.postWriteTransform
} else {
pre = ""
post = ""
}
builder.addStatement("setByte(index + %L, $pre(value shr %L)$post)", i, shift)
}
return builder.build()
}
private fun createWriteIntFunction(type: IntType, order: ByteOrder, transformation: Transformation): FunSpec {
val name = "${type.prettyName}${order.suffix}${transformation.suffix}"
val builder = FunSpec.builder("write$name")
builder.receiver(ByteBuf::class)
builder.addParameter("value", type.writeType)
builder.addStatement("val index = writerIndex()")
builder.addStatement("ensureWritable(%L)", type.width)
builder.addStatement("%N(index, value)", "set$name")
builder.addStatement("writerIndex(index + %L)", type.width)
return builder.build()
}
private fun createGetBooleanFunction(transformation: Transformation): FunSpec {
val builder = FunSpec.builder("getBoolean$transformation")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
builder.returns(Boolean::class)
builder.addStatement("return %N(index).toInt() != 0", "getByte$transformation")
return builder.build()
}
private fun createReadBooleanFunction(transformation: Transformation): FunSpec {
val builder = FunSpec.builder("readBoolean$transformation")
builder.receiver(ByteBuf::class)
builder.returns(Boolean::class)
builder.addStatement("return %N().toInt() != 0", "readByte$transformation")
return builder.build()
}
private fun createSetBooleanFunction(transformation: Transformation): FunSpec {
val builder = FunSpec.builder("setBoolean$transformation")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
builder.addParameter("value", Boolean::class)
builder.beginControlFlow("if (value)")
builder.addStatement("%N(index, 1)", "setByte$transformation")
builder.nextControlFlow("else")
builder.addStatement("%N(index, 0)", "setByte$transformation")
builder.endControlFlow()
return builder.build()
}
private fun createWriteBooleanFunction(transformation: Transformation): FunSpec {
val builder = FunSpec.builder("writeBoolean$transformation")
builder.receiver(ByteBuf::class)
builder.addParameter("value", Boolean::class)
builder.beginControlFlow("if (value)")
builder.addStatement("%N(1)", "writeByte$transformation")
builder.nextControlFlow("else")
builder.addStatement("%N(0)", "writeByte$transformation")
builder.endControlFlow()
return builder.build()
}
private fun createGetArrayFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("getBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
builder.addParameter("dst", ByteArray::class)
builder.addStatement("%N(index, dst, 0, dst.size)", "getBytes${order.suffix}${transformation.suffix}")
return builder.build()
}
private fun createGetArrayIndexLenFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("getBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
builder.addParameter("dst", ByteArray::class)
builder.addParameter("dstIndex", Int::class)
builder.addParameter("len", Int::class)
builder.addStatement("getBytes(index, dst, dstIndex, len)")
builder.beginControlFlow("for (i in 0 until len)")
builder.addStatement(
"dst[dstIndex + i] = " +
"(${transformation.preTransform}dst[dstIndex + i].toInt()${transformation.postReadTransform}).toByte()"
)
builder.endControlFlow()
if (order == ArrayOrder.REVERSE) {
builder.addStatement("dst.reverse(dstIndex, dstIndex + len)")
}
return builder.build()
}
private fun createGetByteBufFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("getBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
builder.addParameter("dst", ByteBuf::class)
builder.addStatement("val dstIndex = dst.writerIndex()")
builder.addStatement("val len = dst.writableBytes()")
builder.addStatement("dst.ensureWritable(len)")
builder.addStatement("%N(index, dst, dstIndex, len)", "getBytes${order.suffix}${transformation.suffix}")
builder.addStatement("dst.writerIndex(dstIndex + len)")
return builder.build()
}
private fun createGetByteBufLenFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("getBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
builder.addParameter("dst", ByteBuf::class)
builder.addParameter("len", Int::class)
builder.addStatement("val dstIndex = dst.writerIndex()")
builder.addStatement("dst.ensureWritable(len)")
builder.addStatement("%N(index, dst, dstIndex, len)", "getBytes${order.suffix}${transformation.suffix}")
builder.addStatement("dst.writerIndex(dstIndex + len)")
return builder.build()
}
private fun createGetByteBufIndexLenFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("getBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
builder.addParameter("dst", ByteBuf::class)
builder.addParameter("dstIndex", Int::class)
builder.addParameter("len", Int::class)
val srcIndex = if (order == ArrayOrder.FORWARD) {
"i"
} else {
"len - i - 1"
}
builder.beginControlFlow("for (i in 0 until len)")
builder.addStatement(
"dst.setByte(dstIndex + i, %N(index + $srcIndex).toInt())",
"getByte${transformation.suffix}"
)
builder.endControlFlow()
return builder.build()
}
private fun createReadByteBufAllocFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("readBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("len", Int::class)
builder.returns(ByteBuf::class)
builder.beginControlFlow("if (len == 0)")
builder.addStatement("return %T.EMPTY_BUFFER", Unpooled::class)
builder.endControlFlow()
builder.beginControlFlow("alloc().buffer(len).use { dst ->")
builder.addStatement("%N(dst, len)", "readBytes${order.suffix}${transformation.suffix}")
builder.addStatement("return dst.retain()")
builder.endControlFlow()
return builder.build()
}
private fun createReadArrayFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("readBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("dst", ByteArray::class)
builder.addStatement("%N(dst, 0, dst.size)", "readBytes${order.suffix}${transformation.suffix}")
return builder.build()
}
private fun createReadArrayIndexLenFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("readBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("dst", ByteArray::class)
builder.addParameter("dstIndex", Int::class)
builder.addParameter("len", Int::class)
builder.addStatement("val index = readerIndex()")
builder.addStatement("%N(index, dst, dstIndex, len)", "getBytes${order.suffix}${transformation.suffix}")
builder.addStatement("readerIndex(index + len)")
return builder.build()
}
private fun createReadByteBufFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("readBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("dst", ByteBuf::class)
builder.addStatement("val dstIndex = dst.writerIndex()")
builder.addStatement("val len = dst.writableBytes()")
builder.addStatement("dst.ensureWritable(len)")
builder.addStatement("%N(dst, dstIndex, len)", "readBytes${order.suffix}${transformation.suffix}")
builder.addStatement("dst.writerIndex(dstIndex + len)")
return builder.build()
}
private fun createReadByteBufLenFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("readBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("dst", ByteBuf::class)
builder.addParameter("len", Int::class)
builder.addStatement("val dstIndex = dst.writerIndex()")
builder.addStatement("dst.ensureWritable(len)")
builder.addStatement("%N(dst, dstIndex, len)", "readBytes${order.suffix}${transformation.suffix}")
builder.addStatement("dst.writerIndex(dstIndex + len)")
return builder.build()
}
private fun createReadByteBufIndexLenFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("readBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("dst", ByteBuf::class)
builder.addParameter("dstIndex", Int::class)
builder.addParameter("len", Int::class)
builder.addStatement("val index = readerIndex()")
builder.addStatement("%N(index, dst, dstIndex, len)", "getBytes${order.suffix}${transformation.suffix}")
builder.addStatement("readerIndex(index + len)")
return builder.build()
}
private fun createSetArrayFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("setBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
builder.addParameter("src", ByteArray::class)
builder.addStatement("%N(index, src, 0, src.size)", "setBytes${order.suffix}${transformation.suffix}")
return builder.build()
}
private fun createSetArrayIndexLenFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("setBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
builder.addParameter("src", ByteArray::class)
builder.addParameter("srcIndex", Int::class)
builder.addParameter("len", Int::class)
builder.beginControlFlow("%T.wrappedBuffer(src).use { buf ->", Unpooled::class)
builder.addStatement("%N(index, buf, srcIndex, len)", "setBytes${order.suffix}${transformation.suffix}")
builder.endControlFlow()
return builder.build()
}
private fun createSetByteBufFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("setBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
builder.addParameter("src", ByteBuf::class)
builder.addStatement("val srcIndex = src.readerIndex()")
builder.addStatement("val len = src.readableBytes()")
builder.addStatement("%N(index, src, srcIndex, len)", "setBytes${order.suffix}${transformation.suffix}")
builder.addStatement("src.readerIndex(srcIndex + len)")
return builder.build()
}
private fun createSetByteBufLenFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("setBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
builder.addParameter("src", ByteBuf::class)
builder.addParameter("len", Int::class)
builder.addStatement("val srcIndex = src.readerIndex()")
builder.addStatement("%N(index, src, srcIndex, len)", "setBytes${order.suffix}${transformation.suffix}")
builder.addStatement("src.readerIndex(srcIndex + len)")
return builder.build()
}
private fun createSetByteBufIndexLenFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("setBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("index", Int::class)
builder.addParameter("src", ByteBuf::class)
builder.addParameter("srcIndex", Int::class)
builder.addParameter("len", Int::class)
val srcIndex = if (order == ArrayOrder.FORWARD) {
"i"
} else {
"len - i - 1"
}
builder.beginControlFlow("for (i in 0 until len)")
builder.addStatement(
"%N(index + i, src.getByte(srcIndex + $srcIndex).toInt())",
"setByte${transformation.suffix}"
)
builder.endControlFlow()
return builder.build()
}
private fun createWriteArrayFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("writeBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("src", ByteArray::class)
builder.addStatement("%N(src, 0, src.size)", "writeBytes${order.suffix}${transformation.suffix}")
return builder.build()
}
private fun createWriteArrayIndexLenFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("writeBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("src", ByteArray::class)
builder.addParameter("srcIndex", Int::class)
builder.addParameter("len", Int::class)
builder.addStatement("val index = writerIndex()")
builder.addStatement("ensureWritable(len)")
builder.addStatement("%N(index, src, srcIndex, len)", "setBytes${order.suffix}${transformation.suffix}")
builder.addStatement("writerIndex(index + len)")
return builder.build()
}
private fun createWriteByteBufFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("writeBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("src", ByteBuf::class)
builder.addStatement("val srcIndex = src.readerIndex()")
builder.addStatement("val len = src.readableBytes()")
builder.addStatement("%N(src, srcIndex, len)", "writeBytes${order.suffix}${transformation.suffix}")
builder.addStatement("src.readerIndex(srcIndex + len)")
return builder.build()
}
private fun createWriteByteBufLenFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("writeBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("src", ByteBuf::class)
builder.addParameter("len", Int::class)
builder.addStatement("val srcIndex = src.readerIndex()")
builder.addStatement("%N(src, srcIndex, len)", "writeBytes${order.suffix}${transformation.suffix}")
builder.addStatement("src.readerIndex(srcIndex + len)")
return builder.build()
}
private fun createWriteByteBufIndexLenFunction(order: ArrayOrder, transformation: Transformation): FunSpec {
val builder = FunSpec.builder("writeBytes${order.suffix}${transformation.suffix}")
builder.receiver(ByteBuf::class)
builder.addParameter("src", ByteBuf::class)
builder.addParameter("srcIndex", Int::class)
builder.addParameter("len", Int::class)
builder.addStatement("val index = writerIndex()")
builder.addStatement("ensureWritable(len)")
builder.addStatement("%N(index, src, srcIndex, len)", "setBytes${order.suffix}${transformation.suffix}")
builder.addStatement("writerIndex(index + len)")
return builder.build()
}
}

33
buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/ByteOrder.kt

@ -0,0 +1,33 @@
package org.openrs2.buffer.generator
public enum class ByteOrder(public val suffix: String) {
BIG(""),
LITTLE("LE"),
ALT3("Alt3"),
ALT3_REVERSE("Alt3Reverse");
public fun getShift(i: Int, width: Int): Int {
return when (this) {
BIG -> (width - i - 1) * 8
LITTLE -> i * 8
ALT3 -> {
require(width == 4)
when (i) {
0 -> 16
1 -> 24
2 -> 0
else -> 8
}
}
ALT3_REVERSE -> {
require(width == 4)
when (i) {
0 -> 8
1 -> 0
2 -> 24
else -> 16
}
}
}
}
}

17
buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/GenerateBufferCommand.kt

@ -0,0 +1,17 @@
package org.openrs2.buffer.generator
import com.github.ajalt.clikt.core.CliktCommand
import java.nio.file.Files
import java.nio.file.Path
public fun main(args: Array<String>): Unit = GenerateBufferCommand().main(args)
public class GenerateBufferCommand : CliktCommand(name = "generate-buffer") {
override fun run() {
Files.writeString(PATH, ByteBufExtensionGenerator().generate())
}
private companion object {
private val PATH = Path.of("buffer/src/main/kotlin/org/openrs2/buffer/GeneratedByteBufExtensions.kt")
}
}

24
buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/IntType.kt

@ -0,0 +1,24 @@
package org.openrs2.buffer.generator
import kotlin.reflect.KClass
public enum class IntType(
public val width: Int,
private val signedReadType: KClass<*>,
private val unsignedReadType: KClass<*>,
public val writeType: KClass<*>
) {
BYTE(1, Byte::class, Short::class, Int::class),
SHORT(2, Short::class, Int::class, Int::class),
INT(4, Int::class, Long::class, Int::class);
public val prettyName: String = name.toLowerCase().capitalize()
public fun getReadType(signedness: Signedness): KClass<*> {
return if (signedness == Signedness.SIGNED) {
signedReadType
} else {
unsignedReadType
}
}
}

6
buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/Signedness.kt

@ -0,0 +1,6 @@
package org.openrs2.buffer.generator
public enum class Signedness(public val prefix: String) {
SIGNED(""),
UNSIGNED("Unsigned")
}

13
buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/Transformation.kt

@ -0,0 +1,13 @@
package org.openrs2.buffer.generator
public enum class Transformation(
public val suffix: String,
public val preTransform: String,
public val postReadTransform: String,
public val postWriteTransform: String
) {
IDENTITY("", "", "", ""),
A("A", "", " - 128", " + 128"),
C("C", "-", "", ""),
S("S", "128 - ", "", "")
}

1719
buffer/src/main/kotlin/org/openrs2/buffer/GeneratedByteBufExtensions.kt

File diff suppressed because it is too large

1
gradle/libs.versions.toml

@ -43,6 +43,7 @@ junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version = { strict
junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" }
kotlin-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinCoroutines" }
kotlin-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinCoroutines" }
kotlinPoet = { module = "com.squareup:kotlinpoet", version = "1.8.0" }
ktor-jackson = { module = "io.ktor:ktor-jackson", version.ref = "ktor" }
ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" }
ktor-thymeleaf = { module = "io.ktor:ktor-thymeleaf", version.ref = "ktor" }

1
settings.gradle.kts

@ -29,6 +29,7 @@ include(
"archive",
"asm",
"buffer",
"buffer-generator",
"cache",
"cli",
"compress",

Loading…
Cancel
Save