Commit e2b2482d authored by Martin Hostettler's avatar Martin Hostettler Committed by Kurt Hindenburg
Browse files

Add Vt102Emulation parsing tests.

parent cc279b7d
Pipeline #181574 passed with stage
in 3 minutes and 50 seconds
......@@ -124,11 +124,15 @@ private:
#define MAX_TOKEN_LENGTH 256 // Max length of tokens (e.g. window title)
void addToCurrentToken(uint cc);
int tokenBufferPos;
protected:
uint tokenBuffer[MAX_TOKEN_LENGTH]; // FIXME: overflow?
private:
#define MAXARGS 15
void addDigit(int dig);
void addArgument();
int argv[MAXARGS];
int argv[MAXARGS] = {};
int argc;
void initTokenizer();
// State machine for escape sequences containing large amount of data
......@@ -146,11 +150,14 @@ private:
quint32 imageId;
QMap<char, qint64> savedKeys;
void reportDecodingError();
protected:
virtual void reportDecodingError();
virtual void processToken(int code, int p, int q);
virtual void processSessionAttributeRequest(int tokenSize);
virtual void processChecksumRequest(int argc, int argv[]);
void processToken(int code, int p, int q);
void processSessionAttributeRequest(int tokenSize);
void processChecksumRequest(int argc, int argv[]);
private:
void processGraphicsToken(int tokenSize);
void sendGraphicsReply(const QString &params, const QString &error);
......
......@@ -76,6 +76,18 @@ constexpr int token_csi_pe(int a)
{
return token_construct(10, a, 0);
}
constexpr int token_csi_sp(int a)
{
return token_construct(11, a, 0);
}
constexpr int token_csi_psp(int a, int n)
{
return token_construct(12, a, n);
}
constexpr int token_csi_pq(int a)
{
return token_construct(13, a, 0);
}
void Vt102EmulationTest::sendAndCompare(TestEmulation *em, const char *input, size_t inputLen, const QString &expectedPrint, const QByteArray &expectedSent)
{
......@@ -101,6 +113,282 @@ void Vt102EmulationTest::testParse()
sendAndCompare(&em, tertiaryDeviceAttributes, sizeof tertiaryDeviceAttributes, QStringLiteral(""), "\033P!|00000000\033\\");
}
Q_DECLARE_METATYPE(std::vector<TestEmulation::Item>)
struct ItemToString {
QString operator()(const TestEmulation::ProcessToken &item)
{
return QStringLiteral("processToken(0x%0, %1, %2)").arg(QString::number(item.code, 16), QString::number(item.p), QString::number(item.q));
}
QString operator()(TestEmulation::ProcessSessionAttributeRequest)
{
return QStringLiteral("ProcessSessionAttributeRequest");
}
QString operator()(TestEmulation::ProcessChecksumRequest)
{
return QStringLiteral("ProcessChecksumRequest");
}
QString operator()(TestEmulation::DecodingError)
{
return QStringLiteral("DecodingError");
}
};
namespace QTest
{
template<>
char *toString(const std::vector<TestEmulation::Item> &items)
{
QStringList res;
for (auto item : items) {
res.append(std::visit(ItemToString{}, item));
}
return toString(res.join(QStringLiteral(",")));
}
}
void Vt102EmulationTest::testTokenizing_data()
{
QTest::addColumn<QVector<uint>>("input");
QTest::addColumn<std::vector<TestEmulation::Item>>("expectedItems");
using ProcessToken = TestEmulation::ProcessToken;
using C = QVector<uint>;
using I = std::vector<TestEmulation::Item>;
/* clang-format off */
QTest::newRow("NUL") << C{'@' - '@'} << I{ProcessToken{token_ctl('@'), 0, 0}};
QTest::newRow("SOH") << C{'A' - '@'} << I{ProcessToken{token_ctl('A'), 0, 0}};
QTest::newRow("STX") << C{'B' - '@'} << I{ProcessToken{token_ctl('B'), 0, 0}};
QTest::newRow("ETX") << C{'C' - '@'} << I{ProcessToken{token_ctl('C'), 0, 0}};
QTest::newRow("EOT") << C{'D' - '@'} << I{ProcessToken{token_ctl('D'), 0, 0}};
QTest::newRow("ENQ") << C{'E' - '@'} << I{ProcessToken{token_ctl('E'), 0, 0}};
QTest::newRow("ACK") << C{'F' - '@'} << I{ProcessToken{token_ctl('F'), 0, 0}};
QTest::newRow("BEL") << C{'G' - '@'} << I{ProcessToken{token_ctl('G'), 0, 0}};
QTest::newRow("BS") << C{'H' - '@'} << I{ProcessToken{token_ctl('H'), 0, 0}};
QTest::newRow("TAB") << C{'I' - '@'} << I{ProcessToken{token_ctl('I'), 0, 0}};
QTest::newRow("LF") << C{'J' - '@'} << I{ProcessToken{token_ctl('J'), 0, 0}};
QTest::newRow("VT") << C{'K' - '@'} << I{ProcessToken{token_ctl('K'), 0, 0}};
QTest::newRow("FF") << C{'L' - '@'} << I{ProcessToken{token_ctl('L'), 0, 0}};
QTest::newRow("CR") << C{'M' - '@'} << I{ProcessToken{token_ctl('M'), 0, 0}};
QTest::newRow("SO") << C{'N' - '@'} << I{ProcessToken{token_ctl('N'), 0, 0}};
QTest::newRow("SI") << C{'O' - '@'} << I{ProcessToken{token_ctl('O'), 0, 0}};
QTest::newRow("DLE") << C{'P' - '@'} << I{ProcessToken{token_ctl('P'), 0, 0}};
QTest::newRow("XON") << C{'Q' - '@'} << I{ProcessToken{token_ctl('Q'), 0, 0}};
QTest::newRow("DC2") << C{'R' - '@'} << I{ProcessToken{token_ctl('R'), 0, 0}};
QTest::newRow("XOFF") << C{'S' - '@'} << I{ProcessToken{token_ctl('S'), 0, 0}};
QTest::newRow("DC4") << C{'T' - '@'} << I{ProcessToken{token_ctl('T'), 0, 0}};
QTest::newRow("NAK") << C{'U' - '@'} << I{ProcessToken{token_ctl('U'), 0, 0}};
QTest::newRow("SYN") << C{'V' - '@'} << I{ProcessToken{token_ctl('V'), 0, 0}};
QTest::newRow("ETB") << C{'W' - '@'} << I{ProcessToken{token_ctl('W'), 0, 0}};
QTest::newRow("CAN") << C{'X' - '@'} << I{ProcessToken{token_ctl('X'), 0, 0}};
QTest::newRow("EM") << C{'Y' - '@'} << I{ProcessToken{token_ctl('Y'), 0, 0}};
QTest::newRow("SUB") << C{'Z' - '@'} << I{ProcessToken{token_ctl('Z'), 0, 0}};
// [ is ESC and parsed differently
QTest::newRow("FS") << C{'\\' - '@'} << I{ProcessToken{token_ctl('\\'), 0, 0}};
QTest::newRow("GS") << C{']' - '@'} << I{ProcessToken{token_ctl(']'), 0, 0}};
QTest::newRow("RS") << C{'^' - '@'} << I{ProcessToken{token_ctl('^'), 0, 0}};
QTest::newRow("US") << C{'_' - '@'} << I{ProcessToken{token_ctl('_'), 0, 0}};
QTest::newRow("DEL") << C{127} << I{};
const uint ESC = '\033';
QTest::newRow("ESC 7") << C{ESC, '7'} << I{ProcessToken{token_esc('7'), 0, 0}};
QTest::newRow("ESC 8") << C{ESC, '8'} << I{ProcessToken{token_esc('8'), 0, 0}};
QTest::newRow("ESC D") << C{ESC, 'D'} << I{ProcessToken{token_esc('D'), 0, 0}};
QTest::newRow("ESC E") << C{ESC, 'E'} << I{ProcessToken{token_esc('E'), 0, 0}};
QTest::newRow("ESC H") << C{ESC, 'H'} << I{ProcessToken{token_esc('H'), 0, 0}};
QTest::newRow("ESC M") << C{ESC, 'M'} << I{ProcessToken{token_esc('M'), 0, 0}};
QTest::newRow("ESC Z") << C{ESC, 'Z'} << I{ProcessToken{token_esc('Z'), 0, 0}};
QTest::newRow("ESC c") << C{ESC, 'c'} << I{ProcessToken{token_esc('c'), 0, 0}};
QTest::newRow("ESC n") << C{ESC, 'n'} << I{ProcessToken{token_esc('n'), 0, 0}};
QTest::newRow("ESC o") << C{ESC, 'o'} << I{ProcessToken{token_esc('o'), 0, 0}};
QTest::newRow("ESC >") << C{ESC, '>'} << I{ProcessToken{token_esc('>'), 0, 0}};
QTest::newRow("ESC <") << C{ESC, '<'} << I{ProcessToken{token_esc('<'), 0, 0}};
QTest::newRow("ESC =") << C{ESC, '='} << I{ProcessToken{token_esc('='), 0, 0}};
QTest::newRow("ESC #3") << C{ESC, '#', '3'} << I{ProcessToken{token_esc_de('3'), 0, 0}};
QTest::newRow("ESC #4") << C{ESC, '#', '4'} << I{ProcessToken{token_esc_de('4'), 0, 0}};
QTest::newRow("ESC #5") << C{ESC, '#', '5'} << I{ProcessToken{token_esc_de('5'), 0, 0}};
QTest::newRow("ESC #6") << C{ESC, '#', '6'} << I{ProcessToken{token_esc_de('6'), 0, 0}};
QTest::newRow("ESC #8") << C{ESC, '#', '8'} << I{ProcessToken{token_esc_de('8'), 0, 0}};
QTest::newRow("ESC %G") << C{ESC, '%', 'G'} << I{ProcessToken{token_esc_cs('%', 'G'), 0, 0}};
QTest::newRow("ESC %@") << C{ESC, '%', '@'} << I{ProcessToken{token_esc_cs('%', '@'), 0, 0}};
QTest::newRow("ESC (0") << C{ESC, '(', '0'} << I{ProcessToken{token_esc_cs('(', '0'), 0, 0}};
QTest::newRow("ESC (A") << C{ESC, '(', 'A'} << I{ProcessToken{token_esc_cs('(', 'A'), 0, 0}};
QTest::newRow("ESC (B") << C{ESC, '(', 'B'} << I{ProcessToken{token_esc_cs('(', 'B'), 0, 0}};
QTest::newRow("ESC )0") << C{ESC, ')', '0'} << I{ProcessToken{token_esc_cs(')', '0'), 0, 0}};
QTest::newRow("ESC )A") << C{ESC, ')', 'A'} << I{ProcessToken{token_esc_cs(')', 'A'), 0, 0}};
QTest::newRow("ESC )B") << C{ESC, ')', 'B'} << I{ProcessToken{token_esc_cs(')', 'B'), 0, 0}};
QTest::newRow("ESC *0") << C{ESC, '*', '0'} << I{ProcessToken{token_esc_cs('*', '0'), 0, 0}};
QTest::newRow("ESC *A") << C{ESC, '*', 'A'} << I{ProcessToken{token_esc_cs('*', 'A'), 0, 0}};
QTest::newRow("ESC *B") << C{ESC, '*', 'B'} << I{ProcessToken{token_esc_cs('*', 'B'), 0, 0}};
QTest::newRow("ESC +0") << C{ESC, '+', '0'} << I{ProcessToken{token_esc_cs('+', '0'), 0, 0}};
QTest::newRow("ESC +A") << C{ESC, '+', 'A'} << I{ProcessToken{token_esc_cs('+', 'A'), 0, 0}};
QTest::newRow("ESC +B") << C{ESC, '+', 'B'} << I{ProcessToken{token_esc_cs('+', 'B'), 0, 0}};
QTest::newRow("ESC [8;12;45t") << C{ESC, '[', '8', ';', '1', '2', ';', '4', '5', 't'} << I{ProcessToken{token_csi_ps('t', 8), 12, 45}};
QTest::newRow("ESC [18t") << C{ESC, '[', '1', '8', 't'} << I{ProcessToken{token_csi_ps('t', 18), 0, 0}};
QTest::newRow("ESC [18;1;2t") << C{ESC, '[', '1', '8', ';', '1', ';', '2', 't'} << I{ProcessToken{token_csi_ps('t', 18), 1, 2}};
QTest::newRow("ESC [K") << C{ESC, '[', 'K'} << I{ProcessToken{token_csi_ps('K', 0), 0, 0}};
QTest::newRow("ESC [0K") << C{ESC, '[', '0', 'K'} << I{ProcessToken{token_csi_ps('K', 0), 0, 0}};
QTest::newRow("ESC [1K") << C{ESC, '[', '1', 'K'} << I{ProcessToken{token_csi_ps('K', 1), 0, 0}};
QTest::newRow("ESC [@") << C{ESC, '[', '@'} << I{ProcessToken{token_csi_pn('@'), 0, 0}};
QTest::newRow("ESC [12@") << C{ESC, '[', '1', '2', '@'} << I{ProcessToken{token_csi_pn('@'), 12, 0}};
QTest::newRow("ESC [H") << C{ESC, '[', 'H'} << I{ProcessToken{token_csi_pn('H'), 0, 0}};
QTest::newRow("ESC [24H") << C{ESC, '[', '2', '4', 'H'} << I{ProcessToken{token_csi_pn('H'), 24, 0}};
QTest::newRow("ESC [32,13H") << C{ESC, '[', '3', '2', ';', '1', '3', 'H'} << I{ProcessToken{token_csi_pn('H'), 32, 13}};
QTest::newRow("ESC [m") << C{ESC, '[', 'm'} << I{ProcessToken{token_csi_ps('m', 0), 0, 0}};
QTest::newRow("ESC [1m") << C{ESC, '[', '1', 'm'} << I{ProcessToken{token_csi_ps('m', 1), 0, 0}};
QTest::newRow("ESC [1;2m") << C{ESC, '[', '1', ';', '2', 'm'} << I{ProcessToken{token_csi_ps('m', 1), 0, 0}, ProcessToken{token_csi_ps('m', 2), 0, 0}};
QTest::newRow("ESC [5n") << C{ESC, '[', '5', 'n'} << I{ProcessToken{token_csi_ps('n', 5), 0, 0}};
QTest::newRow("ESC [?1h") << C{ESC, '[', '?', '1', 'h'} << I{ProcessToken{token_csi_pr('h', 1), 0, 0}};
QTest::newRow("ESC [?1l") << C{ESC, '[', '?', '1', 'l'} << I{ProcessToken{token_csi_pr('l', 1), 0, 0}};
QTest::newRow("ESC [?1r") << C{ESC, '[', '?', '1', 'r'} << I{ProcessToken{token_csi_pr('r', 1), 0, 0}};
QTest::newRow("ESC [?1s") << C{ESC, '[', '?', '1', 's'} << I{ProcessToken{token_csi_pr('s', 1), 0, 0}};
QTest::newRow("ESC [?1;2h") << C{ESC, '[', '?', '1', ';', '2', 'h'}
<< I{ProcessToken{token_csi_pr('h', 1), 0, 0}, ProcessToken{token_csi_pr('h', 2), 1, 0}};
QTest::newRow("ESC [?1;2l") << C{ESC, '[', '?', '1', ';', '2', 'l'}
<< I{ProcessToken{token_csi_pr('l', 1), 0, 0}, ProcessToken{token_csi_pr('l', 2), 1, 0}};
QTest::newRow("ESC [?1;2r") << C{ESC, '[', '?', '1', ';', '2', 'r'}
<< I{ProcessToken{token_csi_pr('r', 1), 0, 0}, ProcessToken{token_csi_pr('r', 2), 1, 0}};
QTest::newRow("ESC [?1;2s") << C{ESC, '[', '?', '1', ';', '2', 's'}
<< I{ProcessToken{token_csi_pr('s', 1), 0, 0}, ProcessToken{token_csi_pr('s', 2), 1, 0}};
QTest::newRow("ESC [? q") << C{ESC, '[', ' ', 'q'} << I{ProcessToken{token_csi_sp('q'), 0, 0}};
QTest::newRow("ESC [? 1q") << C{ESC, '[', '1', ' ', 'q'} << I{ProcessToken{token_csi_psp('q', 1), 0, 0}};
QTest::newRow("ESC [!p") << C{ESC, '[', '!', 'p'} << I{ProcessToken{token_csi_pe('p'), 0, 0}};
QTest::newRow("ESC [=c") << C{ESC, '[', '=', 'p'} << I{ProcessToken{token_csi_pq('p'), 0, 0}};
QTest::newRow("ESC [>c") << C{ESC, '[', '>', 'p'} << I{ProcessToken{token_csi_pg('p'), 0, 0}};
/* clang-format on */
}
void Vt102EmulationTest::testTokenizing()
{
QFETCH(QVector<uint>, input);
QFETCH(std::vector<TestEmulation::Item>, expectedItems);
TestEmulation em;
em.reset();
em.blockFurtherProcessing = true;
em._currentScreen->clearEntireScreen();
em.receiveChars(input);
QString printed = em._currentScreen->text(0, em._currentScreen->getColumns(), Screen::PlainText);
printed.chop(2); // Remove trailing space and newline
QCOMPARE(printed, QStringLiteral(""));
QCOMPARE(em.items, expectedItems);
}
void Vt102EmulationTest::testTokenizingVT52_data()
{
QTest::addColumn<QVector<uint>>("input");
QTest::addColumn<std::vector<TestEmulation::Item>>("expectedItems");
using ProcessToken = TestEmulation::ProcessToken;
using C = QVector<uint>;
using I = std::vector<TestEmulation::Item>;
/* clang-format off */
QTest::newRow("NUL") << C{'@' - '@'} << I{ProcessToken{token_ctl('@'), 0, 0}};
QTest::newRow("SOH") << C{'A' - '@'} << I{ProcessToken{token_ctl('A'), 0, 0}};
QTest::newRow("STX") << C{'B' - '@'} << I{ProcessToken{token_ctl('B'), 0, 0}};
QTest::newRow("ETX") << C{'C' - '@'} << I{ProcessToken{token_ctl('C'), 0, 0}};
QTest::newRow("EOT") << C{'D' - '@'} << I{ProcessToken{token_ctl('D'), 0, 0}};
QTest::newRow("ENQ") << C{'E' - '@'} << I{ProcessToken{token_ctl('E'), 0, 0}};
QTest::newRow("ACK") << C{'F' - '@'} << I{ProcessToken{token_ctl('F'), 0, 0}};
QTest::newRow("BEL") << C{'G' - '@'} << I{ProcessToken{token_ctl('G'), 0, 0}};
QTest::newRow("BS") << C{'H' - '@'} << I{ProcessToken{token_ctl('H'), 0, 0}};
QTest::newRow("TAB") << C{'I' - '@'} << I{ProcessToken{token_ctl('I'), 0, 0}};
QTest::newRow("LF") << C{'J' - '@'} << I{ProcessToken{token_ctl('J'), 0, 0}};
QTest::newRow("VT") << C{'K' - '@'} << I{ProcessToken{token_ctl('K'), 0, 0}};
QTest::newRow("FF") << C{'L' - '@'} << I{ProcessToken{token_ctl('L'), 0, 0}};
QTest::newRow("CR") << C{'M' - '@'} << I{ProcessToken{token_ctl('M'), 0, 0}};
QTest::newRow("SO") << C{'N' - '@'} << I{ProcessToken{token_ctl('N'), 0, 0}};
QTest::newRow("SI") << C{'O' - '@'} << I{ProcessToken{token_ctl('O'), 0, 0}};
QTest::newRow("DLE") << C{'P' - '@'} << I{ProcessToken{token_ctl('P'), 0, 0}};
QTest::newRow("XON") << C{'Q' - '@'} << I{ProcessToken{token_ctl('Q'), 0, 0}};
QTest::newRow("DC2") << C{'R' - '@'} << I{ProcessToken{token_ctl('R'), 0, 0}};
QTest::newRow("XOFF") << C{'S' - '@'} << I{ProcessToken{token_ctl('S'), 0, 0}};
QTest::newRow("DC4") << C{'T' - '@'} << I{ProcessToken{token_ctl('T'), 0, 0}};
QTest::newRow("NAK") << C{'U' - '@'} << I{ProcessToken{token_ctl('U'), 0, 0}};
QTest::newRow("SYN") << C{'V' - '@'} << I{ProcessToken{token_ctl('V'), 0, 0}};
QTest::newRow("ETB") << C{'W' - '@'} << I{ProcessToken{token_ctl('W'), 0, 0}};
QTest::newRow("CAN") << C{'X' - '@'} << I{ProcessToken{token_ctl('X'), 0, 0}};
QTest::newRow("EM") << C{'Y' - '@'} << I{ProcessToken{token_ctl('Y'), 0, 0}};
QTest::newRow("SUB") << C{'Z' - '@'} << I{ProcessToken{token_ctl('Z'), 0, 0}};
// [ is ESC and parsed differently
QTest::newRow("FS") << C{'\\' - '@'} << I{ProcessToken{token_ctl('\\'), 0, 0}};
QTest::newRow("GS") << C{']' - '@'} << I{ProcessToken{token_ctl(']'), 0, 0}};
QTest::newRow("RS") << C{'^' - '@'} << I{ProcessToken{token_ctl('^'), 0, 0}};
QTest::newRow("US") << C{'_' - '@'} << I{ProcessToken{token_ctl('_'), 0, 0}};
QTest::newRow("DEL") << C{127} << I{};
const uint ESC = '\033';
QTest::newRow("ESC A") << C{ESC, 'A'} << I{ProcessToken{token_vt52('A'), 0, 0}};
QTest::newRow("ESC B") << C{ESC, 'B'} << I{ProcessToken{token_vt52('B'), 0, 0}};
QTest::newRow("ESC C") << C{ESC, 'C'} << I{ProcessToken{token_vt52('C'), 0, 0}};
QTest::newRow("ESC D") << C{ESC, 'D'} << I{ProcessToken{token_vt52('D'), 0, 0}};
QTest::newRow("ESC F") << C{ESC, 'F'} << I{ProcessToken{token_vt52('F'), 0, 0}};
QTest::newRow("ESC G") << C{ESC, 'G'} << I{ProcessToken{token_vt52('G'), 0, 0}};
QTest::newRow("ESC H") << C{ESC, 'H'} << I{ProcessToken{token_vt52('H'), 0, 0}};
QTest::newRow("ESC I") << C{ESC, 'I'} << I{ProcessToken{token_vt52('I'), 0, 0}};
QTest::newRow("ESC J") << C{ESC, 'J'} << I{ProcessToken{token_vt52('J'), 0, 0}};
QTest::newRow("ESC K") << C{ESC, 'K'} << I{ProcessToken{token_vt52('K'), 0, 0}};
QTest::newRow("ESC Yab") << C{ESC, 'Y', 'a', 'b'} << I{ProcessToken{token_vt52('Y'), 'a', 'b'}};
QTest::newRow("ESC Z") << C{ESC, 'Z'} << I{ProcessToken{token_vt52('Z'), 0, 0}};
QTest::newRow("ESC <") << C{ESC, '<'} << I{ProcessToken{token_vt52('<'), 0, 0}};
QTest::newRow("ESC =") << C{ESC, '='} << I{ProcessToken{token_vt52('='), 0, 0}};
QTest::newRow("ESC >") << C{ESC, '>'} << I{ProcessToken{token_vt52('>'), 0, 0}};
/* clang-format on */
}
void Vt102EmulationTest::testTokenizingVT52()
{
QFETCH(QVector<uint>, input);
QFETCH(std::vector<TestEmulation::Item>, expectedItems);
TestEmulation em;
em.reset();
em.resetMode(MODE_Ansi);
em.blockFurtherProcessing = true;
em._currentScreen->clearEntireScreen();
em.receiveChars(input);
QString printed = em._currentScreen->text(0, em._currentScreen->getColumns(), Screen::PlainText);
printed.chop(2); // Remove trailing space and newline
QCOMPARE(printed, QStringLiteral(""));
QCOMPARE(em.items, expectedItems);
}
void Vt102EmulationTest::testTokenFunctions()
{
QCOMPARE(token_construct(0, 0, 0), TY_CONSTRUCT(0, 0, 0));
......
......@@ -7,6 +7,9 @@
#ifndef VT102EMULATIONTEST_H
#define VT102EMULATIONTEST_H
#include <variant>
#include <vector>
#include <QObject>
#include "Vt102Emulation.h"
......@@ -23,24 +26,109 @@ private Q_SLOTS:
void testTokenFunctions();
void testParse();
void testTokenizing_data();
void testTokenizing();
void testTokenizingVT52_data();
void testTokenizingVT52();
private:
static void sendAndCompare(TestEmulation *em, const char *input, size_t inputLen, const QString &expectedPrint, const QByteArray &expectedSent);
};
class TestEmulation : public Vt102Emulation {
class TestEmulation : public Vt102Emulation
{
Q_OBJECT
// Give us access to protected functions
friend class Vt102EmulationTest;
QByteArray lastSent;
public:
struct ProcessToken {
int code;
int p;
int q;
bool operator==(const ProcessToken &rhs) const
{
return code == rhs.code && p == rhs.p && q == rhs.q;
}
};
struct ProcessSessionAttributeRequest {
std::vector<uint> chars;
bool operator==(const ProcessSessionAttributeRequest &rhs) const
{
return chars == rhs.chars;
}
};
struct ProcessChecksumRequest {
std::vector<int> args;
bool operator==(const ProcessChecksumRequest &rhs) const
{
return args == rhs.args;
}
};
struct DecodingError {
bool operator==(const DecodingError &) const
{
return true;
}
};
using Item = std::variant<ProcessToken, ProcessSessionAttributeRequest, ProcessChecksumRequest, DecodingError>;
private:
std::vector<Item> items;
bool blockFurtherProcessing = false;
public:
void receiveChars(const QVector<uint> &c) override
{
Vt102Emulation::receiveChars(c);
}
public:
void sendString(const QByteArray &string) override
{
lastSent = string;
Vt102Emulation::sendString(string);
}
void reportDecodingError() override
{
items.push_back(DecodingError{});
}
void processToken(int code, int p, int q) override
{
items.push_back(ProcessToken{code, p, q});
if (!blockFurtherProcessing) {
Vt102Emulation::processToken(code, p, q);
}
}
void processSessionAttributeRequest(int tokenSize) override
{
items.push_back(ProcessSessionAttributeRequest{std::vector<uint>(tokenBuffer, tokenBuffer + tokenSize)});
if (!blockFurtherProcessing) {
Vt102Emulation::processSessionAttributeRequest(tokenSize);
}
}
void processChecksumRequest(int argc, int argv[]) override
{
ProcessChecksumRequest item;
for (int i = 0; i < argc; i++) {
item.args.push_back(argv[i]);
}
items.push_back(item);
if (!blockFurtherProcessing) {
Vt102Emulation::processChecksumRequest(argc, argv);
}
}
};
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment