Added Lexer class.

This commit is contained in:
Nathan Osman 2013-07-15 11:35:51 -07:00
parent 1b45cb3777
commit 76af55e20d
3 changed files with 140 additions and 0 deletions

View File

@ -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.

89
src/lexer.cpp Normal file
View File

@ -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;
}

49
src/lexer.h Normal file
View File

@ -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