diff options
author | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:20:07 +0200 |
---|---|---|
committer | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:20:07 +0200 |
commit | 88a8b528e20013c0aa3cc6bcd9659b0b5ddd9170 (patch) | |
tree | c6c5babb49b90293380106b81ae5c446959ac70f /lib | |
parent | 5.3 (diff) | |
download | FreeFileSync-88a8b528e20013c0aa3cc6bcd9659b0b5ddd9170.tar.gz FreeFileSync-88a8b528e20013c0aa3cc6bcd9659b0b5ddd9170.tar.bz2 FreeFileSync-88a8b528e20013c0aa3cc6bcd9659b0b5ddd9170.zip |
5.4
Diffstat (limited to 'lib')
-rw-r--r-- | lib/binary.cpp | 42 | ||||
-rw-r--r-- | lib/db_file.cpp | 10 | ||||
-rw-r--r-- | lib/dir_exist_async.h | 3 | ||||
-rw-r--r-- | lib/dir_lock.cpp | 46 | ||||
-rw-r--r-- | lib/help_provider.h | 5 | ||||
-rw-r--r-- | lib/localization.cpp | 23 | ||||
-rw-r--r-- | lib/parallel_scan.cpp | 80 | ||||
-rw-r--r-- | lib/parallel_scan.h | 8 | ||||
-rw-r--r-- | lib/parse_lng.h | 25 | ||||
-rw-r--r-- | lib/perf_check.cpp | 7 | ||||
-rw-r--r-- | lib/process_xml.cpp | 20 | ||||
-rw-r--r-- | lib/process_xml.h | 14 | ||||
-rw-r--r-- | lib/resolve_path.cpp | 10 | ||||
-rw-r--r-- | lib/resources.cpp | 2 | ||||
-rw-r--r-- | lib/return_codes.h | 22 | ||||
-rw-r--r-- | lib/shadow.cpp | 2 | ||||
-rw-r--r-- | lib/status_handler.h | 1 | ||||
-rw-r--r-- | lib/xml_base.cpp | 3 |
18 files changed, 170 insertions, 153 deletions
diff --git a/lib/binary.cpp b/lib/binary.cpp index c01bb4d2..4fc1d408 100644 --- a/lib/binary.cpp +++ b/lib/binary.cpp @@ -5,12 +5,15 @@ // ************************************************************************** #include "binary.h" -#include <wx/stopwatch.h> +#include <zen/tick_count.h> #include <vector> #include <zen/file_io.h> #include <zen/int64.h> #include <boost/thread/tss.hpp> +using namespace zen; + + inline void setMinSize(std::vector<char>& buffer, size_t minSize) { @@ -61,6 +64,9 @@ private: size_t bufSize; }; + + +const std::int64_t TICKS_PER_SEC = ticksPerSec(); } @@ -80,33 +86,39 @@ bool zen::filesHaveSameContent(const Zstring& filename1, const Zstring& filename std::vector<char>& memory2 = *cpyBuf2; BufferSize bufferSize; - zen::UInt64 bytesCompared; + UInt64 bytesCompared; - wxLongLong lastDelayViolation = wxGetLocalTimeMillis(); + TickVal lastDelayViolation = getTicks(); do { setMinSize(memory1, bufferSize); setMinSize(memory2, bufferSize); - const wxLongLong startTime = wxGetLocalTimeMillis(); + const TickVal startTime = getTicks(); const size_t length1 = file1.read(&memory1[0], bufferSize); //returns actual number of bytes read; throw FileError() const size_t length2 = file2.read(&memory2[0], bufferSize); // - const wxLongLong stopTime = wxGetLocalTimeMillis(); + const TickVal stopTime = getTicks(); - //-------- dynamically set buffer size to keep callback interval between 200 - 500ms --------------------- - const wxLongLong loopTime = stopTime - startTime; - if (loopTime < 200 && stopTime - lastDelayViolation > 2000) //avoid "flipping back": e.g. DVD-Roms read 32MB at once, so first read may be > 300 ms, but second one will be 0ms! - { - lastDelayViolation = stopTime; - bufferSize.inc(); //practically no costs! - } - else if (loopTime > 500) + //-------- dynamically set buffer size to keep callback interval between 100 - 500ms --------------------- + if (TICKS_PER_SEC > 0) { - lastDelayViolation = stopTime; - bufferSize.dec(); // + const std::int64_t loopTime = (stopTime - startTime) * 1000 / TICKS_PER_SEC; //unit: [ms] + if (loopTime < 100) + { + if ((stopTime - lastDelayViolation) / TICKS_PER_SEC > 2) //avoid "flipping back": e.g. DVD-Roms read 32MB at once, so first read may be > 500 ms, but second one will be 0ms! + { + lastDelayViolation = stopTime; + bufferSize.inc(); + } + } + else if (loopTime > 500) + { + lastDelayViolation = stopTime; + bufferSize.dec(); + } } //------------------------------------------------------------------------------------------------ diff --git a/lib/db_file.cpp b/lib/db_file.cpp index 1bc75d82..33c83a0e 100644 --- a/lib/db_file.cpp +++ b/lib/db_file.cpp @@ -15,7 +15,7 @@ #include <zen/file_io.h> #include <zen/scope_guard.h> #include <zen/guid.h> -#include <zen/utf8.h> +#include <zen/utf.h> #ifdef FFS_WIN #include <zen/win.h> //includes "windows.h" @@ -128,7 +128,7 @@ StreamMapping loadStreams(const Zstring& filename) //throw FileError } catch (const std::bad_alloc& e) { - throw FileError(_("Out of memory!") + L" " + utf8CvrtTo<std::wstring>(e.what())); + throw FileError(_("Out of memory!") + L" " + utfCvrtTo<std::wstring>(e.what())); } } @@ -148,7 +148,7 @@ public: } catch (const std::bad_alloc& e) { - throw FileError(_("Out of memory!") + L" " + utf8CvrtTo<std::wstring>(e.what())); + throw FileError(_("Out of memory!") + L" " + utfCvrtTo<std::wstring>(e.what())); } } @@ -160,7 +160,7 @@ private: Zstring readStringUtf8() const { - return utf8CvrtTo<Zstring>(readString<Zbase<char>>()); + return utfCvrtTo<Zstring>(readString<Zbase<char>>()); } FileId readFileId() const @@ -280,7 +280,7 @@ private: writePOD<bool>(false); //mark last entry } - void writeStringUtf8(const Zstring& str) { writeString(utf8CvrtTo<Zbase<char>>(str)); } + void writeStringUtf8(const Zstring& str) { writeString(utfCvrtTo<Zbase<char>>(str)); } void writeFileId(const FileId& id) { diff --git a/lib/dir_exist_async.h b/lib/dir_exist_async.h index 40ddffc7..2ab98e94 100644 --- a/lib/dir_exist_async.h +++ b/lib/dir_exist_async.h @@ -9,7 +9,6 @@ #include <zen/thread.h> #include <zen/file_handling.h> -//#include "status_handler.h" #include "process_callback.h" #include <zen/file_error.h> #include "resolve_path.h" @@ -21,7 +20,7 @@ bool dirExistsUpdating(const Zstring& dirname, bool allowUserInteraction, Proces { using namespace zen; - procCallback.reportStatus(replaceCpy(_("Searching for directory %x..."), L"%x", fmtFileName(dirname), false)); + procCallback.reportStatus(replaceCpy(_("Searching for folder %x..."), L"%x", fmtFileName(dirname), false)); auto ft = async([=]() -> bool { diff --git a/lib/dir_lock.cpp b/lib/dir_lock.cpp index 402892c6..f41bbfa8 100644 --- a/lib/dir_lock.cpp +++ b/lib/dir_lock.cpp @@ -5,10 +5,9 @@ // ************************************************************************** #include "dir_lock.h" #include <utility> -#include <wx/utils.h> -#include <wx/timer.h> +//#include <wx/utils.h> #include <wx/log.h> -#include <wx/msgdlg.h> +//#include <wx/msgdlg.h> #include <memory> #include <wx+/string_conv.h> #include <zen/last_error.h> @@ -16,6 +15,7 @@ #include <zen/scope_guard.h> #include <zen/guid.h> #include <zen/file_io.h> +#include <zen/tick_count.h> #include <zen/assert_static.h> #include <wx+/serialize.h> #include <zen/int64.h> @@ -39,9 +39,9 @@ using namespace std::rel_ops; namespace { -const size_t EMIT_LIFE_SIGN_INTERVAL = 5000; //show life sign; unit: [ms] -const size_t POLL_LIFE_SIGN_INTERVAL = 4000; //poll for life sign; unit: [ms] -const size_t DETECT_ABANDONED_INTERVAL = 30000; //assume abandoned lock; unit: [ms] +const int EMIT_LIFE_SIGN_INTERVAL = 5; //show life sign; unit: [s] +const int POLL_LIFE_SIGN_INTERVAL = 4; //poll for life sign; unit: [s] +const int DETECT_ABANDONED_INTERVAL = 30; //assume abandoned lock; unit: [s] const char LOCK_FORMAT_DESCR[] = "FreeFileSync"; const int LOCK_FORMAT_VER = 2; //lock file format version @@ -60,7 +60,7 @@ public: { while (true) { - boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(EMIT_LIFE_SIGN_INTERVAL)); //interruption point! + boost::this_thread::sleep(boost::posix_time::seconds(EMIT_LIFE_SIGN_INTERVAL)); //interruption point! //actual work emitLifeSign(); //throw () @@ -68,7 +68,7 @@ public: } catch (const std::exception& e) //exceptions must be catched per thread { - wxSafeShowMessage(_("An exception occurred!") + L" (Dirlock)", utf8CvrtTo<wxString>(e.what())); //simple wxMessageBox won't do for threads + wxSafeShowMessage(_("An exception occurred!") + L" (Dirlock)", utfCvrtTo<wxString>(e.what())); //simple wxMessageBox won't do for threads } } @@ -228,7 +228,7 @@ struct LockInformation //throw FileError explicit LockInformation(FromCurrentProcess) : lockId(zen::generateGUID()), #ifdef FFS_WIN - sessionId(utf8CvrtTo<std::string>(getLoginSid())), //throw FileError + sessionId(utfCvrtTo<std::string>(getLoginSid())), //throw FileError processId(::GetCurrentProcessId()) //never fails { DWORD bufferSize = 0; @@ -239,14 +239,14 @@ struct LockInformation //throw FileError &buffer[0], //__out LPTSTR lpBuffer, &bufferSize)) //__inout LPDWORD lpnSize throw FileError(_("Cannot get process information.") + L"\n\n" + getLastErrorFormatted()); - computerName = "Windows." + utf8CvrtTo<std::string>(&buffer[0]); + computerName = "Windows." + utfCvrtTo<std::string>(&buffer[0]); bufferSize = UNLEN + 1; buffer.resize(bufferSize); if (!::GetUserName(&buffer[0], //__out LPTSTR lpBuffer, &bufferSize)) //__inout LPDWORD lpnSize throw FileError(_("Cannot get process information.") + L"\n\n" + getLastErrorFormatted()); - userId = utf8CvrtTo<std::string>(&buffer[0]); + userId = utfCvrtTo<std::string>(&buffer[0]); } #elif defined FFS_LINUX processId(::getpid()) //never fails @@ -399,6 +399,9 @@ ProcessStatus getProcessStatus(const LockInformation& lockInfo) //throw FileErro } +const std::int64_t TICKS_PER_SEC = ticksPerSec(); //= 0 on error + + void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //throw FileError { const std::wstring infoMsg = replaceCpy(_("Waiting while directory is locked (%x)..."), L"%x", fmtFileName(lockfilename)); @@ -429,13 +432,16 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr catch (FileError&) {} //logfile may be only partly written -> this is no error! UInt64 fileSizeOld; - wxMilliClock_t lastLifeSign = wxGetLocalTimeMillis(); + TickVal lastLifeSign = getTicks(); while (true) { - wxMilliClock_t currentTime = wxGetLocalTimeMillis(); + const TickVal currentTime = getTicks(); const UInt64 fileSizeNew = ::getLockFileSize(lockfilename); //throw FileError, ErrorNotExisting + if (TICKS_PER_SEC <= 0 || !lastLifeSign.isValid() || !currentTime.isValid()) + throw FileError(L"System Timer failed!"); //no i18n: "should" never throw ;) + if (fileSizeNew != fileSizeOld) //received life sign from lock { fileSizeOld = fileSizeNew; @@ -443,7 +449,7 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr } if (lockOwnderDead || //no need to wait any longer... - currentTime - lastLifeSign > DETECT_ABANDONED_INTERVAL) + (currentTime - lastLifeSign) / TICKS_PER_SEC > DETECT_ABANDONED_INTERVAL) { DirLock dummy(deleteAbandonedLockName(lockfilename), callback); //throw FileError @@ -461,19 +467,19 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr } //wait some time... - assert_static(POLL_LIFE_SIGN_INTERVAL % GUI_CALLBACK_INTERVAL == 0); - for (size_t i = 0; i < POLL_LIFE_SIGN_INTERVAL / GUI_CALLBACK_INTERVAL; ++i) + assert_static(1000 * POLL_LIFE_SIGN_INTERVAL % GUI_CALLBACK_INTERVAL == 0); + for (size_t i = 0; i < 1000 * POLL_LIFE_SIGN_INTERVAL / GUI_CALLBACK_INTERVAL; ++i) { if (callback) callback->requestUiRefresh(); - wxMilliSleep(GUI_CALLBACK_INTERVAL); + boost::this_thread::sleep(boost::posix_time::milliseconds(GUI_CALLBACK_INTERVAL)); if (callback) { //one signal missed: it's likely this is an abandoned lock => show countdown - if (currentTime - lastLifeSign > EMIT_LIFE_SIGN_INTERVAL) + if ((currentTime - lastLifeSign) / TICKS_PER_SEC > EMIT_LIFE_SIGN_INTERVAL) { - long remainingSeconds = ((DETECT_ABANDONED_INTERVAL - (wxGetLocalTimeMillis() - lastLifeSign)) / 1000).ToLong(); - remainingSeconds = std::max(0L, remainingSeconds); + int remainingSeconds = DETECT_ABANDONED_INTERVAL - (getTicks() - lastLifeSign) / TICKS_PER_SEC; + remainingSeconds = std::max(0, remainingSeconds); const std::wstring remSecMsg = replaceCpy(_P("1 sec", "%x sec", remainingSeconds), L"%x", numberTo<std::wstring>(remainingSeconds)); callback->reportInfo(infoMsg + L" " + remSecMsg); diff --git a/lib/help_provider.h b/lib/help_provider.h index 213c05e3..3b7443cb 100644 --- a/lib/help_provider.h +++ b/lib/help_provider.h @@ -9,10 +9,11 @@ #include <wx/help.h> #include "ffs_paths.h" +#include <zen/zstring.h> namespace zen { -void displayHelpEntry(const wxString& section = wxEmptyString); +void displayHelpEntry(const wxString& section = wxEmptyString); //use '/' as path separator! @@ -52,7 +53,7 @@ void displayHelpEntry(const wxString& section) if (section.empty()) getHelpCtrl().DisplayContents(); else - getHelpCtrl().DisplaySection(section); + getHelpCtrl().DisplaySection(replaceCpy(section, L'/', utfCvrtTo<std::wstring>(FILE_NAME_SEPARATOR))); } } diff --git a/lib/localization.cpp b/lib/localization.cpp index f056aea0..5f9a4750 100644 --- a/lib/localization.cpp +++ b/lib/localization.cpp @@ -90,21 +90,21 @@ FFSLocale::FFSLocale(const wxString& filename, wxLanguage languageId) : langId_( for (lngfile::TranslationMap::const_iterator i = transInput.begin(); i != transInput.end(); ++i) { - const std::wstring original = utf8CvrtTo<std::wstring>(i->first); - const std::wstring translation = utf8CvrtTo<std::wstring>(i->second); + const std::wstring original = utfCvrtTo<std::wstring>(i->first); + const std::wstring translation = utfCvrtTo<std::wstring>(i->second); assert(!translation.empty()); transMapping.insert(std::make_pair(original , translation)); } for (lngfile::TranslationPluralMap::const_iterator i = transPluralInput.begin(); i != transPluralInput.end(); ++i) { - const std::wstring singular = utf8CvrtTo<std::wstring>(i->first.first); - const std::wstring plural = utf8CvrtTo<std::wstring>(i->first.second); + const std::wstring singular = utfCvrtTo<std::wstring>(i->first.first); + const std::wstring plural = utfCvrtTo<std::wstring>(i->first.second); const lngfile::PluralForms& plForms = i->second; std::vector<std::wstring> plFormsWide; for (lngfile::PluralForms::const_iterator j = plForms.begin(); j != plForms.end(); ++j) - plFormsWide.push_back(utf8CvrtTo<std::wstring>(*j)); + plFormsWide.push_back(utfCvrtTo<std::wstring>(*j)); assert(!plFormsWide.empty()); @@ -127,9 +127,9 @@ public: lngFiles_.push_back(fullName); } - virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) {} + virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) { return LINK_SKIP; } virtual std::shared_ptr<TraverseCallback> onDir(const Zchar* shortName, const Zstring& fullName) { return nullptr; } - virtual HandleError onError(const std::wstring& errorText) { return TRAV_ERROR_IGNORE; } //errors are not really critical in this context + virtual HandleError onError(const std::wstring& errorText) { return ON_ERROR_IGNORE; } //errors are not really critical in this context private: std::vector<Zstring>& lngFiles_; @@ -177,7 +177,6 @@ ExistingTranslations::ExistingTranslations() FindLngfiles traverseCallback(lngFiles); traverseFolder(zen::getResourceDir() + Zstr("Languages"), //throw(); - false, //don't follow symlinks traverseCallback); for (auto i = lngFiles.begin(); i != lngFiles.end(); ++i) @@ -193,14 +192,14 @@ ExistingTranslations::ExistingTranslations() There is some buggy behavior in wxWidgets which maps "zh_TW" to simplified chinese. Fortunately locales can be also entered as description. I changed to "Chinese (Traditional)" which works fine. */ - if (const wxLanguageInfo* locInfo = wxLocale::FindLanguageInfo(utf8CvrtTo<wxString>(lngHeader.localeName))) + if (const wxLanguageInfo* locInfo = wxLocale::FindLanguageInfo(utfCvrtTo<wxString>(lngHeader.localeName))) { ExistingTranslations::Entry newEntry; newEntry.languageID = locInfo->Language; - newEntry.languageName = utf8CvrtTo<wxString>(lngHeader.languageName); + newEntry.languageName = utfCvrtTo<wxString>(lngHeader.languageName); newEntry.languageFile = toWx(*i); - newEntry.translatorName = utf8CvrtTo<wxString>(lngHeader.translatorName); - newEntry.languageFlag = utf8CvrtTo<wxString>(lngHeader.flagFile); + newEntry.translatorName = utfCvrtTo<wxString>(lngHeader.translatorName); + newEntry.languageFlag = utfCvrtTo<wxString>(lngHeader.flagFile); locMapping.push_back(newEntry); } } diff --git a/lib/parallel_scan.cpp b/lib/parallel_scan.cpp index 9ab99920..435067b2 100644 --- a/lib/parallel_scan.cpp +++ b/lib/parallel_scan.cpp @@ -13,6 +13,7 @@ #include <wx+/string_conv.h> #include <zen/thread.h> //includes <boost/thread.hpp> #include <zen/scope_guard.h> +#include <zen/fixed_list.h> using namespace zen; @@ -219,7 +220,7 @@ public: void reportCurrentFile(const Zstring& filename, int threadID) //context of worker thread { - if (threadID != notifyingThreadID) return; //only one thread may report status + if (threadID != notifyingThreadID) return; //only one thread at a time may report status boost::lock_guard<boost::mutex> dummy(lockCurrentStatus); currentFile = filename; @@ -329,7 +330,7 @@ public: virtual std::shared_ptr<TraverseCallback> onDir (const Zchar* shortName, const Zstring& fullName); virtual void onFile (const Zchar* shortName, const Zstring& fullName, const FileInfo& details); - virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details); + virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details); virtual HandleError onError (const std::wstring& errorText); private: @@ -377,26 +378,38 @@ void DirCallback::onFile(const Zchar* shortName, const Zstring& fullName, const } -void DirCallback::onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) +DirCallback::HandleLink DirCallback::onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) { boost::this_thread::interruption_point(); - if (cfg.handleSymlinks_ == SYMLINK_IGNORE) - return; + switch (cfg.handleSymlinks_) + { + case SYMLINK_IGNORE: + return LINK_SKIP; - //update status information no matter whether object is excluded or not! - cfg.acb_.reportCurrentFile(fullName, cfg.threadID_); + case SYMLINK_USE_DIRECTLY: + { + //update status information no matter whether object is excluded or not! + cfg.acb_.reportCurrentFile(fullName, cfg.threadID_); - //------------------------------------------------------------------------------------ - const Zstring& relName = relNameParentPf_ + shortName; + //------------------------------------------------------------------------------------ + const Zstring& relName = relNameParentPf_ + shortName; - //apply filter before processing (use relative name!) - if (!cfg.filterInstance->passFileFilter(relName)) //always use file filter: Link type may not be "stable" on Linux! - return; + //apply filter before processing (use relative name!) + if (cfg.filterInstance->passFileFilter(relName)) //always use file filter: Link type may not be "stable" on Linux! + { + output_.addSubLink(shortName, LinkDescriptor(details.lastWriteTimeRaw, details.targetPath, details.dirLink ? LinkDescriptor::TYPE_DIR : LinkDescriptor::TYPE_FILE)); + cfg.acb_.incItemsScanned(); //add 1 element to the progress indicator + } + } + return LINK_SKIP; - output_.addSubLink(shortName, LinkDescriptor(details.lastWriteTimeRaw, details.targetPath, details.dirLink ? LinkDescriptor::TYPE_DIR : LinkDescriptor::TYPE_FILE)); + case SYMLINK_FOLLOW_LINK: + return LINK_FOLLOW; + } - cfg.acb_.incItemsScanned(); //add 1 element to the progress indicator + assert(false); + return LINK_SKIP; } @@ -429,16 +442,16 @@ DirCallback::HandleError DirCallback::onError(const std::wstring& errorText) { switch (cfg.acb_.reportError(errorText)) { - case FillBufferCallback::TRAV_ERROR_IGNORE: + case FillBufferCallback::ON_ERROR_IGNORE: cfg.failedReads_.insert(relNameParentPf_); - return TRAV_ERROR_IGNORE; + return ON_ERROR_IGNORE; - case FillBufferCallback::TRAV_ERROR_RETRY: - return TRAV_ERROR_RETRY; + case FillBufferCallback::ON_ERROR_RETRY: + return ON_ERROR_RETRY; } assert(false); - return TRAV_ERROR_IGNORE; + return ON_ERROR_IGNORE; } @@ -498,20 +511,6 @@ public: Zstring(), dirVal.dirCont); - bool followSymlinks = false; - switch (item.first.handleSymlinks_) - { - case SYMLINK_IGNORE: - followSymlinks = false; //=> symlinks will be reported via onSymlink() where they are excluded - break; - case SYMLINK_USE_DIRECTLY: - followSymlinks = false; - break; - case SYMLINK_FOLLOW_LINK: - followSymlinks = true; - break; - } - DstHackCallback* dstCallbackPtr = nullptr; #ifdef FFS_WIN DstHackCallbackImpl dstCallback(*acb_, threadID_); @@ -519,7 +518,7 @@ public: #endif //get all files and folders from directoryPostfixed (and subdirectories) - traverseFolder(directoryName, followSymlinks, traverser, dstCallbackPtr); //exceptions may be thrown! + traverseFolder(directoryName, traverser, dstCallbackPtr); //exceptions may be thrown! }); } @@ -540,8 +539,7 @@ void zen::fillBuffer(const std::set<DirectoryKey>& keysToRead, //in std::vector<std::set<DirectoryKey>> buckets = separateByDistinctDisk(keysToRead); //one bucket per physical device - std::vector<boost::thread> worker; //note: GCC doesn't allow to construct an array of empty threads since they would be initialized by const boost::thread& - worker.reserve(buckets.size()); + FixedList<boost::thread> worker; //note: we cannot use std::vector<boost::thread>: compiler error on GCC 4.7, probably a boost screw-up zen::ScopeGuard guardWorker = zen::makeGuard([&] { @@ -554,7 +552,6 @@ void zen::fillBuffer(const std::set<DirectoryKey>& keysToRead, //in //init worker threads for (auto iter = buckets.begin(); iter != buckets.end(); ++iter) { - int threadID = iter - buckets.begin(); const std::set<DirectoryKey>& bucket = *iter; std::vector<std::pair<DirectoryKey, DirectoryValue*>> workload; @@ -566,16 +563,17 @@ void zen::fillBuffer(const std::set<DirectoryKey>& keysToRead, //in workload.push_back(std::make_pair(key, &rv.first->second)); }); - worker.push_back(boost::thread(WorkerThread(threadID, acb, workload))); + const int threadId = iter - buckets.begin(); + worker.emplace_back(WorkerThread(threadId, acb, workload)); } //wait until done - for (auto iter = worker.begin(); iter != worker.end(); ++iter) + int threadId = 0; + for (auto iter = worker.begin(); iter != worker.end(); ++iter, ++threadId) { boost::thread& wt = *iter; - int threadID = iter - worker.begin(); - acb->setNotifyingThread(threadID); //process info messages of first (active) thread only + acb->setNotifyingThread(threadId); //process info messages of first (active) thread only do { diff --git a/lib/parallel_scan.h b/lib/parallel_scan.h index 836892ad..0ce0114d 100644 --- a/lib/parallel_scan.h +++ b/lib/parallel_scan.h @@ -56,11 +56,11 @@ public: enum HandleError { - TRAV_ERROR_RETRY, - TRAV_ERROR_IGNORE + ON_ERROR_RETRY, + ON_ERROR_IGNORE }; - virtual HandleError reportError (const std::wstring& errorText) = 0; //may throw! - virtual void reportStatus(const std::wstring& statusMsg, int itemTotal) = 0; // + virtual HandleError reportError (const std::wstring& errorText) = 0; //may throw! + virtual void reportStatus(const std::wstring& statusMsg, int itemsTotal) = 0; // }; //attention: ensure directory filtering is applied later to exclude filtered directories which have been kept as parent folders diff --git a/lib/parse_lng.h b/lib/parse_lng.h index 07932c3a..6a0b9dc5 100644 --- a/lib/parse_lng.h +++ b/lib/parse_lng.h @@ -17,7 +17,8 @@ #include <stdexcept> #include <string> #include <vector> -#include <zen/utf8.h> +#include <zen/utf.h> +#include <zen/string_tools.h> namespace lngfile { @@ -311,24 +312,6 @@ private: std::string::const_iterator pos; }; -template <class C, class T> -inline -std::basic_string<C> numberToString(const T& number) //convert number to string the C++ way -{ - std::basic_ostringstream<C> ss; - ss << number; - return ss.str(); -} - -template <class T, class C> -inline -T stringToNumber(const std::basic_string<C>& str) //convert string to number the C++ way -{ - T number = 0; - std::basic_istringstream<C>(str) >> number; - return number; -} - class LngParser { @@ -370,7 +353,7 @@ public: consumeToken(Token::TK_FLAG_FILE_END); consumeToken(Token::TK_PLURAL_COUNT_BEGIN); - header.pluralCount = stringToNumber<int>(tk.text); + header.pluralCount = zen::stringTo<int>(tk.text); consumeToken(Token::TK_TEXT); consumeToken(Token::TK_PLURAL_COUNT_END); @@ -521,7 +504,7 @@ void generateLng(const TranslationList& in, const TransHeader& header, std::stri fileStream += KnownTokens::text(Token::TK_FLAG_FILE_END) + LB; fileStream += TAB + KnownTokens::text(Token::TK_PLURAL_COUNT_BEGIN); - fileStream += numberToString<char>(header.pluralCount); + fileStream += zen::numberTo<std::string>(header.pluralCount); fileStream += KnownTokens::text(Token::TK_PLURAL_COUNT_END) + LB; fileStream += TAB + KnownTokens::text(Token::TK_PLURAL_DEF_BEGIN); diff --git a/lib/perf_check.cpp b/lib/perf_check.cpp index 897be12c..ab0f7769 100644 --- a/lib/perf_check.cpp +++ b/lib/perf_check.cpp @@ -79,7 +79,7 @@ wxString PerfCheck::getRemainingTime(double dataRemaining) const return zen::remainingTimeToShortString(remTimeSec); } } - return wxT("-"); //fallback + return L"-"; //fallback } @@ -102,7 +102,7 @@ wxString PerfCheck::getBytesPerSecond() const if (dataDelta > 0) //may be negative if user cancels copying return zen::filesizeToShortString(zen::Int64(dataDelta * 1000 / timeDelta)) + _("/sec"); } - return wxT("-"); //fallback + return L"-"; //fallback } @@ -120,7 +120,7 @@ wxString PerfCheck::getOverallBytesPerSecond() const //for all samples if (dataDelta > 0) //may be negative if user cancels copying return zen::filesizeToShortString(zen::Int64(dataDelta * 1000 / timeDelta)) + _("/sec"); } - return wxT("-"); //fallback + return L"-"; //fallback } @@ -255,5 +255,4 @@ wxString Statistics::getRemainingTime(const int objectsCurrent, const double dat return formatRemainingTime((objectsTotal - objectsCurrent) * z1_current + (dataTotal - dataCurrent) * z2_current); } - */ diff --git a/lib/process_xml.cpp b/lib/process_xml.cpp index a3ed5bfc..677618b4 100644 --- a/lib/process_xml.cpp +++ b/lib/process_xml.cpp @@ -646,7 +646,7 @@ bool readText(const std::string& input, DirectionConfig::Variant& value) template <> inline -bool readValue(const XmlElement& input, ColumnAttributeRim& value) +bool readStruc(const XmlElement& input, ColumnAttributeRim& value) { XmlIn in(input); bool rv1 = in.attribute("Type", value.type_); @@ -656,7 +656,7 @@ bool readValue(const XmlElement& input, ColumnAttributeRim& value) } template <> inline -void writeValue(const ColumnAttributeRim& value, XmlElement& output) +void writeStruc(const ColumnAttributeRim& value, XmlElement& output) { XmlOut out(output); out.attribute("Type", value.type_); @@ -666,7 +666,7 @@ void writeValue(const ColumnAttributeRim& value, XmlElement& output) template <> inline -bool readValue(const XmlElement& input, ColumnAttributeNavi& value) +bool readStruc(const XmlElement& input, ColumnAttributeNavi& value) { XmlIn in(input); bool rv1 = in.attribute("Type", value.type_); @@ -676,7 +676,7 @@ bool readValue(const XmlElement& input, ColumnAttributeNavi& value) } template <> inline -void writeValue(const ColumnAttributeNavi& value, XmlElement& output) +void writeStruc(const ColumnAttributeNavi& value, XmlElement& output) { XmlOut out(output); out.attribute("Type", value.type_); @@ -812,7 +812,7 @@ void readConfig(const XmlIn& in, xmlAccess::XmlGuiConfig& config) inGuiCfg["HideFiltered" ](config.hideFilteredElements); inGuiCfg["HandleError" ](config.handleError); - inGuiCfg["SyncPreviewActive"](config.syncPreviewEnabled); + inGuiCfg["SyncPreviewActive"](config.showSyncAction); } @@ -1081,7 +1081,7 @@ void writeConfig(const XmlGuiConfig& config, XmlOut& out) outGuiCfg["HideFiltered" ](config.hideFilteredElements); outGuiCfg["HandleError" ](config.handleError); - outGuiCfg["SyncPreviewActive"](config.syncPreviewEnabled); + outGuiCfg["SyncPreviewActive"](config.showSyncAction); } void writeConfig(const XmlBatchConfig& config, XmlOut& out) @@ -1220,9 +1220,9 @@ void xmlAccess::writeConfig(const XmlGlobalSettings& config) } -wxString xmlAccess::extractJobName(const wxString& configFilename) +std::wstring xmlAccess::extractJobName(const Zstring& configFilename) { - const wxString shortName = afterLast(configFilename, utf8CvrtTo<wxString>(FILE_NAME_SEPARATOR)); //returns the whole string if separator not found - const wxString jobName = beforeLast(shortName, L'.'); //returns empty string if seperator not found - return jobName.IsEmpty() ? shortName : jobName; + const Zstring shortName = afterLast(configFilename, FILE_NAME_SEPARATOR); //returns the whole string if separator not found + const Zstring jobName = beforeLast(shortName, Zstr('.')); //returns empty string if seperator not found + return utfCvrtTo<std::wstring>(jobName.empty() ? shortName : jobName); } diff --git a/lib/process_xml.h b/lib/process_xml.h index 767e4a40..43dedb51 100644 --- a/lib/process_xml.h +++ b/lib/process_xml.h @@ -39,8 +39,8 @@ enum OnGuiError ON_GUIERROR_IGNORE }; -typedef wxString Description; -typedef wxString Commandline; +typedef std::wstring Description; +typedef std::wstring Commandline; typedef std::vector<std::pair<Description, Commandline> > ExternalApps; //--------------------------------------------------------------------- @@ -49,20 +49,20 @@ struct XmlGuiConfig XmlGuiConfig() : hideFilteredElements(false), handleError(ON_GUIERROR_POPUP), - syncPreviewEnabled(true) {} //initialize values + showSyncAction(true) {} //initialize values zen::MainConfiguration mainCfg; bool hideFilteredElements; OnGuiError handleError; //reaction on error situation during synchronization - bool syncPreviewEnabled; + bool showSyncAction; bool operator==(const XmlGuiConfig& other) const { return mainCfg == other.mainCfg && hideFilteredElements == other.hideFilteredElements && handleError == other.handleError && - syncPreviewEnabled == other.syncPreviewEnabled; + showSyncAction == other.showSyncAction; } bool operator!=(const XmlGuiConfig& other) const { return !(*this == other); } @@ -174,7 +174,7 @@ struct XmlGlobalSettings externelApplications.push_back(std::make_pair(L"Open with default application", //mark for extraction: _("Open with default application") L"\"%name\"")); #elif defined FFS_LINUX - externelApplications.push_back(std::make_pair(L"Browse directory", //mark for extraction: _("Browse directory") + externelApplications.push_back(std::make_pair(L"Browse directory", //mark for extraction: _("Browse directory") Linux doesn't use the term "folder" L"xdg-open \"%dir\"")); externelApplications.push_back(std::make_pair(L"Open with default application", //mark for extraction: _("Open with default application") L"xdg-open \"%name\"")); @@ -250,7 +250,7 @@ MergeType getMergeType(const std::vector<Zstring>& filenames); //throw () void convertConfig(const std::vector<Zstring>& filenames, XmlGuiConfig& config); //throw xmlAccess::FfsXmlError void convertConfig(const std::vector<Zstring>& filenames, XmlBatchConfig& config); //throw xmlAccess::FfsXmlError -wxString extractJobName(const wxString& configFilename); +std::wstring extractJobName(const Zstring& configFilename); } diff --git a/lib/resolve_path.cpp b/lib/resolve_path.cpp index f5a342d2..bb0c1f3b 100644 --- a/lib/resolve_path.cpp +++ b/lib/resolve_path.cpp @@ -260,13 +260,13 @@ public: TraverseMedia(DeviceList& devices) : devices_(devices) {} virtual void onFile(const Zchar* shortName, const Zstring& fullName, const FileInfo& details) {} - virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) {} + virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) { return LINK_SKIP; } virtual std::shared_ptr<TraverseCallback> onDir(const Zchar* shortName, const Zstring& fullName) { devices_.insert(std::make_pair(shortName, fullName)); return nullptr; //DON'T traverse into subdirs } - virtual HandleError onError(const std::wstring& errorText) { return TRAV_ERROR_IGNORE; } + virtual HandleError onError(const std::wstring& errorText) { return ON_ERROR_IGNORE; } private: DeviceList& devices_; @@ -328,7 +328,7 @@ Zstring volumenNameToPath(const Zstring& volumeName) //return empty string on er TraverseMedia::DeviceList deviceList; TraverseMedia traverser(deviceList); - traverseFolder("/media", false, traverser); //traverse one level + traverseFolder("/media", traverser); //traverse one level TraverseMedia::DeviceList::const_iterator iter = deviceList.find(volumeName); if (iter != deviceList.end()) @@ -511,7 +511,7 @@ Zstring zen::getFormattedDirectoryName(const Zstring& dirString) // throw() //remove leading/trailing whitespace trim(dirname, true, false); - while (endsWith(dirname, " ")) //don't remove all whitespace from right, e.g. 0xa0 may be used as part of dir name + while (endsWith(dirname, Zstr(' '))) //don't remove all whitespace from right, e.g. 0xa0 may be used as part of dir name dirname.resize(dirname.size() - 1); if (dirname.empty()) //an empty string would later be resolved as "\"; this is not desired @@ -613,7 +613,7 @@ void zen::loginNetworkShare(const Zstring& dirnameOrig, bool allowUserInteractio trgRes.dwType = RESOURCETYPE_DISK; trgRes.lpRemoteName = const_cast<LPWSTR>(networkShare.c_str()); //trgRes is "__in" - //note: following function call may block heavily if network is not reachable!!! + //following function call may block heavily if network is not reachable!!! DWORD rv2 = ::WNetAddConnection2(&trgRes, // __in LPNETRESOURCE lpNetResource, nullptr, // __in LPCTSTR lpPassword, nullptr, // __in LPCTSTR lpUsername, diff --git a/lib/resources.cpp b/lib/resources.cpp index 3ae24d1d..670f2cfd 100644 --- a/lib/resources.cpp +++ b/lib/resources.cpp @@ -53,7 +53,7 @@ GlobalResources::GlobalResources() wxImage::AddHandler(new wxPNGHandler); //ownership passed wxZipInputStream resourceFile(input, wxConvUTF8); - //do NOT rely on wxConvLocal! May result in "Cannot convert from the charset 'Unknown encoding (-1)'!" + //do NOT rely on wxConvLocal! ON failure shows unhelpful popup "Cannot convert from the charset 'Unknown encoding (-1)'!" while (true) { diff --git a/lib/return_codes.h b/lib/return_codes.h new file mode 100644 index 00000000..c5f8fd15 --- /dev/null +++ b/lib/return_codes.h @@ -0,0 +1,22 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) ZenJu (zhnmju123 AT gmx DOT de) - All Rights Reserved * +// ************************************************************************** + +#ifndef RETURN_CODES_H_INCLUDED +#define RETURN_CODES_H_INCLUDED + +namespace zen +{ +enum FfsReturnCode +{ + FFS_RC_SUCCESS = 0, + FFS_RC_FINISHED_WITH_ERRORS, + FFS_RC_ABORTED, + FFS_RC_EXCEPTION, +}; +} + + +#endif // RETURN_CODES_H_INCLUDED diff --git a/lib/shadow.cpp b/lib/shadow.cpp index f4d7f3af..ba4e1f5e 100644 --- a/lib/shadow.cpp +++ b/lib/shadow.cpp @@ -27,7 +27,7 @@ bool runningWOW64() //test if process is running under WOW64 (reference http://m { BOOL isWow64 = FALSE; if (isWow64Process(::GetCurrentProcess(), &isWow64)) - return isWow64 == TRUE; + return isWow64 != FALSE; } return false; diff --git a/lib/status_handler.h b/lib/status_handler.h index 7b7cb3d7..ca7af298 100644 --- a/lib/status_handler.h +++ b/lib/status_handler.h @@ -8,6 +8,7 @@ #define STATUSHANDLER_H_INCLUDED #include "../process_callback.h" +#include <vector> #include <string> #include <zen/int64.h> #include <zen/i18n.h> diff --git a/lib/xml_base.cpp b/lib/xml_base.cpp index 3f6cc0be..8f8ee74d 100644 --- a/lib/xml_base.cpp +++ b/lib/xml_base.cpp @@ -44,9 +44,6 @@ void xmlAccess::loadXmlDocument(const Zstring& filename, XmlDoc& doc) //throw Ff } catch (const FileError& error) { - if (!fileExists(filename)) - throw FfsXmlError(replaceCpy(_("Cannot find file %x."), L"%x", fmtFileName(filename))); - throw FfsXmlError(error.toString()); } |