retainSlice() unwrap ByteBuf
Motivation: retainSlice() currently does not unwrap the ByteBuf when creating the ByteBuf wrapper. This effectivley forms a linked list of ByteBuf when it is only necessary to maintain a reference to the unwrapped ByteBuf. Modifications: - retainSlice() and retainDuplicate() variants should only maintain a reference to the unwrapped ByteBuf - create new unit tests which generally verify the retainSlice() behavior - Remove unecessary generic arguments from AbstractPooledDerivedByteBuf - Remove unecessary int length member variable from the unpooled sliced ByteBuf implementation - Rename the unpooled sliced/derived ByteBuf to include Unpooled in their name to be more consistent with the Pooled variants Result: Fixes https://github.com/netty/netty/issues/5582
This commit is contained in:
parent
d92c5f5f5b
commit
82b617dfe9
@ -1165,7 +1165,7 @@ public abstract class AbstractByteBuf extends ByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf duplicate() {
|
public ByteBuf duplicate() {
|
||||||
return new DuplicatedAbstractByteBuf(this);
|
return new UnpooledDuplicatedByteBuf(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1185,7 +1185,7 @@ public abstract class AbstractByteBuf extends ByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf slice(int index, int length) {
|
public ByteBuf slice(int index, int length) {
|
||||||
return new SlicedAbstractByteBuf(this, index, length);
|
return new UnpooledSlicedByteBuf(this, index, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -24,15 +24,15 @@ import java.nio.ByteOrder;
|
|||||||
/**
|
/**
|
||||||
* Abstract base class for derived {@link ByteBuf} implementations.
|
* Abstract base class for derived {@link ByteBuf} implementations.
|
||||||
*/
|
*/
|
||||||
abstract class AbstractPooledDerivedByteBuf<T> extends AbstractReferenceCountedByteBuf {
|
abstract class AbstractPooledDerivedByteBuf extends AbstractReferenceCountedByteBuf {
|
||||||
|
|
||||||
private final Handle<AbstractPooledDerivedByteBuf<T>> recyclerHandle;
|
private final Handle<AbstractPooledDerivedByteBuf> recyclerHandle;
|
||||||
private AbstractByteBuf buffer;
|
private AbstractByteBuf buffer;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
AbstractPooledDerivedByteBuf(Handle<? extends AbstractPooledDerivedByteBuf<T>> recyclerHandle) {
|
AbstractPooledDerivedByteBuf(Handle<? extends AbstractPooledDerivedByteBuf> recyclerHandle) {
|
||||||
super(0);
|
super(0);
|
||||||
this.recyclerHandle = (Handle<AbstractPooledDerivedByteBuf<T>>) recyclerHandle;
|
this.recyclerHandle = (Handle<AbstractPooledDerivedByteBuf>) recyclerHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -40,26 +40,25 @@ abstract class AbstractPooledDerivedByteBuf<T> extends AbstractReferenceCountedB
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
final <U extends AbstractPooledDerivedByteBuf<T>> U init(
|
final <U extends AbstractPooledDerivedByteBuf> U init(
|
||||||
AbstractByteBuf buffer, int readerIndex, int writerIndex, int maxCapacity) {
|
AbstractByteBuf unwrapped, ByteBuf wrapped, int readerIndex, int writerIndex, int maxCapacity) {
|
||||||
|
|
||||||
buffer.retain();
|
wrapped.retain(); // Retain up front to ensure the wrapped buffer is accessible before doing more work.
|
||||||
this.buffer = buffer;
|
this.buffer = unwrapped;
|
||||||
|
|
||||||
boolean success = false;
|
|
||||||
try {
|
try {
|
||||||
maxCapacity(maxCapacity);
|
maxCapacity(maxCapacity);
|
||||||
setIndex(readerIndex, writerIndex);
|
setIndex0(readerIndex, writerIndex); // It is assumed the bounds checking is done by the caller.
|
||||||
setRefCnt(1);
|
setRefCnt(1);
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final U castThis = (U) this;
|
final U castThis = (U) this;
|
||||||
success = true;
|
wrapped = null;
|
||||||
return castThis;
|
return castThis;
|
||||||
} finally {
|
} finally {
|
||||||
if (!success) {
|
if (wrapped != null) {
|
||||||
this.buffer = null;
|
this.buffer = null;
|
||||||
buffer.release();
|
wrapped.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,19 +119,9 @@ abstract class AbstractPooledDerivedByteBuf<T> extends AbstractReferenceCountedB
|
|||||||
return nioBuffer(index, length);
|
return nioBuffer(index, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public final ByteBuf retainedDuplicate() {
|
|
||||||
return PooledDuplicatedByteBuf.newInstance(this, readerIndex(), writerIndex());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final ByteBuf retainedSlice() {
|
public final ByteBuf retainedSlice() {
|
||||||
final int index = readerIndex();
|
final int index = readerIndex();
|
||||||
return retainedSlice(index, writerIndex() - index);
|
return retainedSlice(index, writerIndex() - index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public final ByteBuf retainedSlice(int index, int length) {
|
|
||||||
return PooledSlicedByteBuf.newInstance(this, index, length, index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,497 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.buffer;
|
||||||
|
|
||||||
|
import io.netty.util.ByteProcessor;
|
||||||
|
import io.netty.util.CharsetUtil;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.channels.GatheringByteChannel;
|
||||||
|
import java.nio.channels.ScatteringByteChannel;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
import static io.netty.util.internal.MathUtil.isOutOfBounds;
|
||||||
|
|
||||||
|
abstract class AbstractUnpooledSlicedByteBuf extends AbstractDerivedByteBuf {
|
||||||
|
private final ByteBuf buffer;
|
||||||
|
private final int adjustment;
|
||||||
|
|
||||||
|
AbstractUnpooledSlicedByteBuf(ByteBuf buffer, int index, int length) {
|
||||||
|
super(length);
|
||||||
|
checkSliceOutOfBounds(index, length, buffer);
|
||||||
|
|
||||||
|
if (buffer instanceof AbstractUnpooledSlicedByteBuf) {
|
||||||
|
this.buffer = ((AbstractUnpooledSlicedByteBuf) buffer).buffer;
|
||||||
|
adjustment = ((AbstractUnpooledSlicedByteBuf) buffer).adjustment + index;
|
||||||
|
} else if (buffer instanceof DuplicatedByteBuf) {
|
||||||
|
this.buffer = buffer.unwrap();
|
||||||
|
adjustment = index;
|
||||||
|
} else {
|
||||||
|
this.buffer = buffer;
|
||||||
|
adjustment = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
initLength(length);
|
||||||
|
writerIndex(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the constructor before {@link #writerIndex(int)}.
|
||||||
|
* @param length the {@code length} argument from the constructor.
|
||||||
|
*/
|
||||||
|
void initLength(int length) {
|
||||||
|
}
|
||||||
|
|
||||||
|
int length() {
|
||||||
|
return capacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf unwrap() {
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBufAllocator alloc() {
|
||||||
|
return unwrap().alloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public ByteOrder order() {
|
||||||
|
return unwrap().order();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDirect() {
|
||||||
|
return unwrap().isDirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf capacity(int newCapacity) {
|
||||||
|
throw new UnsupportedOperationException("sliced buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasArray() {
|
||||||
|
return unwrap().hasArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] array() {
|
||||||
|
return unwrap().array();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int arrayOffset() {
|
||||||
|
return idx(unwrap().arrayOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasMemoryAddress() {
|
||||||
|
return unwrap().hasMemoryAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long memoryAddress() {
|
||||||
|
return unwrap().memoryAddress() + adjustment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getByte(int index) {
|
||||||
|
checkIndex0(index, 1);
|
||||||
|
return unwrap().getByte(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected byte _getByte(int index) {
|
||||||
|
return unwrap().getByte(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short getShort(int index) {
|
||||||
|
checkIndex0(index, 2);
|
||||||
|
return unwrap().getShort(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected short _getShort(int index) {
|
||||||
|
return unwrap().getShort(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short getShortLE(int index) {
|
||||||
|
checkIndex0(index, 2);
|
||||||
|
return unwrap().getShortLE(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected short _getShortLE(int index) {
|
||||||
|
return unwrap().getShortLE(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getUnsignedMedium(int index) {
|
||||||
|
checkIndex0(index, 3);
|
||||||
|
return unwrap().getUnsignedMedium(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int _getUnsignedMedium(int index) {
|
||||||
|
return unwrap().getUnsignedMedium(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getUnsignedMediumLE(int index) {
|
||||||
|
checkIndex0(index, 3);
|
||||||
|
return unwrap().getUnsignedMediumLE(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int _getUnsignedMediumLE(int index) {
|
||||||
|
return unwrap().getUnsignedMediumLE(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInt(int index) {
|
||||||
|
checkIndex0(index, 4);
|
||||||
|
return unwrap().getInt(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int _getInt(int index) {
|
||||||
|
return unwrap().getInt(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIntLE(int index) {
|
||||||
|
checkIndex0(index, 4);
|
||||||
|
return unwrap().getIntLE(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int _getIntLE(int index) {
|
||||||
|
return unwrap().getIntLE(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLong(int index) {
|
||||||
|
checkIndex0(index, 8);
|
||||||
|
return unwrap().getLong(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long _getLong(int index) {
|
||||||
|
return unwrap().getLong(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLongLE(int index) {
|
||||||
|
checkIndex0(index, 8);
|
||||||
|
return unwrap().getLongLE(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long _getLongLE(int index) {
|
||||||
|
return unwrap().getLongLE(idx(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf duplicate() {
|
||||||
|
final ByteBuf duplicate = unwrap().slice(adjustment, length());
|
||||||
|
duplicate.setIndex(readerIndex(), writerIndex());
|
||||||
|
return duplicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf copy(int index, int length) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
return unwrap().copy(idx(index), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf slice(int index, int length) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
return unwrap().slice(idx(index), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
unwrap().getBytes(idx(index), dst, dstIndex, length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
unwrap().getBytes(idx(index), dst, dstIndex, length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, ByteBuffer dst) {
|
||||||
|
checkIndex0(index, dst.remaining());
|
||||||
|
unwrap().getBytes(idx(index), dst);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setByte(int index, int value) {
|
||||||
|
checkIndex0(index, 1);
|
||||||
|
unwrap().setByte(idx(index), value);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setShort(int index, int value) {
|
||||||
|
checkIndex0(index, 2);
|
||||||
|
unwrap().setShort(idx(index), value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setShort(int index, int value) {
|
||||||
|
unwrap().setShort(idx(index), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setShortLE(int index, int value) {
|
||||||
|
checkIndex0(index, 2);
|
||||||
|
unwrap().setShortLE(idx(index), value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setShortLE(int index, int value) {
|
||||||
|
unwrap().setShortLE(idx(index), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setMedium(int index, int value) {
|
||||||
|
checkIndex0(index, 3);
|
||||||
|
unwrap().setMedium(idx(index), value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setMedium(int index, int value) {
|
||||||
|
unwrap().setMedium(idx(index), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setMediumLE(int index, int value) {
|
||||||
|
checkIndex0(index, 3);
|
||||||
|
unwrap().setMediumLE(idx(index), value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setMediumLE(int index, int value) {
|
||||||
|
unwrap().setMediumLE(idx(index), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setInt(int index, int value) {
|
||||||
|
checkIndex0(index, 4);
|
||||||
|
unwrap().setInt(idx(index), value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setInt(int index, int value) {
|
||||||
|
unwrap().setInt(idx(index), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setIntLE(int index, int value) {
|
||||||
|
checkIndex0(index, 4);
|
||||||
|
unwrap().setIntLE(idx(index), value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setIntLE(int index, int value) {
|
||||||
|
unwrap().setIntLE(idx(index), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setLong(int index, long value) {
|
||||||
|
checkIndex0(index, 8);
|
||||||
|
unwrap().setLong(idx(index), value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setLong(int index, long value) {
|
||||||
|
unwrap().setLong(idx(index), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setLongLE(int index, long value) {
|
||||||
|
checkIndex0(index, 8);
|
||||||
|
unwrap().setLongLE(idx(index), value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setLongLE(int index, long value) {
|
||||||
|
unwrap().setLongLE(idx(index), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
unwrap().setBytes(idx(index), src, srcIndex, length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
unwrap().setBytes(idx(index), src, srcIndex, length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setBytes(int index, ByteBuffer src) {
|
||||||
|
checkIndex0(index, src.remaining());
|
||||||
|
unwrap().setBytes(idx(index), src);
|
||||||
|
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);
|
||||||
|
unwrap().getBytes(idx(index), out, length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
return unwrap().getBytes(idx(index), out, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBytes(int index, FileChannel out, long position, int length) throws IOException {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
return unwrap().getBytes(idx(index), out, position, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int setBytes(int index, InputStream in, int length) throws IOException {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
return unwrap().setBytes(idx(index), in, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
return unwrap().setBytes(idx(index), in, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int setBytes(int index, FileChannel in, long position, int length) throws IOException {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
return unwrap().setBytes(idx(index), in, position, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int nioBufferCount() {
|
||||||
|
return unwrap().nioBufferCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuffer nioBuffer(int index, int length) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
return unwrap().nioBuffer(idx(index), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuffer[] nioBuffers(int index, int length) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
return unwrap().nioBuffers(idx(index), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int forEachByte(int index, int length, ByteProcessor processor) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
int ret = unwrap().forEachByte(idx(index), length, processor);
|
||||||
|
if (ret >= adjustment) {
|
||||||
|
return ret - adjustment;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int forEachByteDesc(int index, int length, ByteProcessor processor) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
int ret = unwrap().forEachByteDesc(idx(index), length, processor);
|
||||||
|
if (ret >= adjustment) {
|
||||||
|
return ret - adjustment;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the index with the needed adjustment.
|
||||||
|
*/
|
||||||
|
final int idx(int index) {
|
||||||
|
return index + adjustment;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void checkSliceOutOfBounds(int index, int length, ByteBuf buffer) {
|
||||||
|
if (isOutOfBounds(index, length, buffer.capacity())) {
|
||||||
|
throw new IndexOutOfBoundsException(buffer + ".slice(" + index + ", " + length + ')');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -47,6 +47,8 @@ public class DuplicatedByteBuf extends AbstractDerivedByteBuf {
|
|||||||
|
|
||||||
if (buffer instanceof DuplicatedByteBuf) {
|
if (buffer instanceof DuplicatedByteBuf) {
|
||||||
this.buffer = ((DuplicatedByteBuf) buffer).buffer;
|
this.buffer = ((DuplicatedByteBuf) buffer).buffer;
|
||||||
|
} else if (buffer instanceof AbstractPooledDerivedByteBuf) {
|
||||||
|
this.buffer = buffer.unwrap();
|
||||||
} else {
|
} else {
|
||||||
this.buffer = buffer;
|
this.buffer = buffer;
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final ByteBuf retainedDuplicate() {
|
public final ByteBuf retainedDuplicate() {
|
||||||
return PooledDuplicatedByteBuf.newInstance(this, readerIndex(), writerIndex());
|
return PooledDuplicatedByteBuf.newInstance(this, this, readerIndex(), writerIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -149,7 +149,7 @@ abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final ByteBuf retainedSlice(int index, int length) {
|
public final ByteBuf retainedSlice(int index, int length) {
|
||||||
return PooledSlicedByteBuf.newInstance(this, index, length, index);
|
return PooledSlicedByteBuf.newInstance(this, this, index, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final ByteBuffer internalNioBuffer() {
|
protected final ByteBuffer internalNioBuffer() {
|
||||||
|
@ -28,7 +28,7 @@ import java.nio.channels.FileChannel;
|
|||||||
import java.nio.channels.GatheringByteChannel;
|
import java.nio.channels.GatheringByteChannel;
|
||||||
import java.nio.channels.ScatteringByteChannel;
|
import java.nio.channels.ScatteringByteChannel;
|
||||||
|
|
||||||
final class PooledDuplicatedByteBuf extends AbstractPooledDerivedByteBuf<PooledDuplicatedByteBuf> {
|
final class PooledDuplicatedByteBuf extends AbstractPooledDerivedByteBuf {
|
||||||
|
|
||||||
private static final Recycler<PooledDuplicatedByteBuf> RECYCLER = new Recycler<PooledDuplicatedByteBuf>() {
|
private static final Recycler<PooledDuplicatedByteBuf> RECYCLER = new Recycler<PooledDuplicatedByteBuf>() {
|
||||||
@Override
|
@Override
|
||||||
@ -37,9 +37,10 @@ final class PooledDuplicatedByteBuf extends AbstractPooledDerivedByteBuf<PooledD
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static PooledDuplicatedByteBuf newInstance(AbstractByteBuf buffer, int readerIndex, int writerIndex) {
|
static PooledDuplicatedByteBuf newInstance(AbstractByteBuf unwrapped, ByteBuf wrapped,
|
||||||
|
int readerIndex, int writerIndex) {
|
||||||
final PooledDuplicatedByteBuf duplicate = RECYCLER.get();
|
final PooledDuplicatedByteBuf duplicate = RECYCLER.get();
|
||||||
duplicate.init(buffer, readerIndex, writerIndex, buffer.maxCapacity());
|
duplicate.init(unwrapped, wrapped, readerIndex, writerIndex, wrapped.maxCapacity());
|
||||||
duplicate.markReaderIndex();
|
duplicate.markReaderIndex();
|
||||||
duplicate.markWriterIndex();
|
duplicate.markWriterIndex();
|
||||||
|
|
||||||
@ -86,6 +87,21 @@ final class PooledDuplicatedByteBuf extends AbstractPooledDerivedByteBuf<PooledD
|
|||||||
return unwrap().copy(index, length);
|
return unwrap().copy(index, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf slice(int index, int length) {
|
||||||
|
return unwrap().slice(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice(int index, int length) {
|
||||||
|
return PooledSlicedByteBuf.newInstance(unwrap(), this, index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedDuplicate() {
|
||||||
|
return PooledDuplicatedByteBuf.newInstance(unwrap(), this, readerIndex(), writerIndex());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte getByte(int index) {
|
public byte getByte(int index) {
|
||||||
return unwrap().getByte(index);
|
return unwrap().getByte(index);
|
||||||
|
@ -28,9 +28,9 @@ import java.nio.channels.FileChannel;
|
|||||||
import java.nio.channels.GatheringByteChannel;
|
import java.nio.channels.GatheringByteChannel;
|
||||||
import java.nio.channels.ScatteringByteChannel;
|
import java.nio.channels.ScatteringByteChannel;
|
||||||
|
|
||||||
import static io.netty.util.internal.MathUtil.isOutOfBounds;
|
import static io.netty.buffer.AbstractUnpooledSlicedByteBuf.checkSliceOutOfBounds;
|
||||||
|
|
||||||
final class PooledSlicedByteBuf extends AbstractPooledDerivedByteBuf<PooledSlicedByteBuf> {
|
final class PooledSlicedByteBuf extends AbstractPooledDerivedByteBuf {
|
||||||
|
|
||||||
private static final Recycler<PooledSlicedByteBuf> RECYCLER = new Recycler<PooledSlicedByteBuf>() {
|
private static final Recycler<PooledSlicedByteBuf> RECYCLER = new Recycler<PooledSlicedByteBuf>() {
|
||||||
@Override
|
@Override
|
||||||
@ -39,20 +39,23 @@ final class PooledSlicedByteBuf extends AbstractPooledDerivedByteBuf<PooledSlice
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static PooledSlicedByteBuf newInstance(AbstractByteBuf buffer, int index, int length, int adjustment) {
|
static PooledSlicedByteBuf newInstance(AbstractByteBuf unwrapped, ByteBuf wrapped,
|
||||||
if (isOutOfBounds(index, length, buffer.capacity())) {
|
int index, int length) {
|
||||||
throw new IndexOutOfBoundsException(buffer + ".slice(" + index + ", " + length + ')');
|
checkSliceOutOfBounds(index, length, unwrapped);
|
||||||
}
|
return newInstance0(unwrapped, wrapped, index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PooledSlicedByteBuf newInstance0(AbstractByteBuf unwrapped, ByteBuf wrapped,
|
||||||
|
int adjustment, int length) {
|
||||||
final PooledSlicedByteBuf slice = RECYCLER.get();
|
final PooledSlicedByteBuf slice = RECYCLER.get();
|
||||||
slice.init(buffer, 0, length, length);
|
slice.init(unwrapped, wrapped, 0, length, length);
|
||||||
slice.discardMarks();
|
slice.discardMarks();
|
||||||
slice.adjustment = adjustment;
|
slice.adjustment = adjustment;
|
||||||
|
|
||||||
return slice;
|
return slice;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int adjustment;
|
int adjustment;
|
||||||
|
|
||||||
private PooledSlicedByteBuf(Handle<PooledSlicedByteBuf> handle) {
|
private PooledSlicedByteBuf(Handle<PooledSlicedByteBuf> handle) {
|
||||||
super(handle);
|
super(handle);
|
||||||
@ -65,7 +68,7 @@ final class PooledSlicedByteBuf extends AbstractPooledDerivedByteBuf<PooledSlice
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf capacity(int newCapacity) {
|
public ByteBuf capacity(int newCapacity) {
|
||||||
return reject();
|
throw new UnsupportedOperationException("sliced buffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -96,6 +99,34 @@ final class PooledSlicedByteBuf extends AbstractPooledDerivedByteBuf<PooledSlice
|
|||||||
return unwrap().copy(idx(index), length);
|
return unwrap().copy(idx(index), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf slice(int index, int length) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
return unwrap().slice(idx(index), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice(int index, int length) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
return PooledSlicedByteBuf.newInstance0(unwrap(), this, idx(index), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf duplicate() {
|
||||||
|
// Capacity is not allowed to change for a sliced ByteBuf, so length == capacity()
|
||||||
|
final ByteBuf duplicate = unwrap().slice(adjustment, capacity());
|
||||||
|
duplicate.setIndex(readerIndex(), writerIndex());
|
||||||
|
return duplicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedDuplicate() {
|
||||||
|
// Capacity is not allowed to change for a sliced ByteBuf, so length == capacity()
|
||||||
|
final ByteBuf duplicate = retainedSlice(0, capacity());
|
||||||
|
duplicate.setIndex(readerIndex(), writerIndex());
|
||||||
|
return duplicate;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte getByte(int index) {
|
public byte getByte(int index) {
|
||||||
checkIndex0(index, 1);
|
checkIndex0(index, 1);
|
||||||
@ -411,8 +442,4 @@ final class PooledSlicedByteBuf extends AbstractPooledDerivedByteBuf<PooledSlice
|
|||||||
private int idx(int index) {
|
private int idx(int index) {
|
||||||
return index + adjustment;
|
return index + adjustment;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ByteBuf reject() {
|
|
||||||
throw new UnsupportedOperationException("sliced buffer");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -15,21 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
import io.netty.util.ByteProcessor;
|
|
||||||
import io.netty.util.CharsetUtil;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.nio.channels.FileChannel;
|
|
||||||
import java.nio.channels.GatheringByteChannel;
|
|
||||||
import java.nio.channels.ScatteringByteChannel;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
|
|
||||||
import static io.netty.util.internal.MathUtil.isOutOfBounds;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A derived buffer which exposes its parent's sub-region only. It is
|
* A derived buffer which exposes its parent's sub-region only. It is
|
||||||
* recommended to use {@link ByteBuf#slice()} and
|
* recommended to use {@link ByteBuf#slice()} and
|
||||||
@ -39,464 +24,26 @@ import static io.netty.util.internal.MathUtil.isOutOfBounds;
|
|||||||
* @deprecated Do not use.
|
* @deprecated Do not use.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public class SlicedByteBuf extends AbstractDerivedByteBuf {
|
public class SlicedByteBuf extends AbstractUnpooledSlicedByteBuf {
|
||||||
|
|
||||||
private final ByteBuf buffer;
|
private int length;
|
||||||
private final int adjustment;
|
|
||||||
private final int length;
|
|
||||||
|
|
||||||
public SlicedByteBuf(ByteBuf buffer, int index, int length) {
|
public SlicedByteBuf(ByteBuf buffer, int index, int length) {
|
||||||
super(length);
|
super(buffer, index, length);
|
||||||
if (isOutOfBounds(index, length, buffer.capacity())) {
|
}
|
||||||
throw new IndexOutOfBoundsException(buffer + ".slice(" + index + ", " + length + ')');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer instanceof SlicedByteBuf) {
|
@Override
|
||||||
this.buffer = ((SlicedByteBuf) buffer).buffer;
|
final void initLength(int length) {
|
||||||
adjustment = ((SlicedByteBuf) buffer).adjustment + index;
|
|
||||||
} else if (buffer instanceof DuplicatedByteBuf) {
|
|
||||||
this.buffer = buffer.unwrap();
|
|
||||||
adjustment = index;
|
|
||||||
} else {
|
|
||||||
this.buffer = buffer;
|
|
||||||
adjustment = index;
|
|
||||||
}
|
|
||||||
this.length = length;
|
this.length = length;
|
||||||
|
|
||||||
writerIndex(length);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int adjustment() {
|
|
||||||
return adjustment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf unwrap() {
|
final int length() {
|
||||||
return buffer;
|
return length;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBufAllocator alloc() {
|
|
||||||
return unwrap().alloc();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public ByteOrder order() {
|
|
||||||
return unwrap().order();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDirect() {
|
|
||||||
return unwrap().isDirect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int capacity() {
|
public int capacity() {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf capacity(int newCapacity) {
|
|
||||||
throw new UnsupportedOperationException("sliced buffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasArray() {
|
|
||||||
return unwrap().hasArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] array() {
|
|
||||||
return unwrap().array();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int arrayOffset() {
|
|
||||||
return idx(unwrap().arrayOffset());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasMemoryAddress() {
|
|
||||||
return unwrap().hasMemoryAddress();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long memoryAddress() {
|
|
||||||
return unwrap().memoryAddress() + adjustment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte getByte(int index) {
|
|
||||||
checkIndex0(index, 1);
|
|
||||||
return unwrap().getByte(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected byte _getByte(int index) {
|
|
||||||
return unwrap().getByte(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short getShort(int index) {
|
|
||||||
checkIndex0(index, 2);
|
|
||||||
return unwrap().getShort(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected short _getShort(int index) {
|
|
||||||
return unwrap().getShort(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short getShortLE(int index) {
|
|
||||||
checkIndex0(index, 2);
|
|
||||||
return unwrap().getShortLE(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected short _getShortLE(int index) {
|
|
||||||
return unwrap().getShortLE(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getUnsignedMedium(int index) {
|
|
||||||
checkIndex0(index, 3);
|
|
||||||
return unwrap().getUnsignedMedium(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int _getUnsignedMedium(int index) {
|
|
||||||
return unwrap().getUnsignedMedium(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getUnsignedMediumLE(int index) {
|
|
||||||
checkIndex0(index, 3);
|
|
||||||
return unwrap().getUnsignedMediumLE(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int _getUnsignedMediumLE(int index) {
|
|
||||||
return unwrap().getUnsignedMediumLE(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(int index) {
|
|
||||||
checkIndex0(index, 4);
|
|
||||||
return unwrap().getInt(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int _getInt(int index) {
|
|
||||||
return unwrap().getInt(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getIntLE(int index) {
|
|
||||||
checkIndex0(index, 4);
|
|
||||||
return unwrap().getIntLE(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int _getIntLE(int index) {
|
|
||||||
return unwrap().getIntLE(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getLong(int index) {
|
|
||||||
checkIndex0(index, 8);
|
|
||||||
return unwrap().getLong(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected long _getLong(int index) {
|
|
||||||
return unwrap().getLong(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getLongLE(int index) {
|
|
||||||
checkIndex0(index, 8);
|
|
||||||
return unwrap().getLongLE(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected long _getLongLE(int index) {
|
|
||||||
return unwrap().getLongLE(idx(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf duplicate() {
|
|
||||||
final ByteBuf duplicate = unwrap().slice(adjustment, length);
|
|
||||||
duplicate.setIndex(readerIndex(), writerIndex());
|
|
||||||
return duplicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf copy(int index, int length) {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
return unwrap().copy(idx(index), length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf slice(int index, int length) {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
return unwrap().slice(idx(index), length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
unwrap().getBytes(idx(index), dst, dstIndex, length);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
unwrap().getBytes(idx(index), dst, dstIndex, length);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf getBytes(int index, ByteBuffer dst) {
|
|
||||||
checkIndex0(index, dst.remaining());
|
|
||||||
unwrap().getBytes(idx(index), dst);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setByte(int index, int value) {
|
|
||||||
checkIndex0(index, 1);
|
|
||||||
unwrap().setByte(idx(index), value);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setShort(int index, int value) {
|
|
||||||
checkIndex0(index, 2);
|
|
||||||
unwrap().setShort(idx(index), value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void _setShort(int index, int value) {
|
|
||||||
unwrap().setShort(idx(index), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setShortLE(int index, int value) {
|
|
||||||
checkIndex0(index, 2);
|
|
||||||
unwrap().setShortLE(idx(index), value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void _setShortLE(int index, int value) {
|
|
||||||
unwrap().setShortLE(idx(index), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setMedium(int index, int value) {
|
|
||||||
checkIndex0(index, 3);
|
|
||||||
unwrap().setMedium(idx(index), value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void _setMedium(int index, int value) {
|
|
||||||
unwrap().setMedium(idx(index), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setMediumLE(int index, int value) {
|
|
||||||
checkIndex0(index, 3);
|
|
||||||
unwrap().setMediumLE(idx(index), value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void _setMediumLE(int index, int value) {
|
|
||||||
unwrap().setMediumLE(idx(index), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setInt(int index, int value) {
|
|
||||||
checkIndex0(index, 4);
|
|
||||||
unwrap().setInt(idx(index), value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void _setInt(int index, int value) {
|
|
||||||
unwrap().setInt(idx(index), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setIntLE(int index, int value) {
|
|
||||||
checkIndex0(index, 4);
|
|
||||||
unwrap().setIntLE(idx(index), value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void _setIntLE(int index, int value) {
|
|
||||||
unwrap().setIntLE(idx(index), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setLong(int index, long value) {
|
|
||||||
checkIndex0(index, 8);
|
|
||||||
unwrap().setLong(idx(index), value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void _setLong(int index, long value) {
|
|
||||||
unwrap().setLong(idx(index), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setLongLE(int index, long value) {
|
|
||||||
checkIndex0(index, 8);
|
|
||||||
unwrap().setLongLE(idx(index), value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void _setLongLE(int index, long value) {
|
|
||||||
unwrap().setLongLE(idx(index), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
unwrap().setBytes(idx(index), src, srcIndex, length);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
unwrap().setBytes(idx(index), src, srcIndex, length);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuf setBytes(int index, ByteBuffer src) {
|
|
||||||
checkIndex0(index, src.remaining());
|
|
||||||
unwrap().setBytes(idx(index), src);
|
|
||||||
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);
|
|
||||||
unwrap().getBytes(idx(index), out, length);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
return unwrap().getBytes(idx(index), out, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBytes(int index, FileChannel out, long position, int length) throws IOException {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
return unwrap().getBytes(idx(index), out, position, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int setBytes(int index, InputStream in, int length) throws IOException {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
return unwrap().setBytes(idx(index), in, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
return unwrap().setBytes(idx(index), in, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int setBytes(int index, FileChannel in, long position, int length) throws IOException {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
return unwrap().setBytes(idx(index), in, position, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int nioBufferCount() {
|
|
||||||
return unwrap().nioBufferCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuffer nioBuffer(int index, int length) {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
return unwrap().nioBuffer(idx(index), length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBuffer[] nioBuffers(int index, int length) {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
return unwrap().nioBuffers(idx(index), length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int forEachByte(int index, int length, ByteProcessor processor) {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
int ret = unwrap().forEachByte(idx(index), length, processor);
|
|
||||||
if (ret >= adjustment) {
|
|
||||||
return ret - adjustment;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int forEachByteDesc(int index, int length, ByteProcessor processor) {
|
|
||||||
checkIndex0(index, length);
|
|
||||||
int ret = unwrap().forEachByteDesc(idx(index), length, processor);
|
|
||||||
if (ret >= adjustment) {
|
|
||||||
return ret - adjustment;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the index with the needed adjustment.
|
|
||||||
*/
|
|
||||||
final int idx(int index) {
|
|
||||||
return index + adjustment;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ package io.netty.buffer;
|
|||||||
* {@link DuplicatedByteBuf} implementation that can do optimizations because it knows the duplicated buffer
|
* {@link DuplicatedByteBuf} implementation that can do optimizations because it knows the duplicated buffer
|
||||||
* is of type {@link AbstractByteBuf}.
|
* is of type {@link AbstractByteBuf}.
|
||||||
*/
|
*/
|
||||||
final class DuplicatedAbstractByteBuf extends DuplicatedByteBuf {
|
final class UnpooledDuplicatedByteBuf extends DuplicatedByteBuf {
|
||||||
DuplicatedAbstractByteBuf(AbstractByteBuf buffer) {
|
UnpooledDuplicatedByteBuf(AbstractByteBuf buffer) {
|
||||||
super(buffer);
|
super(buffer);
|
||||||
}
|
}
|
||||||
|
|
@ -16,15 +16,20 @@
|
|||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A special {@link SlicedByteBuf} that can make optimizations because it knows the sliced buffer is of type
|
* A special {@link AbstractUnpooledSlicedByteBuf} that can make optimizations because it knows the sliced buffer is of
|
||||||
* {@link AbstractByteBuf}.
|
* type {@link AbstractByteBuf}.
|
||||||
*/
|
*/
|
||||||
final class SlicedAbstractByteBuf extends SlicedByteBuf {
|
final class UnpooledSlicedByteBuf extends AbstractUnpooledSlicedByteBuf {
|
||||||
|
|
||||||
SlicedAbstractByteBuf(AbstractByteBuf buffer, int index, int length) {
|
UnpooledSlicedByteBuf(AbstractByteBuf buffer, int index, int length) {
|
||||||
super(buffer, index, length);
|
super(buffer, index, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int capacity() {
|
||||||
|
return maxCapacity();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractByteBuf unwrap() {
|
public AbstractByteBuf unwrap() {
|
||||||
return (AbstractByteBuf) super.unwrap();
|
return (AbstractByteBuf) super.unwrap();
|
@ -2918,6 +2918,54 @@ public abstract class AbstractByteBufTest {
|
|||||||
testDuplicateContents(false);
|
testDuplicateContents(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateCapacityChange() {
|
||||||
|
testDuplicateCapacityChange(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRetainedDuplicateCapacityChange() {
|
||||||
|
testDuplicateCapacityChange(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
|
public void testSliceCapacityChange() {
|
||||||
|
testSliceCapacityChange(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
|
public void testRetainedSliceCapacityChange() {
|
||||||
|
testSliceCapacityChange(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testDuplicateCapacityChange(boolean retainedDuplicate) {
|
||||||
|
ByteBuf buf = releaseLater(newBuffer(8));
|
||||||
|
ByteBuf dup = retainedDuplicate ? buf.retainedDuplicate() : buf.duplicate();
|
||||||
|
try {
|
||||||
|
dup.capacity(10);
|
||||||
|
assertEquals(buf.capacity(), dup.capacity());
|
||||||
|
dup.capacity(5);
|
||||||
|
assertEquals(buf.capacity(), dup.capacity());
|
||||||
|
} finally {
|
||||||
|
if (retainedDuplicate) {
|
||||||
|
dup.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testSliceCapacityChange(boolean retainedSlice) {
|
||||||
|
ByteBuf buf = releaseLater(newBuffer(8));
|
||||||
|
ByteBuf slice = retainedSlice ? buf.retainedSlice(buf.readerIndex() + 1, 3)
|
||||||
|
: buf.slice(buf.readerIndex() + 1, 3);
|
||||||
|
try {
|
||||||
|
slice.capacity(10);
|
||||||
|
} finally {
|
||||||
|
if (retainedSlice) {
|
||||||
|
slice.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void testSliceOutOfBounds(boolean initRetainedSlice, boolean finalRetainedSlice, boolean indexOutOfBounds) {
|
private void testSliceOutOfBounds(boolean initRetainedSlice, boolean finalRetainedSlice, boolean indexOutOfBounds) {
|
||||||
ByteBuf buf = releaseLater(newBuffer(8));
|
ByteBuf buf = releaseLater(newBuffer(8));
|
||||||
ByteBuf slice = initRetainedSlice ? buf.retainedSlice(buf.readerIndex() + 1, 2)
|
ByteBuf slice = initRetainedSlice ? buf.retainedSlice(buf.readerIndex() + 1, 2)
|
||||||
|
@ -457,7 +457,7 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest {
|
|||||||
public void testComponentMustBeSlice() {
|
public void testComponentMustBeSlice() {
|
||||||
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
CompositeByteBuf buf = releaseLater(compositeBuffer());
|
||||||
buf.addComponent(buffer(4).setIndex(1, 3));
|
buf.addComponent(buffer(4).setIndex(1, 3));
|
||||||
assertThat(buf.component(0), is(instanceOf(SlicedByteBuf.class)));
|
assertThat(buf.component(0), is(instanceOf(AbstractUnpooledSlicedByteBuf.class)));
|
||||||
assertThat(buf.component(0).capacity(), is(2));
|
assertThat(buf.component(0).capacity(), is(2));
|
||||||
assertThat(buf.component(0).maxCapacity(), is(2));
|
assertThat(buf.component(0).maxCapacity(), is(2));
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ public class ByteBufDerivationTest {
|
|||||||
ByteBuf buf = Unpooled.buffer(8).setIndex(1, 7);
|
ByteBuf buf = Unpooled.buffer(8).setIndex(1, 7);
|
||||||
ByteBuf slice = buf.slice(1, 7);
|
ByteBuf slice = buf.slice(1, 7);
|
||||||
|
|
||||||
assertThat(slice, instanceOf(SlicedByteBuf.class));
|
assertThat(slice, instanceOf(AbstractUnpooledSlicedByteBuf.class));
|
||||||
assertThat(slice.unwrap(), sameInstance(buf));
|
assertThat(slice.unwrap(), sameInstance(buf));
|
||||||
assertThat(slice.readerIndex(), is(0));
|
assertThat(slice.readerIndex(), is(0));
|
||||||
assertThat(slice.writerIndex(), is(7));
|
assertThat(slice.writerIndex(), is(7));
|
||||||
@ -53,7 +53,7 @@ public class ByteBufDerivationTest {
|
|||||||
ByteBuf slice2 = slice.slice(0, 6);
|
ByteBuf slice2 = slice.slice(0, 6);
|
||||||
|
|
||||||
assertThat(slice2, not(sameInstance(slice)));
|
assertThat(slice2, not(sameInstance(slice)));
|
||||||
assertThat(slice2, instanceOf(SlicedByteBuf.class));
|
assertThat(slice2, instanceOf(AbstractUnpooledSlicedByteBuf.class));
|
||||||
assertThat(slice2.unwrap(), sameInstance(buf));
|
assertThat(slice2.unwrap(), sameInstance(buf));
|
||||||
assertThat(slice2.writerIndex(), is(6));
|
assertThat(slice2.writerIndex(), is(6));
|
||||||
assertThat(slice2.capacity(), is(6));
|
assertThat(slice2.capacity(), is(6));
|
||||||
|
@ -126,6 +126,18 @@ public class SlicedByteBufTest extends AbstractByteBufTest {
|
|||||||
// ignore for SlicedByteBuf
|
// ignore for SlicedByteBuf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
|
@Override
|
||||||
|
public void testDuplicateCapacityChange() {
|
||||||
|
super.testDuplicateCapacityChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedOperationException.class)
|
||||||
|
@Override
|
||||||
|
public void testRetainedDuplicateCapacityChange() {
|
||||||
|
super.testRetainedDuplicateCapacityChange();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReaderIndexAndMarks() {
|
public void testReaderIndexAndMarks() {
|
||||||
ByteBuf wrapped = Unpooled.buffer(16);
|
ByteBuf wrapped = Unpooled.buffer(16);
|
||||||
@ -134,7 +146,7 @@ public class SlicedByteBufTest extends AbstractByteBufTest {
|
|||||||
wrapped.readerIndex(2);
|
wrapped.readerIndex(2);
|
||||||
wrapped.markWriterIndex();
|
wrapped.markWriterIndex();
|
||||||
wrapped.markReaderIndex();
|
wrapped.markReaderIndex();
|
||||||
ByteBuf slice = new SlicedByteBuf(wrapped, 4, 4);
|
ByteBuf slice = wrapped.slice(4, 4);
|
||||||
assertEquals(0, slice.readerIndex());
|
assertEquals(0, slice.readerIndex());
|
||||||
assertEquals(4, slice.writerIndex());
|
assertEquals(4, slice.writerIndex());
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ package io.netty.handler.codec.http.multipart;
|
|||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import io.netty.buffer.SlicedByteBuf;
|
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
||||||
import io.netty.handler.codec.http.HttpContent;
|
import io.netty.handler.codec.http.HttpContent;
|
||||||
@ -37,6 +36,7 @@ import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
|
|||||||
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TRANSFER_ENCODING;
|
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TRANSFER_ENCODING;
|
||||||
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE;
|
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/** {@link HttpPostRequestEncoder} test case. */
|
/** {@link HttpPostRequestEncoder} test case. */
|
||||||
public class HttpPostRequestEncoderTest {
|
public class HttpPostRequestEncoderTest {
|
||||||
@ -225,11 +225,11 @@ public class HttpPostRequestEncoderTest {
|
|||||||
encoder.finalizeRequest();
|
encoder.finalizeRequest();
|
||||||
while (! encoder.isEndOfInput()) {
|
while (! encoder.isEndOfInput()) {
|
||||||
HttpContent httpContent = encoder.readChunk((ByteBufAllocator) null);
|
HttpContent httpContent = encoder.readChunk((ByteBufAllocator) null);
|
||||||
if (httpContent.content() instanceof SlicedByteBuf) {
|
ByteBuf content = httpContent.content();
|
||||||
assertEquals(2, httpContent.content().refCnt());
|
int refCnt = content.refCnt();
|
||||||
} else {
|
assertTrue("content: " + content + " content.unwrap(): " + content.unwrap() + " refCnt: " + refCnt,
|
||||||
assertEquals(1, httpContent.content().refCnt());
|
(content.unwrap() == content || content.unwrap() == null) && refCnt == 1 ||
|
||||||
}
|
content.unwrap() != content && refCnt == 2);
|
||||||
httpContent.release();
|
httpContent.release();
|
||||||
}
|
}
|
||||||
encoder.cleanFiles();
|
encoder.cleanFiles();
|
||||||
|
@ -17,7 +17,6 @@ package io.netty.microbench.buffer;
|
|||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufUtil;
|
import io.netty.buffer.ByteBufUtil;
|
||||||
import io.netty.buffer.SlicedByteBuf;
|
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.microbench.util.AbstractMicrobenchmark;
|
import io.netty.microbench.util.AbstractMicrobenchmark;
|
||||||
import org.openjdk.jmh.annotations.Benchmark;
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
@ -42,7 +41,7 @@ public class SlicedByteBufBenchmark extends AbstractMicrobenchmark {
|
|||||||
public void setup() {
|
public void setup() {
|
||||||
// Use buffer sizes that will also allow to write UTF-8 without grow the buffer
|
// Use buffer sizes that will also allow to write UTF-8 without grow the buffer
|
||||||
ByteBuf buffer = Unpooled.buffer(512).retain();
|
ByteBuf buffer = Unpooled.buffer(512).retain();
|
||||||
slicedByteBuf = new SlicedByteBuf(buffer, 0, 256);
|
slicedByteBuf = buffer.slice(0, 256);
|
||||||
slicedAbstractByteBuf = buffer.slice(0, 256);
|
slicedAbstractByteBuf = buffer.slice(0, 256);
|
||||||
|
|
||||||
if (slicedByteBuf.getClass() == slicedAbstractByteBuf.getClass()) {
|
if (slicedByteBuf.getClass() == slicedAbstractByteBuf.getClass()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user