diff --git a/src/myx/redis/CMakeLists.txt b/src/myx/redis/CMakeLists.txt index 34825af..4e8527d 100644 --- a/src/myx/redis/CMakeLists.txt +++ b/src/myx/redis/CMakeLists.txt @@ -18,9 +18,6 @@ set(TRGT_moc_hpp ${CMAKE_CURRENT_SOURCE_DIR}/request.hpp) set(TRGT_hpp - ${CMAKE_CURRENT_SOURCE_DIR}/client_p.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/request_p.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/parser_p.hpp ${CMAKE_CURRENT_SOURCE_DIR}/client-inl.hpp ${CMAKE_CURRENT_SOURCE_DIR}/lexer-inl.hpp ${CMAKE_CURRENT_SOURCE_DIR}/parser-inl.hpp diff --git a/src/myx/redis/client-inl.hpp b/src/myx/redis/client-inl.hpp index 0c32fc0..1bd7f0c 100644 --- a/src/myx/redis/client-inl.hpp +++ b/src/myx/redis/client-inl.hpp @@ -7,28 +7,10 @@ #include #endif -#include - 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 ) ) @@ -38,41 +20,41 @@ Client::Client( QObject* parent ) : void Client::connectToHost( const QString& hostName, quint16 port ) { - d->socket.connectToHost( hostName, port ); + d->m_socket.connectToHost( hostName, port ); } void Client::disconnectFromHost() { - d->socket.disconnectFromHost(); + d->m_socket.disconnectFromHost(); } bool Client::isConnected() const { - return( d->socket.state() == QAbstractSocket::ConnectedState ); + return( d->m_socket.state() == QAbstractSocket::ConnectedState ); } Request* Client::sendCommand( const QByteArray& command ) { - d->socket.write( command + "\r\n" ); + d->m_socket.write( command + "\r\n" ); auto* request = new Request( this ); - d->queue.enqueue( request ); + d->m_queue.enqueue( request ); return( request ); } bool Client::waitForConnected( int msecs ) { - return( d->socket.waitForConnected( msecs ) ); + return( d->m_socket.waitForConnected( msecs ) ); } bool Client::waitForDisconnected( int msecs ) { - return( d->socket.waitForDisconnected( msecs ) ); + return( d->m_socket.waitForDisconnected( msecs ) ); } } // namespace redis diff --git a/src/myx/redis/client.hpp b/src/myx/redis/client.hpp index 255b88f..d1a36f1 100644 --- a/src/myx/redis/client.hpp +++ b/src/myx/redis/client.hpp @@ -4,17 +4,18 @@ #pragma once #include +#include +#include #include -#include +#include #include +#include namespace myx { namespace redis { -QT_FORWARD_DECLARE_CLASS( ClientPrivate ) - /** * @brief Provides access to a Redis server */ @@ -105,6 +106,33 @@ public: private: + class ClientPrivate : public QObject + { + Q_OBJECT + + friend class Client; + + explicit ClientPrivate( Client* client = nullptr ) : + m_lexer ( &m_socket ), + m_parser( &m_lexer ) + { + connect( &m_socket, &QTcpSocket::connected, client, &Client::connected ); + connect( &m_socket, &QTcpSocket::disconnected, client, &Client::disconnected ); + connect( &m_parser, &Parser::reply, this, &ClientPrivate::sendReply ); + } + + + QTcpSocket m_socket; + QQueue< Request* > m_queue; + Lexer m_lexer; + Parser m_parser; + + Q_SLOT void sendReply( const myx::redis::Reply& reply ) + { + Q_EMIT m_queue.dequeue()->reply( reply ); + } + }; // class ClientPrivate + const QScopedPointer< ClientPrivate > d; }; // class Client @@ -117,4 +145,4 @@ private: #endif -#endif // MYX_REDIS_CLIENT_HPP_ +#endif // ifndef MYX_REDIS_CLIENT_HPP_ diff --git a/src/myx/redis/client_p.hpp b/src/myx/redis/client_p.hpp deleted file mode 100644 index 21786f8..0000000 --- a/src/myx/redis/client_p.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef MYX_REDIS_CLIENT_P_HPP_ -#define MYX_REDIS_CLIENT_P_HPP_ - -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace myx { - -namespace redis { - -class ClientPrivate : public QObject -{ - Q_OBJECT - -public: - explicit ClientPrivate( Client* = nullptr ); - - QTcpSocket socket; - QQueue< Request* > queue; - - Lexer lexer; - Parser parser; - -private: - Q_SLOT void sendReply( const myx::redis::Reply& ); -}; // class ClientPrivate - -} // namespace redis - -} // namespace myx - -#endif // MYX_REDIS_CLIENT_P_HPP_ diff --git a/src/myx/redis/lexer.hpp b/src/myx/redis/lexer.hpp index a5e164c..77ec58d 100644 --- a/src/myx/redis/lexer.hpp +++ b/src/myx/redis/lexer.hpp @@ -57,4 +57,4 @@ private: #endif -#endif // MYX_REDIS_LEXER_HPP_ +#endif // ifndef MYX_REDIS_LEXER_HPP_ diff --git a/src/myx/redis/parser-inl.hpp b/src/myx/redis/parser-inl.hpp index 8c08a60..defca6a 100644 --- a/src/myx/redis/parser-inl.hpp +++ b/src/myx/redis/parser-inl.hpp @@ -25,15 +25,15 @@ void Parser::readCharacter( const char c ) switch ( c ) { case '+': - m_stack.append( ParserTaskPrivate( Reply::Status ) ); break; + m_stack.append( Task( Reply::kStatus ) ); break; case '-': - m_stack.append( ParserTaskPrivate( Reply::Error ) ); break; + m_stack.append( Task( Reply::kError ) ); break; case ':': - m_stack.append( ParserTaskPrivate( Reply::Integer ) ); break; + m_stack.append( Task( Reply::kInteger ) ); break; case '$': - m_stack.append( ParserTaskPrivate( Reply::Bulk ) ); break; + m_stack.append( Task( Reply::kBulk ) ); break; case '*': - m_stack.append( ParserTaskPrivate( Reply::MultiBulk ) ); break; + m_stack.append( Task( Reply::kMultiBulk ) ); break; default: break; } @@ -42,13 +42,13 @@ void Parser::readCharacter( const char c ) void Parser::readUnsafeString( const QString& value ) { - if ( tos().reply.type() == Reply::MultiBulk ) + if ( tos().m_reply.type() == Reply::kMultiBulk ) { - tos().count = value.toInt(); + tos().m_count = value.toInt(); } else { - tos().reply.value() = value; + tos().m_reply.value() = value; } descend(); @@ -57,7 +57,7 @@ void Parser::readUnsafeString( const QString& value ) void Parser::readSafeString( const QByteArray& value ) { - tos().reply.value() = value; + tos().m_reply.value() = value; descend(); } @@ -66,21 +66,21 @@ void Parser::descend() { while ( true ) { - if ( ( tos().reply.type() == Reply::MultiBulk ) && - ( tos().reply.value().toList().count() < tos().count ) ) + if ( ( tos().m_reply.type() == Reply::kMultiBulk ) && + ( tos().m_reply.value().toList().count() < tos().m_count ) ) { return; } if ( m_stack.count() == 1 ) { - auto r = m_stack.takeLast().reply; + auto r = m_stack.takeLast().m_reply; Q_EMIT reply( r ); return; } - auto r = m_stack.takeLast().reply; - tos().reply.value().toList().append( QVariant::fromValue( r ) ); + auto r = m_stack.takeLast().m_reply; + tos().m_reply.value().toList().append( QVariant::fromValue( r ) ); } } diff --git a/src/myx/redis/parser.hpp b/src/myx/redis/parser.hpp index a533836..0a40ae4 100644 --- a/src/myx/redis/parser.hpp +++ b/src/myx/redis/parser.hpp @@ -5,7 +5,7 @@ #include #include -#include +// #include #include #include @@ -33,9 +33,23 @@ private: void descend(); - QList< ParserTaskPrivate > m_stack; + class Task + { + friend class Parser; - ParserTaskPrivate& tos() { return( m_stack.last() ); } + enum { kUnknown = -2 }; + + explicit Task( Reply::Type type ) : + m_reply( type ), + m_count( kUnknown ) {} + + Reply m_reply; + int m_count; + }; + + QList< Task > m_stack; + + Task& tos() { return( m_stack.last() ); } }; // class Parser } // namespace redis @@ -46,4 +60,4 @@ private: #include "parser-inl.hpp" #endif -#endif // MYX_REDIS_PARSER_HPP_ +#endif // ifndef MYX_REDIS_PARSER_HPP_ diff --git a/src/myx/redis/parser_p.hpp b/src/myx/redis/parser_p.hpp deleted file mode 100644 index 124c21c..0000000 --- a/src/myx/redis/parser_p.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef MYX_REDIS_PARSER_P_HPP_ -#define MYX_REDIS_PARSER_P_HPP_ - -#pragma once - -#include - -namespace myx { - -namespace redis { - -class ParserTaskPrivate -{ - friend class Parser; - - enum { Unknown = -2 }; - - ParserTaskPrivate( Reply::Type type ) : - reply( type ), - count( Unknown ) {} - - Reply reply; - int count; -}; - -} // namespace redis - -} // namespace myx - -#endif // MYX_REDIS_PARSER_P_HPP_ diff --git a/src/myx/redis/reply.hpp b/src/myx/redis/reply.hpp index 8b49690..6054300 100644 --- a/src/myx/redis/reply.hpp +++ b/src/myx/redis/reply.hpp @@ -28,7 +28,7 @@ public: * * This value is only set when the default constructor is used. */ - Invalid, + kInvalid, /** * @brief A status reply @@ -36,7 +36,7 @@ public: * The value property will contain the status message returned * by the server as a QString. */ - Status, + kStatus, /** * @brief An error reply @@ -44,7 +44,7 @@ public: * The value property will contain the error message returned by * the server as a QString. */ - Error, + kError, /** * @brief An integer reply @@ -52,7 +52,7 @@ public: * The value property will contain the integer value returned by * the server as a qlonglong. */ - Integer, + kInteger, /** * @brief A bulk reply @@ -60,7 +60,7 @@ public: * The value property will contain the bulk reply returned by * the server as a QByteArray. */ - Bulk, + kBulk, /** * @brief A multi-bulk reply @@ -69,7 +69,7 @@ public: * by the server as a QVariantList. Each entry in the list is of * type Reply. */ - MultiBulk + kMultiBulk }; /** @@ -98,7 +98,7 @@ public: private: - Type m_type { Invalid }; + Type m_type { kInvalid }; QVariant m_value; }; // class Reply @@ -108,4 +108,4 @@ private: Q_DECLARE_METATYPE( myx::redis::Reply ) -#endif // MYX_REDIS_REPLY_HPP_ +#endif // ifndef MYX_REDIS_REPLY_HPP_ diff --git a/src/myx/redis/request-inl.hpp b/src/myx/redis/request-inl.hpp index a06b966..15497b5 100644 --- a/src/myx/redis/request-inl.hpp +++ b/src/myx/redis/request-inl.hpp @@ -8,7 +8,6 @@ #ifndef MYXLIB_HEADER_ONLY #include #endif -#include #include @@ -16,15 +15,9 @@ namespace myx { namespace redis { -void RequestPrivate::quitEventLoop() -{ - loop.exit( 1 ); -} - - Request::Request( QObject* parent ) : QObject( parent ), - d ( new RequestPrivate ) + d ( new Loop ) { connect( this, &Request::reply, this, &Request::deleteLater ); } @@ -36,14 +29,14 @@ bool Request::waitForReply( int msecs ) timer.setInterval( msecs ); timer.setSingleShot( true ); - connect( &timer, &QTimer::timeout, &d->loop, &QEventLoop::quit ); - connect( this, &Request::reply, d.data(), &RequestPrivate::quitEventLoop ); + connect( &timer, &QTimer::timeout, &d->m_loop, &QEventLoop::quit ); + connect( this, &Request::reply, d.data(), &Loop::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 ) ); + return( ( d->m_loop.exec( QEventLoop::ExcludeUserInputEvents ) != 0 ) ); } } // namespace redis diff --git a/src/myx/redis/request.hpp b/src/myx/redis/request.hpp index 7e30c28..a34f773 100644 --- a/src/myx/redis/request.hpp +++ b/src/myx/redis/request.hpp @@ -6,15 +6,14 @@ #include #include -#include +#include #include + namespace myx { namespace redis { -QT_FORWARD_DECLARE_CLASS( RequestPrivate ); - /** * @brief Represents a Redis command and its response */ @@ -50,7 +49,19 @@ public: private: - const QScopedPointer< RequestPrivate > d; + class Loop : public QObject + { + Q_OBJECT + + friend class Request; + explicit Loop( QObject* parent = nullptr ); + + QEventLoop m_loop; + Q_SLOT void quitEventLoop() { m_loop.exit( 1 ); } + }; + + + const QScopedPointer< Loop > d; }; // class Request } // namespace redis @@ -61,4 +72,4 @@ private: #include "request-inl.hpp" #endif -#endif // MYX_REDIS_REQUEST_HPP_ +#endif // ifndef MYX_REDIS_REQUEST_HPP_ diff --git a/src/myx/redis/request_p.hpp b/src/myx/redis/request_p.hpp deleted file mode 100644 index 90e4042..0000000 --- a/src/myx/redis/request_p.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef MYX_REDIS_REQUEST_P_HPP_ -#define MYX_REDIS_REQUEST_P_HPP_ - -#include -#include - -namespace myx { - -namespace redis { - -class RequestPrivate : public QObject -{ - Q_OBJECT - -public: - explicit RequestPrivate( QObject* parent = nullptr ); - - QEventLoop loop; - Q_SLOT void quitEventLoop(); -}; - -} // namespace redis - -} // namespace myx -#endif // MYX_REDIS_REQUEST_P_HPP_