116 lines
1.8 KiB
C++
116 lines
1.8 KiB
C++
#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 );
|
|
}
|