Make MessageBuf bounded
- Move common methods from ByteBuf to Buf - Rename ensureWritableBytes() to ensureWritable() - Rename readable() to isReadable() - Rename writable() to isWritable() - Add isReadable(int) and isWritable(int) - Add AbstractMessageBuf - Rewrite DefaultMessageBuf and QueueBackedMessageBuf - based on Josh Bloch's public domain ArrayDeque impl
This commit is contained in:
parent
ec013bf2d3
commit
42c65cca3a
|
@ -12,7 +12,7 @@ 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
|
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:
|
with the License. You may obtain a copy of the License at:
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
@ -74,6 +74,12 @@ facade for Java, which can be obtained at:
|
||||||
* HOMEPAGE:
|
* HOMEPAGE:
|
||||||
* http://www.slf4j.org/
|
* http://www.slf4j.org/
|
||||||
|
|
||||||
|
This product contains a modified portion of 'ArrayDeque', written by Josh
|
||||||
|
Bloch of Google, Inc:
|
||||||
|
|
||||||
|
* LICENSE:
|
||||||
|
* license/LICENSE.deque.txt (Public Domain)
|
||||||
|
|
||||||
This product optionally depends on 'Metrics', Yammer's JVM- and application-
|
This product optionally depends on 'Metrics', Yammer's JVM- and application-
|
||||||
level metrics library, which can be obtained at:
|
level metrics library, which can be obtained at:
|
||||||
|
|
||||||
|
|
|
@ -110,13 +110,35 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean readable() {
|
public boolean isReadable() {
|
||||||
return writerIndex > readerIndex;
|
return writerIndex > readerIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean writable() {
|
@Deprecated
|
||||||
return writableBytes() > 0;
|
public final boolean readable() {
|
||||||
|
return isReadable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReadable(int numBytes) {
|
||||||
|
return writerIndex - readerIndex >= numBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWritable() {
|
||||||
|
return capacity() > writerIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public final boolean writable() {
|
||||||
|
return isWritable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWritable(int numBytes) {
|
||||||
|
return capacity() - writerIndex >= numBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -216,7 +238,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf ensureWritableBytes(int minWritableBytes) {
|
public ByteBuf ensureWritable(int minWritableBytes) {
|
||||||
if (minWritableBytes < 0) {
|
if (minWritableBytes < 0) {
|
||||||
throw new IllegalArgumentException(String.format(
|
throw new IllegalArgumentException(String.format(
|
||||||
"minWritableBytes: %d (expected: >= 0)", minWritableBytes));
|
"minWritableBytes: %d (expected: >= 0)", minWritableBytes));
|
||||||
|
@ -241,7 +263,13 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int ensureWritableBytes(int minWritableBytes, boolean force) {
|
@Deprecated
|
||||||
|
public final ByteBuf ensureWritableBytes(int minWritableBytes) {
|
||||||
|
return ensureWritable(minWritableBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int ensureWritable(int minWritableBytes, boolean force) {
|
||||||
if (minWritableBytes < 0) {
|
if (minWritableBytes < 0) {
|
||||||
throw new IllegalArgumentException(String.format(
|
throw new IllegalArgumentException(String.format(
|
||||||
"minWritableBytes: %d (expected: >= 0)", minWritableBytes));
|
"minWritableBytes: %d (expected: >= 0)", minWritableBytes));
|
||||||
|
@ -660,14 +688,14 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf writeByte(int value) {
|
public ByteBuf writeByte(int value) {
|
||||||
ensureWritableBytes(1);
|
ensureWritable(1);
|
||||||
setByte(writerIndex ++, value);
|
setByte(writerIndex ++, value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf writeShort(int value) {
|
public ByteBuf writeShort(int value) {
|
||||||
ensureWritableBytes(2);
|
ensureWritable(2);
|
||||||
setShort(writerIndex, value);
|
setShort(writerIndex, value);
|
||||||
writerIndex += 2;
|
writerIndex += 2;
|
||||||
return this;
|
return this;
|
||||||
|
@ -675,7 +703,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf writeMedium(int value) {
|
public ByteBuf writeMedium(int value) {
|
||||||
ensureWritableBytes(3);
|
ensureWritable(3);
|
||||||
setMedium(writerIndex, value);
|
setMedium(writerIndex, value);
|
||||||
writerIndex += 3;
|
writerIndex += 3;
|
||||||
return this;
|
return this;
|
||||||
|
@ -683,7 +711,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf writeInt(int value) {
|
public ByteBuf writeInt(int value) {
|
||||||
ensureWritableBytes(4);
|
ensureWritable(4);
|
||||||
setInt(writerIndex, value);
|
setInt(writerIndex, value);
|
||||||
writerIndex += 4;
|
writerIndex += 4;
|
||||||
return this;
|
return this;
|
||||||
|
@ -691,7 +719,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf writeLong(long value) {
|
public ByteBuf writeLong(long value) {
|
||||||
ensureWritableBytes(8);
|
ensureWritable(8);
|
||||||
setLong(writerIndex, value);
|
setLong(writerIndex, value);
|
||||||
writerIndex += 8;
|
writerIndex += 8;
|
||||||
return this;
|
return this;
|
||||||
|
@ -717,7 +745,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf writeBytes(byte[] src, int srcIndex, int length) {
|
public ByteBuf writeBytes(byte[] src, int srcIndex, int length) {
|
||||||
ensureWritableBytes(length);
|
ensureWritable(length);
|
||||||
setBytes(writerIndex, src, srcIndex, length);
|
setBytes(writerIndex, src, srcIndex, length);
|
||||||
writerIndex += length;
|
writerIndex += length;
|
||||||
return this;
|
return this;
|
||||||
|
@ -748,7 +776,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) {
|
public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) {
|
||||||
ensureWritableBytes(length);
|
ensureWritable(length);
|
||||||
setBytes(writerIndex, src, srcIndex, length);
|
setBytes(writerIndex, src, srcIndex, length);
|
||||||
writerIndex += length;
|
writerIndex += length;
|
||||||
return this;
|
return this;
|
||||||
|
@ -757,7 +785,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf writeBytes(ByteBuffer src) {
|
public ByteBuf writeBytes(ByteBuffer src) {
|
||||||
int length = src.remaining();
|
int length = src.remaining();
|
||||||
ensureWritableBytes(length);
|
ensureWritable(length);
|
||||||
setBytes(writerIndex, src);
|
setBytes(writerIndex, src);
|
||||||
writerIndex += length;
|
writerIndex += length;
|
||||||
return this;
|
return this;
|
||||||
|
@ -766,7 +794,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||||
@Override
|
@Override
|
||||||
public int writeBytes(InputStream in, int length)
|
public int writeBytes(InputStream in, int length)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
ensureWritableBytes(length);
|
ensureWritable(length);
|
||||||
int writtenBytes = setBytes(writerIndex, in, length);
|
int writtenBytes = setBytes(writerIndex, in, length);
|
||||||
if (writtenBytes > 0) {
|
if (writtenBytes > 0) {
|
||||||
writerIndex += writtenBytes;
|
writerIndex += writtenBytes;
|
||||||
|
@ -777,7 +805,7 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||||
@Override
|
@Override
|
||||||
public int writeBytes(ScatteringByteChannel in, int length)
|
public int writeBytes(ScatteringByteChannel in, int length)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
ensureWritableBytes(length);
|
ensureWritable(length);
|
||||||
int writtenBytes = setBytes(writerIndex, in, length);
|
int writtenBytes = setBytes(writerIndex, in, length);
|
||||||
if (writtenBytes > 0) {
|
if (writtenBytes > 0) {
|
||||||
writerIndex += writtenBytes;
|
writerIndex += writtenBytes;
|
||||||
|
@ -956,6 +984,10 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||||
buf.append(writerIndex);
|
buf.append(writerIndex);
|
||||||
buf.append(", cap: ");
|
buf.append(", cap: ");
|
||||||
buf.append(capacity());
|
buf.append(capacity());
|
||||||
|
if (maxCapacity != Integer.MAX_VALUE) {
|
||||||
|
buf.append('/');
|
||||||
|
buf.append(maxCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
ByteBuf unwrapped = unwrap();
|
ByteBuf unwrapped = unwrap();
|
||||||
if (unwrapped != null) {
|
if (unwrapped != null) {
|
||||||
|
|
159
buffer/src/main/java/io/netty/buffer/AbstractMessageBuf.java
Normal file
159
buffer/src/main/java/io/netty/buffer/AbstractMessageBuf.java
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 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 java.util.AbstractQueue;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public abstract class AbstractMessageBuf<T> extends AbstractQueue<T> implements MessageBuf<T> {
|
||||||
|
|
||||||
|
private final int maxCapacity;
|
||||||
|
private boolean freed;
|
||||||
|
|
||||||
|
protected AbstractMessageBuf(int maxCapacity) {
|
||||||
|
if (maxCapacity < 0) {
|
||||||
|
throw new IllegalArgumentException("maxCapacity: " + maxCapacity + " (expected: >= 0)");
|
||||||
|
}
|
||||||
|
this.maxCapacity = maxCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final BufType type() {
|
||||||
|
return BufType.MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isFreed() {
|
||||||
|
return freed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void free() {
|
||||||
|
if (freed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
doFree();
|
||||||
|
} finally {
|
||||||
|
freed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void doFree();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int maxCapacity() {
|
||||||
|
return maxCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isReadable() {
|
||||||
|
return !isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isReadable(int size) {
|
||||||
|
if (size < 0) {
|
||||||
|
throw new IllegalArgumentException("size: " + size + " (expected: >= 0)");
|
||||||
|
}
|
||||||
|
return size() >= size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isWritable() {
|
||||||
|
return size() < maxCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isWritable(int size) {
|
||||||
|
if (size < 0) {
|
||||||
|
throw new IllegalArgumentException("size: " + size + " (expected: >= 0)");
|
||||||
|
}
|
||||||
|
return size() <= maxCapacity - size;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void checkUnfreed() {
|
||||||
|
if (isFreed()) {
|
||||||
|
throw new IllegalBufferAccessException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean add(T t) {
|
||||||
|
return super.add(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final T remove() {
|
||||||
|
return super.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final T element() {
|
||||||
|
return super.element();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int drainTo(Collection<? super T> c) {
|
||||||
|
checkUnfreed();
|
||||||
|
int cnt = 0;
|
||||||
|
for (;;) {
|
||||||
|
T o = poll();
|
||||||
|
if (o == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c.add(o);
|
||||||
|
cnt ++;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int drainTo(Collection<? super T> c, int maxElements) {
|
||||||
|
checkUnfreed();
|
||||||
|
int cnt = 0;
|
||||||
|
while (cnt < maxElements) {
|
||||||
|
T o = poll();
|
||||||
|
if (o == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c.add(o);
|
||||||
|
cnt ++;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if (isFreed()) {
|
||||||
|
return getClass().getSimpleName() + "(freed)";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append(getClass().getSimpleName());
|
||||||
|
buf.append("(size: ");
|
||||||
|
buf.append(size());
|
||||||
|
if (maxCapacity != Integer.MAX_VALUE) {
|
||||||
|
buf.append('/');
|
||||||
|
buf.append(maxCapacity);
|
||||||
|
}
|
||||||
|
buf.append(')');
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,4 +23,30 @@ public interface Buf extends Freeable {
|
||||||
* The BufType which will be handled by the Buf implementation
|
* The BufType which will be handled by the Buf implementation
|
||||||
*/
|
*/
|
||||||
BufType type();
|
BufType type();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum allowed capacity of this buffer.
|
||||||
|
*/
|
||||||
|
int maxCapacity();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if and only if this buffer contains at least one readable element.
|
||||||
|
*/
|
||||||
|
boolean isReadable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if and only if this buffer contains equal to or more than the specified number of elements.
|
||||||
|
*/
|
||||||
|
boolean isReadable(int size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if and only if this buffer has enough room to allow writing one element.
|
||||||
|
*/
|
||||||
|
boolean isWritable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if and only if this buffer has enough room to allow writing the specified number of
|
||||||
|
* elements.
|
||||||
|
*/
|
||||||
|
boolean isWritable(int size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,9 +246,10 @@ public interface ByteBuf extends Buf, Comparable<ByteBuf> {
|
||||||
/**
|
/**
|
||||||
* Returns the maximum allowed capacity of this buffer. If a user attempts to increase the
|
* Returns the maximum allowed capacity of this buffer. If a user attempts to increase the
|
||||||
* capacity of this buffer beyond the maximum capacity using {@link #capacity(int)} or
|
* capacity of this buffer beyond the maximum capacity using {@link #capacity(int)} or
|
||||||
* {@link #ensureWritableBytes(int)}, those methods will raise an
|
* {@link #ensureWritable(int)}, those methods will raise an
|
||||||
* {@link IllegalArgumentException}.
|
* {@link IllegalArgumentException}.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
int maxCapacity();
|
int maxCapacity();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -391,6 +392,13 @@ public interface ByteBuf extends Buf, Comparable<ByteBuf> {
|
||||||
* if and only if {@code (this.writerIndex - this.readerIndex)} is greater
|
* if and only if {@code (this.writerIndex - this.readerIndex)} is greater
|
||||||
* than {@code 0}.
|
* than {@code 0}.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
|
boolean isReadable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #isReadable()} or {@link #isReadable(int)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
boolean readable();
|
boolean readable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -398,6 +406,13 @@ public interface ByteBuf extends Buf, Comparable<ByteBuf> {
|
||||||
* if and only if {@code (this.capacity - this.writerIndex)} is greater
|
* if and only if {@code (this.capacity - this.writerIndex)} is greater
|
||||||
* than {@code 0}.
|
* than {@code 0}.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
|
boolean isWritable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #isWritable()} or {@link #isWritable(int)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
boolean writable();
|
boolean writable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -476,11 +491,17 @@ public interface ByteBuf extends Buf, Comparable<ByteBuf> {
|
||||||
* @throws IndexOutOfBoundsException
|
* @throws IndexOutOfBoundsException
|
||||||
* if {@link #writerIndex()} + {@code minWritableBytes} > {@link #maxCapacity()}
|
* if {@link #writerIndex()} + {@code minWritableBytes} > {@link #maxCapacity()}
|
||||||
*/
|
*/
|
||||||
|
ByteBuf ensureWritable(int minWritableBytes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #ensureWritable(int)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
ByteBuf ensureWritableBytes(int minWritableBytes);
|
ByteBuf ensureWritableBytes(int minWritableBytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to make sure the number of {@linkplain #writableBytes() the writable bytes}
|
* Tries to make sure the number of {@linkplain #writableBytes() the writable bytes}
|
||||||
* is equal to or greater than the specified value. Unlike {@link #ensureWritableBytes(int)},
|
* is equal to or greater than the specified value. Unlike {@link #ensureWritable(int)},
|
||||||
* this method does not raise an exception but returns a code.
|
* this method does not raise an exception but returns a code.
|
||||||
*
|
*
|
||||||
* @param minWritableBytes
|
* @param minWritableBytes
|
||||||
|
@ -497,7 +518,7 @@ public interface ByteBuf extends Buf, Comparable<ByteBuf> {
|
||||||
* {@code 3} if the buffer does not have enough bytes, but its capacity has been
|
* {@code 3} if the buffer does not have enough bytes, but its capacity has been
|
||||||
* increased to its maximum.
|
* increased to its maximum.
|
||||||
*/
|
*/
|
||||||
int ensureWritableBytes(int minWritableBytes, boolean force);
|
int ensureWritable(int minWritableBytes, boolean force);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a boolean at the specified absolute (@code index) in this buffer.
|
* Gets a boolean at the specified absolute (@code index) in this buffer.
|
||||||
|
|
|
@ -103,7 +103,7 @@ public class ByteBufInputStream extends InputStream implements DataInput {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read() throws IOException {
|
public int read() throws IOException {
|
||||||
if (!buffer.readable()) {
|
if (!buffer.isReadable()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return buffer.readByte() & 0xff;
|
return buffer.readByte() & 0xff;
|
||||||
|
@ -143,7 +143,7 @@ public class ByteBufInputStream extends InputStream implements DataInput {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte readByte() throws IOException {
|
public byte readByte() throws IOException {
|
||||||
if (!buffer.readable()) {
|
if (!buffer.isReadable()) {
|
||||||
throw new EOFException();
|
throw new EOFException();
|
||||||
}
|
}
|
||||||
return buffer.readByte();
|
return buffer.readByte();
|
||||||
|
|
|
@ -42,7 +42,7 @@ public interface CompositeByteBuf extends ByteBuf, Iterable<ByteBuf> {
|
||||||
* the {@link ByteBuf} to add
|
* the {@link ByteBuf} to add
|
||||||
* @return self
|
* @return self
|
||||||
* this instance
|
* this instance
|
||||||
* @throws {@link IndexOutOfBoundsException}
|
* @throws IndexOutOfBoundsException
|
||||||
* if the index is invalid
|
* if the index is invalid
|
||||||
*/
|
*/
|
||||||
CompositeByteBuf addComponent(int cIndex, ByteBuf buffer);
|
CompositeByteBuf addComponent(int cIndex, ByteBuf buffer);
|
||||||
|
@ -72,7 +72,7 @@ public interface CompositeByteBuf extends ByteBuf, Iterable<ByteBuf> {
|
||||||
* the {@link ByteBuf}s to add
|
* the {@link ByteBuf}s to add
|
||||||
* @return self
|
* @return self
|
||||||
* this instance
|
* this instance
|
||||||
* @throws {@link IndexOutOfBoundsException}
|
* @throws IndexOutOfBoundsException
|
||||||
* if the index is invalid
|
* if the index is invalid
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -87,7 +87,7 @@ public interface CompositeByteBuf extends ByteBuf, Iterable<ByteBuf> {
|
||||||
* the {@link ByteBuf}s to add
|
* the {@link ByteBuf}s to add
|
||||||
* @return self
|
* @return self
|
||||||
* this instance
|
* this instance
|
||||||
* @throws {@link IndexOutOfBoundsException}
|
* @throws IndexOutOfBoundsException
|
||||||
* if the index is invalid
|
* if the index is invalid
|
||||||
*/
|
*/
|
||||||
CompositeByteBuf addComponents(int cIndex, Iterable<ByteBuf> buffers);
|
CompositeByteBuf addComponents(int cIndex, Iterable<ByteBuf> buffers);
|
||||||
|
@ -99,7 +99,7 @@ public interface CompositeByteBuf extends ByteBuf, Iterable<ByteBuf> {
|
||||||
* the index on from which the {@link ByteBuf} will be remove
|
* the index on from which the {@link ByteBuf} will be remove
|
||||||
* @return self
|
* @return self
|
||||||
* this instance
|
* this instance
|
||||||
* @throws {@link IndexOutOfBoundsException}
|
* @throws IndexOutOfBoundsException
|
||||||
* if the index is invalid
|
* if the index is invalid
|
||||||
*/
|
*/
|
||||||
CompositeByteBuf removeComponent(int cIndex);
|
CompositeByteBuf removeComponent(int cIndex);
|
||||||
|
@ -113,7 +113,7 @@ public interface CompositeByteBuf extends ByteBuf, Iterable<ByteBuf> {
|
||||||
* the number of components to remove
|
* the number of components to remove
|
||||||
* @return self
|
* @return self
|
||||||
* this instance
|
* this instance
|
||||||
* @throws {@link IndexOutOfBoundsException}
|
* @throws IndexOutOfBoundsException
|
||||||
* if the index is invalid
|
* if the index is invalid
|
||||||
*/
|
*/
|
||||||
CompositeByteBuf removeComponents(int cIndex, int numComponents);
|
CompositeByteBuf removeComponents(int cIndex, int numComponents);
|
||||||
|
@ -135,7 +135,7 @@ public interface CompositeByteBuf extends ByteBuf, Iterable<ByteBuf> {
|
||||||
* the index for which the {@link ByteBuf} should be returned
|
* the index for which the {@link ByteBuf} should be returned
|
||||||
* @return buf
|
* @return buf
|
||||||
* the {@link ByteBuf} on the specified index
|
* the {@link ByteBuf} on the specified index
|
||||||
* @throws {@link IndexOutOfBoundsException}
|
* @throws IndexOutOfBoundsException
|
||||||
* if the index is invalid
|
* if the index is invalid
|
||||||
*/
|
*/
|
||||||
ByteBuf component(int cIndex);
|
ByteBuf component(int cIndex);
|
||||||
|
@ -147,7 +147,7 @@ public interface CompositeByteBuf extends ByteBuf, Iterable<ByteBuf> {
|
||||||
* the offset for which the {@link ByteBuf} should be returned
|
* the offset for which the {@link ByteBuf} should be returned
|
||||||
* @return buf
|
* @return buf
|
||||||
* the {@link ByteBuf} on the specified index
|
* the {@link ByteBuf} on the specified index
|
||||||
* @throws {@link IndexOutOfBoundsException}
|
* @throws IndexOutOfBoundsException
|
||||||
* if the offset is invalid
|
* if the offset is invalid
|
||||||
*/
|
*/
|
||||||
ByteBuf componentAtOffset(int offset);
|
ByteBuf componentAtOffset(int offset);
|
||||||
|
@ -175,7 +175,7 @@ public interface CompositeByteBuf extends ByteBuf, Iterable<ByteBuf> {
|
||||||
* the number of components to compose
|
* the number of components to compose
|
||||||
* @return self
|
* @return self
|
||||||
* this instance
|
* this instance
|
||||||
* @throws {@link IndexOutOfBoundsException}
|
* @throws IndexOutOfBoundsException
|
||||||
* if the offset is invalid
|
* if the offset is invalid
|
||||||
*/
|
*/
|
||||||
CompositeByteBuf consolidate(int cIndex, int numComponents);
|
CompositeByteBuf consolidate(int cIndex, int numComponents);
|
||||||
|
@ -226,7 +226,7 @@ public interface CompositeByteBuf extends ByteBuf, Iterable<ByteBuf> {
|
||||||
CompositeByteBuf discardSomeReadBytes();
|
CompositeByteBuf discardSomeReadBytes();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
CompositeByteBuf ensureWritableBytes(int minWritableBytes);
|
CompositeByteBuf ensureWritable(int minWritableBytes);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
CompositeByteBuf getBytes(int index, ByteBuf dst);
|
CompositeByteBuf getBytes(int index, ByteBuf dst);
|
||||||
|
|
|
@ -197,7 +197,7 @@ public class DefaultCompositeByteBuf extends AbstractByteBuf implements Composit
|
||||||
if (b == null) {
|
if (b == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (b.readable()) {
|
if (b.isReadable()) {
|
||||||
cIndex = addComponent0(cIndex, b, false) + 1;
|
cIndex = addComponent0(cIndex, b, false) + 1;
|
||||||
int size = components.size();
|
int size = components.size();
|
||||||
if (cIndex > size) {
|
if (cIndex > size) {
|
||||||
|
@ -1341,8 +1341,8 @@ public class DefaultCompositeByteBuf extends AbstractByteBuf implements Composit
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompositeByteBuf ensureWritableBytes(int minWritableBytes) {
|
public CompositeByteBuf ensureWritable(int minWritableBytes) {
|
||||||
return (CompositeByteBuf) super.ensureWritableBytes(minWritableBytes);
|
return (CompositeByteBuf) super.ensureWritable(minWritableBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -13,179 +13,308 @@
|
||||||
* License for the specific language governing permissions and limitations
|
* License for the specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
* Written by Josh Bloch of Google Inc. and released to the public domain,
|
||||||
|
* as explained at http://creativecommons.org/publicdomain/zero/1.0/.
|
||||||
|
*/
|
||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
import java.lang.reflect.Array;
|
||||||
import java.util.Collection;
|
import java.util.ConcurrentModificationException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default {@link MessageBuf} implementation
|
* Default {@link MessageBuf} implementation
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
final class DefaultMessageBuf<T> extends ArrayDeque<T> implements MessageBuf<T> {
|
final class DefaultMessageBuf<T> extends AbstractMessageBuf<T> {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1229808623624907552L;
|
private static final int MIN_INITIAL_CAPACITY = 8;
|
||||||
|
|
||||||
private boolean freed;
|
private T[] elements;
|
||||||
|
private int head;
|
||||||
|
private int tail;
|
||||||
|
|
||||||
DefaultMessageBuf() { }
|
DefaultMessageBuf() {
|
||||||
|
this(MIN_INITIAL_CAPACITY << 1);
|
||||||
|
}
|
||||||
|
|
||||||
DefaultMessageBuf(int initialCapacity) {
|
DefaultMessageBuf(int initialCapacity) {
|
||||||
super(initialCapacity);
|
this(initialCapacity, Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultMessageBuf(int initialCapacity, int maxCapacity) {
|
||||||
|
super(maxCapacity);
|
||||||
|
|
||||||
|
if (initialCapacity < 0) {
|
||||||
|
throw new IllegalArgumentException("initialCapacity: " + initialCapacity + " (expected: >= 0)");
|
||||||
|
}
|
||||||
|
if (maxCapacity < initialCapacity) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"maxCapacity: " + maxCapacity + " (expected: >= initialCapacity(" + initialCapacity + ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the best power of two to hold elements.
|
||||||
|
// Tests "<=" because arrays aren't kept full.
|
||||||
|
if (initialCapacity >= MIN_INITIAL_CAPACITY) {
|
||||||
|
initialCapacity |= initialCapacity >>> 1;
|
||||||
|
initialCapacity |= initialCapacity >>> 2;
|
||||||
|
initialCapacity |= initialCapacity >>> 4;
|
||||||
|
initialCapacity |= initialCapacity >>> 8;
|
||||||
|
initialCapacity |= initialCapacity >>> 16;
|
||||||
|
initialCapacity ++;
|
||||||
|
|
||||||
|
if (initialCapacity < 0) { // Too many elements, must back off
|
||||||
|
initialCapacity >>>= 1; // Good luck allocating 2 ^ 30 elements
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
initialCapacity = MIN_INITIAL_CAPACITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
elements = cast(new Object[initialCapacity]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BufType type() {
|
protected void doFree() {
|
||||||
return BufType.MESSAGE;
|
elements = null;
|
||||||
|
head = 0;
|
||||||
|
tail = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addFirst(T t) {
|
public boolean offer(T e) {
|
||||||
ensureValid();
|
if (e == null) {
|
||||||
super.addFirst(t);
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
if (!isWritable()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
elements[tail] = e;
|
||||||
|
if ((tail = tail + 1 & elements.length - 1) == head) {
|
||||||
|
doubleCapacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doubleCapacity() {
|
||||||
|
assert head == tail;
|
||||||
|
|
||||||
|
int p = head;
|
||||||
|
int n = elements.length;
|
||||||
|
int r = n - p; // number of elements to the right of p
|
||||||
|
int newCapacity = n << 1;
|
||||||
|
if (newCapacity < 0) {
|
||||||
|
throw new IllegalStateException("Sorry, deque too big");
|
||||||
|
}
|
||||||
|
Object[] a = new Object[newCapacity];
|
||||||
|
System.arraycopy(elements, p, a, 0, r);
|
||||||
|
System.arraycopy(elements, 0, a, r, p);
|
||||||
|
elements = cast(a);
|
||||||
|
head = 0;
|
||||||
|
tail = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addLast(T t) {
|
public T poll() {
|
||||||
ensureValid();
|
int h = head;
|
||||||
super.addLast(t);
|
T result = elements[h]; // Element is null if deque empty
|
||||||
|
if (result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
elements[h] = null; // Must null out slot
|
||||||
|
head = h + 1 & elements.length - 1;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T pollFirst() {
|
public T peek() {
|
||||||
ensureValid();
|
return elements[head]; // elements[head] is null if deque empty
|
||||||
return super.pollFirst();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T pollLast() {
|
public boolean remove(Object o) {
|
||||||
ensureValid();
|
if (o == null) {
|
||||||
return super.pollLast();
|
return false;
|
||||||
|
}
|
||||||
|
int mask = elements.length - 1;
|
||||||
|
int i = head;
|
||||||
|
T x;
|
||||||
|
while ((x = elements[i]) != null) {
|
||||||
|
if (o.equals(x)) {
|
||||||
|
delete(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
i = i + 1 & mask;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean delete(int i) {
|
||||||
|
assert elements[tail] == null;
|
||||||
|
assert head == tail ? elements[head] == null
|
||||||
|
: elements[head] != null && elements[tail - 1 & elements.length - 1] != null;
|
||||||
|
assert elements[head - 1 & elements.length - 1] == null;
|
||||||
|
|
||||||
|
final T[] elements = this.elements;
|
||||||
|
final int mask = elements.length - 1;
|
||||||
|
final int h = head;
|
||||||
|
final int t = tail;
|
||||||
|
final int front = i - h & mask;
|
||||||
|
final int back = t - i & mask;
|
||||||
|
|
||||||
|
// Invariant: head <= i < tail mod circularity
|
||||||
|
if (front >= (t - h & mask)) {
|
||||||
|
throw new ConcurrentModificationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optimize for least element motion
|
||||||
|
if (front < back) {
|
||||||
|
if (h <= i) {
|
||||||
|
System.arraycopy(elements, h, elements, h + 1, front);
|
||||||
|
} else { // Wrap around
|
||||||
|
System.arraycopy(elements, 0, elements, 1, i);
|
||||||
|
elements[0] = elements[mask];
|
||||||
|
System.arraycopy(elements, h, elements, h + 1, mask - h);
|
||||||
|
}
|
||||||
|
elements[h] = null;
|
||||||
|
head = h + 1 & mask;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (i < t) { // Copy the null tail as well
|
||||||
|
System.arraycopy(elements, i + 1, elements, i, back);
|
||||||
|
tail = t - 1;
|
||||||
|
} else { // Wrap around
|
||||||
|
System.arraycopy(elements, i + 1, elements, i, mask - i);
|
||||||
|
elements[mask] = elements[0];
|
||||||
|
System.arraycopy(elements, 1, elements, 0, t);
|
||||||
|
tail = t - 1 & mask;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T getFirst() {
|
public int size() {
|
||||||
ensureValid();
|
return tail - head & elements.length - 1;
|
||||||
return super.getFirst();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T getLast() {
|
public boolean isEmpty() {
|
||||||
ensureValid();
|
return head == tail;
|
||||||
return super.getLast();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T peekFirst() {
|
|
||||||
ensureValid();
|
|
||||||
return super.peekFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T peekLast() {
|
|
||||||
ensureValid();
|
|
||||||
return super.peekLast();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removeFirstOccurrence(Object o) {
|
|
||||||
ensureValid();
|
|
||||||
return super.removeFirstOccurrence(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removeLastOccurrence(Object o) {
|
|
||||||
ensureValid();
|
|
||||||
return super.removeLastOccurrence(o);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<T> iterator() {
|
public Iterator<T> iterator() {
|
||||||
ensureValid();
|
return new Itr();
|
||||||
return super.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<T> descendingIterator() {
|
|
||||||
ensureValid();
|
|
||||||
return super.descendingIterator();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(Object o) {
|
public boolean contains(Object o) {
|
||||||
ensureValid();
|
if (o == null) {
|
||||||
return super.contains(o);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int mask = elements.length - 1;
|
||||||
|
int i = head;
|
||||||
|
Object e;
|
||||||
|
while ((e = elements[i]) != null) {
|
||||||
|
if (o.equals(e)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
i = i + 1 & mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
ensureValid();
|
int head = this.head;
|
||||||
super.clear();
|
int tail = this.tail;
|
||||||
|
if (head != tail) {
|
||||||
|
this.head = this.tail = 0;
|
||||||
|
final int mask = elements.length - 1;
|
||||||
|
int i = head;
|
||||||
|
do {
|
||||||
|
elements[i] = null;
|
||||||
|
i = i + 1 & mask;
|
||||||
|
} while (i != tail);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] toArray() {
|
public Object[] toArray() {
|
||||||
ensureValid();
|
return copyElements(new Object[size()]);
|
||||||
return super.toArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T1> T1[] toArray(T1[] a) {
|
public <T> T[] toArray(T[] a) {
|
||||||
ensureValid();
|
int size = size();
|
||||||
return super.toArray(a);
|
if (a.length < size) {
|
||||||
}
|
a = cast(Array.newInstance(a.getClass().getComponentType(), size));
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayDeque<T> clone() {
|
|
||||||
ensureValid();
|
|
||||||
return super.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int drainTo(Collection<? super T> c) {
|
|
||||||
ensureValid();
|
|
||||||
int cnt = 0;
|
|
||||||
for (;;) {
|
|
||||||
T o = poll();
|
|
||||||
if (o == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
c.add(o);
|
|
||||||
cnt ++;
|
|
||||||
}
|
}
|
||||||
return cnt;
|
copyElements(a);
|
||||||
}
|
if (a.length > size) {
|
||||||
|
a[size] = null;
|
||||||
@Override
|
|
||||||
public int drainTo(Collection<? super T> c, int maxElements) {
|
|
||||||
ensureValid();
|
|
||||||
int cnt = 0;
|
|
||||||
while (cnt < maxElements) {
|
|
||||||
T o = poll();
|
|
||||||
if (o == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
c.add(o);
|
|
||||||
cnt ++;
|
|
||||||
}
|
}
|
||||||
return cnt;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private <U> U[] copyElements(U[] a) {
|
||||||
public boolean isFreed() {
|
if (head < tail) {
|
||||||
return freed;
|
System.arraycopy(elements, head, cast(a), 0, size());
|
||||||
|
} else if (head > tail) {
|
||||||
|
int headPortionLen = elements.length - head;
|
||||||
|
System.arraycopy(elements, head, cast(a), 0, headPortionLen);
|
||||||
|
System.arraycopy(elements, 0, cast(a), headPortionLen, tail);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@SuppressWarnings({ "unchecked", "SuspiciousArrayCast" })
|
||||||
public void free() {
|
private static <T> T[] cast(Object a) {
|
||||||
freed = true;
|
return (T[]) a;
|
||||||
super.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureValid() {
|
private class Itr implements Iterator<T> {
|
||||||
if (freed) {
|
private int cursor = head;
|
||||||
throw new IllegalBufferAccessException();
|
private int fence = tail;
|
||||||
|
private int lastRet = -1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return cursor != fence;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T next() {
|
||||||
|
if (cursor == fence) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
T result = elements[cursor];
|
||||||
|
// This check doesn't catch all possible comodifications,
|
||||||
|
// but does catch the ones that corrupt traversal
|
||||||
|
if (tail != fence || result == null) {
|
||||||
|
throw new ConcurrentModificationException();
|
||||||
|
}
|
||||||
|
lastRet = cursor;
|
||||||
|
cursor = cursor + 1 & elements.length - 1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
if (lastRet < 0) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
if (delete(lastRet)) { // if left-shifted, undo increment in next()
|
||||||
|
cursor = cursor - 1 & elements.length - 1;
|
||||||
|
fence = tail;
|
||||||
|
}
|
||||||
|
lastRet = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,180 +19,108 @@ import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
|
||||||
final class QueueBackedMessageBuf<T> implements MessageBuf<T> {
|
final class QueueBackedMessageBuf<T> extends AbstractMessageBuf<T> {
|
||||||
|
|
||||||
private final Queue<T> queue;
|
private final Queue<T> queue;
|
||||||
private boolean freed;
|
|
||||||
|
|
||||||
QueueBackedMessageBuf(Queue<T> queue) {
|
QueueBackedMessageBuf(Queue<T> queue) {
|
||||||
|
super(Integer.MAX_VALUE);
|
||||||
if (queue == null) {
|
if (queue == null) {
|
||||||
throw new NullPointerException("queue");
|
throw new NullPointerException("queue");
|
||||||
}
|
}
|
||||||
this.queue = queue;
|
this.queue = queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BufType type() {
|
|
||||||
return BufType.MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean add(T e) {
|
|
||||||
ensureValid();
|
|
||||||
return queue.add(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean offer(T e) {
|
public boolean offer(T e) {
|
||||||
ensureValid();
|
checkUnfreed();
|
||||||
return queue.offer(e);
|
return isWritable() && queue.offer(e);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T remove() {
|
|
||||||
ensureValid();
|
|
||||||
return queue.remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T poll() {
|
public T poll() {
|
||||||
ensureValid();
|
checkUnfreed();
|
||||||
return queue.poll();
|
return queue.poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public T element() {
|
|
||||||
ensureValid();
|
|
||||||
return queue.element();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T peek() {
|
public T peek() {
|
||||||
ensureValid();
|
checkUnfreed();
|
||||||
return queue.peek();
|
return queue.peek();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
ensureValid();
|
|
||||||
return queue.size();
|
return queue.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
ensureValid();
|
|
||||||
return queue.isEmpty();
|
return queue.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(Object o) {
|
public boolean contains(Object o) {
|
||||||
ensureValid();
|
checkUnfreed();
|
||||||
return queue.contains(o);
|
return queue.contains(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<T> iterator() {
|
public Iterator<T> iterator() {
|
||||||
ensureValid();
|
checkUnfreed();
|
||||||
return queue.iterator();
|
return queue.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] toArray() {
|
public Object[] toArray() {
|
||||||
ensureValid();
|
checkUnfreed();
|
||||||
return queue.toArray();
|
return queue.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <E> E[] toArray(E[] a) {
|
public <E> E[] toArray(E[] a) {
|
||||||
ensureValid();
|
checkUnfreed();
|
||||||
return queue.toArray(a);
|
return queue.toArray(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean remove(Object o) {
|
public boolean remove(Object o) {
|
||||||
ensureValid();
|
checkUnfreed();
|
||||||
return queue.remove(o);
|
return queue.remove(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean containsAll(Collection<?> c) {
|
public boolean containsAll(Collection<?> c) {
|
||||||
ensureValid();
|
checkUnfreed();
|
||||||
return queue.containsAll(c);
|
return queue.containsAll(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addAll(Collection<? extends T> c) {
|
public boolean addAll(Collection<? extends T> c) {
|
||||||
ensureValid();
|
checkUnfreed();
|
||||||
return queue.addAll(c);
|
return isWritable(c.size()) && queue.addAll(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeAll(Collection<?> c) {
|
public boolean removeAll(Collection<?> c) {
|
||||||
ensureValid();
|
checkUnfreed();
|
||||||
return queue.removeAll(c);
|
return queue.removeAll(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean retainAll(Collection<?> c) {
|
public boolean retainAll(Collection<?> c) {
|
||||||
ensureValid();
|
checkUnfreed();
|
||||||
return queue.retainAll(c);
|
return queue.retainAll(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
ensureValid();
|
checkUnfreed();
|
||||||
queue.clear();
|
queue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int drainTo(Collection<? super T> c) {
|
protected void doFree() {
|
||||||
ensureValid();
|
clear();
|
||||||
int cnt = 0;
|
|
||||||
for (;;) {
|
|
||||||
T o = poll();
|
|
||||||
if (o == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
c.add(o);
|
|
||||||
cnt ++;
|
|
||||||
}
|
|
||||||
return cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int drainTo(Collection<? super T> c, int maxElements) {
|
|
||||||
ensureValid();
|
|
||||||
int cnt = 0;
|
|
||||||
while (cnt < maxElements) {
|
|
||||||
T o = poll();
|
|
||||||
if (o == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
c.add(o);
|
|
||||||
cnt ++;
|
|
||||||
}
|
|
||||||
return cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFreed() {
|
|
||||||
return freed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void free() {
|
|
||||||
freed = true;
|
|
||||||
queue.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return queue.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ensureValid() {
|
|
||||||
if (freed) {
|
|
||||||
throw new IllegalBufferAccessException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,13 +137,35 @@ public final class SwappedByteBuf implements ByteBuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean readable() {
|
public boolean isReadable() {
|
||||||
return buf.readable();
|
return buf.isReadable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public boolean readable() {
|
||||||
|
return buf.isReadable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReadable(int size) {
|
||||||
|
return buf.isReadable(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWritable() {
|
||||||
|
return buf.isWritable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
public boolean writable() {
|
public boolean writable() {
|
||||||
return buf.writable();
|
return buf.isWritable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWritable(int size) {
|
||||||
|
return buf.isWritable(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -189,14 +211,21 @@ public final class SwappedByteBuf implements ByteBuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf ensureWritableBytes(int writableBytes) {
|
public ByteBuf ensureWritable(int writableBytes) {
|
||||||
buf.ensureWritableBytes(writableBytes);
|
buf.ensureWritable(writableBytes);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int ensureWritableBytes(int minWritableBytes, boolean force) {
|
@Deprecated
|
||||||
return buf.ensureWritableBytes(minWritableBytes, force);
|
public ByteBuf ensureWritableBytes(int minWritableBytes) {
|
||||||
|
buf.ensureWritable(minWritableBytes);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int ensureWritable(int minWritableBytes, boolean force) {
|
||||||
|
return buf.ensureWritable(minWritableBytes, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -292,6 +292,10 @@ public final class Unpooled {
|
||||||
return new DefaultMessageBuf<T>(initialCapacity);
|
return new DefaultMessageBuf<T>(initialCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> MessageBuf<T> messageBuffer(int initialCapacity, int maxCapacity) {
|
||||||
|
return new DefaultMessageBuf<T>(initialCapacity, maxCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> MessageBuf<T> wrappedBuffer(Queue<T> queue) {
|
public static <T> MessageBuf<T> wrappedBuffer(Queue<T> queue) {
|
||||||
if (queue instanceof MessageBuf) {
|
if (queue instanceof MessageBuf) {
|
||||||
return (MessageBuf<T>) queue;
|
return (MessageBuf<T>) queue;
|
||||||
|
@ -405,7 +409,7 @@ public final class Unpooled {
|
||||||
* returned buffer.
|
* returned buffer.
|
||||||
*/
|
*/
|
||||||
public static ByteBuf wrappedBuffer(ByteBuf buffer) {
|
public static ByteBuf wrappedBuffer(ByteBuf buffer) {
|
||||||
if (buffer.readable()) {
|
if (buffer.isReadable()) {
|
||||||
return buffer.slice();
|
return buffer.slice();
|
||||||
} else {
|
} else {
|
||||||
return EMPTY_BUFFER;
|
return EMPTY_BUFFER;
|
||||||
|
@ -483,13 +487,13 @@ public final class Unpooled {
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (buffers[0].readable()) {
|
if (buffers[0].isReadable()) {
|
||||||
return wrappedBuffer(buffers[0].order(BIG_ENDIAN));
|
return wrappedBuffer(buffers[0].order(BIG_ENDIAN));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
for (ByteBuf b: buffers) {
|
for (ByteBuf b: buffers) {
|
||||||
if (b.readable()) {
|
if (b.isReadable()) {
|
||||||
return new DefaultCompositeByteBuf(ALLOC, false, maxNumComponents, buffers);
|
return new DefaultCompositeByteBuf(ALLOC, false, maxNumComponents, buffers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -600,7 +604,7 @@ public final class Unpooled {
|
||||||
* respectively.
|
* respectively.
|
||||||
*/
|
*/
|
||||||
public static ByteBuf copiedBuffer(ByteBuf buffer) {
|
public static ByteBuf copiedBuffer(ByteBuf buffer) {
|
||||||
if (buffer.readable()) {
|
if (buffer.isReadable()) {
|
||||||
return buffer.copy();
|
return buffer.copy();
|
||||||
} else {
|
} else {
|
||||||
return EMPTY_BUFFER;
|
return EMPTY_BUFFER;
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class WebSocket00FrameEncoder extends MessageToByteEncoder<WebSocketFrame
|
||||||
// Binary frame
|
// Binary frame
|
||||||
ByteBuf data = msg.data();
|
ByteBuf data = msg.data();
|
||||||
int dataLen = data.readableBytes();
|
int dataLen = data.readableBytes();
|
||||||
out.ensureWritableBytes(dataLen + 5);
|
out.ensureWritable(dataLen + 5);
|
||||||
|
|
||||||
// Encode type.
|
// Encode type.
|
||||||
out.writeByte((byte) 0x80);
|
out.writeByte((byte) 0x80);
|
||||||
|
|
|
@ -142,18 +142,18 @@ public class WebSocket08FrameEncoder extends MessageToByteEncoder<WebSocketFrame
|
||||||
|
|
||||||
int maskLength = maskPayload ? 4 : 0;
|
int maskLength = maskPayload ? 4 : 0;
|
||||||
if (length <= 125) {
|
if (length <= 125) {
|
||||||
out.ensureWritableBytes(2 + maskLength + length);
|
out.ensureWritable(2 + maskLength + length);
|
||||||
out.writeByte(b0);
|
out.writeByte(b0);
|
||||||
byte b = (byte) (maskPayload ? 0x80 | (byte) length : (byte) length);
|
byte b = (byte) (maskPayload ? 0x80 | (byte) length : (byte) length);
|
||||||
out.writeByte(b);
|
out.writeByte(b);
|
||||||
} else if (length <= 0xFFFF) {
|
} else if (length <= 0xFFFF) {
|
||||||
out.ensureWritableBytes(4 + maskLength + length);
|
out.ensureWritable(4 + maskLength + length);
|
||||||
out.writeByte(b0);
|
out.writeByte(b0);
|
||||||
out.writeByte(maskPayload ? 0xFE : 126);
|
out.writeByte(maskPayload ? 0xFE : 126);
|
||||||
out.writeByte(length >>> 8 & 0xFF);
|
out.writeByte(length >>> 8 & 0xFF);
|
||||||
out.writeByte(length & 0xFF);
|
out.writeByte(length & 0xFF);
|
||||||
} else {
|
} else {
|
||||||
out.ensureWritableBytes(10 + maskLength + length);
|
out.ensureWritable(10 + maskLength + length);
|
||||||
out.writeByte(b0);
|
out.writeByte(b0);
|
||||||
out.writeByte(maskPayload ? 0xFF : 127);
|
out.writeByte(maskPayload ? 0xFF : 127);
|
||||||
out.writeLong(length);
|
out.writeLong(length);
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<Object> {
|
||||||
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
|
SpdyDataFrame spdyDataFrame = (SpdyDataFrame) msg;
|
||||||
ByteBuf data = spdyDataFrame.data();
|
ByteBuf data = spdyDataFrame.data();
|
||||||
byte flags = spdyDataFrame.isLast() ? SPDY_DATA_FLAG_FIN : 0;
|
byte flags = spdyDataFrame.isLast() ? SPDY_DATA_FLAG_FIN : 0;
|
||||||
out.ensureWritableBytes(SPDY_HEADER_SIZE + data.readableBytes());
|
out.ensureWritable(SPDY_HEADER_SIZE + data.readableBytes());
|
||||||
out.writeInt(spdyDataFrame.getStreamId() & 0x7FFFFFFF);
|
out.writeInt(spdyDataFrame.getStreamId() & 0x7FFFFFFF);
|
||||||
out.writeByte(flags);
|
out.writeByte(flags);
|
||||||
out.writeMedium(data.readableBytes());
|
out.writeMedium(data.readableBytes());
|
||||||
|
@ -106,7 +106,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<Object> {
|
||||||
} else {
|
} else {
|
||||||
length = 10 + headerBlockLength;
|
length = 10 + headerBlockLength;
|
||||||
}
|
}
|
||||||
out.ensureWritableBytes(SPDY_HEADER_SIZE + length);
|
out.ensureWritable(SPDY_HEADER_SIZE + length);
|
||||||
out.writeShort(version | 0x8000);
|
out.writeShort(version | 0x8000);
|
||||||
out.writeShort(SPDY_SYN_STREAM_FRAME);
|
out.writeShort(SPDY_SYN_STREAM_FRAME);
|
||||||
out.writeByte(flags);
|
out.writeByte(flags);
|
||||||
|
@ -141,7 +141,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<Object> {
|
||||||
} else {
|
} else {
|
||||||
length = 4 + headerBlockLength;
|
length = 4 + headerBlockLength;
|
||||||
}
|
}
|
||||||
out.ensureWritableBytes(SPDY_HEADER_SIZE + length);
|
out.ensureWritable(SPDY_HEADER_SIZE + length);
|
||||||
out.writeShort(version | 0x8000);
|
out.writeShort(version | 0x8000);
|
||||||
out.writeShort(SPDY_SYN_REPLY_FRAME);
|
out.writeShort(SPDY_SYN_REPLY_FRAME);
|
||||||
out.writeByte(flags);
|
out.writeByte(flags);
|
||||||
|
@ -159,7 +159,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<Object> {
|
||||||
} else if (msg instanceof SpdyRstStreamFrame) {
|
} else if (msg instanceof SpdyRstStreamFrame) {
|
||||||
|
|
||||||
SpdyRstStreamFrame spdyRstStreamFrame = (SpdyRstStreamFrame) msg;
|
SpdyRstStreamFrame spdyRstStreamFrame = (SpdyRstStreamFrame) msg;
|
||||||
out.ensureWritableBytes(SPDY_HEADER_SIZE + 8);
|
out.ensureWritable(SPDY_HEADER_SIZE + 8);
|
||||||
out.writeShort(version | 0x8000);
|
out.writeShort(version | 0x8000);
|
||||||
out.writeShort(SPDY_RST_STREAM_FRAME);
|
out.writeShort(SPDY_RST_STREAM_FRAME);
|
||||||
out.writeInt(8);
|
out.writeInt(8);
|
||||||
|
@ -174,7 +174,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<Object> {
|
||||||
Set<Integer> IDs = spdySettingsFrame.getIds();
|
Set<Integer> IDs = spdySettingsFrame.getIds();
|
||||||
int numEntries = IDs.size();
|
int numEntries = IDs.size();
|
||||||
int length = 4 + numEntries * 8;
|
int length = 4 + numEntries * 8;
|
||||||
out.ensureWritableBytes(SPDY_HEADER_SIZE + length);
|
out.ensureWritable(SPDY_HEADER_SIZE + length);
|
||||||
out.writeShort(version | 0x8000);
|
out.writeShort(version | 0x8000);
|
||||||
out.writeShort(SPDY_SETTINGS_FRAME);
|
out.writeShort(SPDY_SETTINGS_FRAME);
|
||||||
out.writeByte(flags);
|
out.writeByte(flags);
|
||||||
|
@ -206,7 +206,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<Object> {
|
||||||
|
|
||||||
} else if (msg instanceof SpdyNoOpFrame) {
|
} else if (msg instanceof SpdyNoOpFrame) {
|
||||||
|
|
||||||
out.ensureWritableBytes(SPDY_HEADER_SIZE);
|
out.ensureWritable(SPDY_HEADER_SIZE);
|
||||||
out.writeShort(version | 0x8000);
|
out.writeShort(version | 0x8000);
|
||||||
out.writeShort(SPDY_NOOP_FRAME);
|
out.writeShort(SPDY_NOOP_FRAME);
|
||||||
out.writeInt(0);
|
out.writeInt(0);
|
||||||
|
@ -214,7 +214,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<Object> {
|
||||||
} else if (msg instanceof SpdyPingFrame) {
|
} else if (msg instanceof SpdyPingFrame) {
|
||||||
|
|
||||||
SpdyPingFrame spdyPingFrame = (SpdyPingFrame) msg;
|
SpdyPingFrame spdyPingFrame = (SpdyPingFrame) msg;
|
||||||
out.ensureWritableBytes(SPDY_HEADER_SIZE + 4);
|
out.ensureWritable(SPDY_HEADER_SIZE + 4);
|
||||||
out.writeShort(version | 0x8000);
|
out.writeShort(version | 0x8000);
|
||||||
out.writeShort(SPDY_PING_FRAME);
|
out.writeShort(SPDY_PING_FRAME);
|
||||||
out.writeInt(4);
|
out.writeInt(4);
|
||||||
|
@ -224,7 +224,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<Object> {
|
||||||
|
|
||||||
SpdyGoAwayFrame spdyGoAwayFrame = (SpdyGoAwayFrame) msg;
|
SpdyGoAwayFrame spdyGoAwayFrame = (SpdyGoAwayFrame) msg;
|
||||||
int length = version < 3 ? 4 : 8;
|
int length = version < 3 ? 4 : 8;
|
||||||
out.ensureWritableBytes(SPDY_HEADER_SIZE + length);
|
out.ensureWritable(SPDY_HEADER_SIZE + length);
|
||||||
out.writeShort(version | 0x8000);
|
out.writeShort(version | 0x8000);
|
||||||
out.writeShort(SPDY_GOAWAY_FRAME);
|
out.writeShort(SPDY_GOAWAY_FRAME);
|
||||||
out.writeInt(length);
|
out.writeInt(length);
|
||||||
|
@ -246,7 +246,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<Object> {
|
||||||
} else {
|
} else {
|
||||||
length = 4 + headerBlockLength;
|
length = 4 + headerBlockLength;
|
||||||
}
|
}
|
||||||
out.ensureWritableBytes(SPDY_HEADER_SIZE + length);
|
out.ensureWritable(SPDY_HEADER_SIZE + length);
|
||||||
out.writeShort(version | 0x8000);
|
out.writeShort(version | 0x8000);
|
||||||
out.writeShort(SPDY_HEADERS_FRAME);
|
out.writeShort(SPDY_HEADERS_FRAME);
|
||||||
out.writeByte(flags);
|
out.writeByte(flags);
|
||||||
|
@ -260,7 +260,7 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<Object> {
|
||||||
} else if (msg instanceof SpdyWindowUpdateFrame) {
|
} else if (msg instanceof SpdyWindowUpdateFrame) {
|
||||||
|
|
||||||
SpdyWindowUpdateFrame spdyWindowUpdateFrame = (SpdyWindowUpdateFrame) msg;
|
SpdyWindowUpdateFrame spdyWindowUpdateFrame = (SpdyWindowUpdateFrame) msg;
|
||||||
out.ensureWritableBytes(SPDY_HEADER_SIZE + 8);
|
out.ensureWritable(SPDY_HEADER_SIZE + 8);
|
||||||
out.writeShort(version | 0x8000);
|
out.writeShort(version | 0x8000);
|
||||||
out.writeShort(SPDY_WINDOW_UPDATE_FRAME);
|
out.writeShort(SPDY_WINDOW_UPDATE_FRAME);
|
||||||
out.writeInt(8);
|
out.writeInt(8);
|
||||||
|
|
|
@ -137,13 +137,18 @@ final class ReplayingDecoderBuffer implements ByteBuf {
|
||||||
throw new UnreplayableOperationException();
|
throw new UnreplayableOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf ensureWritable(int writableBytes) {
|
||||||
|
throw new UnreplayableOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf ensureWritableBytes(int writableBytes) {
|
public ByteBuf ensureWritableBytes(int writableBytes) {
|
||||||
throw new UnreplayableOperationException();
|
throw new UnreplayableOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int ensureWritableBytes(int minWritableBytes, boolean force) {
|
public int ensureWritable(int minWritableBytes, boolean force) {
|
||||||
throw new UnreplayableOperationException();
|
throw new UnreplayableOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,9 +389,19 @@ final class ReplayingDecoderBuffer implements ByteBuf {
|
||||||
return swapped;
|
return swapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReadable() {
|
||||||
|
return terminated? buffer.isReadable() : true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean readable() {
|
public boolean readable() {
|
||||||
return terminated? buffer.readable() : true;
|
return isReadable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReadable(int size) {
|
||||||
|
return terminated? buffer.isReadable(size) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -718,11 +733,21 @@ final class ReplayingDecoderBuffer implements ByteBuf {
|
||||||
')';
|
')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWritable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean writable() {
|
public boolean writable() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWritable(int size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int writableBytes() {
|
public int writableBytes() {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class JZlibDecoder extends ZlibDecoder {
|
||||||
ChannelHandlerContext ctx,
|
ChannelHandlerContext ctx,
|
||||||
ByteBuf in, ByteBuf out) throws Exception {
|
ByteBuf in, ByteBuf out) throws Exception {
|
||||||
|
|
||||||
if (!in.readable()) {
|
if (!in.isReadable()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ public class JZlibDecoder extends ZlibDecoder {
|
||||||
loop: for (;;) {
|
loop: for (;;) {
|
||||||
z.avail_out = maxOutputLength;
|
z.avail_out = maxOutputLength;
|
||||||
if (outHasArray) {
|
if (outHasArray) {
|
||||||
out.ensureWritableBytes(maxOutputLength);
|
out.ensureWritable(maxOutputLength);
|
||||||
z.next_out = out.array();
|
z.next_out = out.array();
|
||||||
z.next_out_index = out.arrayOffset() + out.writerIndex();
|
z.next_out_index = out.arrayOffset() + out.writerIndex();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -294,7 +294,7 @@ public class JZlibEncoder extends ZlibEncoder {
|
||||||
boolean outHasArray = out.hasArray();
|
boolean outHasArray = out.hasArray();
|
||||||
z.avail_out = maxOutputLength;
|
z.avail_out = maxOutputLength;
|
||||||
if (outHasArray) {
|
if (outHasArray) {
|
||||||
out.ensureWritableBytes(maxOutputLength);
|
out.ensureWritable(maxOutputLength);
|
||||||
z.next_out = out.array();
|
z.next_out = out.array();
|
||||||
z.next_out_index = out.arrayOffset() + out.writerIndex();
|
z.next_out_index = out.arrayOffset() + out.writerIndex();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -189,7 +189,7 @@ public class JdkZlibEncoder extends ZlibEncoder {
|
||||||
uncompressed.readBytes(inAry);
|
uncompressed.readBytes(inAry);
|
||||||
|
|
||||||
int sizeEstimate = (int) Math.ceil(inAry.length * 1.001) + 12;
|
int sizeEstimate = (int) Math.ceil(inAry.length * 1.001) + 12;
|
||||||
out.ensureWritableBytes(sizeEstimate);
|
out.ensureWritable(sizeEstimate);
|
||||||
|
|
||||||
synchronized (deflater) {
|
synchronized (deflater) {
|
||||||
if (gzip) {
|
if (gzip) {
|
||||||
|
|
|
@ -268,9 +268,9 @@ public class Snappy {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
out.ensureWritableBytes(inputLength);
|
out.ensureWritable(inputLength);
|
||||||
|
|
||||||
while (in.readable() && in.readerIndex() - inIndex < maxLength) {
|
while (in.isReadable() && in.readerIndex() - inIndex < maxLength) {
|
||||||
byte tag = in.readByte();
|
byte tag = in.readByte();
|
||||||
switch (tag & 0x03) {
|
switch (tag & 0x03) {
|
||||||
case LITERAL:
|
case LITERAL:
|
||||||
|
|
|
@ -15,14 +15,13 @@
|
||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.protobuf;
|
package io.netty.handler.codec.protobuf;
|
||||||
|
|
||||||
|
import com.google.protobuf.CodedOutputStream;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufOutputStream;
|
import io.netty.buffer.ByteBufOutputStream;
|
||||||
import io.netty.channel.ChannelHandler.Sharable;
|
import io.netty.channel.ChannelHandler.Sharable;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.MessageToByteEncoder;
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
|
|
||||||
import com.google.protobuf.CodedOutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An encoder that prepends the the Google Protocol Buffers
|
* An encoder that prepends the the Google Protocol Buffers
|
||||||
* <a href="http://code.google.com/apis/protocolbuffers/docs/encoding.html#varints">Base
|
* <a href="http://code.google.com/apis/protocolbuffers/docs/encoding.html#varints">Base
|
||||||
|
@ -52,7 +51,7 @@ public class ProtobufVarint32LengthFieldPrepender extends MessageToByteEncoder<B
|
||||||
ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
|
ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
|
||||||
int bodyLen = msg.readableBytes();
|
int bodyLen = msg.readableBytes();
|
||||||
int headerLen = CodedOutputStream.computeRawVarint32Size(bodyLen);
|
int headerLen = CodedOutputStream.computeRawVarint32Size(bodyLen);
|
||||||
out.ensureWritableBytes(headerLen + bodyLen);
|
out.ensureWritable(headerLen + bodyLen);
|
||||||
|
|
||||||
CodedOutputStream headerOut =
|
CodedOutputStream headerOut =
|
||||||
CodedOutputStream.newInstance(new ByteBufOutputStream(out));
|
CodedOutputStream.newInstance(new ByteBufOutputStream(out));
|
||||||
|
|
|
@ -100,7 +100,7 @@ public class HttpSnoopServerHandler extends ChannelInboundMessageHandlerAdapter<
|
||||||
HttpContent httpContent = (HttpContent) msg;
|
HttpContent httpContent = (HttpContent) msg;
|
||||||
|
|
||||||
ByteBuf content = httpContent.data();
|
ByteBuf content = httpContent.data();
|
||||||
if (content.readable()) {
|
if (content.isReadable()) {
|
||||||
buf.append("CONTENT: ");
|
buf.append("CONTENT: ");
|
||||||
buf.append(content.toString(CharsetUtil.UTF_8));
|
buf.append(content.toString(CharsetUtil.UTF_8));
|
||||||
buf.append("\r\n");
|
buf.append("\r\n");
|
||||||
|
|
|
@ -450,7 +450,7 @@ public class SslHandler
|
||||||
if (result.getStatus() == Status.CLOSED) {
|
if (result.getStatus() == Status.CLOSED) {
|
||||||
// SSLEngine has been closed already.
|
// SSLEngine has been closed already.
|
||||||
// Any further write attempts should be denied.
|
// Any further write attempts should be denied.
|
||||||
if (in.readable()) {
|
if (in.isReadable()) {
|
||||||
in.clear();
|
in.clear();
|
||||||
SSLException e = new SSLException("SSLEngine already closed");
|
SSLException e = new SSLException("SSLEngine already closed");
|
||||||
promise.setFailure(e);
|
promise.setFailure(e);
|
||||||
|
@ -465,7 +465,7 @@ public class SslHandler
|
||||||
ctx.flush();
|
ctx.flush();
|
||||||
continue;
|
continue;
|
||||||
case NEED_UNWRAP:
|
case NEED_UNWRAP:
|
||||||
if (ctx.inboundByteBuffer().readable()) {
|
if (ctx.inboundByteBuffer().isReadable()) {
|
||||||
unwrapLater = true;
|
unwrapLater = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -556,7 +556,7 @@ public class SslHandler
|
||||||
in.skipBytes(result.bytesConsumed());
|
in.skipBytes(result.bytesConsumed());
|
||||||
out.writerIndex(out.writerIndex() + result.bytesProduced());
|
out.writerIndex(out.writerIndex() + result.bytesProduced());
|
||||||
if (result.getStatus() == Status.BUFFER_OVERFLOW) {
|
if (result.getStatus() == Status.BUFFER_OVERFLOW) {
|
||||||
out.ensureWritableBytes(engine.getSession().getPacketBufferSize());
|
out.ensureWritable(engine.getSession().getPacketBufferSize());
|
||||||
} else {
|
} else {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -862,7 +862,7 @@ public class SslHandler
|
||||||
out.writerIndex(out.writerIndex() + result.bytesProduced());
|
out.writerIndex(out.writerIndex() + result.bytesProduced());
|
||||||
switch (result.getStatus()) {
|
switch (result.getStatus()) {
|
||||||
case BUFFER_OVERFLOW:
|
case BUFFER_OVERFLOW:
|
||||||
out.ensureWritableBytes(engine.getSession().getApplicationBufferSize());
|
out.ensureWritable(engine.getSession().getApplicationBufferSize());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return result;
|
return result;
|
||||||
|
|
26
license/LICENSE.deque.txt
Normal file
26
license/LICENSE.deque.txt
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
The person or persons who have associated work with this document (the
|
||||||
|
"Dedicator" or "Certifier") hereby either (a) certifies that, to the best of
|
||||||
|
his knowledge, the work of authorship identified is in the public domain of
|
||||||
|
the country from which the work is published, or (b) hereby dedicates whatever
|
||||||
|
copyright the dedicators holds in the work of authorship identified below (the
|
||||||
|
"Work") to the public domain. A certifier, moreover, dedicates any copyright
|
||||||
|
interest he may have in the associated work, and for these purposes, is
|
||||||
|
described as a "dedicator" below.
|
||||||
|
|
||||||
|
A certifier has taken reasonable steps to verify the copyright status of this
|
||||||
|
work. Certifier recognizes that his good faith efforts may not shield him from
|
||||||
|
liability if in fact the work certified is not in the public domain.
|
||||||
|
|
||||||
|
Dedicator makes this dedication for the benefit of the public at large and to
|
||||||
|
the detriment of the Dedicator's heirs and successors. Dedicator intends this
|
||||||
|
dedication to be an overt act of relinquishment in perpetuate of all present
|
||||||
|
and future rights under copyright law, whether vested or contingent, in the
|
||||||
|
Work. Dedicator understands that such relinquishment of all rights includes
|
||||||
|
the relinquishment of all rights to enforce (by lawsuit or otherwise) those
|
||||||
|
copyrights in the Work.
|
||||||
|
|
||||||
|
Dedicator recognizes that, once placed in the public domain, the Work may be
|
||||||
|
freely reproduced, distributed, transmitted, used, modified, built upon, or
|
||||||
|
otherwise exploited by anyone for any purpose, commercial or non-commercial,
|
||||||
|
and in any way, including by methods that have not yet been invented or
|
||||||
|
conceived.
|
|
@ -361,7 +361,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
||||||
byteBuf.capacity(maxCapacity);
|
byteBuf.capacity(maxCapacity);
|
||||||
} else {
|
} else {
|
||||||
// Expand by the increment.
|
// Expand by the increment.
|
||||||
byteBuf.ensureWritableBytes(increment);
|
byteBuf.ensureWritable(increment);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -90,7 +90,7 @@ public abstract class AbstractOioByteChannel extends AbstractOioChannel {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (byteBuf.writable()) {
|
if (byteBuf.isWritable()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ public abstract class AbstractOioByteChannel extends AbstractOioChannel {
|
||||||
if (read) {
|
if (read) {
|
||||||
read = false;
|
read = false;
|
||||||
pipeline.fireInboundBufferUpdated();
|
pipeline.fireInboundBufferUpdated();
|
||||||
if (!byteBuf.writable()) {
|
if (!byteBuf.isWritable()) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"an inbound handler whose buffer is full must consume at " +
|
"an inbound handler whose buffer is full must consume at " +
|
||||||
"least one byte.");
|
"least one byte.");
|
||||||
|
@ -111,7 +111,7 @@ public abstract class AbstractOioByteChannel extends AbstractOioChannel {
|
||||||
if (writerIndex + available > maxCapacity) {
|
if (writerIndex + available > maxCapacity) {
|
||||||
byteBuf.capacity(maxCapacity);
|
byteBuf.capacity(maxCapacity);
|
||||||
} else {
|
} else {
|
||||||
byteBuf.ensureWritableBytes(available);
|
byteBuf.ensureWritable(available);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ public abstract class AbstractOioByteChannel extends AbstractOioChannel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doFlushByteBuffer(ByteBuf buf) throws Exception {
|
protected void doFlushByteBuffer(ByteBuf buf) throws Exception {
|
||||||
while (buf.readable()) {
|
while (buf.isReadable()) {
|
||||||
doWriteBytes(buf);
|
doWriteBytes(buf);
|
||||||
}
|
}
|
||||||
buf.clear();
|
buf.clear();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user