[#540] Add a variant of ByteBuf.ensureWritableBytes() which does not throw an exception
This commit is contained in:
parent
aa8a761fe2
commit
df0aee22cb
@ -176,17 +176,17 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||
|
||||
@Override
|
||||
public void ensureWritableBytes(int minWritableBytes) {
|
||||
if (minWritableBytes <= writableBytes()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (minWritableBytes < 0) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"minWritableBytes: %d (expected: >= 0)", minWritableBytes));
|
||||
}
|
||||
|
||||
if (minWritableBytes <= writableBytes()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (minWritableBytes > maxCapacity - writerIndex) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
throw new IndexOutOfBoundsException(String.format(
|
||||
"writerIndex(%d) + minWritableBytes(%d) exceeds maxCapacity(%d)",
|
||||
writerIndex, minWritableBytes, maxCapacity));
|
||||
}
|
||||
@ -198,6 +198,36 @@ public abstract class AbstractByteBuf implements ByteBuf {
|
||||
capacity(newCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ensureWritableBytes(int minWritableBytes, boolean force) {
|
||||
if (minWritableBytes < 0) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"minWritableBytes: %d (expected: >= 0)", minWritableBytes));
|
||||
}
|
||||
|
||||
if (minWritableBytes <= writableBytes()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (minWritableBytes > maxCapacity - writerIndex) {
|
||||
if (force) {
|
||||
if (capacity() == maxCapacity()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
capacity(maxCapacity());
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize the current capacity to the power of 2.
|
||||
int newCapacity = calculateNewCapacity(writerIndex + minWritableBytes);
|
||||
|
||||
// Adjust to the new capacity.
|
||||
capacity(newCapacity);
|
||||
return 2;
|
||||
}
|
||||
|
||||
private int calculateNewCapacity(int minNewCapacity) {
|
||||
final int maxCapacity = this.maxCapacity;
|
||||
final int threshold = 1048576 * 4; // 4 MiB page
|
||||
|
@ -443,23 +443,35 @@ public interface ByteBuf extends ChannelBuf, Comparable<ByteBuf> {
|
||||
* Makes sure the number of {@linkplain #writableBytes() the writable bytes}
|
||||
* is equal to or greater than the specified value. If there is enough
|
||||
* writable bytes in this buffer, this method returns with no side effect.
|
||||
* Otherwise:
|
||||
* <ul>
|
||||
* <li>a non-dynamic buffer will throw an {@link IndexOutOfBoundsException}.</li>
|
||||
* <li>a dynamic buffer will expand its capacity so that the number of the
|
||||
* {@link #writableBytes() writable bytes} becomes equal to or greater
|
||||
* than the specified value. The expansion involves the reallocation of
|
||||
* the internal buffer and consequently memory copy.</li>
|
||||
* </ul>
|
||||
* Otherwise, it raises an {@link IllegalArgumentException}.
|
||||
*
|
||||
* @param writableBytes
|
||||
* @param minWritableBytes
|
||||
* the expected minimum number of writable bytes
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@linkplain #writableBytes() the writable bytes} of this
|
||||
* buffer is less than the specified value and if this buffer is
|
||||
* not a dynamic buffer
|
||||
* if {@link #writerIndex()} + {@code minWritableBytes} > {@link #maxCapacity()}
|
||||
*/
|
||||
void ensureWritableBytes(int writableBytes);
|
||||
void ensureWritableBytes(int minWritableBytes);
|
||||
|
||||
/**
|
||||
* 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)},
|
||||
* this method does not raise an exception but returns a code.
|
||||
*
|
||||
* @param minWritableBytes
|
||||
* the expected minimum number of writable bytes
|
||||
* @param force
|
||||
* When {@link #writerIndex()} + {@code minWritableBytes} > {@link #maxCapacity()}:
|
||||
* <ul>
|
||||
* <li>{@code true} - the capacity of the buffer is expanded to {@link #maxCapacity()}</li>
|
||||
* <li>{@code false} - the capacity of the buffer is unchanged</li>
|
||||
* </ul>
|
||||
* @return {@code 0} if the buffer has enough writable bytes, and its capacity is unchanged.
|
||||
* {@code 1} if the buffer does not have enough bytes, and its capacity is unchanged.
|
||||
* {@code 2} if the buffer has enough writable bytes, and its capacity has been increased.
|
||||
* {@code 3} if the buffer does not have enough bytes, but its capacity has been
|
||||
* increased to its maximum.
|
||||
*/
|
||||
int ensureWritableBytes(int minWritableBytes, boolean force);
|
||||
|
||||
/**
|
||||
* Gets a boolean at the specified absolute (@code index) in this buffer.
|
||||
|
@ -172,6 +172,11 @@ public class SwappedByteBuf implements WrappedByteBuf {
|
||||
buf.ensureWritableBytes(writableBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ensureWritableBytes(int minWritableBytes, boolean force) {
|
||||
return buf.ensureWritableBytes(minWritableBytes, force);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(int index) {
|
||||
return buf.getBoolean(index);
|
||||
|
@ -139,6 +139,11 @@ class ReplayingDecoderBuffer implements ByteBuf {
|
||||
throw new UnreplayableOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ensureWritableBytes(int minWritableBytes, boolean force) {
|
||||
throw new UnreplayableOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf duplicate() {
|
||||
throw new UnreplayableOperationException();
|
||||
|
Loading…
Reference in New Issue
Block a user