Changeset - 0a7f0391eb9c
[Not reviewed]
default
0 1 0
Hasan Yavuz Ă–ZDERYA - 9 years ago 2016-09-05 16:00:45
hy@ozderya.net
improve command parsing, '\' itself can be escaped now
1 file changed with 44 insertions and 8 deletions:
0 comments (0 inline, 0 general)
src/commandedit.cpp
Show inline comments
 
@@ -51,50 +51,50 @@ QValidator::State HexCommandValidator::v
 
    {
 
        input = input.replace(" ", "");
 
        input.replace(QRegExp("([0-9A-F]{2}(?!$))"), "\\1 ");
 
        if (pos == input.size()-1) pos = input.size();
 
        r = QRegExpValidator::validate(input, pos);
 
    }
 

	
 
    return r;
 
}
 

	
 
CommandEdit::CommandEdit(QWidget *parent) :
 
    QLineEdit(parent)
 
{
 
    hexValidator = new HexCommandValidator(this);
 
    asciiValidator = new QRegExpValidator(QRegExp("[\\x0000-\\x007F]+"));
 
    ascii_mode = true;
 
    setValidator(asciiValidator);
 
}
 

	
 
CommandEdit::~CommandEdit()
 
{
 
    delete hexValidator;
 
}
 

	
 
QString unEscape(QString str);
 
QString escape(QString str);
 
static QString unEscape(QString str);
 
static QString escape(QString str);
 

	
 
void CommandEdit::setMode(bool ascii)
 
{
 
    ascii_mode = ascii;
 
    if (ascii)
 
    {
 
        setValidator(asciiValidator);
 

	
 
        auto hexText = text().remove(" ");
 
        // try patching HEX string in case of missing nibble so that
 
        // input doesn't turn into gibberish
 
        if (hexText.size() % 2 == 1)
 
        {
 
            hexText.replace(hexText.size()-1, 1, "3F"); // 0x3F = '?'
 
            qWarning() << "Broken byte in hex command is replaced. Check your command!";
 
        }
 

	
 
        setText(escape(QByteArray::fromHex(hexText.toLatin1())));
 
    }
 
    else
 
    {
 
        setValidator(hexValidator);
 
        setText(unEscape(text()).toLatin1().toHex());
 
    }
 
@@ -104,39 +104,75 @@ void CommandEdit::keyPressEvent(QKeyEven
 
{
 
    if (ascii_mode)
 
    {
 
        QLineEdit::keyPressEvent(event);
 
        return;
 
    }
 

	
 
    if (event->key() == Qt::Key_Backspace && !hasSelectedText())
 
    {
 
        int cursor = cursorPosition();
 
        if (cursor != 0 && text()[cursor-1] == ' ')
 
        {
 
            setCursorPosition(cursor-1);
 
        }
 
    }
 

	
 
    QLineEdit::keyPressEvent(event);
 
}
 

	
 
QString CommandEdit::unEscapedText()
 
{
 
    return unEscape(text());
 
}
 

	
 
QString unEscape(QString str)
 
static QString unEscape(QString str)
 
{
 
    str.replace("\\n", "\n");
 
    str.replace("\\r", "\r");
 
    str.replace("\\t", "\t");
 
    return str;
 
    const QMap<QString, QString> replacements({
 
            {"\\\\", "\\"},
 
            {"\\n", "\n"},
 
            {"\\r", "\r"},
 
            {"\\t", "\t"}
 
        });
 

	
 
    QString result;
 

	
 
    int i = 0;
 
    while (i < str.size())
 
    {
 
        bool found = false;
 

	
 
        for (auto k : replacements.keys())
 
        {
 
            // has enough text left?
 
            if (str.size() - i < 1) continue;
 

	
 
            // try matching the key at current position
 
            if (k == str.midRef(i, k.size()))
 
            {
 
                // append replacement
 
                result += replacements[k];
 
                i += k.size();
 
                found = true;
 
                break; // skip other keys
 
            }
 
        }
 

	
 
        if (!found)
 
        {
 
            // append unmatched character
 
            result += str[i];
 
            i++;
 
        }
 
    }
 

	
 
    return result;
 
}
 

	
 
QString escape(QString str)
 
static QString escape(QString str)
 
{
 
    str.replace("\\", "\\\\");
 
    str.replace("\n", "\\n");
 
    str.replace("\r", "\\r");
 
    str.replace("\t", "\\t");
 
    return str;
 
}
0 comments (0 inline, 0 general)