summaryrefslogtreecommitdiff
path: root/file_hierarchy.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:08:06 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:08:06 +0200
commitfbe76102e941b9f1edaf236788e42678f05fdf9a (patch)
treef5f538316019fa89be8dc478103490c3a826f3ac /file_hierarchy.cpp
parent3.8 (diff)
downloadFreeFileSync-fbe76102e941b9f1edaf236788e42678f05fdf9a.tar.gz
FreeFileSync-fbe76102e941b9f1edaf236788e42678f05fdf9a.tar.bz2
FreeFileSync-fbe76102e941b9f1edaf236788e42678f05fdf9a.zip
3.9
Diffstat (limited to 'file_hierarchy.cpp')
-rw-r--r--file_hierarchy.cpp205
1 files changed, 205 insertions, 0 deletions
diff --git a/file_hierarchy.cpp b/file_hierarchy.cpp
new file mode 100644
index 00000000..e8cb78f0
--- /dev/null
+++ b/file_hierarchy.cpp
@@ -0,0 +1,205 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// **************************************************************************
+//
+#include "file_hierarchy.h"
+#include "shared/build_info.h"
+
+using namespace ffs3;
+
+namespace
+{
+struct LowerID
+{
+ bool operator()(const FileSystemObject& a, HierarchyObject::ObjectID b) const
+ {
+ return a.getId() < b;
+ }
+
+ bool operator()(const FileSystemObject& a, const FileSystemObject& b) const //used by VC++
+ {
+ return a.getId() < b.getId();
+ }
+
+ bool operator()(HierarchyObject::ObjectID a, const FileSystemObject& b) const
+ {
+ return a < b.getId();
+ }
+};
+}
+
+
+const FileSystemObject* HierarchyObject::retrieveById(ObjectID id) const //returns NULL if object is not found
+{
+ //ATTENTION: HierarchyObject::retrieveById() can only work correctly if the following conditions are fulfilled:
+ //1. on each level, files are added first, symlinks, then directories (=> file id < link id < dir id)
+ //2. when a directory is added, all subdirectories must be added immediately (recursion) before the next dir on this level is added
+ //3. entries may be deleted but NEVER new ones inserted!!!
+ //=> this allows for a quasi-binary search by id!
+
+ //See MergeSides::execute()!
+
+
+ //search within sub-files
+ SubFileMapping::const_iterator i = std::lower_bound(subFiles.begin(), subFiles.end(), id, LowerID()); //binary search!
+ if (i != subFiles.end())
+ {
+ //id <= i
+ if (LowerID()(id, *i))
+ return NULL; // --i < id < i
+ else //id found
+ return &(*i);
+ }
+
+ //search within sub-symlinks
+ SubLinkMapping::const_iterator j = std::lower_bound(subLinks.begin(), subLinks.end(), id, LowerID()); //binary search!
+ if (j != subLinks.end())
+ {
+ //id <= i
+ if (LowerID()(id, *j))
+ return NULL; // --i < id < i
+ else //id found
+ return &(*j);
+ }
+
+ //search within sub-directories
+ SubDirMapping::const_iterator k = std::lower_bound(subDirs.begin(), subDirs.end(), id, LowerID()); //binary search!
+ if (k != subDirs.end() && !LowerID()(id, *k)) //id == j
+ return &(*k);
+ else if (k == subDirs.begin()) //either begin() == end() or id < begin()
+ return NULL;
+ else
+ return (--k)->retrieveById(id); //j != begin() and id < j
+}
+
+
+struct IsInvalid
+{
+ bool operator()(const FileSystemObject& fsObj) const
+ {
+ return fsObj.isEmpty();
+ }
+};
+
+
+void FileSystemObject::removeEmptyNonRec(HierarchyObject& hierObj)
+{
+ //remove invalid files:
+ hierObj.useSubFiles().erase(std::remove_if(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), IsInvalid()), hierObj.useSubFiles().end());
+ //remove invalid symlinks:
+ hierObj.useSubLinks().erase(std::remove_if(hierObj.useSubLinks().begin(), hierObj.useSubLinks().end(), IsInvalid()), hierObj.useSubLinks().end());
+ //remove invalid directories:
+ hierObj.useSubDirs(). erase(std::remove_if(hierObj.useSubDirs(). begin(), hierObj.useSubDirs(). end(), IsInvalid()), hierObj.useSubDirs(). end());
+}
+
+
+void removeEmptyRec(HierarchyObject& hierObj)
+{
+ FileSystemObject::removeEmptyNonRec(hierObj);
+
+ //recurse
+ std::for_each(hierObj.useSubDirs().begin(), hierObj.useSubDirs().end(), removeEmptyRec);
+}
+
+
+void FileSystemObject::removeEmpty(BaseDirMapping& baseDir)
+{
+ removeEmptyRec(baseDir);
+}
+
+
+SyncOperation FileSystemObject::getSyncOperation(const CompareFilesResult cmpResult,
+ const bool selectedForSynchronization,
+ const SyncDirectionIntern syncDir)
+{
+ if (!selectedForSynchronization)
+ return cmpResult == FILE_EQUAL ?
+ SO_EQUAL :
+ SO_DO_NOTHING;
+
+ switch (cmpResult)
+ {
+ case FILE_LEFT_SIDE_ONLY:
+ switch (syncDir)
+ {
+ case SYNC_DIR_INT_LEFT:
+ return SO_DELETE_LEFT; //delete files on left
+ case SYNC_DIR_INT_RIGHT:
+ return SO_CREATE_NEW_RIGHT; //copy files to right
+ case SYNC_DIR_INT_NONE:
+ return SO_DO_NOTHING;
+ case SYNC_DIR_INT_CONFLICT:
+ return SO_UNRESOLVED_CONFLICT;
+ }
+ break;
+
+ case FILE_RIGHT_SIDE_ONLY:
+ switch (syncDir)
+ {
+ case SYNC_DIR_INT_LEFT:
+ return SO_CREATE_NEW_LEFT; //copy files to left
+ case SYNC_DIR_INT_RIGHT:
+ return SO_DELETE_RIGHT; //delete files on right
+ case SYNC_DIR_INT_NONE:
+ return SO_DO_NOTHING;
+ case SYNC_DIR_INT_CONFLICT:
+ return SO_UNRESOLVED_CONFLICT;
+ }
+ break;
+
+ case FILE_LEFT_NEWER:
+ case FILE_RIGHT_NEWER:
+ case FILE_DIFFERENT:
+ switch (syncDir)
+ {
+ case SYNC_DIR_INT_LEFT:
+ return SO_OVERWRITE_LEFT; //copy from right to left
+ case SYNC_DIR_INT_RIGHT:
+ return SO_OVERWRITE_RIGHT; //copy from left to right
+ case SYNC_DIR_INT_NONE:
+ return SO_DO_NOTHING;
+ case SYNC_DIR_INT_CONFLICT:
+ return SO_UNRESOLVED_CONFLICT;
+ }
+ break;
+
+ case FILE_CONFLICT:
+ switch (syncDir)
+ {
+ case SYNC_DIR_INT_LEFT:
+ return SO_OVERWRITE_LEFT; //copy from right to left
+ case SYNC_DIR_INT_RIGHT:
+ return SO_OVERWRITE_RIGHT; //copy from left to right
+ case SYNC_DIR_INT_NONE:
+ case SYNC_DIR_INT_CONFLICT:
+ return SO_UNRESOLVED_CONFLICT;
+ }
+ break;
+
+ case FILE_EQUAL:
+ assert(syncDir == SYNC_DIR_INT_NONE);
+ return SO_EQUAL;
+ }
+
+ return SO_DO_NOTHING; //dummy
+}
+
+
+const Zstring& ffs3::getSyncDBFilename()
+{
+ //32 and 64 bit for Linux and Windows builds are binary incompatible! So give them different names
+ //make sure they end with ".ffs_db". These files will not be included into comparison when located in base sync directories
+#ifdef FFS_WIN
+ static Zstring output = Zstring(util::is64BitBuild ?
+ DefaultStr("sync.x64.") :
+ DefaultStr("sync.")) + SYNC_DB_FILE_ENDING;
+#elif defined FFS_LINUX
+ //files beginning with dots are hidden e.g. in Nautilus
+ static Zstring output = Zstring(util::is64BitBuild ?
+ DefaultStr(".sync.x64.") :
+ DefaultStr(".sync.")) + SYNC_DB_FILE_ENDING;
+#endif
+ return output;
+}
bgstack15