Add CRC-32 extension method to the ByteBuf class

Signed-off-by: Graham <gpe@openrs2.dev>
bzip2
Graham 4 years ago
parent 7887a4dff1
commit a4234d066d
  1. 28
      buffer/src/main/java/dev/openrs2/buffer/ByteBufExtensions.kt
  2. 60
      buffer/src/test/java/dev/openrs2/buffer/ByteBufExtensionsTest.kt

@ -1,6 +1,8 @@
package dev.openrs2.buffer package dev.openrs2.buffer
import io.netty.buffer.ByteBuf import io.netty.buffer.ByteBuf
import io.netty.buffer.ByteBufUtil
import java.util.zip.CRC32
public fun ByteBuf.readShortSmart(): Int { public fun ByteBuf.readShortSmart(): Int {
val peek = getUnsignedByte(readerIndex()).toInt() val peek = getUnsignedByte(readerIndex()).toInt()
@ -77,3 +79,29 @@ public fun ByteBuf.writeUnsignedIntSmart(v: Int): ByteBuf {
return this return this
} }
public fun ByteBuf.crc32(): Int {
return crc32(readerIndex(), readableBytes())
}
public fun ByteBuf.crc32(index: Int, len: Int): Int {
if (index < 0 || index >= capacity() || len < 0 || (index + len) >= capacity()) {
throw IndexOutOfBoundsException()
}
val crc = CRC32()
val count = nioBufferCount()
when {
hasArray() -> crc.update(array(), arrayOffset() + index, len)
count > 1 -> {
for (b in nioBuffers(index, len)) {
crc.update(b)
}
}
count == 1 -> crc.update(nioBuffer(index, len))
else -> crc.update(ByteBufUtil.getBytes(this, index, len))
}
return crc.value.toInt()
}

@ -391,4 +391,64 @@ object ByteBufExtensionsTest {
} }
} }
} }
@Test
fun testCrc32() {
val s = "AAThe quick brown fox jumps over the lazy dogA"
/*
* Tests the hasArray() case. The slicedBuf trickery is to allow us
* to test a non-zero arrayOffset().
*/
Unpooled.wrappedBuffer(s.toByteArray()).use { buf ->
val slicedBuf = buf.slice(1, buf.readableBytes() - 1)
assertEquals(0x414FA339, slicedBuf.crc32(1, slicedBuf.writerIndex() - 2))
}
// Tests the nioBufferCount() == 1 case.
Unpooled.wrappedBuffer(s.toByteArray()).use { buf ->
ByteBufAllocator.DEFAULT.directBuffer().use { directBuf ->
directBuf.writeBytes(buf, 0, buf.capacity())
assertEquals(0x414FA339, directBuf.crc32(2, directBuf.writerIndex() - 3))
}
}
// Tests the nioBufferCount() > 1 case.
Unpooled.wrappedBuffer(
Unpooled.wrappedBuffer("AAThe quick brown fox ".toByteArray()),
Unpooled.wrappedBuffer("jumps over the lazy dogA".toByteArray())
).use { buf ->
assertEquals(0x414FA339, buf.crc32(2, buf.writerIndex() - 3))
}
/*
* Check the crc32() method (with no arguments) sets the index/length
* correctly.
*/
Unpooled.wrappedBuffer(s.toByteArray()).use { buf ->
buf.readerIndex(2)
buf.writerIndex(buf.writerIndex() - 1)
assertEquals(0x414FA339, buf.crc32())
}
}
@Test
fun testCrc32Bounds() {
assertThrows<IndexOutOfBoundsException> {
Unpooled.EMPTY_BUFFER.crc32(-1, 0)
}
assertThrows<IndexOutOfBoundsException> {
Unpooled.EMPTY_BUFFER.crc32(0, -1)
}
assertThrows<IndexOutOfBoundsException> {
Unpooled.EMPTY_BUFFER.crc32(1, 0)
}
assertThrows<IndexOutOfBoundsException> {
Unpooled.EMPTY_BUFFER.crc32(0, 1)
}
}
} }

Loading…
Cancel
Save