private void unwrapInput()

in proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SimpleSslTransportWrapper.java [107:206]


    private void unwrapInput() throws SSLException
    {
        int prevInRemaining = -1;
        while (true) {
            SSLEngineResult result = _sslEngine.unwrap(_inputBuffer, _decodedInputBuffer);
            logEngineClientModeAndResult(result, "input");

            int read = result.bytesProduced();
            Status status = result.getStatus();
            HandshakeStatus hstatus = result.getHandshakeStatus();

            int capacity = _underlyingInput.capacity();
            if (capacity == Transport.END_OF_STREAM || capacity <= 0) {
                _tail_closed = true;
                if (_decodedInputBuffer.position() > 0) {
                    throw new TransportException("bytes left unconsumed");
                }
            } else {
                _decodedInputBuffer.flip();

                while (_decodedInputBuffer.hasRemaining() && capacity > 0) {
                    ByteBuffer tail = _underlyingInput.tail();
                    int limit = _decodedInputBuffer.limit();
                    int overflow = _decodedInputBuffer.remaining() - capacity;
                    if (overflow > 0) {
                        _decodedInputBuffer.limit(limit - overflow);
                    }
                    tail.put(_decodedInputBuffer);
                    _decodedInputBuffer.limit(limit);
                    _underlyingInput.process();
                    capacity = _underlyingInput.capacity();
                }

                if (capacity == Transport.END_OF_STREAM || capacity <= 0) {
                    _tail_closed = true;
                    if (_decodedInputBuffer.hasRemaining()) {
                        throw new TransportException("bytes left unconsumed");
                    }
                }

                _decodedInputBuffer.compact();
            }

            switch (status) {
            case CLOSED:
                _tail_closed = true;
                break;
            case BUFFER_OVERFLOW:
                {
                    ByteBuffer old = _decodedInputBuffer;
                    _decodedInputBuffer = newWriteableBuffer(old.capacity()*2);
                    old.flip();
                    _decodedInputBuffer.put(old);
                }
                continue;
            case BUFFER_UNDERFLOW:
                if (_tail_closed) {
                    _head_closed = true;
                }
                // wait for more data
                break;
            case OK:
                break;
            }

            switch (hstatus)
            {
            case NEED_WRAP:
                int inputRemaining = _inputBuffer.remaining();
                if (inputRemaining > 0 && status == Status.OK && (inputRemaining < prevInRemaining || prevInRemaining < 0)) {
                    // Track remaining input so we break if no progress is made.
                    prevInRemaining = inputRemaining;
                    // Process a wrap, try to progress on the remaining input.
                    pending();
                    continue;
                }
                // wait for write to kick in
                break;
            case NEED_TASK:
                runDelegatedTasks(result);
                continue;
            case FINISHED:
                updateCipherAndProtocolName(result);
            case NOT_HANDSHAKING:
            case NEED_UNWRAP:
                if (_inputBuffer.position() > 0 && status == Status.OK) {
                    continue;
                } else {
                    if (_inputBuffer.position() == 0 &&
                        hstatus == HandshakeStatus.NEED_UNWRAP &&
                        _tail_closed) {
                        _head_closed = true;
                    }
                    break;
                }
            }

            break;
        }
    }