92 lines
1.6 KiB
C++
92 lines
1.6 KiB
C++
#ifndef MYX_REDIS_PARSER_INL_HPP_
|
|
#define MYX_REDIS_PARSER_INL_HPP_
|
|
|
|
#pragma once
|
|
|
|
#ifndef MYXLIB_HEADER_ONLY
|
|
#include <myx/redis/parser.hpp>
|
|
#endif
|
|
|
|
namespace myx {
|
|
|
|
namespace redis {
|
|
|
|
Parser::Parser( Lexer* lexer, QObject* parent ) :
|
|
QObject( parent )
|
|
{
|
|
connect( lexer, &Lexer::character, this, &Parser::readCharacter );
|
|
connect( lexer, &Lexer::unsafeString, this, &Parser::readUnsafeString );
|
|
connect( lexer, &Lexer::safeString, this, &Parser::readSafeString );
|
|
}
|
|
|
|
|
|
void Parser::readCharacter( const char c )
|
|
{
|
|
switch ( c )
|
|
{
|
|
case '+':
|
|
stack.append( Task( Reply::Status ) ); break;
|
|
case '-':
|
|
stack.append( Task( Reply::Error ) ); break;
|
|
case ':':
|
|
stack.append( Task( Reply::Integer ) ); break;
|
|
case '$':
|
|
stack.append( Task( Reply::Bulk ) ); break;
|
|
case '*':
|
|
stack.append( Task( Reply::MultiBulk ) ); break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void Parser::readUnsafeString( const QString& value )
|
|
{
|
|
if ( tos().reply.type() == Reply::MultiBulk )
|
|
{
|
|
tos().count = value.toInt();
|
|
}
|
|
else
|
|
{
|
|
tos().reply.value() = value;
|
|
}
|
|
|
|
descend();
|
|
}
|
|
|
|
|
|
void Parser::readSafeString( const QByteArray& value )
|
|
{
|
|
tos().reply.value() = value;
|
|
descend();
|
|
}
|
|
|
|
|
|
void Parser::descend()
|
|
{
|
|
while ( true )
|
|
{
|
|
if ( ( tos().reply.type() == Reply::MultiBulk ) &&
|
|
( tos().reply.value().toList().count() < tos().count ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( stack.count() == 1 )
|
|
{
|
|
auto r = stack.takeLast().reply;
|
|
Q_EMIT reply( r );
|
|
return;
|
|
}
|
|
|
|
auto r = stack.takeLast().reply;
|
|
tos().reply.value().toList().append( QVariant::fromValue( r ) );
|
|
}
|
|
}
|
|
|
|
} // namespace redis
|
|
|
|
} // namespace myx
|
|
|
|
#endif // ifndef MYX_REDIS_PARSER_INL_HPP_
|