From 953316e4d03400a1071a19509e402d9cad774a9c Mon Sep 17 00:00:00 2001 From: Nathan Osman Date: Wed, 7 Aug 2013 21:56:47 -0700 Subject: [PATCH] Added invalid reply type and empty constructor. Rewrote most of the parsing routines. --- include/qredis/reply.h | 17 +++++++++-- src/parser.cpp | 59 ++++++++++++------------------------ src/parser.h | 68 +++++++++++++++++++----------------------- 3 files changed, 65 insertions(+), 79 deletions(-) diff --git a/include/qredis/reply.h b/include/qredis/reply.h index b9738be..03f6ca5 100644 --- a/include/qredis/reply.h +++ b/include/qredis/reply.h @@ -19,6 +19,13 @@ namespace QRedis */ enum Type { + /** + * @brief An invalid reply + * + * This value is only set when the default constructor is used. + */ + Invalid, + /** * @brief A status reply * @@ -61,10 +68,14 @@ namespace QRedis MultiBulk }; + /** + * @brief Creates an empty reply + */ + Reply() : _type(Invalid) {} + /** * @brief Initializes the reply * @param type the type of the reply - * @param value the value of the reply */ Reply(Type type) : _type(type) {} @@ -75,7 +86,7 @@ namespace QRedis Type type() const { return _type; } /** - * @brief Returns the value of the reply + * @brief Returns a reference to the value of the reply * @return the reply value */ QVariant & value() { return _value; } @@ -87,4 +98,6 @@ namespace QRedis }; } +Q_DECLARE_METATYPE(QRedis::Reply) + #endif // QREDIS_REPLY_H diff --git a/src/parser.cpp b/src/parser.cpp index db05d41..ecf5c5f 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1,5 +1,7 @@ #include "parser.h" +using namespace QRedis; + Parser::Parser(Lexer * lexer, QObject * parent) : QObject(parent) { @@ -16,11 +18,11 @@ void Parser::readCharacter(char c) { switch(c) { - case '+': stack.append(Task(Task::ReadStatus)); break; - case '-': stack.append(Task(Task::ReadError)); break; - case ':': stack.append(Task(Task::ReadInteger)); break; - case '$': stack.append(Task(Task::ReadBulk)); break; - case '*': stack.append(Task(Task::ReadMultiBulk)); break; + 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: qWarning("Skipping unexpected character '%x'", static_cast(c)); break; @@ -29,58 +31,35 @@ void Parser::readCharacter(char c) void Parser::readUnsafeString(const QString & value) { - if(tos().action == Task::ReadMultiBulk) + if(tos().reply.type() == Reply::MultiBulk) tos().count = value.toInt(); else - { - Task::Action action = tos().action; - stack.removeLast(); + tos().reply.value() = value; - if(action == Task::ReadStatus) - ;//emit status(value); - else if(action == Task::ReadError) - { - int pos = value.indexOf(' '); - ;//emit error(value.left(pos), value.right(pos + 1)); - } - else if(!stack.count()) - ;//emit integer(value.toLongLong()); - else - { - tos().value.toList().append(value); - descend(); - } - } + descend(); } void Parser::readSafeString(const QByteArray & value) { - stack.removeLast(); - - if(!stack.count()) - ;//emit bulk(value); - else - { - tos().value.toList().append(value); - descend(); - } + tos().reply.value() = value; + descend(); } void Parser::descend() { while(true) { - if(tos().value.toList().count() < tos().count) - break; + if(tos().reply.type() == Reply::MultiBulk && + tos().reply.value().toList().count() < tos().count) + return; if(stack.count() == 1) { - ;//emit multiBulk(tos().value.toList()); - stack.removeLast(); - break; + emit reply(stack.takeLast().reply); + return; } - Task task = stack.takeLast(); - tos().value.toList().append(task.value); + Reply r = stack.takeLast().reply; + tos().reply.value().toList().append(QVariant::fromValue(r)); } } diff --git a/src/parser.h b/src/parser.h index 876ce0b..ca61fe4 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,61 +1,55 @@ -#ifndef PARSER_H -#define PARSER_H +#ifndef QREDIS_PARSER_H +#define QREDIS_PARSER_H #include #include +#include #include -#include #include #include "lexer.h" -class Parser : public QObject +namespace QRedis { - Q_OBJECT + class Parser : public QObject + { + Q_OBJECT - public: + public: - Parser(Lexer *, QObject * = 0); - virtual ~Parser(); + Parser(Lexer *, QObject * = 0); + virtual ~Parser(); - Q_SIGNALS: + Q_SIGNALS: - void reply(QRedis::Reply &); + void reply(const Reply &); - private Q_SLOTS: + private Q_SLOTS: - void readCharacter(char); - void readUnsafeString(const QString &); - void readSafeString(const QByteArray &); + void readCharacter(char); + void readUnsafeString(const QString &); + void readSafeString(const QByteArray &); - private: + private: - void descend(); + void descend(); - class Task - { - public: + class Task + { + public: - enum Action { - ReadStatus, - ReadError, - ReadInteger, - ReadBulk, - ReadMultiBulk - }; + enum { Unknown = -2 }; - enum { Unknown = -2 }; + Task(Reply::Type type) : reply(type), count(Unknown) {} - Task(Action action) : action(action), count(Unknown) {} + Reply reply; + int count; + }; - Action action; - int count; - QVariant value; - }; + QList stack; - QList stack; + Task & tos() { return stack.last(); } + }; +} - inline Task & tos() { return stack.last(); } -}; - -#endif // PARSER_H +#endif // QREDIS_PARSER_H