Fix broken buffer resize

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2022-10-31 10:06:05 +01:00
parent 93718276c5
commit 42195c536b
3 changed files with 45 additions and 4 deletions

View File

@ -256,7 +256,8 @@ public final class NetworkBuffer {
void ensureSize(int length) {
if (!resizable) return;
if (nioBuffer.capacity() < writeIndex + length) {
ByteBuffer newBuffer = ByteBuffer.allocateDirect(nioBuffer.capacity() * 2);
final int newCapacity = Math.max(nioBuffer.capacity() * 2, writeIndex + length);
ByteBuffer newBuffer = ByteBuffer.allocateDirect(newCapacity);
nioBuffer.position(0);
newBuffer.put(nioBuffer);
nioBuffer = newBuffer.clear();

View File

@ -114,28 +114,30 @@ final class NetworkBufferTypes {
(buffer, boxed) -> {
final int value = boxed;
final int index = buffer.writeIndex();
var nio = buffer.nioBuffer;
if ((value & (0xFFFFFFFF << 7)) == 0) {
buffer.ensureSize(1);
nio.put(index, (byte) value);
buffer.nioBuffer.put(index, (byte) value);
return 1;
} else if ((value & (0xFFFFFFFF << 14)) == 0) {
buffer.ensureSize(2);
nio.putShort(index, (short) ((value & 0x7F | 0x80) << 8 | (value >>> 7)));
buffer.nioBuffer.putShort(index, (short) ((value & 0x7F | 0x80) << 8 | (value >>> 7)));
return 2;
} else if ((value & (0xFFFFFFFF << 21)) == 0) {
buffer.ensureSize(3);
var nio = buffer.nioBuffer;
nio.put(index, (byte) (value & 0x7F | 0x80));
nio.put(index + 1, (byte) ((value >>> 7) & 0x7F | 0x80));
nio.put(index + 2, (byte) (value >>> 14));
return 3;
} else if ((value & (0xFFFFFFFF << 28)) == 0) {
buffer.ensureSize(4);
var nio = buffer.nioBuffer;
nio.putInt(index, (value & 0x7F | 0x80) << 24 | (((value >>> 7) & 0x7F | 0x80) << 16)
| ((value >>> 14) & 0x7F | 0x80) << 8 | (value >>> 21));
return 4;
} else {
buffer.ensureSize(5);
var nio = buffer.nioBuffer;
nio.putInt(index, (value & 0x7F | 0x80) << 24 | ((value >>> 7) & 0x7F | 0x80) << 16
| ((value >>> 14) & 0x7F | 0x80) << 8 | ((value >>> 21) & 0x7F | 0x80));
nio.put(index + 4, (byte) (value >>> 28));

View File

@ -17,6 +17,30 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public class NetworkBufferTest {
@Test
public void resize() {
var buffer = new NetworkBuffer(6);
buffer.write(INT, 6);
assertEquals(4, buffer.writeIndex());
buffer.write(INT, 7);
assertEquals(8, buffer.writeIndex());
assertEquals(6, buffer.read(INT));
assertEquals(7, buffer.read(INT));
// Test one-off length
buffer = new NetworkBuffer(1);
buffer.write(BYTE, (byte) 3);
assertEquals(1, buffer.writeIndex());
buffer.write(BYTE, (byte) 4);
assertEquals(2, buffer.writeIndex());
assertEquals((byte) 3, buffer.read(BYTE));
assertEquals((byte) 4, buffer.read(BYTE));
}
@Test
public void readableBytes() {
var buffer = new NetworkBuffer();
@ -264,6 +288,20 @@ public class NetworkBufferTest {
buffer.copyTo(0, bytes, 0, bytes.length);
assertArrayEquals(expected, bytes, "Invalid bytes: " + Arrays.toString(expected) + " != " + Arrays.toString(bytes));
}
// Ensure resize support
{
var tmp = new NetworkBuffer(0);
action.write(tmp, type, value);
assertEquals(0, tmp.readIndex());
if (expected != null) assertEquals(expected.length, tmp.writeIndex());
var tmpRead = action.read(tmp, type);
assertEquals(value, tmpRead);
if (expected != null) assertEquals(expected.length, tmp.readIndex(), "Invalid read index");
if (expected != null) assertEquals(expected.length, tmp.writeIndex());
}
}
static <T> void assertBufferType(NetworkBuffer.@NotNull Type<T> type, @NotNull T value, byte @Nullable [] expected) {