Added invalid reply type and empty constructor. Rewrote most of the parsing routines.

This commit is contained in:
Nathan Osman 2013-08-07 21:56:47 -07:00
parent be19213978
commit 953316e4d0
3 changed files with 65 additions and 79 deletions

View File

@ -19,6 +19,13 @@ namespace QRedis
*/ */
enum Type { enum Type {
/**
* @brief An invalid reply
*
* This value is only set when the default constructor is used.
*/
Invalid,
/** /**
* @brief A status reply * @brief A status reply
* *
@ -61,10 +68,14 @@ namespace QRedis
MultiBulk MultiBulk
}; };
/**
* @brief Creates an empty reply
*/
Reply() : _type(Invalid) {}
/** /**
* @brief Initializes the reply * @brief Initializes the reply
* @param type the type of the reply * @param type the type of the reply
* @param value the value of the reply
*/ */
Reply(Type type) : _type(type) {} Reply(Type type) : _type(type) {}
@ -75,7 +86,7 @@ namespace QRedis
Type type() const { return _type; } 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 * @return the reply value
*/ */
QVariant & value() { return _value; } QVariant & value() { return _value; }
@ -87,4 +98,6 @@ namespace QRedis
}; };
} }
Q_DECLARE_METATYPE(QRedis::Reply)
#endif // QREDIS_REPLY_H #endif // QREDIS_REPLY_H

View File

@ -1,5 +1,7 @@
#include "parser.h" #include "parser.h"
using namespace QRedis;
Parser::Parser(Lexer * lexer, QObject * parent) Parser::Parser(Lexer * lexer, QObject * parent)
: QObject(parent) : QObject(parent)
{ {
@ -16,11 +18,11 @@ void Parser::readCharacter(char c)
{ {
switch(c) switch(c)
{ {
case '+': stack.append(Task(Task::ReadStatus)); break; case '+': stack.append(Task(Reply::Status)); break;
case '-': stack.append(Task(Task::ReadError)); break; case '-': stack.append(Task(Reply::Error)); break;
case ':': stack.append(Task(Task::ReadInteger)); break; case ':': stack.append(Task(Reply::Integer)); break;
case '$': stack.append(Task(Task::ReadBulk)); break; case '$': stack.append(Task(Reply::Bulk)); break;
case '*': stack.append(Task(Task::ReadMultiBulk)); break; case '*': stack.append(Task(Reply::MultiBulk)); break;
default: default:
qWarning("Skipping unexpected character '%x'", static_cast<int>(c)); qWarning("Skipping unexpected character '%x'", static_cast<int>(c));
break; break;
@ -29,58 +31,35 @@ void Parser::readCharacter(char c)
void Parser::readUnsafeString(const QString & value) void Parser::readUnsafeString(const QString & value)
{ {
if(tos().action == Task::ReadMultiBulk) if(tos().reply.type() == Reply::MultiBulk)
tos().count = value.toInt(); tos().count = value.toInt();
else else
{ tos().reply.value() = value;
Task::Action action = tos().action;
stack.removeLast();
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) void Parser::readSafeString(const QByteArray & value)
{ {
stack.removeLast(); tos().reply.value() = value;
if(!stack.count())
;//emit bulk(value);
else
{
tos().value.toList().append(value);
descend(); descend();
} }
}
void Parser::descend() void Parser::descend()
{ {
while(true) while(true)
{ {
if(tos().value.toList().count() < tos().count) if(tos().reply.type() == Reply::MultiBulk &&
break; tos().reply.value().toList().count() < tos().count)
return;
if(stack.count() == 1) if(stack.count() == 1)
{ {
;//emit multiBulk(tos().value.toList()); emit reply(stack.takeLast().reply);
stack.removeLast(); return;
break;
} }
Task task = stack.takeLast(); Reply r = stack.takeLast().reply;
tos().value.toList().append(task.value); tos().reply.value().toList().append(QVariant::fromValue(r));
} }
} }

View File

@ -1,14 +1,16 @@
#ifndef PARSER_H #ifndef QREDIS_PARSER_H
#define PARSER_H #define QREDIS_PARSER_H
#include <QList> #include <QList>
#include <QObject> #include <QObject>
#include <QPair>
#include <QVariant> #include <QVariant>
#include <QVariantList>
#include <qredis/reply.h> #include <qredis/reply.h>
#include "lexer.h" #include "lexer.h"
namespace QRedis
{
class Parser : public QObject class Parser : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -20,7 +22,7 @@ class Parser : public QObject
Q_SIGNALS: Q_SIGNALS:
void reply(QRedis::Reply &); void reply(const Reply &);
private Q_SLOTS: private Q_SLOTS:
@ -36,26 +38,18 @@ class Parser : public QObject
{ {
public: public:
enum Action {
ReadStatus,
ReadError,
ReadInteger,
ReadBulk,
ReadMultiBulk
};
enum { Unknown = -2 }; enum { Unknown = -2 };
Task(Action action) : action(action), count(Unknown) {} Task(Reply::Type type) : reply(type), count(Unknown) {}
Action action; Reply reply;
int count; int count;
QVariant value;
}; };
QList<Task> stack; QList<Task> stack;
inline Task & tos() { return stack.last(); } Task & tos() { return stack.last(); }
}; };
}
#endif // PARSER_H #endif // QREDIS_PARSER_H