diff --git a/.idea/runConfigurations/GenerateBuffer.xml b/.idea/runConfigurations/GenerateBuffer.xml
new file mode 100644
index 00000000..ba301b39
--- /dev/null
+++ b/.idea/runConfigurations/GenerateBuffer.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/all/build.gradle.kts b/all/build.gradle.kts
index 64771976..1ac8c0be 100644
--- a/all/build.gradle.kts
+++ b/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)
diff --git a/all/src/main/kotlin/org/openrs2/Command.kt b/all/src/main/kotlin/org/openrs2/Command.kt
index 37211692..7a83abc1 100644
--- a/all/src/main/kotlin/org/openrs2/Command.kt
+++ b/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()
)
}
diff --git a/buffer-generator/build.gradle.kts b/buffer-generator/build.gradle.kts
new file mode 100644
index 00000000..1bf96e3a
--- /dev/null
+++ b/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("maven") {
+ from(components["java"])
+
+ pom {
+ packaging = "jar"
+ name.set("OpenRS2 Buffer Generator")
+ description.set(
+ """
+ Tool for generating Jagex-specific ByteBuf extension methods
+ automatically.
+ """.trimIndent()
+ )
+ }
+ }
+}
diff --git a/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/ArrayOrder.kt b/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/ArrayOrder.kt
new file mode 100644
index 00000000..0920e1a4
--- /dev/null
+++ b/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")
+}
diff --git a/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/ByteBufExtensionGenerator.kt b/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/ByteBufExtensionGenerator.kt
new file mode 100644
index 00000000..6bd537f6
--- /dev/null
+++ b/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()
+ }
+}
diff --git a/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/ByteOrder.kt b/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/ByteOrder.kt
new file mode 100644
index 00000000..2680c0ac
--- /dev/null
+++ b/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
+ }
+ }
+ }
+ }
+}
diff --git a/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/GenerateBufferCommand.kt b/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/GenerateBufferCommand.kt
new file mode 100644
index 00000000..b1fc2d1e
--- /dev/null
+++ b/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): 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")
+ }
+}
diff --git a/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/IntType.kt b/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/IntType.kt
new file mode 100644
index 00000000..22b9911e
--- /dev/null
+++ b/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
+ }
+ }
+}
diff --git a/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/Signedness.kt b/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/Signedness.kt
new file mode 100644
index 00000000..3044cc48
--- /dev/null
+++ b/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")
+}
diff --git a/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/Transformation.kt b/buffer-generator/src/main/kotlin/org/openrs2/buffer/generator/Transformation.kt
new file mode 100644
index 00000000..a3bac8e3
--- /dev/null
+++ b/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 - ", "", "")
+}
diff --git a/buffer/src/main/kotlin/org/openrs2/buffer/GeneratedByteBufExtensions.kt b/buffer/src/main/kotlin/org/openrs2/buffer/GeneratedByteBufExtensions.kt
new file mode 100644
index 00000000..451ffcab
--- /dev/null
+++ b/buffer/src/main/kotlin/org/openrs2/buffer/GeneratedByteBufExtensions.kt
@@ -0,0 +1,1719 @@
+// This file is generated automatically. DO NOT EDIT.
+package org.openrs2.buffer
+
+import io.netty.buffer.ByteBuf
+import io.netty.buffer.Unpooled
+
+public fun ByteBuf.getByteA(index: Int): Byte {
+ var value = 0
+ value = value or (((getByte(index + 0).toInt() - 128) and 0xFF) shl 0)
+ return value.toByte()
+}
+
+public fun ByteBuf.readByteA(): Byte {
+ val index = readerIndex()
+ val result = getByteA(index)
+ readerIndex(index + 1)
+ return result
+}
+
+public fun ByteBuf.getUnsignedByteA(index: Int): Short {
+ var value = 0
+ value = value or (((getByte(index + 0).toInt() - 128) and 0xFF) shl 0)
+ return value.toShort()
+}
+
+public fun ByteBuf.readUnsignedByteA(): Short {
+ val index = readerIndex()
+ val result = getUnsignedByteA(index)
+ readerIndex(index + 1)
+ return result
+}
+
+public fun ByteBuf.setByteA(index: Int, `value`: Int) {
+ setByte(index + 0, (value shr 0) + 128)
+}
+
+public fun ByteBuf.writeByteA(`value`: Int) {
+ val index = writerIndex()
+ ensureWritable(1)
+ setByteA(index, value)
+ writerIndex(index + 1)
+}
+
+public fun ByteBuf.getByteC(index: Int): Byte {
+ var value = 0
+ value = value or (((-getByte(index + 0).toInt()) and 0xFF) shl 0)
+ return value.toByte()
+}
+
+public fun ByteBuf.readByteC(): Byte {
+ val index = readerIndex()
+ val result = getByteC(index)
+ readerIndex(index + 1)
+ return result
+}
+
+public fun ByteBuf.getUnsignedByteC(index: Int): Short {
+ var value = 0
+ value = value or (((-getByte(index + 0).toInt()) and 0xFF) shl 0)
+ return value.toShort()
+}
+
+public fun ByteBuf.readUnsignedByteC(): Short {
+ val index = readerIndex()
+ val result = getUnsignedByteC(index)
+ readerIndex(index + 1)
+ return result
+}
+
+public fun ByteBuf.setByteC(index: Int, `value`: Int) {
+ setByte(index + 0, -(value shr 0))
+}
+
+public fun ByteBuf.writeByteC(`value`: Int) {
+ val index = writerIndex()
+ ensureWritable(1)
+ setByteC(index, value)
+ writerIndex(index + 1)
+}
+
+public fun ByteBuf.getByteS(index: Int): Byte {
+ var value = 0
+ value = value or (((128 - getByte(index + 0).toInt()) and 0xFF) shl 0)
+ return value.toByte()
+}
+
+public fun ByteBuf.readByteS(): Byte {
+ val index = readerIndex()
+ val result = getByteS(index)
+ readerIndex(index + 1)
+ return result
+}
+
+public fun ByteBuf.getUnsignedByteS(index: Int): Short {
+ var value = 0
+ value = value or (((128 - getByte(index + 0).toInt()) and 0xFF) shl 0)
+ return value.toShort()
+}
+
+public fun ByteBuf.readUnsignedByteS(): Short {
+ val index = readerIndex()
+ val result = getUnsignedByteS(index)
+ readerIndex(index + 1)
+ return result
+}
+
+public fun ByteBuf.setByteS(index: Int, `value`: Int) {
+ setByte(index + 0, 128 - (value shr 0))
+}
+
+public fun ByteBuf.writeByteS(`value`: Int) {
+ val index = writerIndex()
+ ensureWritable(1)
+ setByteS(index, value)
+ writerIndex(index + 1)
+}
+
+public fun ByteBuf.getShortA(index: Int): Short {
+ var value = 0
+ value = value or (((getByte(index + 0).toInt()) and 0xFF) shl 8)
+ value = value or (((getByte(index + 1).toInt() - 128) and 0xFF) shl 0)
+ return value.toShort()
+}
+
+public fun ByteBuf.readShortA(): Short {
+ val index = readerIndex()
+ val result = getShortA(index)
+ readerIndex(index + 2)
+ return result
+}
+
+public fun ByteBuf.getUnsignedShortA(index: Int): Int {
+ var value = 0
+ value = value or (((getByte(index + 0).toInt()) and 0xFF) shl 8)
+ value = value or (((getByte(index + 1).toInt() - 128) and 0xFF) shl 0)
+ return value.toInt()
+}
+
+public fun ByteBuf.readUnsignedShortA(): Int {
+ val index = readerIndex()
+ val result = getUnsignedShortA(index)
+ readerIndex(index + 2)
+ return result
+}
+
+public fun ByteBuf.setShortA(index: Int, `value`: Int) {
+ setByte(index + 0, (value shr 8))
+ setByte(index + 1, (value shr 0) + 128)
+}
+
+public fun ByteBuf.writeShortA(`value`: Int) {
+ val index = writerIndex()
+ ensureWritable(2)
+ setShortA(index, value)
+ writerIndex(index + 2)
+}
+
+public fun ByteBuf.getShortC(index: Int): Short {
+ var value = 0
+ value = value or (((getByte(index + 0).toInt()) and 0xFF) shl 8)
+ value = value or (((-getByte(index + 1).toInt()) and 0xFF) shl 0)
+ return value.toShort()
+}
+
+public fun ByteBuf.readShortC(): Short {
+ val index = readerIndex()
+ val result = getShortC(index)
+ readerIndex(index + 2)
+ return result
+}
+
+public fun ByteBuf.getUnsignedShortC(index: Int): Int {
+ var value = 0
+ value = value or (((getByte(index + 0).toInt()) and 0xFF) shl 8)
+ value = value or (((-getByte(index + 1).toInt()) and 0xFF) shl 0)
+ return value.toInt()
+}
+
+public fun ByteBuf.readUnsignedShortC(): Int {
+ val index = readerIndex()
+ val result = getUnsignedShortC(index)
+ readerIndex(index + 2)
+ return result
+}
+
+public fun ByteBuf.setShortC(index: Int, `value`: Int) {
+ setByte(index + 0, (value shr 8))
+ setByte(index + 1, -(value shr 0))
+}
+
+public fun ByteBuf.writeShortC(`value`: Int) {
+ val index = writerIndex()
+ ensureWritable(2)
+ setShortC(index, value)
+ writerIndex(index + 2)
+}
+
+public fun ByteBuf.getShortS(index: Int): Short {
+ var value = 0
+ value = value or (((getByte(index + 0).toInt()) and 0xFF) shl 8)
+ value = value or (((128 - getByte(index + 1).toInt()) and 0xFF) shl 0)
+ return value.toShort()
+}
+
+public fun ByteBuf.readShortS(): Short {
+ val index = readerIndex()
+ val result = getShortS(index)
+ readerIndex(index + 2)
+ return result
+}
+
+public fun ByteBuf.getUnsignedShortS(index: Int): Int {
+ var value = 0
+ value = value or (((getByte(index + 0).toInt()) and 0xFF) shl 8)
+ value = value or (((128 - getByte(index + 1).toInt()) and 0xFF) shl 0)
+ return value.toInt()
+}
+
+public fun ByteBuf.readUnsignedShortS(): Int {
+ val index = readerIndex()
+ val result = getUnsignedShortS(index)
+ readerIndex(index + 2)
+ return result
+}
+
+public fun ByteBuf.setShortS(index: Int, `value`: Int) {
+ setByte(index + 0, (value shr 8))
+ setByte(index + 1, 128 - (value shr 0))
+}
+
+public fun ByteBuf.writeShortS(`value`: Int) {
+ val index = writerIndex()
+ ensureWritable(2)
+ setShortS(index, value)
+ writerIndex(index + 2)
+}
+
+public fun ByteBuf.getShortLEA(index: Int): Short {
+ var value = 0
+ value = value or (((getByte(index + 0).toInt() - 128) and 0xFF) shl 0)
+ value = value or (((getByte(index + 1).toInt()) and 0xFF) shl 8)
+ return value.toShort()
+}
+
+public fun ByteBuf.readShortLEA(): Short {
+ val index = readerIndex()
+ val result = getShortLEA(index)
+ readerIndex(index + 2)
+ return result
+}
+
+public fun ByteBuf.getUnsignedShortLEA(index: Int): Int {
+ var value = 0
+ value = value or (((getByte(index + 0).toInt() - 128) and 0xFF) shl 0)
+ value = value or (((getByte(index + 1).toInt()) and 0xFF) shl 8)
+ return value.toInt()
+}
+
+public fun ByteBuf.readUnsignedShortLEA(): Int {
+ val index = readerIndex()
+ val result = getUnsignedShortLEA(index)
+ readerIndex(index + 2)
+ return result
+}
+
+public fun ByteBuf.setShortLEA(index: Int, `value`: Int) {
+ setByte(index + 0, (value shr 0) + 128)
+ setByte(index + 1, (value shr 8))
+}
+
+public fun ByteBuf.writeShortLEA(`value`: Int) {
+ val index = writerIndex()
+ ensureWritable(2)
+ setShortLEA(index, value)
+ writerIndex(index + 2)
+}
+
+public fun ByteBuf.getShortLEC(index: Int): Short {
+ var value = 0
+ value = value or (((-getByte(index + 0).toInt()) and 0xFF) shl 0)
+ value = value or (((getByte(index + 1).toInt()) and 0xFF) shl 8)
+ return value.toShort()
+}
+
+public fun ByteBuf.readShortLEC(): Short {
+ val index = readerIndex()
+ val result = getShortLEC(index)
+ readerIndex(index + 2)
+ return result
+}
+
+public fun ByteBuf.getUnsignedShortLEC(index: Int): Int {
+ var value = 0
+ value = value or (((-getByte(index + 0).toInt()) and 0xFF) shl 0)
+ value = value or (((getByte(index + 1).toInt()) and 0xFF) shl 8)
+ return value.toInt()
+}
+
+public fun ByteBuf.readUnsignedShortLEC(): Int {
+ val index = readerIndex()
+ val result = getUnsignedShortLEC(index)
+ readerIndex(index + 2)
+ return result
+}
+
+public fun ByteBuf.setShortLEC(index: Int, `value`: Int) {
+ setByte(index + 0, -(value shr 0))
+ setByte(index + 1, (value shr 8))
+}
+
+public fun ByteBuf.writeShortLEC(`value`: Int) {
+ val index = writerIndex()
+ ensureWritable(2)
+ setShortLEC(index, value)
+ writerIndex(index + 2)
+}
+
+public fun ByteBuf.getShortLES(index: Int): Short {
+ var value = 0
+ value = value or (((128 - getByte(index + 0).toInt()) and 0xFF) shl 0)
+ value = value or (((getByte(index + 1).toInt()) and 0xFF) shl 8)
+ return value.toShort()
+}
+
+public fun ByteBuf.readShortLES(): Short {
+ val index = readerIndex()
+ val result = getShortLES(index)
+ readerIndex(index + 2)
+ return result
+}
+
+public fun ByteBuf.getUnsignedShortLES(index: Int): Int {
+ var value = 0
+ value = value or (((128 - getByte(index + 0).toInt()) and 0xFF) shl 0)
+ value = value or (((getByte(index + 1).toInt()) and 0xFF) shl 8)
+ return value.toInt()
+}
+
+public fun ByteBuf.readUnsignedShortLES(): Int {
+ val index = readerIndex()
+ val result = getUnsignedShortLES(index)
+ readerIndex(index + 2)
+ return result
+}
+
+public fun ByteBuf.setShortLES(index: Int, `value`: Int) {
+ setByte(index + 0, 128 - (value shr 0))
+ setByte(index + 1, (value shr 8))
+}
+
+public fun ByteBuf.writeShortLES(`value`: Int) {
+ val index = writerIndex()
+ ensureWritable(2)
+ setShortLES(index, value)
+ writerIndex(index + 2)
+}
+
+public fun ByteBuf.getIntAlt3(index: Int): Int {
+ var value = 0
+ value = value or (((getByte(index + 0).toInt()) and 0xFF) shl 16)
+ value = value or (((getByte(index + 1).toInt()) and 0xFF) shl 24)
+ value = value or (((getByte(index + 2).toInt()) and 0xFF) shl 0)
+ value = value or (((getByte(index + 3).toInt()) and 0xFF) shl 8)
+ return value.toInt()
+}
+
+public fun ByteBuf.readIntAlt3(): Int {
+ val index = readerIndex()
+ val result = getIntAlt3(index)
+ readerIndex(index + 4)
+ return result
+}
+
+public fun ByteBuf.setIntAlt3(index: Int, `value`: Int) {
+ setByte(index + 0, (value shr 16))
+ setByte(index + 1, (value shr 24))
+ setByte(index + 2, (value shr 0))
+ setByte(index + 3, (value shr 8))
+}
+
+public fun ByteBuf.writeIntAlt3(`value`: Int) {
+ val index = writerIndex()
+ ensureWritable(4)
+ setIntAlt3(index, value)
+ writerIndex(index + 4)
+}
+
+public fun ByteBuf.getIntAlt3Reverse(index: Int): Int {
+ var value = 0
+ value = value or (((getByte(index + 0).toInt()) and 0xFF) shl 8)
+ value = value or (((getByte(index + 1).toInt()) and 0xFF) shl 0)
+ value = value or (((getByte(index + 2).toInt()) and 0xFF) shl 24)
+ value = value or (((getByte(index + 3).toInt()) and 0xFF) shl 16)
+ return value.toInt()
+}
+
+public fun ByteBuf.readIntAlt3Reverse(): Int {
+ val index = readerIndex()
+ val result = getIntAlt3Reverse(index)
+ readerIndex(index + 4)
+ return result
+}
+
+public fun ByteBuf.setIntAlt3Reverse(index: Int, `value`: Int) {
+ setByte(index + 0, (value shr 8))
+ setByte(index + 1, (value shr 0))
+ setByte(index + 2, (value shr 24))
+ setByte(index + 3, (value shr 16))
+}
+
+public fun ByteBuf.writeIntAlt3Reverse(`value`: Int) {
+ val index = writerIndex()
+ ensureWritable(4)
+ setIntAlt3Reverse(index, value)
+ writerIndex(index + 4)
+}
+
+public fun ByteBuf.getBytesA(index: Int, dst: ByteArray) {
+ getBytesA(index, dst, 0, dst.size)
+}
+
+public fun ByteBuf.getBytesA(
+ index: Int,
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ getBytes(index, dst, dstIndex, len)
+ for (i in 0 until len) {
+ dst[dstIndex + i] = (dst[dstIndex + i].toInt() - 128).toByte()
+ }
+}
+
+public fun ByteBuf.getBytesA(index: Int, dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ getBytesA(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesA(
+ index: Int,
+ dst: ByteBuf,
+ len: Int
+) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ getBytesA(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesA(
+ index: Int,
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ dst.setByte(dstIndex + i, getByteA(index + i).toInt())
+ }
+}
+
+public fun ByteBuf.readBytesA(dst: ByteArray) {
+ readBytesA(dst, 0, dst.size)
+}
+
+public fun ByteBuf.readBytesA(
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesA(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesA(dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ readBytesA(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesA(dst: ByteBuf, len: Int) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ readBytesA(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesA(
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesA(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesA(len: Int): ByteBuf {
+ if (len == 0) {
+ return Unpooled.EMPTY_BUFFER
+ }
+ alloc().buffer(len).use { dst ->
+ readBytesA(dst, len)
+ return dst.retain()
+ }
+}
+
+public fun ByteBuf.setBytesA(index: Int, src: ByteArray) {
+ setBytesA(index, src, 0, src.size)
+}
+
+public fun ByteBuf.setBytesA(
+ index: Int,
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ Unpooled.wrappedBuffer(src).use { buf ->
+ setBytesA(index, buf, srcIndex, len)
+ }
+}
+
+public fun ByteBuf.setBytesA(index: Int, src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ setBytesA(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesA(
+ index: Int,
+ src: ByteBuf,
+ len: Int
+) {
+ val srcIndex = src.readerIndex()
+ setBytesA(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesA(
+ index: Int,
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ setByteA(index + i, src.getByte(srcIndex + i).toInt())
+ }
+}
+
+public fun ByteBuf.writeBytesA(src: ByteArray) {
+ writeBytesA(src, 0, src.size)
+}
+
+public fun ByteBuf.writeBytesA(
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesA(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.writeBytesA(src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ writeBytesA(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesA(src: ByteBuf, len: Int) {
+ val srcIndex = src.readerIndex()
+ writeBytesA(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesA(
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesA(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.getBytesC(index: Int, dst: ByteArray) {
+ getBytesC(index, dst, 0, dst.size)
+}
+
+public fun ByteBuf.getBytesC(
+ index: Int,
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ getBytes(index, dst, dstIndex, len)
+ for (i in 0 until len) {
+ dst[dstIndex + i] = (-dst[dstIndex + i].toInt()).toByte()
+ }
+}
+
+public fun ByteBuf.getBytesC(index: Int, dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ getBytesC(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesC(
+ index: Int,
+ dst: ByteBuf,
+ len: Int
+) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ getBytesC(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesC(
+ index: Int,
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ dst.setByte(dstIndex + i, getByteC(index + i).toInt())
+ }
+}
+
+public fun ByteBuf.readBytesC(dst: ByteArray) {
+ readBytesC(dst, 0, dst.size)
+}
+
+public fun ByteBuf.readBytesC(
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesC(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesC(dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ readBytesC(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesC(dst: ByteBuf, len: Int) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ readBytesC(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesC(
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesC(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesC(len: Int): ByteBuf {
+ if (len == 0) {
+ return Unpooled.EMPTY_BUFFER
+ }
+ alloc().buffer(len).use { dst ->
+ readBytesC(dst, len)
+ return dst.retain()
+ }
+}
+
+public fun ByteBuf.setBytesC(index: Int, src: ByteArray) {
+ setBytesC(index, src, 0, src.size)
+}
+
+public fun ByteBuf.setBytesC(
+ index: Int,
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ Unpooled.wrappedBuffer(src).use { buf ->
+ setBytesC(index, buf, srcIndex, len)
+ }
+}
+
+public fun ByteBuf.setBytesC(index: Int, src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ setBytesC(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesC(
+ index: Int,
+ src: ByteBuf,
+ len: Int
+) {
+ val srcIndex = src.readerIndex()
+ setBytesC(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesC(
+ index: Int,
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ setByteC(index + i, src.getByte(srcIndex + i).toInt())
+ }
+}
+
+public fun ByteBuf.writeBytesC(src: ByteArray) {
+ writeBytesC(src, 0, src.size)
+}
+
+public fun ByteBuf.writeBytesC(
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesC(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.writeBytesC(src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ writeBytesC(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesC(src: ByteBuf, len: Int) {
+ val srcIndex = src.readerIndex()
+ writeBytesC(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesC(
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesC(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.getBytesS(index: Int, dst: ByteArray) {
+ getBytesS(index, dst, 0, dst.size)
+}
+
+public fun ByteBuf.getBytesS(
+ index: Int,
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ getBytes(index, dst, dstIndex, len)
+ for (i in 0 until len) {
+ dst[dstIndex + i] = (128 - dst[dstIndex + i].toInt()).toByte()
+ }
+}
+
+public fun ByteBuf.getBytesS(index: Int, dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ getBytesS(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesS(
+ index: Int,
+ dst: ByteBuf,
+ len: Int
+) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ getBytesS(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesS(
+ index: Int,
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ dst.setByte(dstIndex + i, getByteS(index + i).toInt())
+ }
+}
+
+public fun ByteBuf.readBytesS(dst: ByteArray) {
+ readBytesS(dst, 0, dst.size)
+}
+
+public fun ByteBuf.readBytesS(
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesS(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesS(dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ readBytesS(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesS(dst: ByteBuf, len: Int) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ readBytesS(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesS(
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesS(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesS(len: Int): ByteBuf {
+ if (len == 0) {
+ return Unpooled.EMPTY_BUFFER
+ }
+ alloc().buffer(len).use { dst ->
+ readBytesS(dst, len)
+ return dst.retain()
+ }
+}
+
+public fun ByteBuf.setBytesS(index: Int, src: ByteArray) {
+ setBytesS(index, src, 0, src.size)
+}
+
+public fun ByteBuf.setBytesS(
+ index: Int,
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ Unpooled.wrappedBuffer(src).use { buf ->
+ setBytesS(index, buf, srcIndex, len)
+ }
+}
+
+public fun ByteBuf.setBytesS(index: Int, src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ setBytesS(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesS(
+ index: Int,
+ src: ByteBuf,
+ len: Int
+) {
+ val srcIndex = src.readerIndex()
+ setBytesS(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesS(
+ index: Int,
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ setByteS(index + i, src.getByte(srcIndex + i).toInt())
+ }
+}
+
+public fun ByteBuf.writeBytesS(src: ByteArray) {
+ writeBytesS(src, 0, src.size)
+}
+
+public fun ByteBuf.writeBytesS(
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesS(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.writeBytesS(src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ writeBytesS(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesS(src: ByteBuf, len: Int) {
+ val srcIndex = src.readerIndex()
+ writeBytesS(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesS(
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesS(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.getBytesReverse(index: Int, dst: ByteArray) {
+ getBytesReverse(index, dst, 0, dst.size)
+}
+
+public fun ByteBuf.getBytesReverse(
+ index: Int,
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ getBytes(index, dst, dstIndex, len)
+ for (i in 0 until len) {
+ dst[dstIndex + i] = (dst[dstIndex + i].toInt()).toByte()
+ }
+ dst.reverse(dstIndex, dstIndex + len)
+}
+
+public fun ByteBuf.getBytesReverse(index: Int, dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ getBytesReverse(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesReverse(
+ index: Int,
+ dst: ByteBuf,
+ len: Int
+) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ getBytesReverse(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesReverse(
+ index: Int,
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ dst.setByte(dstIndex + i, getByte(index + len - i - 1).toInt())
+ }
+}
+
+public fun ByteBuf.readBytesReverse(dst: ByteArray) {
+ readBytesReverse(dst, 0, dst.size)
+}
+
+public fun ByteBuf.readBytesReverse(
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesReverse(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesReverse(dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ readBytesReverse(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesReverse(dst: ByteBuf, len: Int) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ readBytesReverse(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesReverse(
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesReverse(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesReverse(len: Int): ByteBuf {
+ if (len == 0) {
+ return Unpooled.EMPTY_BUFFER
+ }
+ alloc().buffer(len).use { dst ->
+ readBytesReverse(dst, len)
+ return dst.retain()
+ }
+}
+
+public fun ByteBuf.setBytesReverse(index: Int, src: ByteArray) {
+ setBytesReverse(index, src, 0, src.size)
+}
+
+public fun ByteBuf.setBytesReverse(
+ index: Int,
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ Unpooled.wrappedBuffer(src).use { buf ->
+ setBytesReverse(index, buf, srcIndex, len)
+ }
+}
+
+public fun ByteBuf.setBytesReverse(index: Int, src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ setBytesReverse(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesReverse(
+ index: Int,
+ src: ByteBuf,
+ len: Int
+) {
+ val srcIndex = src.readerIndex()
+ setBytesReverse(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesReverse(
+ index: Int,
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ setByte(index + i, src.getByte(srcIndex + len - i - 1).toInt())
+ }
+}
+
+public fun ByteBuf.writeBytesReverse(src: ByteArray) {
+ writeBytesReverse(src, 0, src.size)
+}
+
+public fun ByteBuf.writeBytesReverse(
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesReverse(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.writeBytesReverse(src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ writeBytesReverse(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesReverse(src: ByteBuf, len: Int) {
+ val srcIndex = src.readerIndex()
+ writeBytesReverse(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesReverse(
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesReverse(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.getBytesReverseA(index: Int, dst: ByteArray) {
+ getBytesReverseA(index, dst, 0, dst.size)
+}
+
+public fun ByteBuf.getBytesReverseA(
+ index: Int,
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ getBytes(index, dst, dstIndex, len)
+ for (i in 0 until len) {
+ dst[dstIndex + i] = (dst[dstIndex + i].toInt() - 128).toByte()
+ }
+ dst.reverse(dstIndex, dstIndex + len)
+}
+
+public fun ByteBuf.getBytesReverseA(index: Int, dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ getBytesReverseA(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesReverseA(
+ index: Int,
+ dst: ByteBuf,
+ len: Int
+) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ getBytesReverseA(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesReverseA(
+ index: Int,
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ dst.setByte(dstIndex + i, getByteA(index + len - i - 1).toInt())
+ }
+}
+
+public fun ByteBuf.readBytesReverseA(dst: ByteArray) {
+ readBytesReverseA(dst, 0, dst.size)
+}
+
+public fun ByteBuf.readBytesReverseA(
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesReverseA(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesReverseA(dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ readBytesReverseA(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesReverseA(dst: ByteBuf, len: Int) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ readBytesReverseA(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesReverseA(
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesReverseA(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesReverseA(len: Int): ByteBuf {
+ if (len == 0) {
+ return Unpooled.EMPTY_BUFFER
+ }
+ alloc().buffer(len).use { dst ->
+ readBytesReverseA(dst, len)
+ return dst.retain()
+ }
+}
+
+public fun ByteBuf.setBytesReverseA(index: Int, src: ByteArray) {
+ setBytesReverseA(index, src, 0, src.size)
+}
+
+public fun ByteBuf.setBytesReverseA(
+ index: Int,
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ Unpooled.wrappedBuffer(src).use { buf ->
+ setBytesReverseA(index, buf, srcIndex, len)
+ }
+}
+
+public fun ByteBuf.setBytesReverseA(index: Int, src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ setBytesReverseA(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesReverseA(
+ index: Int,
+ src: ByteBuf,
+ len: Int
+) {
+ val srcIndex = src.readerIndex()
+ setBytesReverseA(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesReverseA(
+ index: Int,
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ setByteA(index + i, src.getByte(srcIndex + len - i - 1).toInt())
+ }
+}
+
+public fun ByteBuf.writeBytesReverseA(src: ByteArray) {
+ writeBytesReverseA(src, 0, src.size)
+}
+
+public fun ByteBuf.writeBytesReverseA(
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesReverseA(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.writeBytesReverseA(src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ writeBytesReverseA(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesReverseA(src: ByteBuf, len: Int) {
+ val srcIndex = src.readerIndex()
+ writeBytesReverseA(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesReverseA(
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesReverseA(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.getBytesReverseC(index: Int, dst: ByteArray) {
+ getBytesReverseC(index, dst, 0, dst.size)
+}
+
+public fun ByteBuf.getBytesReverseC(
+ index: Int,
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ getBytes(index, dst, dstIndex, len)
+ for (i in 0 until len) {
+ dst[dstIndex + i] = (-dst[dstIndex + i].toInt()).toByte()
+ }
+ dst.reverse(dstIndex, dstIndex + len)
+}
+
+public fun ByteBuf.getBytesReverseC(index: Int, dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ getBytesReverseC(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesReverseC(
+ index: Int,
+ dst: ByteBuf,
+ len: Int
+) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ getBytesReverseC(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesReverseC(
+ index: Int,
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ dst.setByte(dstIndex + i, getByteC(index + len - i - 1).toInt())
+ }
+}
+
+public fun ByteBuf.readBytesReverseC(dst: ByteArray) {
+ readBytesReverseC(dst, 0, dst.size)
+}
+
+public fun ByteBuf.readBytesReverseC(
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesReverseC(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesReverseC(dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ readBytesReverseC(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesReverseC(dst: ByteBuf, len: Int) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ readBytesReverseC(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesReverseC(
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesReverseC(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesReverseC(len: Int): ByteBuf {
+ if (len == 0) {
+ return Unpooled.EMPTY_BUFFER
+ }
+ alloc().buffer(len).use { dst ->
+ readBytesReverseC(dst, len)
+ return dst.retain()
+ }
+}
+
+public fun ByteBuf.setBytesReverseC(index: Int, src: ByteArray) {
+ setBytesReverseC(index, src, 0, src.size)
+}
+
+public fun ByteBuf.setBytesReverseC(
+ index: Int,
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ Unpooled.wrappedBuffer(src).use { buf ->
+ setBytesReverseC(index, buf, srcIndex, len)
+ }
+}
+
+public fun ByteBuf.setBytesReverseC(index: Int, src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ setBytesReverseC(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesReverseC(
+ index: Int,
+ src: ByteBuf,
+ len: Int
+) {
+ val srcIndex = src.readerIndex()
+ setBytesReverseC(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesReverseC(
+ index: Int,
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ setByteC(index + i, src.getByte(srcIndex + len - i - 1).toInt())
+ }
+}
+
+public fun ByteBuf.writeBytesReverseC(src: ByteArray) {
+ writeBytesReverseC(src, 0, src.size)
+}
+
+public fun ByteBuf.writeBytesReverseC(
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesReverseC(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.writeBytesReverseC(src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ writeBytesReverseC(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesReverseC(src: ByteBuf, len: Int) {
+ val srcIndex = src.readerIndex()
+ writeBytesReverseC(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesReverseC(
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesReverseC(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.getBytesReverseS(index: Int, dst: ByteArray) {
+ getBytesReverseS(index, dst, 0, dst.size)
+}
+
+public fun ByteBuf.getBytesReverseS(
+ index: Int,
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ getBytes(index, dst, dstIndex, len)
+ for (i in 0 until len) {
+ dst[dstIndex + i] = (128 - dst[dstIndex + i].toInt()).toByte()
+ }
+ dst.reverse(dstIndex, dstIndex + len)
+}
+
+public fun ByteBuf.getBytesReverseS(index: Int, dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ getBytesReverseS(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesReverseS(
+ index: Int,
+ dst: ByteBuf,
+ len: Int
+) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ getBytesReverseS(index, dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.getBytesReverseS(
+ index: Int,
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ dst.setByte(dstIndex + i, getByteS(index + len - i - 1).toInt())
+ }
+}
+
+public fun ByteBuf.readBytesReverseS(dst: ByteArray) {
+ readBytesReverseS(dst, 0, dst.size)
+}
+
+public fun ByteBuf.readBytesReverseS(
+ dst: ByteArray,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesReverseS(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesReverseS(dst: ByteBuf) {
+ val dstIndex = dst.writerIndex()
+ val len = dst.writableBytes()
+ dst.ensureWritable(len)
+ readBytesReverseS(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesReverseS(dst: ByteBuf, len: Int) {
+ val dstIndex = dst.writerIndex()
+ dst.ensureWritable(len)
+ readBytesReverseS(dst, dstIndex, len)
+ dst.writerIndex(dstIndex + len)
+}
+
+public fun ByteBuf.readBytesReverseS(
+ dst: ByteBuf,
+ dstIndex: Int,
+ len: Int
+) {
+ val index = readerIndex()
+ getBytesReverseS(index, dst, dstIndex, len)
+ readerIndex(index + len)
+}
+
+public fun ByteBuf.readBytesReverseS(len: Int): ByteBuf {
+ if (len == 0) {
+ return Unpooled.EMPTY_BUFFER
+ }
+ alloc().buffer(len).use { dst ->
+ readBytesReverseS(dst, len)
+ return dst.retain()
+ }
+}
+
+public fun ByteBuf.setBytesReverseS(index: Int, src: ByteArray) {
+ setBytesReverseS(index, src, 0, src.size)
+}
+
+public fun ByteBuf.setBytesReverseS(
+ index: Int,
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ Unpooled.wrappedBuffer(src).use { buf ->
+ setBytesReverseS(index, buf, srcIndex, len)
+ }
+}
+
+public fun ByteBuf.setBytesReverseS(index: Int, src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ setBytesReverseS(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesReverseS(
+ index: Int,
+ src: ByteBuf,
+ len: Int
+) {
+ val srcIndex = src.readerIndex()
+ setBytesReverseS(index, src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.setBytesReverseS(
+ index: Int,
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ for (i in 0 until len) {
+ setByteS(index + i, src.getByte(srcIndex + len - i - 1).toInt())
+ }
+}
+
+public fun ByteBuf.writeBytesReverseS(src: ByteArray) {
+ writeBytesReverseS(src, 0, src.size)
+}
+
+public fun ByteBuf.writeBytesReverseS(
+ src: ByteArray,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesReverseS(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.writeBytesReverseS(src: ByteBuf) {
+ val srcIndex = src.readerIndex()
+ val len = src.readableBytes()
+ writeBytesReverseS(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesReverseS(src: ByteBuf, len: Int) {
+ val srcIndex = src.readerIndex()
+ writeBytesReverseS(src, srcIndex, len)
+ src.readerIndex(srcIndex + len)
+}
+
+public fun ByteBuf.writeBytesReverseS(
+ src: ByteBuf,
+ srcIndex: Int,
+ len: Int
+) {
+ val index = writerIndex()
+ ensureWritable(len)
+ setBytesReverseS(index, src, srcIndex, len)
+ writerIndex(index + len)
+}
+
+public fun ByteBuf.getBooleanA(index: Int): Boolean = getByteA(index).toInt() != 0
+
+public fun ByteBuf.readBooleanA(): Boolean = readByteA().toInt() != 0
+
+public fun ByteBuf.setBooleanA(index: Int, `value`: Boolean) {
+ if (value) {
+ setByteA(index, 1)
+ } else {
+ setByteA(index, 0)
+ }
+}
+
+public fun ByteBuf.writeBooleanA(`value`: Boolean) {
+ if (value) {
+ writeByteA(1)
+ } else {
+ writeByteA(0)
+ }
+}
+
+public fun ByteBuf.getBooleanC(index: Int): Boolean = getByteC(index).toInt() != 0
+
+public fun ByteBuf.readBooleanC(): Boolean = readByteC().toInt() != 0
+
+public fun ByteBuf.setBooleanC(index: Int, `value`: Boolean) {
+ if (value) {
+ setByteC(index, 1)
+ } else {
+ setByteC(index, 0)
+ }
+}
+
+public fun ByteBuf.writeBooleanC(`value`: Boolean) {
+ if (value) {
+ writeByteC(1)
+ } else {
+ writeByteC(0)
+ }
+}
+
+public fun ByteBuf.getBooleanS(index: Int): Boolean = getByteS(index).toInt() != 0
+
+public fun ByteBuf.readBooleanS(): Boolean = readByteS().toInt() != 0
+
+public fun ByteBuf.setBooleanS(index: Int, `value`: Boolean) {
+ if (value) {
+ setByteS(index, 1)
+ } else {
+ setByteS(index, 0)
+ }
+}
+
+public fun ByteBuf.writeBooleanS(`value`: Boolean) {
+ if (value) {
+ writeByteS(1)
+ } else {
+ writeByteS(0)
+ }
+}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index ec49cced..6d90db7c 100644
--- a/gradle/libs.versions.toml
+++ b/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" }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index ab21ea18..ca06ab9a 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -29,6 +29,7 @@ include(
"archive",
"asm",
"buffer",
+ "buffer-generator",
"cache",
"cli",
"compress",