myxlib/src/myx/redis/parser-inl.hpp

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_