Make retained derived buffers recyclable
Related: #4333 #4421 #5128 Motivation: slice(), duplicate() and readSlice() currently create a non-recyclable derived buffer instance. Under heavy load, an application that creates a lot of derived buffers can put the garbage collector under pressure. Modifications: - Add the following methods which creates a non-recyclable derived buffer - retainedSlice() - retainedDuplicate() - readRetainedSlice() - Add the new recyclable derived buffer implementations, which has its own reference count value - Add ByteBufHolder.retainedDuplicate() - Add ByteBufHolder.replace(ByteBuf) so that.. - a user can replace the content of the holder in a consistent way - copy/duplicate/retainedDuplicate() can delegate the holder construction to replace(ByteBuf) - Use retainedDuplicate() and retainedSlice() wherever possible - Miscellaneous: - Rename DuplicateByteBufTest to DuplicatedByteBufTest (missing 'D') - Make ReplayingDecoderByteBuf.reject() return an exception instead of throwing it so that its callers don't need to add dummy return statement Result: Derived buffers are now recycled when created via retainedSlice() and retainedDuplicate() and derived from a pooled buffer
This commit is contained in:
parent
68cd670eb9
commit
3a9f472161
@ -836,6 +836,13 @@ public abstract class AbstractByteBuf extends ByteBuf {
|
|||||||
return slice;
|
return slice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readRetainedSlice(int length) {
|
||||||
|
ByteBuf slice = retainedSlice(readerIndex, length);
|
||||||
|
readerIndex += length;
|
||||||
|
return slice;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf readBytes(byte[] dst, int dstIndex, int length) {
|
public ByteBuf readBytes(byte[] dst, int dstIndex, int length) {
|
||||||
checkReadableBytes(length);
|
checkReadableBytes(length);
|
||||||
@ -1159,16 +1166,31 @@ public abstract class AbstractByteBuf extends ByteBuf {
|
|||||||
return new DuplicatedAbstractByteBuf(this);
|
return new DuplicatedAbstractByteBuf(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedDuplicate() {
|
||||||
|
return duplicate().retain();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf slice() {
|
public ByteBuf slice() {
|
||||||
return slice(readerIndex, readableBytes());
|
return slice(readerIndex, readableBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice() {
|
||||||
|
return slice().retain();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf slice(int index, int length) {
|
public ByteBuf slice(int index, int length) {
|
||||||
return new SlicedAbstractByteBuf(this, index, length);
|
return new SlicedAbstractByteBuf(this, index, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice(int index, int length) {
|
||||||
|
return slice(index, length).retain();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer nioBuffer() {
|
public ByteBuffer nioBuffer() {
|
||||||
return nioBuffer(readerIndex, readableBytes());
|
return nioBuffer(readerIndex, readableBytes());
|
||||||
|
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* 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.Recycler.Handle;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base class for derived {@link ByteBuf} implementations.
|
||||||
|
*/
|
||||||
|
abstract class AbstractPooledDerivedByteBuf<T> extends AbstractReferenceCountedByteBuf {
|
||||||
|
|
||||||
|
private final Handle<AbstractPooledDerivedByteBuf<T>> recyclerHandle;
|
||||||
|
private AbstractByteBuf buffer;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
AbstractPooledDerivedByteBuf(Handle<? extends AbstractPooledDerivedByteBuf<T>> recyclerHandle) {
|
||||||
|
super(0);
|
||||||
|
this.recyclerHandle = (Handle<AbstractPooledDerivedByteBuf<T>>) recyclerHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final AbstractByteBuf unwrap() {
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
final <U extends AbstractPooledDerivedByteBuf<T>> U init(
|
||||||
|
AbstractByteBuf buffer, int readerIndex, int writerIndex, int maxCapacity) {
|
||||||
|
|
||||||
|
buffer.retain();
|
||||||
|
this.buffer = buffer;
|
||||||
|
|
||||||
|
boolean success = false;
|
||||||
|
try {
|
||||||
|
maxCapacity(maxCapacity);
|
||||||
|
setIndex(readerIndex, writerIndex);
|
||||||
|
setRefCnt(1);
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final U castThis = (U) this;
|
||||||
|
success = true;
|
||||||
|
return castThis;
|
||||||
|
} finally {
|
||||||
|
if (!success) {
|
||||||
|
this.buffer = null;
|
||||||
|
buffer.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final void deallocate() {
|
||||||
|
recyclerHandle.recycle(this);
|
||||||
|
unwrap().release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ByteBufAllocator alloc() {
|
||||||
|
return unwrap().alloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public final ByteOrder order() {
|
||||||
|
return unwrap().order();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReadOnly() {
|
||||||
|
return unwrap().isReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isDirect() {
|
||||||
|
return unwrap().isDirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasArray() {
|
||||||
|
return unwrap().hasArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] array() {
|
||||||
|
return unwrap().array();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasMemoryAddress() {
|
||||||
|
return unwrap().hasMemoryAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int nioBufferCount() {
|
||||||
|
return unwrap().nioBufferCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ByteBuffer internalNioBuffer(int index, int length) {
|
||||||
|
return nioBuffer(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ByteBuf retainedDuplicate() {
|
||||||
|
return PooledDuplicatedByteBuf.newInstance(this, readerIndex(), writerIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ByteBuf retainedSlice() {
|
||||||
|
final int index = readerIndex();
|
||||||
|
return retainedSlice(index, writerIndex() - index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ByteBuf retainedSlice(int index, int length) {
|
||||||
|
return PooledSlicedByteBuf.newInstance(this, index, length, index);
|
||||||
|
}
|
||||||
|
}
|
@ -76,24 +76,48 @@ final class AdvancedLeakAwareByteBuf extends WrappedByteBuf {
|
|||||||
return new AdvancedLeakAwareByteBuf(super.slice(), leak);
|
return new AdvancedLeakAwareByteBuf(super.slice(), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice() {
|
||||||
|
recordLeakNonRefCountingOperation(leak);
|
||||||
|
return new AdvancedLeakAwareByteBuf(super.retainedSlice(), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf slice(int index, int length) {
|
public ByteBuf slice(int index, int length) {
|
||||||
recordLeakNonRefCountingOperation(leak);
|
recordLeakNonRefCountingOperation(leak);
|
||||||
return new AdvancedLeakAwareByteBuf(super.slice(index, length), leak);
|
return new AdvancedLeakAwareByteBuf(super.slice(index, length), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice(int index, int length) {
|
||||||
|
recordLeakNonRefCountingOperation(leak);
|
||||||
|
return new AdvancedLeakAwareByteBuf(super.retainedSlice(index, length), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf duplicate() {
|
public ByteBuf duplicate() {
|
||||||
recordLeakNonRefCountingOperation(leak);
|
recordLeakNonRefCountingOperation(leak);
|
||||||
return new AdvancedLeakAwareByteBuf(super.duplicate(), leak);
|
return new AdvancedLeakAwareByteBuf(super.duplicate(), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedDuplicate() {
|
||||||
|
recordLeakNonRefCountingOperation(leak);
|
||||||
|
return new AdvancedLeakAwareByteBuf(super.retainedDuplicate(), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf readSlice(int length) {
|
public ByteBuf readSlice(int length) {
|
||||||
recordLeakNonRefCountingOperation(leak);
|
recordLeakNonRefCountingOperation(leak);
|
||||||
return new AdvancedLeakAwareByteBuf(super.readSlice(length), leak);
|
return new AdvancedLeakAwareByteBuf(super.readSlice(length), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readRetainedSlice(int length) {
|
||||||
|
recordLeakNonRefCountingOperation(leak);
|
||||||
|
return new AdvancedLeakAwareByteBuf(super.readRetainedSlice(length), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf discardReadBytes() {
|
public ByteBuf discardReadBytes() {
|
||||||
recordLeakNonRefCountingOperation(leak);
|
recordLeakNonRefCountingOperation(leak);
|
||||||
|
@ -58,24 +58,48 @@ final class AdvancedLeakAwareCompositeByteBuf extends WrappedCompositeByteBuf {
|
|||||||
return new AdvancedLeakAwareByteBuf(super.slice(), leak);
|
return new AdvancedLeakAwareByteBuf(super.slice(), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice() {
|
||||||
|
recordLeakNonRefCountingOperation(leak);
|
||||||
|
return new AdvancedLeakAwareByteBuf(super.retainedSlice(), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf slice(int index, int length) {
|
public ByteBuf slice(int index, int length) {
|
||||||
recordLeakNonRefCountingOperation(leak);
|
recordLeakNonRefCountingOperation(leak);
|
||||||
return new AdvancedLeakAwareByteBuf(super.slice(index, length), leak);
|
return new AdvancedLeakAwareByteBuf(super.slice(index, length), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice(int index, int length) {
|
||||||
|
recordLeakNonRefCountingOperation(leak);
|
||||||
|
return new AdvancedLeakAwareByteBuf(super.retainedSlice(index, length), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf duplicate() {
|
public ByteBuf duplicate() {
|
||||||
recordLeakNonRefCountingOperation(leak);
|
recordLeakNonRefCountingOperation(leak);
|
||||||
return new AdvancedLeakAwareByteBuf(super.duplicate(), leak);
|
return new AdvancedLeakAwareByteBuf(super.duplicate(), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedDuplicate() {
|
||||||
|
recordLeakNonRefCountingOperation(leak);
|
||||||
|
return new AdvancedLeakAwareByteBuf(super.retainedDuplicate(), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf readSlice(int length) {
|
public ByteBuf readSlice(int length) {
|
||||||
recordLeakNonRefCountingOperation(leak);
|
recordLeakNonRefCountingOperation(leak);
|
||||||
return new AdvancedLeakAwareByteBuf(super.readSlice(length), leak);
|
return new AdvancedLeakAwareByteBuf(super.readSlice(length), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readRetainedSlice(int length) {
|
||||||
|
recordLeakNonRefCountingOperation(leak);
|
||||||
|
return new AdvancedLeakAwareByteBuf(super.readRetainedSlice(length), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompositeByteBuf discardReadBytes() {
|
public CompositeByteBuf discardReadBytes() {
|
||||||
recordLeakNonRefCountingOperation(leak);
|
recordLeakNonRefCountingOperation(leak);
|
||||||
|
@ -194,17 +194,31 @@ import java.nio.charset.UnsupportedCharsetException;
|
|||||||
*
|
*
|
||||||
* <h3>Derived buffers</h3>
|
* <h3>Derived buffers</h3>
|
||||||
*
|
*
|
||||||
* You can create a view of an existing buffer by calling either
|
* You can create a view of an existing buffer by calling one of the following methods:
|
||||||
* {@link #duplicate()}, {@link #slice()} or {@link #slice(int, int)}.
|
* <ul>
|
||||||
|
* <li>{@link #duplicate()}</li>
|
||||||
|
* <li>{@link #slice()}</li>
|
||||||
|
* <li>{@link #slice(int, int)}</li>
|
||||||
|
* <li>{@link #readSlice(int)}</li>
|
||||||
|
* <li>{@link #retainedDuplicate()}</li>
|
||||||
|
* <li>{@link #retainedSlice()}</li>
|
||||||
|
* <li>{@link #retainedSlice(int, int)}</li>
|
||||||
|
* <li>{@link #readRetainedSlice(int)}</li>
|
||||||
|
* </ul>
|
||||||
* A derived buffer will have an independent {@link #readerIndex() readerIndex},
|
* A derived buffer will have an independent {@link #readerIndex() readerIndex},
|
||||||
* {@link #writerIndex() writerIndex} and marker indexes, while it shares
|
* {@link #writerIndex() writerIndex} and marker indexes, while it shares
|
||||||
* other internal data representation, just like a NIO buffer does.
|
* other internal data representation, just like a NIO buffer does.
|
||||||
* <p>
|
* <p>
|
||||||
* In case a completely fresh copy of an existing buffer is required, please
|
* In case a completely fresh copy of an existing buffer is required, please
|
||||||
* call {@link #copy()} method instead.
|
* call {@link #copy()} method instead.
|
||||||
* <p>
|
*
|
||||||
* Also be aware that obtaining derived buffers will NOT call {@link #retain()} and so the
|
* <h4>Non-retained and retained derived buffers</h4>
|
||||||
* reference count will NOT be increased.
|
*
|
||||||
|
* Note that the {@link #duplicate()}, {@link #slice()}, {@link #slice(int, int)} and {@link #readSlice(int)} does NOT
|
||||||
|
* call {@link #retain()} on the returned derived buffer, and thus its reference count will NOT be increased. If you
|
||||||
|
* need to create a derived buffer with increased reference count, consider using {@link #retainedDuplicate()},
|
||||||
|
* {@link #retainedSlice()}, {@link #retainedSlice(int, int)} and {@link #readRetainedSlice(int)} which may return
|
||||||
|
* a buffer implementation that produces less garbage.
|
||||||
*
|
*
|
||||||
* <h3>Conversion to existing JDK types</h3>
|
* <h3>Conversion to existing JDK types</h3>
|
||||||
*
|
*
|
||||||
@ -1491,6 +1505,24 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
|||||||
*/
|
*/
|
||||||
public abstract ByteBuf readSlice(int length);
|
public abstract ByteBuf readSlice(int length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new retained slice of this buffer's sub-region starting at the current
|
||||||
|
* {@code readerIndex} and increases the {@code readerIndex} by the size
|
||||||
|
* of the new slice (= {@code length}).
|
||||||
|
* <p>
|
||||||
|
* Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #readSlice(int)}.
|
||||||
|
* This method behaves similarly to {@code readSlice(...).retain()} except that this method may return
|
||||||
|
* a buffer implementation that produces less garbage.
|
||||||
|
*
|
||||||
|
* @param length the size of the new slice
|
||||||
|
*
|
||||||
|
* @return the newly created slice
|
||||||
|
*
|
||||||
|
* @throws IndexOutOfBoundsException
|
||||||
|
* if {@code length} is greater than {@code this.readableBytes}
|
||||||
|
*/
|
||||||
|
public abstract ByteBuf readRetainedSlice(int length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transfers this buffer's data to the specified destination starting at
|
* Transfers this buffer's data to the specified destination starting at
|
||||||
* the current {@code readerIndex} until the destination becomes
|
* the current {@code readerIndex} until the destination becomes
|
||||||
@ -2060,6 +2092,20 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
|||||||
*/
|
*/
|
||||||
public abstract ByteBuf slice();
|
public abstract ByteBuf slice();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a retained slice of this buffer's readable bytes. Modifying the content
|
||||||
|
* of the returned buffer or this buffer affects each other's content
|
||||||
|
* while they maintain separate indexes and marks. This method is
|
||||||
|
* identical to {@code buf.slice(buf.readerIndex(), buf.readableBytes())}.
|
||||||
|
* This method does not modify {@code readerIndex} or {@code writerIndex} of
|
||||||
|
* this buffer.
|
||||||
|
* <p>
|
||||||
|
* Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #slice()}.
|
||||||
|
* This method behaves similarly to {@code slice().retain()} except that this method may return
|
||||||
|
* a buffer implementation that produces less garbage.
|
||||||
|
*/
|
||||||
|
public abstract ByteBuf retainedSlice();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a slice of this buffer's sub-region. Modifying the content of
|
* Returns a slice of this buffer's sub-region. Modifying the content of
|
||||||
* the returned buffer or this buffer affects each other's content while
|
* the returned buffer or this buffer affects each other's content while
|
||||||
@ -2072,6 +2118,19 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
|||||||
*/
|
*/
|
||||||
public abstract ByteBuf slice(int index, int length);
|
public abstract ByteBuf slice(int index, int length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a retained slice of this buffer's sub-region. Modifying the content of
|
||||||
|
* the returned buffer or this buffer affects each other's content while
|
||||||
|
* they maintain separate indexes and marks.
|
||||||
|
* This method does not modify {@code readerIndex} or {@code writerIndex} of
|
||||||
|
* this buffer.
|
||||||
|
* <p>
|
||||||
|
* Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #slice(int, int)}.
|
||||||
|
* This method behaves similarly to {@code slice(...).retain()} except that this method may return
|
||||||
|
* a buffer implementation that produces less garbage.
|
||||||
|
*/
|
||||||
|
public abstract ByteBuf retainedSlice(int index, int length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a buffer which shares the whole region of this buffer.
|
* Returns a buffer which shares the whole region of this buffer.
|
||||||
* Modifying the content of the returned buffer or this buffer affects
|
* Modifying the content of the returned buffer or this buffer affects
|
||||||
@ -2085,6 +2144,20 @@ public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {
|
|||||||
*/
|
*/
|
||||||
public abstract ByteBuf duplicate();
|
public abstract ByteBuf duplicate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a retained buffer which shares the whole region of this buffer.
|
||||||
|
* Modifying the content of the returned buffer or this buffer affects
|
||||||
|
* each other's content while they maintain separate indexes and marks.
|
||||||
|
* This method is identical to {@code buf.slice(0, buf.capacity())}.
|
||||||
|
* This method does not modify {@code readerIndex} or {@code writerIndex} of
|
||||||
|
* this buffer.
|
||||||
|
* <p>
|
||||||
|
* Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #slice(int, int)}.
|
||||||
|
* This method behaves similarly to {@code duplicate().retain()} except that this method may return
|
||||||
|
* a buffer implementation that produces less garbage.
|
||||||
|
*/
|
||||||
|
public abstract ByteBuf retainedDuplicate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the maximum number of NIO {@link ByteBuffer}s that consist this buffer. Note that {@link #nioBuffers()}
|
* Returns the maximum number of NIO {@link ByteBuffer}s that consist this buffer. Note that {@link #nioBuffers()}
|
||||||
* or {@link #nioBuffers(int, int)} might return a less number of {@link ByteBuffer}s.
|
* or {@link #nioBuffers(int, int)} might return a less number of {@link ByteBuffer}s.
|
||||||
|
@ -28,15 +28,27 @@ public interface ByteBufHolder extends ReferenceCounted {
|
|||||||
ByteBuf content();
|
ByteBuf content();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a deep copy of this {@link ByteBufHolder}.
|
* Creates a deep copy of this {@link ByteBufHolder}.
|
||||||
*/
|
*/
|
||||||
ByteBufHolder copy();
|
ByteBufHolder copy();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Duplicate the {@link ByteBufHolder}. Be aware that this will not automatically call {@link #retain()}.
|
* Duplicates this {@link ByteBufHolder}. Be aware that this will not automatically call {@link #retain()}.
|
||||||
*/
|
*/
|
||||||
ByteBufHolder duplicate();
|
ByteBufHolder duplicate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duplicates this {@link ByteBufHolder}. This method returns a retained duplicate unlike {@link #duplicate()}.
|
||||||
|
*
|
||||||
|
* @see ByteBuf#retainedDuplicate()
|
||||||
|
*/
|
||||||
|
ByteBufHolder retainedDuplicate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new {@link ByteBufHolder} which contains the specified {@code content}.
|
||||||
|
*/
|
||||||
|
ByteBufHolder replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ByteBufHolder retain();
|
ByteBufHolder retain();
|
||||||
|
|
||||||
|
@ -41,14 +41,46 @@ public class DefaultByteBufHolder implements ByteBufHolder {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>
|
||||||
|
* This method calls {@code replace(content().copy())} by default.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ByteBufHolder copy() {
|
public ByteBufHolder copy() {
|
||||||
return new DefaultByteBufHolder(data.copy());
|
return replace(data.copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>
|
||||||
|
* This method calls {@code replace(content().duplicate())} by default.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ByteBufHolder duplicate() {
|
public ByteBufHolder duplicate() {
|
||||||
return new DefaultByteBufHolder(data.duplicate());
|
return replace(data.duplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>
|
||||||
|
* This method calls {@code replace(content().retainedDuplicate())} by default.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ByteBufHolder retainedDuplicate() {
|
||||||
|
return replace(data.retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>
|
||||||
|
* Override this method to return a new instance of this object whose content is set to the specified
|
||||||
|
* {@code content}. The default implementation of {@link #copy()}, {@link #duplicate()} and
|
||||||
|
* {@link #retainedDuplicate()} invokes this method to create a copy.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ByteBufHolder replace(ByteBuf content) {
|
||||||
|
return new DefaultByteBufHolder(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,6 +39,10 @@ public class DuplicatedByteBuf extends AbstractDerivedByteBuf {
|
|||||||
private final ByteBuf buffer;
|
private final ByteBuf buffer;
|
||||||
|
|
||||||
public DuplicatedByteBuf(ByteBuf buffer) {
|
public DuplicatedByteBuf(ByteBuf buffer) {
|
||||||
|
this(buffer, buffer.readerIndex(), buffer.writerIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
DuplicatedByteBuf(ByteBuf buffer, int readerIndex, int writerIndex) {
|
||||||
super(buffer.maxCapacity());
|
super(buffer.maxCapacity());
|
||||||
|
|
||||||
if (buffer instanceof DuplicatedByteBuf) {
|
if (buffer instanceof DuplicatedByteBuf) {
|
||||||
@ -47,7 +51,7 @@ public class DuplicatedByteBuf extends AbstractDerivedByteBuf {
|
|||||||
this.buffer = buffer;
|
this.buffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
setIndex(buffer.readerIndex(), buffer.writerIndex());
|
setIndex(readerIndex, writerIndex);
|
||||||
markReaderIndex();
|
markReaderIndex();
|
||||||
markWriterIndex();
|
markWriterIndex();
|
||||||
}
|
}
|
||||||
|
@ -630,6 +630,11 @@ public final class EmptyByteBuf extends ByteBuf {
|
|||||||
return checkLength(length);
|
return checkLength(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readRetainedSlice(int length) {
|
||||||
|
return checkLength(length);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf readBytes(ByteBuf dst) {
|
public ByteBuf readBytes(ByteBuf dst) {
|
||||||
return checkLength(dst.writableBytes());
|
return checkLength(dst.writableBytes());
|
||||||
@ -872,16 +877,31 @@ public final class EmptyByteBuf extends ByteBuf {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf slice(int index, int length) {
|
public ByteBuf slice(int index, int length) {
|
||||||
return checkIndex(index, length);
|
return checkIndex(index, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice(int index, int length) {
|
||||||
|
return checkIndex(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf duplicate() {
|
public ByteBuf duplicate() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedDuplicate() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int nioBufferCount() {
|
public int nioBufferCount() {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -136,6 +136,22 @@ abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ByteBuf retainedDuplicate() {
|
||||||
|
return PooledDuplicatedByteBuf.newInstance(this, readerIndex(), writerIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ByteBuf retainedSlice() {
|
||||||
|
final int index = readerIndex();
|
||||||
|
return retainedSlice(index, writerIndex() - index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ByteBuf retainedSlice(int index, int length) {
|
||||||
|
return PooledSlicedByteBuf.newInstance(this, index, length, index);
|
||||||
|
}
|
||||||
|
|
||||||
protected final ByteBuffer internalNioBuffer() {
|
protected final ByteBuffer internalNioBuffer() {
|
||||||
ByteBuffer tmpNioBuf = this.tmpNioBuf;
|
ByteBuffer tmpNioBuf = this.tmpNioBuf;
|
||||||
if (tmpNioBuf == null) {
|
if (tmpNioBuf == null) {
|
||||||
|
@ -0,0 +1,360 @@
|
|||||||
|
/*
|
||||||
|
* 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.Recycler;
|
||||||
|
import io.netty.util.Recycler.Handle;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.channels.GatheringByteChannel;
|
||||||
|
import java.nio.channels.ScatteringByteChannel;
|
||||||
|
|
||||||
|
final class PooledDuplicatedByteBuf extends AbstractPooledDerivedByteBuf<PooledDuplicatedByteBuf> {
|
||||||
|
|
||||||
|
private static final Recycler<PooledDuplicatedByteBuf> RECYCLER = new Recycler<PooledDuplicatedByteBuf>() {
|
||||||
|
@Override
|
||||||
|
protected PooledDuplicatedByteBuf newObject(Handle<PooledDuplicatedByteBuf> handle) {
|
||||||
|
return new PooledDuplicatedByteBuf(handle);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static PooledDuplicatedByteBuf newInstance(AbstractByteBuf buffer, int readerIndex, int writerIndex) {
|
||||||
|
final PooledDuplicatedByteBuf duplicate = RECYCLER.get();
|
||||||
|
duplicate.init(buffer, readerIndex, writerIndex, buffer.maxCapacity());
|
||||||
|
duplicate.markReaderIndex();
|
||||||
|
duplicate.markWriterIndex();
|
||||||
|
|
||||||
|
return duplicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PooledDuplicatedByteBuf(Handle<PooledDuplicatedByteBuf> handle) {
|
||||||
|
super(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int capacity() {
|
||||||
|
return unwrap().capacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf capacity(int newCapacity) {
|
||||||
|
unwrap().capacity(newCapacity);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int arrayOffset() {
|
||||||
|
return unwrap().arrayOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long memoryAddress() {
|
||||||
|
return unwrap().memoryAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuffer nioBuffer(int index, int length) {
|
||||||
|
return unwrap().nioBuffer(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuffer[] nioBuffers(int index, int length) {
|
||||||
|
return unwrap().nioBuffers(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf copy(int index, int length) {
|
||||||
|
return unwrap().copy(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getByte(int index) {
|
||||||
|
return unwrap().getByte(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected byte _getByte(int index) {
|
||||||
|
return unwrap()._getByte(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short getShort(int index) {
|
||||||
|
return unwrap().getShort(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected short _getShort(int index) {
|
||||||
|
return unwrap()._getShort(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short getShortLE(int index) {
|
||||||
|
return unwrap().getShortLE(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected short _getShortLE(int index) {
|
||||||
|
return unwrap()._getShortLE(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getUnsignedMedium(int index) {
|
||||||
|
return unwrap().getUnsignedMedium(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int _getUnsignedMedium(int index) {
|
||||||
|
return unwrap()._getUnsignedMedium(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getUnsignedMediumLE(int index) {
|
||||||
|
return unwrap().getUnsignedMediumLE(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int _getUnsignedMediumLE(int index) {
|
||||||
|
return unwrap()._getUnsignedMediumLE(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInt(int index) {
|
||||||
|
return unwrap().getInt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int _getInt(int index) {
|
||||||
|
return unwrap()._getInt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIntLE(int index) {
|
||||||
|
return unwrap().getIntLE(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int _getIntLE(int index) {
|
||||||
|
return unwrap()._getIntLE(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLong(int index) {
|
||||||
|
return unwrap().getLong(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long _getLong(int index) {
|
||||||
|
return unwrap()._getLong(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLongLE(int index) {
|
||||||
|
return unwrap().getLongLE(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long _getLongLE(int index) {
|
||||||
|
return unwrap()._getLongLE(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
|
||||||
|
unwrap().getBytes(index, dst, dstIndex, length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
|
||||||
|
unwrap().getBytes(index, dst, dstIndex, length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, ByteBuffer dst) {
|
||||||
|
unwrap().getBytes(index, dst);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setByte(int index, int value) {
|
||||||
|
unwrap().setByte(index, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setByte(int index, int value) {
|
||||||
|
unwrap()._setByte(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setShort(int index, int value) {
|
||||||
|
unwrap().setShort(index, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setShort(int index, int value) {
|
||||||
|
unwrap()._setShort(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setShortLE(int index, int value) {
|
||||||
|
unwrap().setShortLE(index, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setShortLE(int index, int value) {
|
||||||
|
unwrap()._setShortLE(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setMedium(int index, int value) {
|
||||||
|
unwrap().setMedium(index, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setMedium(int index, int value) {
|
||||||
|
unwrap()._setMedium(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setMediumLE(int index, int value) {
|
||||||
|
unwrap().setMediumLE(index, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setMediumLE(int index, int value) {
|
||||||
|
unwrap()._setMediumLE(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setInt(int index, int value) {
|
||||||
|
unwrap().setInt(index, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setInt(int index, int value) {
|
||||||
|
unwrap()._setInt(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setIntLE(int index, int value) {
|
||||||
|
unwrap().setIntLE(index, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setIntLE(int index, int value) {
|
||||||
|
unwrap()._setIntLE(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setLong(int index, long value) {
|
||||||
|
unwrap().setLong(index, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setLong(int index, long value) {
|
||||||
|
unwrap()._setLong(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setLongLE(int index, long value) {
|
||||||
|
unwrap().setLongLE(index, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _setLongLE(int index, long value) {
|
||||||
|
unwrap().setLongLE(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
|
||||||
|
unwrap().setBytes(index, src, srcIndex, length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
|
||||||
|
unwrap().setBytes(index, src, srcIndex, length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf setBytes(int index, ByteBuffer src) {
|
||||||
|
unwrap().setBytes(index, src);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf getBytes(int index, OutputStream out, int length)
|
||||||
|
throws IOException {
|
||||||
|
unwrap().getBytes(index, out, length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBytes(int index, GatheringByteChannel out, int length)
|
||||||
|
throws IOException {
|
||||||
|
return unwrap().getBytes(index, out, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBytes(int index, FileChannel out, long position, int length)
|
||||||
|
throws IOException {
|
||||||
|
return unwrap().getBytes(index, out, position, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int setBytes(int index, InputStream in, int length)
|
||||||
|
throws IOException {
|
||||||
|
return unwrap().setBytes(index, in, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int setBytes(int index, ScatteringByteChannel in, int length)
|
||||||
|
throws IOException {
|
||||||
|
return unwrap().setBytes(index, in, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int setBytes(int index, FileChannel in, long position, int length)
|
||||||
|
throws IOException {
|
||||||
|
return unwrap().setBytes(index, in, position, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int forEachByte(int index, int length, ByteProcessor processor) {
|
||||||
|
return unwrap().forEachByte(index, length, processor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int forEachByteDesc(int index, int length, ByteProcessor processor) {
|
||||||
|
return unwrap().forEachByteDesc(index, length, processor);
|
||||||
|
}
|
||||||
|
}
|
418
buffer/src/main/java/io/netty/buffer/PooledSlicedByteBuf.java
Normal file
418
buffer/src/main/java/io/netty/buffer/PooledSlicedByteBuf.java
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
/*
|
||||||
|
* 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.Recycler;
|
||||||
|
import io.netty.util.Recycler.Handle;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.channels.GatheringByteChannel;
|
||||||
|
import java.nio.channels.ScatteringByteChannel;
|
||||||
|
|
||||||
|
import static io.netty.util.internal.MathUtil.isOutOfBounds;
|
||||||
|
|
||||||
|
final class PooledSlicedByteBuf extends AbstractPooledDerivedByteBuf<PooledSlicedByteBuf> {
|
||||||
|
|
||||||
|
private static final Recycler<PooledSlicedByteBuf> RECYCLER = new Recycler<PooledSlicedByteBuf>() {
|
||||||
|
@Override
|
||||||
|
protected PooledSlicedByteBuf newObject(Handle<PooledSlicedByteBuf> handle) {
|
||||||
|
return new PooledSlicedByteBuf(handle);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static PooledSlicedByteBuf newInstance(AbstractByteBuf buffer, int index, int length, int adjustment) {
|
||||||
|
if (isOutOfBounds(index, length, buffer.capacity())) {
|
||||||
|
throw new IndexOutOfBoundsException(buffer + ".slice(" + index + ", " + length + ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
final PooledSlicedByteBuf slice = RECYCLER.get();
|
||||||
|
slice.init(buffer, 0, length, length);
|
||||||
|
slice.discardMarks();
|
||||||
|
slice.adjustment = adjustment;
|
||||||
|
|
||||||
|
return slice;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int adjustment;
|
||||||
|
|
||||||
|
private PooledSlicedByteBuf(Handle<PooledSlicedByteBuf> handle) {
|
||||||
|
super(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int capacity() {
|
||||||
|
return maxCapacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf capacity(int newCapacity) {
|
||||||
|
return reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int arrayOffset() {
|
||||||
|
return idx(unwrap().arrayOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long memoryAddress() {
|
||||||
|
return unwrap().memoryAddress() + adjustment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 ByteBuf copy(int index, int length) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
return unwrap().copy(idx(index), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 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
|
||||||
|
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 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 forEachByte(int index, int length, ByteProcessor processor) {
|
||||||
|
checkIndex0(index, length);
|
||||||
|
int ret = unwrap().forEachByte(idx(index), length, processor);
|
||||||
|
if (ret < adjustment) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return ret - adjustment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 -1;
|
||||||
|
}
|
||||||
|
return ret - adjustment;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int idx(int index) {
|
||||||
|
return index + adjustment;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ByteBuf reject() {
|
||||||
|
throw new UnsupportedOperationException("sliced buffer");
|
||||||
|
}
|
||||||
|
}
|
@ -72,18 +72,38 @@ final class SimpleLeakAwareByteBuf extends WrappedByteBuf {
|
|||||||
return new SimpleLeakAwareByteBuf(super.slice(), leak);
|
return new SimpleLeakAwareByteBuf(super.slice(), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice() {
|
||||||
|
return new SimpleLeakAwareByteBuf(super.retainedSlice(), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf slice(int index, int length) {
|
public ByteBuf slice(int index, int length) {
|
||||||
return new SimpleLeakAwareByteBuf(super.slice(index, length), leak);
|
return new SimpleLeakAwareByteBuf(super.slice(index, length), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice(int index, int length) {
|
||||||
|
return new SimpleLeakAwareByteBuf(super.retainedSlice(index, length), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf duplicate() {
|
public ByteBuf duplicate() {
|
||||||
return new SimpleLeakAwareByteBuf(super.duplicate(), leak);
|
return new SimpleLeakAwareByteBuf(super.duplicate(), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedDuplicate() {
|
||||||
|
return new SimpleLeakAwareByteBuf(super.retainedDuplicate(), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf readSlice(int length) {
|
public ByteBuf readSlice(int length) {
|
||||||
return new SimpleLeakAwareByteBuf(super.readSlice(length), leak);
|
return new SimpleLeakAwareByteBuf(super.readSlice(length), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readRetainedSlice(int length) {
|
||||||
|
return new SimpleLeakAwareByteBuf(super.readRetainedSlice(length), leak);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,18 +62,38 @@ final class SimpleLeakAwareCompositeByteBuf extends WrappedCompositeByteBuf {
|
|||||||
return new SimpleLeakAwareByteBuf(super.slice(), leak);
|
return new SimpleLeakAwareByteBuf(super.slice(), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice() {
|
||||||
|
return new SimpleLeakAwareByteBuf(super.retainedSlice(), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf slice(int index, int length) {
|
public ByteBuf slice(int index, int length) {
|
||||||
return new SimpleLeakAwareByteBuf(super.slice(index, length), leak);
|
return new SimpleLeakAwareByteBuf(super.slice(index, length), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice(int index, int length) {
|
||||||
|
return new SimpleLeakAwareByteBuf(super.retainedSlice(index, length), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf duplicate() {
|
public ByteBuf duplicate() {
|
||||||
return new SimpleLeakAwareByteBuf(super.duplicate(), leak);
|
return new SimpleLeakAwareByteBuf(super.duplicate(), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedDuplicate() {
|
||||||
|
return new SimpleLeakAwareByteBuf(super.retainedDuplicate(), leak);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf readSlice(int length) {
|
public ByteBuf readSlice(int length) {
|
||||||
return new SimpleLeakAwareByteBuf(super.readSlice(length), leak);
|
return new SimpleLeakAwareByteBuf(super.readSlice(length), leak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readRetainedSlice(int length) {
|
||||||
|
return new SimpleLeakAwareByteBuf(super.readRetainedSlice(length), leak);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,10 @@ public class SlicedByteBuf extends AbstractDerivedByteBuf {
|
|||||||
writerIndex(length);
|
writerIndex(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final int adjustment() {
|
||||||
|
return adjustment;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf unwrap() {
|
public ByteBuf unwrap() {
|
||||||
return buffer;
|
return buffer;
|
||||||
|
@ -631,6 +631,11 @@ public class SwappedByteBuf extends ByteBuf {
|
|||||||
return buf.readSlice(length).order(order);
|
return buf.readSlice(length).order(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readRetainedSlice(int length) {
|
||||||
|
return buf.readRetainedSlice(length).order(order);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf readBytes(ByteBuf dst) {
|
public ByteBuf readBytes(ByteBuf dst) {
|
||||||
buf.readBytes(dst);
|
buf.readBytes(dst);
|
||||||
@ -889,16 +894,31 @@ public class SwappedByteBuf extends ByteBuf {
|
|||||||
return buf.slice().order(order);
|
return buf.slice().order(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice() {
|
||||||
|
return buf.slice().order(order);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf slice(int index, int length) {
|
public ByteBuf slice(int index, int length) {
|
||||||
return buf.slice(index, length).order(order);
|
return buf.slice(index, length).order(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice(int index, int length) {
|
||||||
|
return buf.slice(index, length).order(order);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf duplicate() {
|
public ByteBuf duplicate() {
|
||||||
return buf.duplicate().order(order);
|
return buf.duplicate().order(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedDuplicate() {
|
||||||
|
return buf.retainedDuplicate().order(order);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int nioBufferCount() {
|
public int nioBufferCount() {
|
||||||
return buf.nioBufferCount();
|
return buf.nioBufferCount();
|
||||||
|
@ -55,21 +55,41 @@ final class UnreleasableByteBuf extends WrappedByteBuf {
|
|||||||
return new UnreleasableByteBuf(buf.readSlice(length));
|
return new UnreleasableByteBuf(buf.readSlice(length));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readRetainedSlice(int length) {
|
||||||
|
return new UnreleasableByteBuf(buf.readRetainedSlice(length));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf slice() {
|
public ByteBuf slice() {
|
||||||
return new UnreleasableByteBuf(buf.slice());
|
return new UnreleasableByteBuf(buf.slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice() {
|
||||||
|
return new UnreleasableByteBuf(buf.retainedSlice());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf slice(int index, int length) {
|
public ByteBuf slice(int index, int length) {
|
||||||
return new UnreleasableByteBuf(buf.slice(index, length));
|
return new UnreleasableByteBuf(buf.slice(index, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice(int index, int length) {
|
||||||
|
return new UnreleasableByteBuf(buf.retainedSlice(index, length));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf duplicate() {
|
public ByteBuf duplicate() {
|
||||||
return new UnreleasableByteBuf(buf.duplicate());
|
return new UnreleasableByteBuf(buf.duplicate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedDuplicate() {
|
||||||
|
return new UnreleasableByteBuf(buf.retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf retain(int increment) {
|
public ByteBuf retain(int increment) {
|
||||||
return this;
|
return this;
|
||||||
|
@ -621,6 +621,11 @@ class WrappedByteBuf extends ByteBuf {
|
|||||||
return buf.readSlice(length);
|
return buf.readSlice(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readRetainedSlice(int length) {
|
||||||
|
return buf.readRetainedSlice(length);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf readBytes(ByteBuf dst) {
|
public ByteBuf readBytes(ByteBuf dst) {
|
||||||
buf.readBytes(dst);
|
buf.readBytes(dst);
|
||||||
@ -879,16 +884,31 @@ class WrappedByteBuf extends ByteBuf {
|
|||||||
return buf.slice();
|
return buf.slice();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice() {
|
||||||
|
return buf.retainedSlice();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf slice(int index, int length) {
|
public ByteBuf slice(int index, int length) {
|
||||||
return buf.slice(index, length);
|
return buf.slice(index, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice(int index, int length) {
|
||||||
|
return buf.retainedSlice(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf duplicate() {
|
public ByteBuf duplicate() {
|
||||||
return buf.duplicate();
|
return buf.duplicate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedDuplicate() {
|
||||||
|
return buf.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int nioBufferCount() {
|
public int nioBufferCount() {
|
||||||
return buf.nioBufferCount();
|
return buf.nioBufferCount();
|
||||||
|
@ -332,11 +332,21 @@ class WrappedCompositeByteBuf extends CompositeByteBuf {
|
|||||||
return wrapped.slice();
|
return wrapped.slice();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice() {
|
||||||
|
return wrapped.retainedSlice();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf slice(int index, int length) {
|
public ByteBuf slice(int index, int length) {
|
||||||
return wrapped.slice(index, length);
|
return wrapped.slice(index, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedSlice(int index, int length) {
|
||||||
|
return wrapped.retainedSlice(index, length);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer nioBuffer() {
|
public ByteBuffer nioBuffer() {
|
||||||
return wrapped.nioBuffer();
|
return wrapped.nioBuffer();
|
||||||
@ -417,11 +427,21 @@ class WrappedCompositeByteBuf extends CompositeByteBuf {
|
|||||||
return wrapped.duplicate();
|
return wrapped.duplicate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf retainedDuplicate() {
|
||||||
|
return wrapped.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf readSlice(int length) {
|
public ByteBuf readSlice(int length) {
|
||||||
return wrapped.readSlice(length);
|
return wrapped.readSlice(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf readRetainedSlice(int length) {
|
||||||
|
return wrapped.readRetainedSlice(length);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int readBytes(GatheringByteChannel out, int length) throws IOException {
|
public int readBytes(GatheringByteChannel out, int length) throws IOException {
|
||||||
return wrapped.readBytes(out, length);
|
return wrapped.readBytes(out, length);
|
||||||
|
@ -22,7 +22,7 @@ import static org.junit.Assert.assertEquals;
|
|||||||
/**
|
/**
|
||||||
* Tests duplicated channel buffers
|
* Tests duplicated channel buffers
|
||||||
*/
|
*/
|
||||||
public class DuplicateByteBufTest extends AbstractByteBufTest {
|
public class DuplicatedByteBufTest extends AbstractByteBufTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ByteBuf newBuffer(int length) {
|
protected ByteBuf newBuffer(int length) {
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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 static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class RetainedDuplicatedByteBufTest extends DuplicatedByteBufTest {
|
||||||
|
@Override
|
||||||
|
protected ByteBuf newBuffer(int length) {
|
||||||
|
ByteBuf wrapped = Unpooled.buffer(length);
|
||||||
|
ByteBuf buffer = wrapped.retainedDuplicate();
|
||||||
|
wrapped.release();
|
||||||
|
|
||||||
|
assertEquals(wrapped.writerIndex(), buffer.writerIndex());
|
||||||
|
assertEquals(wrapped.readerIndex(), buffer.readerIndex());
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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.internal.ThreadLocalRandom;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class RetainedSlicedByteBufTest extends SlicedByteBufTest {
|
||||||
|
@Override
|
||||||
|
protected ByteBuf newBuffer(int length) {
|
||||||
|
ByteBuf wrapped = Unpooled.wrappedBuffer(new byte[length * 2]);
|
||||||
|
ByteBuf buffer = wrapped.retainedSlice(ThreadLocalRandom.current().nextInt(length - 1) + 1, length);
|
||||||
|
wrapped.release();
|
||||||
|
|
||||||
|
assertEquals(0, buffer.readerIndex());
|
||||||
|
assertEquals(length, buffer.writerIndex());
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
|
import io.netty.util.internal.ThreadLocalRandom;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -27,12 +28,11 @@ import static org.junit.Assert.*;
|
|||||||
*/
|
*/
|
||||||
public class SlicedByteBufTest extends AbstractByteBufTest {
|
public class SlicedByteBufTest extends AbstractByteBufTest {
|
||||||
|
|
||||||
private final Random random = new Random();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ByteBuf newBuffer(int length) {
|
protected ByteBuf newBuffer(int length) {
|
||||||
ByteBuf buffer = Unpooled.wrappedBuffer(
|
ByteBuf buffer = Unpooled.wrappedBuffer(
|
||||||
new byte[length * 2], random.nextInt(length - 1) + 1, length);
|
new byte[length * 2], ThreadLocalRandom.current().nextInt(length - 1) + 1, length);
|
||||||
|
assertEquals(0, buffer.readerIndex());
|
||||||
assertEquals(length, buffer.writerIndex());
|
assertEquals(length, buffer.writerIndex());
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@ -69,12 +69,22 @@ public class DefaultDnsRawRecord extends AbstractDnsRecord implements DnsRawReco
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DnsRawRecord copy() {
|
public DnsRawRecord copy() {
|
||||||
return new DefaultDnsRawRecord(name(), type(), dnsClass(), timeToLive(), content().copy());
|
return replace(content().copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DnsRawRecord duplicate() {
|
public DnsRawRecord duplicate() {
|
||||||
return new DefaultDnsRawRecord(name(), type(), dnsClass(), timeToLive(), content().duplicate());
|
return replace(content().duplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DnsRawRecord retainedDuplicate() {
|
||||||
|
return replace(content().retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DnsRawRecord replace(ByteBuf content) {
|
||||||
|
return new DefaultDnsRawRecord(name(), type(), dnsClass(), timeToLive(), content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -95,7 +95,7 @@ public class DefaultDnsRecordDecoder implements DnsRecordDecoder {
|
|||||||
return new DefaultDnsPtrRecord(name, dnsClass, timeToLive, decodeName(in));
|
return new DefaultDnsPtrRecord(name, dnsClass, timeToLive, decodeName(in));
|
||||||
}
|
}
|
||||||
return new DefaultDnsRawRecord(
|
return new DefaultDnsRawRecord(
|
||||||
name, type, dnsClass, timeToLive, in.duplicate().setIndex(offset, offset + length).retain());
|
name, type, dnsClass, timeToLive, in.retainedDuplicate().setIndex(offset, offset + length));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.dns;
|
package io.netty.handler.codec.dns;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufHolder;
|
import io.netty.buffer.ByteBufHolder;
|
||||||
import io.netty.util.internal.UnstableApi;
|
import io.netty.util.internal.UnstableApi;
|
||||||
|
|
||||||
@ -29,6 +30,12 @@ public interface DnsRawRecord extends DnsRecord, ByteBufHolder {
|
|||||||
@Override
|
@Override
|
||||||
DnsRawRecord duplicate();
|
DnsRawRecord duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
DnsRawRecord retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
DnsRawRecord replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
DnsRawRecord retain();
|
DnsRawRecord retain();
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ final class ComposedLastHttpContent implements LastHttpContent {
|
|||||||
ComposedLastHttpContent(HttpHeaders trailingHeaders) {
|
ComposedLastHttpContent(HttpHeaders trailingHeaders) {
|
||||||
this.trailingHeaders = trailingHeaders;
|
this.trailingHeaders = trailingHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpHeaders trailingHeaders() {
|
public HttpHeaders trailingHeaders() {
|
||||||
return trailingHeaders;
|
return trailingHeaders;
|
||||||
@ -39,6 +40,23 @@ final class ComposedLastHttpContent implements LastHttpContent {
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastHttpContent duplicate() {
|
||||||
|
return copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastHttpContent retainedDuplicate() {
|
||||||
|
return copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastHttpContent replace(ByteBuf content) {
|
||||||
|
final LastHttpContent dup = new DefaultLastHttpContent(content);
|
||||||
|
dup.trailingHeaders().setAll(trailingHeaders());
|
||||||
|
return dup;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LastHttpContent retain(int increment) {
|
public LastHttpContent retain(int increment) {
|
||||||
return this;
|
return this;
|
||||||
@ -59,11 +77,6 @@ final class ComposedLastHttpContent implements LastHttpContent {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public LastHttpContent duplicate() {
|
|
||||||
return copy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf content() {
|
public ByteBuf content() {
|
||||||
return Unpooled.EMPTY_BUFFER;
|
return Unpooled.EMPTY_BUFFER;
|
||||||
|
@ -125,44 +125,24 @@ public class DefaultFullHttpRequest extends DefaultHttpRequest implements FullHt
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy this object
|
|
||||||
*
|
|
||||||
* @param copyContent
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code true} if this object's {@link #content()} should be used to copy.</li>
|
|
||||||
* <li>{@code false} if {@code newContent} should be used instead.</li>
|
|
||||||
* </ul>
|
|
||||||
* @param newContent
|
|
||||||
* <ul>
|
|
||||||
* <li>if {@code copyContent} is false then this will be used in the copy's content.</li>
|
|
||||||
* <li>if {@code null} then a default buffer of 0 size will be selected</li>
|
|
||||||
* </ul>
|
|
||||||
* @return A copy of this object
|
|
||||||
*/
|
|
||||||
private FullHttpRequest copy(boolean copyContent, ByteBuf newContent) {
|
|
||||||
return new DefaultFullHttpRequest(
|
|
||||||
protocolVersion(), method(), uri(),
|
|
||||||
copyContent ? content().copy() :
|
|
||||||
newContent == null ? Unpooled.buffer(0) : newContent,
|
|
||||||
headers(),
|
|
||||||
trailingHeaders());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FullHttpRequest copy(ByteBuf newContent) {
|
|
||||||
return copy(false, newContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FullHttpRequest copy() {
|
public FullHttpRequest copy() {
|
||||||
return copy(true, null);
|
return replace(content().copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FullHttpRequest duplicate() {
|
public FullHttpRequest duplicate() {
|
||||||
return new DefaultFullHttpRequest(
|
return replace(content().duplicate());
|
||||||
protocolVersion(), method(), uri(), content().duplicate(), headers(), trailingHeaders());
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullHttpRequest retainedDuplicate() {
|
||||||
|
return replace(content().retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullHttpRequest replace(ByteBuf content) {
|
||||||
|
return new DefaultFullHttpRequest(protocolVersion(), method(), uri(), content, headers(), trailingHeaders());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -132,44 +132,24 @@ public class DefaultFullHttpResponse extends DefaultHttpResponse implements Full
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy this object
|
|
||||||
*
|
|
||||||
* @param copyContent
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code true} if this object's {@link #content()} should be used to copy.</li>
|
|
||||||
* <li>{@code false} if {@code newContent} should be used instead.</li>
|
|
||||||
* </ul>
|
|
||||||
* @param newContent
|
|
||||||
* <ul>
|
|
||||||
* <li>if {@code copyContent} is false then this will be used in the copy's content.</li>
|
|
||||||
* <li>if {@code null} then a default buffer of 0 size will be selected</li>
|
|
||||||
* </ul>
|
|
||||||
* @return A copy of this object
|
|
||||||
*/
|
|
||||||
private FullHttpResponse copy(boolean copyContent, ByteBuf newContent) {
|
|
||||||
return new DefaultFullHttpResponse(
|
|
||||||
protocolVersion(), status(),
|
|
||||||
copyContent ? content().copy() :
|
|
||||||
newContent == null ? Unpooled.buffer(0) : newContent,
|
|
||||||
headers(),
|
|
||||||
trailingHeaders());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FullHttpResponse copy(ByteBuf newContent) {
|
|
||||||
return copy(false, newContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FullHttpResponse copy() {
|
public FullHttpResponse copy() {
|
||||||
return copy(true, null);
|
return replace(content().copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FullHttpResponse duplicate() {
|
public FullHttpResponse duplicate() {
|
||||||
return new DefaultFullHttpResponse(protocolVersion(), status(),
|
return replace(content().duplicate());
|
||||||
content().duplicate(), headers(), trailingHeaders());
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullHttpResponse retainedDuplicate() {
|
||||||
|
return replace(content().retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullHttpResponse replace(ByteBuf content) {
|
||||||
|
return new DefaultFullHttpResponse(protocolVersion(), status(), content, headers(), trailingHeaders());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -42,12 +42,22 @@ public class DefaultHttpContent extends DefaultHttpObject implements HttpContent
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpContent copy() {
|
public HttpContent copy() {
|
||||||
return new DefaultHttpContent(content.copy());
|
return replace(content.copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpContent duplicate() {
|
public HttpContent duplicate() {
|
||||||
return new DefaultHttpContent(content.duplicate());
|
return replace(content.duplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpContent retainedDuplicate() {
|
||||||
|
return replace(content.retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpContent replace(ByteBuf content) {
|
||||||
|
return new DefaultHttpContent(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,16 +45,24 @@ public class DefaultLastHttpContent extends DefaultHttpContent implements LastHt
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LastHttpContent copy() {
|
public LastHttpContent copy() {
|
||||||
DefaultLastHttpContent copy = new DefaultLastHttpContent(content().copy(), validateHeaders);
|
return replace(content().copy());
|
||||||
copy.trailingHeaders().set(trailingHeaders());
|
|
||||||
return copy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LastHttpContent duplicate() {
|
public LastHttpContent duplicate() {
|
||||||
DefaultLastHttpContent copy = new DefaultLastHttpContent(content().duplicate(), validateHeaders);
|
return replace(content().duplicate());
|
||||||
copy.trailingHeaders().set(trailingHeaders());
|
}
|
||||||
return copy;
|
|
||||||
|
@Override
|
||||||
|
public LastHttpContent retainedDuplicate() {
|
||||||
|
return replace(content().retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastHttpContent replace(ByteBuf content) {
|
||||||
|
final DefaultLastHttpContent dup = new DefaultLastHttpContent(content, validateHeaders);
|
||||||
|
dup.trailingHeaders().set(trailingHeaders());
|
||||||
|
return dup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -22,19 +22,18 @@ import io.netty.buffer.ByteBuf;
|
|||||||
* message. So it represent a <i>complete</i> http message.
|
* message. So it represent a <i>complete</i> http message.
|
||||||
*/
|
*/
|
||||||
public interface FullHttpMessage extends HttpMessage, LastHttpContent {
|
public interface FullHttpMessage extends HttpMessage, LastHttpContent {
|
||||||
/**
|
|
||||||
* Create a copy of this {@link FullHttpMessage} with alternative content.
|
|
||||||
*
|
|
||||||
* @param newContent The buffer to use instead of this {@link FullHttpMessage}'s content in the copy operation.
|
|
||||||
* <p>
|
|
||||||
* NOTE: retain will NOT be called on this buffer. {@code null} results in an empty default choice buffer.
|
|
||||||
* @return The result of the copy operation
|
|
||||||
*/
|
|
||||||
FullHttpMessage copy(ByteBuf newContent);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullHttpMessage copy();
|
FullHttpMessage copy();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullHttpMessage duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullHttpMessage retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullHttpMessage replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullHttpMessage retain(int increment);
|
FullHttpMessage retain(int increment);
|
||||||
|
|
||||||
@ -46,7 +45,4 @@ public interface FullHttpMessage extends HttpMessage, LastHttpContent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullHttpMessage touch(Object hint);
|
FullHttpMessage touch(Object hint);
|
||||||
|
|
||||||
@Override
|
|
||||||
FullHttpMessage duplicate();
|
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,16 @@ import io.netty.buffer.ByteBuf;
|
|||||||
*/
|
*/
|
||||||
public interface FullHttpRequest extends HttpRequest, FullHttpMessage {
|
public interface FullHttpRequest extends HttpRequest, FullHttpMessage {
|
||||||
@Override
|
@Override
|
||||||
FullHttpRequest copy(ByteBuf newContent);
|
FullHttpRequest copy();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullHttpRequest copy();
|
FullHttpRequest duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullHttpRequest retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullHttpRequest replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullHttpRequest retain(int increment);
|
FullHttpRequest retain(int increment);
|
||||||
@ -40,9 +46,6 @@ public interface FullHttpRequest extends HttpRequest, FullHttpMessage {
|
|||||||
@Override
|
@Override
|
||||||
FullHttpRequest touch(Object hint);
|
FullHttpRequest touch(Object hint);
|
||||||
|
|
||||||
@Override
|
|
||||||
FullHttpRequest duplicate();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullHttpRequest setProtocolVersion(HttpVersion version);
|
FullHttpRequest setProtocolVersion(HttpVersion version);
|
||||||
|
|
||||||
|
@ -23,10 +23,16 @@ import io.netty.buffer.ByteBuf;
|
|||||||
*/
|
*/
|
||||||
public interface FullHttpResponse extends HttpResponse, FullHttpMessage {
|
public interface FullHttpResponse extends HttpResponse, FullHttpMessage {
|
||||||
@Override
|
@Override
|
||||||
FullHttpResponse copy(ByteBuf newContent);
|
FullHttpResponse copy();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullHttpResponse copy();
|
FullHttpResponse duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullHttpResponse retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullHttpResponse replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullHttpResponse retain(int increment);
|
FullHttpResponse retain(int increment);
|
||||||
@ -40,9 +46,6 @@ public interface FullHttpResponse extends HttpResponse, FullHttpMessage {
|
|||||||
@Override
|
@Override
|
||||||
FullHttpResponse touch(Object hint);
|
FullHttpResponse touch(Object hint);
|
||||||
|
|
||||||
@Override
|
|
||||||
FullHttpResponse duplicate();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullHttpResponse setProtocolVersion(HttpVersion version);
|
FullHttpResponse setProtocolVersion(HttpVersion version);
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.http;
|
package io.netty.handler.codec.http;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufHolder;
|
import io.netty.buffer.ByteBufHolder;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
|
|
||||||
@ -33,6 +34,12 @@ public interface HttpContent extends HttpObject, ByteBufHolder {
|
|||||||
@Override
|
@Override
|
||||||
HttpContent duplicate();
|
HttpContent duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
HttpContent retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
HttpContent replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
HttpContent retain();
|
HttpContent retain();
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
package io.netty.handler.codec.http;
|
package io.netty.handler.codec.http;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufHolder;
|
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
@ -121,11 +120,11 @@ public class HttpObjectAggregator
|
|||||||
protected Object newContinueResponse(HttpMessage start, int maxContentLength, ChannelPipeline pipeline) {
|
protected Object newContinueResponse(HttpMessage start, int maxContentLength, ChannelPipeline pipeline) {
|
||||||
if (HttpUtil.is100ContinueExpected(start)) {
|
if (HttpUtil.is100ContinueExpected(start)) {
|
||||||
if (getContentLength(start, -1L) <= maxContentLength) {
|
if (getContentLength(start, -1L) <= maxContentLength) {
|
||||||
return CONTINUE.duplicate().retain();
|
return CONTINUE.retainedDuplicate();
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline.fireUserEventTriggered(HttpExpectationFailedEvent.INSTANCE);
|
pipeline.fireUserEventTriggered(HttpExpectationFailedEvent.INSTANCE);
|
||||||
return EXPECTATION_FAILED.duplicate().retain();
|
return EXPECTATION_FAILED.retainedDuplicate();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -176,7 +175,7 @@ public class HttpObjectAggregator
|
|||||||
// See rfc2616 14.13 Content-Length
|
// See rfc2616 14.13 Content-Length
|
||||||
if (!HttpUtil.isContentLengthSet(aggregated)) {
|
if (!HttpUtil.isContentLengthSet(aggregated)) {
|
||||||
aggregated.headers().set(
|
aggregated.headers().set(
|
||||||
HttpHeaderNames.CONTENT_LENGTH,
|
CONTENT_LENGTH,
|
||||||
String.valueOf(aggregated.content().readableBytes()));
|
String.valueOf(aggregated.content().readableBytes()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,7 +184,7 @@ public class HttpObjectAggregator
|
|||||||
protected void handleOversizedMessage(final ChannelHandlerContext ctx, HttpMessage oversized) throws Exception {
|
protected void handleOversizedMessage(final ChannelHandlerContext ctx, HttpMessage oversized) throws Exception {
|
||||||
if (oversized instanceof HttpRequest) {
|
if (oversized instanceof HttpRequest) {
|
||||||
// send back a 413 and close the connection
|
// send back a 413 and close the connection
|
||||||
ChannelFuture future = ctx.writeAndFlush(TOO_LARGE.duplicate().retain()).addListener(
|
ChannelFuture future = ctx.writeAndFlush(TOO_LARGE.retainedDuplicate()).addListener(
|
||||||
new ChannelFutureListener() {
|
new ChannelFutureListener() {
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(ChannelFuture future) throws Exception {
|
public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
@ -217,7 +216,7 @@ public class HttpObjectAggregator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract static class AggregatedFullHttpMessage implements ByteBufHolder, FullHttpMessage {
|
private abstract static class AggregatedFullHttpMessage implements FullHttpMessage {
|
||||||
protected final HttpMessage message;
|
protected final HttpMessage message;
|
||||||
private final ByteBuf content;
|
private final ByteBuf content;
|
||||||
private HttpHeaders trailingHeaders;
|
private HttpHeaders trailingHeaders;
|
||||||
@ -327,6 +326,9 @@ public class HttpObjectAggregator
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract FullHttpMessage duplicate();
|
public abstract FullHttpMessage duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract FullHttpMessage retainedDuplicate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class AggregatedFullHttpRequest extends AggregatedFullHttpMessage implements FullHttpRequest {
|
private static final class AggregatedFullHttpRequest extends AggregatedFullHttpMessage implements FullHttpRequest {
|
||||||
@ -335,48 +337,27 @@ public class HttpObjectAggregator
|
|||||||
super(request, content, trailingHeaders);
|
super(request, content, trailingHeaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy this object
|
|
||||||
*
|
|
||||||
* @param copyContent
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code true} if this object's {@link #content()} should be used to copy.</li>
|
|
||||||
* <li>{@code false} if {@code newContent} should be used instead.</li>
|
|
||||||
* </ul>
|
|
||||||
* @param newContent
|
|
||||||
* <ul>
|
|
||||||
* <li>if {@code copyContent} is false then this will be used in the copy's content.</li>
|
|
||||||
* <li>if {@code null} then a default buffer of 0 size will be selected</li>
|
|
||||||
* </ul>
|
|
||||||
* @return A copy of this object
|
|
||||||
*/
|
|
||||||
private FullHttpRequest copy(boolean copyContent, ByteBuf newContent) {
|
|
||||||
DefaultFullHttpRequest copy = new DefaultFullHttpRequest(
|
|
||||||
protocolVersion(), method(), uri(),
|
|
||||||
copyContent ? content().copy() :
|
|
||||||
newContent == null ? Unpooled.buffer(0) : newContent);
|
|
||||||
copy.headers().set(headers());
|
|
||||||
copy.trailingHeaders().set(trailingHeaders());
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FullHttpRequest copy(ByteBuf newContent) {
|
|
||||||
return copy(false, newContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FullHttpRequest copy() {
|
public FullHttpRequest copy() {
|
||||||
return copy(true, null);
|
return replace(content().copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FullHttpRequest duplicate() {
|
public FullHttpRequest duplicate() {
|
||||||
DefaultFullHttpRequest duplicate = new DefaultFullHttpRequest(
|
return replace(content().duplicate());
|
||||||
getProtocolVersion(), getMethod(), getUri(), content().duplicate());
|
}
|
||||||
duplicate.headers().set(headers());
|
|
||||||
duplicate.trailingHeaders().set(trailingHeaders());
|
@Override
|
||||||
return duplicate;
|
public FullHttpRequest retainedDuplicate() {
|
||||||
|
return replace(content().retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullHttpRequest replace(ByteBuf content) {
|
||||||
|
DefaultFullHttpRequest dup = new DefaultFullHttpRequest(protocolVersion(), method(), uri(), content);
|
||||||
|
dup.headers().set(headers());
|
||||||
|
dup.trailingHeaders().set(trailingHeaders());
|
||||||
|
return dup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -454,48 +435,27 @@ public class HttpObjectAggregator
|
|||||||
super(message, content, trailingHeaders);
|
super(message, content, trailingHeaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy this object
|
|
||||||
*
|
|
||||||
* @param copyContent
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code true} if this object's {@link #content()} should be used to copy.</li>
|
|
||||||
* <li>{@code false} if {@code newContent} should be used instead.</li>
|
|
||||||
* </ul>
|
|
||||||
* @param newContent
|
|
||||||
* <ul>
|
|
||||||
* <li>if {@code copyContent} is false then this will be used in the copy's content.</li>
|
|
||||||
* <li>if {@code null} then a default buffer of 0 size will be selected</li>
|
|
||||||
* </ul>
|
|
||||||
* @return A copy of this object
|
|
||||||
*/
|
|
||||||
private FullHttpResponse copy(boolean copyContent, ByteBuf newContent) {
|
|
||||||
DefaultFullHttpResponse copy = new DefaultFullHttpResponse(
|
|
||||||
protocolVersion(), status(),
|
|
||||||
copyContent ? content().copy() :
|
|
||||||
newContent == null ? Unpooled.buffer(0) : newContent);
|
|
||||||
copy.headers().set(headers());
|
|
||||||
copy.trailingHeaders().set(trailingHeaders());
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FullHttpResponse copy(ByteBuf newContent) {
|
|
||||||
return copy(false, newContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FullHttpResponse copy() {
|
public FullHttpResponse copy() {
|
||||||
return copy(true, null);
|
return replace(content().copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FullHttpResponse duplicate() {
|
public FullHttpResponse duplicate() {
|
||||||
DefaultFullHttpResponse duplicate = new DefaultFullHttpResponse(getProtocolVersion(), getStatus(),
|
return replace(content().duplicate());
|
||||||
content().duplicate());
|
}
|
||||||
duplicate.headers().set(headers());
|
|
||||||
duplicate.trailingHeaders().set(trailingHeaders());
|
@Override
|
||||||
return duplicate;
|
public FullHttpResponse retainedDuplicate() {
|
||||||
|
return replace(content().retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullHttpResponse replace(ByteBuf content) {
|
||||||
|
DefaultFullHttpResponse dup = new DefaultFullHttpResponse(getProtocolVersion(), getStatus(), content);
|
||||||
|
dup.headers().set(headers());
|
||||||
|
dup.trailingHeaders().set(trailingHeaders());
|
||||||
|
return dup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -279,7 +279,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
|
|||||||
// Keep reading data as a chunk until the end of connection is reached.
|
// Keep reading data as a chunk until the end of connection is reached.
|
||||||
int toRead = Math.min(buffer.readableBytes(), maxChunkSize);
|
int toRead = Math.min(buffer.readableBytes(), maxChunkSize);
|
||||||
if (toRead > 0) {
|
if (toRead > 0) {
|
||||||
ByteBuf content = buffer.readSlice(toRead).retain();
|
ByteBuf content = buffer.readRetainedSlice(toRead);
|
||||||
out.add(new DefaultHttpContent(content));
|
out.add(new DefaultHttpContent(content));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -301,7 +301,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
|
|||||||
if (toRead > chunkSize) {
|
if (toRead > chunkSize) {
|
||||||
toRead = (int) chunkSize;
|
toRead = (int) chunkSize;
|
||||||
}
|
}
|
||||||
ByteBuf content = buffer.readSlice(toRead).retain();
|
ByteBuf content = buffer.readRetainedSlice(toRead);
|
||||||
chunkSize -= toRead;
|
chunkSize -= toRead;
|
||||||
|
|
||||||
if (chunkSize == 0) {
|
if (chunkSize == 0) {
|
||||||
@ -341,7 +341,7 @@ public abstract class HttpObjectDecoder extends ByteToMessageDecoder {
|
|||||||
if (toRead == 0) {
|
if (toRead == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HttpContent chunk = new DefaultHttpContent(buffer.readSlice(toRead).retain());
|
HttpContent chunk = new DefaultHttpContent(buffer.readRetainedSlice(toRead));
|
||||||
chunkSize -= toRead;
|
chunkSize -= toRead;
|
||||||
|
|
||||||
out.add(chunk);
|
out.add(chunk);
|
||||||
|
@ -44,6 +44,16 @@ public interface LastHttpContent extends HttpContent {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastHttpContent replace(ByteBuf content) {
|
||||||
|
return new DefaultLastHttpContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastHttpContent retainedDuplicate() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpHeaders trailingHeaders() {
|
public HttpHeaders trailingHeaders() {
|
||||||
return EmptyHttpHeaders.INSTANCE;
|
return EmptyHttpHeaders.INSTANCE;
|
||||||
@ -111,6 +121,15 @@ public interface LastHttpContent extends HttpContent {
|
|||||||
@Override
|
@Override
|
||||||
LastHttpContent copy();
|
LastHttpContent copy();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastHttpContent duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastHttpContent retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastHttpContent replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
LastHttpContent retain(int increment);
|
LastHttpContent retain(int increment);
|
||||||
|
|
||||||
@ -122,7 +141,4 @@ public interface LastHttpContent extends HttpContent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
LastHttpContent touch(Object hint);
|
LastHttpContent touch(Object hint);
|
||||||
|
|
||||||
@Override
|
|
||||||
LastHttpContent duplicate();
|
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,10 @@ import java.nio.ByteBuffer;
|
|||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
import static io.netty.buffer.Unpooled.*;
|
import static io.netty.buffer.Unpooled.EMPTY_BUFFER;
|
||||||
|
import static io.netty.buffer.Unpooled.buffer;
|
||||||
|
import static io.netty.buffer.Unpooled.compositeBuffer;
|
||||||
|
import static io.netty.buffer.Unpooled.wrappedBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract Memory HttpData implementation
|
* Abstract Memory HttpData implementation
|
||||||
@ -209,7 +212,7 @@ public abstract class AbstractMemoryHttpData extends AbstractHttpData {
|
|||||||
if (sizeLeft < length) {
|
if (sizeLeft < length) {
|
||||||
sliceLength = sizeLeft;
|
sliceLength = sizeLeft;
|
||||||
}
|
}
|
||||||
ByteBuf chunk = byteBuf.slice(chunkPosition, sliceLength).retain();
|
ByteBuf chunk = byteBuf.retainedSlice(chunkPosition, sliceLength);
|
||||||
chunkPosition += sliceLength;
|
chunkPosition += sliceLength;
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.http.multipart;
|
package io.netty.handler.codec.http.multipart;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,6 +39,12 @@ public interface Attribute extends HttpData {
|
|||||||
@Override
|
@Override
|
||||||
Attribute duplicate();
|
Attribute duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Attribute retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Attribute replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Attribute retain();
|
Attribute retain();
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import io.netty.handler.codec.http.HttpConstants;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
import static io.netty.buffer.Unpooled.*;
|
import static io.netty.buffer.Unpooled.wrappedBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disk implementation of Attributes
|
* Disk implementation of Attributes
|
||||||
@ -162,27 +162,43 @@ public class DiskAttribute extends AbstractDiskHttpData implements Attribute {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Attribute copy() {
|
public Attribute copy() {
|
||||||
DiskAttribute attr = new DiskAttribute(getName());
|
final ByteBuf content = content();
|
||||||
attr.setCharset(getCharset());
|
return replace(content != null ? content.copy() : null);
|
||||||
ByteBuf content = content();
|
|
||||||
if (content != null) {
|
|
||||||
try {
|
|
||||||
attr.setContent(content.copy());
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ChannelException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return attr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Attribute duplicate() {
|
public Attribute duplicate() {
|
||||||
DiskAttribute attr = new DiskAttribute(getName());
|
final ByteBuf content = content();
|
||||||
attr.setCharset(getCharset());
|
return replace(content != null ? content.duplicate() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Attribute retainedDuplicate() {
|
||||||
ByteBuf content = content();
|
ByteBuf content = content();
|
||||||
if (content != null) {
|
if (content != null) {
|
||||||
|
content = content.retainedDuplicate();
|
||||||
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
attr.setContent(content.duplicate());
|
Attribute duplicate = replace(content);
|
||||||
|
success = true;
|
||||||
|
return duplicate;
|
||||||
|
} finally {
|
||||||
|
if (!success) {
|
||||||
|
content.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return replace(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Attribute replace(ByteBuf content) {
|
||||||
|
DiskAttribute attr = new DiskAttribute(getName());
|
||||||
|
attr.setCharset(getCharset());
|
||||||
|
if (content != null) {
|
||||||
|
try {
|
||||||
|
attr.setContent(content);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ChannelException(e);
|
throw new ChannelException(e);
|
||||||
}
|
}
|
||||||
|
@ -173,27 +173,43 @@ public class DiskFileUpload extends AbstractDiskHttpData implements FileUpload {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FileUpload copy() {
|
public FileUpload copy() {
|
||||||
DiskFileUpload upload = new DiskFileUpload(getName(),
|
final ByteBuf content = content();
|
||||||
getFilename(), getContentType(), getContentTransferEncoding(), getCharset(), size);
|
return replace(content != null ? content.copy() : null);
|
||||||
ByteBuf buf = content();
|
|
||||||
if (buf != null) {
|
|
||||||
try {
|
|
||||||
upload.setContent(buf.copy());
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ChannelException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return upload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FileUpload duplicate() {
|
public FileUpload duplicate() {
|
||||||
DiskFileUpload upload = new DiskFileUpload(getName(),
|
final ByteBuf content = content();
|
||||||
getFilename(), getContentType(), getContentTransferEncoding(), getCharset(), size);
|
return replace(content != null ? content.duplicate() : null);
|
||||||
ByteBuf buf = content();
|
}
|
||||||
if (buf != null) {
|
|
||||||
|
@Override
|
||||||
|
public FileUpload retainedDuplicate() {
|
||||||
|
ByteBuf content = content();
|
||||||
|
if (content != null) {
|
||||||
|
content = content.retainedDuplicate();
|
||||||
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
upload.setContent(buf.duplicate());
|
FileUpload duplicate = replace(content);
|
||||||
|
success = true;
|
||||||
|
return duplicate;
|
||||||
|
} finally {
|
||||||
|
if (!success) {
|
||||||
|
content.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return replace(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileUpload replace(ByteBuf content) {
|
||||||
|
DiskFileUpload upload = new DiskFileUpload(
|
||||||
|
getName(), getFilename(), getContentType(), getContentTransferEncoding(), getCharset(), size);
|
||||||
|
if (content != null) {
|
||||||
|
try {
|
||||||
|
upload.setContent(content);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ChannelException(e);
|
throw new ChannelException(e);
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.http.multipart;
|
package io.netty.handler.codec.http.multipart;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FileUpload interface that could be in memory, on temporary file or any other implementations.
|
* FileUpload interface that could be in memory, on temporary file or any other implementations.
|
||||||
*
|
*
|
||||||
@ -62,6 +64,12 @@ public interface FileUpload extends HttpData {
|
|||||||
@Override
|
@Override
|
||||||
FileUpload duplicate();
|
FileUpload duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FileUpload retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FileUpload replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
FileUpload retain();
|
FileUpload retain();
|
||||||
|
|
||||||
|
@ -219,6 +219,12 @@ public interface HttpData extends InterfaceHttpData, ByteBufHolder {
|
|||||||
@Override
|
@Override
|
||||||
HttpData duplicate();
|
HttpData duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
HttpData retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
HttpData replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
HttpData retain();
|
HttpData retain();
|
||||||
|
|
||||||
|
@ -26,11 +26,11 @@ import io.netty.handler.codec.http.FullHttpRequest;
|
|||||||
import io.netty.handler.codec.http.HttpConstants;
|
import io.netty.handler.codec.http.HttpConstants;
|
||||||
import io.netty.handler.codec.http.HttpContent;
|
import io.netty.handler.codec.http.HttpContent;
|
||||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||||
import io.netty.handler.codec.http.HttpUtil;
|
|
||||||
import io.netty.handler.codec.http.HttpHeaderValues;
|
import io.netty.handler.codec.http.HttpHeaderValues;
|
||||||
import io.netty.handler.codec.http.HttpHeaders;
|
import io.netty.handler.codec.http.HttpHeaders;
|
||||||
import io.netty.handler.codec.http.HttpMethod;
|
import io.netty.handler.codec.http.HttpMethod;
|
||||||
import io.netty.handler.codec.http.HttpRequest;
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
|
import io.netty.handler.codec.http.HttpUtil;
|
||||||
import io.netty.handler.codec.http.HttpVersion;
|
import io.netty.handler.codec.http.HttpVersion;
|
||||||
import io.netty.handler.codec.http.LastHttpContent;
|
import io.netty.handler.codec.http.LastHttpContent;
|
||||||
import io.netty.handler.stream.ChunkedInput;
|
import io.netty.handler.stream.ChunkedInput;
|
||||||
@ -48,7 +48,7 @@ import java.util.ListIterator;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static io.netty.buffer.Unpooled.*;
|
import static io.netty.buffer.Unpooled.wrappedBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This encoder will help to encode Request for a FORM as POST.
|
* This encoder will help to encode Request for a FORM as POST.
|
||||||
@ -836,7 +836,6 @@ public class HttpPostRequestEncoder implements ChunkedInput<HttpContent> {
|
|||||||
int length = currentBuffer.readableBytes();
|
int length = currentBuffer.readableBytes();
|
||||||
if (length > HttpPostBodyUtil.chunkSize) {
|
if (length > HttpPostBodyUtil.chunkSize) {
|
||||||
ByteBuf slice = currentBuffer.slice(currentBuffer.readerIndex(), HttpPostBodyUtil.chunkSize);
|
ByteBuf slice = currentBuffer.slice(currentBuffer.readerIndex(), HttpPostBodyUtil.chunkSize);
|
||||||
currentBuffer.retain();
|
|
||||||
currentBuffer.skipBytes(HttpPostBodyUtil.chunkSize);
|
currentBuffer.skipBytes(HttpPostBodyUtil.chunkSize);
|
||||||
return slice;
|
return slice;
|
||||||
} else {
|
} else {
|
||||||
@ -1239,45 +1238,24 @@ public class HttpPostRequestEncoder implements ChunkedInput<HttpContent> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy this object
|
|
||||||
*
|
|
||||||
* @param copyContent
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code true} if this object's {@link #content()} should be used to copy.</li>
|
|
||||||
* <li>{@code false} if {@code newContent} should be used instead.</li>
|
|
||||||
* </ul>
|
|
||||||
* @param newContent
|
|
||||||
* <ul>
|
|
||||||
* <li>if {@code copyContent} is false then this will be used in the copy's content.</li>
|
|
||||||
* <li>if {@code null} then a default buffer of 0 size will be selected</li>
|
|
||||||
* </ul>
|
|
||||||
* @return A copy of this object
|
|
||||||
*/
|
|
||||||
private FullHttpRequest copy(boolean copyContent, ByteBuf newContent) {
|
|
||||||
DefaultFullHttpRequest copy = new DefaultFullHttpRequest(
|
|
||||||
protocolVersion(), method(), uri(),
|
|
||||||
copyContent ? content().copy() :
|
|
||||||
newContent == null ? buffer(0) : newContent);
|
|
||||||
copy.headers().set(headers());
|
|
||||||
copy.trailingHeaders().set(trailingHeaders());
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FullHttpRequest copy(ByteBuf newContent) {
|
|
||||||
return copy(false, newContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FullHttpRequest copy() {
|
public FullHttpRequest copy() {
|
||||||
return copy(true, null);
|
return replace(content().copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FullHttpRequest duplicate() {
|
public FullHttpRequest duplicate() {
|
||||||
DefaultFullHttpRequest duplicate = new DefaultFullHttpRequest(
|
return replace(content().duplicate());
|
||||||
getProtocolVersion(), getMethod(), getUri(), content().duplicate());
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullHttpRequest retainedDuplicate() {
|
||||||
|
return replace(content().retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullHttpRequest replace(ByteBuf content) {
|
||||||
|
DefaultFullHttpRequest duplicate = new DefaultFullHttpRequest(protocolVersion(), method(), uri(), content);
|
||||||
duplicate.headers().set(headers());
|
duplicate.headers().set(headers());
|
||||||
duplicate.trailingHeaders().set(trailingHeaders());
|
duplicate.trailingHeaders().set(trailingHeaders());
|
||||||
return duplicate;
|
return duplicate;
|
||||||
|
@ -122,27 +122,43 @@ public class MemoryAttribute extends AbstractMemoryHttpData implements Attribute
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Attribute copy() {
|
public Attribute copy() {
|
||||||
MemoryAttribute attr = new MemoryAttribute(getName());
|
final ByteBuf content = content();
|
||||||
attr.setCharset(getCharset());
|
return replace(content != null ? content.copy() : null);
|
||||||
ByteBuf content = content();
|
|
||||||
if (content != null) {
|
|
||||||
try {
|
|
||||||
attr.setContent(content.copy());
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ChannelException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return attr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Attribute duplicate() {
|
public Attribute duplicate() {
|
||||||
MemoryAttribute attr = new MemoryAttribute(getName());
|
final ByteBuf content = content();
|
||||||
attr.setCharset(getCharset());
|
return replace(content != null ? content.duplicate() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Attribute retainedDuplicate() {
|
||||||
ByteBuf content = content();
|
ByteBuf content = content();
|
||||||
if (content != null) {
|
if (content != null) {
|
||||||
|
content = content.retainedDuplicate();
|
||||||
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
attr.setContent(content.duplicate());
|
Attribute duplicate = replace(content);
|
||||||
|
success = true;
|
||||||
|
return duplicate;
|
||||||
|
} finally {
|
||||||
|
if (!success) {
|
||||||
|
content.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return replace(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Attribute replace(ByteBuf content) {
|
||||||
|
MemoryAttribute attr = new MemoryAttribute(getName());
|
||||||
|
attr.setCharset(getCharset());
|
||||||
|
if (content != null) {
|
||||||
|
try {
|
||||||
|
attr.setContent(content);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ChannelException(e);
|
throw new ChannelException(e);
|
||||||
}
|
}
|
||||||
|
@ -132,12 +132,43 @@ public class MemoryFileUpload extends AbstractMemoryHttpData implements FileUplo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FileUpload copy() {
|
public FileUpload copy() {
|
||||||
MemoryFileUpload upload = new MemoryFileUpload(getName(), getFilename(), getContentType(),
|
final ByteBuf content = content();
|
||||||
getContentTransferEncoding(), getCharset(), size);
|
return replace(content != null ? content.copy() : content);
|
||||||
ByteBuf buf = content();
|
}
|
||||||
if (buf != null) {
|
|
||||||
|
@Override
|
||||||
|
public FileUpload duplicate() {
|
||||||
|
final ByteBuf content = content();
|
||||||
|
return replace(content != null ? content.duplicate() : content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileUpload retainedDuplicate() {
|
||||||
|
ByteBuf content = content();
|
||||||
|
if (content != null) {
|
||||||
|
content = content.retainedDuplicate();
|
||||||
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
upload.setContent(buf.copy());
|
FileUpload duplicate = replace(content);
|
||||||
|
success = true;
|
||||||
|
return duplicate;
|
||||||
|
} finally {
|
||||||
|
if (!success) {
|
||||||
|
content.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return replace(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileUpload replace(ByteBuf content) {
|
||||||
|
MemoryFileUpload upload = new MemoryFileUpload(
|
||||||
|
getName(), getFilename(), getContentType(), getContentTransferEncoding(), getCharset(), size);
|
||||||
|
if (content != null) {
|
||||||
|
try {
|
||||||
|
upload.setContent(content);
|
||||||
return upload;
|
return upload;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ChannelException(e);
|
throw new ChannelException(e);
|
||||||
@ -146,21 +177,6 @@ public class MemoryFileUpload extends AbstractMemoryHttpData implements FileUplo
|
|||||||
return upload;
|
return upload;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileUpload duplicate() {
|
|
||||||
MemoryFileUpload upload = new MemoryFileUpload(getName(), getFilename(), getContentType(),
|
|
||||||
getContentTransferEncoding(), getCharset(), size);
|
|
||||||
ByteBuf buf = content();
|
|
||||||
if (buf != null) {
|
|
||||||
try {
|
|
||||||
upload.setContent(buf.duplicate());
|
|
||||||
return upload;
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ChannelException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return upload;
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public FileUpload retain() {
|
public FileUpload retain() {
|
||||||
super.retain();
|
super.retain();
|
||||||
|
@ -271,6 +271,16 @@ public class MixedAttribute implements Attribute {
|
|||||||
return attribute.duplicate();
|
return attribute.duplicate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Attribute retainedDuplicate() {
|
||||||
|
return attribute.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Attribute replace(ByteBuf content) {
|
||||||
|
return attribute.replace(content);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf content() {
|
public ByteBuf content() {
|
||||||
return attribute.content();
|
return attribute.content();
|
||||||
|
@ -293,6 +293,16 @@ public class MixedFileUpload implements FileUpload {
|
|||||||
return fileUpload.duplicate();
|
return fileUpload.duplicate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileUpload retainedDuplicate() {
|
||||||
|
return fileUpload.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileUpload replace(ByteBuf content) {
|
||||||
|
return fileUpload.replace(content);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf content() {
|
public ByteBuf content() {
|
||||||
return fileUpload.content();
|
return fileUpload.content();
|
||||||
|
@ -56,12 +56,22 @@ public class BinaryWebSocketFrame extends WebSocketFrame {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BinaryWebSocketFrame copy() {
|
public BinaryWebSocketFrame copy() {
|
||||||
return new BinaryWebSocketFrame(isFinalFragment(), rsv(), content().copy());
|
return (BinaryWebSocketFrame) super.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BinaryWebSocketFrame duplicate() {
|
public BinaryWebSocketFrame duplicate() {
|
||||||
return new BinaryWebSocketFrame(isFinalFragment(), rsv(), content().duplicate());
|
return (BinaryWebSocketFrame) super.duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BinaryWebSocketFrame retainedDuplicate() {
|
||||||
|
return (BinaryWebSocketFrame) super.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BinaryWebSocketFrame replace(ByteBuf content) {
|
||||||
|
return new BinaryWebSocketFrame(isFinalFragment(), rsv(), content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -140,12 +140,22 @@ public class CloseWebSocketFrame extends WebSocketFrame {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CloseWebSocketFrame copy() {
|
public CloseWebSocketFrame copy() {
|
||||||
return new CloseWebSocketFrame(isFinalFragment(), rsv(), content().copy());
|
return (CloseWebSocketFrame) super.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CloseWebSocketFrame duplicate() {
|
public CloseWebSocketFrame duplicate() {
|
||||||
return new CloseWebSocketFrame(isFinalFragment(), rsv(), content().duplicate());
|
return (CloseWebSocketFrame) super.duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CloseWebSocketFrame retainedDuplicate() {
|
||||||
|
return (CloseWebSocketFrame) super.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CloseWebSocketFrame replace(ByteBuf content) {
|
||||||
|
return new CloseWebSocketFrame(isFinalFragment(), rsv(), content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -93,12 +93,22 @@ public class ContinuationWebSocketFrame extends WebSocketFrame {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContinuationWebSocketFrame copy() {
|
public ContinuationWebSocketFrame copy() {
|
||||||
return new ContinuationWebSocketFrame(isFinalFragment(), rsv(), content().copy());
|
return (ContinuationWebSocketFrame) super.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContinuationWebSocketFrame duplicate() {
|
public ContinuationWebSocketFrame duplicate() {
|
||||||
return new ContinuationWebSocketFrame(isFinalFragment(), rsv(), content().duplicate());
|
return (ContinuationWebSocketFrame) super.duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContinuationWebSocketFrame retainedDuplicate() {
|
||||||
|
return (ContinuationWebSocketFrame) super.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContinuationWebSocketFrame replace(ByteBuf content) {
|
||||||
|
return new ContinuationWebSocketFrame(isFinalFragment(), rsv(), content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -56,12 +56,22 @@ public class PingWebSocketFrame extends WebSocketFrame {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PingWebSocketFrame copy() {
|
public PingWebSocketFrame copy() {
|
||||||
return new PingWebSocketFrame(isFinalFragment(), rsv(), content().copy());
|
return (PingWebSocketFrame) super.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PingWebSocketFrame duplicate() {
|
public PingWebSocketFrame duplicate() {
|
||||||
return new PingWebSocketFrame(isFinalFragment(), rsv(), content().duplicate());
|
return (PingWebSocketFrame) super.duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PingWebSocketFrame retainedDuplicate() {
|
||||||
|
return (PingWebSocketFrame) super.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PingWebSocketFrame replace(ByteBuf content) {
|
||||||
|
return new PingWebSocketFrame(isFinalFragment(), rsv(), content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -56,12 +56,22 @@ public class PongWebSocketFrame extends WebSocketFrame {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PongWebSocketFrame copy() {
|
public PongWebSocketFrame copy() {
|
||||||
return new PongWebSocketFrame(isFinalFragment(), rsv(), content().copy());
|
return (PongWebSocketFrame) super.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PongWebSocketFrame duplicate() {
|
public PongWebSocketFrame duplicate() {
|
||||||
return new PongWebSocketFrame(isFinalFragment(), rsv(), content().duplicate());
|
return (PongWebSocketFrame) super.duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PongWebSocketFrame retainedDuplicate() {
|
||||||
|
return (PongWebSocketFrame) super.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PongWebSocketFrame replace(ByteBuf content) {
|
||||||
|
return new PongWebSocketFrame(isFinalFragment(), rsv(), content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -96,12 +96,22 @@ public class TextWebSocketFrame extends WebSocketFrame {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TextWebSocketFrame copy() {
|
public TextWebSocketFrame copy() {
|
||||||
return new TextWebSocketFrame(isFinalFragment(), rsv(), content().copy());
|
return (TextWebSocketFrame) super.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TextWebSocketFrame duplicate() {
|
public TextWebSocketFrame duplicate() {
|
||||||
return new TextWebSocketFrame(isFinalFragment(), rsv(), content().duplicate());
|
return (TextWebSocketFrame) super.duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextWebSocketFrame retainedDuplicate() {
|
||||||
|
return (TextWebSocketFrame) super.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextWebSocketFrame replace(ByteBuf content) {
|
||||||
|
return new TextWebSocketFrame(isFinalFragment(), rsv(), content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -61,10 +61,22 @@ public abstract class WebSocketFrame extends DefaultByteBufHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract WebSocketFrame copy();
|
public WebSocketFrame copy() {
|
||||||
|
return (WebSocketFrame) super.copy();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract WebSocketFrame duplicate();
|
public WebSocketFrame duplicate() {
|
||||||
|
return (WebSocketFrame) super.duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WebSocketFrame retainedDuplicate() {
|
||||||
|
return (WebSocketFrame) super.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract WebSocketFrame replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -80,14 +80,22 @@ public class DefaultSpdyDataFrame extends DefaultSpdyStreamFrame implements Spdy
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpdyDataFrame copy() {
|
public SpdyDataFrame copy() {
|
||||||
SpdyDataFrame frame = new DefaultSpdyDataFrame(streamId(), content().copy());
|
return replace(content().copy());
|
||||||
frame.setLast(isLast());
|
|
||||||
return frame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpdyDataFrame duplicate() {
|
public SpdyDataFrame duplicate() {
|
||||||
SpdyDataFrame frame = new DefaultSpdyDataFrame(streamId(), content().duplicate());
|
return replace(content().duplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SpdyDataFrame retainedDuplicate() {
|
||||||
|
return replace(content().retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SpdyDataFrame replace(ByteBuf content) {
|
||||||
|
SpdyDataFrame frame = new DefaultSpdyDataFrame(streamId(), content);
|
||||||
frame.setLast(isLast());
|
frame.setLast(isLast());
|
||||||
return frame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,12 @@ public interface SpdyDataFrame extends ByteBufHolder, SpdyStreamFrame {
|
|||||||
@Override
|
@Override
|
||||||
SpdyDataFrame duplicate();
|
SpdyDataFrame duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
SpdyDataFrame retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
SpdyDataFrame replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
SpdyDataFrame retain();
|
SpdyDataFrame retain();
|
||||||
|
|
||||||
|
@ -24,7 +24,8 @@ import io.netty.util.internal.EmptyArrays;
|
|||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import static io.netty.handler.codec.spdy.SpdyCodecUtil.*;
|
import static io.netty.handler.codec.spdy.SpdyCodecUtil.SPDY_SESSION_STREAM_ID;
|
||||||
|
import static io.netty.handler.codec.spdy.SpdyCodecUtil.isServerId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages streams within a SPDY session.
|
* Manages streams within a SPDY session.
|
||||||
@ -190,8 +191,8 @@ public class SpdySessionHandler extends ChannelDuplexHandler {
|
|||||||
// Send data frames upstream in initialReceiveWindowSize chunks
|
// Send data frames upstream in initialReceiveWindowSize chunks
|
||||||
if (newWindowSize < 0) {
|
if (newWindowSize < 0) {
|
||||||
while (spdyDataFrame.content().readableBytes() > initialReceiveWindowSize) {
|
while (spdyDataFrame.content().readableBytes() > initialReceiveWindowSize) {
|
||||||
SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId,
|
SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(
|
||||||
spdyDataFrame.content().readSlice(initialReceiveWindowSize).retain());
|
streamId, spdyDataFrame.content().readRetainedSlice(initialReceiveWindowSize));
|
||||||
ctx.writeAndFlush(partialDataFrame);
|
ctx.writeAndFlush(partialDataFrame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -497,8 +498,8 @@ public class SpdySessionHandler extends ChannelDuplexHandler {
|
|||||||
spdySession.updateSendWindowSize(SPDY_SESSION_STREAM_ID, -1 * sendWindowSize);
|
spdySession.updateSendWindowSize(SPDY_SESSION_STREAM_ID, -1 * sendWindowSize);
|
||||||
|
|
||||||
// Create a partial data frame whose length is the current window size
|
// Create a partial data frame whose length is the current window size
|
||||||
SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(streamId,
|
SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(
|
||||||
spdyDataFrame.content().readSlice(sendWindowSize).retain());
|
streamId, spdyDataFrame.content().readRetainedSlice(sendWindowSize));
|
||||||
|
|
||||||
// Enqueue the remaining data (will be the first frame queued)
|
// Enqueue the remaining data (will be the first frame queued)
|
||||||
spdySession.putPendingWrite(streamId, new SpdySession.PendingWrite(spdyDataFrame, promise));
|
spdySession.putPendingWrite(streamId, new SpdySession.PendingWrite(spdyDataFrame, promise));
|
||||||
@ -778,8 +779,8 @@ public class SpdySessionHandler extends ChannelDuplexHandler {
|
|||||||
spdySession.updateSendWindowSize(SPDY_SESSION_STREAM_ID, -1 * sendWindowSize);
|
spdySession.updateSendWindowSize(SPDY_SESSION_STREAM_ID, -1 * sendWindowSize);
|
||||||
|
|
||||||
// Create a partial data frame whose length is the current window size
|
// Create a partial data frame whose length is the current window size
|
||||||
SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(writeStreamId,
|
SpdyDataFrame partialDataFrame = new DefaultSpdyDataFrame(
|
||||||
spdyDataFrame.content().readSlice(sendWindowSize).retain());
|
writeStreamId, spdyDataFrame.content().readRetainedSlice(sendWindowSize));
|
||||||
|
|
||||||
// The transfer window size is pre-decremented when sending a data frame downstream.
|
// The transfer window size is pre-decremented when sending a data frame downstream.
|
||||||
// Close the session on write failures that leave the transfer window in a corrupt state.
|
// Close the session on write failures that leave the transfer window in a corrupt state.
|
||||||
|
@ -74,22 +74,32 @@ public class AbstractMemoryHttpDataTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InterfaceHttpData.HttpDataType getHttpDataType() {
|
public InterfaceHttpData.HttpDataType getHttpDataType() {
|
||||||
throw new UnsupportedOperationException("Should never be called.");
|
throw reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpData copy() {
|
public HttpData copy() {
|
||||||
throw new UnsupportedOperationException("Should never be called.");
|
throw reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpData duplicate() {
|
public HttpData duplicate() {
|
||||||
throw new UnsupportedOperationException("Should never be called.");
|
throw reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpData retainedDuplicate() {
|
||||||
|
throw reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpData replace(ByteBuf content) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(InterfaceHttpData o) {
|
public int compareTo(InterfaceHttpData o) {
|
||||||
throw new UnsupportedOperationException("Should never be called.");
|
throw reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -101,5 +111,9 @@ public class AbstractMemoryHttpDataTest {
|
|||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
return super.equals(obj);
|
return super.equals(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static UnsupportedOperationException reject() {
|
||||||
|
throw new UnsupportedOperationException("Should never be called.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -460,7 +460,7 @@ public class DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder {
|
|||||||
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
public void onPingRead(ChannelHandlerContext ctx, ByteBuf data) throws Http2Exception {
|
||||||
// Send an ack back to the remote client.
|
// Send an ack back to the remote client.
|
||||||
// Need to retain the buffer here since it will be released after the write completes.
|
// Need to retain the buffer here since it will be released after the write completes.
|
||||||
encoder.writePing(ctx, true, data.slice().retain(), ctx.newPromise());
|
encoder.writePing(ctx, true, data.retainedSlice(), ctx.newPromise());
|
||||||
|
|
||||||
listener.onPingRead(ctx, data);
|
listener.onPingRead(ctx, data);
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
import static io.netty.util.internal.ObjectUtil.checkNotNull;
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.util.IllegalReferenceCountException;
|
import io.netty.util.IllegalReferenceCountException;
|
||||||
import io.netty.util.internal.UnstableApi;
|
import io.netty.util.internal.UnstableApi;
|
||||||
|
|
||||||
|
import static io.netty.util.internal.ObjectUtil.checkNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default {@link Http2DataFrame} implementation.
|
* The default {@link Http2DataFrame} implementation.
|
||||||
*/
|
*/
|
||||||
@ -101,12 +101,22 @@ public final class DefaultHttp2DataFrame extends AbstractHttp2StreamFrame implem
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultHttp2DataFrame copy() {
|
public DefaultHttp2DataFrame copy() {
|
||||||
return new DefaultHttp2DataFrame(content().copy(), endStream, padding);
|
return replace(content().copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultHttp2DataFrame duplicate() {
|
public DefaultHttp2DataFrame duplicate() {
|
||||||
return new DefaultHttp2DataFrame(content().duplicate(), endStream, padding);
|
return replace(content().duplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DefaultHttp2DataFrame retainedDuplicate() {
|
||||||
|
return replace(content().retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DefaultHttp2DataFrame replace(ByteBuf content) {
|
||||||
|
return new DefaultHttp2DataFrame(content, endStream, padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -15,6 +15,14 @@
|
|||||||
|
|
||||||
package io.netty.handler.codec.http2;
|
package io.netty.handler.codec.http2;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelPromise;
|
||||||
|
import io.netty.handler.codec.http2.Http2CodecUtil.SimpleChannelPromiseAggregator;
|
||||||
|
import io.netty.handler.codec.http2.Http2FrameWriter.Configuration;
|
||||||
|
import io.netty.util.internal.UnstableApi;
|
||||||
|
|
||||||
import static io.netty.buffer.Unpooled.directBuffer;
|
import static io.netty.buffer.Unpooled.directBuffer;
|
||||||
import static io.netty.buffer.Unpooled.unreleasableBuffer;
|
import static io.netty.buffer.Unpooled.unreleasableBuffer;
|
||||||
import static io.netty.handler.codec.http2.Http2CodecUtil.CONTINUATION_FRAME_HEADER_LENGTH;
|
import static io.netty.handler.codec.http2.Http2CodecUtil.CONTINUATION_FRAME_HEADER_LENGTH;
|
||||||
@ -55,14 +63,6 @@ import static io.netty.util.internal.ObjectUtil.checkNotNull;
|
|||||||
import static java.lang.Math.max;
|
import static java.lang.Math.max;
|
||||||
import static java.lang.Math.min;
|
import static java.lang.Math.min;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.channel.ChannelFuture;
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import io.netty.channel.ChannelPromise;
|
|
||||||
import io.netty.handler.codec.http2.Http2CodecUtil.SimpleChannelPromiseAggregator;
|
|
||||||
import io.netty.handler.codec.http2.Http2FrameWriter.Configuration;
|
|
||||||
import io.netty.util.internal.UnstableApi;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Http2FrameWriter} that supports all frame types defined by the HTTP/2 specification.
|
* A {@link Http2FrameWriter} that supports all frame types defined by the HTTP/2 specification.
|
||||||
*/
|
*/
|
||||||
@ -304,8 +304,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
|
|||||||
// INT_FIELD_LENGTH is for the length of the promisedStreamId
|
// INT_FIELD_LENGTH is for the length of the promisedStreamId
|
||||||
int nonFragmentLength = INT_FIELD_LENGTH + padding + flags.getPaddingPresenceFieldLength();
|
int nonFragmentLength = INT_FIELD_LENGTH + padding + flags.getPaddingPresenceFieldLength();
|
||||||
int maxFragmentLength = maxFrameSize - nonFragmentLength;
|
int maxFragmentLength = maxFrameSize - nonFragmentLength;
|
||||||
ByteBuf fragment =
|
ByteBuf fragment = headerBlock.readRetainedSlice(min(headerBlock.readableBytes(), maxFragmentLength));
|
||||||
headerBlock.readSlice(min(headerBlock.readableBytes(), maxFragmentLength));
|
|
||||||
|
|
||||||
flags.endOfHeaders(!headerBlock.isReadable());
|
flags.endOfHeaders(!headerBlock.isReadable());
|
||||||
|
|
||||||
@ -319,7 +318,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
|
|||||||
ctx.write(buf, promiseAggregator.newPromise());
|
ctx.write(buf, promiseAggregator.newPromise());
|
||||||
|
|
||||||
// Write the first fragment.
|
// Write the first fragment.
|
||||||
ctx.write(fragment.retain(), promiseAggregator.newPromise());
|
ctx.write(fragment, promiseAggregator.newPromise());
|
||||||
|
|
||||||
if (padding > 0) { // Write out the padding, if any.
|
if (padding > 0) { // Write out the padding, if any.
|
||||||
ctx.write(ZERO_BUFFER.slice(0, padding), promiseAggregator.newPromise());
|
ctx.write(ZERO_BUFFER.slice(0, padding), promiseAggregator.newPromise());
|
||||||
@ -429,8 +428,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
|
|||||||
// Read the first fragment (possibly everything).
|
// Read the first fragment (possibly everything).
|
||||||
int nonFragmentBytes = padding + flags.getNumPriorityBytes() + flags.getPaddingPresenceFieldLength();
|
int nonFragmentBytes = padding + flags.getNumPriorityBytes() + flags.getPaddingPresenceFieldLength();
|
||||||
int maxFragmentLength = maxFrameSize - nonFragmentBytes;
|
int maxFragmentLength = maxFrameSize - nonFragmentBytes;
|
||||||
ByteBuf fragment =
|
ByteBuf fragment = headerBlock.readRetainedSlice(min(headerBlock.readableBytes(), maxFragmentLength));
|
||||||
headerBlock.readSlice(min(headerBlock.readableBytes(), maxFragmentLength));
|
|
||||||
|
|
||||||
// Set the end of headers flag for the first frame.
|
// Set the end of headers flag for the first frame.
|
||||||
flags.endOfHeaders(!headerBlock.isReadable());
|
flags.endOfHeaders(!headerBlock.isReadable());
|
||||||
@ -450,7 +448,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
|
|||||||
ctx.write(buf, promiseAggregator.newPromise());
|
ctx.write(buf, promiseAggregator.newPromise());
|
||||||
|
|
||||||
// Write the first fragment.
|
// Write the first fragment.
|
||||||
ctx.write(fragment.retain(), promiseAggregator.newPromise());
|
ctx.write(fragment, promiseAggregator.newPromise());
|
||||||
|
|
||||||
if (padding > 0) { // Write out the padding, if any.
|
if (padding > 0) { // Write out the padding, if any.
|
||||||
ctx.write(ZERO_BUFFER.slice(0, padding), promiseAggregator.newPromise());
|
ctx.write(ZERO_BUFFER.slice(0, padding), promiseAggregator.newPromise());
|
||||||
@ -493,7 +491,7 @@ public class DefaultHttp2FrameWriter implements Http2FrameWriter, Http2FrameSize
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
fragmentReadableBytes = min(headerBlock.readableBytes(), maxFragmentLength);
|
fragmentReadableBytes = min(headerBlock.readableBytes(), maxFragmentLength);
|
||||||
ByteBuf fragment = headerBlock.readSlice(fragmentReadableBytes).retain();
|
ByteBuf fragment = headerBlock.readRetainedSlice(fragmentReadableBytes);
|
||||||
|
|
||||||
payloadLength = fragmentReadableBytes + nonFragmentLength;
|
payloadLength = fragmentReadableBytes + nonFragmentLength;
|
||||||
if (headerBlock.isReadable()) {
|
if (headerBlock.isReadable()) {
|
||||||
|
@ -78,7 +78,7 @@ public final class DefaultHttp2GoAwayFrame extends DefaultByteBufHolder implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultHttp2GoAwayFrame setExtraStreamIds(int extraStreamIds) {
|
public Http2GoAwayFrame setExtraStreamIds(int extraStreamIds) {
|
||||||
if (extraStreamIds < 0) {
|
if (extraStreamIds < 0) {
|
||||||
throw new IllegalArgumentException("extraStreamIds must be non-negative");
|
throw new IllegalArgumentException("extraStreamIds must be non-negative");
|
||||||
}
|
}
|
||||||
@ -87,41 +87,45 @@ public final class DefaultHttp2GoAwayFrame extends DefaultByteBufHolder implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultHttp2GoAwayFrame copy() {
|
public Http2GoAwayFrame copy() {
|
||||||
return new DefaultHttp2GoAwayFrame(errorCode, content().copy()).setExtraStreamIds(extraStreamIds);
|
return (Http2GoAwayFrame) super.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultHttp2GoAwayFrame duplicate() {
|
public Http2GoAwayFrame duplicate() {
|
||||||
return new DefaultHttp2GoAwayFrame(errorCode, content().duplicate()).setExtraStreamIds(extraStreamIds);
|
return (Http2GoAwayFrame) super.duplicate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultHttp2GoAwayFrame retain() {
|
public Http2GoAwayFrame retainedDuplicate() {
|
||||||
|
return (Http2GoAwayFrame) super.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Http2GoAwayFrame replace(ByteBuf content) {
|
||||||
|
return new DefaultHttp2GoAwayFrame(errorCode, content).setExtraStreamIds(extraStreamIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Http2GoAwayFrame retain() {
|
||||||
super.retain();
|
super.retain();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultHttp2GoAwayFrame retain(int increment) {
|
public Http2GoAwayFrame retain(int increment) {
|
||||||
super.retain(increment);
|
super.retain(increment);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public Http2GoAwayFrame touch() {
|
||||||
return "DefaultHttp2GoAwayFrame(errorCode=" + errorCode + ", content=" + content()
|
|
||||||
+ ", extraStreamIds=" + extraStreamIds + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DefaultHttp2GoAwayFrame touch() {
|
|
||||||
super.touch();
|
super.touch();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultHttp2GoAwayFrame touch(Object hint) {
|
public Http2GoAwayFrame touch(Object hint) {
|
||||||
super.touch(hint);
|
super.touch(hint);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -144,4 +148,10 @@ public final class DefaultHttp2GoAwayFrame extends DefaultByteBufHolder implemen
|
|||||||
hash = hash * 31 + extraStreamIds;
|
hash = hash * 31 + extraStreamIds;
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DefaultHttp2GoAwayFrame(errorCode=" + errorCode + ", content=" + content()
|
||||||
|
+ ", extraStreamIds=" + extraStreamIds + ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ public final class Http2CodecUtil {
|
|||||||
*/
|
*/
|
||||||
public static ByteBuf connectionPrefaceBuf() {
|
public static ByteBuf connectionPrefaceBuf() {
|
||||||
// Return a duplicate so that modifications to the reader index will not affect the original buffer.
|
// Return a duplicate so that modifications to the reader index will not affect the original buffer.
|
||||||
return CONNECTION_PREFACE.duplicate().retain();
|
return CONNECTION_PREFACE.retainedDuplicate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,7 +127,7 @@ public final class Http2CodecUtil {
|
|||||||
*/
|
*/
|
||||||
public static ByteBuf emptyPingBuf() {
|
public static ByteBuf emptyPingBuf() {
|
||||||
// Return a duplicate so that modifications to the reader index will not affect the original buffer.
|
// Return a duplicate so that modifications to the reader index will not affect the original buffer.
|
||||||
return EMPTY_PING.duplicate().retain();
|
return EMPTY_PING.retainedDuplicate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,6 +49,12 @@ public interface Http2DataFrame extends Http2StreamFrame, ByteBufHolder {
|
|||||||
@Override
|
@Override
|
||||||
Http2DataFrame duplicate();
|
Http2DataFrame duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Http2DataFrame retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Http2DataFrame replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Http2DataFrame retain();
|
Http2DataFrame retain();
|
||||||
|
|
||||||
|
@ -58,6 +58,12 @@ public interface Http2GoAwayFrame extends Http2Frame, ByteBufHolder {
|
|||||||
@Override
|
@Override
|
||||||
Http2GoAwayFrame duplicate();
|
Http2GoAwayFrame duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Http2GoAwayFrame retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Http2GoAwayFrame replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Http2GoAwayFrame retain();
|
Http2GoAwayFrame retain();
|
||||||
|
|
||||||
|
@ -371,7 +371,7 @@ public final class Http2MultiplexCodec extends ChannelDuplexHandler {
|
|||||||
StreamInfo streamInfo = (StreamInfo) stream.getProperty(streamInfoKey);
|
StreamInfo streamInfo = (StreamInfo) stream.getProperty(streamInfoKey);
|
||||||
// TODO: Can we force a user interaction pattern that doesn't require us to duplicate()?
|
// TODO: Can we force a user interaction pattern that doesn't require us to duplicate()?
|
||||||
// https://github.com/netty/netty/issues/4943
|
// https://github.com/netty/netty/issues/4943
|
||||||
streamInfo.childChannel.pipeline().fireUserEventTriggered(goAway.duplicate().retain());
|
streamInfo.childChannel.pipeline().fireUserEventTriggered(goAway.retainedDuplicate());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -389,12 +389,12 @@ public final class Http2MultiplexCodec extends ChannelDuplexHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.fireUserEventTriggered(goAway.duplicate().retain());
|
ctx.fireUserEventTriggered(goAway.retainedDuplicate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class InternalHttp2ConnectionHandler extends Http2ConnectionHandler {
|
class InternalHttp2ConnectionHandler extends Http2ConnectionHandler {
|
||||||
public InternalHttp2ConnectionHandler(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
|
InternalHttp2ConnectionHandler(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
|
||||||
Http2Settings initialSettings) {
|
Http2Settings initialSettings) {
|
||||||
super(decoder, encoder, initialSettings);
|
super(decoder, encoder, initialSettings);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ package io.netty.handler.codec.http2;
|
|||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.http.FullHttpMessage;
|
import io.netty.handler.codec.http.FullHttpMessage;
|
||||||
import io.netty.handler.codec.http.FullHttpRequest;
|
import io.netty.handler.codec.http.FullHttpRequest;
|
||||||
@ -53,7 +54,7 @@ public class InboundHttp2ToHttpAdapter extends Http2EventAdapter {
|
|||||||
@Override
|
@Override
|
||||||
public FullHttpMessage copyIfNeeded(FullHttpMessage msg) {
|
public FullHttpMessage copyIfNeeded(FullHttpMessage msg) {
|
||||||
if (msg instanceof FullHttpRequest) {
|
if (msg instanceof FullHttpRequest) {
|
||||||
FullHttpRequest copy = ((FullHttpRequest) msg).copy(null);
|
FullHttpRequest copy = ((FullHttpRequest) msg).replace(Unpooled.buffer(0));
|
||||||
copy.headers().remove(HttpHeaderNames.EXPECT);
|
copy.headers().remove(HttpHeaderNames.EXPECT);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
@ -394,7 +394,7 @@ public class Http2ConnectionRoundtripTest {
|
|||||||
public void run() throws Http2Exception {
|
public void run() throws Http2Exception {
|
||||||
http2Client.encoder().writeHeaders(ctx(), 3, headers, 0, (short) 16, false, 0,
|
http2Client.encoder().writeHeaders(ctx(), 3, headers, 0, (short) 16, false, 0,
|
||||||
false, newPromise());
|
false, newPromise());
|
||||||
http2Client.encoder().writeData(ctx(), 3, data.duplicate().retain(), 0, false, newPromise());
|
http2Client.encoder().writeData(ctx(), 3, data.retainedDuplicate(), 0, false, newPromise());
|
||||||
|
|
||||||
// Write trailers.
|
// Write trailers.
|
||||||
http2Client.encoder().writeHeaders(ctx(), 3, headers, 0, (short) 16, false, 0,
|
http2Client.encoder().writeHeaders(ctx(), 3, headers, 0, (short) 16, false, 0,
|
||||||
@ -479,10 +479,10 @@ public class Http2ConnectionRoundtripTest {
|
|||||||
// Send a bunch of data on each stream.
|
// Send a bunch of data on each stream.
|
||||||
http2Client.encoder().writeHeaders(ctx(), streamId, headers, 0, (short) 16,
|
http2Client.encoder().writeHeaders(ctx(), streamId, headers, 0, (short) 16,
|
||||||
false, 0, false, newPromise());
|
false, 0, false, newPromise());
|
||||||
http2Client.encoder().writePing(ctx(), false, pingData.slice().retain(),
|
http2Client.encoder().writePing(ctx(), false, pingData.retainedSlice(),
|
||||||
newPromise());
|
newPromise());
|
||||||
http2Client.encoder().writeData(ctx(), streamId, data.slice().retain(), 0,
|
http2Client.encoder().writeData(ctx(), streamId, data.retainedSlice(), 0,
|
||||||
false, newPromise());
|
false, newPromise());
|
||||||
// Write trailers.
|
// Write trailers.
|
||||||
http2Client.encoder().writeHeaders(ctx(), streamId, headers, 0, (short) 16,
|
http2Client.encoder().writeHeaders(ctx(), streamId, headers, 0, (short) 16,
|
||||||
false, 0, true, newPromise());
|
false, 0, true, newPromise());
|
||||||
|
@ -267,7 +267,7 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
clientHandler.encoder().writeHeaders(ctxClient(), 3, http2Headers, 0, false, newPromiseClient());
|
clientHandler.encoder().writeHeaders(ctxClient(), 3, http2Headers, 0, false, newPromiseClient());
|
||||||
clientHandler.encoder().writeData(ctxClient(), 3, content.duplicate().retain(), 0, true,
|
clientHandler.encoder().writeData(ctxClient(), 3, content.retainedDuplicate(), 0, true,
|
||||||
newPromiseClient());
|
newPromiseClient());
|
||||||
clientChannel.flush();
|
clientChannel.flush();
|
||||||
}
|
}
|
||||||
@ -300,10 +300,11 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
clientHandler.encoder().writeHeaders(ctxClient(), 3, http2Headers, 0, false, newPromiseClient());
|
clientHandler.encoder().writeHeaders(ctxClient(), 3, http2Headers, 0, false, newPromiseClient());
|
||||||
clientHandler.encoder().writeData(ctxClient(), 3, content.slice(0, midPoint).retain(), 0, false,
|
clientHandler.encoder().writeData(
|
||||||
newPromiseClient());
|
ctxClient(), 3, content.retainedSlice(0, midPoint), 0, false, newPromiseClient());
|
||||||
clientHandler.encoder().writeData(ctxClient(), 3,
|
clientHandler.encoder().writeData(
|
||||||
content.slice(midPoint, text.length() - midPoint).retain(), 0, true, newPromiseClient());
|
ctxClient(), 3, content.retainedSlice(midPoint, text.length() - midPoint),
|
||||||
|
0, true, newPromiseClient());
|
||||||
clientChannel.flush();
|
clientChannel.flush();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -417,7 +418,7 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
clientHandler.encoder().writeHeaders(ctxClient(), 3, http2Headers, 0, false, newPromiseClient());
|
clientHandler.encoder().writeHeaders(ctxClient(), 3, http2Headers, 0, false, newPromiseClient());
|
||||||
clientHandler.encoder().writeData(ctxClient(), 3, content.duplicate().retain(), 0, false,
|
clientHandler.encoder().writeData(ctxClient(), 3, content.retainedDuplicate(), 0, false,
|
||||||
newPromiseClient());
|
newPromiseClient());
|
||||||
clientHandler.encoder().writeHeaders(ctxClient(), 3, http2Headers2, 0, true, newPromiseClient());
|
clientHandler.encoder().writeHeaders(ctxClient(), 3, http2Headers2, 0, true, newPromiseClient());
|
||||||
clientChannel.flush();
|
clientChannel.flush();
|
||||||
@ -464,9 +465,9 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
clientHandler.encoder().writeHeaders(ctxClient(), 5, http2Headers2, 0, false, newPromiseClient());
|
clientHandler.encoder().writeHeaders(ctxClient(), 5, http2Headers2, 0, false, newPromiseClient());
|
||||||
clientChannel.flush(); // Headers are queued in the flow controller and so flush them.
|
clientChannel.flush(); // Headers are queued in the flow controller and so flush them.
|
||||||
clientHandler.encoder().writePriority(ctxClient(), 5, 3, (short) 123, true, newPromiseClient());
|
clientHandler.encoder().writePriority(ctxClient(), 5, 3, (short) 123, true, newPromiseClient());
|
||||||
clientHandler.encoder().writeData(ctxClient(), 3, content.duplicate().retain(), 0, true,
|
clientHandler.encoder().writeData(ctxClient(), 3, content.retainedDuplicate(), 0, true,
|
||||||
newPromiseClient());
|
newPromiseClient());
|
||||||
clientHandler.encoder().writeData(ctxClient(), 5, content2.duplicate().retain(), 0, true,
|
clientHandler.encoder().writeData(ctxClient(), 5, content2.retainedDuplicate(), 0, true,
|
||||||
newPromiseClient());
|
newPromiseClient());
|
||||||
clientChannel.flush();
|
clientChannel.flush();
|
||||||
}
|
}
|
||||||
@ -518,9 +519,9 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
public void run() {
|
public void run() {
|
||||||
clientHandler.encoder().writeHeaders(ctxClient(), 3, http2Headers, 0, false, newPromiseClient());
|
clientHandler.encoder().writeHeaders(ctxClient(), 3, http2Headers, 0, false, newPromiseClient());
|
||||||
clientHandler.encoder().writeHeaders(ctxClient(), 5, http2Headers2, 0, false, newPromiseClient());
|
clientHandler.encoder().writeHeaders(ctxClient(), 5, http2Headers2, 0, false, newPromiseClient());
|
||||||
clientHandler.encoder().writeData(ctxClient(), 3, content.duplicate().retain(), 0, true,
|
clientHandler.encoder().writeData(ctxClient(), 3, content.retainedDuplicate(), 0, true,
|
||||||
newPromiseClient());
|
newPromiseClient());
|
||||||
clientHandler.encoder().writeData(ctxClient(), 5, content2.duplicate().retain(), 0, true,
|
clientHandler.encoder().writeData(ctxClient(), 5, content2.retainedDuplicate(), 0, true,
|
||||||
newPromiseClient());
|
newPromiseClient());
|
||||||
clientChannel.flush(); // headers and data are queued in the flow controller, so flush them.
|
clientChannel.flush(); // headers and data are queued in the flow controller, so flush them.
|
||||||
clientHandler.encoder().writePriority(ctxClient(), 5, 3, (short) 222, false, newPromiseClient());
|
clientHandler.encoder().writePriority(ctxClient(), 5, 3, (short) 222, false, newPromiseClient());
|
||||||
@ -592,9 +593,9 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
public void run() {
|
public void run() {
|
||||||
serverHandler.encoder().writeHeaders(ctxServer(), 3, http2Headers, 0, false, newPromiseServer());
|
serverHandler.encoder().writeHeaders(ctxServer(), 3, http2Headers, 0, false, newPromiseServer());
|
||||||
serverHandler.encoder().writePushPromise(ctxServer(), 3, 2, http2Headers2, 0, newPromiseServer());
|
serverHandler.encoder().writePushPromise(ctxServer(), 3, 2, http2Headers2, 0, newPromiseServer());
|
||||||
serverHandler.encoder().writeData(ctxServer(), 3, content.duplicate().retain(), 0, true,
|
serverHandler.encoder().writeData(ctxServer(), 3, content.retainedDuplicate(), 0, true,
|
||||||
newPromiseServer());
|
newPromiseServer());
|
||||||
serverHandler.encoder().writeData(ctxServer(), 5, content2.duplicate().retain(), 0, true,
|
serverHandler.encoder().writeData(ctxServer(), 5, content2.retainedDuplicate(), 0, true,
|
||||||
newPromiseServer());
|
newPromiseServer());
|
||||||
serverConnectedChannel.flush();
|
serverConnectedChannel.flush();
|
||||||
}
|
}
|
||||||
@ -627,7 +628,7 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
final FullHttpMessage response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE);
|
final FullHttpMessage response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE);
|
||||||
final String text = "a big payload";
|
final String text = "a big payload";
|
||||||
final ByteBuf payload = Unpooled.copiedBuffer(text.getBytes());
|
final ByteBuf payload = Unpooled.copiedBuffer(text.getBytes());
|
||||||
final FullHttpMessage request2 = request.copy(payload);
|
final FullHttpMessage request2 = request.replace(payload);
|
||||||
final FullHttpMessage response2 = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
|
final FullHttpMessage response2 = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -660,7 +661,7 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
runInChannel(clientChannel, new Http2Runnable() {
|
runInChannel(clientChannel, new Http2Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
clientHandler.encoder().writeData(ctxClient(), 3, payload.duplicate().retain(), 0, true,
|
clientHandler.encoder().writeData(ctxClient(), 3, payload.retainedDuplicate(), 0, true,
|
||||||
newPromiseClient());
|
newPromiseClient());
|
||||||
clientChannel.flush();
|
clientChannel.flush();
|
||||||
}
|
}
|
||||||
|
@ -60,11 +60,21 @@ public class DefaultLastMemcacheContent extends DefaultMemcacheContent implement
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LastMemcacheContent copy() {
|
public LastMemcacheContent copy() {
|
||||||
return new DefaultLastMemcacheContent(content().copy());
|
return replace(content().copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LastMemcacheContent duplicate() {
|
public LastMemcacheContent duplicate() {
|
||||||
return new DefaultLastMemcacheContent(content().duplicate());
|
return replace(content().duplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastMemcacheContent retainedDuplicate() {
|
||||||
|
return replace(content().retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastMemcacheContent replace(ByteBuf content) {
|
||||||
|
return new DefaultLastMemcacheContent(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,12 +44,22 @@ public class DefaultMemcacheContent extends AbstractMemcacheObject implements Me
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MemcacheContent copy() {
|
public MemcacheContent copy() {
|
||||||
return new DefaultMemcacheContent(content.copy());
|
return replace(content.copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MemcacheContent duplicate() {
|
public MemcacheContent duplicate() {
|
||||||
return new DefaultMemcacheContent(content.duplicate());
|
return replace(content.duplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MemcacheContent retainedDuplicate() {
|
||||||
|
return replace(content.retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MemcacheContent replace(ByteBuf content) {
|
||||||
|
return new DefaultMemcacheContent(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.memcache;
|
package io.netty.handler.codec.memcache;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.util.internal.UnstableApi;
|
import io.netty.util.internal.UnstableApi;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,6 +28,15 @@ public interface FullMemcacheMessage extends MemcacheMessage, LastMemcacheConten
|
|||||||
@Override
|
@Override
|
||||||
FullMemcacheMessage copy();
|
FullMemcacheMessage copy();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullMemcacheMessage duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullMemcacheMessage retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullMemcacheMessage replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullMemcacheMessage retain(int increment);
|
FullMemcacheMessage retain(int increment);
|
||||||
|
|
||||||
@ -38,7 +48,4 @@ public interface FullMemcacheMessage extends MemcacheMessage, LastMemcacheConten
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullMemcacheMessage touch(Object hint);
|
FullMemcacheMessage touch(Object hint);
|
||||||
|
|
||||||
@Override
|
|
||||||
FullMemcacheMessage duplicate();
|
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,21 @@ public interface LastMemcacheContent extends MemcacheContent {
|
|||||||
return EMPTY_LAST_CONTENT;
|
return EMPTY_LAST_CONTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastMemcacheContent duplicate() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastMemcacheContent retainedDuplicate() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastMemcacheContent replace(ByteBuf content) {
|
||||||
|
return new DefaultLastMemcacheContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LastMemcacheContent retain(int increment) {
|
public LastMemcacheContent retain(int increment) {
|
||||||
return this;
|
return this;
|
||||||
@ -57,11 +72,6 @@ public interface LastMemcacheContent extends MemcacheContent {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public LastMemcacheContent duplicate() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf content() {
|
public ByteBuf content() {
|
||||||
return Unpooled.EMPTY_BUFFER;
|
return Unpooled.EMPTY_BUFFER;
|
||||||
@ -96,6 +106,15 @@ public interface LastMemcacheContent extends MemcacheContent {
|
|||||||
@Override
|
@Override
|
||||||
LastMemcacheContent copy();
|
LastMemcacheContent copy();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastMemcacheContent duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastMemcacheContent retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastMemcacheContent replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
LastMemcacheContent retain(int increment);
|
LastMemcacheContent retain(int increment);
|
||||||
|
|
||||||
@ -107,7 +126,4 @@ public interface LastMemcacheContent extends MemcacheContent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
LastMemcacheContent touch(Object hint);
|
LastMemcacheContent touch(Object hint);
|
||||||
|
|
||||||
@Override
|
|
||||||
LastMemcacheContent duplicate();
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.memcache;
|
package io.netty.handler.codec.memcache;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufHolder;
|
import io.netty.buffer.ByteBufHolder;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.util.internal.UnstableApi;
|
import io.netty.util.internal.UnstableApi;
|
||||||
@ -36,6 +37,12 @@ public interface MemcacheContent extends MemcacheObject, ByteBufHolder {
|
|||||||
@Override
|
@Override
|
||||||
MemcacheContent duplicate();
|
MemcacheContent duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
MemcacheContent retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
MemcacheContent replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
MemcacheContent retain();
|
MemcacheContent retain();
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentMessage.setExtras(in.readSlice(extrasLength).retain());
|
currentMessage.setExtras(in.readRetainedSlice(extrasLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
state = State.READ_KEY;
|
state = State.READ_KEY;
|
||||||
@ -105,7 +105,7 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentMessage.setKey(in.readSlice(keyLength).retain());
|
currentMessage.setKey(in.readRetainedSlice(keyLength));
|
||||||
}
|
}
|
||||||
out.add(currentMessage.retain());
|
out.add(currentMessage.retain());
|
||||||
state = State.READ_CONTENT;
|
state = State.READ_CONTENT;
|
||||||
@ -133,7 +133,7 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
|
|||||||
toRead = remainingLength;
|
toRead = remainingLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuf chunkBuffer = in.readSlice(toRead).retain();
|
ByteBuf chunkBuffer = in.readRetainedSlice(toRead);
|
||||||
|
|
||||||
MemcacheContent chunk;
|
MemcacheContent chunk;
|
||||||
if ((alreadyReadChunkSize += toRead) >= valueLength) {
|
if ((alreadyReadChunkSize += toRead) >= valueLength) {
|
||||||
|
@ -117,4 +117,22 @@ public class DefaultFullBinaryMemcacheRequest extends DefaultBinaryMemcacheReque
|
|||||||
}
|
}
|
||||||
return new DefaultFullBinaryMemcacheRequest(key, extras, content().duplicate());
|
return new DefaultFullBinaryMemcacheRequest(key, extras, content().duplicate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBinaryMemcacheRequest retainedDuplicate() {
|
||||||
|
return replace(content().retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBinaryMemcacheRequest replace(ByteBuf content) {
|
||||||
|
ByteBuf key = key();
|
||||||
|
if (key != null) {
|
||||||
|
key = key.retainedDuplicate();
|
||||||
|
}
|
||||||
|
ByteBuf extras = extras();
|
||||||
|
if (extras != null) {
|
||||||
|
extras = extras.retainedDuplicate();
|
||||||
|
}
|
||||||
|
return new DefaultFullBinaryMemcacheRequest(key, extras, content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,4 +117,22 @@ public class DefaultFullBinaryMemcacheResponse extends DefaultBinaryMemcacheResp
|
|||||||
}
|
}
|
||||||
return new DefaultFullBinaryMemcacheResponse(key, extras, content().duplicate());
|
return new DefaultFullBinaryMemcacheResponse(key, extras, content().duplicate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBinaryMemcacheResponse retainedDuplicate() {
|
||||||
|
return replace(content().retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBinaryMemcacheResponse replace(ByteBuf content) {
|
||||||
|
ByteBuf key = key();
|
||||||
|
if (key != null) {
|
||||||
|
key = key.retainedDuplicate();
|
||||||
|
}
|
||||||
|
ByteBuf extras = extras();
|
||||||
|
if (extras != null) {
|
||||||
|
extras = extras.retainedDuplicate();
|
||||||
|
}
|
||||||
|
return new DefaultFullBinaryMemcacheResponse(key, extras, content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.memcache.binary;
|
package io.netty.handler.codec.memcache.binary;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.handler.codec.memcache.FullMemcacheMessage;
|
import io.netty.handler.codec.memcache.FullMemcacheMessage;
|
||||||
import io.netty.util.internal.UnstableApi;
|
import io.netty.util.internal.UnstableApi;
|
||||||
|
|
||||||
@ -27,6 +28,15 @@ public interface FullBinaryMemcacheRequest extends BinaryMemcacheRequest, FullMe
|
|||||||
@Override
|
@Override
|
||||||
FullBinaryMemcacheRequest copy();
|
FullBinaryMemcacheRequest copy();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullBinaryMemcacheRequest duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullBinaryMemcacheRequest retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullBinaryMemcacheRequest replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullBinaryMemcacheRequest retain(int increment);
|
FullBinaryMemcacheRequest retain(int increment);
|
||||||
|
|
||||||
@ -38,7 +48,4 @@ public interface FullBinaryMemcacheRequest extends BinaryMemcacheRequest, FullMe
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullBinaryMemcacheRequest touch(Object hint);
|
FullBinaryMemcacheRequest touch(Object hint);
|
||||||
|
|
||||||
@Override
|
|
||||||
FullBinaryMemcacheRequest duplicate();
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.memcache.binary;
|
package io.netty.handler.codec.memcache.binary;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.handler.codec.memcache.FullMemcacheMessage;
|
import io.netty.handler.codec.memcache.FullMemcacheMessage;
|
||||||
import io.netty.util.internal.UnstableApi;
|
import io.netty.util.internal.UnstableApi;
|
||||||
|
|
||||||
@ -27,6 +28,15 @@ public interface FullBinaryMemcacheResponse extends BinaryMemcacheResponse, Full
|
|||||||
@Override
|
@Override
|
||||||
FullBinaryMemcacheResponse copy();
|
FullBinaryMemcacheResponse copy();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullBinaryMemcacheResponse duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullBinaryMemcacheResponse retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
FullBinaryMemcacheResponse replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullBinaryMemcacheResponse retain(int increment);
|
FullBinaryMemcacheResponse retain(int increment);
|
||||||
|
|
||||||
@ -38,7 +48,4 @@ public interface FullBinaryMemcacheResponse extends BinaryMemcacheResponse, Full
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
FullBinaryMemcacheResponse touch(Object hint);
|
FullBinaryMemcacheResponse touch(Object hint);
|
||||||
|
|
||||||
@Override
|
|
||||||
FullBinaryMemcacheResponse duplicate();
|
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,11 @@ import io.netty.util.CharsetUtil;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static io.netty.handler.codec.mqtt.MqttCodecUtil.*;
|
import static io.netty.handler.codec.mqtt.MqttCodecUtil.isValidClientId;
|
||||||
|
import static io.netty.handler.codec.mqtt.MqttCodecUtil.isValidMessageId;
|
||||||
|
import static io.netty.handler.codec.mqtt.MqttCodecUtil.isValidPublishTopicName;
|
||||||
|
import static io.netty.handler.codec.mqtt.MqttCodecUtil.resetUnusedFields;
|
||||||
|
import static io.netty.handler.codec.mqtt.MqttCodecUtil.validateFixedHeader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes Mqtt messages from bytes, following
|
* Decodes Mqtt messages from bytes, following
|
||||||
@ -409,7 +413,7 @@ public final class MqttDecoder extends ReplayingDecoder<DecoderState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Result<ByteBuf> decodePublishPayload(ByteBuf buffer, int bytesRemainingInVariablePart) {
|
private static Result<ByteBuf> decodePublishPayload(ByteBuf buffer, int bytesRemainingInVariablePart) {
|
||||||
ByteBuf b = buffer.readSlice(bytesRemainingInVariablePart).retain();
|
ByteBuf b = buffer.readRetainedSlice(bytesRemainingInVariablePart);
|
||||||
return new Result<ByteBuf>(b, bytesRemainingInVariablePart);
|
return new Result<ByteBuf>(b, bytesRemainingInVariablePart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,12 +53,22 @@ public class MqttPublishMessage extends MqttMessage implements ByteBufHolder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MqttPublishMessage copy() {
|
public MqttPublishMessage copy() {
|
||||||
return new MqttPublishMessage(fixedHeader(), variableHeader(), content().copy());
|
return replace(content().copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MqttPublishMessage duplicate() {
|
public MqttPublishMessage duplicate() {
|
||||||
return new MqttPublishMessage(fixedHeader(), variableHeader(), content().duplicate());
|
return replace(content().duplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MqttPublishMessage retainedDuplicate() {
|
||||||
|
return replace(content().retainedDuplicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MqttPublishMessage replace(ByteBuf content) {
|
||||||
|
return new MqttPublishMessage(fixedHeader(), variableHeader(), content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
package io.netty.handler.codec.redis;
|
package io.netty.handler.codec.redis;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufHolder;
|
import io.netty.buffer.ByteBufHolder;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.util.internal.UnstableApi;
|
import io.netty.util.internal.UnstableApi;
|
||||||
@ -28,4 +29,28 @@ import io.netty.util.internal.UnstableApi;
|
|||||||
*/
|
*/
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public interface BulkStringRedisContent extends RedisMessage, ByteBufHolder {
|
public interface BulkStringRedisContent extends RedisMessage, ByteBufHolder {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
BulkStringRedisContent copy();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
BulkStringRedisContent duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
BulkStringRedisContent retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
BulkStringRedisContent replace(ByteBuf content);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
BulkStringRedisContent retain();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
BulkStringRedisContent retain(int increment);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
BulkStringRedisContent touch();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
BulkStringRedisContent touch(Object hint);
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,50 @@ public class DefaultBulkStringRedisContent extends DefaultByteBufHolder implemen
|
|||||||
super(content);
|
super(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BulkStringRedisContent copy() {
|
||||||
|
return (BulkStringRedisContent) super.copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BulkStringRedisContent duplicate() {
|
||||||
|
return (BulkStringRedisContent) super.duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BulkStringRedisContent retainedDuplicate() {
|
||||||
|
return (BulkStringRedisContent) super.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BulkStringRedisContent replace(ByteBuf content) {
|
||||||
|
return new DefaultBulkStringRedisContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BulkStringRedisContent retain() {
|
||||||
|
super.retain();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BulkStringRedisContent retain(int increment) {
|
||||||
|
super.retain(increment);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BulkStringRedisContent touch() {
|
||||||
|
super.touch();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BulkStringRedisContent touch(Object hint) {
|
||||||
|
super.touch(hint);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new StringBuilder(StringUtil.simpleClassName(this))
|
return new StringBuilder(StringUtil.simpleClassName(this))
|
||||||
|
@ -32,4 +32,48 @@ public final class DefaultLastBulkStringRedisContent extends DefaultBulkStringRe
|
|||||||
public DefaultLastBulkStringRedisContent(ByteBuf content) {
|
public DefaultLastBulkStringRedisContent(ByteBuf content) {
|
||||||
super(content);
|
super(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastBulkStringRedisContent copy() {
|
||||||
|
return (LastBulkStringRedisContent) super.copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastBulkStringRedisContent duplicate() {
|
||||||
|
return (LastBulkStringRedisContent) super.duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastBulkStringRedisContent retainedDuplicate() {
|
||||||
|
return (LastBulkStringRedisContent) super.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastBulkStringRedisContent replace(ByteBuf content) {
|
||||||
|
return new DefaultLastBulkStringRedisContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastBulkStringRedisContent retain() {
|
||||||
|
super.retain();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastBulkStringRedisContent retain(int increment) {
|
||||||
|
super.retain(increment);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastBulkStringRedisContent touch() {
|
||||||
|
super.touch();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastBulkStringRedisContent touch(Object hint) {
|
||||||
|
super.touch(hint);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,11 @@ public class FullBulkStringRedisMessage extends DefaultByteBufHolder implements
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBulkStringRedisMessage retainedDuplicate() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int refCnt() {
|
public int refCnt() {
|
||||||
return 1;
|
return 1;
|
||||||
@ -131,7 +136,7 @@ public class FullBulkStringRedisMessage extends DefaultByteBufHolder implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FullBulkStringRedisMessage copy() {
|
public FullBulkStringRedisMessage copy() {
|
||||||
return EMPTY_INSTANCE;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -139,6 +144,11 @@ public class FullBulkStringRedisMessage extends DefaultByteBufHolder implements
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBulkStringRedisMessage retainedDuplicate() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int refCnt() {
|
public int refCnt() {
|
||||||
return 1;
|
return 1;
|
||||||
@ -174,4 +184,48 @@ public class FullBulkStringRedisMessage extends DefaultByteBufHolder implements
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBulkStringRedisMessage copy() {
|
||||||
|
return (FullBulkStringRedisMessage) super.copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBulkStringRedisMessage duplicate() {
|
||||||
|
return (FullBulkStringRedisMessage) super.duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBulkStringRedisMessage retainedDuplicate() {
|
||||||
|
return (FullBulkStringRedisMessage) super.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBulkStringRedisMessage replace(ByteBuf content) {
|
||||||
|
return new FullBulkStringRedisMessage(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBulkStringRedisMessage retain() {
|
||||||
|
super.retain();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBulkStringRedisMessage retain(int increment) {
|
||||||
|
super.retain(increment);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBulkStringRedisMessage touch() {
|
||||||
|
super.touch();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FullBulkStringRedisMessage touch(Object hint) {
|
||||||
|
super.touch(hint);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
package io.netty.handler.codec.redis;
|
package io.netty.handler.codec.redis;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufHolder;
|
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.util.internal.UnstableApi;
|
import io.netty.util.internal.UnstableApi;
|
||||||
|
|
||||||
@ -37,17 +36,32 @@ public interface LastBulkStringRedisContent extends BulkStringRedisContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBufHolder copy() {
|
public LastBulkStringRedisContent copy() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBufHolder retain(int increment) {
|
public LastBulkStringRedisContent duplicate() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBufHolder retain() {
|
public LastBulkStringRedisContent retainedDuplicate() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastBulkStringRedisContent replace(ByteBuf content) {
|
||||||
|
return new DefaultLastBulkStringRedisContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastBulkStringRedisContent retain(int increment) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastBulkStringRedisContent retain() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,12 +71,12 @@ public interface LastBulkStringRedisContent extends BulkStringRedisContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBufHolder touch() {
|
public LastBulkStringRedisContent touch() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBufHolder touch(Object hint) {
|
public LastBulkStringRedisContent touch(Object hint) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,10 +89,29 @@ public interface LastBulkStringRedisContent extends BulkStringRedisContent {
|
|||||||
public boolean release(int decrement) {
|
public boolean release(int decrement) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ByteBufHolder duplicate() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastBulkStringRedisContent copy();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastBulkStringRedisContent duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastBulkStringRedisContent retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastBulkStringRedisContent replace(ByteBuf content);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastBulkStringRedisContent retain();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastBulkStringRedisContent retain(int increment);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastBulkStringRedisContent touch();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastBulkStringRedisContent touch(Object hint);
|
||||||
}
|
}
|
||||||
|
@ -33,34 +33,44 @@ public final class DefaultLastSmtpContent extends DefaultSmtpContent implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LastSmtpContent copy() {
|
public LastSmtpContent copy() {
|
||||||
return new DefaultLastSmtpContent(content().copy());
|
return (LastSmtpContent) super.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LastSmtpContent duplicate() {
|
public LastSmtpContent duplicate() {
|
||||||
return new DefaultLastSmtpContent(content().duplicate());
|
return (LastSmtpContent) super.duplicate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LastSmtpContent retain() {
|
public LastSmtpContent retainedDuplicate() {
|
||||||
|
return (LastSmtpContent) super.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastSmtpContent replace(ByteBuf content) {
|
||||||
|
return new DefaultLastSmtpContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DefaultLastSmtpContent retain() {
|
||||||
super.retain();
|
super.retain();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LastSmtpContent retain(int increment) {
|
public DefaultLastSmtpContent retain(int increment) {
|
||||||
super.retain(increment);
|
super.retain(increment);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LastSmtpContent touch() {
|
public DefaultLastSmtpContent touch() {
|
||||||
super.touch();
|
super.touch();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LastSmtpContent touch(Object hint) {
|
public DefaultLastSmtpContent touch(Object hint) {
|
||||||
super.touch(hint);
|
super.touch(hint);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -34,12 +34,22 @@ public class DefaultSmtpContent extends DefaultByteBufHolder implements SmtpCont
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SmtpContent copy() {
|
public SmtpContent copy() {
|
||||||
return new DefaultSmtpContent(content().copy());
|
return (SmtpContent) super.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SmtpContent duplicate() {
|
public SmtpContent duplicate() {
|
||||||
return new DefaultSmtpContent(content().duplicate());
|
return (SmtpContent) super.duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SmtpContent retainedDuplicate() {
|
||||||
|
return (SmtpContent) super.retainedDuplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SmtpContent replace(ByteBuf content) {
|
||||||
|
return new DefaultSmtpContent(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -42,6 +42,16 @@ public interface LastSmtpContent extends SmtpContent {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastSmtpContent retainedDuplicate() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LastSmtpContent replace(ByteBuf content) {
|
||||||
|
return new DefaultLastSmtpContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LastSmtpContent retain() {
|
public LastSmtpContent retain() {
|
||||||
return this;
|
return this;
|
||||||
@ -89,6 +99,12 @@ public interface LastSmtpContent extends SmtpContent {
|
|||||||
@Override
|
@Override
|
||||||
LastSmtpContent duplicate();
|
LastSmtpContent duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastSmtpContent retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
LastSmtpContent replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
LastSmtpContent retain();
|
LastSmtpContent retain();
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.smtp;
|
package io.netty.handler.codec.smtp;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufHolder;
|
import io.netty.buffer.ByteBufHolder;
|
||||||
import io.netty.util.internal.UnstableApi;
|
import io.netty.util.internal.UnstableApi;
|
||||||
|
|
||||||
@ -32,6 +33,12 @@ public interface SmtpContent extends ByteBufHolder {
|
|||||||
@Override
|
@Override
|
||||||
SmtpContent duplicate();
|
SmtpContent duplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
SmtpContent retainedDuplicate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
SmtpContent replace(ByteBuf content);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
SmtpContent retain();
|
SmtpContent retain();
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ public final class SmtpRequestEncoder extends MessageToMessageEncoder<Object> {
|
|||||||
final ByteBuf content = ((SmtpContent) msg).content();
|
final ByteBuf content = ((SmtpContent) msg).content();
|
||||||
out.add(content.retain());
|
out.add(content.retain());
|
||||||
if (msg instanceof LastSmtpContent) {
|
if (msg instanceof LastSmtpContent) {
|
||||||
out.add(DOT_CRLF_BUFFER.duplicate().retain());
|
out.add(DOT_CRLF_BUFFER.retainedDuplicate());
|
||||||
contentExpected = false;
|
contentExpected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ public class Socks4ClientDecoder extends ReplayingDecoder<State> {
|
|||||||
case SUCCESS: {
|
case SUCCESS: {
|
||||||
int readableBytes = actualReadableBytes();
|
int readableBytes = actualReadableBytes();
|
||||||
if (readableBytes > 0) {
|
if (readableBytes > 0) {
|
||||||
out.add(in.readSlice(readableBytes).retain());
|
out.add(in.readRetainedSlice(readableBytes));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ public class Socks4ServerDecoder extends ReplayingDecoder<State> {
|
|||||||
case SUCCESS: {
|
case SUCCESS: {
|
||||||
int readableBytes = actualReadableBytes();
|
int readableBytes = actualReadableBytes();
|
||||||
if (readableBytes > 0) {
|
if (readableBytes > 0) {
|
||||||
out.add(in.readSlice(readableBytes).retain());
|
out.add(in.readRetainedSlice(readableBytes));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ public class Socks5CommandRequestDecoder extends ReplayingDecoder<State> {
|
|||||||
case SUCCESS: {
|
case SUCCESS: {
|
||||||
int readableBytes = actualReadableBytes();
|
int readableBytes = actualReadableBytes();
|
||||||
if (readableBytes > 0) {
|
if (readableBytes > 0) {
|
||||||
out.add(in.readSlice(readableBytes).retain());
|
out.add(in.readRetainedSlice(readableBytes));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ public class Socks5CommandResponseDecoder extends ReplayingDecoder<State> {
|
|||||||
case SUCCESS: {
|
case SUCCESS: {
|
||||||
int readableBytes = actualReadableBytes();
|
int readableBytes = actualReadableBytes();
|
||||||
if (readableBytes > 0) {
|
if (readableBytes > 0) {
|
||||||
out.add(in.readSlice(readableBytes).retain());
|
out.add(in.readRetainedSlice(readableBytes));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ public class Socks5InitialRequestDecoder extends ReplayingDecoder<State> {
|
|||||||
case SUCCESS: {
|
case SUCCESS: {
|
||||||
int readableBytes = actualReadableBytes();
|
int readableBytes = actualReadableBytes();
|
||||||
if (readableBytes > 0) {
|
if (readableBytes > 0) {
|
||||||
out.add(in.readSlice(readableBytes).retain());
|
out.add(in.readRetainedSlice(readableBytes));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ public class Socks5InitialResponseDecoder extends ReplayingDecoder<State> {
|
|||||||
case SUCCESS: {
|
case SUCCESS: {
|
||||||
int readableBytes = actualReadableBytes();
|
int readableBytes = actualReadableBytes();
|
||||||
if (readableBytes > 0) {
|
if (readableBytes > 0) {
|
||||||
out.add(in.readSlice(readableBytes).retain());
|
out.add(in.readRetainedSlice(readableBytes));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ public class Socks5PasswordAuthRequestDecoder extends ReplayingDecoder<State> {
|
|||||||
case SUCCESS: {
|
case SUCCESS: {
|
||||||
int readableBytes = actualReadableBytes();
|
int readableBytes = actualReadableBytes();
|
||||||
if (readableBytes > 0) {
|
if (readableBytes > 0) {
|
||||||
out.add(in.readSlice(readableBytes).retain());
|
out.add(in.readRetainedSlice(readableBytes));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user