From: hama Date: Sun, 31 Jan 2016 17:40:59 +0000 (+0100) Subject: rebackgui: checksum works X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=db6ccd91f9722997fceab97becd058bd73ae155f;p=reqt rebackgui: checksum works --- diff --git a/appl/rebackgui/BackupEngine.cpp b/appl/rebackgui/BackupEngine.cpp index 2b28086..5e7eadc 100644 --- a/appl/rebackgui/BackupEngine.cpp +++ b/appl/rebackgui/BackupEngine.cpp @@ -21,6 +21,8 @@ bool BackupEngine::m_searchReady = false; QMutex BackupEngine::m_mutex; QChar BackupEngine::m_separator = '\t'; QString BackupEngine::m_separatorString = "\t"; +QStringList ChecksumTask::m_checksumInfo; +bool ChecksumTask::m_sourceProcessingReady = false; /** * Constructor. @@ -78,6 +80,9 @@ bool BackupEngine::log(const QString& message){ /** * Constructor. * + * @param compareWithTarget false: all files will be found
+ * otherwise: only not existing or newer files will + * be found * @param name name of the task * @param filePatterns only files which match the patterns will be found * @param dirPatterns only subdirectories which matches the patterns will be entered @@ -85,15 +90,15 @@ bool BackupEngine::log(const QString& message){ * @param targetDir the base target directory * @param mainWindow the GUI module, the parent */ -SearchTask::SearchTask(const QString& name, +SearchTask::SearchTask(bool compareWithTarget, const QString& name, const QString& filePatterns, const QString& dirPatterns, const QStringList& sourceDirs, const QString& targetDir, MainWindow* mainWindow) : BackupEngine(name, sourceDirs, targetDir, mainWindow), m_fileMatcher(filePatterns), - m_dirMatcher(dirPatterns) + m_dirMatcher(dirPatterns), + m_compareWithTarget(compareWithTarget) { - } /** @@ -106,12 +111,13 @@ void SearchTask::run() QString targetDir, sourceDir; for (int ix = 0; ix < m_sourceDirs.size(); ix++){ sourceDir = m_sourceDirs.at(ix); - targetDir = m_targetDirs.at(ix) + ReFileUtils::nodeOf(sourceDir); - processOneDirectory(sourceDir, targetDir, ix); + if (m_compareWithTarget) + targetDir = m_targetDirs.at(ix) + ReFileUtils::nodeOf(sourceDir); + searchOneDirectory(sourceDir, targetDir, ix); } m_searchReady = true; m_mainWindow->externalLog(tr( - "Search finished: to copy: %1 with %2 matching: %3 total: %4 " + "Search finished: to process: %1 with %2 matching: %3 total: %4 " "subdirs: %5 runtime: %6") .arg(m_hotFiles) .arg(ReQStringUtils::readableSize(m_hotBytes)) @@ -132,12 +138,16 @@ void SearchTask::run() * it is newer or has another size * @param index the index of the base directory in m_sourceDirs */ -void SearchTask::processOneDirectory(const QString& source, +void SearchTask::searchOneDirectory(const QString& source, const QString& target, int index){ QDirIterator it(source); - QString prefix; QString info, node; int lengthBase = m_sourceDirs.at(index).length(); + assert(index < 0x7fff); + QString prefix; + m_mutex.lock(); + m_totalDirs++; + m_mutex.unlock(); if (source.length() > lengthBase){ prefix = QChar(1 + index) + source.mid(lengthBase) + OS_SEPARATOR_STR + m_separator; @@ -159,7 +169,9 @@ void SearchTask::processOneDirectory(const QString& source, } else { qint64 diff = 0; bool doCopy = false; - if (target.isEmpty()) + if (! m_compareWithTarget) + doCopy = true; + else if (target.isEmpty()) doCopy = true; else { QFileInfo trg(target + it.fileName()); @@ -175,7 +187,6 @@ void SearchTask::processOneDirectory(const QString& source, } } if (doCopy){ - assert(index < 0x7fff); info = prefix + it.fileName(); } m_mutex.lock(); @@ -209,11 +220,8 @@ void SearchTask::processOneDirectory(const QString& source, subTarget.clear(); else subTarget += OS_SEPARATOR_STR; - processOneDirectory(it2.filePath(), subTarget, index); - m_mutex.lock(); - m_totalDirs++; - m_mutex.unlock(); } + searchOneDirectory(it2.filePath(), subTarget, index); } } } @@ -231,7 +239,8 @@ BackupTask::BackupTask(const QString& name, const QStringList& sourceDirs, const QString& targetDir, MainWindow* mainWindow) : BackupEngine(name, sourceDirs, targetDir, mainWindow), - m_lastRelPath() + m_lastRelPath(), + m_buffer() { } @@ -253,7 +262,7 @@ void BackupTask::copyFile(int index, const QString& relPath, bool isFile; if (! ReFileUtils::isDirectory(targetDir, &isFile)){ if (isFile){ - if (_unlink(I18N::s2b(targetDir).constData()) != 0) + if (_unlink(I18N::s2b(targetDir).constData()) != 0) error(tr("cannot remove file (for making a directory (%1): %2") .arg(errno).arg(targetDir)); } @@ -318,8 +327,203 @@ void BackupTask::run() .arg(ReQStringUtils::readableDuration(estimated))); } } - m_mainWindow->externalTaskFinished(tr("backup complete after %1. Errors: %2") - .arg(ReQStringUtils::readableDuration( - QDateTime::currentMSecsSinceEpoch() - start)) - .arg(m_mainWindow->errors())); + m_mainWindow->externalTaskFinished(tr("backup complete after %1. Errors: %2") + .arg(ReQStringUtils::readableDuration( + QDateTime::currentMSecsSinceEpoch() - start)) + .arg(m_mainWindow->errors())); +} + +/** + * Constructor. + * + * @param name name of the task + * @param sourceDirs the list of source directories to inspect + * @param targetDir the base of the target directories + * @param mainWindow the GUI module + */ +ChecksumTask::ChecksumTask(const QString& name, + const QStringList& sourceDirs, const QString& targetDir, + MainWindow* mainWindow) : + BackupEngine(name, sourceDirs, targetDir, mainWindow), + m_lastRelPath(), + m_buffer() +{ + m_buffer.resize(1024*1024); +} + +/** + * Calculates the checksum of a given file. + * + * @param isSource true: the file is taken from the source
+ * true: the file is taken from the target + * @param index index in source/target dirs (dependin on isSource) + * @param relpath the relative path from the base (source or target) + * @param node the node of the file (without path) + * @return "": checksum could not be calculated
+ * otherwise: the checksum of the file + */ +QByteArray ChecksumTask::buildChecksum(bool isSource, int index, + const QString& relpath, const QString& node) +{ + QString filename; + if (isSource) + filename = m_sourceDirs.at(index) + relpath + node; + else + filename = m_targetDirs.at(index) + relpath + node; + qint64 size = 0; + QByteArray rc = ReFileUtils::buildChecksum(filename, m_buffer, &size).toHex(); + m_mutex.lock(); + m_processedFiles++; + m_processedBytes += size; + m_mutex.unlock(); + if (rc.isEmpty()){ + error(QObject::tr("cannot build checksum: %1").arg(filename) ); + } else { + m_mainWindow->addToFileList(QString(rc) + " " + filename); + } + return rc; } + +/** + * Constructor. + * + * @param name name of the task + * @param sourceDirs the list of source directories to inspect + * @param targetDir the base of the target directories + * @param mainWindow the GUI module + */ +ChecksumOfSourceTask::ChecksumOfSourceTask(const QString& name, + const QStringList& sourceDirs, const QString& targetDir, + MainWindow* mainWindow) : + ChecksumTask(name, sourceDirs, targetDir, mainWindow) +{ +} + +/** + * Calculats the checksum of source files. + */ +void ChecksumOfSourceTask::run() +{ + qint64 start = QDateTime::currentMSecsSinceEpoch(); + QString relPath, node; + QString info; + int count = 0; + while (true){ + m_mutex.lock(); + if (m_files.size() == 0) + info.clear(); + else{ + info = m_files.first(); + m_files.removeFirst(); + } + m_mutex.unlock(); + if (info.isEmpty()){ + if (m_searchReady) + break; + else + QThread::msleep(50); + } else { + int index = int(info.at(0).unicode()) - 1; + int pos = info.indexOf(m_separator, 1); + if (pos == 1) + relPath.clear(); + else + relPath = info.mid(1, pos - 1); + node = info.mid(pos + 1); + QByteArray checksum = buildChecksum(true, index, relPath, node); + count++; + if (! checksum.isEmpty()){ + QString info = QChar(1 + index) + relPath + m_separator + + node + m_separatorString + checksum; + m_mutex.lock(); + m_checksumInfo.append(info); + m_mutex.unlock(); + } + } + } + m_sourceProcessingReady = true; + qint64 now = QDateTime::currentMSecsSinceEpoch(); + m_mainWindow->externalTaskFinished(tr("Building source checksum complete after %1. Processed: %2") + .arg(ReQStringUtils::readableDuration(now - start)) + .arg(count)); +} + +/** + * Constructor. + * + * @param name name of the task + * @param sourceDirs the list of source directories to inspect + * @param targetDir the base of the target directories + * @param mainWindow the GUI module + */ +ChecksumOfTargetTask::ChecksumOfTargetTask(const QString& name, + const QStringList& sourceDirs, const QString& targetDir, + MainWindow* mainWindow) : + ChecksumTask(name, sourceDirs, targetDir, mainWindow) +{ + +} + +/** + * Calculats the checksum of target files. + */ +void ChecksumOfTargetTask::run() +{ + qint64 start = QDateTime::currentMSecsSinceEpoch(); + QString relPath, node; + qint64 now = 0; + QString info; + int count = 0; + while (true){ + m_mutex.lock(); + if (m_checksumInfo.size() == 0) + info.clear(); + else{ + info = m_checksumInfo.first(); + m_checksumInfo.removeFirst(); + } + m_mutex.unlock(); + if (info.isEmpty()){ + if (m_sourceProcessingReady) + break; + else + QThread::msleep(50); + } else { + int index = int(info.at(0).unicode()) - 1; + int pos = info.indexOf(m_separator, 1); + if (pos == 1) + relPath.clear(); + else + relPath = info.mid(1, pos - 1); + int pos2 = info.indexOf(m_separator, pos + 1); + node = info.mid(pos + 1, pos2 - pos - 1); + QString sourceChecksum = info.mid(pos2 + 1); + + QByteArray checksum = buildChecksum(false, index, relPath, node); + count++; + if (! checksum.isEmpty()){ + if (checksum != sourceChecksum) + error(QObject::tr("checksum differs: ") + relPath + node + + " [" + sourceChecksum + "/" + checksum + "]"); + } + now = QDateTime::currentMSecsSinceEpoch(); + qint64 estimated = (now - start) * m_hotBytes * 2 / max(1LL, m_processedBytes); + m_mainWindow->externalAppend(ReGuiQueueItem::StatusLine, NULL, + tr("%1 of %2 (%3 of %4) %5 MB/sec Remaining: %6 of %7") + .arg(m_processedFiles).arg(m_hotFiles * 2) + .arg(ReQStringUtils::readableSize(m_processedBytes)) + .arg(ReQStringUtils::readableSize(m_hotBytes * 2)) + .arg(m_processedBytes / 1024.0 / 1024 / (now - start) * 1000, 0, 'f', 3) + .arg(ReQStringUtils::readableDuration(estimated - (now - start))) + .arg(ReQStringUtils::readableDuration(estimated))); + + } + } + now = QDateTime::currentMSecsSinceEpoch(); + m_mainWindow->externalTaskFinished(tr("Building target checksums complete after %1. Processed: %2 Errors: %3") + .arg(ReQStringUtils::readableDuration(now - start)) + .arg(count) + .arg(m_mainWindow->errors())); +} + + diff --git a/appl/rebackgui/BackupEngine.hpp b/appl/rebackgui/BackupEngine.hpp index 07f0a1f..5171ee1 100644 --- a/appl/rebackgui/BackupEngine.hpp +++ b/appl/rebackgui/BackupEngine.hpp @@ -10,6 +10,9 @@ #define BACKUPPROCESSOR_HPP +/** + * Abstract base class of executing backup and related tasks. + */ class BackupEngine : public QThread { public: @@ -32,6 +35,7 @@ protected: QString m_name; public: static bool m_shouldStop; + /// Entry: TAB static QStringList m_files; static qint64 m_hotBytes; static int m_processedFiles; @@ -46,37 +50,99 @@ public: static QString m_separatorString; }; -class SearchTask : public BackupEngine +/** + * Reads filenames from the file list and copies the files from source to target. + */ +class BackupTask : public BackupEngine { public: - SearchTask(const QString& name, - const QString& filePatterns, const QString& dirPatterns, - const QStringList& sourceDirs, const QString& targetDir, + BackupTask(const QString& name, const QStringList& sourceDirs, const QString& targetDir, MainWindow* mainWindow); public: virtual void run(); +protected: + void copyFile(int index, const QString& relpath, + const QString& node); private: - QString m_filePatterns; - QString m_dirPatterns; - ReIncludeExcludeMatcher m_fileMatcher; - ReIncludeExcludeMatcher m_dirMatcher; - void processOneDirectory(const QString& source, const QString& target, - int index); + QString m_lastRelPath; + QByteArray m_buffer; }; -class BackupTask : public BackupEngine +/** + * Abstract base class of the checksum test classes. + */ +class ChecksumTask : public BackupEngine { public: - BackupTask(const QString& name, const QStringList& sourceDirs, const QString& targetDir, + ChecksumTask(const QString& name, const QStringList& sourceDirs, const QString& targetDir, MainWindow* mainWindow); public: - virtual void run(); + virtual void run() = 0; protected: - void copyFile(int index, const QString& relpath, + QByteArray buildChecksum( bool isSource, int index, const QString& relpath, const QString& node); -private: +protected: QString m_lastRelPath; QByteArray m_buffer; +protected: + /// Entry: TABTAB + static QStringList m_checksumInfo; +public: + static bool m_sourceProcessingReady; +}; + +/** + Handles the checksum activities for the source files. + + * Reads from the file list, calculates the checksum of the source file and + * writes an entry into the checksum file list + */ +class ChecksumOfSourceTask : public ChecksumTask +{ +public: + ChecksumOfSourceTask(const QString& name, const QStringList& sourceDirs, const QString& targetDir, + MainWindow* mainWindow); +public: + virtual void run(); }; +/** + Handles the checksum activities for the target files. + + * Reads from the checksum file list, calculates the checksum of the target file + * and compares it with the checksum of the source file. + */ +class ChecksumOfTargetTask : public ChecksumTask +{ +public: + ChecksumOfTargetTask(const QString& name, const QStringList& sourceDirs, const QString& targetDir, + MainWindow* mainWindow); +public: + virtual void run(); +}; + +/** + * Searches the files matching the file patterns and writes them into the file list. + */ +class SearchTask : public BackupEngine +{ +public: + SearchTask(bool compareWithTarget, const QString& name, + const QString& filePatterns, const QString& dirPatterns, + const QStringList& sourceDirs, const QString& targetDir, + MainWindow* mainWindow); +public: + virtual void run(); +private: + QString m_filePatterns; + QString m_dirPatterns; + ReIncludeExcludeMatcher m_fileMatcher; + ReIncludeExcludeMatcher m_dirMatcher; + void searchOneDirectory(const QString& source, const QString& target, + int index); +private: + bool m_compareWithTarget; +}; + + #endif // BACKUPPROCESSOR_HPP diff --git a/appl/rebackgui/mainwindow.cpp b/appl/rebackgui/mainwindow.cpp index 59887d7..293657c 100644 --- a/appl/rebackgui/mainwindow.cpp +++ b/appl/rebackgui/mainwindow.cpp @@ -10,7 +10,7 @@ #include "aboutdialog.hpp" #include -const QString VERSION("2016.01.30"); +const QString VERSION("2016.01.31"); /** * Constructor. @@ -28,6 +28,8 @@ MainWindow::MainWindow(const QString& homeDir, QWidget *parent) : m_lastSource(), m_searchTask(NULL), m_backupTask(NULL), + m_checksumOfSourceTask(NULL), + m_checksumOfTargetTask(NULL), m_errors(0) { ui->setupUi(this); @@ -35,9 +37,12 @@ MainWindow::MainWindow(const QString& homeDir, QWidget *parent) : startStop(false); connect(ui->actionStart, SIGNAL(triggered()), this, SLOT(onStart())); + connect(ui->actionChecksums, SIGNAL(triggered()), this, + SLOT(onChecksums())); connect(ui->actionStop, SIGNAL(triggered()), this, SLOT(onStop())); connect(ui->pushButtonBackup, SIGNAL(clicked()), this, SLOT(onStart())); + connect(ui->pushButtonChecksum, SIGNAL(clicked()), this, SLOT(onChecksums())); connect(ui->pushButtonStop, SIGNAL(clicked()), this, SLOT(onStop())); connect(ui->pushButtonAddItem, SIGNAL(clicked()), this, SLOT(onAddItem())); connect(ui->pushButtonDeleteItem, SIGNAL(clicked()), this, SLOT(onDeleteItem())); @@ -78,7 +83,7 @@ MainWindow::~MainWindow() /** * Calles at the program's end. */ -void MainWindow::aboutToQuit() +void MainWindow::onAboutToQuit() { } @@ -153,7 +158,7 @@ QString MainWindow::extractTarget(const QString& dir){ /** * Set GUI elements from the queue when the GUI timer is triggered. */ -void MainWindow::guiTimerUpdate() +void MainWindow::onGuiTimerUpdate() { int count = m_guiQueue.count(); while(count-- > 0){ @@ -189,6 +194,23 @@ void MainWindow::guiTimerUpdate() } } +/** + * Common initializations for all task starts. + */ +void MainWindow::initializeStart(){ + BackupEngine::m_searchReady = false; + BackupEngine::m_hotBytes = 0; + BackupEngine::m_hotFiles = 0; + BackupEngine::m_matchedFiles = 0; + BackupEngine::m_totalDirs = 0; + BackupEngine::m_totalFiles = 0; + BackupEngine::m_processedFiles = 0; + BackupEngine::m_processedBytes = 0; + ChecksumTask::m_sourceProcessingReady = false; + m_errors = 0; + startStop(true); +} + /** * @brief Logs a message * @@ -261,6 +283,40 @@ void MainWindow::onSelectionChanged(const QItemSelection& selected, } } + +/** + * Starts the backup. + */ +void MainWindow::onChecksums(){ + int row = ui->tableWidget->currentRow(); + if (row < 0){ + say(LOG_ERROR, tr("no backup item selected")); + } else { + BackupItem& item = m_configuration.items()[row]; + QString target = BackupUtils::findTarget(item, &m_logger); + if (target.isEmpty()){ + say(LOG_ERROR, tr("Target not available")); + } else { + ReQStringUtils::ensureLastChar(target, OS_SEPARATOR); + initializeStart(); + writeTargetConfiguration(item, target); + delete m_searchTask; + m_searchTask = new SearchTask(false, item.m_name, + item.m_filePatterns, item.m_dirPatterns, + item.m_sources, target, this); + m_searchTask->start(); + delete m_checksumOfSourceTask; + m_checksumOfSourceTask = new ChecksumOfSourceTask(item.m_name, + item.m_sources, target, this); + m_checksumOfSourceTask->start(); + delete m_checksumOfTargetTask; + m_checksumOfTargetTask = new ChecksumOfTargetTask(item.m_name, + item.m_sources, target, this); + m_checksumOfTargetTask->start(); + } + } +} + /** * Handles the push of the button "select directory". */ @@ -367,24 +423,15 @@ void MainWindow::onStart(){ say(LOG_ERROR, tr("no backup item selected")); } else { BackupItem& item = m_configuration.items()[row]; - BackupEngine::m_searchReady = false; - BackupEngine::m_hotBytes = 0; - BackupEngine::m_hotFiles = 0; - BackupEngine::m_matchedFiles = 0; - BackupEngine::m_totalDirs = 0; - BackupEngine::m_totalFiles = 0; - BackupEngine::m_processedFiles = 0; - BackupEngine::m_processedBytes = 0; - m_errors = 0; QString target = BackupUtils::findTarget(item, &m_logger); if (target.isEmpty()){ say(LOG_ERROR, tr("Target not available")); } else { ReQStringUtils::ensureLastChar(target, OS_SEPARATOR); writeTargetConfiguration(item, target); - startStop(true); + initializeStart(); delete m_searchTask; - m_searchTask = new SearchTask(item.m_name, + m_searchTask = new SearchTask(true, item.m_name, item.m_filePatterns, item.m_dirPatterns, item.m_sources, target, this); m_searchTask->start(); @@ -480,6 +527,8 @@ void MainWindow::startStop(bool isStart){ ui->actionStop->setEnabled(isStart); ui->pushButtonBackup->setEnabled(! isStart); ui->pushButtonStop->setEnabled(isStart); + ui->pushButtonChecksum->setEnabled(! isStart); + ui->actionChecksums->setEnabled(! isStart); } diff --git a/appl/rebackgui/mainwindow.hpp b/appl/rebackgui/mainwindow.hpp index e2c6edf..9e2163b 100644 --- a/appl/rebackgui/mainwindow.hpp +++ b/appl/rebackgui/mainwindow.hpp @@ -35,21 +35,24 @@ public: void restoreState(); void saveState(); +public slots: private: QString extractTarget(const QString& dir); + void initializeStart(); void writeTargetConfiguration(BackupItem& item, const QString& target); private slots: - virtual void aboutToQuit(); - virtual void guiTimerUpdate(); void onAbout(); + virtual void onAboutToQuit(); void onAddItem(); void onAddSource(); + void onChecksums(); void onClearFileList(); void onClearErrorList(); void onClearLog(); void onCurrentChanged(const QModelIndex& current, const QModelIndex& previous); void onDeleteItem(); void onDeleteSource(); + virtual void onGuiTimerUpdate(); void onSaveConfig(); void onStart(); void onSelectionChanged(const QItemSelection& prior, const QItemSelection& later); @@ -68,6 +71,8 @@ private: QString m_lastSource; SearchTask* m_searchTask; BackupTask* m_backupTask; + ChecksumOfSourceTask* m_checksumOfSourceTask; + ChecksumOfTargetTask* m_checksumOfTargetTask; int m_errors; }; diff --git a/appl/rebackgui/mainwindow.ui b/appl/rebackgui/mainwindow.ui index 6cf4e04..c62cbfb 100644 --- a/appl/rebackgui/mainwindow.ui +++ b/appl/rebackgui/mainwindow.ui @@ -117,6 +117,22 @@ + + + + + 125 + 0 + + + + Calculates checksums for source and target files and reports differences + + + Checksums + + + @@ -650,6 +666,7 @@ + @@ -687,7 +704,7 @@ - Stop backup + Stop @@ -695,6 +712,14 @@ About + + + Checksums + + + Calculates checksums for source and target files and reports differences + + diff --git a/base/ReFileUtils.cpp b/base/ReFileUtils.cpp index 4e36b44..e1bcf51 100644 --- a/base/ReFileUtils.cpp +++ b/base/ReFileUtils.cpp @@ -10,6 +10,8 @@ */ #include "base/rebase.hpp" +#include + enum { LOC_DELETE_TREE_1 = LOC_FIRST_OF(LOC_FILE_UTILS), // 12501 LOC_DELETE_TREE_2, // 12502 @@ -30,6 +32,41 @@ ReTreeStatistic::ReTreeStatistic() : m_fileSizes(0L) { } +/** + * Builds a checksum of the given file. + * + * @param filename the name of the file to process + * @param buffer OUT: buffer for reading the files + * @param sizes OUT: size of the file content. May be NULL + * @return "": the file could not be read completely
+ * otherwise: the checksum + */ +QByteArray ReFileUtils::buildChecksum(const char* filename, QByteArray& buffer, + qint64* size) +{ + if (buffer.capacity() < 0x10000) + buffer.reserve(0x10000); + // round it down to a multiple of the checksum size: + int blocksize = buffer.capacity() / 128 * 128; + buffer.resize(blocksize); + qint64 sumBytes = 0; + QByteArray rc; + FILE* fp = fopen(filename, "rb"); + if (fp != NULL){ + int bytesRead = 0; + char* bufferPointer = buffer.data(); + QCryptographicHash hash(QCryptographicHash::Md5); + while( (bytesRead = fread(bufferPointer, 1, blocksize, fp)) > 0){ + hash.addData(bufferPointer, bytesRead); + sumBytes += bytesRead; + } + rc = hash.result(); + fclose(fp); + if (size != NULL) + *size = sumBytes; + } + return rc; +} /** Normalizes a file path. * @@ -427,10 +464,10 @@ mode_t ReFileUtils::nativePermissions(QFile::Permissions permissions){ if (permissions.testFlag(QFile::ExeOther)) rc |= S_IXOTH; #elif defined _WIN32 - if (permissions.testFlag(QFile::ReadOwner) || permissions.testFlag(QFile::ReadOther)) - rc |= _S_IREAD; - if (permissions.testFlag(QFile::ReadOwner) ||permissions.testFlag(QFile::WriteOther)) - rc |= _S_IWRITE; + if (permissions.testFlag(QFile::ReadOwner) || permissions.testFlag(QFile::ReadOther)) + rc |= _S_IREAD; + if (permissions.testFlag(QFile::ReadOwner) ||permissions.testFlag(QFile::WriteOther)) + rc |= _S_IWRITE; #endif return rc; } @@ -491,8 +528,8 @@ bool ReFileUtils::makeDirWithParents(const char* path, ReLogger* logger) { else { const char* end; const char* start = path; - rc = true; - dir.clear(); + rc = true; + dir.clear(); while (rc && (end = strchr(start, OS_SEPARATOR)) != NULL) { if (end == path) { start++; @@ -501,10 +538,10 @@ bool ReFileUtils::makeDirWithParents(const char* path, ReLogger* logger) { dir.append(start, end - start); start = end + 1; #if defined _WIN32 - if (dir.length() == 2 && dir.at(1) == ':'){ - dir.append(OS_SEPARATOR); + if (dir.length() == 2 && dir.at(1) == ':'){ + dir.append(OS_SEPARATOR); continue; - } + } #endif rc = makeDir(dir.constData(), logger); dir += OS_SEPARATOR; @@ -804,7 +841,7 @@ void ReFileUtils::splitUrl(const QString& url, QString* protocol, QString* host, bool ReFileUtils::setPermissions(const char* filename, QFile::Permissions permissions, ReLogger* logger) { bool rc = true; - if (chmod(filename, nativePermissions(permissions)) != 0){ + if (chmod(filename, nativePermissions(permissions)) != 0){ if (logger != NULL) logger->logv(LOG_ERROR, LOC_SET_TIMES_1, "cannot change permissions (%d): $s", errno, filename); diff --git a/base/ReFileUtils.hpp b/base/ReFileUtils.hpp index 1f52787..2571afb 100644 --- a/base/ReFileUtils.hpp +++ b/base/ReFileUtils.hpp @@ -28,12 +28,28 @@ public: */ class ReFileUtils { public: - static bool deleteTree(const QString& path, bool withBase, - ReLogger* logger = NULL); + static QByteArray buildChecksum(const char* filename, QByteArray& buffer, + qint64* size = NULL); + /** + * Builds a checksum of the given file. + * + * @param filename the name of the file to process + * @param buffer OUT: buffer for reading the files + * @param sizes OUT: size of the file content. May be NULL + * @return "": the file could not be read completely
+ * otherwise: the checksum + */ + inline static QByteArray buildChecksum(const QString& filename, + QByteArray& buffer, qint64* size = NULL){ + return buildChecksum(I18N::s2b(filename).constData(), buffer, size); + } + static QByteArray cleanPath(const char* path); static QString cleanPath(const QString& path); static QString copy(const QString& source, const QString& target, const QFileInfo* sourceInfo, QByteArray& buffer); + static bool deleteTree(const QString& path, bool withBase, + ReLogger* logger = NULL); static QString extensionOf(const QString& filename); static QByteArray extensionOf(const char* filename); static QStringList findRootDirs(); diff --git a/gui/ReGuiApplication.cpp b/gui/ReGuiApplication.cpp index bbe0734..1fc1523 100644 --- a/gui/ReGuiApplication.cpp +++ b/gui/ReGuiApplication.cpp @@ -51,7 +51,7 @@ ReGuiApplication::ReGuiApplication(const char* applicationName, /** * Callback method at the application's end. */ -void ReGuiApplication::aboutToQuit() +void ReGuiApplication::onAboutToQuit() { m_logger.log(LOG_INFO, LOC_QUIT_1, "end"); } @@ -79,7 +79,7 @@ QString ReGuiApplication::fileOfHome(const QString& node) QString ReGuiApplication::buildHomeDir(QString homeDirBase, const QString& node){ QString homeDir; if (homeDirBase.isEmpty()){ - homeDir = ReFileUtils::nativePath(QDir::home().absoluteFilePath(node)); + homeDir = ReFileUtils::nativePath(QDir::home().absoluteFilePath(node)); } else if (ReFileUtils::isRootDir(homeDirBase.toLatin1().constData())){ homeDir = homeDirBase + node; } @@ -115,7 +115,7 @@ void ReGuiApplication::externalTaskFinished(const QString& message){ void ReGuiApplication::initializeGuiElements(){ QCoreApplication* app = QCoreApplication::instance(); QObject::connect(app, SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit())); - connect(m_guiTimer, SIGNAL(timeout()), this, SLOT(guiTimerUpdate())); + connect(m_guiTimer, SIGNAL(timeout()), this, SLOT(onGuiTimerUpdate())); m_guiTimer->start(100); statusBar()->addWidget(m_statusMessage); } diff --git a/gui/ReGuiApplication.hpp b/gui/ReGuiApplication.hpp index e99da72..2b90c39 100644 --- a/gui/ReGuiApplication.hpp +++ b/gui/ReGuiApplication.hpp @@ -26,7 +26,7 @@ public slots: /** * Callback method called when the application is closed. */ - void aboutToQuit(); + virtual void onAboutToQuit(); public: const QByteArray& applicationName() const; QString fileOfHome(const QString& node); @@ -43,7 +43,7 @@ protected slots: /** * Reads the m_guiQueue. */ - virtual void guiTimerUpdate() = 0; + virtual void onGuiTimerUpdate() = 0; protected: QByteArray m_applicationName; /// the base directory for resources of the program like configuration file.