Рефакторинг библиотеки для Redis
This commit is contained in:
parent
aa1f06b306
commit
8d9a5590d7
@ -44,7 +44,7 @@ add_subdirectory(src/myx/base)
|
||||
add_subdirectory(src/myx/filesystem)
|
||||
add_subdirectory(src/myx/qt)
|
||||
add_subdirectory(src/myx/math)
|
||||
# add_subdirectory(src/myx/redis)
|
||||
add_subdirectory(src/myx/redis)
|
||||
|
||||
# Примеры
|
||||
if(MYXLIB_BUILD_EXAMPLES OR MYXLIB_BUILD_EXAMPLES_HO)
|
||||
|
@ -5,7 +5,6 @@ set(TRGT redis)
|
||||
# Список файлов исходных текстов
|
||||
set(TRGT_cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/client.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/config.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lexer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/parser.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/request.cpp)
|
||||
@ -13,13 +12,18 @@ set(TRGT_cpp
|
||||
# Список заголовочных файлов (используется для установки)
|
||||
set(TRGT_moc_hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/client.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/config.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lexer.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/parser.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/reply.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/request.hpp)
|
||||
|
||||
set(TRGT_headers ${TRGT_hpp})
|
||||
set(TRGT_hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/client-inl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lexer-inl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/parser-inl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/request-inl.hpp)
|
||||
|
||||
set(TRGT_headers ${TRGT_moc_hpp} ${TRGT_hpp})
|
||||
# cmake-format: on
|
||||
|
||||
add_library(${TRGT}-header-only INTERFACE)
|
||||
|
82
src/myx/redis/client-inl.hpp
Normal file
82
src/myx/redis/client-inl.hpp
Normal file
@ -0,0 +1,82 @@
|
||||
#ifndef MYX_REDIS_CLIENT_INL_HPP_
|
||||
#define MYX_REDIS_CLIENT_INL_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/redis/client.hpp>
|
||||
#endif
|
||||
|
||||
#include <myx/redis/client_p.hpp>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace redis {
|
||||
|
||||
ClientPrivate::ClientPrivate( Client* client ) :
|
||||
lexer ( &socket ),
|
||||
parser( &lexer )
|
||||
{
|
||||
connect( &socket, &QTcpSocket::connected, client, &Client::connected );
|
||||
connect( &socket, &QTcpSocket::disconnected, client, &Client::disconnected );
|
||||
connect( &parser, &Parser::reply, this, &ClientPrivate::sendReply );
|
||||
}
|
||||
|
||||
|
||||
void ClientPrivate::sendReply( const Reply& reply )
|
||||
{
|
||||
Q_EMIT queue.dequeue()->reply( reply );
|
||||
}
|
||||
|
||||
|
||||
Client::Client( QObject* parent ) :
|
||||
QObject( parent ),
|
||||
d ( new ClientPrivate( this ) )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Client::connectToHost( const QString& hostName, quint16 port )
|
||||
{
|
||||
d->socket.connectToHost( hostName, port );
|
||||
}
|
||||
|
||||
|
||||
void Client::disconnectFromHost()
|
||||
{
|
||||
d->socket.disconnectFromHost();
|
||||
}
|
||||
|
||||
|
||||
bool Client::isConnected() const
|
||||
{
|
||||
return( d->socket.state() == QAbstractSocket::ConnectedState );
|
||||
}
|
||||
|
||||
|
||||
Request* Client::sendCommand( const QByteArray& command )
|
||||
{
|
||||
d->socket.write( command + "\r\n" );
|
||||
|
||||
auto* request = new Request( this );
|
||||
d->queue.enqueue( request );
|
||||
return( request );
|
||||
}
|
||||
|
||||
|
||||
bool Client::waitForConnected( int msecs )
|
||||
{
|
||||
return( d->socket.waitForConnected( msecs ) );
|
||||
}
|
||||
|
||||
|
||||
bool Client::waitForDisconnected( int msecs )
|
||||
{
|
||||
return( d->socket.waitForDisconnected( msecs ) );
|
||||
}
|
||||
|
||||
} // namespace redis
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // ifndef MYX_REDIS_CLIENT_INL_HPP_
|
@ -1,72 +1,5 @@
|
||||
#include <client.hpp>
|
||||
#include <client_p.hpp>
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#endif
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace redis {
|
||||
|
||||
ClientPrivate::ClientPrivate( Client* client ) :
|
||||
lexer ( &socket ),
|
||||
parser( &lexer )
|
||||
{
|
||||
connect( &socket, &QTcpSocket::connected, client, &Client::connected );
|
||||
connect( &socket, &QTcpSocket::disconnected, client, &Client::disconnected );
|
||||
connect( &parser, &Parser::reply, this, &ClientPrivate::sendReply );
|
||||
}
|
||||
|
||||
|
||||
void ClientPrivate::sendReply( const Reply& reply )
|
||||
{
|
||||
Q_EMIT queue.dequeue()->reply( reply );
|
||||
}
|
||||
|
||||
|
||||
Client::Client( QObject* parent ) :
|
||||
QObject( parent ),
|
||||
d ( new ClientPrivate( this ) )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Client::connectToHost( const QString& hostName, quint16 port )
|
||||
{
|
||||
d->socket.connectToHost( hostName, port );
|
||||
}
|
||||
|
||||
|
||||
void Client::disconnectFromHost()
|
||||
{
|
||||
d->socket.disconnectFromHost();
|
||||
}
|
||||
|
||||
|
||||
bool Client::isConnected() const
|
||||
{
|
||||
return( d->socket.state() == QAbstractSocket::ConnectedState );
|
||||
}
|
||||
|
||||
|
||||
Request* Client::sendCommand( const QByteArray& command )
|
||||
{
|
||||
d->socket.write( command + "\r\n" );
|
||||
|
||||
auto* request = new Request( this );
|
||||
d->queue.enqueue( request );
|
||||
return( request );
|
||||
}
|
||||
|
||||
|
||||
bool Client::waitForConnected( int msecs )
|
||||
{
|
||||
return( d->socket.waitForConnected( msecs ) );
|
||||
}
|
||||
|
||||
|
||||
bool Client::waitForDisconnected( int msecs )
|
||||
{
|
||||
return( d->socket.waitForDisconnected( msecs ) );
|
||||
}
|
||||
|
||||
} // namespace redis
|
||||
|
||||
} // namespace myx
|
||||
#include <myx/redis/client-inl.hpp>
|
||||
|
@ -1,22 +1,24 @@
|
||||
#ifndef MYX_REDIS_CLIENT_HPP_
|
||||
#define MYX_REDIS_CLIENT_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
#include <myx/redis/request.hpp>
|
||||
|
||||
#include <QObject>
|
||||
#include <QScopedPointer>
|
||||
|
||||
#include <config.hpp>
|
||||
#include <request.hpp>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace redis {
|
||||
|
||||
class MYX_REDIS_EXPORT ClientPrivate;
|
||||
QT_FORWARD_DECLARE_CLASS( ClientPrivate )
|
||||
|
||||
/**
|
||||
* @brief Provides access to a Redis server
|
||||
*/
|
||||
class MYX_REDIS_EXPORT Client : public QObject
|
||||
class Client : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -104,10 +106,15 @@ public:
|
||||
private:
|
||||
|
||||
const QScopedPointer< ClientPrivate > d;
|
||||
}; // class MYX_REDIS_EXPORT
|
||||
}; // class Client
|
||||
|
||||
} // namespace redis
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "client-inl.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
#endif // MYX_REDIS_CLIENT_HPP_
|
||||
|
@ -1 +0,0 @@
|
||||
#include "config.hpp"
|
@ -1,14 +0,0 @@
|
||||
#ifndef MYX_REDIS_CONFIG_HPP_
|
||||
#define MYX_REDIS_CONFIG_HPP_
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
// #if defined( qredis_EXPORTS )
|
||||
#define MYX_REDIS_EXPORT Q_DECL_EXPORT
|
||||
// #else
|
||||
// #define MYX_REDIS_EXPORT Q_DECL_IMPORT
|
||||
// #endif
|
||||
|
||||
// #include <myx/base/config_flags.hpp>
|
||||
|
||||
#endif // MYX_REDIS_CONFIG_HPP_
|
@ -1,6 +0,0 @@
|
||||
#ifndef @CMLIB_PROJECT_NAME_CANONICAL@_CONFIG_FLAGS_HPP_
|
||||
#define @CMLIB_PROJECT_NAME_CANONICAL@_CONFIG_FLAGS_HPP_
|
||||
|
||||
// #cmakedefine
|
||||
|
||||
#endif /* @CMLIB_PROJECT_NAME_CANONICAL@_CONFIG_FLAGS_HPP_ */
|
130
src/myx/redis/lexer-inl.hpp
Normal file
130
src/myx/redis/lexer-inl.hpp
Normal file
@ -0,0 +1,130 @@
|
||||
#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 {
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
} // namespace redis
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // ifndef MYX_REDIS_LEXER_INL_HPP_
|
@ -1,121 +1,5 @@
|
||||
#include "lexer.hpp"
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#endif
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace redis {
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
} // namespace redis
|
||||
|
||||
} // namespace myx
|
||||
#include <myx/redis/lexer-inl.hpp>
|
||||
|
@ -1,8 +1,11 @@
|
||||
#ifndef MYX_REDIS_LEXER_HPP_
|
||||
#define MYX_REDIS_LEXER_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
|
||||
#include <QIODevice>
|
||||
#include <QObject>
|
||||
|
||||
namespace myx {
|
||||
|
||||
@ -51,4 +54,9 @@ private:
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "lexer-inl.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
#endif // MYX_REDIS_LEXER_HPP_
|
||||
|
91
src/myx/redis/parser-inl.hpp
Normal file
91
src/myx/redis/parser-inl.hpp
Normal file
@ -0,0 +1,91 @@
|
||||
#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_
|
@ -1,82 +1,5 @@
|
||||
#include "parser.hpp"
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#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
|
||||
#include <myx/redis/parser-inl.hpp>
|
||||
|
@ -1,14 +1,16 @@
|
||||
#ifndef MYX_REDIS_PARSER_HPP_
|
||||
#define MYX_REDIS_PARSER_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
#include <myx/redis/reply.hpp>
|
||||
#include <myx/redis/lexer.hpp>
|
||||
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
#include <QPair>
|
||||
#include <QVariant>
|
||||
|
||||
#include <reply.hpp>
|
||||
#include <lexer.hpp>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace redis {
|
||||
@ -54,4 +56,8 @@ public:
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "parser-inl.hpp"
|
||||
#endif
|
||||
|
||||
#endif // MYX_REDIS_PARSER_HPP_
|
||||
|
@ -1,9 +1,11 @@
|
||||
#ifndef MYX_REDIS_REPLY_HPP_
|
||||
#define MYX_REDIS_REPLY_HPP_
|
||||
|
||||
#include <QVariant>
|
||||
#pragma once
|
||||
|
||||
#include <config.hpp>
|
||||
#include <myx/base/config.hpp>
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
namespace myx {
|
||||
|
||||
@ -12,7 +14,7 @@ namespace redis {
|
||||
/**
|
||||
* @brief Represents a Redis reply
|
||||
*/
|
||||
class MYX_REDIS_EXPORT Reply
|
||||
class Reply
|
||||
{
|
||||
public:
|
||||
|
||||
|
53
src/myx/redis/request-inl.hpp
Normal file
53
src/myx/redis/request-inl.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef MYX_REDIS_REQUEST_INL_HPP_
|
||||
#define MYX_REDIS_REQUEST_INL_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/redis/request.hpp>
|
||||
#endif
|
||||
#include <myx/redis/request_p.hpp>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace redis {
|
||||
|
||||
void RequestPrivate::quitEventLoop()
|
||||
{
|
||||
loop.exit( 1 );
|
||||
}
|
||||
|
||||
|
||||
Request::Request( QObject* parent ) :
|
||||
QObject( parent ),
|
||||
d ( new RequestPrivate )
|
||||
{
|
||||
connect( this, &Request::reply, this, &Request::deleteLater );
|
||||
}
|
||||
|
||||
|
||||
bool Request::waitForReply( int msecs )
|
||||
{
|
||||
QTimer timer;
|
||||
timer.setInterval( msecs );
|
||||
timer.setSingleShot( true );
|
||||
|
||||
connect( &timer, &QTimer::timeout, &d->loop, &QEventLoop::quit );
|
||||
connect( this, &Request::reply, d.data(), &RequestPrivate::quitEventLoop );
|
||||
|
||||
/*
|
||||
* If the timer fires, the return value will be 0.
|
||||
* Otherwise, quitEventLoop() will terminate the loop with 1.
|
||||
*/
|
||||
return( ( d->loop.exec( QEventLoop::ExcludeUserInputEvents ) != 0 ) );
|
||||
}
|
||||
|
||||
} // namespace redis
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // ifndef MYX_REDIS_REQUEST_INL_HPP_
|
@ -1,42 +1,5 @@
|
||||
#include <QTimer>
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#endif
|
||||
|
||||
#include <request.hpp>
|
||||
#include <request_p.hpp>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace redis {
|
||||
|
||||
void RequestPrivate::quitEventLoop()
|
||||
{
|
||||
loop.exit( 1 );
|
||||
}
|
||||
|
||||
|
||||
Request::Request( QObject* parent ) :
|
||||
QObject( parent ),
|
||||
d ( new RequestPrivate )
|
||||
{
|
||||
connect( this, &Request::reply, this, &Request::deleteLater );
|
||||
}
|
||||
|
||||
|
||||
bool Request::waitForReply( int msecs )
|
||||
{
|
||||
QTimer timer;
|
||||
timer.setInterval( msecs );
|
||||
timer.setSingleShot( true );
|
||||
|
||||
connect( &timer, &QTimer::timeout, &d->loop, &QEventLoop::quit );
|
||||
connect( this, &Request::reply, d.data(), &RequestPrivate::quitEventLoop );
|
||||
|
||||
/*
|
||||
* If the timer fires, the return value will be 0.
|
||||
* Otherwise, quitEventLoop() will terminate the loop with 1.
|
||||
*/
|
||||
return( ( d->loop.exec( QEventLoop::ExcludeUserInputEvents ) != 0 ) );
|
||||
}
|
||||
|
||||
} // namespace redis
|
||||
|
||||
} // namespace myx
|
||||
#include <myx/redis/request-inl.hpp>
|
||||
|
@ -1,22 +1,24 @@
|
||||
#ifndef MYX_REDIS_REQUEST_HPP_
|
||||
#define MYX_REDIS_REQUEST_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
#include <myx/redis/reply.hpp>
|
||||
|
||||
#include <QObject>
|
||||
#include <QScopedPointer>
|
||||
|
||||
#include <config.hpp>
|
||||
#include <reply.hpp>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace redis {
|
||||
|
||||
class MYX_REDIS_EXPORT RequestPrivate;
|
||||
QT_FORWARD_DECLARE_CLASS( RequestPrivate );
|
||||
|
||||
/**
|
||||
* @brief Represents a Redis command and its response
|
||||
*/
|
||||
class MYX_REDIS_EXPORT Request : public QObject
|
||||
class Request : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -49,10 +51,14 @@ public:
|
||||
private:
|
||||
|
||||
const QScopedPointer< RequestPrivate > d;
|
||||
}; // class MYX_REDIS_EXPORT
|
||||
}; // class Request
|
||||
|
||||
} // namespace redis
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "request-inl.hpp"
|
||||
#endif
|
||||
|
||||
#endif // MYX_REDIS_REQUEST_HPP_
|
||||
|
Loading…
Reference in New Issue
Block a user