Added Lexer class.
This commit is contained in:
parent
1b45cb3777
commit
76af55e20d
|
|
@ -22,6 +22,7 @@ include_directories(include)
|
|||
# QRedis source files.
|
||||
set(QREDIS_SRC
|
||||
src/client.cpp
|
||||
src/lexer.cpp
|
||||
src/request.cpp)
|
||||
|
||||
# QRedis header files requiring MOC.
|
||||
|
|
@ -29,6 +30,7 @@ qt5_wrap_cpp(QREDIS_MOC
|
|||
include/qredis/client.h
|
||||
include/qredis/request.h
|
||||
src/client_p.h
|
||||
src/lexer.h
|
||||
src/request_p.h)
|
||||
|
||||
# Create the client library.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
#include "lexer.h"
|
||||
|
||||
Lexer::Lexer(QIODevice * device, QObject * parent)
|
||||
: QObject(parent), device(device), state(DoingNothing), crlf(0)
|
||||
{
|
||||
connect(device, SIGNAL(readyRead()), SLOT(readData()));
|
||||
}
|
||||
|
||||
Lexer::~Lexer()
|
||||
{
|
||||
}
|
||||
|
||||
void Lexer::readData()
|
||||
{
|
||||
buffer.append(device->readAll());
|
||||
|
||||
while(true)
|
||||
{
|
||||
if(state == DoingNothing && !readCharacter())
|
||||
break;
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case ReadingLength:
|
||||
case ReadingUnsafeString: if(!readUnsafeString()) return; break;
|
||||
case ReadingSafeString: if(!readSafeString()) return; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Lexer::readCharacter()
|
||||
{
|
||||
if(!buffer.size())
|
||||
return false;
|
||||
|
||||
char c = buffer.at(0);
|
||||
buffer.remove(0, 1);
|
||||
|
||||
switch(c)
|
||||
{
|
||||
case '+':
|
||||
case '-':
|
||||
case '*':
|
||||
case ':': state = ReadingUnsafeString; 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);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Lexer::readUnsafeString()
|
||||
{
|
||||
crlf = buffer.indexOf("\r\n", crlf);
|
||||
if(crlf == -1)
|
||||
{
|
||||
crlf = buffer.size();
|
||||
return false;
|
||||
}
|
||||
|
||||
QString s = buffer.mid(0, crlf);
|
||||
buffer.remove(0, crlf + 2);
|
||||
|
||||
if(state == ReadingLength)
|
||||
{
|
||||
length = s.toInt();
|
||||
state = ReadingSafeString;
|
||||
}
|
||||
else
|
||||
emit unsafeString(s);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Lexer::readSafeString()
|
||||
{
|
||||
if(buffer.size() < length + 2)
|
||||
return false;
|
||||
|
||||
QByteArray d = buffer.mid(0, length);
|
||||
buffer.remove(0, length + 2);
|
||||
|
||||
emit safeString(d);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef LEXER_H
|
||||
#define LEXER_H
|
||||
|
||||
#include <QIODevice>
|
||||
#include <QObject>
|
||||
|
||||
class Lexer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
Lexer(QIODevice *, QObject * = 0);
|
||||
virtual ~Lexer();
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
void character(char);
|
||||
void unsafeString(const QString &);
|
||||
void safeString(const QByteArray &);
|
||||
|
||||
void warning(const QString &);
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
void readData();
|
||||
|
||||
private:
|
||||
|
||||
bool readCharacter();
|
||||
bool readLength();
|
||||
bool readUnsafeString();
|
||||
bool readSafeString();
|
||||
|
||||
QIODevice * device;
|
||||
QByteArray buffer;
|
||||
|
||||
enum {
|
||||
DoingNothing,
|
||||
ReadingLength,
|
||||
ReadingUnsafeString,
|
||||
ReadingSafeString
|
||||
} state;
|
||||
|
||||
int crlf;
|
||||
int length;
|
||||
};
|
||||
|
||||
#endif // LEXER_H
|
||||
Loading…
Reference in New Issue