Add a Buffer.writeBytes bulk transfer method
This simplifies some of the ByteToMessageDecoder example code.
This commit is contained in:
parent
d72982a5ef
commit
8c2987a824
@ -377,6 +377,23 @@ public interface Buffer extends Rc<Buffer>, BufferAccessors {
|
||||
*/
|
||||
void copyInto(int srcPos, Buffer dest, int destPos, int length);
|
||||
|
||||
/**
|
||||
* Write into this buffer, all the readable bytes from the given buffer.
|
||||
* This updates the {@linkplain #writerOffset() write offset} of this buffer, and the
|
||||
* {@linkplain #readerOffset() reader offset} of the given buffer.
|
||||
*
|
||||
* @param source The buffer to read from.
|
||||
* @return This buffer.
|
||||
*/
|
||||
default Buffer writeBytes(Buffer source) {
|
||||
int size = source.readableBytes();
|
||||
int woff = writerOffset();
|
||||
writerOffset(woff + size);
|
||||
source.copyInto(source.readerOffset(), this, woff, size);
|
||||
source.readerOffset(source.readerOffset() + size);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the {@linkplain #readerOffset() read offset} and the {@linkplain #writerOffset() write offset} on this
|
||||
* buffer to their initial values.
|
||||
|
@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
|
||||
|
||||
import static java.nio.ByteOrder.BIG_ENDIAN;
|
||||
import static java.nio.ByteOrder.LITTLE_ENDIAN;
|
||||
import static org.assertj.core.api.Assertions.as;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class BufferBulkAccessTest extends BufferTestSupport {
|
||||
@ -301,4 +302,50 @@ public class BufferBulkAccessTest extends BufferTestSupport {
|
||||
assertThat(buf.nativeAddress()).isNotZero();
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("allocators")
|
||||
public void writeBytesMustTransferDataAndUpdateOffsets(Fixture fixture) {
|
||||
try (BufferAllocator alloc1 = fixture.createAllocator()) {
|
||||
for (Fixture otherFixture : allocators()) {
|
||||
try (BufferAllocator alloc2 = otherFixture.createAllocator();
|
||||
Buffer target = alloc1.allocate(37);
|
||||
Buffer source = alloc2.allocate(35)) {
|
||||
// BE to BE
|
||||
target.order(BIG_ENDIAN);
|
||||
source.order(BIG_ENDIAN);
|
||||
verifyWriteBytes(target, source);
|
||||
|
||||
// LE to BE
|
||||
target.fill((byte) 0).reset().order(BIG_ENDIAN);
|
||||
source.fill((byte) 0).reset().order(LITTLE_ENDIAN);
|
||||
verifyWriteBytes(target, source);
|
||||
|
||||
// BE to LE
|
||||
target.fill((byte) 0).reset().order(LITTLE_ENDIAN);
|
||||
source.fill((byte) 0).reset().order(BIG_ENDIAN);
|
||||
verifyWriteBytes(target, source);
|
||||
|
||||
// LE to LE
|
||||
target.fill((byte) 0).reset().order(LITTLE_ENDIAN);
|
||||
source.fill((byte) 0).reset().order(BIG_ENDIAN);
|
||||
verifyWriteBytes(target, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void verifyWriteBytes(Buffer target, Buffer source) {
|
||||
for (int i = 0; i < 35; i++) {
|
||||
source.writeByte((byte) (i + 1));
|
||||
}
|
||||
target.writeBytes(source);
|
||||
assertThat(target.readerOffset()).isZero();
|
||||
assertThat(target.writerOffset()).isEqualTo(35);
|
||||
assertThat(source.readerOffset()).isEqualTo(35);
|
||||
assertThat(source.writerOffset()).isEqualTo(35);
|
||||
try (Buffer readableSlice = target.slice()) {
|
||||
assertEquals(source, readableSlice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,12 +96,10 @@ public abstract class AlternativeMessageDecoder extends ChannelHandlerAdapter {
|
||||
try (Buffer prev = collector) {
|
||||
int requiredCapacity = input.capacity() + prev.readableBytes();
|
||||
collector = allocator.allocate(Math.max(requiredCapacity, DEFAULT_CHUNK_SIZE), input.order());
|
||||
prev.copyInto(prev.readerOffset(), collector, 0, prev.readableBytes());
|
||||
collector.readerOffset(prev.readableBytes());
|
||||
collector.writeBytes(prev);
|
||||
}
|
||||
}
|
||||
input.copyInto(input.readerOffset(), collector, collector.writerOffset(), input.readableBytes());
|
||||
collector.writerOffset(collector.writerOffset() + input.readableBytes());
|
||||
collector.writeBytes(input);
|
||||
drainCollector(ctx);
|
||||
}
|
||||
|
||||
|
@ -110,9 +110,7 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter {
|
||||
// assumed to be shared (e.g. refCnt() > 1) and the reallocation may not be safe.
|
||||
return expandCumulation(alloc, cumulation, in);
|
||||
}
|
||||
in.copyInto(in.readerOffset(), cumulation, cumulation.writerOffset(), required);
|
||||
cumulation.writerOffset(cumulation.writerOffset() + required);
|
||||
in.readerOffset(in.writerOffset());
|
||||
cumulation.writeBytes(in);
|
||||
return cumulation;
|
||||
}
|
||||
};
|
||||
@ -480,9 +478,8 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter {
|
||||
Buffer newCumulation = alloc.allocate(newSize, oldCumulation.order());
|
||||
Buffer toRelease = newCumulation;
|
||||
try {
|
||||
oldCumulation.copyInto(oldCumulation.readerOffset(), newCumulation, 0, oldCumulation.readableBytes());
|
||||
in.copyInto(in.readerOffset(), newCumulation, oldCumulation.readableBytes(), in.readableBytes());
|
||||
newCumulation.writerOffset(oldCumulation.readableBytes() + in.readableBytes());
|
||||
newCumulation.writeBytes(oldCumulation);
|
||||
newCumulation.writeBytes(in);
|
||||
toRelease = oldCumulation;
|
||||
return newCumulation;
|
||||
} finally {
|
||||
|
Loading…
Reference in New Issue
Block a user