summaryrefslogtreecommitdiff
path: root/zen/file_traverser.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:23:48 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:23:48 +0200
commitee1c8c5c25d25dfa42120125a8a45dc9831ee412 (patch)
tree67aa287157db954e0cadeee05b4aad331eb2ecf2 /zen/file_traverser.cpp
parent5.13 (diff)
downloadFreeFileSync-ee1c8c5c25d25dfa42120125a8a45dc9831ee412.tar.gz
FreeFileSync-ee1c8c5c25d25dfa42120125a8a45dc9831ee412.tar.bz2
FreeFileSync-ee1c8c5c25d25dfa42120125a8a45dc9831ee412.zip
5.14
Diffstat (limited to 'zen/file_traverser.cpp')
-rw-r--r--zen/file_traverser.cpp32
1 files changed, 29 insertions, 3 deletions
diff --git a/zen/file_traverser.cpp b/zen/file_traverser.cpp
index b39f8416..7093c44a 100644
--- a/zen/file_traverser.cpp
+++ b/zen/file_traverser.cpp
@@ -17,7 +17,11 @@
#include "dll.h"
#include "FindFilePlus/find_file_plus.h"
-#elif defined FFS_LINUX || defined FFS_MAC
+#elif defined FFS_MAC
+#include <zen/osx_string.h>
+#endif
+
+#if defined FFS_LINUX || defined FFS_MAC
#include <sys/stat.h>
#include <dirent.h>
#endif
@@ -284,7 +288,7 @@ struct FilePlusTraverser
*/
if (lastError == ERROR_NOT_SUPPORTED)
{
- fb(); //fallback should apply to whole directory sub-tree!
+ fb(); //fallback should apply to whole directory sub-tree! => client needs to handle duplicate file notifications!
return false;
}
@@ -555,11 +559,30 @@ private:
return;
//don't return "." and ".."
- const char* const shortName = dirEntry->d_name; //evaluate dirEntry *before* going into recursion => we use a single "buffer"!
+ const char* shortName = dirEntry->d_name; //evaluate dirEntry *before* going into recursion => we use a single "buffer"!
if (shortName[0] == '.' &&
(shortName[1] == 0 || (shortName[1] == '.' && shortName[2] == 0)))
continue;
+#ifdef FFS_MAC
+ //some file system abstraction layers fail to properly return decomposed UTF8: http://developer.apple.com/library/mac/#qa/qa1173/_index.html
+ //so we need to do it ourselves; perf: ~600 ns per conversion
+ //note: it's not sufficient to apply this in z_impl::compareFilenamesNoCase: if UTF8 forms differ, FFS assumes a rename in case sensitivity and
+ // will try to propagate the rename => this won't work if target drive reports a particular UTF8 form only!
+ if (CFStringRef cfStr = osx::createCFString(shortName))
+ {
+ ZEN_ON_SCOPE_EXIT(::CFRelease(cfStr));
+ CFIndex lenMax = ::CFStringGetMaximumSizeOfFileSystemRepresentation(cfStr); //"could be much larger than the actual space required" => don't store in Zstring
+ if (lenMax > 0)
+ {
+ bufferUtfDecomposed.resize(lenMax);
+ if (::CFStringGetFileSystemRepresentation(cfStr, &bufferUtfDecomposed[0], lenMax)) //get decomposed UTF form (verified!) despite ambiguous documentation
+ shortName = &bufferUtfDecomposed[0];
+ }
+ }
+ //const char* sampleDecomposed = "\x6f\xcc\x81.txt";
+ //const char* samplePrecomposed = "\xc3\xb3.txt";
+#endif
const Zstring& fullName = appendSeparator(directory) + shortName;
struct ::stat statData = {};
@@ -645,6 +668,9 @@ private:
}
std::vector<char> buffer;
+#ifdef FFS_MAC
+ std::vector<char> bufferUtfDecomposed;
+#endif
};
#endif
}
bgstack15