#include "qbrainfuck.h" #include "ui_qbrainfuck.h" QBrainfuck::QBrainfuck(QWidget *parent) : QMainWindow(parent), ui(new Ui::QBrainfuck) { ui->setupUi(this); decoder = new DecoderThread(); QObject::connect(decoder, &DecoderThread::programDecoded, this, &QBrainfuck::setText); QObject::connect(decoder, &DecoderThread::errorMessage, this, &QBrainfuck::errorMessage); } QBrainfuck::~QBrainfuck() { delete ui; } void QBrainfuck::on_encodeButton_clicked() { QByteArray text = ui->textTextEdit->document()->toPlainText().toLatin1(); ui->programTextEdit->setPlainText(""); // First pass : find decades/steps QList decades; // Store the decades for initial loop decades.append(0); QList memory; // Store the program's memory memory.append(0); QList steps; // Store the steps to construct the program QByteArray::const_iterator textIterator; for (textIterator = text.constBegin(); textIterator != text.constEnd(); ++textIterator) { int max_diff = ui->maxSignsSpinBox->value()+1; QList::iterator index; // Find nearest memory's case and store it QList::iterator memoryIterator; for (memoryIterator = memory.begin(); memoryIterator != memory.end(); ++memoryIterator) { if (qAbs(*memoryIterator-*textIterator) < max_diff) { max_diff = qAbs(*memoryIterator-*textIterator); index = memoryIterator; } } // Add step and insert current value in the memory, else add a decade if we don't find a case nearer than max_diff if (max_diff <= ui->maxSignsSpinBox->value()) { steps.append(*index); *index = *textIterator; } else { steps.append(qRound(*textIterator/(float)ui->decadesSpinBox->value())*ui->decadesSpinBox->value()); decades.append(qRound(*textIterator/(float)ui->decadesSpinBox->value())*ui->decadesSpinBox->value()); memory.append(*textIterator); } } qSort(decades); // Second pass : write program QString program = ""; for (int i = 0; i < ui->decadesSpinBox->value(); ++i) { program += "+"; } program += "\["; QList::iterator decadesIterator; for (decadesIterator = decades.begin()+1; decadesIterator != decades.end(); ++decadesIterator) { program += ">"; for (int i = 0; i < *decadesIterator; i+=ui->decadesSpinBox->value()) { program += "+"; } } for (int i = 0; i < decades.size()-1; ++i) { program += "<"; } program += "-]"; int prev_ptr = 0; QList::const_iterator stepsIterator; textIterator = text.constBegin(); for (stepsIterator = steps.constBegin(); stepsIterator != steps.constEnd(); ++stepsIterator) { int next_ptr = decades.indexOf(*stepsIterator); if (next_ptr > prev_ptr) { for (int i = 0; i < next_ptr-prev_ptr; ++i) { program += ">"; } } else { for (int i = 0; i < prev_ptr-next_ptr; ++i) { program += "<"; } } if (*textIterator > *stepsIterator) { for (int i = 0; i < *textIterator-*stepsIterator; ++i) { program += "+"; } } else { for (int i = 0; i < *stepsIterator-*textIterator; ++i) { program += "-"; } } program += "."; prev_ptr = next_ptr; decades[next_ptr] = *textIterator; ++textIterator; } ui->programTextEdit->setPlainText(program); } void QBrainfuck::on_decodeButton_clicked() { ui->textTextEdit->setPlainText(""); QByteArray program = ui->programTextEdit->document()->toPlainText().toLatin1(); QByteArray input = ui->inputLineEdit->text().toLatin1(); decoder->decode(program, input); } void QBrainfuck::on_motifButton_clicked() { QString motif = ui->motifTextEdit->document()->toPlainText(); QByteArray program = ui->programTextEdit->document()->toPlainText().toLatin1(); if (motif.contains(QRegExp(">|<|\\+|-|\\.|,|\\[|\\]"))) { QMessageBox::critical(this, "QBrainfuck error", "Error: Motif contains Brainfuck characters"); return; } QByteArray::const_iterator programIterator; for (programIterator = program.constBegin(); programIterator != program.constEnd(); ++programIterator) { switch (*programIterator) { case '>': case '<': case '+': case '-': case '.': case ',': case '[': case ']': int index = motif.indexOf(QRegExp(ui->regexLineEdit->text())); if (index==-1) { motif += *programIterator; } else { motif.replace(index, 1, *programIterator); } break; } } ui->resultTextEdit->setPlainText(motif); } void QBrainfuck::on_textTextEdit_textChanged() { ui->textLabel->setText("Text length: " + QString().setNum(ui->textTextEdit->document()->toPlainText().length())); } void QBrainfuck::on_programTextEdit_textChanged() { ui->programLabel->setText("Program length: " + QString().setNum(ui->programTextEdit->document()->toPlainText().count(QRegExp(">|<|\\+|-|\\.|,|\\[|\\]")))); } void QBrainfuck::on_motifTextEdit_textChanged() { ui->motifLabel->setText("Motif length: " + QString().setNum(ui->motifTextEdit->document()->toPlainText().count(QRegExp(ui->regexLineEdit->text())))); } void QBrainfuck::on_regexLineEdit_textChanged(const QString &arg1) { on_motifTextEdit_textChanged(); } void QBrainfuck::on_saveButton_clicked() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilter("Json Files (*.json);;Txt Files (*.txt)"); dialog.setDefaultSuffix("json"); dialog.setAcceptMode(QFileDialog::AcceptSave); if (dialog.exec()) { QFile saveFile(dialog.selectedFiles().first()); if (!saveFile.open(QIODevice::WriteOnly)) { return; } if (dialog.selectedNameFilter() == "Json Files (*.json)") { QJsonObject jsonObject; jsonObject["text"] = ui->textTextEdit->document()->toPlainText(); jsonObject["program"] = ui->programTextEdit->document()->toPlainText(); jsonObject["motif"] = ui->motifTextEdit->document()->toPlainText(); jsonObject["result"] = ui->resultTextEdit->document()->toPlainText(); QJsonDocument jsonDoc(jsonObject); saveFile.write(jsonDoc.toJson()); } else { saveFile.write(ui->textTextEdit->document()->toPlainText().toUtf8() + "\n\n"); saveFile.write(ui->programTextEdit->document()->toPlainText().toUtf8() + "\n\n"); saveFile.write(ui->motifTextEdit->document()->toPlainText().toUtf8() + "\n\n"); saveFile.write(ui->resultTextEdit->document()->toPlainText().toUtf8() + "\n\n"); } } } void QBrainfuck::on_loadButton_clicked() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilter("Json Files (*.json)"); dialog.setDefaultSuffix("json"); dialog.setAcceptMode(QFileDialog::AcceptOpen); if (dialog.exec()) { QFile loadFile(dialog.selectedFiles().first()); if (!loadFile.open(QIODevice::ReadOnly)) { return; } QByteArray saveData = loadFile.readAll(); QJsonDocument jsonDoc(QJsonDocument::fromJson(saveData)); QJsonObject jsonObject = jsonDoc.object(); ui->textTextEdit->setPlainText(jsonObject["text"].toString()); ui->programTextEdit->setPlainText(jsonObject["program"].toString()); ui->motifTextEdit->setPlainText(jsonObject["motif"].toString()); ui->resultTextEdit->setPlainText(jsonObject["result"].toString()); } } void QBrainfuck::setText(QString text) { ui->textTextEdit->setPlainText(text); } void QBrainfuck::errorMessage(QString message) { QMessageBox::critical(this, "QBrainfuck error", "Error: " + message); }