in protonj2/src/main/java/org/apache/qpid/protonj2/buffer/impl/ProtonCompositeBufferImpl.java [556:611]
public ProtonCompositeBuffer ensureWritable(int size, int minimumGrowth, boolean allowCompaction) throws IndexOutOfBoundsException, IllegalArgumentException {
if (isClosed()) {
throw ProtonBufferUtils.genericBufferIsClosed(this);
}
ProtonBufferUtils.checkIsNotNegative(size, "New writable size value cannot be negative");
ProtonBufferUtils.checkIsNotNegative(minimumGrowth, "Minimum growth value cannot be negative");
if (isReadOnly()) {
throw ProtonBufferUtils.genericBufferIsReadOnly(this);
}
if (getWritableBytes() >= size) {
return this;
}
if (allowCompaction && readOffset >= size) {
if (buffers.length == 1) {
final ProtonBuffer target = buffers[0];
target.compact();
readOffset = target.getReadOffset();
writeOffset = target.getWriteOffset();
} else {
int compacted = 0;
for (int i = 0; i < buffers.length; ++i) {
final ProtonBuffer current = buffers[i];
if (current.getReadableBytes() == current.capacity()) {
compacted++;
// Buffer is now fully writable so reset the offsets
current.clear();
continue;
} else {
break;
}
}
if (compacted > 0) {
ProtonBuffer[] compactedSet = new ProtonBuffer[compacted];
// Retain the front buffers that are going to the end
System.arraycopy(buffers, 0, compactedSet, 0, compacted);
// Move the rest down
System.arraycopy(buffers, compacted, buffers, 0, buffers.length - compacted);
// Placed the compacted buffers at the tail
System.arraycopy(compactedSet, 0, buffers, compacted, compacted);
recomputeChunkIndexValues();
}
}
}
if (getWritableBytes() < size) {
final int allocate = Math.max(size - getWritableBytes(), minimumGrowth);
ProtonBufferUtils.checkBufferCanGrowTo(capacity(), allocate);
appendBuffer(allocator.allocate(allocate));
}
return this;
}