#include "qbrainfuck.h" #include "ui_qbrainfuck.h" QBrainfuck::QBrainfuck(QWidget *parent) : QMainWindow(parent), ui(new Ui::QBrainfuck) { ui->setupUi(this); } QBrainfuck::~QBrainfuck() { delete ui; } void QBrainfuck::on_encodeButton_clicked() { QByteArray text = ui->textTextEdit->document()->toPlainText().toLatin1(); // First pass : find decades/steps QList decades; // Store the decades for initial loop decades.append(0); QList array; // Store the program's memory array.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 arrayIterator; for (arrayIterator = array.begin(); arrayIterator != array.end(); ++arrayIterator) { if (qAbs(*arrayIterator-*textIterator) < max_diff) { max_diff = qAbs(*arrayIterator-*textIterator); index = arrayIterator; } } // Add step and insert current value in the array, 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()); array.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(""); int ptr = 0; QByteArray text = ui->programTextEdit->document()->toPlainText().toLatin1(); QByteArray array = QByteArray(ui->arraySpinBox->value(), (char)0); QByteArray input = ui->inputLineEdit->text().toLatin1(); QByteArray::const_iterator last_textIterator; QByteArray::const_iterator inputIterator = input.constBegin(); QByteArray::const_iterator textIterator; int loopCounter = 0; for (textIterator = text.constBegin(); textIterator != text.constEnd(); ++textIterator) { switch (*textIterator) { case '>': ptr++; if (ptr >= ui->arraySpinBox->value()) { QMessageBox::critical(this, "QBrainfuck", "Error: Pointer went upper than array's length"); return; } break; case '<': ptr--; if (ptr < 0) { QMessageBox::critical(this, "QBrainfuck", "Error: Pointer went under 0"); return; } break; case '+': array[ptr] = array.at(ptr) + 1; break; case '-': array[ptr] = array.at(ptr) - 1; break; case '.': ui->textTextEdit->insertPlainText(QString(array.at(ptr))); break; case ',': array[ptr] = *inputIterator; inputIterator++; break; case '[': last_textIterator = textIterator; loopCounter = 0; break; case ']': if(array.at(ptr)!=0) { textIterator = last_textIterator; loopCounter++; if (loopCounter >= ui->loopSpinBox->value()) { QMessageBox::critical(this, "QBrainfuck", "Error: Loop too long"); return; } } break; } } } 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: 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()); } }