in sshd-sftp/src/main/java/org/apache/sshd/sftp/client/impl/SftpInputStreamAsync.java [269:342]
protected boolean fillData() throws IOException {
SftpAckData ack = pendingReads.pollFirst();
boolean traceEnabled = log.isTraceEnabled();
boolean debugEnabled = log.isDebugEnabled();
if (ack == null) {
if (traceEnabled) {
log.trace("fillData({}) no pending ack", this);
}
return false;
}
if (traceEnabled) {
log.trace("fillData({}) process ack={}", this, ack);
}
boolean alreadyEof = eofIndicator;
pollBuffer(ack);
if (!alreadyEof && clientOffset < ack.offset) {
shortReads++;
// We are missing some data: request it synchronously to fill the gap.
int nb = (int) (ack.offset - clientOffset);
byte[] data = new byte[nb + buffer.available()];
if (traceEnabled) {
log.trace("fillData({}) reading {} bytes", this, nb);
}
AtomicReference<Boolean> eof = new AtomicReference<>();
SftpClient client = getClient();
int cur = 0;
while (cur < nb) {
int dlen = client.read(handle, clientOffset + cur, data, cur, nb - cur, eof);
if (dlen > 0) {
cur += dlen;
}
Boolean eofSignal = eof.getAndSet(null);
if ((dlen < 0) || ((eofSignal != null) && eofSignal.booleanValue())) {
eofIndicator = true;
break;
}
}
if (debugEnabled) {
log.debug("fillData({}) read {} of {} bytes - EOF={}", this, cur, nb, eofIndicator);
}
if (cur == 0) {
// Got no data but an EOF. File got shorter? Prepare an empty buffer.
buffer.rpos(buffer.wpos());
} else if (cur < nb) {
// Could not fill the gap, got an EOF. Use just the data we got now.
buffer = new ByteArrayBuffer(data, 0, cur);
} else {
// cur == nb: Gap filled.
buffer.getRawBytes(data, cur, buffer.available());
buffer = new ByteArrayBuffer(data);
}
if (!eofIndicator && !bufferAdjusted) {
int newBufferSize = adjustBufferIfNeeded(bufferSize, shortReads, maxReceived, ack.offset - clientOffset);
if (newBufferSize > 0 && newBufferSize < bufferSize) {
int originalSize = bufferSize;
bufferSize = newBufferSize;
bufferAdjusted = true;
if (debugEnabled) {
log.debug("adjustBufferIfNeeded({}) changing SFTP buffer size: {} -> {}", this, originalSize,
bufferSize);
}
} else if (newBufferSize > bufferSize) {
throw new IllegalStateException("New buffer size " + newBufferSize + " > existing size " + bufferSize);
}
}
return !pendingReads.isEmpty();
}
return false;
}