Implemented parser, although it does not support NULL replies nor is it integrated into the Client class.
This commit is contained in:
parent
76af55e20d
commit
ac876e196e
|
|
@ -23,6 +23,7 @@ include_directories(include)
|
||||||
set(QREDIS_SRC
|
set(QREDIS_SRC
|
||||||
src/client.cpp
|
src/client.cpp
|
||||||
src/lexer.cpp
|
src/lexer.cpp
|
||||||
|
src/parser.cpp
|
||||||
src/request.cpp)
|
src/request.cpp)
|
||||||
|
|
||||||
# QRedis header files requiring MOC.
|
# QRedis header files requiring MOC.
|
||||||
|
|
@ -31,6 +32,7 @@ qt5_wrap_cpp(QREDIS_MOC
|
||||||
include/qredis/request.h
|
include/qredis/request.h
|
||||||
src/client_p.h
|
src/client_p.h
|
||||||
src/lexer.h
|
src/lexer.h
|
||||||
|
src/parser.h
|
||||||
src/request_p.h)
|
src/request_p.h)
|
||||||
|
|
||||||
# Create the client library.
|
# Create the client library.
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,9 @@ void Lexer::readData()
|
||||||
case ReadingUnsafeString: if(!readUnsafeString()) return; break;
|
case ReadingUnsafeString: if(!readUnsafeString()) return; break;
|
||||||
case ReadingSafeString: if(!readSafeString()) return; break;
|
case ReadingSafeString: if(!readSafeString()) return; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(state != ReadingSafeString)
|
||||||
|
state = DoingNothing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,12 +44,9 @@ bool Lexer::readCharacter()
|
||||||
{
|
{
|
||||||
case '+':
|
case '+':
|
||||||
case '-':
|
case '-':
|
||||||
case '*':
|
case ':':
|
||||||
case ':': state = ReadingUnsafeString; break;
|
case '*': state = ReadingUnsafeString; break;
|
||||||
case '$': state = ReadingLength; break;
|
case '$': state = ReadingLength; break;
|
||||||
default:
|
|
||||||
emit warning(tr("Unexpected character '%1' encountered").arg(static_cast<int>(c), 0, 16));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emit character(c);
|
emit character(c);
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,6 @@ class Lexer : public QObject
|
||||||
void unsafeString(const QString &);
|
void unsafeString(const QString &);
|
||||||
void safeString(const QByteArray &);
|
void safeString(const QByteArray &);
|
||||||
|
|
||||||
void warning(const QString &);
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
|
|
||||||
void readData();
|
void readData();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
Parser::Parser(Lexer * lexer, QObject * parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
connect(lexer, SIGNAL(character(char)), SLOT(readCharacter(char)));
|
||||||
|
connect(lexer, SIGNAL(unsafeString(QString)), SLOT(readUnsafeString(QString)));
|
||||||
|
connect(lexer, SIGNAL(safeString(QByteArray)), SLOT(readSafeString(QByteArray)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::~Parser()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
default:
|
||||||
|
emit warning(tr("Skipping unexpected character '%1'").arg(static_cast<int>(c), 0, 16));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Parser::readUnsafeString(const QString & value)
|
||||||
|
{
|
||||||
|
if(tos().action == Task::ReadMultiBulk)
|
||||||
|
tos().count = value.toInt();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stack.removeLast();
|
||||||
|
|
||||||
|
if(tos().action == Task::ReadStatus)
|
||||||
|
emit status(value);
|
||||||
|
else if(tos().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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Parser::readSafeString(const QByteArray & value)
|
||||||
|
{
|
||||||
|
stack.removeLast();
|
||||||
|
|
||||||
|
if(!stack.count())
|
||||||
|
emit bulk(value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tos().value.toList().append(value);
|
||||||
|
descend();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Parser::descend()
|
||||||
|
{
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
if(tos().value.toList().count() < tos().count)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(stack.count() == 1)
|
||||||
|
{
|
||||||
|
emit multiBulk(tos().value.toList());
|
||||||
|
stack.removeLast();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Task task = stack.takeLast();
|
||||||
|
tos().value.toList().append(task.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
#ifndef PARSER_H
|
||||||
|
#define PARSER_H
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QVariant>
|
||||||
|
#include <QVariantList>
|
||||||
|
|
||||||
|
#include "lexer.h"
|
||||||
|
|
||||||
|
class Parser : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Parser(Lexer *, QObject * = 0);
|
||||||
|
virtual ~Parser();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
|
||||||
|
void status(const QString &);
|
||||||
|
void error(const QString &, const QString &);
|
||||||
|
void integer(qlonglong);
|
||||||
|
void bulk(const QByteArray &);
|
||||||
|
void multiBulk(const QVariantList &);
|
||||||
|
|
||||||
|
void warning(const QString &);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
|
||||||
|
void readCharacter(char);
|
||||||
|
void readUnsafeString(const QString &);
|
||||||
|
void readSafeString(const QByteArray &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void descend();
|
||||||
|
|
||||||
|
class Task
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum Action {
|
||||||
|
ReadStatus,
|
||||||
|
ReadError,
|
||||||
|
ReadInteger,
|
||||||
|
ReadBulk,
|
||||||
|
ReadMultiBulk
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { Unknown = -2 };
|
||||||
|
|
||||||
|
Task(Action action) : action(action), count(Unknown) {}
|
||||||
|
|
||||||
|
Action action;
|
||||||
|
int count;
|
||||||
|
QVariant value;
|
||||||
|
};
|
||||||
|
|
||||||
|
QList<Task> stack;
|
||||||
|
|
||||||
|
inline Task & tos() { return stack.last(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PARSER_H
|
||||||
Loading…
Reference in New Issue