Рефакторинг библиотеки для 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/filesystem)
|
||||||
add_subdirectory(src/myx/qt)
|
add_subdirectory(src/myx/qt)
|
||||||
add_subdirectory(src/myx/math)
|
add_subdirectory(src/myx/math)
|
||||||
# add_subdirectory(src/myx/redis)
|
add_subdirectory(src/myx/redis)
|
||||||
|
|
||||||
# Примеры
|
# Примеры
|
||||||
if(MYXLIB_BUILD_EXAMPLES OR MYXLIB_BUILD_EXAMPLES_HO)
|
if(MYXLIB_BUILD_EXAMPLES OR MYXLIB_BUILD_EXAMPLES_HO)
|
||||||
|
@ -5,7 +5,6 @@ set(TRGT redis)
|
|||||||
# Список файлов исходных текстов
|
# Список файлов исходных текстов
|
||||||
set(TRGT_cpp
|
set(TRGT_cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/client.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/client.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/config.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/lexer.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/lexer.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/parser.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/parser.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/request.cpp)
|
${CMAKE_CURRENT_SOURCE_DIR}/request.cpp)
|
||||||
@ -13,13 +12,18 @@ set(TRGT_cpp
|
|||||||
# Список заголовочных файлов (используется для установки)
|
# Список заголовочных файлов (используется для установки)
|
||||||
set(TRGT_moc_hpp
|
set(TRGT_moc_hpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/client.hpp
|
${CMAKE_CURRENT_SOURCE_DIR}/client.hpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/config.hpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/lexer.hpp
|
${CMAKE_CURRENT_SOURCE_DIR}/lexer.hpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/parser.hpp
|
${CMAKE_CURRENT_SOURCE_DIR}/parser.hpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/reply.hpp
|
${CMAKE_CURRENT_SOURCE_DIR}/reply.hpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/request.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
|
# cmake-format: on
|
||||||
|
|
||||||
add_library(${TRGT}-header-only INTERFACE)
|
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>
|
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||||
#include <client_p.hpp>
|
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace myx {
|
#include <myx/redis/client-inl.hpp>
|
||||||
|
|
||||||
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
|
|
||||||
|
@ -1,22 +1,24 @@
|
|||||||
#ifndef MYX_REDIS_CLIENT_HPP_
|
#ifndef MYX_REDIS_CLIENT_HPP_
|
||||||
#define MYX_REDIS_CLIENT_HPP_
|
#define MYX_REDIS_CLIENT_HPP_
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <myx/base/config.hpp>
|
||||||
|
#include <myx/redis/request.hpp>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
|
|
||||||
#include <config.hpp>
|
|
||||||
#include <request.hpp>
|
|
||||||
|
|
||||||
namespace myx {
|
namespace myx {
|
||||||
|
|
||||||
namespace redis {
|
namespace redis {
|
||||||
|
|
||||||
class MYX_REDIS_EXPORT ClientPrivate;
|
QT_FORWARD_DECLARE_CLASS( ClientPrivate )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Provides access to a Redis server
|
* @brief Provides access to a Redis server
|
||||||
*/
|
*/
|
||||||
class MYX_REDIS_EXPORT Client : public QObject
|
class Client : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -104,10 +106,15 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
const QScopedPointer< ClientPrivate > d;
|
const QScopedPointer< ClientPrivate > d;
|
||||||
}; // class MYX_REDIS_EXPORT
|
}; // class Client
|
||||||
|
|
||||||
} // namespace redis
|
} // namespace redis
|
||||||
|
|
||||||
} // namespace myx
|
} // namespace myx
|
||||||
|
|
||||||
|
#ifdef MYXLIB_HEADER_ONLY
|
||||||
|
#include "client-inl.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // MYX_REDIS_CLIENT_HPP_
|
#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 {
|
#include <myx/redis/lexer-inl.hpp>
|
||||||
|
|
||||||
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
|
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
#ifndef MYX_REDIS_LEXER_HPP_
|
#ifndef MYX_REDIS_LEXER_HPP_
|
||||||
#define MYX_REDIS_LEXER_HPP_
|
#define MYX_REDIS_LEXER_HPP_
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <myx/base/config.hpp>
|
||||||
|
|
||||||
#include <QIODevice>
|
#include <QIODevice>
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
namespace myx {
|
namespace myx {
|
||||||
|
|
||||||
@ -51,4 +54,9 @@ private:
|
|||||||
|
|
||||||
} // namespace myx
|
} // namespace myx
|
||||||
|
|
||||||
|
#ifdef MYXLIB_HEADER_ONLY
|
||||||
|
#include "lexer-inl.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // MYX_REDIS_LEXER_HPP_
|
#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 {
|
#include <myx/redis/parser-inl.hpp>
|
||||||
|
|
||||||
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
|
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
#ifndef MYX_REDIS_PARSER_HPP_
|
#ifndef MYX_REDIS_PARSER_HPP_
|
||||||
#define 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 <QList>
|
||||||
#include <QObject>
|
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
#include <reply.hpp>
|
|
||||||
#include <lexer.hpp>
|
|
||||||
|
|
||||||
namespace myx {
|
namespace myx {
|
||||||
|
|
||||||
namespace redis {
|
namespace redis {
|
||||||
@ -54,4 +56,8 @@ public:
|
|||||||
|
|
||||||
} // namespace myx
|
} // namespace myx
|
||||||
|
|
||||||
|
#ifdef MYXLIB_HEADER_ONLY
|
||||||
|
#include "parser-inl.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // MYX_REDIS_PARSER_HPP_
|
#endif // MYX_REDIS_PARSER_HPP_
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
#ifndef MYX_REDIS_REPLY_HPP_
|
#ifndef MYX_REDIS_REPLY_HPP_
|
||||||
#define 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 {
|
namespace myx {
|
||||||
|
|
||||||
@ -12,7 +14,7 @@ namespace redis {
|
|||||||
/**
|
/**
|
||||||
* @brief Represents a Redis reply
|
* @brief Represents a Redis reply
|
||||||
*/
|
*/
|
||||||
class MYX_REDIS_EXPORT Reply
|
class Reply
|
||||||
{
|
{
|
||||||
public:
|
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 <myx/redis/request-inl.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
|
|
||||||
|
@ -1,22 +1,24 @@
|
|||||||
#ifndef MYX_REDIS_REQUEST_HPP_
|
#ifndef MYX_REDIS_REQUEST_HPP_
|
||||||
#define MYX_REDIS_REQUEST_HPP_
|
#define MYX_REDIS_REQUEST_HPP_
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <myx/base/config.hpp>
|
||||||
|
#include <myx/redis/reply.hpp>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
|
|
||||||
#include <config.hpp>
|
|
||||||
#include <reply.hpp>
|
|
||||||
|
|
||||||
namespace myx {
|
namespace myx {
|
||||||
|
|
||||||
namespace redis {
|
namespace redis {
|
||||||
|
|
||||||
class MYX_REDIS_EXPORT RequestPrivate;
|
QT_FORWARD_DECLARE_CLASS( RequestPrivate );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Represents a Redis command and its response
|
* @brief Represents a Redis command and its response
|
||||||
*/
|
*/
|
||||||
class MYX_REDIS_EXPORT Request : public QObject
|
class Request : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -49,10 +51,14 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
const QScopedPointer< RequestPrivate > d;
|
const QScopedPointer< RequestPrivate > d;
|
||||||
}; // class MYX_REDIS_EXPORT
|
}; // class Request
|
||||||
|
|
||||||
} // namespace redis
|
} // namespace redis
|
||||||
|
|
||||||
} // namespace myx
|
} // namespace myx
|
||||||
|
|
||||||
|
#ifdef MYXLIB_HEADER_ONLY
|
||||||
|
#include "request-inl.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // MYX_REDIS_REQUEST_HPP_
|
#endif // MYX_REDIS_REQUEST_HPP_
|
||||||
|
Loading…
x
Reference in New Issue
Block a user