package io.netty.channel;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.util.UncheckedBooleanSupplier;
import java.util.AbstractMap;
import java.util.Map.Entry;
public class DefaultMaxBytesRecvByteBufAllocator implements MaxBytesRecvByteBufAllocator {
private volatile int maxBytesPerRead;
private volatile int maxBytesPerIndividualRead;
private final class HandleImpl implements ExtendedHandle {
private int individualReadMax;
private int bytesToRead;
private int lastBytesRead;
private int attemptBytesRead;
private final UncheckedBooleanSupplier defaultMaybeMoreSupplier = new UncheckedBooleanSupplier() {
@Override
public boolean get() {
return attemptBytesRead == lastBytesRead;
}
};
@Override
public ByteBuf allocate(ByteBufAllocator alloc) {
return alloc.ioBuffer(guess());
}
@Override
public int guess() {
return Math.min(individualReadMax, bytesToRead);
}
@Override
public void reset(ChannelConfig config) {
bytesToRead = maxBytesPerRead();
individualReadMax = maxBytesPerIndividualRead();
}
@Override
public void incMessagesRead(int amt) {
}
@Override
public void lastBytesRead(int bytes) {
lastBytesRead = bytes;
bytesToRead -= bytes;
}
@Override
public int lastBytesRead() {
return lastBytesRead;
}
@Override
public boolean continueReading() {
return continueReading(defaultMaybeMoreSupplier);
}
@Override
public boolean continueReading(UncheckedBooleanSupplier maybeMoreDataSupplier) {
return bytesToRead > 0 && maybeMoreDataSupplier.get();
}
@Override
public void readComplete() {
}
@Override
public void attemptedBytesRead(int bytes) {
attemptBytesRead = bytes;
}
@Override
public int attemptedBytesRead() {
return attemptBytesRead;
}
}
public DefaultMaxBytesRecvByteBufAllocator() {
this(64 * 1024, 64 * 1024);
}
public DefaultMaxBytesRecvByteBufAllocator(int maxBytesPerRead, int maxBytesPerIndividualRead) {
checkMaxBytesPerReadPair(maxBytesPerRead, maxBytesPerIndividualRead);
this.maxBytesPerRead = maxBytesPerRead;
this.maxBytesPerIndividualRead = maxBytesPerIndividualRead;
}
@SuppressWarnings("deprecation")
@Override
public Handle newHandle() {
return new HandleImpl();
}
@Override
public int maxBytesPerRead() {
return maxBytesPerRead;
}
@Override
public DefaultMaxBytesRecvByteBufAllocator maxBytesPerRead(int maxBytesPerRead) {
if (maxBytesPerRead <= 0) {
throw new IllegalArgumentException("maxBytesPerRead: " + maxBytesPerRead + " (expected: > 0)");
}
synchronized (this) {
final int maxBytesPerIndividualRead = maxBytesPerIndividualRead();
if (maxBytesPerRead < maxBytesPerIndividualRead) {
throw new IllegalArgumentException(
"maxBytesPerRead cannot be less than " +
"maxBytesPerIndividualRead (" + maxBytesPerIndividualRead + "): " + maxBytesPerRead);
}
this.maxBytesPerRead = maxBytesPerRead;
}
return this;
}
@Override
public int maxBytesPerIndividualRead() {
return maxBytesPerIndividualRead;
}
@Override
public DefaultMaxBytesRecvByteBufAllocator maxBytesPerIndividualRead(int maxBytesPerIndividualRead) {
if (maxBytesPerIndividualRead <= 0) {
throw new IllegalArgumentException(
"maxBytesPerIndividualRead: " + maxBytesPerIndividualRead + " (expected: > 0)");
}
synchronized (this) {
final int maxBytesPerRead = maxBytesPerRead();
if (maxBytesPerIndividualRead > maxBytesPerRead) {
throw new IllegalArgumentException(
"maxBytesPerIndividualRead cannot be greater than " +
"maxBytesPerRead (" + maxBytesPerRead + "): " + maxBytesPerIndividualRead);
}
this.maxBytesPerIndividualRead = maxBytesPerIndividualRead;
}
return this;
}
@Override
public synchronized Entry<Integer, Integer> maxBytesPerReadPair() {
return new AbstractMap.SimpleEntry<Integer, Integer>(maxBytesPerRead, maxBytesPerIndividualRead);
}
private static void checkMaxBytesPerReadPair(int maxBytesPerRead, int maxBytesPerIndividualRead) {
if (maxBytesPerRead <= 0) {
throw new IllegalArgumentException("maxBytesPerRead: " + maxBytesPerRead + " (expected: > 0)");
}
if (maxBytesPerIndividualRead <= 0) {
throw new IllegalArgumentException(
"maxBytesPerIndividualRead: " + maxBytesPerIndividualRead + " (expected: > 0)");
}
if (maxBytesPerRead < maxBytesPerIndividualRead) {
throw new IllegalArgumentException(
"maxBytesPerRead cannot be less than " +
"maxBytesPerIndividualRead (" + maxBytesPerIndividualRead + "): " + maxBytesPerRead);
}
}
@Override
public DefaultMaxBytesRecvByteBufAllocator maxBytesPerReadPair(int maxBytesPerRead,
int maxBytesPerIndividualRead) {
checkMaxBytesPerReadPair(maxBytesPerRead, maxBytesPerIndividualRead);
synchronized (this) {
this.maxBytesPerRead = maxBytesPerRead;
this.maxBytesPerIndividualRead = maxBytesPerIndividualRead;
}
return this;
}
}