Add CharSequence operations to ByteBuf
Motivation: Often users either need to read or write CharSequences to a ByteBuf. We should add methods for this to ByteBuf as we can do some optimizations for this depending on the implementation. Modifications: Add setCharSequence, writeCharSequence, getCharSequence and readCharSequence Result: Easier reading / writing of CharSequence with ByteBuf.
This commit is contained in:
parent
b2bb72b2de
commit
9f5eb7d698
@ -16,6 +16,7 @@
|
||||
package io.netty.buffer;
|
||||
|
||||
import io.netty.util.ByteProcessor;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import io.netty.util.IllegalReferenceCountException;
|
||||
import io.netty.util.ResourceLeakDetector;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
@ -483,6 +484,19 @@ public abstract class AbstractByteBuf extends ByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharSequence(int index, int length, Charset charset) {
|
||||
// TODO: We could optimize this for UTF8 and US_ASCII
|
||||
return toString(index, length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence readCharSequence(int length, Charset charset) {
|
||||
CharSequence sequence = getCharSequence(readerIndex, length, charset);
|
||||
readerIndex += length;
|
||||
return sequence;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setByte(int index, int value) {
|
||||
checkIndex(index);
|
||||
@ -649,6 +663,23 @@ public abstract class AbstractByteBuf extends ByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCharSequence(int index, CharSequence sequence, Charset charset) {
|
||||
if (charset.equals(CharsetUtil.UTF_8)) {
|
||||
ensureWritable(ByteBufUtil.utf8MaxBytes(sequence));
|
||||
return ByteBufUtil.writeUtf8(this, index, sequence, sequence.length());
|
||||
}
|
||||
if (charset.equals(CharsetUtil.US_ASCII)) {
|
||||
int len = sequence.length();
|
||||
ensureWritable(len);
|
||||
return ByteBufUtil.writeAscii(this, index, sequence, len);
|
||||
}
|
||||
byte[] bytes = sequence.toString().getBytes(charset);
|
||||
ensureWritable(bytes.length);
|
||||
setBytes(index, bytes);
|
||||
return bytes.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte() {
|
||||
checkReadableBytes0(1);
|
||||
@ -1111,6 +1142,13 @@ public abstract class AbstractByteBuf extends ByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeCharSequence(CharSequence sequence, Charset charset) {
|
||||
int written = setCharSequence(writerIndex, sequence, charset);
|
||||
writerIndex += written;
|
||||
return written;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf copy() {
|
||||
return copy(readerIndex, readableBytes());
|
||||
|
@ -244,6 +244,12 @@ final class AdvancedLeakAwareByteBuf extends WrappedByteBuf {
|
||||
return super.getBytes(index, out, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharSequence(int index, int length, Charset charset) {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
return super.getCharSequence(index, length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setBoolean(int index, boolean value) {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
@ -352,6 +358,12 @@ final class AdvancedLeakAwareByteBuf extends WrappedByteBuf {
|
||||
return super.setZero(index, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCharSequence(int index, CharSequence sequence, Charset charset) {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
return super.setCharSequence(index, sequence, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean readBoolean() {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
@ -484,6 +496,12 @@ final class AdvancedLeakAwareByteBuf extends WrappedByteBuf {
|
||||
return super.readBytes(out, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence readCharSequence(int length, Charset charset) {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
return super.readCharSequence(length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf skipBytes(int length) {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
@ -844,6 +862,12 @@ final class AdvancedLeakAwareByteBuf extends WrappedByteBuf {
|
||||
return super.writeLongLE(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeCharSequence(CharSequence sequence, Charset charset) {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
return super.writeCharSequence(sequence, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBytes(int index, FileChannel out, long position, int length) throws IOException {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
|
@ -226,6 +226,12 @@ final class AdvancedLeakAwareCompositeByteBuf extends WrappedCompositeByteBuf {
|
||||
return super.getBytes(index, out, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharSequence(int index, int length, Charset charset) {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
return super.getCharSequence(index, length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompositeByteBuf setBoolean(int index, boolean value) {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
@ -466,6 +472,12 @@ final class AdvancedLeakAwareCompositeByteBuf extends WrappedCompositeByteBuf {
|
||||
return super.readBytes(out, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence readCharSequence(int length, Charset charset) {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
return super.readCharSequence(length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompositeByteBuf skipBytes(int length) {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
@ -580,6 +592,12 @@ final class AdvancedLeakAwareCompositeByteBuf extends WrappedCompositeByteBuf {
|
||||
return super.writeZero(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeCharSequence(CharSequence sequence, Charset charset) {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
return super.writeCharSequence(sequence, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(int fromIndex, int toIndex, byte value) {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
@ -760,6 +778,12 @@ final class AdvancedLeakAwareCompositeByteBuf extends WrappedCompositeByteBuf {
|
||||
return super.setLongLE(index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCharSequence(int index, CharSequence sequence, Charset charset) {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
return super.setCharSequence(index, sequence, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short readShortLE() {
|
||||
recordLeakNonRefCountingOperation(leak);
|
||||
|
@ -913,6 +913,17 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
||||
*/
|
||||
public abstract int getBytes(int index, FileChannel out, long position, int length) throws IOException;
|
||||
|
||||
/**
|
||||
* Gets a {@link CharSequence} with the given length at the given index.
|
||||
*
|
||||
* @param length the length to read
|
||||
* @param charset that should be used
|
||||
* @return the sequence
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code length} is greater than {@code this.readableBytes}
|
||||
*/
|
||||
public abstract CharSequence getCharSequence(int index, int length, Charset charset);
|
||||
|
||||
/**
|
||||
* Sets the specified boolean at the specified absolute {@code index} in this
|
||||
* buffer.
|
||||
@ -1247,6 +1258,19 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
||||
*/
|
||||
public abstract ByteBuf setZero(int index, int length);
|
||||
|
||||
/**
|
||||
* Writes the specified {@link CharSequence} at the current {@code writerIndex} and increases
|
||||
* the {@code writerIndex} by the written bytes.
|
||||
*
|
||||
* @param index on which the sequence should be written
|
||||
* @param sequence to write
|
||||
* @param charset that should be used.
|
||||
* @return the written number of bytes.
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code this.writableBytes} is not large enough to write the whole sequence
|
||||
*/
|
||||
public abstract int setCharSequence(int index, CharSequence sequence, Charset charset);
|
||||
|
||||
/**
|
||||
* Gets a boolean at the current {@code readerIndex} and increases
|
||||
* the {@code readerIndex} by {@code 1} in this buffer.
|
||||
@ -1579,6 +1603,18 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
||||
*/
|
||||
public abstract int readBytes(GatheringByteChannel out, int length) throws IOException;
|
||||
|
||||
/**
|
||||
* Gets a {@link CharSequence} with the given length at the current {@code readerIndex}
|
||||
* and increases the {@code readerIndex} by the given length.
|
||||
*
|
||||
* @param length the length to read
|
||||
* @param charset that should be used
|
||||
* @return the sequence
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code length} is greater than {@code this.readableBytes}
|
||||
*/
|
||||
public abstract CharSequence readCharSequence(int length, Charset charset);
|
||||
|
||||
/**
|
||||
* Transfers this buffer's data starting at the current {@code readerIndex}
|
||||
* to the specified channel starting at the given file position.
|
||||
@ -1885,6 +1921,19 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
||||
*/
|
||||
public abstract ByteBuf writeZero(int length);
|
||||
|
||||
/**
|
||||
* Writes the specified {@link CharSequence} at the current {@code writerIndex} and increases
|
||||
* the {@code writerIndex} by the written bytes.
|
||||
* in this buffer.
|
||||
*
|
||||
* @param sequence to write
|
||||
* @param charset that should be used
|
||||
* @return the written number of bytes
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code this.writableBytes} is not large enough to write the whole sequence
|
||||
*/
|
||||
public abstract int writeCharSequence(CharSequence sequence, Charset charset);
|
||||
|
||||
/**
|
||||
* Locates the first occurrence of the specified {@code value} in this
|
||||
* buffer. The search takes place from the specified {@code fromIndex}
|
||||
|
@ -382,7 +382,10 @@ public final class ByteBufUtil {
|
||||
|
||||
for (;;) {
|
||||
if (buf instanceof AbstractByteBuf) {
|
||||
return writeUtf8((AbstractByteBuf) buf, seq, len);
|
||||
AbstractByteBuf byteBuf = (AbstractByteBuf) buf;
|
||||
int written = writeUtf8(byteBuf, byteBuf.writerIndex, seq, len);
|
||||
byteBuf.writerIndex += written;
|
||||
return written;
|
||||
} else if (buf instanceof WrappedByteBuf) {
|
||||
// Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path.
|
||||
buf = buf.unwrap();
|
||||
@ -395,9 +398,8 @@ public final class ByteBufUtil {
|
||||
}
|
||||
|
||||
// Fast-Path implementation
|
||||
private static int writeUtf8(AbstractByteBuf buffer, CharSequence seq, int len) {
|
||||
int oldWriterIndex = buffer.writerIndex;
|
||||
int writerIndex = oldWriterIndex;
|
||||
static int writeUtf8(AbstractByteBuf buffer, int writerIndex, CharSequence seq, int len) {
|
||||
int oldWriterIndex = writerIndex;
|
||||
|
||||
// We can use the _set methods as these not need to do any index checks and reference checks.
|
||||
// This is possible as we called ensureWritable(...) before.
|
||||
@ -440,8 +442,6 @@ public final class ByteBufUtil {
|
||||
buffer._setByte(writerIndex++, (byte) (0x80 | (c & 0x3f)));
|
||||
}
|
||||
}
|
||||
// update the writerIndex without any extra checks for performance reasons
|
||||
buffer.writerIndex = writerIndex;
|
||||
return writerIndex - oldWriterIndex;
|
||||
}
|
||||
|
||||
@ -483,8 +483,10 @@ public final class ByteBufUtil {
|
||||
} else {
|
||||
for (;;) {
|
||||
if (buf instanceof AbstractByteBuf) {
|
||||
writeAscii((AbstractByteBuf) buf, seq, len);
|
||||
break;
|
||||
AbstractByteBuf byteBuf = (AbstractByteBuf) buf;
|
||||
int written = writeAscii(byteBuf, byteBuf.writerIndex, seq, len);
|
||||
byteBuf.writerIndex += written;
|
||||
return written;
|
||||
} else if (buf instanceof WrappedByteBuf) {
|
||||
// Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path.
|
||||
buf = buf.unwrap();
|
||||
@ -497,16 +499,14 @@ public final class ByteBufUtil {
|
||||
}
|
||||
|
||||
// Fast-Path implementation
|
||||
private static void writeAscii(AbstractByteBuf buffer, CharSequence seq, int len) {
|
||||
int writerIndex = buffer.writerIndex;
|
||||
static int writeAscii(AbstractByteBuf buffer, int writerIndex, CharSequence seq, int len) {
|
||||
|
||||
// We can use the _set methods as these not need to do any index checks and reference checks.
|
||||
// This is possible as we called ensureWritable(...) before.
|
||||
for (int i = 0; i < len; i++) {
|
||||
buffer._setByte(writerIndex++, (byte) seq.charAt(i));
|
||||
}
|
||||
// update the writerIndex without any extra checks for performance reasons
|
||||
buffer.writerIndex = writerIndex;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -391,6 +391,12 @@ public final class EmptyByteBuf extends ByteBuf {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharSequence(int index, int length, Charset charset) {
|
||||
checkIndex(index, length);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setBoolean(int index, boolean value) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
@ -509,6 +515,11 @@ public final class EmptyByteBuf extends ByteBuf {
|
||||
return checkIndex(index, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCharSequence(int index, CharSequence sequence, Charset charset) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean readBoolean() {
|
||||
throw new IndexOutOfBoundsException();
|
||||
@ -666,6 +677,12 @@ public final class EmptyByteBuf extends ByteBuf {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence readCharSequence(int length, Charset charset) {
|
||||
checkLength(length);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf skipBytes(int length) {
|
||||
return checkLength(length);
|
||||
@ -789,6 +806,11 @@ public final class EmptyByteBuf extends ByteBuf {
|
||||
return checkLength(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeCharSequence(CharSequence sequence, Charset charset) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(int fromIndex, int toIndex, byte value) {
|
||||
checkIndex(fromIndex);
|
||||
|
@ -16,6 +16,7 @@
|
||||
package io.netty.buffer;
|
||||
|
||||
import io.netty.util.ByteProcessor;
|
||||
import io.netty.util.CharsetUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -25,6 +26,7 @@ import java.nio.ByteOrder;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.GatheringByteChannel;
|
||||
import java.nio.channels.ScatteringByteChannel;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* A derived buffer which exposes its parent's sub-region only. It is
|
||||
@ -264,6 +266,12 @@ public class SlicedByteBuf extends AbstractDerivedByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharSequence(int index, int length, Charset charset) {
|
||||
checkIndex0(index, length);
|
||||
return buffer.getCharSequence(idx(index), length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setByte(int index, int value) {
|
||||
unwrap().setByte(idx(index), value);
|
||||
@ -386,6 +394,23 @@ public class SlicedByteBuf extends AbstractDerivedByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCharSequence(int index, CharSequence sequence, Charset charset) {
|
||||
if (charset.equals(CharsetUtil.UTF_8)) {
|
||||
checkIndex0(index, ByteBufUtil.utf8MaxBytes(sequence));
|
||||
return ByteBufUtil.writeUtf8(this, idx(index), sequence, sequence.length());
|
||||
}
|
||||
if (charset.equals(CharsetUtil.US_ASCII)) {
|
||||
int len = sequence.length();
|
||||
checkIndex0(index, len);
|
||||
return ByteBufUtil.writeAscii(this, idx(index), sequence, len);
|
||||
}
|
||||
byte[] bytes = sequence.toString().getBytes(charset);
|
||||
checkIndex0(index, bytes.length);
|
||||
buffer.setBytes(idx(index), bytes);
|
||||
return bytes.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
|
||||
checkIndex0(index, length);
|
||||
|
@ -376,6 +376,11 @@ public class SwappedByteBuf extends ByteBuf {
|
||||
return buf.getBytes(index, out, position, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharSequence(int index, int length, Charset charset) {
|
||||
return buf.getCharSequence(index, length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setBoolean(int index, boolean value) {
|
||||
buf.setBoolean(index, value);
|
||||
@ -511,6 +516,11 @@ public class SwappedByteBuf extends ByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCharSequence(int index, CharSequence sequence, Charset charset) {
|
||||
return buf.setCharSequence(index, sequence, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean readBoolean() {
|
||||
return buf.readBoolean();
|
||||
@ -673,6 +683,11 @@ public class SwappedByteBuf extends ByteBuf {
|
||||
return buf.readBytes(out, position, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence readCharSequence(int length, Charset charset) {
|
||||
return buf.readCharSequence(length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf skipBytes(int length) {
|
||||
buf.skipBytes(length);
|
||||
@ -814,6 +829,11 @@ public class SwappedByteBuf extends ByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeCharSequence(CharSequence sequence, Charset charset) {
|
||||
return buf.writeCharSequence(sequence, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(int fromIndex, int toIndex, byte value) {
|
||||
return buf.indexOf(fromIndex, toIndex, value);
|
||||
|
@ -366,6 +366,11 @@ class WrappedByteBuf extends ByteBuf {
|
||||
return buf.getBytes(index, out, position, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharSequence(int index, int length, Charset charset) {
|
||||
return buf.getCharSequence(index, length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setBoolean(int index, boolean value) {
|
||||
buf.setBoolean(index, value);
|
||||
@ -501,6 +506,11 @@ class WrappedByteBuf extends ByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCharSequence(int index, CharSequence sequence, Charset charset) {
|
||||
return buf.setCharSequence(index, sequence, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean readBoolean() {
|
||||
return buf.readBoolean();
|
||||
@ -663,6 +673,11 @@ class WrappedByteBuf extends ByteBuf {
|
||||
return buf.readBytes(out, position, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence readCharSequence(int length, Charset charset) {
|
||||
return buf.readCharSequence(length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf skipBytes(int length) {
|
||||
buf.skipBytes(length);
|
||||
@ -804,6 +819,11 @@ class WrappedByteBuf extends ByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeCharSequence(CharSequence sequence, Charset charset) {
|
||||
return buf.writeCharSequence(sequence, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(int fromIndex, int toIndex, byte value) {
|
||||
return buf.indexOf(fromIndex, toIndex, value);
|
||||
|
@ -359,6 +359,12 @@ final class ReplayingDecoderByteBuf extends ByteBuf {
|
||||
return buffer.getDouble(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharSequence(int index, int length, Charset charset) {
|
||||
checkIndex(index, length);
|
||||
return buffer.getCharSequence(index, length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
reject();
|
||||
@ -712,6 +718,12 @@ final class ReplayingDecoderByteBuf extends ByteBuf {
|
||||
return buffer.readDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence readCharSequence(int length, Charset charset) {
|
||||
checkReadableBytes(length);
|
||||
return buffer.readCharSequence(length, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf resetReaderIndex() {
|
||||
buffer.resetReaderIndex();
|
||||
@ -1114,6 +1126,18 @@ final class ReplayingDecoderByteBuf extends ByteBuf {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCharSequence(int index, CharSequence sequence, Charset charset) {
|
||||
reject();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeCharSequence(CharSequence sequence, Charset charset) {
|
||||
reject();
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void checkIndex(int index, int length) {
|
||||
if (index + length > buffer.writerIndex()) {
|
||||
throw REPLAY;
|
||||
|
Loading…
x
Reference in New Issue
Block a user