src/main/java/org/michailov/async/io/AsyncCharDecoder.java
private void decodeFromMainBuffer() {
        // Take a snapshot of the real buffers.
        int readPosition = _byteRingBuffer.getReadPosition();
        int readStraight = _byteRingBuffer.getAvailableToReadStraight();
        int writePosition = _charRingBuffer.getWritePosition();
        int writeStraight = _charRingBuffer.getAvailableToWriteStraight();

        // Map the virtual decoder buffers over the native buffers. 
        _mainByteBuffer.position(readPosition);
        _mainByteBuffer.limit(readPosition + readStraight);
        _mainCharBuffer.position(writePosition);
        _mainCharBuffer.limit(writePosition + writeStraight);
        
        // Attempt to decode.
        _charsetDecoder.reset();
        CoderResult coderResult = _charsetDecoder.decode(_mainByteBuffer, _mainCharBuffer, DECODE_AS_EOF);
        
        // Advance positions of physical buffers based on the state of the virtual buffers.
        int newReadPosition = _mainByteBuffer.position();
        int readDelta = newReadPosition - readPosition;
        if (readDelta > 0) {
            _byteRingBuffer.advanceReadPosition(readDelta);
        }
        
        int newWritePosition = _mainCharBuffer.position();
        int writeDelta = newWritePosition - writePosition;
        if (writeDelta > 0) {
            _charRingBuffer.advanceWritePosition(writeDelta);
        }
        
        // If input was malformed AND this is the physical end of the main buffer,
        // decoding must transition to the temp buffer.
        if (coderResult.isMalformed() && (_mainByteBuffer.limit() == _mainByteBuffer.capacity())) {
            // The temp buffer must be initialized exactly once.
            // Therefore, it can't be done in the loop. It must be done here.

            // Copy the undecoded remainder to the temp buffer.
            int remainder = _mainByteBuffer.limit() - newReadPosition;
            _tempByteBuffer.position(0);
            _tempByteBuffer.limit(_tempByteBuffer.capacity());
            _tempByteBuffer.put(_mainByteBuffer.array(), newReadPosition, remainder);
            
            // Advance the real byte ring buffer's read position because 
            // the remainder wasn't counted towards the read delta. 
            _byteRingBuffer.advanceReadPosition(remainder);
            
            // Reset the temp buffer positions.
            _tempByteBuffer.position(0);
            _tempByteBuffer.limit(remainder);

            // Transition to temp buffer.
            _isTempBufferDirty = true;
        }
        // If it is hopeless to make progress due to a stale remainder, complete. 
        else if (readDelta == 0 && _byteRingBuffer.isEOF() && _byteRingBuffer.getAvailableToReadStraight() == readStraight) {
            setEOF();
        }
    }
/**
     * Attempts to decode bytes from the main buffer.
     */
Attempts to decode bytes from the main buffer.
Attempts to decode bytes from the main buffer .
private void decodeFromMainBuffer() {
        int readPosition = _byteRingBuffer.getReadPosition();
        int readStraight = _byteRingBuffer.getAvailableToReadStraight();
        int writePosition = _charRingBuffer.getWritePosition();
        int writeStraight = _charRingBuffer.getAvailableToWriteStraight();
        _mainByteBuffer.position(readPosition);
        _mainByteBuffer.limit(readPosition + readStraight);
        _mainCharBuffer.position(writePosition);
        _mainCharBuffer.limit(writePosition + writeStraight);
        _charsetDecoder.reset();
        CoderResult coderResult = _charsetDecoder.decode(_mainByteBuffer, _mainCharBuffer, DECODE_AS_EOF);
        int newReadPosition = _mainByteBuffer.position();
        int readDelta = newReadPosition - readPosition;
        if (readDelta > 0) {
            _byteRingBuffer.advanceReadPosition(readDelta);
        }
        int newWritePosition = _mainCharBuffer.position();
        int writeDelta = newWritePosition - writePosition;
        if (writeDelta > 0) {
            _charRingBuffer.advanceWritePosition(writeDelta);
        }
        if (coderResult.isMalformed() && (_mainByteBuffer.limit() == _mainByteBuffer.capacity())) {
            int remainder = _mainByteBuffer.limit() - newReadPosition;
            _tempByteBuffer.position(0);
            _tempByteBuffer.limit(_tempByteBuffer.capacity());
            _tempByteBuffer.put(_mainByteBuffer.array(), newReadPosition, remainder);
            _byteRingBuffer.advanceReadPosition(remainder);
            _tempByteBuffer.position(0);
            _tempByteBuffer.limit(remainder);
            _isTempBufferDirty = true;
        }
        else if (readDelta == 0 && _byteRingBuffer.isEOF() && _byteRingBuffer.getAvailableToReadStraight() == readStraight) {
            setEOF();
        }
    }
private void decodeFromMainBuffer ( ) { int readPosition = _byteRingBuffer . getReadPosition ( ) ; int readStraight = _byteRingBuffer . getAvailableToReadStraight ( ) ; int writePosition = _charRingBuffer . getWritePosition ( ) ; int writeStraight = _charRingBuffer . getAvailableToWriteStraight ( ) ; _mainByteBuffer . position ( readPosition ) ; _mainByteBuffer . limit ( readPosition + readStraight ) ; _mainCharBuffer . position ( writePosition ) ; _mainCharBuffer . limit ( writePosition + writeStraight ) ; _charsetDecoder . reset ( ) ; CoderResult coderResult = _charsetDecoder . decode ( _mainByteBuffer , _mainCharBuffer , DECODE_AS_EOF ) ; int newReadPosition = _mainByteBuffer . position ( ) ; int readDelta = newReadPosition - readPosition ; if ( readDelta > 0 ) { _byteRingBuffer . advanceReadPosition ( readDelta ) ; } int newWritePosition = _mainCharBuffer . position ( ) ; int writeDelta = newWritePosition - writePosition ; if ( writeDelta > 0 ) { _charRingBuffer . advanceWritePosition ( writeDelta ) ; } if ( coderResult . isMalformed ( ) && ( _mainByteBuffer . limit ( ) == _mainByteBuffer . capacity ( ) ) ) { int remainder = _mainByteBuffer . limit ( ) - newReadPosition ; _tempByteBuffer . position ( 0 ) ; _tempByteBuffer . limit ( _tempByteBuffer . capacity ( ) ) ; _tempByteBuffer . put ( _mainByteBuffer . array ( ) , newReadPosition , remainder ) ; _byteRingBuffer . advanceReadPosition ( remainder ) ; _tempByteBuffer . position ( 0 ) ; _tempByteBuffer . limit ( remainder ) ; _isTempBufferDirty = true ; } else if ( readDelta == 0 && _byteRingBuffer . isEOF ( ) && _byteRingBuffer . getAvailableToReadStraight ( ) == readStraight ) { setEOF ( ) ; } }
Attempts to decode bytes from the main buffer.
Attempts to decode bytes from the main buffer .
// Take a snapshot of the real buffers.
 // Map the virtual decoder buffers over the native buffers. 
 // Attempt to decode.
 // Advance positions of physical buffers based on the state of the virtual buffers.
 // If input was malformed AND this is the physical end of the main buffer,
 // decoding must transition to the temp buffer.
 // The temp buffer must be initialized exactly once.
 // Therefore, it can't be done in the loop. It must be done here.
 // Copy the undecoded remainder to the temp buffer.
 // Advance the real byte ring buffer's read position because 
 // the remainder wasn't counted towards the read delta. 
 // Reset the temp buffer positions.
 // Transition to temp buffer.
 // If it is hopeless to make progress due to a stale remainder, complete. 
