Add ByteBuf extension methods for reading/writing smarts

Signed-off-by: Graham <gpe@openrs2.dev>
Graham 4 years ago
parent 4b1c6c7cb7
commit 6314f3625a
  1. 71
      buffer/src/main/java/dev/openrs2/buffer/ByteBufExtensions.kt
  2. 393
      buffer/src/test/java/dev/openrs2/buffer/ByteBufExtensionsTest.kt

@ -0,0 +1,71 @@
package dev.openrs2.buffer
import io.netty.buffer.ByteBuf
public fun ByteBuf.readShortSmart(): Int {
val peek = getUnsignedByte(readerIndex()).toInt()
return if ((peek and 0x80) == 0) {
readUnsignedByte().toInt() - 0x40
} else {
(readUnsignedShort() and 0x7FFF) - 0x4000
}
}
public fun ByteBuf.writeShortSmart(v: Int) {
when (v) {
in -0x40..0x3F -> writeByte(v + 0x40)
in -0x4000..0x3FFF -> writeShort(0x8000 or (v + 0x4000))
else -> throw IllegalArgumentException()
}
}
public fun ByteBuf.readUnsignedShortSmart(): Int {
val peek = getUnsignedByte(readerIndex()).toInt()
return if ((peek and 0x80) == 0) {
readUnsignedByte().toInt()
} else {
readUnsignedShort() and 0x7FFF
}
}
public fun ByteBuf.writeUnsignedShortSmart(v: Int) {
when (v) {
in 0..0x7F -> writeByte(v)
in 0..0x7FFF -> writeShort(0x8000 or v)
else -> throw IllegalArgumentException()
}
}
public fun ByteBuf.readIntSmart(): Int {
val peek = getUnsignedByte(readerIndex()).toInt()
return if ((peek and 0x80) == 0) {
readUnsignedShort() - 0x4000
} else {
(readInt() and 0x7FFFFFFF) - 0x40000000
}
}
public fun ByteBuf.writeIntSmart(v: Int) {
when (v) {
in -0x4000..0x3FFF -> writeShort(v + 0x4000)
in -0x40000000..0x3FFFFFFF -> writeInt(0x80000000.toInt() or (v + 0x40000000))
else -> throw IllegalArgumentException()
}
}
public fun ByteBuf.readUnsignedIntSmart(): Int {
val peek = getUnsignedByte(readerIndex()).toInt()
return if ((peek and 0x80) == 0) {
readUnsignedShort()
} else {
readInt() and 0x7FFFFFFF
}
}
public fun ByteBuf.writeUnsignedIntSmart(v: Int) {
when (v) {
in 0..0x7FFF -> writeShort(v)
in 0..0x7FFFFFFF -> writeInt(0x80000000.toInt() or v)
else -> throw IllegalArgumentException()
}
}

@ -0,0 +1,393 @@
package dev.openrs2.buffer
import io.netty.buffer.Unpooled
import org.junit.jupiter.api.assertThrows
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
object ByteBufExtensionsTest {
@Test
fun testReadShortSmart() {
Unpooled.wrappedBuffer(byteArrayOf(0x00)).use { buf ->
assertEquals(-0x40, buf.readShortSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0x40)).use { buf ->
assertEquals(0, buf.readShortSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0x7F)).use { buf ->
assertEquals(0x3F, buf.readShortSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0x80.toByte(), 0x00)).use { buf ->
assertEquals(-0x4000, buf.readShortSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0xBF.toByte(), 0xBF.toByte())).use { buf ->
assertEquals(-0x41, buf.readShortSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0xC0.toByte(), 0x40.toByte())).use { buf ->
assertEquals(0x40, buf.readShortSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0xFF.toByte(), 0xFF.toByte())).use { buf ->
assertEquals(0x3FFF, buf.readShortSmart())
assertFalse(buf.isReadable)
}
}
@Test
fun testWriteShortSmart() {
Unpooled.wrappedBuffer(byteArrayOf(0x00)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeShortSmart(-0x40)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0x40)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeShortSmart(0)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0x7F)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeShortSmart(0x3F)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0x80.toByte(), 0x00)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeShortSmart(-0x4000)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0xBF.toByte(), 0xBF.toByte())).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeShortSmart(-0x41)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0xC0.toByte(), 0x40.toByte())).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeShortSmart(0x40)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0xFF.toByte(), 0xFF.toByte())).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeShortSmart(0x3FFF)
assertEquals(expected, actual)
}
}
Unpooled.buffer().use { buf ->
assertThrows<IllegalArgumentException> {
buf.writeShortSmart(-0x4001)
}
}
Unpooled.buffer().use { buf ->
assertThrows<IllegalArgumentException> {
buf.writeShortSmart(0x4000)
}
}
}
@Test
fun testReadUnsignedShortSmart() {
Unpooled.wrappedBuffer(byteArrayOf(0x00)).use { buf ->
assertEquals(0, buf.readUnsignedShortSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0x40)).use { buf ->
assertEquals(0x40, buf.readUnsignedShortSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0x7F)).use { buf ->
assertEquals(0x7F, buf.readUnsignedShortSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0x80.toByte(), 0x80.toByte())).use { buf ->
assertEquals(0x80, buf.readUnsignedShortSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0xC0.toByte(), 0x00)).use { buf ->
assertEquals(0x4000, buf.readUnsignedShortSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0xFF.toByte(), 0xFF.toByte())).use { buf ->
assertEquals(0x7FFF, buf.readUnsignedShortSmart())
assertFalse(buf.isReadable)
}
}
@Test
fun testWriteUnsignedShortSmart() {
Unpooled.wrappedBuffer(byteArrayOf(0x00)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeUnsignedShortSmart(0)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0x40)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeUnsignedShortSmart(0x40)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0x7F)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeUnsignedShortSmart(0x7F)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0x80.toByte(), 0x80.toByte())).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeUnsignedShortSmart(0x80)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0xC0.toByte(), 0x00)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeUnsignedShortSmart(0x4000)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0xFF.toByte(), 0xFF.toByte())).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeUnsignedShortSmart(0x7FFF)
assertEquals(expected, actual)
}
}
Unpooled.buffer().use { buf ->
assertThrows<IllegalArgumentException> {
buf.writeUnsignedShortSmart(-0x1)
}
}
Unpooled.buffer().use { buf ->
assertThrows<IllegalArgumentException> {
buf.writeUnsignedShortSmart(0x10000)
}
}
}
@Test
fun testReadIntSmart() {
Unpooled.wrappedBuffer(byteArrayOf(0x00, 0x00)).use { buf ->
assertEquals(-0x4000, buf.readIntSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0x40, 0x00)).use { buf ->
assertEquals(0, buf.readIntSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0x7F, 0xFF.toByte())).use { buf ->
assertEquals(0x3FFF, buf.readIntSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0x80.toByte(), 0x00, 0x00, 0x00)).use { buf ->
assertEquals(-0x40000000, buf.readIntSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0xBF.toByte(), 0xFF.toByte(), 0xBF.toByte(), 0xFF.toByte())).use { buf ->
assertEquals(-0x4001, buf.readIntSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0xC0.toByte(), 0x00, 0x40.toByte(), 0x00)).use { buf ->
assertEquals(0x4000, buf.readIntSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte())).use { buf ->
assertEquals(0x3FFFFFFF, buf.readIntSmart())
assertFalse(buf.isReadable)
}
}
@Test
fun testWriteIntSmart() {
Unpooled.wrappedBuffer(byteArrayOf(0x00, 0x00)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeIntSmart(-0x4000)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0x40, 0x00)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeIntSmart(0)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0x7F, 0xFF.toByte())).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeIntSmart(0x3FFF)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0x80.toByte(), 0x00, 0x00, 0x00)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeIntSmart(-0x40000000)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(
byteArrayOf(0xBF.toByte(), 0xFF.toByte(), 0xBF.toByte(), 0xFF.toByte())
).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeIntSmart(-0x4001)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0xC0.toByte(), 0x00, 0x40.toByte(), 0x00)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeIntSmart(0x4000)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(
byteArrayOf(0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte())
).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeIntSmart(0x3FFFFFFF)
assertEquals(expected, actual)
}
}
Unpooled.buffer().use { buf ->
assertThrows<IllegalArgumentException> {
buf.writeIntSmart(-0x40000001)
}
}
Unpooled.buffer().use { buf ->
assertThrows<IllegalArgumentException> {
buf.writeIntSmart(0x40000000)
}
}
}
@Test
fun testReadUnsignedIntSmart() {
Unpooled.wrappedBuffer(byteArrayOf(0x00, 0x00)).use { buf ->
assertEquals(0, buf.readUnsignedIntSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0x40, 0x00)).use { buf ->
assertEquals(0x4000, buf.readUnsignedIntSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0x7F, 0xFF.toByte())).use { buf ->
assertEquals(0x7FFF, buf.readUnsignedIntSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0x80.toByte(), 0x00, 0x80.toByte(), 0x00)).use { buf ->
assertEquals(0x8000, buf.readUnsignedIntSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0xC0.toByte(), 0x00, 0x00, 0x00)).use { buf ->
assertEquals(0x40000000, buf.readUnsignedIntSmart())
assertFalse(buf.isReadable)
}
Unpooled.wrappedBuffer(byteArrayOf(0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte())).use { buf ->
assertEquals(0x7FFFFFFF, buf.readUnsignedIntSmart())
assertFalse(buf.isReadable)
}
}
@Test
fun testWriteUnsignedIntSmart() {
Unpooled.wrappedBuffer(byteArrayOf(0x00, 0x00)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeUnsignedIntSmart(0)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0x40, 0x00)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeUnsignedIntSmart(0x4000)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0x7F, 0xFF.toByte())).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeUnsignedIntSmart(0x7FFF)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0x80.toByte(), 0x00, 0x80.toByte(), 0x00)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeUnsignedIntSmart(0x8000)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(byteArrayOf(0xC0.toByte(), 0x00, 0x00, 0x00)).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeUnsignedIntSmart(0x40000000)
assertEquals(expected, actual)
}
}
Unpooled.wrappedBuffer(
byteArrayOf(0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte(), 0xFF.toByte())
).use { expected ->
Unpooled.buffer().use { actual ->
actual.writeUnsignedIntSmart(0x7FFFFFFF)
assertEquals(expected, actual)
}
}
Unpooled.buffer().use { buf ->
assertThrows<IllegalArgumentException> {
buf.writeUnsignedIntSmart(0x80000000.toInt())
}
}
}
}
Loading…
Cancel
Save