summaryrefslogtreecommitdiff
path: root/zen
diff options
context:
space:
mode:
Diffstat (limited to 'zen')
-rw-r--r--zen/async_task.h1
-rw-r--r--zen/dir_watcher.h1
-rw-r--r--zen/error_log.h1
-rw-r--r--zen/file_access.cpp31
-rw-r--r--zen/file_access.h1
-rw-r--r--zen/file_traverser.h1
-rw-r--r--zen/format_unit.h1
-rw-r--r--zen/long_path_prefix.h1
-rw-r--r--zen/process_priority.h1
-rw-r--r--zen/recycler.h1
-rw-r--r--zen/serialize.h1
-rw-r--r--zen/stl_tools.h100
-rw-r--r--zen/symlink_target.h8
-rw-r--r--zen/time.h1
-rw-r--r--zen/type_tools.h1
15 files changed, 87 insertions, 64 deletions
diff --git a/zen/async_task.h b/zen/async_task.h
index d8f489a3..76e7824f 100644
--- a/zen/async_task.h
+++ b/zen/async_task.h
@@ -12,6 +12,7 @@
#include "thread.h"
#include "scope_guard.h"
+
namespace zen
{
//run a job in an async thread, but process result on GUI event loop
diff --git a/zen/dir_watcher.h b/zen/dir_watcher.h
index cdc80165..7a1ada96 100644
--- a/zen/dir_watcher.h
+++ b/zen/dir_watcher.h
@@ -12,6 +12,7 @@
#include <functional>
#include "file_error.h"
+
namespace zen
{
//Windows: ReadDirectoryChangesW http://msdn.microsoft.com/en-us/library/aa365465(v=vs.85).aspx
diff --git a/zen/error_log.h b/zen/error_log.h
index 9814ec23..81892a25 100644
--- a/zen/error_log.h
+++ b/zen/error_log.h
@@ -15,6 +15,7 @@
#include "i18n.h"
#include "string_base.h"
+
namespace zen
{
enum MessageType
diff --git a/zen/file_access.cpp b/zen/file_access.cpp
index 84d3b264..c898c5d2 100644
--- a/zen/file_access.cpp
+++ b/zen/file_access.cpp
@@ -435,29 +435,34 @@ void renameFile_sub(const Zstring& pathSource, const Zstring& pathTarget) //thro
if (lastError == ERROR_NOT_SAME_DEVICE)
throw ErrorDifferentVolume(errorMsg, errorDescr);
if (lastError == ERROR_ALREADY_EXISTS || //-> used on Win7 x64
- lastError == ERROR_FILE_EXISTS) //-> used by XP???
+ lastError == ERROR_FILE_EXISTS) //-> used by XP???
throw ErrorTargetExisting(errorMsg, errorDescr);
throw FileError(errorMsg, errorDescr);
}
#elif defined ZEN_LINUX || defined ZEN_MAC
//rename() will never fail with EEXIST, but always overwrite!
- //=> OS X: no solution
//=> Linux: renameat2() with RENAME_NOREPLACE -> still new, probably buggy
- const bool alreadyExists = somethingExists(pathTarget); //we have to let go of atomicity!
+ //=> OS X: no solution
- if (alreadyExists || ::rename(pathSource.c_str(), pathTarget.c_str()) != 0)
- {
- const int lastError = alreadyExists ? EEXIST : errno; //copy before directly or indirectly making other system calls!
+ auto throwException = [&](int ec)
+ {
const std::wstring errorMsg = replaceCpy(replaceCpy(_("Cannot move file %x to %y."), L"%x", L"\n" + fmtPath(pathSource)), L"%y", L"\n" + fmtPath(pathTarget));
- const std::wstring errorDescr = formatSystemError(L"rename", lastError);
+ const std::wstring errorDescr = formatSystemError(L"rename", ec);
- if (lastError == EXDEV)
+ if (ec == EXDEV)
throw ErrorDifferentVolume(errorMsg, errorDescr);
- if (lastError == EEXIST)
+ if (ec == EEXIST)
throw ErrorTargetExisting(errorMsg, errorDescr);
throw FileError(errorMsg, errorDescr);
- }
+ };
+
+ if (!EqualFilePath()(pathSource, pathTarget)) //OS X: changing file name case is not an "already exists" error!
+ if (somethingExists(pathTarget))
+ throwException(EEXIST);
+
+ if (::rename(pathSource.c_str(), pathTarget.c_str()) != 0)
+ throwException(errno);
#endif
}
@@ -1084,9 +1089,9 @@ void copyItemPermissions(const Zstring& sourcePath, const Zstring& targetPath, P
//in contrast to ::SetSecurityInfo(), ::SetFileSecurity() seems to honor the "inherit DACL/SACL" flags
//CAVEAT: if a file system does not support ACLs, GetFileSecurity() will return successfully with a *valid* security descriptor containing *no* ACL entries!
- //NOTE: ::GetFileSecurity()/::SetFileSecurity() do NOT follow Symlinks! getResolvedFilePath() requires Vista or later!
- const Zstring sourceResolved = procSl == ProcSymlink::FOLLOW && symlinkExists(sourcePath) ? getResolvedFilePath(sourcePath) : sourcePath; //throw FileError
- const Zstring targetResolved = procSl == ProcSymlink::FOLLOW && symlinkExists(targetPath) ? getResolvedFilePath(targetPath) : targetPath; //
+ //NOTE: ::GetFileSecurity()/::SetFileSecurity() do NOT follow Symlinks! getResolvedSymlinkPath() requires Vista or later!
+ const Zstring sourceResolved = procSl == ProcSymlink::FOLLOW && symlinkExists(sourcePath) ? getResolvedSymlinkPath(sourcePath) : sourcePath; //throw FileError
+ const Zstring targetResolved = procSl == ProcSymlink::FOLLOW && symlinkExists(targetPath) ? getResolvedSymlinkPath(targetPath) : targetPath; //
//setting privileges requires admin rights!
try
diff --git a/zen/file_access.h b/zen/file_access.h
index 4b1c31dd..3588f79b 100644
--- a/zen/file_access.h
+++ b/zen/file_access.h
@@ -12,6 +12,7 @@
#include "file_error.h"
#include "file_id_def.h"
+
namespace zen
{
bool fileExists (const Zstring& filePath); //noexcept; check whether file or file-symlink exists
diff --git a/zen/file_traverser.h b/zen/file_traverser.h
index 9cba9e58..3f8030d3 100644
--- a/zen/file_traverser.h
+++ b/zen/file_traverser.h
@@ -11,6 +11,7 @@
#include <functional>
#include "zstring.h"
+
namespace zen
{
struct FileInfo
diff --git a/zen/format_unit.h b/zen/format_unit.h
index 009199f6..d50baa32 100644
--- a/zen/format_unit.h
+++ b/zen/format_unit.h
@@ -11,6 +11,7 @@
#include <cstdint>
#include "string_tools.h"
+
namespace zen
{
std::wstring filesizeToShortString(std::int64_t filesize);
diff --git a/zen/long_path_prefix.h b/zen/long_path_prefix.h
index 3db2722b..4b79e051 100644
--- a/zen/long_path_prefix.h
+++ b/zen/long_path_prefix.h
@@ -10,6 +10,7 @@
#include "win.h"
#include "zstring.h"
+
namespace zen
{
//handle filepaths longer-equal 260 (== MAX_PATH) characters by applying \\?\-prefix; see: http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
diff --git a/zen/process_priority.h b/zen/process_priority.h
index 3e217776..72ce972c 100644
--- a/zen/process_priority.h
+++ b/zen/process_priority.h
@@ -9,6 +9,7 @@
#include <memory>
#include "file_error.h"
+
namespace zen
{
//signal a "busy" state to the operating system
diff --git a/zen/recycler.h b/zen/recycler.h
index 61a721cd..7c63cf8a 100644
--- a/zen/recycler.h
+++ b/zen/recycler.h
@@ -11,6 +11,7 @@
#include <functional>
#include "file_error.h"
+
namespace zen
{
/*
diff --git a/zen/serialize.h b/zen/serialize.h
index a41745e4..07d9362c 100644
--- a/zen/serialize.h
+++ b/zen/serialize.h
@@ -12,6 +12,7 @@
#include "string_base.h"
#include "file_io.h"
+
namespace zen
{
//high-performance unformatted serialization (avoiding wxMemoryOutputStream/wxMemoryInputStream inefficiencies)
diff --git a/zen/stl_tools.h b/zen/stl_tools.h
index 685f5118..e949c5c9 100644
--- a/zen/stl_tools.h
+++ b/zen/stl_tools.h
@@ -7,36 +7,42 @@
#ifndef STL_TOOLS_HEADER_84567184321434
#define STL_TOOLS_HEADER_84567184321434
+#include <set>
+#include <map>
+#include <vector>
#include <memory>
#include <algorithm>
#include "type_tools.h"
-
//enhancements for <algorithm>
namespace zen
{
-//idomatic remove selected elements from container
-template <class V, class Predicate>
-void vector_remove_if(V& vec, Predicate p);
+//erase selected elements from any container:
+template <class T, class Alloc, class Predicate>
+void erase_if(std::vector<T, Alloc>& v, Predicate p);
-template <class V, class W>
-void vector_append(V& vec, const W& vec2);
+template <class T, class LessType, class Alloc, class Predicate>
+void erase_if(std::set<T, LessType, Alloc>& s, Predicate p);
-template <class V>
-void removeDuplicates(V& v);
+template <class KeyType, class ValueType, class LessType, class Alloc, class Predicate>
+void erase_if(std::map<KeyType, ValueType, LessType, Alloc>& m, Predicate p);
-template <class V, class W>
-void set_append(V& s, const W& s2);
+//append STL containers
+template <class T, class Alloc, class C>
+void append(std::vector<T, Alloc>& v, const C& c);
-template <class S, class Predicate>
-void set_remove_if(S& set, Predicate p);
+template <class T, class LessType, class Alloc, class C>
+void append(std::set<T, LessType, Alloc>& s, const C& c);
-template <class M, class Predicate>
-void map_remove_if(M& map, Predicate p);
+template <class KeyType, class ValueType, class LessType, class Alloc, class C>
+void append(std::map<KeyType, ValueType, LessType, Alloc>& m, const C& c);
template <class M, class K, class V>
V& map_add_or_update(M& map, const K& key, const V& value); //efficient add or update without "default-constructible" requirement (Effective STL, item 24)
+template <class T, class Alloc>
+void removeDuplicates(std::vector<T, Alloc>& v);
+
//binary search returning an iterator
template <class ForwardIterator, class T, typename CompLess>
ForwardIterator binary_search(ForwardIterator first, ForwardIterator last, const T& value, CompLess less);
@@ -67,52 +73,45 @@ std::unique_ptr<T> make_unique(Args&& ... args) { return std::unique_ptr<T>(new
//######################## implementation ########################
-template <class V, class Predicate> inline
-void vector_remove_if(V& vec, Predicate p)
+template <class T, class Alloc, class Predicate> inline
+void erase_if(std::vector<T, Alloc>& v, Predicate p)
{
- static_assert(IsSameType<typename std::iterator_traits<typename V::iterator>::iterator_category, std::random_access_iterator_tag>::value, "poor man's check for vector");
- vec.erase(std::remove_if(vec.begin(), vec.end(), p), vec.end());
+ v.erase(std::remove_if(v.begin(), v.end(), p), v.end());
}
-template <class V> inline
-void removeDuplicates(V& v)
+namespace impl
{
- std::sort(v.begin(), v.end());
- v.erase(std::unique(v.begin(), v.end()), v.end());
+template <class S, class Predicate> inline
+void set_or_map_erase_if(S& s, Predicate p)
+{
+ for (auto iter = s.begin(); iter != s.end();)
+ if (p(*iter))
+ s.erase(iter++);
+ else
+ ++iter;
+}
}
-template <class V, class W> inline
-void vector_append(V& vec, const W& vec2)
-{
- vec.insert(vec.end(), vec2.begin(), vec2.end());
-}
+template <class T, class LessType, class Alloc, class Predicate> inline
+void erase_if(std::set<T, LessType, Alloc>& s, Predicate p) { impl::set_or_map_erase_if(s, p); } //don't make this any more generic! e.g. must not compile for std::vector!!!
-template <class V, class W> inline
-void set_append(V& s, const W& s2)
-{
- s.insert(s2.begin(), s2.end());
-}
+template <class KeyType, class ValueType, class LessType, class Alloc, class Predicate> inline
+void erase_if(std::map<KeyType, ValueType, LessType, Alloc>& m, Predicate p) { impl::set_or_map_erase_if(m, p); }
-template <class S, class Predicate> inline
-void set_remove_if(S& set, Predicate p)
-{
- //function compiles and fails (if we're lucky) not before runtime for std::vector!!!
- static_assert(!IsSameType<typename std::iterator_traits<typename S::iterator>::iterator_category, std::random_access_iterator_tag>::value, "poor man's check for non-vector");
+template <class T, class Alloc, class C> inline
+void append(std::vector<T, Alloc>& v, const C& c) { v.insert(v.end(), c.begin(), c.end()); }
- for (auto iter = set.begin(); iter != set.end();)
- if (p(*iter))
- set.erase(iter++);
- else
- ++iter;
-}
+
+template <class T, class LessType, class Alloc, class C> inline
+void append(std::set<T, LessType, Alloc>& s, const C& c) { s.insert(c.begin(), c.end()); }
-template <class M, class Predicate> inline
-void map_remove_if(M& map, Predicate p) { set_remove_if(map, p); }
+template <class KeyType, class ValueType, class LessType, class Alloc, class C> inline
+void append(std::map<KeyType, ValueType, LessType, Alloc>& m, const C& c) { m.insert(c.begin(), c.end()); }
template <class M, class K, class V> inline
@@ -129,6 +128,14 @@ V& map_add_or_update(M& map, const K& key, const V& value) //efficient add or up
}
+template <class T, class Alloc> inline
+void removeDuplicates(std::vector<T, Alloc>& v)
+{
+ std::sort(v.begin(), v.end());
+ v.erase(std::unique(v.begin(), v.end()), v.end());
+}
+
+
template <class ForwardIterator, class T, typename CompLess> inline
ForwardIterator binary_search(ForwardIterator first, ForwardIterator last, const T& value, CompLess less)
{
@@ -190,8 +197,7 @@ bool equal(InputIterator1 first1, InputIterator1 last1,
#if defined _MSC_VER && _MSC_VER <= 1600
- //VS2010 performance bug in std::unordered_set<>: http://drdobbs.com/blogs/cpp/232200410 -> should be fixed in VS11
- static_assert(false, "");
+ static_assert(false, "VS2010 performance bug in std::unordered_set<>: http://drdobbs.com/blogs/cpp/232200410 -> should be fixed in VS11");
#endif
}
diff --git a/zen/symlink_target.h b/zen/symlink_target.h
index aa320dfe..c4557559 100644
--- a/zen/symlink_target.h
+++ b/zen/symlink_target.h
@@ -29,8 +29,8 @@ namespace zen
bool isSymlink(DWORD fileAttributes, DWORD reparseTag);
#endif
-Zstring getResolvedFilePath(const Zstring& linkPath); //throw FileError; Win: requires Vista or later!
-Zstring getSymlinkTargetRaw(const Zstring& linkPath); //throw FileError
+Zstring getResolvedSymlinkPath(const Zstring& linkPath); //throw FileError; Win: requires Vista or later!
+Zstring getSymlinkTargetRaw (const Zstring& linkPath); //throw FileError
}
@@ -153,7 +153,7 @@ Zstring getSymlinkRawTargetString_impl(const Zstring& linkPath) //throw FileErro
}
-Zstring getResolvedFilePath_impl(const Zstring& linkPath) //throw FileError
+Zstring getResolvedSymlinkPath_impl(const Zstring& linkPath) //throw FileError
{
using namespace zen;
#ifdef ZEN_WIN
@@ -211,7 +211,7 @@ inline
Zstring getSymlinkTargetRaw(const Zstring& linkPath) { return getSymlinkRawTargetString_impl(linkPath); }
inline
-Zstring getResolvedFilePath(const Zstring& linkPath) { return getResolvedFilePath_impl(linkPath); }
+Zstring getResolvedSymlinkPath(const Zstring& linkPath) { return getResolvedSymlinkPath_impl(linkPath); }
#ifdef ZEN_WIN
/*
diff --git a/zen/time.h b/zen/time.h
index 9d821a1f..df0f3a54 100644
--- a/zen/time.h
+++ b/zen/time.h
@@ -10,6 +10,7 @@
#include <ctime>
#include "string_tools.h"
+
namespace zen
{
struct TimeComp //replaces "struct std::tm" and SYSTEMTIME
diff --git a/zen/type_tools.h b/zen/type_tools.h
index ac365f05..31384d4c 100644
--- a/zen/type_tools.h
+++ b/zen/type_tools.h
@@ -9,6 +9,7 @@
#include "type_traits.h"
+
namespace zen
{
//########## Strawman Classes ##########################
bgstack15