#include "lexer.hpp" using namespace qxredis; Lexer::Lexer( QIODevice* device, QObject* parent ) : QObject ( parent ), m_device( device ), m_state ( DoingNothing ), m_crlf ( 0 ), m_length( 0 ) { connect( device, &QIODevice::readyRead, this, &Lexer::readData ); } void Lexer::readData() { m_buffer.append( m_device->readAll() ); while ( true ) { if ( ( m_state == DoingNothing ) && !readCharacter() ) { break; } switch ( m_state ) { case ReadingLength: case ReadingUnsafeString: if ( !readUnsafeString() ) { return; } break; case ReadingSafeString: if ( !readSafeString() ) { return; } break; case DoingNothing: break; } if ( m_state != ReadingSafeString ) { m_state = DoingNothing; } } } // Lexer::readData bool Lexer::readCharacter() { if ( m_buffer.isEmpty() ) { return( false ); } char c = m_buffer.at( 0 ); m_buffer.remove( 0, 1 ); switch ( c ) { case '+': case '-': case ':': case '*': m_state = ReadingUnsafeString; break; case '$': m_state = ReadingLength; break; } Q_EMIT character( c ); return( true ); } // Lexer::readCharacter bool Lexer::readUnsafeString() { m_crlf = m_buffer.indexOf( "\r\n", m_crlf ); if ( m_crlf == -1 ) { m_crlf = m_buffer.size(); return( false ); } QString s = m_buffer.mid( 0, m_crlf ); m_buffer.remove( 0, m_crlf + 2 ); if ( m_state == ReadingLength ) { m_length = s.toInt(); m_state = ReadingSafeString; } else { Q_EMIT unsafeString( s ); } m_crlf = 0; return( true ); } // Lexer::readUnsafeString bool Lexer::readSafeString() { if ( m_buffer.size() - m_length < 2 ) { return( false ); } QByteArray d = m_buffer.mid( 0, m_length ); m_buffer.remove( 0, m_length + 2 ); Q_EMIT safeString( d ); m_state = DoingNothing; return( true ); }