protected boolean fillData()

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;
    }