131 lines
2.1 KiB
C++
131 lines
2.1 KiB
C++
#ifndef MYX_REDIS_LEXER_INL_HPP_
|
|
#define MYX_REDIS_LEXER_INL_HPP_
|
|
|
|
#pragma once
|
|
|
|
#ifndef MYXLIB_HEADER_ONLY
|
|
#include <myx/redis/lexer.hpp>
|
|
#endif
|
|
|
|
namespace myx {
|
|
|
|
namespace redis {
|
|
|
|
MYXLIB_INLINE Lexer::Lexer( QIODevice* device, QObject* parent ) :
|
|
QObject ( parent ),
|
|
m_device( device ),
|
|
m_state ( kDoingNothing ),
|
|
m_crlf ( 0 ),
|
|
m_length( 0 )
|
|
{
|
|
connect( device, &QIODevice::readyRead, this, &Lexer::readData );
|
|
}
|
|
|
|
|
|
MYXLIB_INLINE void Lexer::readData()
|
|
{
|
|
m_buffer.append( m_device->readAll() );
|
|
|
|
while ( true )
|
|
{
|
|
if ( ( m_state == kDoingNothing ) && !readCharacter() )
|
|
{
|
|
break;
|
|
}
|
|
|
|
switch ( m_state )
|
|
{
|
|
case kReadingLength:
|
|
case kReadingUnsafeString:
|
|
if ( !readUnsafeString() ) { return; }
|
|
break;
|
|
case kReadingSafeString:
|
|
if ( !readSafeString() ) { return; }
|
|
break;
|
|
case kDoingNothing:
|
|
break;
|
|
}
|
|
|
|
if ( m_state != kReadingSafeString )
|
|
{
|
|
m_state = kDoingNothing;
|
|
}
|
|
}
|
|
} // Lexer::readData
|
|
|
|
|
|
MYXLIB_INLINE 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 = kReadingUnsafeString; break;
|
|
case '$':
|
|
m_state = kReadingLength; break;
|
|
}
|
|
|
|
Q_EMIT character( c );
|
|
return( true );
|
|
} // Lexer::readCharacter
|
|
|
|
|
|
MYXLIB_INLINE 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 == kReadingLength )
|
|
{
|
|
m_length = s.toInt();
|
|
m_state = kReadingSafeString;
|
|
}
|
|
else
|
|
{
|
|
Q_EMIT unsafeString( s );
|
|
}
|
|
|
|
m_crlf = 0;
|
|
return( true );
|
|
} // Lexer::readUnsafeString
|
|
|
|
|
|
MYXLIB_INLINE 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 = kDoingNothing;
|
|
return( true );
|
|
}
|
|
|
|
} // namespace redis
|
|
|
|
} // namespace myx
|
|
|
|
#endif // ifndef MYX_REDIS_LEXER_INL_HPP_
|