summaryrefslogtreecommitdiff
path: root/zen
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2015-10-02 14:52:04 +0200
committerDaniel Wilhelm <daniel@wili.li>2015-10-02 14:52:04 +0200
commit1845c028b8cb8496d1d78f0da738120e1c31401a (patch)
treeadf9fb436aea09be367aef8ed3b6cdbf6a46e34c /zen
parent6.7 (diff)
downloadFreeFileSync-1845c028b8cb8496d1d78f0da738120e1c31401a.tar.gz
FreeFileSync-1845c028b8cb8496d1d78f0da738120e1c31401a.tar.bz2
FreeFileSync-1845c028b8cb8496d1d78f0da738120e1c31401a.zip
6.8
Diffstat (limited to 'zen')
-rw-r--r--zen/async_task.h4
-rw-r--r--zen/dir_watcher.cpp84
-rw-r--r--zen/dir_watcher.h8
-rw-r--r--zen/dst_hack.cpp65
-rw-r--r--zen/file_error.h4
-rw-r--r--zen/file_handling.cpp275
-rw-r--r--zen/file_handling.h27
-rw-r--r--zen/file_id_def.h20
-rw-r--r--zen/file_io.cpp62
-rw-r--r--zen/file_io.h22
-rw-r--r--zen/file_traverser.cpp443
-rw-r--r--zen/file_traverser.h25
-rw-r--r--zen/fixed_list.h4
-rw-r--r--zen/format_unit.cpp28
-rw-r--r--zen/format_unit.h10
-rw-r--r--zen/int64.h222
-rw-r--r--zen/long_path_prefix.h6
-rw-r--r--zen/notify_removal.cpp8
-rw-r--r--zen/process_priority.cpp7
-rw-r--r--zen/recycler.cpp72
-rw-r--r--zen/recycler.h7
-rw-r--r--zen/serialize.h16
-rw-r--r--zen/shell_execute.h8
-rw-r--r--zen/symlink_target.h1
-rw-r--r--zen/thread.h4
-rw-r--r--zen/win_ver.h2
-rw-r--r--zen/xml_io.cpp20
-rw-r--r--zen/xml_io.h9
-rw-r--r--zen/zstring.cpp7
-rw-r--r--zen/zstring.h7
30 files changed, 661 insertions, 816 deletions
diff --git a/zen/async_task.h b/zen/async_task.h
index c5e5857a..f9bea890 100644
--- a/zen/async_task.h
+++ b/zen/async_task.h
@@ -9,8 +9,8 @@
#include <list>
#include <functional>
-#include <zen/thread.h>
-#include <zen/scope_guard.h>
+#include "thread.h"
+#include "scope_guard.h"
//#include "type_tools.h"
namespace zen
diff --git a/zen/dir_watcher.cpp b/zen/dir_watcher.cpp
index 258a1c35..3751e5dd 100644
--- a/zen/dir_watcher.cpp
+++ b/zen/dir_watcher.cpp
@@ -22,7 +22,7 @@
#elif defined ZEN_MAC
#include <CoreServices/CoreServices.h>
-#include <zen/osx_string.h>
+#include "osx_string.h"
#endif
using namespace zen;
@@ -35,7 +35,7 @@ class SharedData
{
public:
//context of worker thread
- void addChanges(const char* buffer, DWORD bytesWritten, const Zstring& dirname) //throw ()
+ void addChanges(const char* buffer, DWORD bytesWritten, const Zstring& dirpath) //throw ()
{
boost::lock_guard<boost::mutex> dummy(lockAccess);
@@ -48,7 +48,7 @@ public:
{
const FILE_NOTIFY_INFORMATION& notifyInfo = reinterpret_cast<const FILE_NOTIFY_INFORMATION&>(*bufPos);
- const Zstring fullname = dirname + Zstring(notifyInfo.FileName, notifyInfo.FileNameLength / sizeof(WCHAR));
+ const Zstring fullpath = dirpath + Zstring(notifyInfo.FileName, notifyInfo.FileNameLength / sizeof(WCHAR));
[&]
{
@@ -57,7 +57,7 @@ public:
if (notifyInfo.Action == FILE_ACTION_MODIFIED)
{
//note: this check will not work if top watched directory has been renamed
- const DWORD ret = ::GetFileAttributes(applyLongPathPrefix(fullname).c_str());
+ const DWORD ret = ::GetFileAttributes(applyLongPathPrefix(fullpath).c_str());
if (ret != INVALID_FILE_ATTRIBUTES && (ret & FILE_ATTRIBUTE_DIRECTORY)) //returns true for (dir-)symlinks also
return;
}
@@ -67,14 +67,14 @@ public:
{
case FILE_ACTION_ADDED:
case FILE_ACTION_RENAMED_NEW_NAME: //harmonize with "move" which is notified as "create + delete"
- changedFiles.push_back(DirWatcher::Entry(DirWatcher::ACTION_CREATE, fullname));
+ changedFiles.push_back(DirWatcher::Entry(DirWatcher::ACTION_CREATE, fullpath));
break;
case FILE_ACTION_REMOVED:
case FILE_ACTION_RENAMED_OLD_NAME:
- changedFiles.push_back(DirWatcher::Entry(DirWatcher::ACTION_DELETE, fullname));
+ changedFiles.push_back(DirWatcher::Entry(DirWatcher::ACTION_DELETE, fullpath));
break;
case FILE_ACTION_MODIFIED:
- changedFiles.push_back(DirWatcher::Entry(DirWatcher::ACTION_UPDATE, fullname));
+ changedFiles.push_back(DirWatcher::Entry(DirWatcher::ACTION_UPDATE, fullpath));
break;
}
}();
@@ -87,10 +87,10 @@ public:
}
////context of main thread
- //void addChange(const Zstring& dirname) //throw ()
+ //void addChange(const Zstring& dirpath) //throw ()
//{
// boost::lock_guard<boost::mutex> dummy(lockAccess);
- // changedFiles.insert(dirname);
+ // changedFiles.insert(dirpath);
//}
@@ -144,10 +144,10 @@ public:
ReadChangesAsync(const Zstring& directory, //make sure to not leak-in thread-unsafe types!
const std::shared_ptr<SharedData>& shared) :
shared_(shared),
- dirnamePf(appendSeparator(directory)),
+ dirpathPf(appendSeparator(directory)),
hDir(INVALID_HANDLE_VALUE)
{
- hDir = ::CreateFile(applyLongPathPrefix(dirnamePf).c_str(), //_In_ LPCTSTR lpFileName,
+ hDir = ::CreateFile(applyLongPathPrefix(dirpathPf).c_str(), //_In_ LPCTSTR lpFileName,
FILE_LIST_DIRECTORY, //_In_ DWORD dwDesiredAccess,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, //_In_ DWORD dwShareMode,
nullptr, //_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
@@ -165,7 +165,7 @@ public:
hDir(INVALID_HANDLE_VALUE)
{
shared_ = std::move(other.shared_);
- dirnamePf = std::move(other.dirnamePf);
+ dirpathPf = std::move(other.dirpathPf);
std::swap(hDir, other.hDir);
}
@@ -194,7 +194,7 @@ public:
if (overlapped.hEvent == nullptr)
{
const DWORD lastError = ::GetLastError(); //copy before directly or indirectly making other system calls!
- return shared_->reportError(replaceCpy(_("Cannot monitor directory %x."), L"%x", fmtFileName(dirnamePf)), formatSystemError(L"CreateEvent", lastError), lastError);
+ return shared_->reportError(replaceCpy(_("Cannot monitor directory %x."), L"%x", fmtFileName(dirpathPf)), formatSystemError(L"CreateEvent", lastError), lastError);
}
ZEN_ON_SCOPE_EXIT(::CloseHandle(overlapped.hEvent));
@@ -214,7 +214,7 @@ public:
nullptr)) // __in_opt LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
{
const DWORD lastError = ::GetLastError(); //copy before directly or indirectly making other system calls!
- return shared_->reportError(replaceCpy(_("Cannot monitor directory %x."), L"%x", fmtFileName(dirnamePf)), formatSystemError(L"ReadDirectoryChangesW", lastError), lastError);
+ return shared_->reportError(replaceCpy(_("Cannot monitor directory %x."), L"%x", fmtFileName(dirpathPf)), formatSystemError(L"ReadDirectoryChangesW", lastError), lastError);
}
//async I/O is a resource that needs to be guarded since it will write to local variable "buffer"!
@@ -238,7 +238,7 @@ public:
{
const DWORD lastError = ::GetLastError(); //copy before directly or indirectly making other system calls!
if (lastError != ERROR_IO_INCOMPLETE)
- return shared_->reportError(replaceCpy(_("Cannot monitor directory %x."), L"%x", fmtFileName(dirnamePf)), formatSystemError(L"GetOverlappedResult", lastError), lastError);
+ return shared_->reportError(replaceCpy(_("Cannot monitor directory %x."), L"%x", fmtFileName(dirpathPf)), formatSystemError(L"GetOverlappedResult", lastError), lastError);
//execute asynchronous procedure calls (APC) queued on this thread
::SleepEx(50, // __in DWORD dwMilliseconds,
@@ -248,7 +248,7 @@ public:
}
guardAio.dismiss();
- shared_->addChanges(&buffer[0], bytesWritten, dirnamePf); //throw ()
+ shared_->addChanges(&buffer[0], bytesWritten, dirpathPf); //throw ()
}
}
catch (boost::thread_interrupted&)
@@ -260,13 +260,13 @@ public:
HANDLE getDirHandle() const { return hDir; } //for reading/monitoring purposes only, don't abuse (e.g. close handle)!
private:
- ReadChangesAsync(const ReadChangesAsync&);
- ReadChangesAsync& operator=(const ReadChangesAsync&);
+ ReadChangesAsync (const ReadChangesAsync&) = delete;
+ ReadChangesAsync& operator=(const ReadChangesAsync&) = delete;
//shared between main and worker:
std::shared_ptr<SharedData> shared_;
//worker thread only:
- Zstring dirnamePf; //thread safe!
+ Zstring dirpathPf; //thread safe!
HANDLE hDir;
};
@@ -314,7 +314,7 @@ struct DirWatcher::Pimpl
boost::thread worker;
std::shared_ptr<SharedData> shared;
- Zstring dirname;
+ Zstring dirpath;
std::unique_ptr<HandleVolumeRemoval> volRemoval;
};
@@ -323,7 +323,7 @@ DirWatcher::DirWatcher(const Zstring& directory) : //throw FileError
pimpl_(new Pimpl)
{
pimpl_->shared = std::make_shared<SharedData>();
- pimpl_->dirname = directory;
+ pimpl_->dirpath = directory;
ReadChangesAsync reader(directory, pimpl_->shared); //throw FileError
pimpl_->volRemoval.reset(new HandleVolumeRemoval(reader.getDirHandle(), pimpl_->worker)); //throw FileError
@@ -360,7 +360,7 @@ std::vector<DirWatcher::Entry> DirWatcher::getChanges(const std::function<void()
boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(50));
}
- output.push_back(Entry(ACTION_DELETE, pimpl_->dirname)); //report removal as change to main directory
+ output.push_back(Entry(ACTION_DELETE, pimpl_->dirpath)); //report removal as change to main directory
}
else //the normal case...
pimpl_->shared->fetchChanges(output); //throw FileError
@@ -376,11 +376,11 @@ class DirsOnlyTraverser : public zen::TraverseCallback
public:
DirsOnlyTraverser(std::vector<Zstring>& dirs) : dirs_(dirs) {}
- virtual void onFile (const Zchar* shortName, const Zstring& fullName, const FileInfo& details) {}
- virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) { return LINK_SKIP; }
- virtual TraverseCallback* onDir(const Zchar* shortName, const Zstring& fullName)
+ virtual void onFile (const Zchar* shortName, const Zstring& filepath, const FileInfo& details) {}
+ virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& linkpath, const SymlinkInfo& details) { return LINK_SKIP; }
+ virtual TraverseCallback* onDir(const Zchar* shortName, const Zstring& dirpath)
{
- dirs_.push_back(fullName);
+ dirs_.push_back(dirpath);
return this;
}
virtual HandleError reportDirError (const std::wstring& msg, size_t retryNumber) { throw FileError(msg); }
@@ -396,7 +396,7 @@ struct DirWatcher::Pimpl
{
Pimpl() : notifDescr() {}
- Zstring baseDirname;
+ Zstring basedirpath;
int notifDescr;
std::map<int, Zstring> watchDescrs; //watch descriptor and (sub-)directory name (postfixed with separator) -> owned by "notifDescr"
};
@@ -406,18 +406,18 @@ DirWatcher::DirWatcher(const Zstring& directory) : //throw FileError
pimpl_(new Pimpl)
{
//get all subdirectories
- Zstring dirname = directory;
- if (endsWith(dirname, FILE_NAME_SEPARATOR))
- dirname.resize(dirname.size() - 1);
+ Zstring dirpathFmt = directory;
+ if (endsWith(dirpathFmt, FILE_NAME_SEPARATOR))
+ dirpathFmt.resize(dirpathFmt.size() - 1);
- std::vector<Zstring> fullDirList { dirname };
+ std::vector<Zstring> fullDirList { dirpathFmt };
{
DirsOnlyTraverser traverser(fullDirList); //throw FileError
- zen::traverseFolder(dirname, traverser); //don't traverse into symlinks (analog to windows build)
+ zen::traverseFolder(dirpathFmt, traverser); //don't traverse into symlinks (analog to windows build)
}
//init
- pimpl_->baseDirname = directory;
+ pimpl_->basedirpath = directory;
pimpl_->notifDescr = ::inotify_init();
if (pimpl_->notifDescr == -1)
throwFileError(replaceCpy(_("Cannot monitor directory %x."), L"%x", fmtFileName(directory)), L"inotify_init", getLastError());
@@ -481,7 +481,7 @@ std::vector<DirWatcher::Entry> DirWatcher::getChanges(const std::function<void()
if (errno == EAGAIN) //this error is ignored in all inotify wrappers I found
return std::vector<Entry>();
- throwFileError(replaceCpy(_("Cannot monitor directory %x."), L"%x", fmtFileName(pimpl_->baseDirname)), L"read", getLastError());
+ throwFileError(replaceCpy(_("Cannot monitor directory %x."), L"%x", fmtFileName(pimpl_->basedirpath)), L"read", getLastError());
}
std::vector<Entry> output;
@@ -573,18 +573,18 @@ struct DirWatcher::Pimpl
DirWatcher::DirWatcher(const Zstring& directory) :
pimpl_(new Pimpl)
{
- CFStringRef dirnameCf = osx::createCFString(directory.c_str()); //returns nullptr on error
- if (!dirnameCf)
+ CFStringRef dirpathCf = osx::createCFString(directory.c_str()); //returns nullptr on error
+ if (!dirpathCf)
throw FileError(replaceCpy(_("Cannot monitor directory %x."), L"%x", fmtFileName(directory)), L"Function call failed: createCFString"); //no error code documented!
- ZEN_ON_SCOPE_EXIT(::CFRelease(dirnameCf));
+ ZEN_ON_SCOPE_EXIT(::CFRelease(dirpathCf));
- CFArrayRef dirnameCfArray = ::CFArrayCreate(nullptr, //CFAllocatorRef allocator,
- reinterpret_cast<const void**>(&dirnameCf), //const void** values,
+ CFArrayRef dirpathCfArray = ::CFArrayCreate(nullptr, //CFAllocatorRef allocator,
+ reinterpret_cast<const void**>(&dirpathCf), //const void** values,
1, //CFIndex numValues,
nullptr); //const CFArrayCallBacks* callBacks
- if (!dirnameCfArray)
+ if (!dirpathCfArray)
throw FileError(replaceCpy(_("Cannot monitor directory %x."), L"%x", fmtFileName(directory)), L"Function call failed: CFArrayCreate"); //no error code documented!
- ZEN_ON_SCOPE_EXIT(::CFRelease(dirnameCfArray));
+ ZEN_ON_SCOPE_EXIT(::CFRelease(dirpathCfArray));
FSEventStreamContext context = {};
context.info = &pimpl_->changedFiles;
@@ -592,7 +592,7 @@ DirWatcher::DirWatcher(const Zstring& directory) :
pimpl_->eventStream = ::FSEventStreamCreate(nullptr, //CFAllocatorRef allocator,
&eventCallback, //FSEventStreamCallback callback,
&context, //FSEventStreamContext* context,
- dirnameCfArray, //CFArrayRef pathsToWatch,
+ dirpathCfArray, //CFArrayRef pathsToWatch,
kFSEventStreamEventIdSinceNow, //FSEventStreamEventId sinceWhen,
0, //CFTimeInterval latency, in seconds
kFSEventStreamCreateFlagWatchRoot |
diff --git a/zen/dir_watcher.h b/zen/dir_watcher.h
index bc9714a0..99131470 100644
--- a/zen/dir_watcher.h
+++ b/zen/dir_watcher.h
@@ -49,18 +49,18 @@ public:
struct Entry
{
Entry() : action_(ACTION_CREATE) {}
- Entry(ActionType action, const Zstring& filename) : action_(action), filename_(filename) {}
+ Entry(ActionType action, const Zstring& filepath) : action_(action), filepath_(filepath) {}
ActionType action_;
- Zstring filename_;
+ Zstring filepath_;
};
//extract accumulated changes since last call
std::vector<Entry> getChanges(const std::function<void()>& processGuiMessages); //throw FileError
private:
- DirWatcher(const DirWatcher&);
- DirWatcher& operator=(const DirWatcher&);
+ DirWatcher (const DirWatcher&) = delete;
+ DirWatcher& operator=(const DirWatcher&) = delete;
struct Pimpl;
std::unique_ptr<Pimpl> pimpl_;
diff --git a/zen/dst_hack.cpp b/zen/dst_hack.cpp
index 95fbe732..52d45679 100644
--- a/zen/dst_hack.cpp
+++ b/zen/dst_hack.cpp
@@ -14,16 +14,16 @@ using namespace zen;
namespace
{
//fast ::GetVolumePathName() clone: let's hope it's not too simple (doesn't honor mount points)
-Zstring getVolumeName(const Zstring& filename)
+Zstring getVolumeName(const Zstring& filepath)
{
//this call is expensive: ~1.5 ms!
- // if (!::GetVolumePathName(filename.c_str(), //__in LPCTSTR lpszFileName,
+ // if (!::GetVolumePathName(filepath.c_str(), //__in LPCTSTR lpszFileName,
// fsName, //__out LPTSTR lpszVolumePathName,
// BUFFER_SIZE)) //__in DWORD cchBufferLength
// ...
// Zstring volumePath = appendSeparator(fsName);
- const Zstring nameFmt = appendSeparator(removeLongPathPrefix(filename)); //throw()
+ const Zstring nameFmt = appendSeparator(removeLongPathPrefix(filepath)); //throw()
if (startsWith(nameFmt, Zstr("\\\\"))) //UNC path: "\\ComputerName\SharedFolder\"
{
@@ -50,9 +50,9 @@ Zstring getVolumeName(const Zstring& filename)
}
-bool dst::isFatDrive(const Zstring& fileName) //throw()
+bool dst::isFatDrive(const Zstring& filepath) //throw()
{
- const Zstring volumePath = getVolumeName(fileName);
+ const Zstring volumePath = getVolumeName(filepath);
if (volumePath.empty())
return false;
@@ -123,37 +123,34 @@ Requires Windows Vista!
namespace
{
-//convert UInt64 and Int64 to FILETIME
+//convert std::uint64_t and std::int64_t to FILETIME
inline
-FILETIME toFiletime(Int64 number)
+FILETIME toFiletime(std::uint64_t number)
{
- const UInt64 unsig = to<UInt64>(number);
+ ULARGE_INTEGER cvt = {};
+ cvt.QuadPart = number;
- FILETIME output = {};
- output.dwLowDateTime = unsig.getLo();
- output.dwHighDateTime = unsig.getHi();
+ const FILETIME output = { cvt.LowPart, cvt.HighPart };
return output;
}
-FILETIME toFiletime(UInt64 number)
+inline
+FILETIME toFiletime(std::int64_t number)
{
- FILETIME output = {};
- output.dwLowDateTime = number.getLo();
- output.dwHighDateTime = number.getHi();
- return output;
+ return toFiletime(static_cast<std::uint64_t>(number));
}
inline
-UInt64 toUInt64(const FILETIME& fileTime)
+std::uint64_t toUInt64(const FILETIME& fileTime)
{
- return UInt64(fileTime.dwLowDateTime, fileTime.dwHighDateTime);
+ return get64BitUInt(fileTime.dwLowDateTime, fileTime.dwHighDateTime);
}
inline
-Int64 toInt64(const FILETIME& fileTime)
+std::int64_t toInt64(const FILETIME& fileTime)
{
- return to<Int64>(UInt64(fileTime.dwLowDateTime, fileTime.dwHighDateTime));
+ return get64BitUInt(fileTime.dwLowDateTime, fileTime.dwHighDateTime); //convert unsigned to signed in return
}
@@ -216,7 +213,7 @@ const size_t WRITE_TIME_HASH_BITS = CREATE_TIME_INFO_BITS - INDICATOR_EXISTING_B
template <size_t precision> inline
-FILETIME encodeRawInformation(UInt64 rawInfo)
+FILETIME encodeRawInformation(std::uint64_t rawInfo)
{
rawInfo *= precision;
rawInfo += toUInt64(FAT_MIN_TIME);
@@ -227,13 +224,13 @@ FILETIME encodeRawInformation(UInt64 rawInfo)
template <size_t precision> inline
-UInt64 extractRawInformation(const FILETIME& createTime)
+std::uint64_t extractRawInformation(const FILETIME& createTime)
{
assert(toUInt64(FAT_MIN_TIME) <= toUInt64(createTime));
assert(toUInt64(createTime) <= toUInt64(FAT_MAX_TIME));
//FAT create time ranges from 1980 - 2107 (2^7 years) with 1/100 seconds precision
- UInt64 rawInfo = toUInt64(createTime);
+ std::uint64_t rawInfo = toUInt64(createTime);
rawInfo -= toUInt64(FAT_MIN_TIME);
rawInfo /= precision; //reduce precision (FILETIME has unit 10^-7 s)
@@ -245,9 +242,9 @@ UInt64 extractRawInformation(const FILETIME& createTime)
//convert write time to it's minimal representation (no restriction to FAT range "1980 - 2107")
inline
-UInt64 extractRawWriteTime(const FILETIME& writeTime)
+std::uint64_t extractRawWriteTime(const FILETIME& writeTime)
{
- UInt64 rawInfo = toUInt64(writeTime);
+ std::uint64_t rawInfo = toUInt64(writeTime);
assert(rawInfo % PRECISION_WRITE_TIME == 0U);
rawInfo /= PRECISION_WRITE_TIME; //reduce precision (FILETIME has unit 10^-7 s)
return rawInfo;
@@ -258,7 +255,7 @@ UInt64 extractRawWriteTime(const FILETIME& writeTime)
inline
FILETIME roundToFatWriteTime(const FILETIME& writeTime)
{
- UInt64 rawData = toUInt64(writeTime);
+ std::uint64_t rawData = toUInt64(writeTime);
if (rawData % PRECISION_WRITE_TIME != 0U)
rawData += PRECISION_WRITE_TIME;
@@ -277,7 +274,7 @@ std::bitset<UTC_LOCAL_OFFSET_BITS> getUtcLocalShift()
const FILETIME localTime = utcToLocal(utcTime);
- const int timeShiftSec = to<int>((toInt64(localTime) - toInt64(utcTime)) / 10000000); //time shift in seconds
+ const int timeShiftSec = static_cast<int>((toInt64(localTime) - toInt64(utcTime)) / 10000000); //time shift in seconds
const int timeShiftQuarter = timeShiftSec / (60 * 15); //time shift in quarter-hours
@@ -311,7 +308,7 @@ int convertUtcLocalShift(std::bitset<UTC_LOCAL_OFFSET_BITS> rawShift)
}
-bool dst::fatHasUtcEncoded(const RawTime& rawTime) //"createTimeRaw" as retrieved by ::FindFirstFile() and ::GetFileAttributesEx(); throw (std::runtime_error)
+bool dst::fatHasUtcEncoded(const RawTime& rawTime) //"createTimeRaw" as retrieved by ::FindFirstFile() and ::GetFileAttributesEx(); throw std::runtime_error
{
if (toUInt64(rawTime.createTimeRaw) < toUInt64(FAT_MIN_TIME) ||
toUInt64(FAT_MAX_TIME) < toUInt64(rawTime.createTimeRaw))
@@ -320,7 +317,7 @@ bool dst::fatHasUtcEncoded(const RawTime& rawTime) //"createTimeRaw" as retrieve
return false;
}
- const UInt64 rawInfo = extractRawInformation<PRECISION_CREATE_TIME>(utcToLocal(rawTime.createTimeRaw));
+ const std::uint64_t rawInfo = extractRawInformation<PRECISION_CREATE_TIME>(utcToLocal(rawTime.createTimeRaw));
assert_static(WRITE_TIME_HASH_BITS == 30);
return (extractRawWriteTime(utcToLocal(rawTime.writeTimeRaw)) & 0x3FFFFFFFU) == (rawInfo & 0x3FFFFFFFU) && //ensure write time wasn't changed externally
@@ -335,7 +332,7 @@ dst::RawTime dst::fatEncodeUtcTime(const FILETIME& writeTimeRealUtc) //throw std
//create time lets us store 40 bit of information
//indicator that utc time is encoded -> hopefully results in a date long way in the future; but even if this bit is accidentally set, we still have the hash!
- UInt64 data = 1U;
+ std::uint64_t data = 1U;
const std::bitset<UTC_LOCAL_OFFSET_BITS> utcShift = getUtcLocalShift();
data <<= UTC_LOCAL_OFFSET_BITS;
@@ -358,14 +355,14 @@ FILETIME dst::fatDecodeUtcTime(const RawTime& rawTime) //return real UTC time; t
if (!fatHasUtcEncoded(rawTime))
return rawTime.writeTimeRaw;
- const UInt64 rawInfo = extractRawInformation<PRECISION_CREATE_TIME>(utcToLocal(rawTime.createTimeRaw));
+ const std::uint64_t rawInfo = extractRawInformation<PRECISION_CREATE_TIME>(utcToLocal(rawTime.createTimeRaw));
- const std::bitset<UTC_LOCAL_OFFSET_BITS> rawShift(to<int>((rawInfo >> WRITE_TIME_HASH_BITS) & 0x7FU)); //static_cast<int>: a shame MSC... "unsigned long" should be supported instead!
+ const std::bitset<UTC_LOCAL_OFFSET_BITS> rawShift(static_cast<int>((rawInfo >> WRITE_TIME_HASH_BITS) & 0x7FU)); //static_cast<int>: a shame MSC... "unsigned long long" should be supported instead!
assert_static(UTC_LOCAL_OFFSET_BITS == 7);
- const int timeShiftSec = convertUtcLocalShift(rawShift);
+ const std::int64_t timeShiftSec = convertUtcLocalShift(rawShift);
const FILETIME writeTimeLocal = utcToLocal(rawTime.writeTimeRaw);
- const Int64 realUTC = toInt64(writeTimeLocal) - Int64(timeShiftSec) * 10000000;
+ const std::int64_t realUTC = toInt64(writeTimeLocal) - timeShiftSec * 10000000;
return toFiletime(realUTC);
}
diff --git a/zen/file_error.h b/zen/file_error.h
index cb5e3a7b..73cfa17a 100644
--- a/zen/file_error.h
+++ b/zen/file_error.h
@@ -55,11 +55,11 @@ std::wstring operator+(const std::wstring& lhs, const Zstring& rhs) { return std
inline
-std::wstring fmtFileName(const Zstring& filename)
+std::wstring fmtFileName(const Zstring& filepath)
{
std::wstring output;
output += L'\"';
- output += utfCvrtTo<std::wstring>(filename);
+ output += utfCvrtTo<std::wstring>(filepath);
output += L'\"';
return output;
}
diff --git a/zen/file_handling.cpp b/zen/file_handling.cpp
index cecebff1..b4622a9c 100644
--- a/zen/file_handling.cpp
+++ b/zen/file_handling.cpp
@@ -8,13 +8,13 @@
#include <map>
#include <algorithm>
#include <stdexcept>
+#include "int64.h"
#include "file_traverser.h"
#include "scope_guard.h"
#include "symlink_target.h"
#include "file_io.h"
#include "assert_static.h"
#include "file_id_def.h"
-//#include <boost/thread/tss.hpp>
#ifdef ZEN_WIN
#include <Aclapi.h>
@@ -35,7 +35,6 @@
#elif defined ZEN_MAC
#include <sys/mount.h> //statfs
-//#include <utime.h>
#endif
#if defined ZEN_LINUX || defined ZEN_MAC
@@ -46,34 +45,34 @@
using namespace zen;
-bool zen::fileExists(const Zstring& filename)
+bool zen::fileExists(const Zstring& filepath)
{
//symbolic links (broken or not) are also treated as existing files!
#ifdef ZEN_WIN
- const DWORD attr = ::GetFileAttributes(applyLongPathPrefix(filename).c_str());
+ const DWORD attr = ::GetFileAttributes(applyLongPathPrefix(filepath).c_str());
if (attr != INVALID_FILE_ATTRIBUTES)
return (attr & FILE_ATTRIBUTE_DIRECTORY) == 0; //returns true for (file-)symlinks also
#elif defined ZEN_LINUX || defined ZEN_MAC
struct ::stat fileInfo = {};
- if (::stat(filename.c_str(), &fileInfo) == 0) //follow symlinks!
+ if (::stat(filepath.c_str(), &fileInfo) == 0) //follow symlinks!
return S_ISREG(fileInfo.st_mode);
#endif
return false;
}
-bool zen::dirExists(const Zstring& dirname)
+bool zen::dirExists(const Zstring& dirpath)
{
//symbolic links (broken or not) are also treated as existing directories!
#ifdef ZEN_WIN
- const DWORD attr = ::GetFileAttributes(applyLongPathPrefix(dirname).c_str());
+ const DWORD attr = ::GetFileAttributes(applyLongPathPrefix(dirpath).c_str());
if (attr != INVALID_FILE_ATTRIBUTES)
return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0; //returns true for (dir-)symlinks also
#elif defined ZEN_LINUX || defined ZEN_MAC
struct ::stat dirInfo = {};
- if (::stat(dirname.c_str(), &dirInfo) == 0) //follow symlinks!
+ if (::stat(dirpath.c_str(), &dirInfo) == 0) //follow symlinks!
return S_ISDIR(dirInfo.st_mode);
#endif
return false;
@@ -137,7 +136,7 @@ namespace
{
#ifdef ZEN_WIN
//(try to) enhance error messages by showing which processes lock the file
-Zstring getLockingProcessNames(const Zstring& filename) //throw(), empty string if none found or error occurred
+Zstring getLockingProcessNames(const Zstring& filepath) //throw(), empty string if none found or error occurred
{
if (vistaOrLater())
{
@@ -146,7 +145,7 @@ Zstring getLockingProcessNames(const Zstring& filename) //throw(), empty string
const DllFun<FunType_freeString> freeString (getDllName(), funName_freeString);
if (getLockingProcesses && freeString)
- if (const wchar_t* procList = getLockingProcesses(filename.c_str()))
+ if (const wchar_t* procList = getLockingProcesses(filepath.c_str()))
{
ZEN_ON_SCOPE_EXIT(freeString(procList));
return procList;
@@ -158,14 +157,14 @@ Zstring getLockingProcessNames(const Zstring& filename) //throw(), empty string
}
-UInt64 zen::getFilesize(const Zstring& filename) //throw FileError
+std::uint64_t zen::getFilesize(const Zstring& filepath) //throw FileError
{
#ifdef ZEN_WIN
WIN32_FIND_DATA fileInfo = {};
{
- const HANDLE searchHandle = ::FindFirstFile(applyLongPathPrefix(filename).c_str(), &fileInfo);
+ const HANDLE searchHandle = ::FindFirstFile(applyLongPathPrefix(filepath).c_str(), &fileInfo);
if (searchHandle == INVALID_HANDLE_VALUE)
- throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(filename)), L"FindFirstFile", getLastError());
+ throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(filepath)), L"FindFirstFile", getLastError());
::FindClose(searchHandle);
}
// WIN32_FILE_ATTRIBUTE_DATA sourceAttr = {};
@@ -174,11 +173,11 @@ UInt64 zen::getFilesize(const Zstring& filename) //throw FileError
// &sourceAttr)) //__out LPVOID lpFileInformation
if (!isSymlink(fileInfo))
- return UInt64(fileInfo.nFileSizeLow, fileInfo.nFileSizeHigh);
+ return get64BitUInt(fileInfo.nFileSizeLow, fileInfo.nFileSizeHigh);
else
{
//open handle to target of symbolic link
- const HANDLE hFile = ::CreateFile(applyLongPathPrefix(filename).c_str(), //_In_ LPCTSTR lpFileName,
+ const HANDLE hFile = ::CreateFile(applyLongPathPrefix(filepath).c_str(), //_In_ LPCTSTR lpFileName,
0, //_In_ DWORD dwDesiredAccess,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, //_In_ DWORD dwShareMode,
nullptr, //_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
@@ -186,27 +185,27 @@ UInt64 zen::getFilesize(const Zstring& filename) //throw FileError
FILE_FLAG_BACKUP_SEMANTICS, /*needed to open a directory*/ //_In_ DWORD dwFlagsAndAttributes,
nullptr); //_In_opt_ HANDLE hTemplateFile
if (hFile == INVALID_HANDLE_VALUE)
- throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(filename)), L"CreateFile", getLastError());
+ throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(filepath)), L"CreateFile", getLastError());
ZEN_ON_SCOPE_EXIT(::CloseHandle(hFile));
BY_HANDLE_FILE_INFORMATION fileInfoHnd = {};
if (!::GetFileInformationByHandle(hFile, &fileInfoHnd))
- throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(filename)), L"GetFileInformationByHandle", getLastError());
+ throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(filepath)), L"GetFileInformationByHandle", getLastError());
- return UInt64(fileInfoHnd.nFileSizeLow, fileInfoHnd.nFileSizeHigh);
+ return get64BitUInt(fileInfoHnd.nFileSizeLow, fileInfoHnd.nFileSizeHigh);
}
#elif defined ZEN_LINUX || defined ZEN_MAC
struct ::stat fileInfo = {};
- if (::stat(filename.c_str(), &fileInfo) != 0)
- throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(filename)), L"stat", getLastError());
+ if (::stat(filepath.c_str(), &fileInfo) != 0)
+ throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(filepath)), L"stat", getLastError());
- return UInt64(fileInfo.st_size);
+ return fileInfo.st_size;
#endif
}
-UInt64 zen::getFreeDiskSpace(const Zstring& path) //throw FileError
+std::uint64_t zen::getFreeDiskSpace(const Zstring& path) //throw FileError
{
#ifdef ZEN_WIN
ULARGE_INTEGER bytesFree = {};
@@ -216,52 +215,52 @@ UInt64 zen::getFreeDiskSpace(const Zstring& path) //throw FileError
nullptr)) //__out_opt PULARGE_INTEGER lpTotalNumberOfFreeBytes
throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(path)), L"GetDiskFreeSpaceEx", getLastError());
- return UInt64(bytesFree.LowPart, bytesFree.HighPart);
+ return get64BitUInt(bytesFree.LowPart, bytesFree.HighPart);
#elif defined ZEN_LINUX || defined ZEN_MAC
struct statfs info = {};
if (::statfs(path.c_str(), &info) != 0)
throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(path)), L"statfs", getLastError());
- return UInt64(info.f_bsize) * info.f_bavail;
+ return static_cast<std::uint64_t>(info.f_bsize) * info.f_bavail;
#endif
}
-bool zen::removeFile(const Zstring& filename) //throw FileError
+bool zen::removeFile(const Zstring& filepath) //throw FileError
{
#ifdef ZEN_WIN
const wchar_t functionName[] = L"DeleteFile";
- const Zstring& filenameFmt = applyLongPathPrefix(filename);
- if (!::DeleteFile(filenameFmt.c_str()))
+ const Zstring& filepathFmt = applyLongPathPrefix(filepath);
+ if (!::DeleteFile(filepathFmt.c_str()))
#elif defined ZEN_LINUX || defined ZEN_MAC
const wchar_t functionName[] = L"unlink";
- if (::unlink(filename.c_str()) != 0)
+ if (::unlink(filepath.c_str()) != 0)
#endif
{
ErrorCode lastError = getLastError();
#ifdef ZEN_WIN
if (lastError == ERROR_ACCESS_DENIED) //function fails if file is read-only
{
- ::SetFileAttributes(filenameFmt.c_str(), FILE_ATTRIBUTE_NORMAL); //(try to) normalize file attributes
+ ::SetFileAttributes(filepathFmt.c_str(), FILE_ATTRIBUTE_NORMAL); //(try to) normalize file attributes
- if (::DeleteFile(filenameFmt.c_str())) //now try again...
+ if (::DeleteFile(filepathFmt.c_str())) //now try again...
return true;
lastError = ::GetLastError();
}
#endif
- if (!somethingExists(filename)) //warning: changes global error code!!
+ if (!somethingExists(filepath)) //warning: changes global error code!!
return false; //neither file nor any other object (e.g. broken symlink) with that name existing - caveat: what if "access is denied"!?!??!?!?
//begin of "regular" error reporting
- const std::wstring errorMsg = replaceCpy(_("Cannot delete file %x."), L"%x", fmtFileName(filename));
+ const std::wstring errorMsg = replaceCpy(_("Cannot delete file %x."), L"%x", fmtFileName(filepath));
std::wstring errorDescr = formatSystemError(functionName, lastError);
#ifdef ZEN_WIN
if (lastError == ERROR_SHARING_VIOLATION || //-> enhance error message!
lastError == ERROR_LOCK_VIOLATION)
{
- const Zstring procList = getLockingProcessNames(filename); //throw()
+ const Zstring procList = getLockingProcessNames(filepath); //throw()
if (!procList.empty())
errorDescr = _("The file is locked by another process:") + L"\n" + procList;
}
@@ -364,17 +363,17 @@ void renameFile_sub(const Zstring& oldName, const Zstring& newName) //throw File
::GetShortPathName()
::GetLongPathName() */
template <typename Function>
-Zstring getFilenameFmt(const Zstring& filename, Function fun) //throw(); returns empty string on error
+Zstring getFilenameFmt(const Zstring& filepath, Function fun) //throw(); returns empty string on error
{
- const Zstring filenameFmt = applyLongPathPrefix(filename);
+ const Zstring filepathFmt = applyLongPathPrefix(filepath);
- const DWORD bufferSize = fun(filenameFmt.c_str(), nullptr, 0);
+ const DWORD bufferSize = fun(filepathFmt.c_str(), nullptr, 0);
if (bufferSize == 0)
return Zstring();
std::vector<wchar_t> buffer(bufferSize);
- const DWORD charsWritten = fun(filenameFmt.c_str(), //__in LPCTSTR lpszShortPath,
+ const DWORD charsWritten = fun(filepathFmt.c_str(), //__in LPCTSTR lpszShortPath,
&buffer[0], //__out LPTSTR lpszLongPath,
bufferSize); //__in DWORD cchBuffer
if (charsWritten == 0 || charsWritten >= bufferSize)
@@ -384,18 +383,18 @@ Zstring getFilenameFmt(const Zstring& filename, Function fun) //throw(); returns
}
-Zstring findUnused8Dot3Name(const Zstring& filename) //find a unique 8.3 short name
+Zstring findUnused8Dot3Name(const Zstring& filepath) //find a unique 8.3 short name
{
- const Zstring pathPrefix = contains(filename, FILE_NAME_SEPARATOR) ?
- (beforeLast(filename, FILE_NAME_SEPARATOR) + FILE_NAME_SEPARATOR) : Zstring();
+ const Zstring pathPrefix = contains(filepath, FILE_NAME_SEPARATOR) ?
+ (beforeLast(filepath, FILE_NAME_SEPARATOR) + FILE_NAME_SEPARATOR) : Zstring();
- Zstring extension = afterLast(afterLast(filename, FILE_NAME_SEPARATOR), Zchar('.')); //extension needn't contain reasonable data
+ Zstring extension = afterLast(afterLast(filepath, FILE_NAME_SEPARATOR), Zchar('.')); //extension needn't contain reasonable data
if (extension.empty())
extension = Zstr("FFS");
else if (extension.length() > 3)
extension.resize(3);
- for (int index = 0; index < 100000000; ++index) //filename must be representable by <= 8 characters
+ for (int index = 0; index < 100000000; ++index) //filepath must be representable by <= 8 characters
{
const Zstring output = pathPrefix + numberTo<Zstring>(index) + Zchar('.') + extension;
if (!somethingExists(output)) //ensure uniqueness
@@ -405,24 +404,24 @@ Zstring findUnused8Dot3Name(const Zstring& filename) //find a unique 8.3 short n
}
-bool have8dot3NameClash(const Zstring& filename)
+bool have8dot3NameClash(const Zstring& filepath)
{
- if (!contains(filename, FILE_NAME_SEPARATOR))
+ if (!contains(filepath, FILE_NAME_SEPARATOR))
return false;
- if (somethingExists(filename)) //name OR directory!
+ if (somethingExists(filepath)) //name OR directory!
{
- const Zstring origName = afterLast(filename, FILE_NAME_SEPARATOR); //returns the whole string if ch not found
- const Zstring shortName = afterLast(getFilenameFmt(filename, ::GetShortPathName), FILE_NAME_SEPARATOR); //throw() returns empty string on error
- const Zstring longName = afterLast(getFilenameFmt(filename, ::GetLongPathName ), FILE_NAME_SEPARATOR); //
+ const Zstring origName = afterLast(filepath, FILE_NAME_SEPARATOR); //returns the whole string if ch not found
+ const Zstring shortName = afterLast(getFilenameFmt(filepath, ::GetShortPathName), FILE_NAME_SEPARATOR); //throw() returns empty string on error
+ const Zstring longName = afterLast(getFilenameFmt(filepath, ::GetLongPathName ), FILE_NAME_SEPARATOR); //
if (!shortName.empty() &&
!longName .empty() &&
EqualFilename()(origName, shortName) &&
!EqualFilename()(shortName, longName))
{
- //for filename short and long file name are equal and another unrelated file happens to have the same short name
- //e.g. filename == "TESTWE~1", but another file is existing named "TestWeb" with short name ""TESTWE~1"
+ //for filepath short and long file name are equal and another unrelated file happens to have the same short name
+ //e.g. filepath == "TESTWE~1", but another file is existing named "TestWeb" with short name ""TESTWE~1"
return true;
}
}
@@ -432,14 +431,14 @@ bool have8dot3NameClash(const Zstring& filename)
class Fix8Dot3NameClash //throw FileError
{
public:
- Fix8Dot3NameClash(const Zstring& filename)
+ Fix8Dot3NameClash(const Zstring& filepath)
{
- const Zstring longName = afterLast(getFilenameFmt(filename, ::GetLongPathName), FILE_NAME_SEPARATOR); //throw() returns empty string on error
+ const Zstring longName = afterLast(getFilenameFmt(filepath, ::GetLongPathName), FILE_NAME_SEPARATOR); //throw() returns empty string on error
- unrelatedFile = beforeLast(filename, FILE_NAME_SEPARATOR) + FILE_NAME_SEPARATOR + longName;
+ unrelatedFile = beforeLast(filepath, FILE_NAME_SEPARATOR) + FILE_NAME_SEPARATOR + longName;
//find another name in short format: this ensures the actual short name WILL be renamed as well!
- unrelatedFileParked = findUnused8Dot3Name(filename);
+ unrelatedFileParked = findUnused8Dot3Name(filepath);
//move already existing short name out of the way for now
renameFile_sub(unrelatedFile, unrelatedFileParked); //throw FileError, ErrorDifferentVolume
@@ -476,7 +475,7 @@ void zen::renameFile(const Zstring& oldName, const Zstring& newName) //throw Fil
//try to handle issues with already existing short 8.3 file names on Windows
if (have8dot3NameClash(newName))
{
- Fix8Dot3NameClash dummy(newName); //throw FileError; move clashing filename to the side
+ Fix8Dot3NameClash dummy(newName); //throw FileError; move clashing filepath to the side
//now try again...
renameFile_sub(oldName, newName); //throw FileError
return;
@@ -496,29 +495,29 @@ public:
files_(files),
dirs_(dirs) {}
- virtual void onFile(const Zchar* shortName, const Zstring& fullName, const FileInfo& details)
+ virtual void onFile(const Zchar* shortName, const Zstring& filepath, const FileInfo& details)
{
- files_.push_back(fullName);
+ files_.push_back(filepath);
}
- virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details)
+ virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& linkpath, const SymlinkInfo& details)
{
- if (dirExists(fullName)) //dir symlink
+ if (dirExists(linkpath)) //dir symlink
dirs_.push_back(shortName);
else //file symlink, broken symlink
files_.push_back(shortName);
return LINK_SKIP;
}
- virtual TraverseCallback* onDir(const Zchar* shortName, const Zstring& fullName)
+ virtual TraverseCallback* onDir(const Zchar* shortName, const Zstring& dirpath)
{
- dirs_.push_back(fullName);
+ dirs_.push_back(dirpath);
return nullptr; //DON'T traverse into subdirs; removeDirectory works recursively!
}
virtual HandleError reportDirError (const std::wstring& msg, size_t retryNumber) { throw FileError(msg); }
virtual HandleError reportItemError(const std::wstring& msg, size_t retryNumber, const Zchar* shortName) { throw FileError(msg); }
private:
- CollectFilesFlat(const CollectFilesFlat&);
- CollectFilesFlat& operator=(const CollectFilesFlat&);
+ CollectFilesFlat (const CollectFilesFlat&) = delete;
+ CollectFilesFlat& operator=(const CollectFilesFlat&) = delete;
std::vector<Zstring>& files_;
std::vector<Zstring>& dirs_;
@@ -526,8 +525,8 @@ private:
void removeDirectoryImpl(const Zstring& directory, //throw FileError
- const std::function<void (const Zstring& filename)>& onBeforeFileDeletion,
- const std::function<void (const Zstring& dirname)>& onBeforeDirDeletion)
+ const std::function<void (const Zstring& filepath)>& onBeforeFileDeletion,
+ const std::function<void (const Zstring& dirpath)>& onBeforeDirDeletion)
{
assert(somethingExists(directory)); //[!]
@@ -563,15 +562,15 @@ void removeDirectoryImpl(const Zstring& directory, //throw FileError
}
//delete directories recursively
- for (const Zstring& dirname : dirList)
- removeDirectoryImpl(dirname, onBeforeFileDeletion, onBeforeDirDeletion); //throw FileError; call recursively to correctly handle symbolic links
+ for (const Zstring& dirpath : dirList)
+ removeDirectoryImpl(dirpath, onBeforeFileDeletion, onBeforeDirDeletion); //throw FileError; call recursively to correctly handle symbolic links
//delete files
- for (const Zstring& filename : fileList)
+ for (const Zstring& filepath : fileList)
{
if (onBeforeFileDeletion)
- onBeforeFileDeletion(filename); //call once per file
- removeFile(filename); //throw FileError
+ onBeforeFileDeletion(filepath); //call once per file
+ removeFile(filepath); //throw FileError
}
//parent directory is deleted last
@@ -594,7 +593,7 @@ void removeDirectoryImpl(const Zstring& directory, //throw FileError
#ifdef ZEN_WIN
-void setFileTimeRaw(const Zstring& filename, const FILETIME& creationTime, const FILETIME& lastWriteTime, ProcSymlink procSl) //throw FileError
+void setFileTimeRaw(const Zstring& filepath, const FILETIME& creationTime, const FILETIME& lastWriteTime, ProcSymlink procSl) //throw FileError
{
{
//extra scope for debug check below
@@ -623,21 +622,21 @@ void setFileTimeRaw(const Zstring& filename, const FILETIME& creationTime, const
DWORD attribs = INVALID_FILE_ATTRIBUTES;
ZEN_ON_SCOPE_EXIT(
if (attribs != INVALID_FILE_ATTRIBUTES)
- ::SetFileAttributes(applyLongPathPrefix(filename).c_str(), attribs);
+ ::SetFileAttributes(applyLongPathPrefix(filepath).c_str(), attribs);
);
auto removeReadonly = [&]() -> bool //throw FileError; may need to remove the readonly-attribute (e.g. on FAT usb drives)
{
if (attribs == INVALID_FILE_ATTRIBUTES)
{
- const DWORD tmpAttr = ::GetFileAttributes(applyLongPathPrefix(filename).c_str());
+ const DWORD tmpAttr = ::GetFileAttributes(applyLongPathPrefix(filepath).c_str());
if (tmpAttr == INVALID_FILE_ATTRIBUTES)
- throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(filename)), L"GetFileAttributes", getLastError());
+ throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(filepath)), L"GetFileAttributes", getLastError());
if (tmpAttr & FILE_ATTRIBUTE_READONLY)
{
- if (!::SetFileAttributes(applyLongPathPrefix(filename).c_str(), FILE_ATTRIBUTE_NORMAL))
- throwFileError(replaceCpy(_("Cannot write file attributes of %x."), L"%x", fmtFileName(filename)), L"SetFileAttributes", getLastError());
+ if (!::SetFileAttributes(applyLongPathPrefix(filepath).c_str(), FILE_ATTRIBUTE_NORMAL))
+ throwFileError(replaceCpy(_("Cannot write file attributes of %x."), L"%x", fmtFileName(filepath)), L"SetFileAttributes", getLastError());
attribs = tmpAttr; //reapplied on scope exit
return true;
@@ -648,7 +647,7 @@ void setFileTimeRaw(const Zstring& filename, const FILETIME& creationTime, const
auto openFile = [&](bool conservativeApproach)
{
- return ::CreateFile(applyLongPathPrefix(filename).c_str(), //_In_ LPCTSTR lpFileName,
+ return ::CreateFile(applyLongPathPrefix(filepath).c_str(), //_In_ LPCTSTR lpFileName,
(conservativeApproach ?
//some NAS seem to have issues with FILE_WRITE_ATTRIBUTES, even worse, they may fail silently!
//http://sourceforge.net/tracker/?func=detail&atid=1093081&aid=3536680&group_id=234430
@@ -687,7 +686,7 @@ void setFileTimeRaw(const Zstring& filename, const FILETIME& creationTime, const
continue;
//3. after these herculean stunts we give up...
- throwFileError(replaceCpy(_("Cannot write modification time of %x."), L"%x", fmtFileName(filename)), L"CreateFile", lastError);
+ throwFileError(replaceCpy(_("Cannot write modification time of %x."), L"%x", fmtFileName(filepath)), L"CreateFile", lastError);
}
}
break;
@@ -719,7 +718,7 @@ void setFileTimeRaw(const Zstring& filename, const FILETIME& creationTime, const
FileBasicInfo, //__in FILE_INFO_BY_HANDLE_CLASS FileInformationClass,
&basicInfo, //__in LPVOID lpFileInformation,
sizeof(basicInfo))) //__in DWORD dwBufferSize
- throwFileError(replaceCpy(_("Cannot write file attributes of %x."), L"%x", fmtFileName(filename)), L"SetFileInformationByHandle", getLastError());
+ throwFileError(replaceCpy(_("Cannot write file attributes of %x."), L"%x", fmtFileName(filepath)), L"SetFileInformationByHandle", getLastError());
};
auto toLargeInteger = [](const FILETIME& ft) -> LARGE_INTEGER
@@ -757,11 +756,11 @@ void setFileTimeRaw(const Zstring& filename, const FILETIME& creationTime, const
}
}
- std::wstring errorMsg = replaceCpy(_("Cannot write modification time of %x."), L"%x", fmtFileName(filename));
+ std::wstring errorMsg = replaceCpy(_("Cannot write modification time of %x."), L"%x", fmtFileName(filepath));
//add more meaningful message: FAT accepts only a subset of the NTFS date range
if (lastError == ERROR_INVALID_PARAMETER &&
- dst::isFatDrive(filename))
+ dst::isFatDrive(filepath))
{
//we need a low-level reliable routine to format a potentially invalid date => don't use strftime!!!
auto fmtDate = [](const FILETIME& ft) -> Zstring
@@ -813,7 +812,7 @@ void setFileTimeRaw(const Zstring& filename, const FILETIME& creationTime, const
FILETIME creationTimeDbg = {};
FILETIME lastWriteTimeDbg = {};
- HANDLE hFile = ::CreateFile(applyLongPathPrefix(filename).c_str(), //_In_ LPCTSTR lpFileName,
+ HANDLE hFile = ::CreateFile(applyLongPathPrefix(filepath).c_str(), //_In_ LPCTSTR lpFileName,
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, //_In_ DWORD dwDesiredAccess,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, //_In_ DWORD dwShareMode,
nullptr, //_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
@@ -829,8 +828,8 @@ void setFileTimeRaw(const Zstring& filename, const FILETIME& creationTime, const
nullptr,
&lastWriteTimeDbg));
- assert(::CompareFileTime(&creationTimeDbg, &creationTime) == 0);
- assert(::CompareFileTime(&lastWriteTimeDbg, &lastWriteTime) == 0);
+ assert(std::abs(filetimeToTimeT(creationTimeDbg ) - filetimeToTimeT(creationTime )) <= 2); //respect 2 second FAT/FAT32 precision
+ assert(std::abs(filetimeToTimeT(lastWriteTimeDbg) - filetimeToTimeT(lastWriteTime)) <= 2); //
#endif
}
#endif
@@ -838,8 +837,8 @@ void setFileTimeRaw(const Zstring& filename, const FILETIME& creationTime, const
void zen::removeDirectory(const Zstring& directory, //throw FileError
- const std::function<void (const Zstring& filename)>& onBeforeFileDeletion,
- const std::function<void (const Zstring& dirname)>& onBeforeDirDeletion)
+ const std::function<void (const Zstring& filepath)>& onBeforeFileDeletion,
+ const std::function<void (const Zstring& dirpath)>& onBeforeDirDeletion)
{
//no error situation if directory is not existing! manual deletion relies on it!
if (!somethingExists(directory))
@@ -848,22 +847,25 @@ void zen::removeDirectory(const Zstring& directory, //throw FileError
}
-void zen::setFileTime(const Zstring& filename, const Int64& modTime, ProcSymlink procSl) //throw FileError
+void zen::setFileTime(const Zstring& filepath, std::int64_t modTime, ProcSymlink procSl) //throw FileError
{
#ifdef ZEN_WIN
FILETIME creationTime = {};
- FILETIME lastWriteTime = toFileTime(modTime);
+ FILETIME lastWriteTime = timetToFileTime(modTime);
//####################################### DST hack ###########################################
- if (dst::isFatDrive(filename)) //throw(); hacky: does not consider symlinks pointing to FAT!
+ warn_static("let's tentatively disable the DST hack:")
+#if 0
+ if (dst::isFatDrive(filepath)) //throw(); hacky: does not consider symlinks pointing to FAT!
{
const dst::RawTime encodedTime = dst::fatEncodeUtcTime(lastWriteTime); //throw std::runtime_error
creationTime = encodedTime.createTimeRaw;
lastWriteTime = encodedTime.writeTimeRaw;
}
+#endif
//####################################### DST hack ###########################################
- setFileTimeRaw(filename, creationTime, lastWriteTime, procSl); //throw FileError
+ setFileTimeRaw(filepath, creationTime, lastWriteTime, procSl); //throw FileError
#elif defined ZEN_LINUX || defined ZEN_MAC
//sigh, we can't use utimensat on NTFS volumes on Ubuntu: silent failure!!! what morons are programming this shit???
@@ -872,35 +874,35 @@ void zen::setFileTime(const Zstring& filename, const Int64& modTime, ProcSymlink
// newTimes[0].tv_nsec = UTIME_OMIT; //omit access time
// newTimes[1].tv_sec = to<time_t>(modTime); //modification time (seconds)
//
- // if (::utimensat(AT_FDCWD, filename.c_str(), newTimes, procSl == SYMLINK_DIRECT ? AT_SYMLINK_NOFOLLOW : 0) != 0)
- // throwFileError(replaceCpy(_("Cannot write modification time of %x."), L"%x", fmtFileName(filename)), L"utimensat", getLastError());
+ // if (::utimensat(AT_FDCWD, filepath.c_str(), newTimes, procSl == SYMLINK_DIRECT ? AT_SYMLINK_NOFOLLOW : 0) != 0)
+ // throwFileError(replaceCpy(_("Cannot write modification time of %x."), L"%x", fmtFileName(filepath)), L"utimensat", getLastError());
//=> fallback to "retarded-idiot version"! -- DarkByte
//OS X: utime() is obsoleted by utimes()! utimensat() not yet implemented
struct ::timeval newTimes[2] = {};
- newTimes[0].tv_sec = ::time(nullptr); //access time (seconds)
- newTimes[1].tv_sec = to<time_t>(modTime); //modification time (seconds)
+ newTimes[0].tv_sec = ::time(nullptr); //access time (seconds)
+ newTimes[1].tv_sec = modTime; //modification time (seconds)
const int rv = procSl == ProcSymlink::FOLLOW ?
- :: utimes(filename.c_str(), newTimes) :
- ::lutimes(filename.c_str(), newTimes);
+ :: utimes(filepath.c_str(), newTimes) :
+ ::lutimes(filepath.c_str(), newTimes);
if (rv != 0)
- throwFileError(replaceCpy(_("Cannot write modification time of %x."), L"%x", fmtFileName(filename)), L"utimes", getLastError());
+ throwFileError(replaceCpy(_("Cannot write modification time of %x."), L"%x", fmtFileName(filepath)), L"utimes", getLastError());
#endif
}
-bool zen::supportsPermissions(const Zstring& dirname) //throw FileError
+bool zen::supportsPermissions(const Zstring& dirpath) //throw FileError
{
#ifdef ZEN_WIN
const DWORD bufferSize = MAX_PATH + 1;
std::vector<wchar_t> buffer(bufferSize);
- if (!::GetVolumePathName(dirname.c_str(), //__in LPCTSTR lpszFileName,
+ if (!::GetVolumePathName(dirpath.c_str(), //__in LPCTSTR lpszFileName,
&buffer[0], //__out LPTSTR lpszVolumePathName,
bufferSize)) //__in DWORD cchBufferLength
- throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(dirname)), L"GetVolumePathName", getLastError());
+ throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(dirpath)), L"GetVolumePathName", getLastError());
DWORD fsFlags = 0;
if (!::GetVolumeInformation(&buffer[0], //__in_opt LPCTSTR lpRootPathName,
@@ -911,7 +913,7 @@ bool zen::supportsPermissions(const Zstring& dirname) //throw FileError
&fsFlags, //__out_opt LPDWORD lpFileSystemFlags,
nullptr, //__out LPTSTR lpFileSystemNameBuffer,
0)) //__in DWORD nFileSystemNameSize
- throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(dirname)), L"GetVolumeInformation", getLastError());
+ throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(dirpath)), L"GetVolumeInformation", getLastError());
return (fsFlags & FILE_PERSISTENT_ACLS) != 0;
@@ -1431,7 +1433,7 @@ void zen::copySymlink(const Zstring& sourceLink, const Zstring& targetLink, bool
if (::lstat(sourceLink.c_str(), &srcInfo) != 0)
throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(sourceLink)), L"lstat", getLastError());
- setFileTime(targetLink, Int64(srcInfo.st_mtime), ProcSymlink::DIRECT); //throw FileError
+ setFileTime(targetLink, srcInfo.st_mtime, ProcSymlink::DIRECT); //throw FileError
#endif
if (copyFilePermissions)
@@ -1545,7 +1547,7 @@ bool canCopyAsSparse(const Zstring& sourceFile, const Zstring& targetFile) //thr
//precondition: canCopyAsSparse() must return "true"!
void copyFileWindowsSparse(const Zstring& sourceFile,
const Zstring& targetFile,
- const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus,
+ const std::function<void(std::int64_t bytesDelta)>& onUpdateCopyStatus,
InSyncAttributes* newAttrib) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked
{
assert(canCopyAsSparse(sourceFile, targetFile));
@@ -1641,10 +1643,10 @@ void copyFileWindowsSparse(const Zstring& sourceFile,
//return up-to-date file attributes
if (newAttrib)
{
- newAttrib->fileSize = UInt64(fileInfoSource.nFileSizeLow, fileInfoSource.nFileSizeHigh);
- newAttrib->modificationTime = toTimeT(fileInfoSource.ftLastWriteTime); //no DST hack (yet)
- newAttrib->sourceFileId = extractFileID(fileInfoSource);
- newAttrib->targetFileId = extractFileID(fileInfoTarget);
+ newAttrib->fileSize = get64BitUInt(fileInfoSource.nFileSizeLow, fileInfoSource.nFileSizeHigh);
+ newAttrib->modificationTime = filetimeToTimeT(fileInfoSource.ftLastWriteTime); //no DST hack (yet)
+ newAttrib->sourceFileId = extractFileId(fileInfoSource);
+ newAttrib->targetFileId = extractFileId(fileInfoTarget);
}
//#################### copy NTFS compressed attribute #########################
@@ -1737,7 +1739,7 @@ void copyFileWindowsSparse(const Zstring& sourceFile,
//invoke callback method to update progress indicators
if (onUpdateCopyStatus)
- onUpdateCopyStatus(Int64(bytesRead)); //throw X!
+ onUpdateCopyStatus(bytesRead); //throw X!
if (bytesRead > 0)
someBytesWritten = true;
@@ -1747,7 +1749,7 @@ void copyFileWindowsSparse(const Zstring& sourceFile,
//DST hack not required, since both source and target volumes cannot be FAT!
//::BackupRead() silently fails reading encrypted files -> double check!
- if (!someBytesWritten && UInt64(fileInfoSource.nFileSizeLow, fileInfoSource.nFileSizeHigh) != 0U)
+ if (!someBytesWritten && get64BitUInt(fileInfoSource.nFileSizeLow, fileInfoSource.nFileSizeHigh) != 0U)
//note: there is no guaranteed ordering relation beween bytes transferred and file size! Consider ADS (>) and compressed/sparse files (<)!
throw FileError(replaceCpy(_("Cannot read file %x."), L"%x", fmtFileName(sourceFile)), L"unknown error"); //user should never see this -> this method is called only if "canCopyAsSparse()"
@@ -1804,7 +1806,7 @@ public:
//call context: copyCallbackInternal()
void reportErrorShouldCopyAsSparse() { shouldCopyAsSparse = true; }
- void reportUserException(const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus) { exceptionInUserCallback = onUpdateCopyStatus; }
+ void reportUserException(const std::function<void(std::int64_t bytesDelta)>& onUpdateCopyStatus) { exceptionInUserCallback = onUpdateCopyStatus; }
void reportError(const std::wstring& msg, const std::wstring& description) { errorMsg = std::make_pair(msg, description); }
@@ -1827,30 +1829,31 @@ public:
private:
bool shouldCopyAsSparse; //
std::pair<std::wstring, std::wstring> errorMsg; //these are exclusive!
- std::function<void(Int64 bytesDelta)> exceptionInUserCallback; // -> optional
+ std::function<void(std::int64_t bytesDelta)> exceptionInUserCallback; // -> optional
};
struct CallbackData
{
- CallbackData(const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus,
+ CallbackData(const std::function<void(std::int64_t bytesDelta)>& onUpdateCopyStatus,
const Zstring& sourceFile,
const Zstring& targetFile) :
sourceFile_(sourceFile),
targetFile_(targetFile),
onUpdateCopyStatus_(onUpdateCopyStatus),
fileInfoSrc(),
- fileInfoTrg() {}
+ fileInfoTrg(),
+ bytesReported() {}
const Zstring& sourceFile_;
const Zstring& targetFile_;
- const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus_;
+ const std::function<void(std::int64_t bytesDelta)>& onUpdateCopyStatus_;
ErrorHandling errorHandler;
BY_HANDLE_FILE_INFORMATION fileInfoSrc; //modified by CopyFileEx() at beginning
BY_HANDLE_FILE_INFORMATION fileInfoTrg; //
- Int64 bytesReported; //used internally to calculate bytes transferred delta
+ std::int64_t bytesReported; //used internally to calculate bytes transferred delta
};
@@ -1962,7 +1965,7 @@ const bool supportNonEncryptedDestination = winXpOrLater(); //encrypted destinat
void copyFileWindowsDefault(const Zstring& sourceFile,
const Zstring& targetFile,
- const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus,
+ const std::function<void(std::int64_t bytesDelta)>& onUpdateCopyStatus,
InSyncAttributes* newAttrib) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked, ErrorShouldCopyAsSparse
{
//try to get backup read and write privileges: who knows, maybe this helps solve some obscure "access denied" errors
@@ -2039,10 +2042,10 @@ void copyFileWindowsDefault(const Zstring& sourceFile,
//trying to copy > 4GB file to FAT/FAT32 volume gives obscure ERROR_INVALID_PARAMETER (FAT can indeed handle files up to 4 Gig, tested!)
if (lastError == ERROR_INVALID_PARAMETER &&
dst::isFatDrive(targetFile) &&
- getFilesize(sourceFile) >= 4U * UInt64(1024U * 1024 * 1024)) //throw FileError
+ getFilesize(sourceFile) >= 4U * std::uint64_t(1024U * 1024 * 1024)) //throw FileError
errorDescr += L"\nFAT volumes cannot store files larger than 4 gigabyte.";
- //note: ERROR_INVALID_PARAMETER can also occur when copying to a SharePoint server or MS SkyDrive and the target filename is of a restricted type.
+ //note: ERROR_INVALID_PARAMETER can also occur when copying to a SharePoint server or MS SkyDrive and the target filepath is of a restricted type.
}
catch (FileError&) {}
@@ -2051,16 +2054,18 @@ void copyFileWindowsDefault(const Zstring& sourceFile,
if (newAttrib)
{
- newAttrib->fileSize = UInt64(cbd.fileInfoSrc.nFileSizeLow, cbd.fileInfoSrc.nFileSizeHigh);
+ newAttrib->fileSize = get64BitUInt(cbd.fileInfoSrc.nFileSizeLow, cbd.fileInfoSrc.nFileSizeHigh);
//newAttrib->modificationTime = -> set further below
- newAttrib->sourceFileId = extractFileID(cbd.fileInfoSrc);
- newAttrib->targetFileId = extractFileID(cbd.fileInfoTrg);
+ newAttrib->sourceFileId = extractFileId(cbd.fileInfoSrc);
+ newAttrib->targetFileId = extractFileId(cbd.fileInfoTrg);
}
{
FILETIME creationtime = cbd.fileInfoSrc.ftCreationTime;
FILETIME lastWriteTimeRaw = cbd.fileInfoSrc.ftLastWriteTime;
//####################################### DST hack ###########################################
+ warn_static("let's tentatively disable the DST hack:")
+#if 0
if (dst::isFatDrive(sourceFile)) //throw(); hacky: does not consider symlinks pointing to FAT!
{
const dst::RawTime rawTime(creationtime, lastWriteTimeRaw);
@@ -2070,10 +2075,11 @@ void copyFileWindowsDefault(const Zstring& sourceFile,
::GetSystemTimeAsFileTime(&creationtime); //real creation time information is not available...
}
}
+#endif
//####################################### DST hack ###########################################
if (newAttrib)
- newAttrib->modificationTime = toTimeT(lastWriteTimeRaw);
+ newAttrib->modificationTime = filetimeToTimeT(lastWriteTimeRaw);
//caveat: - ::CopyFileEx() silently *ignores* failure to set modification time!!! => we always need to set it again but with proper error checking!
// - perf-loss on USB sticks with many small files of about 30%!
@@ -2081,12 +2087,15 @@ void copyFileWindowsDefault(const Zstring& sourceFile,
FILETIME lastWriteTimeOut = lastWriteTimeRaw;
//####################################### DST hack ###########################################
+ warn_static("let's tentatively disable the DST hack:")
+#if 0
if (dst::isFatDrive(targetFile)) //throw(); target cannot be a symlink in this context!
{
const dst::RawTime encodedTime = dst::fatEncodeUtcTime(lastWriteTimeRaw); //throw std::runtime_error
creationTimeOut = encodedTime.createTimeRaw;
lastWriteTimeOut = encodedTime.writeTimeRaw;
}
+#endif
//####################################### DST hack ###########################################
setFileTimeRaw(targetFile, creationTimeOut, lastWriteTimeOut, ProcSymlink::FOLLOW); //throw FileError
@@ -2098,7 +2107,7 @@ void copyFileWindowsDefault(const Zstring& sourceFile,
//another layer to support copying sparse files
inline
-void copyFileWindowsSelectRoutine(const Zstring& sourceFile, const Zstring& targetFile, const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus, InSyncAttributes* sourceAttr)
+void copyFileWindowsSelectRoutine(const Zstring& sourceFile, const Zstring& targetFile, const std::function<void(std::int64_t bytesDelta)>& onUpdateCopyStatus, InSyncAttributes* sourceAttr)
{
try
{
@@ -2115,7 +2124,7 @@ void copyFileWindowsSelectRoutine(const Zstring& sourceFile, const Zstring& targ
inline
void copyFileWindows(const Zstring& sourceFile,
const Zstring& targetFile,
- const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus,
+ const std::function<void(std::int64_t bytesDelta)>& onUpdateCopyStatus,
InSyncAttributes* sourceAttr)
{
try
@@ -2127,8 +2136,8 @@ void copyFileWindows(const Zstring& sourceFile,
//try to handle issues with already existing short 8.3 file names on Windows
if (have8dot3NameClash(targetFile))
{
- Fix8Dot3NameClash dummy(targetFile); //throw FileError; move clashing filename to the side
- copyFileWindowsSelectRoutine(sourceFile, targetFile, onUpdateCopyStatus, sourceAttr); //throw FileError; the short filename name clash is solved, this should work now
+ Fix8Dot3NameClash dummy(targetFile); //throw FileError; move clashing filepath to the side
+ copyFileWindowsSelectRoutine(sourceFile, targetFile, onUpdateCopyStatus, sourceAttr); //throw FileError; the short filepath name clash is solved, this should work now
return;
}
throw;
@@ -2139,7 +2148,7 @@ void copyFileWindows(const Zstring& sourceFile,
#elif defined ZEN_LINUX || defined ZEN_MAC
void copyFileLinuxMac(const Zstring& sourceFile,
const Zstring& targetFile,
- const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus,
+ const std::function<void(std::int64_t bytesDelta)>& onUpdateCopyStatus,
InSyncAttributes* newAttrib) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting
{
//open sourceFile for reading
@@ -2165,7 +2174,7 @@ void copyFileLinuxMac(const Zstring& sourceFile,
//invoke callback method to update progress indicators
if (onUpdateCopyStatus)
- onUpdateCopyStatus(Int64(bytesRead)); //throw X!
+ onUpdateCopyStatus(bytesRead); //throw X!
}
while (!fileIn.eof());
@@ -2178,10 +2187,10 @@ void copyFileLinuxMac(const Zstring& sourceFile,
if (newAttrib)
{
- newAttrib->fileSize = UInt64(sourceInfo.st_size);
+ newAttrib->fileSize = sourceInfo.st_size;
newAttrib->modificationTime = sourceInfo.st_mtime;
- newAttrib->sourceFileId = extractFileID(sourceInfo);
- newAttrib->targetFileId = extractFileID(targetInfo);
+ newAttrib->sourceFileId = extractFileId(sourceInfo);
+ newAttrib->targetFileId = extractFileId(targetInfo);
}
}
}
@@ -2220,7 +2229,7 @@ copyFileWindowsDefault(::CopyFileEx) copyFileWindowsSparse(::BackupRead/::Backu
inline
void copyFileSelectOs(const Zstring& sourceFile,
const Zstring& targetFile,
- const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus,
+ const std::function<void(std::int64_t bytesDelta)>& onUpdateCopyStatus,
InSyncAttributes* sourceAttr)
{
#ifdef ZEN_WIN
@@ -2238,7 +2247,7 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath
bool copyFilePermissions,
bool transactionalCopy,
const std::function<void()>& onDeleteTargetFile,
- const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus,
+ const std::function<void(std::int64_t bytesDelta)>& onUpdateCopyStatus,
InSyncAttributes* sourceAttr)
{
if (transactionalCopy)
diff --git a/zen/file_handling.h b/zen/file_handling.h
index c3ce1d83..b58f6c07 100644
--- a/zen/file_handling.h
+++ b/zen/file_handling.h
@@ -11,12 +11,11 @@
#include "zstring.h"
#include "file_error.h"
#include "file_id_def.h"
-#include "int64.h"
namespace zen
{
-bool fileExists (const Zstring& filename); //noexcept; check whether file or file-symlink exists
-bool dirExists (const Zstring& dirname ); //noexcept; check whether directory or dir-symlink exists
+bool fileExists (const Zstring& filepath); //noexcept; check whether file or file-symlink exists
+bool dirExists (const Zstring& dirpath ); //noexcept; check whether directory or dir-symlink exists
bool symlinkExists (const Zstring& linkname); //noexcept; check whether a symbolic link exists
bool somethingExists(const Zstring& objname ); //noexcept; check whether any object with this name exists
@@ -26,21 +25,21 @@ enum class ProcSymlink
FOLLOW
};
-void setFileTime(const Zstring& filename, const Int64& modificationTime, ProcSymlink procSl); //throw FileError
+void setFileTime(const Zstring& filepath, std::int64_t modificationTime, ProcSymlink procSl); //throw FileError
//symlink handling: always evaluate target
-UInt64 getFilesize(const Zstring& filename); //throw FileError
-UInt64 getFreeDiskSpace(const Zstring& path); //throw FileError
+std::uint64_t getFilesize(const Zstring& filepath); //throw FileError
+std::uint64_t getFreeDiskSpace(const Zstring& path); //throw FileError
-bool removeFile(const Zstring& filename); //throw FileError; return "false" if file is not existing
+bool removeFile(const Zstring& filepath); //throw FileError; return "false" if file is not existing
void removeDirectory(const Zstring& directory, //throw FileError
- const std::function<void (const Zstring& filename)>& onBeforeFileDeletion = nullptr, //optional;
- const std::function<void (const Zstring& dirname)>& onBeforeDirDeletion = nullptr); //one call for each *existing* object!
+ const std::function<void (const Zstring& filepath)>& onBeforeFileDeletion = nullptr, //optional;
+ const std::function<void (const Zstring& dirpath)>& onBeforeDirDeletion = nullptr); //one call for each *existing* object!
//rename file or directory: no copying!!!
void renameFile(const Zstring& oldName, const Zstring& newName); //throw FileError, ErrorDifferentVolume, ErrorTargetExisting
-bool supportsPermissions(const Zstring& dirname); //throw FileError, dereferences symlinks
+bool supportsPermissions(const Zstring& dirpath); //throw FileError, dereferences symlinks
//if parent directory not existing: create recursively:
void makeDirectory(const Zstring& directory, bool failIfExists = false); //throw FileError, ErrorTargetExisting
@@ -52,8 +51,8 @@ void makeDirectoryPlain(const Zstring& directory, const Zstring& templateDir, bo
struct InSyncAttributes
{
- UInt64 fileSize;
- Int64 modificationTime; //time_t UTC compatible
+ std::uint64_t fileSize;
+ std::int64_t modificationTime; //time_t UTC compatible
FileId sourceFileId;
FileId targetFileId;
};
@@ -64,11 +63,11 @@ void copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPathMissi
bool transactionalCopy,
//if target is existing user needs to implement deletion: copyFile() NEVER overwrites target if already existing!
//if transactionalCopy == true, full read access on source had been proven at this point, so it's safe to delete it.
- const std::function<void()>& onDeleteTargetFile, //may be nullptr; throw X!
+ const std::function<void()>& onDeleteTargetFile, //may be nullptr; may throw!
//Linux: unconditionally
//Windows: first exception is swallowed, updateCopyStatus() is then called again where it should throw again and the exception will propagate as expected
//accummulated delta != file size! consider ADS, sparse, compressed files
- const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus, //may be nullptr; throw X!
+ const std::function<void(std::int64_t bytesDelta)>& onUpdateCopyStatus, //may be nullptr; may throw!
InSyncAttributes* newAttrib = nullptr); //return current attributes at the time of copy
diff --git a/zen/file_id_def.h b/zen/file_id_def.h
index 0608aacd..daadd391 100644
--- a/zen/file_id_def.h
+++ b/zen/file_id_def.h
@@ -27,21 +27,21 @@ typedef ULONGLONG FileIndex;
typedef std::pair<DeviceId, FileIndex> FileId;
inline
-FileId extractFileID(const BY_HANDLE_FILE_INFORMATION& fileInfo)
+FileId extractFileId(const BY_HANDLE_FILE_INFORMATION& fileInfo)
{
- ULARGE_INTEGER uint = {};
- uint.HighPart = fileInfo.nFileIndexHigh;
- uint.LowPart = fileInfo.nFileIndexLow;
+ ULARGE_INTEGER fileIndex = {};
+ fileIndex.HighPart = fileInfo.nFileIndexHigh;
+ fileIndex.LowPart = fileInfo.nFileIndexLow;
- return fileInfo.dwVolumeSerialNumber != 0 && uint.QuadPart != 0 ?
- FileId(fileInfo.dwVolumeSerialNumber, uint.QuadPart) : FileId();
+ return fileInfo.dwVolumeSerialNumber != 0 && fileIndex.QuadPart != 0 ?
+ FileId(fileInfo.dwVolumeSerialNumber, fileIndex.QuadPart) : FileId();
}
inline
-FileId extractFileID(DWORD dwVolumeSerialNumber, ULARGE_INTEGER fileId)
+FileId extractFileId(DWORD volumeSerialNumber, ULONGLONG fileIndex)
{
- return dwVolumeSerialNumber != 0 && fileId.QuadPart != 0 ?
- FileId(dwVolumeSerialNumber, fileId.QuadPart) : FileId();
+ return volumeSerialNumber != 0 && fileIndex != 0 ?
+ FileId(volumeSerialNumber, fileIndex) : FileId();
}
assert_static(sizeof(FileId().first ) == sizeof(BY_HANDLE_FILE_INFORMATION().dwVolumeSerialNumber));
@@ -58,7 +58,7 @@ typedef decltype(impl::StatDummy::st_ino) FileIndex;
typedef std::pair<DeviceId, FileIndex> FileId;
inline
-FileId extractFileID(const struct ::stat& fileInfo)
+FileId extractFileId(const struct ::stat& fileInfo)
{
return fileInfo.st_dev != 0 && fileInfo.st_ino != 0 ?
FileId(fileInfo.st_dev, fileInfo.st_ino) : FileId();
diff --git a/zen/file_io.cpp b/zen/file_io.cpp
index 82b1def5..e11a1201 100644
--- a/zen/file_io.cpp
+++ b/zen/file_io.cpp
@@ -24,7 +24,7 @@ namespace
{
#ifdef ZEN_WIN
//(try to) enhance error messages by showing which processes lock the file
-Zstring getLockingProcessNames(const Zstring& filename) //throw(), empty string if none found or error occurred
+Zstring getLockingProcessNames(const Zstring& filepath) //throw(), empty string if none found or error occurred
{
if (vistaOrLater())
{
@@ -33,7 +33,7 @@ Zstring getLockingProcessNames(const Zstring& filename) //throw(), empty string
const DllFun<FunType_freeString> freeString (getDllName(), funName_freeString);
if (getLockingProcesses && freeString)
- if (const wchar_t* procList = getLockingProcesses(filename.c_str()))
+ if (const wchar_t* procList = getLockingProcesses(filepath.c_str()))
{
ZEN_ON_SCOPE_EXIT(freeString(procList));
return procList;
@@ -43,11 +43,11 @@ Zstring getLockingProcessNames(const Zstring& filename) //throw(), empty string
}
#elif defined ZEN_LINUX || defined ZEN_MAC
-//"filename" could be a named pipe which *blocks* forever during "open()"! https://sourceforge.net/p/freefilesync/bugs/221/
-void checkForUnsupportedType(const Zstring& filename) //throw FileError
+//"filepath" could be a named pipe which *blocks* forever during "open()"! https://sourceforge.net/p/freefilesync/bugs/221/
+void checkForUnsupportedType(const Zstring& filepath) //throw FileError
{
struct ::stat fileInfo = {};
- if (::stat(filename.c_str(), &fileInfo) != 0) //follows symlinks
+ if (::stat(filepath.c_str(), &fileInfo) != 0) //follows symlinks
return; //let the caller handle errors like "not existing"
if (!S_ISREG(fileInfo.st_mode) &&
@@ -64,21 +64,21 @@ void checkForUnsupportedType(const Zstring& filename) //throw FileError
const std::wstring numFmt = printNumber<std::wstring>(L"0%06o", m & S_IFMT);
return name ? numFmt + L", " + name : numFmt;
};
- throw FileError(replaceCpy(_("Type of item %x is not supported:"), L"%x", fmtFileName(filename)) + L" " + getTypeName(fileInfo.st_mode));
+ throw FileError(replaceCpy(_("Type of item %x is not supported:"), L"%x", fmtFileName(filepath)) + L" " + getTypeName(fileInfo.st_mode));
}
}
#endif
}
-FileInput::FileInput(FileHandle handle, const Zstring& filename) : FileInputBase(filename), fileHandle(handle) {}
+FileInput::FileInput(FileHandle handle, const Zstring& filepath) : FileInputBase(filepath), fileHandle(handle) {}
-FileInput::FileInput(const Zstring& filename) : FileInputBase(filename) //throw FileError
+FileInput::FileInput(const Zstring& filepath) : FileInputBase(filepath) //throw FileError
{
#ifdef ZEN_WIN
const wchar_t functionName[] = L"CreateFile";
- fileHandle = ::CreateFile(applyLongPathPrefix(filename).c_str(), //_In_ LPCTSTR lpFileName,
+ fileHandle = ::CreateFile(applyLongPathPrefix(filepath).c_str(), //_In_ LPCTSTR lpFileName,
GENERIC_READ, //_In_ DWORD dwDesiredAccess,
FILE_SHARE_READ | FILE_SHARE_DELETE, //_In_ DWORD dwShareMode,
nullptr, //_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
@@ -111,21 +111,21 @@ FileInput::FileInput(const Zstring& filename) : FileInputBase(filename) //throw
nullptr); //_In_opt_ HANDLE hTemplateFile
if (fileHandle == INVALID_HANDLE_VALUE)
#elif defined ZEN_LINUX || defined ZEN_MAC
- checkForUnsupportedType(filename); //throw FileError; reading a named pipe would block forever!
+ checkForUnsupportedType(filepath); //throw FileError; reading a named pipe would block forever!
const wchar_t functionName[] = L"fopen";
- fileHandle = ::fopen(filename.c_str(), "r,type=record,noseek"); //utilize UTF-8 filename
+ fileHandle = ::fopen(filepath.c_str(), "r,type=record,noseek"); //utilize UTF-8 filepath
if (!fileHandle)
#endif
{
const ErrorCode lastError = getLastError(); //copy before making other system calls!
- const std::wstring errorMsg = replaceCpy(_("Cannot open file %x."), L"%x", fmtFileName(filename));
+ const std::wstring errorMsg = replaceCpy(_("Cannot open file %x."), L"%x", fmtFileName(filepath));
std::wstring errorDescr = formatSystemError(functionName, lastError);
#ifdef ZEN_WIN
if (lastError == ERROR_SHARING_VIOLATION || //-> enhance error message!
lastError == ERROR_LOCK_VIOLATION)
{
- const Zstring procList = getLockingProcessNames(filename); //throw()
+ const Zstring procList = getLockingProcessNames(filepath); //throw()
if (!procList.empty())
errorDescr = _("The file is locked by another process:") + L"\n" + procList;
}
@@ -184,18 +184,18 @@ size_t FileInput::read(void* buffer, size_t bytesToRead) //returns actual number
}
-FileOutput::FileOutput(FileHandle handle, const Zstring& filename) : FileOutputBase(filename), fileHandle(handle) {}
+FileOutput::FileOutput(FileHandle handle, const Zstring& filepath) : FileOutputBase(filepath), fileHandle(handle) {}
-FileOutput::FileOutput(const Zstring& filename, AccessFlag access) : //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting
- FileOutputBase(filename)
+FileOutput::FileOutput(const Zstring& filepath, AccessFlag access) : //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting
+ FileOutputBase(filepath)
{
#ifdef ZEN_WIN
const DWORD dwCreationDisposition = access == FileOutput::ACC_OVERWRITE ? CREATE_ALWAYS : CREATE_NEW;
auto getHandle = [&](DWORD dwFlagsAndAttributes)
{
- return ::CreateFile(applyLongPathPrefix(filename).c_str(), //_In_ LPCTSTR lpFileName,
+ return ::CreateFile(applyLongPathPrefix(filepath).c_str(), //_In_ LPCTSTR lpFileName,
GENERIC_READ | GENERIC_WRITE, //_In_ DWORD dwDesiredAccess,
/* http://msdn.microsoft.com/en-us/library/aa363858(v=vs.85).aspx
quote: When an application creates a file across a network, it is better
@@ -220,7 +220,7 @@ FileOutput::FileOutput(const Zstring& filename, AccessFlag access) : //throw Fil
if (lastError == ERROR_ACCESS_DENIED &&
dwCreationDisposition == CREATE_ALWAYS)
{
- const DWORD attrib = ::GetFileAttributes(applyLongPathPrefix(filename).c_str());
+ const DWORD attrib = ::GetFileAttributes(applyLongPathPrefix(filepath).c_str());
if (attrib != INVALID_FILE_ATTRIBUTES)
{
fileHandle = getHandle(attrib); //retry: alas this may still fail for hidden file, e.g. accessing shared folder in XP as Virtual Box guest!
@@ -231,13 +231,13 @@ FileOutput::FileOutput(const Zstring& filename, AccessFlag access) : //throw Fil
//begin of "regular" error reporting
if (fileHandle == INVALID_HANDLE_VALUE)
{
- const std::wstring errorMsg = replaceCpy(_("Cannot write file %x."), L"%x", fmtFileName(filename));
+ const std::wstring errorMsg = replaceCpy(_("Cannot write file %x."), L"%x", fmtFileName(filepath));
std::wstring errorDescr = formatSystemError(L"CreateFile", lastError);
if (lastError == ERROR_SHARING_VIOLATION || //-> enhance error message!
lastError == ERROR_LOCK_VIOLATION)
{
- const Zstring procList = getLockingProcessNames(filename); //throw()
+ const Zstring procList = getLockingProcessNames(filepath); //throw()
if (!procList.empty())
errorDescr = _("The file is locked by another process:") + L"\n" + procList;
}
@@ -254,8 +254,8 @@ FileOutput::FileOutput(const Zstring& filename, AccessFlag access) : //throw Fil
}
#elif defined ZEN_LINUX || defined ZEN_MAC
- checkForUnsupportedType(filename); //throw FileError; writing a named pipe would block forever!
- fileHandle = ::fopen(filename.c_str(),
+ checkForUnsupportedType(filepath); //throw FileError; writing a named pipe would block forever!
+ fileHandle = ::fopen(filepath.c_str(),
//GNU extension: https://www.securecoding.cert.org/confluence/display/cplusplus/FIO03-CPP.+Do+not+make+assumptions+about+fopen()+and+file+creation
access == ACC_OVERWRITE ? "w,type=record,noseek" : "wx,type=record,noseek");
if (!fileHandle)
@@ -311,13 +311,13 @@ void FileOutput::write(const void* buffer, size_t bytesToWrite) //throw FileErro
#if defined ZEN_LINUX || defined ZEN_MAC
//Compare copy_reg() in copy.c: ftp://ftp.gnu.org/gnu/coreutils/coreutils-5.0.tar.gz
-FileInputUnbuffered::FileInputUnbuffered(const Zstring& filename) : FileInputBase(filename) //throw FileError
+FileInputUnbuffered::FileInputUnbuffered(const Zstring& filepath) : FileInputBase(filepath) //throw FileError
{
- checkForUnsupportedType(filename); //throw FileError; reading a named pipe would block forever!
+ checkForUnsupportedType(filepath); //throw FileError; reading a named pipe would block forever!
- fdFile = ::open(filename.c_str(), O_RDONLY);
+ fdFile = ::open(filepath.c_str(), O_RDONLY);
if (fdFile == -1) //don't check "< 0" -> docu seems to allow "-2" to be a valid file handle
- throwFileError(replaceCpy(_("Cannot open file %x."), L"%x", fmtFileName(filename)), L"open", getLastError());
+ throwFileError(replaceCpy(_("Cannot open file %x."), L"%x", fmtFileName(filepath)), L"open", getLastError());
}
@@ -348,16 +348,16 @@ size_t FileInputUnbuffered::read(void* buffer, size_t bytesToRead) //throw FileE
}
-FileOutputUnbuffered::FileOutputUnbuffered(const Zstring& filename, mode_t mode) : FileOutputBase(filename) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting
+FileOutputUnbuffered::FileOutputUnbuffered(const Zstring& filepath, mode_t mode) : FileOutputBase(filepath) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting
{
- //checkForUnsupportedType(filename); -> not needed, open() + O_EXCL shoul fail fast
+ //checkForUnsupportedType(filepath); -> not needed, open() + O_EXCL shoul fail fast
//overwrite is: O_CREAT | O_WRONLY | O_TRUNC
- fdFile = ::open(filename.c_str(), O_CREAT | O_WRONLY | O_EXCL, mode & (S_IRWXU | S_IRWXG | S_IRWXO));
+ fdFile = ::open(filepath.c_str(), O_CREAT | O_WRONLY | O_EXCL, mode & (S_IRWXU | S_IRWXG | S_IRWXO));
if (fdFile == -1)
{
const int lastError = errno; //copy before making other system calls!
- const std::wstring errorMsg = replaceCpy(_("Cannot write file %x."), L"%x", fmtFileName(filename));
+ const std::wstring errorMsg = replaceCpy(_("Cannot write file %x."), L"%x", fmtFileName(filepath));
const std::wstring errorDescr = formatSystemError(L"open", lastError);
if (lastError == EEXIST)
@@ -370,7 +370,7 @@ FileOutputUnbuffered::FileOutputUnbuffered(const Zstring& filename, mode_t mode)
}
}
-FileOutputUnbuffered::FileOutputUnbuffered(int fd, const Zstring& filename) : FileOutputBase(filename), fdFile(fd) {}
+FileOutputUnbuffered::FileOutputUnbuffered(int fd, const Zstring& filepath) : FileOutputBase(filepath), fdFile(fd) {}
FileOutputUnbuffered::~FileOutputUnbuffered() { ::close(fdFile); }
diff --git a/zen/file_io.h b/zen/file_io.h
index 2e9e828e..5ae6eb1c 100644
--- a/zen/file_io.h
+++ b/zen/file_io.h
@@ -37,11 +37,11 @@ typedef FILE* FileHandle;
class FileInput : public FileInputBase
{
public:
- FileInput(const Zstring& filename); //throw FileError
- FileInput(FileHandle handle, const Zstring& filename); //takes ownership!
+ FileInput(const Zstring& filepath); //throw FileError
+ FileInput(FileHandle handle, const Zstring& filepath); //takes ownership!
~FileInput();
- virtual size_t read(void* buffer, size_t bytesToRead); //throw FileError; returns actual number of bytes read
+ virtual size_t read(void* buffer, size_t bytesToRead) override; //throw FileError; returns actual number of bytes read
//expected to fill buffer completely unless "end of file"
private:
@@ -52,11 +52,11 @@ private:
class FileOutput : public FileOutputBase
{
public:
- FileOutput(const Zstring& filename, AccessFlag access); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting
- FileOutput(FileHandle handle, const Zstring& filename); //takes ownership!
+ FileOutput(const Zstring& filepath, AccessFlag access); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting
+ FileOutput(FileHandle handle, const Zstring& filepath); //takes ownership!
~FileOutput();
- virtual void write(const void* buffer, size_t bytesToWrite); //throw FileError
+ virtual void write(const void* buffer, size_t bytesToWrite) override; //throw FileError
private:
FileHandle fileHandle;
@@ -66,11 +66,11 @@ private:
class FileInputUnbuffered : public FileInputBase
{
public:
- FileInputUnbuffered(const Zstring& filename); //throw FileError
+ FileInputUnbuffered(const Zstring& filepath); //throw FileError
~FileInputUnbuffered();
//considering safe-read.c it seems buffer size should be a multiple of 8192
- virtual size_t read(void* buffer, size_t bytesToRead); //throw FileError; returns actual number of bytes read
+ virtual size_t read(void* buffer, size_t bytesToRead) override; //throw FileError; returns actual number of bytes read
//do NOT rely on partially filled buffer meaning EOF!
int getDescriptor() { return fdFile;}
@@ -83,11 +83,11 @@ class FileOutputUnbuffered : public FileOutputBase
{
public:
//creates a new file (no overwrite allowed!)
- FileOutputUnbuffered(const Zstring& filename, mode_t mode); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting
- FileOutputUnbuffered(int fd, const Zstring& filename); //takes ownership!
+ FileOutputUnbuffered(const Zstring& filepath, mode_t mode); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting
+ FileOutputUnbuffered(int fd, const Zstring& filepath); //takes ownership!
~FileOutputUnbuffered();
- virtual void write(const void* buffer, size_t bytesToWrite); //throw FileError
+ virtual void write(const void* buffer, size_t bytesToWrite) override; //throw FileError
int getDescriptor() { return fdFile;}
private:
diff --git a/zen/file_traverser.cpp b/zen/file_traverser.cpp
index 65d95f4a..d8f2d0cf 100644
--- a/zen/file_traverser.cpp
+++ b/zen/file_traverser.cpp
@@ -8,9 +8,10 @@
#include "sys_error.h"
#include "assert_static.h"
#include "symlink_target.h"
+#include "int64.h"
#ifdef ZEN_WIN
-#include <zen/win_ver.h>
+#include "win_ver.h"
#include "long_path_prefix.h"
#include "dst_hack.h"
#include "file_handling.h" //remove this huge dependency when getting rid of DST hack!! until then we need "setFileTime"
@@ -18,7 +19,7 @@
#include "FindFilePlus/find_file_plus.h"
#elif defined ZEN_MAC
-#include <zen/osx_string.h>
+#include "osx_string.h"
#endif
#if defined ZEN_LINUX || defined ZEN_MAC
@@ -29,7 +30,7 @@
using namespace zen;
-
+
namespace
{
//implement "retry" in a generic way:
@@ -78,7 +79,7 @@ bool tryReportingItemError(Command cmd, zen::TraverseCallback& callback, const Z
#ifdef ZEN_WIN
-void getInfoFromFileSymlink(const Zstring& linkName, zen::TraverseCallback::FileInfo& output) //throw FileError
+TraverseCallback::FileInfo getInfoFromFileSymlink(const Zstring& linkName) //throw FileError
{
//open handle to target of symbolic link
HANDLE hFile = ::CreateFile(zen::applyLongPathPrefix(linkName).c_str(), //_In_ LPCTSTR lpFileName,
@@ -104,11 +105,12 @@ void getInfoFromFileSymlink(const Zstring& linkName, zen::TraverseCallback::File
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
throw FileError(replaceCpy(_("Cannot resolve symbolic link %x."), L"%x", fmtFileName(linkName)), formatSystemError(L"GetFileInformationByHandle", static_cast<DWORD>(ERROR_FILE_INVALID)));
- //write output
- output.fileSize = UInt64(fileInfo.nFileSizeLow, fileInfo.nFileSizeHigh);
- output.lastWriteTime = toTimeT(fileInfo.ftLastWriteTime);
- output.id = extractFileID(fileInfo); //consider detection of moved files: allow for duplicate file ids, renaming affects symlink, not target, ...
+ TraverseCallback::FileInfo output;
+ output.fileSize = get64BitUInt(fileInfo.nFileSizeLow, fileInfo.nFileSizeHigh);
+ output.lastWriteTime = filetimeToTimeT(fileInfo.ftLastWriteTime);
+ output.id = extractFileId(fileInfo); //consider detection of moved files: allow for duplicate file ids, renaming affects symlink, not target, ...
//output.symlinkInfo -> not filled here
+ return output;
}
@@ -154,17 +156,17 @@ struct TraverserPolicy //see "policy based design"
typedef ... DirHandle;
typedef ... FindData;
-static void create(const Zstring& directory, DirHandle& hnd); //throw FileError - *no* concession to FindFirstFile(): open handle only, *no* return of data!
+static DirHandle create(const Zstring& directory); //throw FileError - don't follow FindFirstFile() design: open handle only, *no* return of data!
static void destroy(DirHandle hnd); //throw()
static bool getEntry(DirHandle hnd, const Zstring& directory, FindData& fileInfo) //throw FileError, NeedFallbackToWin32Traverser -> fallback to FindFirstFile()/FindNextFile()
//FindData "member" functions
-static void extractFileInfo (const FindData& fileInfo, DWORD volumeSerial, TraverseCallback::FileInfo& output); //volumeSerial may be 0 if not available!
-static Int64 getModTime (const FindData& fileInfo);
+static TraverseCallback::FileInfo extractFileInfo(const FindData& fileInfo, DWORD volumeSerial); //volumeSerial may be 0 if not available!
+static std::int64_t getModTime (const FindData& fileInfo);
static const FILETIME& getModTimeRaw (const FindData& fileInfo); //yet another concession to DST hack
static const FILETIME& getCreateTimeRaw(const FindData& fileInfo); //
-static const wchar_t* getShortName (const FindData& fileInfo);
+static const wchar_t* getItemName (const FindData& fileInfo);
static bool isDirectory (const FindData& fileInfo);
static bool isSymlink (const FindData& fileInfo);
}
@@ -177,40 +179,41 @@ struct Win32Traverser
{
struct DirHandle
{
- DirHandle() : searchHandle(nullptr), haveData(true), data() {}
+ DirHandle(HANDLE hnd, const WIN32_FIND_DATA& d) : searchHandle(hnd), haveData(true), data(d) {}
+ explicit DirHandle(HANDLE hnd) : searchHandle(hnd), haveData(false) {}
HANDLE searchHandle;
-
bool haveData;
WIN32_FIND_DATA data;
};
typedef WIN32_FIND_DATA FindData;
- static void create(const Zstring& dirname, DirHandle& hnd) //throw FileError
+ static DirHandle create(const Zstring& dirpath) //throw FileError
{
- const Zstring& dirnamePf = appendSeparator(dirname);
+ const Zstring& dirpathPf = appendSeparator(dirpath);
- hnd.searchHandle = ::FindFirstFile(applyLongPathPrefix(dirnamePf + L'*').c_str(), &hnd.data);
+ WIN32_FIND_DATA fileData = {};
+ HANDLE hnd = ::FindFirstFile(applyLongPathPrefix(dirpathPf + L'*').c_str(), &fileData);
//no noticable performance difference compared to FindFirstFileEx with FindExInfoBasic, FIND_FIRST_EX_CASE_SENSITIVE and/or FIND_FIRST_EX_LARGE_FETCH
- if (hnd.searchHandle == INVALID_HANDLE_VALUE)
+ if (hnd == INVALID_HANDLE_VALUE)
{
const DWORD lastError = ::GetLastError(); //copy before making other system calls!
- hnd.haveData = false;
if (lastError == ERROR_FILE_NOT_FOUND)
{
//1. directory may not exist *or* 2. it is completely empty: not all directories contain "., .." entries, e.g. a drive's root directory; NetDrive
// -> FindFirstFile() is a nice example of violation of API design principle of single responsibility
- if (dirExists(dirname)) //yes, a race-condition, still the best we can do
- return;
+ if (dirExists(dirpath)) //yes, a race-condition, still the best we can do
+ return DirHandle(hnd);
}
- throwFileError(replaceCpy(_("Cannot open directory %x."), L"%x", fmtFileName(dirname)), L"FindFirstFile", lastError);
+ throwFileError(replaceCpy(_("Cannot open directory %x."), L"%x", fmtFileName(dirpath)), L"FindFirstFile", lastError);
}
+ return DirHandle(hnd, fileData);
}
static void destroy(const DirHandle& hnd) { ::FindClose(hnd.searchHandle); } //throw()
- static bool getEntry(DirHandle& hnd, const Zstring& dirname, FindData& fileInfo) //throw FileError
+ static bool getEntry(DirHandle& hnd, const Zstring& dirpath, FindData& fileInfo) //throw FileError
{
if (hnd.searchHandle == INVALID_HANDLE_VALUE) //handle special case of "truly empty directories"
return false;
@@ -228,22 +231,25 @@ struct Win32Traverser
if (lastError == ERROR_NO_MORE_FILES) //not an error situation
return false;
//else we have a problem... report it:
- throwFileError(replaceCpy(_("Cannot enumerate directory %x."), L"%x", fmtFileName(dirname)), L"FindNextFile", lastError);
+ throwFileError(replaceCpy(_("Cannot enumerate directory %x."), L"%x", fmtFileName(dirpath)), L"FindNextFile", lastError);
}
return true;
}
- static void extractFileInfo(const FindData& fileInfo, DWORD volumeSerial, TraverseCallback::FileInfo& output)
+ static TraverseCallback::FileInfo extractFileInfo(const FindData& fileInfo, DWORD volumeSerial)
{
- output.fileSize = UInt64(fileInfo.nFileSizeLow, fileInfo.nFileSizeHigh);
+ TraverseCallback::FileInfo output;
+ output.fileSize = get64BitUInt(fileInfo.nFileSizeLow, fileInfo.nFileSizeHigh);
output.lastWriteTime = getModTime(fileInfo);
- output.id = FileId();
+ //output.id = FileId();
+ //output.symlinkInfo = nullptr;
+ return output;
}
- static Int64 getModTime (const FindData& fileInfo) { return toTimeT(fileInfo.ftLastWriteTime); }
+ static std::int64_t getModTime (const FindData& fileInfo) { return filetimeToTimeT(fileInfo.ftLastWriteTime); }
static const FILETIME& getModTimeRaw (const FindData& fileInfo) { return fileInfo.ftLastWriteTime; }
static const FILETIME& getCreateTimeRaw(const FindData& fileInfo) { return fileInfo.ftCreationTime; }
- static const wchar_t* getShortName (const FindData& fileInfo) { return fileInfo.cFileName; }
+ static const wchar_t* getItemName (const FindData& fileInfo) { return fileInfo.cFileName; }
static bool isDirectory (const FindData& fileInfo) { return (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
static bool isSymlink (const FindData& fileInfo) { return zen::isSymlink(fileInfo); } //[!] keep namespace
};
@@ -256,23 +262,25 @@ struct FilePlusTraverser
{
struct DirHandle
{
- DirHandle() : searchHandle(nullptr) {}
+ explicit DirHandle(findplus::FindHandle hnd) : searchHandle(hnd) {}
findplus::FindHandle searchHandle;
};
typedef findplus::FileInformation FindData;
- static void create(const Zstring& dirname, DirHandle& hnd) //throw FileError
+ static DirHandle create(const Zstring& dirpath) //throw FileError
{
- hnd.searchHandle = ::openDir(applyLongPathPrefix(dirname).c_str());
- if (hnd.searchHandle == nullptr)
- throwFileError(replaceCpy(_("Cannot open directory %x."), L"%x", fmtFileName(dirname)), L"openDir", getLastError());
+ const findplus::FindHandle hnd = ::openDir(applyLongPathPrefix(dirpath).c_str());
+ if (!hnd)
+ throwFileError(replaceCpy(_("Cannot open directory %x."), L"%x", fmtFileName(dirpath)), L"openDir", getLastError());
+
+ return DirHandle(hnd);
}
static void destroy(DirHandle hnd) { ::closeDir(hnd.searchHandle); } //throw()
- static bool getEntry(DirHandle hnd, const Zstring& dirname, FindData& fileInfo) //throw FileError, NeedFallbackToWin32Traverser
+ static bool getEntry(DirHandle hnd, const Zstring& dirpath, FindData& fileInfo) //throw FileError, NeedFallbackToWin32Traverser
{
if (!::readDir(hnd.searchHandle, fileInfo))
{
@@ -289,23 +297,26 @@ struct FilePlusTraverser
//fallback should apply to whole directory sub-tree! => client needs to handle duplicate file notifications!
//else we have a problem... report it:
- throwFileError(replaceCpy(_("Cannot enumerate directory %x."), L"%x", fmtFileName(dirname)), L"readDir", lastError);
+ throwFileError(replaceCpy(_("Cannot enumerate directory %x."), L"%x", fmtFileName(dirpath)), L"readDir", lastError);
}
return true;
}
- static void extractFileInfo(const FindData& fileInfo, DWORD volumeSerial, TraverseCallback::FileInfo& output)
+ static TraverseCallback::FileInfo extractFileInfo(const FindData& fileInfo, DWORD volumeSerial)
{
- output.fileSize = fileInfo.fileSize.QuadPart;
+ TraverseCallback::FileInfo output;
+ output.fileSize = fileInfo.fileSize;
output.lastWriteTime = getModTime(fileInfo);
- output.id = extractFileID(volumeSerial, fileInfo.fileId);
+ output.id = extractFileId(volumeSerial, fileInfo.fileId);
+ //output.symlinkInfo = nullptr;
+ return output;
}
- static Int64 getModTime (const FindData& fileInfo) { return toTimeT(fileInfo.lastWriteTime); }
+ static std::int64_t getModTime (const FindData& fileInfo) { return filetimeToTimeT(fileInfo.lastWriteTime); }
static const FILETIME& getModTimeRaw (const FindData& fileInfo) { return fileInfo.lastWriteTime; }
static const FILETIME& getCreateTimeRaw(const FindData& fileInfo) { return fileInfo.creationTime; }
- static const wchar_t* getShortName (const FindData& fileInfo) { return fileInfo.shortName; }
+ static const wchar_t* getItemName (const FindData& fileInfo) { return fileInfo.shortName; }
static bool isDirectory (const FindData& fileInfo) { return (fileInfo.fileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
static bool isSymlink (const FindData& fileInfo) { return zen::isSymlink(fileInfo.fileAttributes, fileInfo.reparseTag); } //[!] keep namespace
};
@@ -320,139 +331,15 @@ public:
}
private:
- DirTraverser(const Zstring& baseDirectory, TraverseCallback& sink, DstHackCallback* dstCallback) :
- needDstHack(dstCallback ? dst::isFatDrive(baseDirectory) : false)
- {
- try //traversing certain folders with restricted permissions requires this privilege! (but copying these files may still fail)
- {
- activatePrivilege(SE_BACKUP_NAME); //throw FileError
- }
- catch (FileError&) {} //don't cause issues in user mode
-
- if (::openDir && ::readDir && ::closeDir)
- {
- try
- {
- traverse<FilePlusTraverser>(baseDirectory, sink, retrieveVolumeSerial(baseDirectory)); //throw NeedFallbackToWin32Traverser; retrieveVolumeSerial returns 0 on error
- }
- catch (NeedFallbackToWin32Traverser&) { traverse<Win32Traverser>(baseDirectory, sink, 0); }
- }
- else //fallback
- traverse<Win32Traverser>(baseDirectory, sink, 0);
-
- //apply daylight saving time hack AFTER file traversing, to give separate feedback to user
- if (needDstHack)
- if (dstCallback) //bound if "needDstHack == true"
- applyDstHack(*dstCallback);
- }
-
- DirTraverser(const DirTraverser&);
- DirTraverser& operator=(const DirTraverser&);
+ DirTraverser(const Zstring& baseDirectory, TraverseCallback& sink, DstHackCallback* dstCallback);
+ DirTraverser (const DirTraverser&) = delete;
+ DirTraverser& operator=(const DirTraverser&) = delete;
template <class Trav>
- void traverse(const Zstring& dirname, zen::TraverseCallback& sink, DWORD volumeSerial /*may be 0!*/) //throw NeedFallbackToWin32Traverser
- {
- //no need to check for endless recursion: Windows seems to have an internal path limit of about 700 chars
-
- typename Trav::DirHandle searchHandle;
-
- if (!tryReportingDirError([&] { Trav::create(dirname, searchHandle); /*throw FileError*/ }, sink))
- return; //ignored error
- ZEN_ON_SCOPE_EXIT(Trav::destroy(searchHandle));
-
- typename Trav::FindData findData = {};
-
- for (;;)
- {
- bool gotEntry = false;
- tryReportingDirError([&]
- {
- gotEntry = Trav::getEntry(searchHandle, dirname, findData); //throw FileError, NeedFallbackToWin32Traverser
- }, sink);
- if (!gotEntry) //no more items or ignored error
- return;
-
- //skip "." and ".."
- const Zchar* const shortName = Trav::getShortName(findData);
- if (shortName[0] == L'.' &&
- (shortName[1] == 0 || (shortName[1] == L'.' && shortName[2] == 0)))
- continue;
-
- const Zstring& fullName = appendSeparator(dirname) + shortName;
-
- if (Trav::isSymlink(findData)) //check first!
- {
- TraverseCallback::SymlinkInfo linkInfo;
- linkInfo.lastWriteTime = Trav::getModTime (findData);
-
- switch (sink.onSymlink(shortName, fullName, linkInfo))
- {
- case TraverseCallback::LINK_FOLLOW:
- if (Trav::isDirectory(findData))
- {
- if (TraverseCallback* trav = sink.onDir(shortName, fullName))
- {
- ZEN_ON_SCOPE_EXIT(sink.releaseDirTraverser(trav));
- try
- {
- traverse<Trav>(fullName, *trav, retrieveVolumeSerial(fullName)); //throw NeedFallbackToWin32Traverser; symlink may link to different volume => redetermine volume serial!
- }
- catch (NeedFallbackToWin32Traverser&) { traverse<Win32Traverser>(fullName, *trav, 0); }
- }
- }
- else //a file
- {
- TraverseCallback::FileInfo targetInfo;
- const bool validLink = tryReportingItemError([&] //try to resolve symlink (and report error on failure!!!)
- {
- getInfoFromFileSymlink(fullName, targetInfo); //throw FileError
- targetInfo.symlinkInfo = &linkInfo;
- }, sink, shortName);
-
- if (validLink)
- sink.onFile(shortName, fullName, targetInfo);
- // else //broken symlink -> ignore: it's client's responsibility to handle error!
- }
- break;
-
- case TraverseCallback::LINK_SKIP:
- break;
- }
- }
- else if (Trav::isDirectory(findData))
- {
- if (TraverseCallback* trav = sink.onDir(shortName, fullName))
- {
- ZEN_ON_SCOPE_EXIT(sink.releaseDirTraverser(trav));
- try
- {
- traverse<Trav>(fullName, *trav, volumeSerial); //throw NeedFallbackToWin32Traverser
- }
- catch (NeedFallbackToWin32Traverser&) { traverse<Win32Traverser>(fullName, *trav, 0); }
- }
- }
- else //a file
- {
- TraverseCallback::FileInfo fileInfo;
- Trav::extractFileInfo(findData, volumeSerial, fileInfo);
-
- //####################################### DST hack ###########################################
- if (needDstHack)
- {
- const dst::RawTime rawTime(Trav::getCreateTimeRaw(findData), Trav::getModTimeRaw(findData));
-
- if (dst::fatHasUtcEncoded(rawTime)) //throw std::runtime_error
- fileInfo.lastWriteTime = toTimeT(dst::fatDecodeUtcTime(rawTime)); //return real UTC time; throw std::runtime_error
- else
- markForDstHack.push_back(std::make_pair(fullName, toTimeT(rawTime.writeTimeRaw)));
- }
- //####################################### DST hack ###########################################
-
- sink.onFile(shortName, fullName, fileInfo);
- }
- }
- }
+ void traverse(const Zstring& dirpath, TraverseCallback& sink, DWORD volumeSerial);
+ template <class Trav>
+ void traverseWithException(const Zstring& dirpath, TraverseCallback& sink, DWORD volumeSerial /*may be 0!*/); //throw FileError, NeedFallbackToWin32Traverser
//####################################### DST hack ###########################################
void applyDstHack(zen::DstHackCallback& dstCallback)
@@ -482,7 +369,7 @@ private:
//even at this point it's not sure whether data was written correctly, again cloud storages tend to lie about success status
if (filesToValidate-- > 0)
{
- const dst::RawTime encodedTime = dst::fatEncodeUtcTime(toFileTime(it->second)); //throw std::runtime_error
+ const dst::RawTime encodedTime = dst::fatEncodeUtcTime(timetToFileTime(it->second)); //throw std::runtime_error
//dst hack: verify data written; attention: this check may fail for "sync.ffs_lock"
WIN32_FILE_ATTRIBUTE_DATA debugeAttr = {};
@@ -502,11 +389,144 @@ private:
}
const bool needDstHack;
- typedef std::vector<std::pair<Zstring, Int64>> FilenameTimeList;
+ typedef std::vector<std::pair<Zstring, std::int64_t>> FilenameTimeList;
FilenameTimeList markForDstHack;
//####################################### DST hack ###########################################
};
+
+template <> inline
+void DirTraverser::traverse<Win32Traverser>(const Zstring& dirpath, TraverseCallback& sink, DWORD volumeSerial)
+{
+ tryReportingDirError([&]
+ {
+ traverseWithException<Win32Traverser>(dirpath, sink, 0); //throw FileError
+ }, sink);
+}
+
+
+template <> inline
+void DirTraverser::traverse<FilePlusTraverser>(const Zstring& dirpath, TraverseCallback& sink, DWORD volumeSerial)
+{
+ try
+ {
+ tryReportingDirError([&]
+ {
+ traverseWithException<FilePlusTraverser>(dirpath, sink, volumeSerial); //throw FileError, NeedFallbackToWin32Traverser
+ }, sink);
+ }
+ catch (NeedFallbackToWin32Traverser&) { traverse<Win32Traverser>(dirpath, sink, 0); }
+}
+
+
+inline
+DirTraverser::DirTraverser(const Zstring& baseDirectory, TraverseCallback& sink, DstHackCallback* dstCallback) :
+ needDstHack(dstCallback ? dst::isFatDrive(baseDirectory) : false)
+{
+ try //traversing certain folders with restricted permissions requires this privilege! (but copying these files may still fail)
+ {
+ activatePrivilege(SE_BACKUP_NAME); //throw FileError
+ }
+ catch (FileError&) {} //don't cause issues in user mode
+
+ if (::openDir && ::readDir && ::closeDir)
+ traverse<FilePlusTraverser>(baseDirectory, sink, retrieveVolumeSerial(baseDirectory)); //retrieveVolumeSerial returns 0 on error
+ else //fallback
+ traverse<Win32Traverser>(baseDirectory, sink, 0);
+
+ //apply daylight saving time hack AFTER file traversing, to give separate feedback to user
+ if (needDstHack)
+ if (dstCallback) //bound if "needDstHack == true"
+ applyDstHack(*dstCallback);
+}
+
+
+template <class Trav>
+void DirTraverser::traverseWithException(const Zstring& dirpath, TraverseCallback& sink, DWORD volumeSerial /*may be 0!*/) //throw FileError, NeedFallbackToWin32Traverser
+{
+ //no need to check for endless recursion: Windows seems to have an internal path limit of about 700 chars
+
+ typename Trav::DirHandle searchHandle = Trav::create(dirpath); //throw FileError
+ ZEN_ON_SCOPE_EXIT(Trav::destroy(searchHandle));
+
+ typename Trav::FindData findData = {};
+
+ while (Trav::getEntry(searchHandle, dirpath, findData)) //throw FileError, NeedFallbackToWin32Traverser
+ //don't retry but restart dir traversal on error! http://blogs.msdn.com/b/oldnewthing/archive/2014/06/12/10533529.aspx
+ {
+ //skip "." and ".."
+ const Zchar* const shortName = Trav::getItemName(findData);
+ if (shortName[0] == L'.' &&
+ (shortName[1] == 0 || (shortName[1] == L'.' && shortName[2] == 0)))
+ continue;
+
+ const Zstring& itempath = appendSeparator(dirpath) + shortName;
+
+ if (Trav::isSymlink(findData)) //check first!
+ {
+ TraverseCallback::SymlinkInfo linkInfo;
+ linkInfo.lastWriteTime = Trav::getModTime (findData);
+
+ switch (sink.onSymlink(shortName, itempath, linkInfo))
+ {
+ case TraverseCallback::LINK_FOLLOW:
+ if (Trav::isDirectory(findData))
+ {
+ if (TraverseCallback* trav = sink.onDir(shortName, itempath))
+ {
+ ZEN_ON_SCOPE_EXIT(sink.releaseDirTraverser(trav));
+ traverse<Trav>(itempath, *trav, retrieveVolumeSerial(itempath)); //symlink may link to different volume => redetermine volume serial!
+ }
+ }
+ else //a file
+ {
+ TraverseCallback::FileInfo targetInfo;
+ const bool validLink = tryReportingItemError([&] //try to resolve symlink (and report error on failure!!!)
+ {
+ targetInfo = getInfoFromFileSymlink(itempath); //throw FileError
+ targetInfo.symlinkInfo = &linkInfo;
+ }, sink, shortName);
+
+ if (validLink)
+ sink.onFile(shortName, itempath, targetInfo);
+ // else //broken symlink -> ignore: it's client's responsibility to handle error!
+ }
+ break;
+
+ case TraverseCallback::LINK_SKIP:
+ break;
+ }
+ }
+ else if (Trav::isDirectory(findData))
+ {
+ if (TraverseCallback* trav = sink.onDir(shortName, itempath))
+ {
+ ZEN_ON_SCOPE_EXIT(sink.releaseDirTraverser(trav));
+ traverse<Trav>(itempath, *trav, volumeSerial);
+ }
+ }
+ else //a file
+ {
+ TraverseCallback::FileInfo fileInfo = Trav::extractFileInfo(findData, volumeSerial);
+
+ //####################################### DST hack ###########################################
+ if (needDstHack)
+ {
+ const dst::RawTime rawTime(Trav::getCreateTimeRaw(findData), Trav::getModTimeRaw(findData));
+
+ if (dst::fatHasUtcEncoded(rawTime)) //throw std::runtime_error
+ fileInfo.lastWriteTime = filetimeToTimeT(dst::fatDecodeUtcTime(rawTime)); //return real UTC time; throw std::runtime_error
+ else
+ markForDstHack.push_back(std::make_pair(itempath, filetimeToTimeT(rawTime.writeTimeRaw)));
+ }
+ //####################################### DST hack ###########################################
+
+ sink.onFile(shortName, itempath, fileInfo);
+ }
+ }
+}
+
+
#elif defined ZEN_LINUX || defined ZEN_MAC
class DirTraverser
{
@@ -535,32 +555,34 @@ private:
traverse(directoryFormatted, sink);
}
- DirTraverser(const DirTraverser&);
- DirTraverser& operator=(const DirTraverser&);
+ DirTraverser (const DirTraverser&) = delete;
+ DirTraverser& operator=(const DirTraverser&) = delete;
- void traverse(const Zstring& dirname, zen::TraverseCallback& sink)
+ void traverse(const Zstring& dirpath, TraverseCallback& sink)
{
- //no need to check for endless recursion: Linux has a fixed limit on the number of symbolic links in a path
+ tryReportingDirError([&]
+ {
+ traverseWithException(dirpath, sink); //throw FileError
+ }, sink);
+ }
- DIR* dirObj = nullptr;
- if (!tryReportingDirError([&]
+ void traverseWithException(const Zstring& dirpath, TraverseCallback& sink) //throw FileError
{
- dirObj = ::opendir(dirname.c_str()); //directory must NOT end with path separator, except "/"
- if (!dirObj)
- throwFileError(replaceCpy(_("Cannot open directory %x."), L"%x", fmtFileName(dirname)), L"opendir", getLastError());
- }, sink))
- return; //ignored error
+ //no need to check for endless recursion: Linux has a fixed limit on the number of symbolic links in a path
+
+ DIR* dirObj = ::opendir(dirpath.c_str()); //directory must NOT end with path separator, except "/"
+ if (!dirObj)
+ throwFileError(replaceCpy(_("Cannot open directory %x."), L"%x", fmtFileName(dirpath)), L"opendir", getLastError());
ZEN_ON_SCOPE_EXIT(::closedir(dirObj)); //never close nullptr handles! -> crash
for (;;)
{
struct ::dirent* dirEntry = nullptr;
- tryReportingDirError([&]
- {
- if (::readdir_r(dirObj, reinterpret_cast< ::dirent*>(&buffer[0]), &dirEntry) != 0)
- throwFileError(replaceCpy(_("Cannot enumerate directory %x."), L"%x", fmtFileName(dirname)), L"readdir_r", getLastError());
- }, sink);
- if (!dirEntry) //no more items or ignored error
+ if (::readdir_r(dirObj, reinterpret_cast< ::dirent*>(&buffer[0]), &dirEntry) != 0)
+ throwFileError(replaceCpy(_("Cannot enumerate directory %x."), L"%x", fmtFileName(dirpath)), L"readdir_r", getLastError());
+ //don't retry but restart dir traversal on error! http://blogs.msdn.com/b/oldnewthing/archive/2014/06/12/10533529.aspx
+
+ if (!dirEntry) //no more items
return;
//don't return "." and ".."
@@ -588,13 +610,13 @@ private:
//const char* sampleDecomposed = "\x6f\xcc\x81.txt";
//const char* samplePrecomposed = "\xc3\xb3.txt";
#endif
- const Zstring& fullName = appendSeparator(dirname) + shortName;
+ const Zstring& itempath = appendSeparator(dirpath) + shortName;
struct ::stat statData = {};
if (!tryReportingItemError([&]
{
- if (::lstat(fullName.c_str(), &statData) != 0) //lstat() does not resolve symlinks
- throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(fullName)), L"lstat", getLastError());
+ if (::lstat(itempath.c_str(), &statData) != 0) //lstat() does not resolve symlinks
+ throwFileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(itempath)), L"lstat", getLastError());
}, sink, shortName))
continue; //ignore error: skip file
@@ -603,7 +625,7 @@ private:
TraverseCallback::SymlinkInfo linkInfo;
linkInfo.lastWriteTime = statData.st_mtime; //UTC time (ANSI C format); unit: 1 second
- switch (sink.onSymlink(shortName, fullName, linkInfo))
+ switch (sink.onSymlink(shortName, itempath, linkInfo))
{
case TraverseCallback::LINK_FOLLOW:
{
@@ -611,28 +633,28 @@ private:
struct ::stat statDataTrg = {};
bool validLink = tryReportingItemError([&]
{
- if (::stat(fullName.c_str(), &statDataTrg) != 0)
- throwFileError(replaceCpy(_("Cannot resolve symbolic link %x."), L"%x", fmtFileName(fullName)), L"stat", getLastError());
+ if (::stat(itempath.c_str(), &statDataTrg) != 0)
+ throwFileError(replaceCpy(_("Cannot resolve symbolic link %x."), L"%x", fmtFileName(itempath)), L"stat", getLastError());
}, sink, shortName);
if (validLink)
{
if (S_ISDIR(statDataTrg.st_mode)) //a directory
{
- if (TraverseCallback* trav = sink.onDir(shortName, fullName))
+ if (TraverseCallback* trav = sink.onDir(shortName, itempath))
{
ZEN_ON_SCOPE_EXIT(sink.releaseDirTraverser(trav));
- traverse(fullName, *trav);
+ traverse(itempath, *trav);
}
}
else //a file or named pipe, ect.
{
TraverseCallback::FileInfo fileInfo;
- fileInfo.fileSize = zen::UInt64(statDataTrg.st_size);
+ fileInfo.fileSize = statDataTrg.st_size;
fileInfo.lastWriteTime = statDataTrg.st_mtime; //UTC time (time_t format); unit: 1 second
- fileInfo.id = extractFileID(statDataTrg);
+ fileInfo.id = extractFileId(statDataTrg);
fileInfo.symlinkInfo = &linkInfo;
- sink.onFile(shortName, fullName, fileInfo);
+ sink.onFile(shortName, itempath, fileInfo);
}
}
// else //broken symlink -> ignore: it's client's responsibility to handle error!
@@ -645,20 +667,20 @@ private:
}
else if (S_ISDIR(statData.st_mode)) //a directory
{
- if (TraverseCallback* trav = sink.onDir(shortName, fullName))
+ if (TraverseCallback* trav = sink.onDir(shortName, itempath))
{
ZEN_ON_SCOPE_EXIT(sink.releaseDirTraverser(trav));
- traverse(fullName, *trav);
+ traverse(itempath, *trav);
}
}
else //a file or named pipe, ect.
{
TraverseCallback::FileInfo fileInfo;
- fileInfo.fileSize = zen::UInt64(statData.st_size);
+ fileInfo.fileSize = statData.st_size;
fileInfo.lastWriteTime = statData.st_mtime; //UTC time (time_t format); unit: 1 second
- fileInfo.id = extractFileID(statData);
+ fileInfo.id = extractFileId(statData);
- sink.onFile(shortName, fullName, fileInfo);
+ sink.onFile(shortName, itempath, fileInfo);
}
/*
It may be a good idea to not check "S_ISREG(statData.st_mode)" explicitly and to not issue an error message on other types to support these scenarios:
@@ -679,7 +701,12 @@ private:
}
-void zen::traverseFolder(const Zstring& dirname, TraverseCallback& sink, DstHackCallback* dstCallback)
+void zen::traverseFolder(const Zstring& dirpath, TraverseCallback& sink, DstHackCallback* dstCallback)
{
- DirTraverser::execute(dirname, sink, dstCallback);
+ warn_static("let's tentatively disable the DST hack:")
+ DirTraverser::execute(dirpath, sink, nullptr);
+ return;
+#if 0
+ DirTraverser::execute(dirpath, sink, dstCallback);
+#endif
}
diff --git a/zen/file_traverser.h b/zen/file_traverser.h
index db93a688..f240d8c7 100644
--- a/zen/file_traverser.h
+++ b/zen/file_traverser.h
@@ -7,8 +7,8 @@
#ifndef FILETRAVERSER_H_INCLUDED
#define FILETRAVERSER_H_INCLUDED
+#include <cstdint>
#include "zstring.h"
-#include "int64.h"
#include "file_id_def.h"
//advanced file traverser returning metadata and hierarchical information on files and directories
@@ -21,14 +21,17 @@ struct TraverseCallback
struct SymlinkInfo
{
- Int64 lastWriteTime; //number of seconds since Jan. 1st 1970 UTC
+ SymlinkInfo() : lastWriteTime() {}
+
+ std::int64_t lastWriteTime; //number of seconds since Jan. 1st 1970 UTC
};
struct FileInfo
{
- FileInfo() : symlinkInfo() {}
- UInt64 fileSize; //unit: bytes!
- Int64 lastWriteTime; //number of seconds since Jan. 1st 1970 UTC
+ FileInfo() : fileSize(), lastWriteTime(), symlinkInfo() {}
+
+ std::uint64_t fileSize; //unit: bytes!
+ std::int64_t lastWriteTime; //number of seconds since Jan. 1st 1970 UTC
FileId id; //optional: initial if not supported!
const SymlinkInfo* symlinkInfo; //only filled if file is a followed symlink
};
@@ -45,13 +48,13 @@ struct TraverseCallback
ON_ERROR_IGNORE
};
- virtual void onFile (const Zchar* shortName, const Zstring& fullName, const FileInfo& details) = 0;
- virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) = 0;
- virtual TraverseCallback* onDir (const Zchar* shortName, const Zstring& fullName) = 0;
+ virtual void onFile (const Zchar* shortName, const Zstring& filepath, const FileInfo& details) = 0;
+ virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& linkpath, const SymlinkInfo& details) = 0;
+ virtual TraverseCallback* onDir (const Zchar* shortName, const Zstring& dirpath) = 0;
//nullptr: ignore directory, non-nullptr: traverse into using the (new) callback => implement releaseDirTraverser() if necessary!
virtual void releaseDirTraverser(TraverseCallback* trav) {}
- virtual HandleError reportDirError (const std::wstring& msg, size_t retryNumber) = 0; //failed directory traversal -> consider directory data as incomplete!
+ virtual HandleError reportDirError (const std::wstring& msg, size_t retryNumber) = 0; //failed directory traversal -> consider directory data at current level as incomplete!
virtual HandleError reportItemError(const std::wstring& msg, size_t retryNumber, const Zchar* shortName) = 0; //failed to get data for single file/dir/symlink only!
};
@@ -60,7 +63,7 @@ struct TraverseCallback
struct DstHackCallback
{
virtual ~DstHackCallback() {}
- virtual void requestUiRefresh(const Zstring& filename) = 0; //applying DST hack imposes significant one-time performance drawback => callback to inform user
+ virtual void requestUiRefresh(const Zstring& filepath) = 0; //applying DST hack imposes significant one-time performance drawback => callback to inform user
};
#elif defined ZEN_LINUX || defined ZEN_MAC
struct DstHackCallback; //DST hack not required on Unix
@@ -69,7 +72,7 @@ struct DstHackCallback; //DST hack not required on Unix
//custom traverser with detail information about files
//- client needs to handle duplicate file reports! (FilePlusTraverser fallback, retrying to read directory contents, ...)
//- directory may end with PATH_SEPARATOR
-void traverseFolder(const Zstring& dirname, //throw()
+void traverseFolder(const Zstring& dirpath, //throw()
TraverseCallback& sink,
DstHackCallback* dstCallback = nullptr); //apply DST hack if callback is supplied
}
diff --git a/zen/fixed_list.h b/zen/fixed_list.h
index 7e35f012..63ef3f2f 100644
--- a/zen/fixed_list.h
+++ b/zen/fixed_list.h
@@ -129,8 +129,8 @@ public:
size_t size() const { return sz; }
private:
- FixedList(const FixedList&);
- FixedList& operator=(const FixedList&);
+ FixedList (const FixedList&) = delete;
+ FixedList& operator=(const FixedList&) = delete;
void pushNode(Node* newNode) //throw()
{
diff --git a/zen/format_unit.cpp b/zen/format_unit.cpp
index bcf318d9..e251dc3c 100644
--- a/zen/format_unit.cpp
+++ b/zen/format_unit.cpp
@@ -5,20 +5,21 @@
// **************************************************************************
#include "format_unit.h"
-#include <zen/basic_math.h>
-#include <zen/i18n.h>
-#include <zen/time.h>
+#include "basic_math.h"
+#include "i18n.h"
+#include "time.h"
+#include "int64.h"
#include <cwchar> //swprintf
#include <ctime>
#include <cstdio>
#ifdef ZEN_WIN
-#include <zen/win.h> //includes "windows.h"
-#include <zen/win_ver.h>
+#include "win.h" //includes "windows.h"
+#include "win_ver.h"
#elif defined ZEN_LINUX || defined ZEN_MAC
-#include <clocale> //thousands separator
-#include <zen/utf.h> //
+#include <clocale> //thousands separator
+#include "utf.h" //
#endif
using namespace zen;
@@ -35,14 +36,15 @@ std::wstring zen::formatThreeDigitPrecision(double value)
}
-std::wstring zen::filesizeToShortString(Int64 size)
+std::wstring zen::filesizeToShortString(std::int64_t size)
{
//if (size < 0) return _("Error"); -> really?
if (numeric::abs(size) <= 999)
- return _P("1 byte", "%x bytes", to<int>(size));
+ return _P("1 byte", "%x bytes", static_cast<int>(size));
+
+ double sizeInUnit = static_cast<double>(size);
- double sizeInUnit = to<double>(size);
auto formatUnit = [&](const std::wstring& unitTxt) { return replaceCpy(unitTxt, L"%x", formatThreeDigitPrecision(sizeInUnit)); };
sizeInUnit /= 1024;
@@ -282,12 +284,12 @@ const bool useNewLocalTimeCalculation = zen::vistaOrLater();
#endif
-std::wstring zen::utcToLocalTimeString(Int64 utcTime)
+std::wstring zen::utcToLocalTimeString(std::int64_t utcTime)
{
auto errorMsg = [&] { return _("Error") + L" (time_t: " + numberTo<std::wstring>(utcTime) + L")"; };
#ifdef ZEN_WIN
- FILETIME lastWriteTimeUtc = toFileTime(utcTime); //convert ansi C time to FILETIME
+ FILETIME lastWriteTimeUtc = timetToFileTime(utcTime); //convert ansi C time to FILETIME
SYSTEMTIME systemTimeLocal = {};
@@ -325,7 +327,7 @@ std::wstring zen::utcToLocalTimeString(Int64 utcTime)
loc.second = systemTimeLocal.wSecond;
#elif defined ZEN_LINUX || defined ZEN_MAC
- zen::TimeComp loc = zen::localTime(to<time_t>(utcTime));
+ zen::TimeComp loc = zen::localTime(utcTime);
#endif
std::wstring dateString = formatTime<std::wstring>(L"%x %X", loc);
diff --git a/zen/format_unit.h b/zen/format_unit.h
index e3e2d107..237b9f04 100644
--- a/zen/format_unit.h
+++ b/zen/format_unit.h
@@ -8,15 +8,15 @@
#define FMT_UNIT_8702184019487324
#include <string>
-#include <zen/int64.h>
-#include <zen/string_tools.h>
+#include <cstdint>
+#include "string_tools.h"
namespace zen
{
-std::wstring filesizeToShortString(Int64 filesize);
+std::wstring filesizeToShortString(std::int64_t filesize);
std::wstring remainingTimeToString(double timeInSec);
std::wstring fractionToString(double fraction); //within [0, 1]
-std::wstring utcToLocalTimeString(Int64 utcTime); //like Windows Explorer would...
+std::wstring utcToLocalTimeString(std::int64_t utcTime); //like Windows Explorer would...
std::wstring formatThreeDigitPrecision(double value); //= *at least* three digits
@@ -44,7 +44,7 @@ std::wstring includeNumberSeparator(const std::wstring& number);
template <class NumberType> inline
std::wstring toGuiString(NumberType number)
{
- //assert_static(IsInteger<NumberType>::value); -> doesn't work for UInt64
+ assert_static(IsInteger<NumberType>::value);
return ffs_Impl::includeNumberSeparator(zen::numberTo<std::wstring>(number));
}
}
diff --git a/zen/int64.h b/zen/int64.h
index f658e034..4183c8da 100644
--- a/zen/int64.h
+++ b/zen/int64.h
@@ -7,251 +7,65 @@
#ifndef FFS_LARGE_64_BIT_INTEGER_H_INCLUDED
#define FFS_LARGE_64_BIT_INTEGER_H_INCLUDED
-#include <cassert>
-#include <limits>
#include <cstdint>
-#include <cstdint>
-#include <ostream>
-#include "assert_static.h"
-#include "type_tools.h"
#ifdef ZEN_WIN
#include "win.h"
#endif
-/*
-zen::Int64/zen::UInt64: wrapper classes around std::int64_t/std::uint64_t
-
- - default initialization with 0
- - debug runtime overflow/underflow checks
- - safe and explicit semantics: no unsafe type conversions
- - safe conversion to and from Windows 64-bit integers
- - specializes std::numeric_limits
- - support stream operator<< and operator>>
-*/
-
namespace zen
{
-template <class T, class U> inline
-void checkRange(U value)
-{
- //caveat: std::numeric_limits<T>::min returns minimum positive(!) number for T = double, while behaving correctly for integer types... sigh
- assert(double(std::numeric_limits<T>::lowest()) <= double(value) && //new with C++11!
- double(std::numeric_limits<T>::max() ) >= double(value));
-}
-
-class Int64
-{
-public:
- //safe implicit conversions
- Int64() : value(0) {}
- Int64(const Int64& rhs) : value(rhs.value) {}
- template <class T>
- Int64(T rhs, typename EnableIf<IsSignedInt<T>::value&& sizeof(T) <= sizeof(std::int64_t)>::Type* = nullptr) :
- value(static_cast<std::int64_t>(rhs)) {}
-
- //unsafe explicit but checked conversion for all other integer types
- template <class T> explicit Int64(T rhs, typename EnableIf<!(IsSignedInt<T>::value&& sizeof(T) <= sizeof(std::int64_t))>::Type* = nullptr) :
- value(static_cast<std::int64_t>(rhs)) { checkRange<std::int64_t>(rhs); }
-
- Int64& operator=(const Int64& rhs) { value = rhs.value; return *this; }
-
#ifdef ZEN_WIN
- Int64(DWORD low, LONG high)
+inline
+ std::int64_t get64BitInt(DWORD low, LONG high)
{
- assert_static(sizeof(low) + sizeof(high) == sizeof(value));
+ static_assert(sizeof(low) + sizeof(high) == sizeof(std::int64_t), "");
LARGE_INTEGER cvt = {};
cvt.LowPart = low;
cvt.HighPart = high;
- value = cvt.QuadPart;
- }
- LONG getHi() const
- {
- LARGE_INTEGER cvt = {};
- cvt.QuadPart = value;
- return cvt.HighPart;
+ return cvt.QuadPart;
}
- DWORD getLo() const
- {
- LARGE_INTEGER cvt = {};
- cvt.QuadPart = value;
- return cvt.LowPart;
- }
-#endif
-
- Int64& operator+=(const Int64& rhs) { checkRange<std::int64_t>(double(value) + rhs.value); value += rhs.value; return *this; }
- Int64& operator-=(const Int64& rhs) { checkRange<std::int64_t>(double(value) - rhs.value); value -= rhs.value; return *this; }
- Int64& operator*=(const Int64& rhs) { checkRange<std::int64_t>(double(value) * rhs.value); value *= rhs.value; return *this; }
- Int64& operator/=(const Int64& rhs) { assert(rhs.value != 0); value /= rhs.value; return *this; }
- Int64& operator%=(const Int64& rhs) { assert(rhs.value != 0); value %= rhs.value; return *this; }
- Int64& operator&=(const Int64& rhs) { value &= rhs.value; return *this;}
- Int64& operator|=(const Int64& rhs) { value |= rhs.value; return *this;}
- Int64& operator<<=(int rhs) { assert(rhs < 0 || (value << rhs) >> rhs == value); value <<= rhs; return *this; }
- Int64& operator>>=(int rhs) { assert(rhs > 0 || (value >> rhs) << rhs == value); value >>= rhs; return *this; }
- Int64 operator-() const { return -value; }
-
- inline friend bool operator==(const Int64& lhs, const Int64& rhs) { return lhs.value == rhs.value; }
- inline friend bool operator!=(const Int64& lhs, const Int64& rhs) { return lhs.value != rhs.value; }
- inline friend bool operator< (const Int64& lhs, const Int64& rhs) { return lhs.value < rhs.value; }
- inline friend bool operator> (const Int64& lhs, const Int64& rhs) { return lhs.value > rhs.value; }
- inline friend bool operator<=(const Int64& lhs, const Int64& rhs) { return lhs.value <= rhs.value; }
- inline friend bool operator>=(const Int64& lhs, const Int64& rhs) { return lhs.value >= rhs.value; }
-
- //checked conversion to arbitrary target integer type
- template <class T> inline friend T to(Int64 number) { checkRange<T>(number.value); return static_cast<T>(number.value); }
- template <class T> inline friend std::basic_istream<T>& operator>>(std::basic_istream<T>& lhs, Int64& rhs) { lhs >> rhs.value; return lhs; }
- template <class T> inline friend std::basic_ostream<T>& operator<<(std::basic_ostream<T>& lhs, const Int64& rhs) { lhs << rhs.value; return lhs; }
+std::int64_t get64BitInt(std::uint64_t low, std::int64_t high) = delete;
-private:
- std::int64_t value;
-};
-inline Int64 operator+ (const Int64& lhs, const Int64& rhs) { return Int64(lhs) += rhs; }
-inline Int64 operator- (const Int64& lhs, const Int64& rhs) { return Int64(lhs) -= rhs; }
-inline Int64 operator* (const Int64& lhs, const Int64& rhs) { return Int64(lhs) *= rhs; }
-inline Int64 operator/ (const Int64& lhs, const Int64& rhs) { return Int64(lhs) /= rhs; }
-inline Int64 operator% (const Int64& lhs, const Int64& rhs) { return Int64(lhs) %= rhs; }
-inline Int64 operator& (const Int64& lhs, const Int64& rhs) { return Int64(lhs) &= rhs; }
-inline Int64 operator| (const Int64& lhs, const Int64& rhs) { return Int64(lhs) |= rhs; }
-inline Int64 operator<<(const Int64& lhs, int rhs) { return Int64(lhs) <<= rhs; }
-inline Int64 operator>>(const Int64& lhs, int rhs) { return Int64(lhs) >>= rhs; }
-
-
-class UInt64
-{
-public:
- //safe implicit conversions
- UInt64() : value(0) {}
- UInt64(const UInt64& rhs) : value(rhs.value) {}
- template <class T>
- UInt64(T rhs, typename EnableIf<IsUnsignedInt<T>::value&& sizeof(T) <= sizeof(std::uint64_t)>::Type* = nullptr) :
- value(static_cast<std::uint64_t>(rhs)) {}
-
- //unsafe explicit but checked conversion for all other integer types
- template <class T> explicit UInt64(T rhs, typename EnableIf<!(IsUnsignedInt<T>::value&& sizeof(T) <= sizeof(std::uint64_t))>::Type* = nullptr) :
- value(static_cast<std::uint64_t>(rhs)) { checkRange<std::uint64_t>(rhs); }
-
- UInt64& operator=(const UInt64& rhs) { value = rhs.value; return *this; }
-
-#ifdef ZEN_WIN
- UInt64(DWORD low, DWORD high)
+inline
+std::uint64_t get64BitUInt(DWORD low, DWORD high)
{
- assert_static(sizeof(low) + sizeof(high) == sizeof(value));
+ static_assert(sizeof(low) + sizeof(high) == sizeof(std::uint64_t), "");
ULARGE_INTEGER cvt = {};
cvt.LowPart = low;
cvt.HighPart = high;
- value = cvt.QuadPart;
- }
- DWORD getHi() const
- {
- ULARGE_INTEGER cvt = {};
- cvt.QuadPart = value;
- return cvt.HighPart;
- }
- DWORD getLo() const
- {
- ULARGE_INTEGER cvt = {};
- cvt.QuadPart = value;
- return cvt.LowPart;
+ return cvt.QuadPart;
}
-#endif
-
- UInt64& operator+=(const UInt64& rhs) { checkRange<std::uint64_t>(double(value) + rhs.value); value += rhs.value; return *this; }
- UInt64& operator-=(const UInt64& rhs) { checkRange<std::uint64_t>(double(value) - rhs.value); value -= rhs.value; return *this; }
- UInt64& operator*=(const UInt64& rhs) { checkRange<std::uint64_t>(double(value) * rhs.value); value *= rhs.value; return *this; }
- UInt64& operator/=(const UInt64& rhs) { assert(rhs.value != 0); value /= rhs.value; return *this; }
- UInt64& operator%=(const UInt64& rhs) { assert(rhs.value != 0); value %= rhs.value; return *this; }
- UInt64& operator&=(const UInt64& rhs) { value &= rhs.value; return *this;}
- UInt64& operator|=(const UInt64& rhs) { value |= rhs.value; return *this;}
- UInt64& operator<<=(int rhs) { assert(rhs < 0 || (value << rhs) >> rhs == value); value <<= rhs; return *this; }
- UInt64& operator>>=(int rhs) { assert(rhs > 0 || (value >> rhs) << rhs == value); value >>= rhs; return *this; }
-
- inline friend bool operator==(const UInt64& lhs, const UInt64& rhs) { return lhs.value == rhs.value; }
- inline friend bool operator!=(const UInt64& lhs, const UInt64& rhs) { return lhs.value != rhs.value; }
- inline friend bool operator< (const UInt64& lhs, const UInt64& rhs) { return lhs.value < rhs.value; }
- inline friend bool operator> (const UInt64& lhs, const UInt64& rhs) { return lhs.value > rhs.value; }
- inline friend bool operator<=(const UInt64& lhs, const UInt64& rhs) { return lhs.value <= rhs.value; }
- inline friend bool operator>=(const UInt64& lhs, const UInt64& rhs) { return lhs.value >= rhs.value; }
-
- //checked conversion to arbitrary target integer type
- template <class T> friend T to(UInt64 number);
-
- template <class T> inline friend std::basic_istream<T>& operator>>(std::basic_istream<T>& lhs, UInt64& rhs) { lhs >> rhs.value; return lhs; }
- template <class T> inline friend std::basic_ostream<T>& operator<<(std::basic_ostream<T>& lhs, const UInt64& rhs) { lhs << rhs.value; return lhs; }
-
-private:
- std::uint64_t value;
-};
-
-template <class T> inline T to(UInt64 number) { checkRange<T>(number.value); return static_cast<T>(number.value); } //Clang 3.2 doesn't properly handle inline-friends defined in class definition
-inline UInt64 operator+ (const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) += rhs; }
-inline UInt64 operator- (const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) -= rhs; }
-inline UInt64 operator* (const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) *= rhs; }
-inline UInt64 operator/ (const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) /= rhs; }
-inline UInt64 operator% (const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) %= rhs; }
-inline UInt64 operator& (const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) &= rhs; }
-inline UInt64 operator| (const UInt64& lhs, const UInt64& rhs) { return UInt64(lhs) |= rhs; }
-inline UInt64 operator<<(const UInt64& lhs, int rhs) { return UInt64(lhs) <<= rhs; }
-inline UInt64 operator>>(const UInt64& lhs, int rhs) { return UInt64(lhs) >>= rhs; }
+std::int64_t get64BitUInt(std::uint64_t low, std::uint64_t high) = delete;
-template <> inline UInt64 to(Int64 number) { checkRange<std::uint64_t>(number.value); return UInt64(number.value); }
-template <> inline Int64 to(UInt64 number) { checkRange<std:: int64_t>(number.value); return Int64(number.value); }
-
-#ifdef ZEN_WIN
//convert FILETIME (number of 100-nanosecond intervals since January 1, 1601 UTC)
// to time_t (number of seconds since Jan. 1st 1970 UTC)
//
//FAT32 time is preserved exactly: FAT32 -> toTimeT -> tofiletime -> FAT32
inline
-Int64 toTimeT(const FILETIME& ft)
+std::int64_t filetimeToTimeT(const FILETIME& ft)
{
- return to<Int64>(UInt64(ft.dwLowDateTime, ft.dwHighDateTime) / 10000000U) - Int64(3054539008UL, 2);
+ return static_cast<std::int64_t>(get64BitUInt(ft.dwLowDateTime, ft.dwHighDateTime) / 10000000U) - get64BitInt(3054539008UL, 2); //caveat: signed/unsigned arithmetics!
//timeshift between ansi C time and FILETIME in seconds == 11644473600s
}
inline
-FILETIME toFileTime(const Int64& utcTime)
-{
- const UInt64 fileTimeLong = to<UInt64>(utcTime + Int64(3054539008UL, 2)) * 10000000U;
- const FILETIME output = { fileTimeLong.getLo(), fileTimeLong.getHi() };
+FILETIME timetToFileTime(std::int64_t utcTime)
+{
+ ULARGE_INTEGER cvt = {};
+ cvt.QuadPart = (utcTime + get64BitInt(3054539008UL, 2)) * 10000000U; //caveat: signed/unsigned arithmetics!
+
+ const FILETIME output = { cvt.LowPart, cvt.HighPart };
return output;
}
#endif
}
-//specialize numeric limits
-namespace std
-{
-assert_static(std::numeric_limits<std:: int64_t>::is_specialized);
-assert_static(std::numeric_limits<std::uint64_t>::is_specialized);
-
-template <> class numeric_limits<zen::Int64> : public numeric_limits<std::int64_t>
-{
-public:
- static zen::Int64 min() throw() { return numeric_limits<std::int64_t>::min(); }
- static zen::Int64 max() throw() { return numeric_limits<std::int64_t>::max(); }
-};
-
-template <> class numeric_limits<zen::UInt64> : public numeric_limits<std::uint64_t>
-{
-public:
- static zen::UInt64 min() throw() { return numeric_limits<std::uint64_t>::min(); }
- static zen::UInt64 max() throw() { return numeric_limits<std::uint64_t>::max(); }
-};
-}
-
-/*
-//specialize zen type trait
-namespace zen -> we cannot mix signed/unsigned in general arithmetic operations -> we'll use the ostream-approach
-{
-template <> struct IsUnsignedInt<UInt64> : StaticBool<true> {};
-template <> struct IsSignedInt <Int64> : StaticBool<true> {};
-}
-*/
#endif //FFS_LARGE_64_BIT_INTEGER_H_INCLUDED
diff --git a/zen/long_path_prefix.h b/zen/long_path_prefix.h
index 0669cf88..824c7084 100644
--- a/zen/long_path_prefix.h
+++ b/zen/long_path_prefix.h
@@ -12,14 +12,14 @@
namespace zen
{
-//handle filenames longer-equal 260 (== MAX_PATH) characters by applying \\?\-prefix; see: http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
+//handle filepaths longer-equal 260 (== MAX_PATH) characters by applying \\?\-prefix; see: http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
/*
1. path must be absolute
2. if path is smaller than MAX_PATH nothing is changed! caveat: FindFirstFile() "Prepending the string "\\?\" does not allow access to the root directory."
3. path may already contain \\?\-prefix
*/
Zstring applyLongPathPrefix(const Zstring& path); //noexcept
-Zstring applyLongPathPrefixCreateDir(const Zstring& path); //noexcept -> special rule for ::CreateDirectory()/::CreateDirectoryEx(): MAX_PATH - 12(=^ 8.3 filename) is threshold
+Zstring applyLongPathPrefixCreateDir(const Zstring& path); //noexcept -> special rule for ::CreateDirectory()/::CreateDirectoryEx(): MAX_PATH - 12(=^ 8.3 filepath) is threshold
Zstring removeLongPathPrefix(const Zstring& path); //noexcept
@@ -97,7 +97,7 @@ Zstring zen::applyLongPathPrefix(const Zstring& path)
inline
Zstring zen::applyLongPathPrefixCreateDir(const Zstring& path) //noexcept
{
- //special rule for ::CreateDirectoryEx(): MAX_PATH - 12(=^ 8.3 filename) is threshold
+ //special rule for ::CreateDirectoryEx(): MAX_PATH - 12(=^ 8.3 filepath) is threshold
return applyLongPathPrefixImpl<MAX_PATH - 12> (path);
}
diff --git a/zen/notify_removal.cpp b/zen/notify_removal.cpp
index c66eb3c1..3de375f2 100644
--- a/zen/notify_removal.cpp
+++ b/zen/notify_removal.cpp
@@ -35,8 +35,8 @@ public:
private:
MessageProvider();
~MessageProvider();
- MessageProvider(const MessageProvider&);
- MessageProvider& operator=(const MessageProvider&);
+ MessageProvider (const MessageProvider&) = delete;
+ MessageProvider& operator=(const MessageProvider&) = delete;
static const wchar_t dummyWindowName[];
@@ -173,8 +173,8 @@ public:
}
private:
- Pimpl(Pimpl&);
- Pimpl& operator=(Pimpl&);
+ Pimpl (const Pimpl&) = delete;
+ Pimpl& operator=(const Pimpl&) = delete;
virtual void onMessage(UINT message, WPARAM wParam, LPARAM lParam) //throw()!
{
diff --git a/zen/process_priority.cpp b/zen/process_priority.cpp
index a50fbd75..d2f6dc26 100644
--- a/zen/process_priority.cpp
+++ b/zen/process_priority.cpp
@@ -5,18 +5,17 @@
// **************************************************************************
#include "process_priority.h"
-#include <zen/sys_error.h>
-#include <zen/i18n.h>
+#include "sys_error.h"
+#include "i18n.h"
#ifdef ZEN_WIN
#include "win.h" //includes "windows.h"
#elif defined ZEN_LINUX
-//#include <sys/syscall.h>
#elif defined ZEN_MAC
#include <sys/resource.h> //getiopolicy_np
-#include <IOKit/pwr_mgt/IOPMLib.h> //keep in .cpp file to not pollute global namespace! e.g. with UInt64
+#include <IOKit/pwr_mgt/IOPMLib.h> //keep in .cpp file to not pollute global namespace!
#endif
using namespace zen;
diff --git a/zen/recycler.cpp b/zen/recycler.cpp
index 0e4e4be0..41ea6002 100644
--- a/zen/recycler.cpp
+++ b/zen/recycler.cpp
@@ -5,7 +5,7 @@
// **************************************************************************
#include "recycler.h"
-#include <zen/file_handling.h>
+#include "file_handling.h"
#ifdef ZEN_WIN
#include "thread.h"
@@ -16,9 +16,9 @@
#include "IFileOperation/file_op.h"
#elif defined ZEN_LINUX
-#include <zen/scope_guard.h>
#include <sys/stat.h>
#include <gio/gio.h>
+#include "scope_guard.h"
#elif defined ZEN_MAC
#include <CoreServices/CoreServices.h>
@@ -54,14 +54,14 @@ struct CallbackData
};
-bool onRecyclerCallback(const wchar_t* filename, void* sink)
+bool onRecyclerCallback(const wchar_t* itempath, void* sink)
{
CallbackData& cbd = *static_cast<CallbackData*>(sink); //sink is NOT optional here
if (cbd.notifyDeletionStatus_)
try
{
- cbd.notifyDeletionStatus_(filename); //throw ?
+ cbd.notifyDeletionStatus_(itempath); //throw ?
}
catch (...)
{
@@ -73,11 +73,11 @@ bool onRecyclerCallback(const wchar_t* filename, void* sink)
}
-void zen::recycleOrDelete(const std::vector<Zstring>& filenames, const std::function<void (const Zstring& currentItem)>& notifyDeletionStatus)
+void zen::recycleOrDelete(const std::vector<Zstring>& itempaths, const std::function<void (const Zstring& currentItem)>& notifyDeletionStatus)
{
- if (filenames.empty())
+ if (itempaths.empty())
return;
- //::SetFileAttributes(applyLongPathPrefix(filename).c_str(), FILE_ATTRIBUTE_NORMAL);
+ //::SetFileAttributes(applyLongPathPrefix(itempath).c_str(), FILE_ATTRIBUTE_NORMAL);
//warning: moving long file paths to recycler does not work!
//both ::SHFileOperation() and ::IFileOperation() cannot delete a folder named "System Volume Information" with normal attributes but shamelessly report success
//both ::SHFileOperation() and ::IFileOperation() can't handle \\?\-prefix!
@@ -89,11 +89,11 @@ void zen::recycleOrDelete(const std::vector<Zstring>& filenames, const std::func
const DllFun<FunType_getLastErrorMessage> getLastErrorMessage(getDllName(), funName_getLastErrorMessage);
if (!moveToRecycler || !getLastErrorMessage)
- throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filenames[0])),
+ throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(itempaths[0])),
replaceCpy(_("Cannot load file %x."), L"%x", fmtFileName(getDllName())));
std::vector<const wchar_t*> cNames;
- for (auto it = filenames.begin(); it != filenames.end(); ++it) //CAUTION: do not create temporary strings here!!
+ for (auto it = itempaths.begin(); it != itempaths.end(); ++it) //CAUTION: do not create temporary strings here!!
cNames.push_back(it->c_str());
CallbackData cbd(notifyDeletionStatus);
@@ -106,26 +106,26 @@ void zen::recycleOrDelete(const std::vector<Zstring>& filenames, const std::func
assert(false);
}
- std::wstring filenameFmt = fmtFileName(filenames[0]); //probably not the correct file name for file lists larger than 1!
- if (filenames.size() > 1)
- filenameFmt += L", ..."; //give at least some hint that there are multiple files, and the error need not be related to the first one
+ std::wstring itempathFmt = fmtFileName(itempaths[0]); //probably not the correct file name for file lists larger than 1!
+ if (itempaths.size() > 1)
+ itempathFmt += L", ..."; //give at least some hint that there are multiple files, and the error need not be related to the first one
- throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", filenameFmt), getLastErrorMessage()); //already includes details about locking errors!
+ throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", itempathFmt), getLastErrorMessage()); //already includes details about locking errors!
}
}
else //regular recycle bin usage: available since XP
{
- Zstring filenamesDoubleNull;
- for (const Zstring& filename : filenames)
+ Zstring itempathsDoubleNull;
+ for (const Zstring& itempath : itempaths)
{
- filenamesDoubleNull += filename;
- filenamesDoubleNull += L'\0';
+ itempathsDoubleNull += itempath;
+ itempathsDoubleNull += L'\0';
}
SHFILEOPSTRUCT fileOp = {};
fileOp.hwnd = nullptr;
fileOp.wFunc = FO_DELETE;
- fileOp.pFrom = filenamesDoubleNull.c_str();
+ fileOp.pFrom = itempathsDoubleNull.c_str();
fileOp.pTo = nullptr;
fileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
fileOp.fAnyOperationsAborted = false;
@@ -135,25 +135,25 @@ void zen::recycleOrDelete(const std::vector<Zstring>& filenames, const std::func
//"You should use fully-qualified path names with this function. Using it with relative path names is not thread safe."
if (::SHFileOperation(&fileOp) != 0 || fileOp.fAnyOperationsAborted)
{
- throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filenames[0]))); //probably not the correct file name for file list larger than 1!
+ throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(itempaths[0]))); //probably not the correct file name for file list larger than 1!
}
}
}
#endif
-bool zen::recycleOrDelete(const Zstring& filename) //throw FileError
+bool zen::recycleOrDelete(const Zstring& itempath) //throw FileError
{
- if (!somethingExists(filename)) //[!] do not optimize away, OS X needs this for reliable detection of "recycle bin missing"
+ if (!somethingExists(itempath)) //[!] do not optimize away, OS X needs this for reliable detection of "recycle bin missing"
return false; //neither file nor any other object with that name existing: no error situation, manual deletion relies on it!
#ifdef ZEN_WIN
- std::vector<Zstring> filenames;
- filenames.push_back(filename);
- recycleOrDelete(filenames, nullptr); //throw FileError
+ std::vector<Zstring> itempaths;
+ itempaths.push_back(itempath);
+ recycleOrDelete(itempaths, nullptr); //throw FileError
#elif defined ZEN_LINUX
- GFile* file = ::g_file_new_for_path(filename.c_str()); //never fails according to docu
+ GFile* file = ::g_file_new_for_path(itempath.c_str()); //never fails according to docu
ZEN_ON_SCOPE_EXIT(g_object_unref(file);)
GError* error = nullptr;
@@ -161,7 +161,7 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError
if (!::g_file_trash(file, nullptr, &error))
{
- const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filename));
+ const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(itempath));
if (!error)
throw FileError(errorMsg, L"Unknown error."); //user should never see this
@@ -170,13 +170,13 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError
if (error->code == G_IO_ERROR_NOT_SUPPORTED)
{
struct ::stat fileInfo = {};
- if (::lstat(filename.c_str(), &fileInfo) != 0)
+ if (::lstat(itempath.c_str(), &fileInfo) != 0)
return false;
if (S_ISLNK(fileInfo.st_mode) || S_ISREG(fileInfo.st_mode))
- removeFile(filename); //throw FileError
+ removeFile(itempath); //throw FileError
else if (S_ISDIR(fileInfo.st_mode))
- removeDirectory(filename); //throw FileError
+ removeDirectory(itempath); //throw FileError
return true;
}
@@ -188,11 +188,11 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError
//we cannot use FSPathMoveObjectToTrashSync directly since it follows symlinks!
assert_static(sizeof(Zchar) == sizeof(char));
- const UInt8* filenameUtf8 = reinterpret_cast<const UInt8*>(filename.c_str());
+ const UInt8* itempathUtf8 = reinterpret_cast<const UInt8*>(itempath.c_str());
auto throwFileError = [&](OSStatus oss)
{
- const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filename));
+ const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(itempath));
std::wstring errorDescr = L"OSStatus Code " + numberTo<std::wstring>(oss);
if (const char* description = ::GetMacOSStatusCommentString(oss)) //found no documentation for proper use of GetMacOSStatusCommentString
@@ -201,7 +201,7 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError
};
FSRef objectRef = {}; //= POD structure not a pointer type!
- OSStatus rv = ::FSPathMakeRefWithOptions(filenameUtf8, //const UInt8 *path,
+ OSStatus rv = ::FSPathMakeRefWithOptions(itempathUtf8, //const UInt8 *path,
kFSPathMakeRefDoNotFollowLeafSymlink, //OptionBits options,
&objectRef, //FSRef *ref,
nullptr); //Boolean *isDirectory
@@ -218,13 +218,13 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError
if (rv2 == -120) //=="Directory not found or incomplete pathname." but should really be "recycle bin directory not found"!
{
struct ::stat fileInfo = {};
- if (::lstat(filename.c_str(), &fileInfo) != 0)
+ if (::lstat(itempath.c_str(), &fileInfo) != 0)
return false;
if (S_ISLNK(fileInfo.st_mode) || S_ISREG(fileInfo.st_mode))
- removeFile(filename); //throw FileError
+ removeFile(itempath); //throw FileError
else if (S_ISDIR(fileInfo.st_mode))
- removeDirectory(filename); //throw FileError
+ removeDirectory(itempath); //throw FileError
return true;
}
@@ -352,7 +352,7 @@ We really need access to a similar function to check whether a directory support
The following function looks perfect, alas it is restricted to local files and to the implementation of GIO only:
- gboolean _g_local_file_has_trash_dir(const char* dirname, dev_t dir_dev);
+ gboolean _g_local_file_has_trash_dir(const char* dirpath, dev_t dir_dev);
See: http://www.netmite.com/android/mydroid/2.0/external/bluetooth/glib/gio/glocalfileinfo.h
Just checking for "G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH" is not correct, since we find in
diff --git a/zen/recycler.h b/zen/recycler.h
index 255f11ef..e900dfa3 100644
--- a/zen/recycler.h
+++ b/zen/recycler.h
@@ -9,8 +9,7 @@
#include <vector>
#include <functional>
-#include <zen/file_error.h>
-#include <zen/zstring.h>
+#include "file_error.h"
namespace zen
{
@@ -32,14 +31,14 @@ Already included in package "gtk+-2.0"!
*/
//move a file or folder to Recycle Bin (deletes permanently if recycler is not available) -> crappy semantics, but we have no choice thanks to Windows' design
-bool recycleOrDelete(const Zstring& filename); //throw FileError, return "true" if file/dir was actually deleted
+bool recycleOrDelete(const Zstring& itempath); //throw FileError, return "true" if file/dir was actually deleted
#ifdef ZEN_WIN
//can take a long time if recycle bin is full and drive is slow!!! => buffer volume ids!
bool recycleBinExists(const Zstring& pathName, const std::function<void ()>& onUpdateGui); //throw FileError
-void recycleOrDelete(const std::vector<Zstring>& filenames, //throw FileError, return "true" if file/dir was actually deleted
+void recycleOrDelete(const std::vector<Zstring>& filepaths, //throw FileError, return "true" if file/dir was actually deleted
//may throw: first exception is swallowed, updateStatus() is then called again where it should throw again and the exception will propagate as expected
const std::function<void (const Zstring& currentItem)>& notifyDeletionStatus); //optional; currentItem may be empty
#endif
diff --git a/zen/serialize.h b/zen/serialize.h
index 9a14e6af..64df0329 100644
--- a/zen/serialize.h
+++ b/zen/serialize.h
@@ -8,8 +8,8 @@
#define SERIALIZE_H_INCLUDED_83940578357
#include <cstdint>
-#include <zen/string_base.h>
-#include <zen/file_io.h>
+#include "string_base.h"
+#include "file_io.h"
namespace zen
{
@@ -54,8 +54,8 @@ private:
//----------------------------------------------------------------------
//functions based on binary container abstraction
-template <class BinContainer> void saveBinStream(const Zstring& filename, const BinContainer& cont); //throw FileError
-template <class BinContainer> BinContainer loadBinStream(const Zstring& filename); //throw FileError
+template <class BinContainer> void saveBinStream(const Zstring& filepath, const BinContainer& cont); //throw FileError
+template <class BinContainer> BinContainer loadBinStream(const Zstring& filepath); //throw FileError
/*
@@ -135,22 +135,22 @@ template < class BinInputStream> void readArray (BinInputStream& stre
//-----------------------implementation-------------------------------
template <class BinContainer> inline
-void saveBinStream(const Zstring& filename, const BinContainer& cont) //throw FileError
+void saveBinStream(const Zstring& filepath, const BinContainer& cont) //throw FileError
{
assert_static(sizeof(typename BinContainer::value_type) == 1); //expect: bytes (until further)
- FileOutput fileOut(filename, zen::FileOutput::ACC_OVERWRITE); //throw FileError
+ FileOutput fileOut(filepath, zen::FileOutput::ACC_OVERWRITE); //throw FileError
if (!cont.empty())
fileOut.write(&*cont.begin(), cont.size()); //throw FileError
}
template <class BinContainer> inline
-BinContainer loadBinStream(const Zstring& filename) //throw FileError
+BinContainer loadBinStream(const Zstring& filepath) //throw FileError
{
assert_static(sizeof(typename BinContainer::value_type) == 1); //expect: bytes (until further)
- FileInput fileIn(filename); //throw FileError
+ FileInput fileIn(filepath); //throw FileError
BinContainer contOut;
const size_t blockSize = 128 * 1024;
diff --git a/zen/shell_execute.h b/zen/shell_execute.h
index 78526b70..9f99315a 100644
--- a/zen/shell_execute.h
+++ b/zen/shell_execute.h
@@ -46,11 +46,11 @@ void shellExecute2(const Zstring& command, ExecutionType type) //throw FileError
std::copy(tmp, tmp + argc, std::back_inserter(argv));
}
- Zstring filename;
+ Zstring filepath;
Zstring arguments;
if (!argv.empty())
{
- filename = argv[0];
+ filepath = argv[0];
for (auto iter = argv.begin() + 1; iter != argv.end(); ++iter)
arguments += (iter != argv.begin() ? L" " : L"") +
(iter->empty() || std::any_of(iter->begin(), iter->end(), &isWhiteSpace<wchar_t>) ? L"\"" + *iter + L"\"" : *iter);
@@ -63,12 +63,12 @@ void shellExecute2(const Zstring& command, ExecutionType type) //throw FileError
execInfo.fMask = type == EXEC_TYPE_SYNC ? (SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT) : 0; //don't use SEE_MASK_ASYNCOK -> returns successful despite errors!
execInfo.fMask |= SEE_MASK_UNICODE | SEE_MASK_FLAG_NO_UI; //::ShellExecuteEx() shows a non-blocking pop-up dialog on errors -> we want a blocking one
execInfo.lpVerb = nullptr;
- execInfo.lpFile = filename.c_str();
+ execInfo.lpFile = filepath.c_str();
execInfo.lpParameters = arguments.c_str();
execInfo.nShow = SW_SHOWNORMAL;
if (!::ShellExecuteEx(&execInfo)) //__inout LPSHELLEXECUTEINFO lpExecInfo
- throwFileError(_("Incorrect command line:") + L"\nFile: " + filename + L"\nArg: " + arguments, L"ShellExecuteEx", ::GetLastError());
+ throwFileError(_("Incorrect command line:") + L"\nFile: " + filepath + L"\nArg: " + arguments, L"ShellExecuteEx", ::GetLastError());
if (execInfo.hProcess)
{
diff --git a/zen/symlink_target.h b/zen/symlink_target.h
index 13226f1f..21833492 100644
--- a/zen/symlink_target.h
+++ b/zen/symlink_target.h
@@ -12,7 +12,6 @@
#ifdef ZEN_WIN
#include "win.h" //includes "windows.h"
-//#include <WinIoCtl.h>
#include "privilege.h"
#include "long_path_prefix.h"
#include "dll.h"
diff --git a/zen/thread.h b/zen/thread.h
index d74eaa5b..8c72e43f 100644
--- a/zen/thread.h
+++ b/zen/thread.h
@@ -43,8 +43,8 @@ std::async replacement without crappy semantics:
2. does not follow C++11 [futures.async], Paragraph 5, where std::future waits for thread in destructor
Example:
- Zstring dirname = ...
- auto ft = zen::async([=](){ return zen::dirExists(dirname); });
+ Zstring dirpath = ...
+ auto ft = zen::async([=](){ return zen::dirExists(dirpath); });
if (ft.timed_wait(boost::posix_time::milliseconds(200)) && ft.get())
//dir exising
*/
diff --git a/zen/win_ver.h b/zen/win_ver.h
index 766c0ee9..e123737d 100644
--- a/zen/win_ver.h
+++ b/zen/win_ver.h
@@ -8,7 +8,7 @@
#define WINDOWS_VERSION_HEADER_238470348254325
#include <cstdint>
-#include <zen/win.h> //includes "windows.h"
+#include "win.h" //includes "windows.h"
namespace zen
{
diff --git a/zen/xml_io.cpp b/zen/xml_io.cpp
index a8236300..485d78bb 100644
--- a/zen/xml_io.cpp
+++ b/zen/xml_io.cpp
@@ -12,13 +12,13 @@
using namespace zen;
-XmlDoc zen::loadXmlDocument(const Zstring& filename) //throw FileError
+XmlDoc zen::loadXmlDocument(const Zstring& filepath) //throw FileError
{
//can't simply use zen::loadBinStream() due to the short-circuit xml-validation below!
std::string stream;
- FileInput inputFile(filename); //throw FileError
+ FileInput inputFile(filepath); //throw FileError
{
//quick test whether input is an XML: avoid loading large binary files up front!
const std::string xmlBegin = "<?xml version=";
@@ -29,7 +29,7 @@ XmlDoc zen::loadXmlDocument(const Zstring& filename) //throw FileError
if (!startsWith(stream, xmlBegin) &&
!startsWith(stream, BYTE_ORDER_MARK_UTF8 + xmlBegin)) //allow BOM!
- throw FileError(replaceCpy(_("File %x does not contain a valid configuration."), L"%x", fmtFileName(filename)));
+ throw FileError(replaceCpy(_("File %x does not contain a valid configuration."), L"%x", fmtFileName(filepath)));
}
const size_t blockSize = 128 * 1024;
@@ -51,32 +51,32 @@ XmlDoc zen::loadXmlDocument(const Zstring& filename) //throw FileError
{
throw FileError(
replaceCpy(replaceCpy(replaceCpy(_("Error parsing file %x, row %y, column %z."),
- L"%x", fmtFileName(filename)),
+ L"%x", fmtFileName(filepath)),
L"%y", numberTo<std::wstring>(e.row + 1)),
L"%z", numberTo<std::wstring>(e.col + 1)));
}
}
-void zen::saveXmlDocument(const XmlDoc& doc, const Zstring& filename) //throw FileError
+void zen::saveXmlDocument(const XmlDoc& doc, const Zstring& filepath) //throw FileError
{
std::string stream = serialize(doc); //noexcept
//only update xml file if there are real changes
try
{
- if (getFilesize(filename) == stream.size()) //throw FileError
- if (loadBinStream<std::string>(filename) == stream) //throw FileError
+ if (getFilesize(filepath) == stream.size()) //throw FileError
+ if (loadBinStream<std::string>(filepath) == stream) //throw FileError
return;
}
catch (FileError&) {}
- FileOutput outputFile(filename, FileOutput::ACC_OVERWRITE); //throw FileError
+ FileOutput outputFile(filepath, FileOutput::ACC_OVERWRITE); //throw FileError
outputFile.write(stream.c_str(), stream.length()); //
}
-void zen::checkForMappingErrors(const XmlIn& xmlInput, const Zstring& filename) //throw FileError
+void zen::checkForMappingErrors(const XmlIn& xmlInput, const Zstring& filepath) //throw FileError
{
if (xmlInput.errorsOccured())
{
@@ -84,6 +84,6 @@ void zen::checkForMappingErrors(const XmlIn& xmlInput, const Zstring& filename)
for (const std::wstring& elem : xmlInput.getErrorsAs<std::wstring>())
msg += L"\n" + elem;
- throw FileError(replaceCpy(_("Configuration file %x loaded partially only."), L"%x", fmtFileName(filename)) + L"\n\n" + msg);
+ throw FileError(replaceCpy(_("Configuration file %x loaded partially only."), L"%x", fmtFileName(filepath)) + L"\n\n" + msg);
}
}
diff --git a/zen/xml_io.h b/zen/xml_io.h
index b53a5ef4..e3e47f59 100644
--- a/zen/xml_io.h
+++ b/zen/xml_io.h
@@ -8,8 +8,7 @@
#define XMLBASE_H_INCLUDED
#include <zenxml/xml.h>
-#include <zen/zstring.h>
-#include <zen/file_error.h>
+#include "file_error.h"
//combine zen::Xml and zen file i/o
//-> loadXmlDocument vs loadStream:
@@ -18,10 +17,10 @@
namespace zen
{
-XmlDoc loadXmlDocument(const Zstring& filename); //throw FileError
-void checkForMappingErrors(const XmlIn& xmlInput, const Zstring& filename); //throw FileError
+XmlDoc loadXmlDocument(const Zstring& filepath); //throw FileError
+void checkForMappingErrors(const XmlIn& xmlInput, const Zstring& filepath); //throw FileError
-void saveXmlDocument(const XmlDoc& doc, const Zstring& filename); //throw FileError
+void saveXmlDocument(const XmlDoc& doc, const Zstring& filepath); //throw FileError
}
#endif // XMLBASE_H_INCLUDED
diff --git a/zen/zstring.cpp b/zen/zstring.cpp
index 3e579b1e..f1858efc 100644
--- a/zen/zstring.cpp
+++ b/zen/zstring.cpp
@@ -12,7 +12,6 @@
#include "win_ver.h"
#elif defined ZEN_MAC
-//#include <zen/scope_guard.h>
#include <ctype.h> //toupper()
#endif
@@ -75,8 +74,8 @@ private:
}
}
- LeakChecker(const LeakChecker&);
- LeakChecker& operator=(const LeakChecker&);
+ LeakChecker (const LeakChecker&) = delete;
+ LeakChecker& operator=(const LeakChecker&) = delete;
static std::string rawMemToString(const void* ptr, size_t size)
{
@@ -165,7 +164,7 @@ int z_impl::compareFilenamesNoCase(const wchar_t* lhs, const wchar_t* rhs, size_
else //fallback
{
//do NOT use "CompareString"; this function is NOT accurate (even with LOCALE_INVARIANT and SORT_STRINGSORT): for example "weiß" == "weiss"!!!
- //the only reliable way to compare filenames (with XP) is to call "CharUpper" or "LCMapString":
+ //the only reliable way to compare filepaths (with XP) is to call "CharUpper" or "LCMapString":
auto copyToUpperCase = [](const wchar_t* strIn, wchar_t* strOut, size_t len)
{
diff --git a/zen/zstring.h b/zen/zstring.h
index f103faf7..2152954d 100644
--- a/zen/zstring.h
+++ b/zen/zstring.h
@@ -8,10 +8,9 @@
#define ZSTRING_H_INCLUDED
#include "string_base.h"
+
#ifdef ZEN_LINUX
#include <cstring> //strcmp
-#elif defined ZEN_MAC
-//#include <strings.h> //strcasecmp
#endif
@@ -66,7 +65,7 @@ typedef zen::Zbase<Zchar, zen::StorageRefCountThreadSafe, AllocatorFreeStoreChec
-//Compare filenames: Windows does NOT distinguish between upper/lower-case, while Linux DOES
+//Compare filepaths: Windows does NOT distinguish between upper/lower-case, while Linux DOES
template <template <class, class> class SP, class AP>
int cmpFileName(const zen::Zbase<Zchar, SP, AP>& lhs, const zen::Zbase<Zchar, SP, AP>& rhs);
@@ -114,7 +113,7 @@ int cmpFileName(const zen::Zbase<Zchar, SP, AP>& lhs, const zen::Zbase<Zchar, SP
#if defined ZEN_WIN || defined ZEN_MAC
return z_impl::compareFilenamesNoCase(lhs.data(), rhs.data(), lhs.length(), rhs.length());
#elif defined ZEN_LINUX
- return std::strcmp(lhs.c_str(), rhs.c_str()); //POSIX filenames don't have embedded 0
+ return std::strcmp(lhs.c_str(), rhs.c_str()); //POSIX filepaths don't have embedded 0
//#elif defined ZEN_MAC
// return ::strcasecmp(lhs.c_str(), rhs.c_str()); //locale-dependent!
#endif
bgstack15