summaryrefslogtreecommitdiff
path: root/fileHierarchy.h
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:01:29 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:01:29 +0200
commit9a2a524f1e311853d08050be2dcdddc09ac7759a (patch)
treed8e4a24169fce88c2d89931d58514889a0bcb0ea /fileHierarchy.h
parent2.3 (diff)
downloadFreeFileSync-9a2a524f1e311853d08050be2dcdddc09ac7759a.tar.gz
FreeFileSync-9a2a524f1e311853d08050be2dcdddc09ac7759a.tar.bz2
FreeFileSync-9a2a524f1e311853d08050be2dcdddc09ac7759a.zip
3.0
Diffstat (limited to 'fileHierarchy.h')
-rw-r--r--fileHierarchy.h1361
1 files changed, 765 insertions, 596 deletions
diff --git a/fileHierarchy.h b/fileHierarchy.h
index 755bb97d..0db44c42 100644
--- a/fileHierarchy.h
+++ b/fileHierarchy.h
@@ -4,323 +4,395 @@
#include "shared/zstring.h"
#include "shared/systemConstants.h"
#include <wx/longlong.h>
+#include <map>
#include <set>
#include <vector>
#include "structures.h"
+#include <boost/shared_ptr.hpp>
class DirectoryBuffer;
namespace FreeFileSync
{
- struct FileDescriptor
- {
- FileDescriptor( const Zstring& shortNameIn,
- const wxLongLong& lastWriteTimeRawIn,
- const wxULongLong& fileSizeIn) :
- shortName(shortNameIn),
- lastWriteTimeRaw(lastWriteTimeRawIn),
- fileSize(fileSizeIn) {}
-
- //fullname == baseDirectoryPf + parentRelNamePf + shortName
- Zstring shortName;
- wxLongLong lastWriteTimeRaw; //number of seconds since Jan. 1st 1970 UTC, same semantics like time_t (== signed long)
- wxULongLong fileSize;
- };
-
+struct FileDescriptor
+{
+ FileDescriptor(const wxLongLong& lastWriteTimeRawIn, const wxULongLong& fileSizeIn) :
+ lastWriteTimeRaw(lastWriteTimeRawIn),
+ fileSize(fileSizeIn) {}
+ wxLongLong lastWriteTimeRaw; //number of seconds since Jan. 1st 1970 UTC, same semantics like time_t (== signed long)
+ wxULongLong fileSize;
+};
- struct DirDescriptor
- {
- DirDescriptor(const Zstring& shortNameIn) :
- shortName(shortNameIn) {}
- //fullname == baseDirectoryPf + parentRelNamePf + shortName
- Zstring shortName;
- };
+enum SelectedSide
+{
+ LEFT_SIDE,
+ RIGHT_SIDE
+};
- class FileContainer;
- class FileMapping;
- class DirMapping;
- class CompareProcess;
- class HierarchyObject;
- class BaseDirMapping;
+class FileContainer;
+class FileMapping;
+class DirMapping;
+class CompareProcess;
+class FileSystemObject;
+class BaseDirMapping;
//------------------------------------------------------------------
- /*
- DirContainer FileContainer
+/*
+ DirContainer FileContainer
- ERD:
- DirContainer 1 -----> 0..n DirContainer
- DirContainer 1 -----> 0..n FileContainer
- */
+ERD:
+DirContainer 1 -----> 0..n DirContainer
+DirContainer 1 -----> 0..n FileContainer
+*/
//------------------------------------------------------------------
- class DirContainer
+class DirContainer
+{
+public:
+ void addSubFile(const Zstring& shortName, const FileDescriptor& fileData);
+ DirContainer& addSubDir(const Zstring& shortName);
+
+ //------------------------------------------------------------------
+ struct CmpFilename
{
- public:
- void addSubFile(const FileDescriptor& fileData, const Zstring& parentRelativeNamePf);
- DirContainer& addSubDir(const DirDescriptor& dirData, const Zstring& parentRelativeNamePf);
+ bool operator()(const Zstring& a, const Zstring& b) const;
+ };
- //------------------------------------------------------------------
- template <class T>
- struct CmpLess : public std::binary_function<T, T, bool>
- {
- bool operator()(const T& a, const T& b) const;
- };
+ typedef std::map<Zstring, DirContainer, CmpFilename> SubDirList; //key: shortName
+ typedef std::map<Zstring, FileContainer, CmpFilename> SubFileList; //
+ //------------------------------------------------------------------
- typedef std::set<DirContainer, CmpLess<DirContainer> > SubDirList;
- typedef std::set<FileContainer, CmpLess<FileContainer> > SubFileList;
- //------------------------------------------------------------------
+ const SubDirList& getSubDirs() const;
+ const SubFileList& getSubFiles() const;
- const DirDescriptor& getData() const;
- const Zstring& getParentRelNamePf() const;
+ DirContainer() {} //default constructor use for base directory only!
- const SubDirList& getSubDirs() const;
- const SubFileList& getSubFiles() const;
+private:
+ SubDirList subDirs; //contained directories
+ SubFileList subFiles; //contained files
+};
- private:
- friend class CompareProcess; //only DirectoryBuffer is allowed to create (Base-)DirContainers
+//------------------------------------------------------------------
+class FileContainer
+{
+public:
+ const FileDescriptor& getData() const;
- DirContainer(const DirDescriptor& dirData, const Zstring& parentRelativeNamePf) :
- data(dirData),
- parentRelNamePf(parentRelativeNamePf) {}
+private:
+ friend class DirContainer;
- DirContainer() : data(Zstring()) {} //default constructor used by DirectoryBuffer only!
+ FileContainer(const FileDescriptor& fileData) :
+ data(fileData) {}
- const DirDescriptor data;
- const Zstring parentRelNamePf; //buffer some redundant data:
+ const FileDescriptor data;
+};
- SubDirList subDirs; //contained directories
- SubFileList subFiles; //contained files
- };
//------------------------------------------------------------------
- class FileContainer
- {
- public:
- const FileDescriptor& getData() const;
- const Zstring& getParentRelNamePf() const;
-
- private:
- friend class DirContainer;
-
- FileContainer(const FileDescriptor& fileData, const Zstring& parentRelativeNamePf) :
- data(fileData),
- parentRelNamePf(parentRelativeNamePf) {}
+struct DirInformation
+{
+ //filter settings (used when retrieving directory data)
+ bool filterActive;
+ Zstring includeFilter;
+ Zstring excludeFilter;
+ //hierarchical directory information
+ DirContainer baseDirContainer;
+};
- const FileDescriptor data;
- const Zstring parentRelNamePf; //buffer some redundant data:
- };
+//save/load full directory information
+const Zstring& getSyncDBFilename(); //get short filename of database file
+void saveToDisk(const BaseDirMapping& baseMapping, SelectedSide side, const Zstring& filename); //throw (FileError) -> return value always bound!
+boost::shared_ptr<const DirInformation> loadFromDisk(const Zstring& filename); //throw (FileError)
//------------------------------------------------------------------
- /* class hierarchy:
+/* class hierarchy:
- FileSystemObject HierarchyObject
- /|\ /|\
- ______|______ ______|______
- | | | |
- FileMapping DirMapping BaseDirMapping
- */
+ FileSystemObject HierarchyObject
+ /|\ /|\
+ ______|______ ______|______
+ | | | |
+FileMapping DirMapping BaseDirMapping
+*/
//------------------------------------------------------------------
- enum SelectedSide
+class HierarchyObject
+{
+public:
+ typedef unsigned int ObjectID;
+ FileSystemObject* retrieveById(ObjectID id); //returns NULL if object is not found; logarithmic complexity
+ const FileSystemObject* retrieveById(ObjectID id) const; //
+
+ DirMapping& addSubDir(bool existsLeft,
+ const Zstring& dirNameShort,
+ bool existsRight);
+
+ FileMapping& addSubFile(const FileDescriptor& left, //file exists on both sides
+ const Zstring& fileNameShort,
+ CompareFilesResult defaultCmpResult,
+ const FileDescriptor& right);
+ void addSubFile(const FileDescriptor& left, //file exists on left side only
+ const Zstring& fileNameShort);
+ void addSubFile(const Zstring& fileNameShort, //file exists on right side only
+ const FileDescriptor& right);
+
+ const Zstring& getRelativeNamePf() const; //get name relative to base sync dir with FILE_NAME_SEPARATOR postfix: "blah\"
+ template <SelectedSide side> const Zstring& getBaseDir() const //postfixed!
{
- LEFT_SIDE,
- RIGHT_SIDE
- };
+ return side == LEFT_SIDE ? baseDirLeft : baseDirRight;
+ }
+
+ typedef std::vector<FileMapping> SubFileMapping;
+ typedef std::vector<DirMapping> SubDirMapping;
+
+ SubFileMapping subFiles; //contained file maps
+ SubDirMapping subDirs; //contained directory maps
+
+protected:
+ //constructor used by DirMapping
+ HierarchyObject(const HierarchyObject& parent, const Zstring& shortName) :
+ relNamePf(parent.getRelativeNamePf() + shortName + globalFunctions::FILE_NAME_SEPARATOR),
+ baseDirLeft(parent.getBaseDir<LEFT_SIDE>()),
+ baseDirRight(parent.getBaseDir<RIGHT_SIDE>()) {}
+
+ //constructor used by BaseDirMapping
+ HierarchyObject(const Zstring& dirPostfixedLeft,
+ const Zstring& dirPostfixedRight) :
+ baseDirLeft(dirPostfixedLeft),
+ baseDirRight(dirPostfixedRight) {}
+ ~HierarchyObject() {} //don't need polymorphic deletion
+
+ virtual void swap();
+
+private:
+ Zstring relNamePf;
+ Zstring baseDirLeft; //directory name ending with FILE_NAME_SEPARATOR
+ Zstring baseDirRight; //directory name ending with FILE_NAME_SEPARATOR
+};
- struct RelNamesBuffered
- {
- RelNamesBuffered(const Zstring& baseDirPfLIn, //base sync dir postfixed
- const Zstring& baseDirPfRIn,
- const Zstring& parentRelNamePfIn) : //relative parent name postfixed
- baseDirPfL(baseDirPfLIn),
- baseDirPfR(baseDirPfRIn),
- parentRelNamePf(parentRelNamePfIn) {}
-
- Zstring baseDirPfL;
- Zstring baseDirPfR;
- Zstring parentRelNamePf;
- };
//------------------------------------------------------------------
- class FileSystemObject
- {
- public:
- typedef unsigned int ObjectID;
- template <SelectedSide side> bool isEmpty() const;
- template <SelectedSide side> const Zstring& getShortName() const;
- template <SelectedSide side> const Zstring getRelativeName() const; //get name relative to base sync dir without FILE_NAME_SEPARATOR prefix
- template <SelectedSide side> const Zstring getParentRelativeName() const; //get name relative to base sync dir without FILE_NAME_SEPARATOR postfix
- template <SelectedSide side> const Zstring getFullName() const; //getFullName() == getBaseDirPf() + getRelativeName()
- template <SelectedSide side> const Zstring& getBaseDirPf() const; //base sync directory postfixed with FILE_NAME_SEPARATOR
- ObjectID getId() const; //get unique id; ^= logical key
-
- void swap();
-
- template <SelectedSide side> void copyTo(); //copy one side to the other (NOT recursive!!!)
- template <SelectedSide side> void removeObject(); //removes file or directory (recursively!): used by manual deletion
- bool isEmpty() const; //true, if both sides are empty
- static void removeEmpty(BaseDirMapping& baseDir); //remove all invalid entries (where both sides are empty) recursively
- static void removeEmptyNonRec(HierarchyObject& hierObj); //remove all invalid entries (where both sides are empty) non-recursively
-
- //sync settings:
- SyncDirection syncDir;
- bool selectedForSynchronization;
-
- virtual CompareFilesResult getCategory() const = 0;
- virtual const wxString& getConflictDescription() const = 0;
-
- protected:
- FileSystemObject(const RelNamesBuffered& relNameBuff) :
- syncDir(SYNC_DIR_NONE),
- selectedForSynchronization(true),
- nameBuffer(relNameBuff),
- uniqueId(getUniqueId()) {}
-
- ~FileSystemObject() {} //don't need polymorphic deletion
-
- private:
- virtual void swapDescriptors() = 0;
-
- virtual bool isEmptyL() const = 0;
- virtual bool isEmptyR() const = 0;
- virtual void removeObjectL() = 0;
- virtual void removeObjectR() = 0;
- virtual void copyToL() = 0;
- virtual void copyToR() = 0;
- virtual const Zstring& getShortNameL() const = 0;
- virtual const Zstring& getShortNameR() const = 0;
- static ObjectID getUniqueId();
-
- //buffer some redundant data:
- RelNamesBuffered nameBuffer; //base sync dirs + relative parent name: this does NOT belong into FileDescriptor/DirDescriptor
-
- ObjectID uniqueId;
- };
+struct RelNamesBuffered
+{
+ RelNamesBuffered(const Zstring& baseDirPfLIn, //base sync dir postfixed
+ const Zstring& baseDirPfRIn,
+ const Zstring& parentRelNamePfIn) : //relative parent name postfixed
+ baseDirPfL(baseDirPfLIn),
+ baseDirPfR(baseDirPfRIn),
+ parentRelNamePf(parentRelNamePfIn) {}
+
+ Zstring baseDirPfL;
+ Zstring baseDirPfR;
+ Zstring parentRelNamePf;
+};
+
//------------------------------------------------------------------
- class HierarchyObject
- {
- public:
- FileSystemObject* retrieveById(FileSystemObject::ObjectID id); //returns NULL if object is not found; logarithmic complexity
- const FileSystemObject* retrieveById(FileSystemObject::ObjectID id) const; //
-
- DirMapping& addSubDir(const DirDescriptor& left,
- CompareDirResult defaultCmpResult,
- const DirDescriptor& right,
- const RelNamesBuffered& relNameBuff);
- FileMapping& addSubFile(const FileDescriptor& left,
- CompareFilesResult defaultCmpResult,
- const FileDescriptor& right,
- const RelNamesBuffered& relNameBuff);
-
- typedef std::vector<FileMapping> SubFileMapping;
- typedef std::vector<DirMapping> SubDirMapping;
-
- SubFileMapping subFiles; //contained file maps
- SubDirMapping subDirs; //contained directory maps
-
- protected:
- HierarchyObject() {}
- ~HierarchyObject() {} //don't need polymorphic deletion
+class FileSystemObject
+{
+public:
+ const Zstring getParentRelativeName() const; //get name relative to base sync dir without FILE_NAME_SEPARATOR postfix
+ const Zstring getObjRelativeName() const; //same as getRelativeName() but also returns value if either side is empty
+ const Zstring& getObjShortName() const; //same as getShortName() but also returns value if either side is empty
+ template <SelectedSide side> bool isEmpty() const;
+ template <SelectedSide side> const Zstring& getShortName() const;
+ template <SelectedSide side> const Zstring getRelativeName() const; //get name relative to base sync dir without FILE_NAME_SEPARATOR prefix
+ template <SelectedSide side> const Zstring getFullName() const; //getFullName() == getBaseDirPf() + getRelativeName()
+ template <SelectedSide side> const Zstring& getBaseDirPf() const; //base sync directory postfixed with FILE_NAME_SEPARATOR
+
+ HierarchyObject::ObjectID getId() const; //get unique id; ^= logical key
+
+ //comparison result
+ virtual CompareFilesResult getCategory() const = 0;
+ virtual const wxString& getCatConflict() const = 0; //only filled if cmpResult == FILE_CONFLICT
+ //sync operation
+ SyncOperation getSyncOperation() const;
+ const wxString& getSyncOpConflict() const; //only filled if syncDir == SYNC_DIR_INT_CONFLICT
+ SyncOperation testSyncOperation(bool selected, SyncDirection syncDir) const; //get syncOp with provided settings
+
+ //sync settings
+ void setSyncDir(SyncDirection newDir);
+ void setSyncDirConflict(const wxString& description); //set syncDir = SYNC_DIR_INT_CONFLICT
+
+ bool isActive() const;
+ void setActive(bool active);
+
+ void synchronizeSides(); //copy one side to the other (NOT recursive!!!)
+ template <SelectedSide side> void removeObject(); //removes file or directory (recursively!): used by manual deletion
+ bool isEmpty() const; //true, if both sides are empty
+ static void removeEmpty(BaseDirMapping& baseDir); //remove all invalid entries (where both sides are empty) recursively
+ static void removeEmptyNonRec(HierarchyObject& hierObj); //remove all invalid entries (where both sides are empty) non-recursively
+
+protected:
+ FileSystemObject(bool existsLeft, bool existsRight, const Zstring& shortName, const HierarchyObject& parent) :
+ selectedForSynchronization(true),
+ syncDir(SYNC_DIR_INT_NONE),
+ nameBuffer(parent.getBaseDir<LEFT_SIDE>(), parent.getBaseDir<RIGHT_SIDE>(), parent.getRelativeNamePf()),
+ existsLeft_(existsLeft),
+ existsRight_(existsRight),
+ shortName_(shortName),
+ uniqueId(getUniqueId()) {}
+
+ ~FileSystemObject() {} //don't need polymorphic deletion
+
+ virtual void swap();
+
+private:
+ virtual void removeObjectL() = 0;
+ virtual void removeObjectR() = 0;
+ virtual void copyToL() = 0;
+ virtual void copyToR() = 0;
+ static HierarchyObject::ObjectID getUniqueId();
+
+ enum SyncDirectionIntern //same as SyncDirection, but one additional conflict type
+ {
+ SYNC_DIR_INT_LEFT = SYNC_DIR_LEFT,
+ SYNC_DIR_INT_RIGHT = SYNC_DIR_RIGHT,
+ SYNC_DIR_INT_NONE = SYNC_DIR_NONE,
+ SYNC_DIR_INT_CONFLICT //set if automatic synchronization cannot determine a direction
};
+ static SyncOperation getSyncOperation(const CompareFilesResult cmpResult,
+ const bool selectedForSynchronization,
+ const SyncDirectionIntern syncDir); //evaluate comparison result and sync direction
+
+ bool selectedForSynchronization;
+ SyncDirectionIntern syncDir;
+ wxString syncOpConflictDescr; //only filled if syncDir == SYNC_DIR_INT_CONFLICT
+
+
+ //buffer some redundant data:
+ RelNamesBuffered nameBuffer; //base sync dirs + relative parent name: this does NOT belong into FileDescriptor/DirDescriptor
+
+ bool existsLeft_;
+ bool existsRight_;
+ Zstring shortName_;
+ HierarchyObject::ObjectID uniqueId;
+};
//------------------------------------------------------------------
- class DirMapping : public FileSystemObject, public HierarchyObject
- {
- public:
- static const DirDescriptor& nullData();
-
- virtual CompareFilesResult getCategory() const;
- virtual const wxString& getConflictDescription() const;
-
- private:
- friend class CompareProcess; //only CompareProcess shall be allowed to change cmpResult
- friend class HierarchyObject;
- virtual void swapDescriptors();
- virtual bool isEmptyL() const;
- virtual bool isEmptyR() const;
- virtual void removeObjectL();
- virtual void removeObjectR();
- virtual void copyToL();
- virtual void copyToR();
- virtual const Zstring& getShortNameL() const;
- virtual const Zstring& getShortNameR() const;
- //------------------------------------------------------------------
-
- DirMapping(const DirDescriptor& left, CompareDirResult defaultCmpResult, const DirDescriptor& right, const RelNamesBuffered& relNameBuff) :
- FileSystemObject(relNameBuff),
- cmpResult(defaultCmpResult),
- dataLeft(left),
- dataRight(right) {}
-
- //categorization
- CompareDirResult cmpResult;
-
- DirDescriptor dataLeft;
- DirDescriptor dataRight;
- };
+class DirMapping : public FileSystemObject, public HierarchyObject
+{
+public:
+ virtual CompareFilesResult getCategory() const;
+ CompareDirResult getDirCategory() const; //returns actually used subsed of CompareFilesResult
+ virtual const wxString& getCatConflict() const;
+
+private:
+ friend class CompareProcess; //only CompareProcess shall be allowed to change cmpResult
+ friend class HierarchyObject;
+ virtual void swap();
+ virtual void removeObjectL();
+ virtual void removeObjectR();
+ virtual void copyToL();
+ virtual void copyToR();
+ //------------------------------------------------------------------
+
+ DirMapping(bool existsLeft,
+ const Zstring& dirNameShort,
+ bool existsRight,
+ const HierarchyObject& parent) :
+ FileSystemObject(existsLeft, existsRight, dirNameShort, parent),
+ HierarchyObject(parent, dirNameShort),
+ cmpResult(!existsRight ? DIR_LEFT_SIDE_ONLY : existsLeft ? DIR_EQUAL : DIR_RIGHT_SIDE_ONLY) {}
+
+ //categorization
+ CompareDirResult cmpResult;
+};
//------------------------------------------------------------------
- class FileMapping : public FileSystemObject
- {
- public:
- template <SelectedSide side> const wxLongLong& getLastWriteTime() const;
- template <SelectedSide side> const wxULongLong& getFileSize() const;
-
- static const FileDescriptor& nullData();
-
- virtual CompareFilesResult getCategory() const;
- virtual const wxString& getConflictDescription() const;
-
- private:
- friend class CompareProcess; //only CompareProcess shall be allowed to change cmpResult
- friend class HierarchyObject;
-
- FileMapping(const FileDescriptor& left, CompareFilesResult defaultCmpResult, const FileDescriptor& right, const RelNamesBuffered& relNameBuff) :
- FileSystemObject(relNameBuff),
- cmpResult(defaultCmpResult),
- dataLeft(left),
- dataRight(right) {}
-
- virtual void swapDescriptors();
- virtual bool isEmptyL() const;
- virtual bool isEmptyR() const;
- virtual void removeObjectL();
- virtual void removeObjectR();
- virtual void copyToL();
- virtual void copyToR();
- virtual const Zstring& getShortNameL() const;
- virtual const Zstring& getShortNameR() const;
- //------------------------------------------------------------------
-
- //categorization
- CompareFilesResult cmpResult;
- wxString conflictDescription; //only filled if cmpResult == FILE_CONFLICT
-
- FileDescriptor dataLeft;
- FileDescriptor dataRight;
- };
+class FileMapping : public FileSystemObject
+{
+public:
+ template <SelectedSide side> const wxLongLong& getLastWriteTime() const;
+ template <SelectedSide side> const wxULongLong& getFileSize() const;
+
+ virtual CompareFilesResult getCategory() const;
+ virtual const wxString& getCatConflict() const;
+
+private:
+ friend class CompareProcess; //only CompareProcess shall be allowed to change cmpResult
+ friend class HierarchyObject; //construction
+
+ template <CompareFilesResult res>
+ void setCategory();
+ void setCategoryConflict(const wxString& description);
+
+ FileMapping(const FileDescriptor& left, //file exists on both sides
+ const Zstring& fileNameShort,
+ CompareFilesResult defaultCmpResult,
+ const FileDescriptor& right,
+ const HierarchyObject& parent) :
+ FileSystemObject(true, true, fileNameShort, parent),
+ cmpResult(defaultCmpResult),
+ dataLeft(left),
+ dataRight(right) {}
+ FileMapping(const FileDescriptor& left, //file exists on left side only
+ const Zstring& fileNameShort,
+ const HierarchyObject& parent) :
+ FileSystemObject(true, false, fileNameShort, parent),
+ cmpResult(FILE_LEFT_SIDE_ONLY),
+ dataLeft(left),
+ dataRight(0, 0) {}
+ FileMapping(const Zstring& fileNameShort, //file exists on right side only
+ const FileDescriptor& right,
+ const HierarchyObject& parent) :
+ FileSystemObject(false, true, fileNameShort, parent),
+ cmpResult(FILE_RIGHT_SIDE_ONLY),
+ dataLeft(0, 0),
+ dataRight(right) {}
+
+ virtual void swap();
+ virtual void removeObjectL();
+ virtual void removeObjectR();
+ virtual void copyToL();
+ virtual void copyToR();
+ //------------------------------------------------------------------
+
+ //categorization
+ CompareFilesResult cmpResult;
+ wxString cmpConflictDescr; //only filled if cmpResult == FILE_CONFLICT
+
+ FileDescriptor dataLeft;
+ FileDescriptor dataRight;
+};
//------------------------------------------------------------------
- class BaseDirMapping : public HierarchyObject //synchronization base directory
- {
- public:
- BaseDirMapping(const Zstring& dirPostfixedLeft, const Zstring& dirPostfixedRight) :
- baseDirLeft(dirPostfixedLeft),
- baseDirRight(dirPostfixedRight) {}
+class BaseDirMapping : public HierarchyObject //synchronization base directory
+{
+public:
+ BaseDirMapping(const Zstring& dirPostfixedLeft,
+ const Zstring& dirPostfixedRight,
+ bool filterActive,
+ const Zstring& includeFilter,
+ const Zstring& excludeFilter) :
+ HierarchyObject(dirPostfixedLeft, dirPostfixedRight),
+ filter(filterActive, includeFilter, excludeFilter) {}
+
+ struct FilterSettings
+ {
+ FilterSettings(bool active,
+ const Zstring& include,
+ const Zstring& exclude) :
+ filterActive(active),
+ includeFilter(include),
+ excludeFilter(exclude) {}
+ bool filterActive;
+ Zstring includeFilter;
+ Zstring excludeFilter;
+ };
- template <SelectedSide side> const Zstring& getBaseDir() const;
+ const FilterSettings& getFilter() const;
+ template <SelectedSide side> Zstring getDBFilename() const;
+ virtual void swap();
- private:
- Zstring baseDirLeft; //directory name ending with FILE_NAME_SEPARATOR
- Zstring baseDirRight; //directory name ending with FILE_NAME_SEPARATOR
- };
+private:
+ FilterSettings filter;
+};
- typedef std::vector<BaseDirMapping> FolderComparison;
+typedef std::vector<BaseDirMapping> FolderComparison;
//------------------------------------------------------------------
@@ -343,33 +415,32 @@ namespace FreeFileSync
//---------------Inline Implementation---------------------------------------------------
- inline
- FileSystemObject* HierarchyObject::retrieveById(FileSystemObject::ObjectID id) //returns NULL if object is not found
- {
- //code re-use of const method: see Meyers Effective C++
- return const_cast<FileSystemObject*>(static_cast<const HierarchyObject&>(*this).retrieveById(id));
- }
+inline
+FileSystemObject* HierarchyObject::retrieveById(ObjectID id) //returns NULL if object is not found
+{
+ //code re-use of const method: see Meyers Effective C++
+ return const_cast<FileSystemObject*>(static_cast<const HierarchyObject&>(*this).retrieveById(id));
+}
- inline
- FileSystemObject::ObjectID FileSystemObject::getId() const
- {
- return uniqueId;
- }
+inline
+HierarchyObject::ObjectID FileSystemObject::getId() const
+{
+ return uniqueId;
+}
- inline
- FileSystemObject::ObjectID FileSystemObject::getUniqueId()
- {
- static unsigned int id = 0;
- return ++id;
- }
+inline
+HierarchyObject::ObjectID FileSystemObject::getUniqueId()
+{
+ static unsigned int id = 0;
+ return ++id;
+}
- template <class T>
- inline
- bool DirContainer::CmpLess<T>::operator()(const T& a, const T& b) const
- {
+inline
+bool DirContainer::CmpFilename::operator()(const Zstring& a, const Zstring& b) const
+{
// //quick check based on string length
// const size_t aLength = a.data.shortName.length();
// const size_t bLength = b.data.shortName.length();
@@ -377,418 +448,516 @@ namespace FreeFileSync
// return aLength < bLength;
#ifdef FFS_WIN //Windows does NOT distinguish between upper/lower-case
- return a.data.shortName.CmpNoCase(b.data.shortName) < 0;
+ return a.CmpNoCase(b) < 0;
#elif defined FFS_LINUX //Linux DOES distinguish between upper/lower-case
- return a.data.shortName.Cmp(b.data.shortName) < 0;
+ return a.Cmp(b) < 0;
#endif
- }
+}
+inline
+const DirContainer::SubDirList& DirContainer::getSubDirs() const
+{
+ return subDirs;
+}
- inline
- const DirDescriptor& DirContainer::getData() const
- {
- return data;
- }
+inline
+const DirContainer::SubFileList& DirContainer::getSubFiles() const
+{
+ return subFiles;
+}
- inline
- const Zstring& DirContainer::getParentRelNamePf() const
- {
- return parentRelNamePf;
- }
+inline
+const FileDescriptor& FileContainer::getData() const
+{
+ return data;
+}
- inline
- const DirContainer::SubDirList& DirContainer::getSubDirs() const
- {
- return subDirs;
- }
+inline
+DirContainer& DirContainer::addSubDir(const Zstring& shortName)
+{
+ return subDirs.insert(std::make_pair(shortName, DirContainer())).first->second;
+}
- inline
- const DirContainer::SubFileList& DirContainer::getSubFiles() const
- {
- return subFiles;
- }
+inline
+void DirContainer::addSubFile(const Zstring& shortName, const FileDescriptor& fileData)
+{
+ subFiles.insert(std::make_pair(shortName, FileContainer(fileData)));
+}
- inline
- const FileDescriptor& FileContainer::getData() const
- {
- return data;
- }
+inline
+CompareFilesResult FileMapping::getCategory() const
+{
+ return cmpResult;
+}
- inline
- const Zstring& FileContainer::getParentRelNamePf() const
- {
- return parentRelNamePf;
- }
+inline
+const wxString& FileMapping::getCatConflict() const
+{
+ return cmpConflictDescr;
+}
- inline
- DirContainer& DirContainer::addSubDir(const DirDescriptor& dirData, const Zstring& parentRelativeNamePf)
- {
- //const cast: another crime in the name of unproven performance optimization ;) however key part cannot be changed, so this should be safe
- return const_cast<DirContainer&>(*subDirs.insert(DirContainer(dirData, parentRelativeNamePf)).first);
- }
+inline
+CompareFilesResult DirMapping::getCategory() const
+{
+ return convertToFilesResult(cmpResult);
+}
- inline
- void DirContainer::addSubFile(const FileDescriptor& fileData, const Zstring& parentRelativeNamePf)
- {
- subFiles.insert(FileContainer(fileData, parentRelativeNamePf));
- }
+inline
+CompareDirResult DirMapping::getDirCategory() const
+{
+ return cmpResult;
+}
- inline
- CompareFilesResult FileMapping::getCategory() const
- {
- return cmpResult;
- }
+inline
+const wxString& DirMapping::getCatConflict() const
+{
+ static wxString empty;
+ return empty;
+}
- inline
- const wxString& FileMapping::getConflictDescription() const
- {
- return conflictDescription;
- }
+inline
+void FileSystemObject::setSyncDir(SyncDirection newDir)
+{
+ syncDir = static_cast<SyncDirectionIntern>(newDir); //should be safe by design
+}
- inline
- CompareFilesResult DirMapping::getCategory() const
- {
- return convertToFilesResult(cmpResult);
- }
+inline
+const wxString& FileSystemObject::getSyncOpConflict() const
+{
+ //a sync operation conflict can occur when:
+ //1. category-conflict and syncDir == NONE -> problem finding category
+ //2. syncDir == SYNC_DIR_INT_CONFLICT -> problem finding sync direction
+ return syncDir == SYNC_DIR_INT_CONFLICT ? syncOpConflictDescr : getCatConflict();
+}
- inline
- const wxString& DirMapping::getConflictDescription() const
- {
- static wxString empty;
- return empty;
- }
+inline
+void FileSystemObject::setSyncDirConflict(const wxString& description) //set syncDir = SYNC_DIR_INT_CONFLICT
+{
+ syncDir = SYNC_DIR_INT_CONFLICT;
+ syncOpConflictDescr = description;
+}
- template <SelectedSide side>
- inline
- bool FileSystemObject::isEmpty() const
- {
- return side == LEFT_SIDE ? isEmptyL() : isEmptyR();
- }
+inline
+bool FileSystemObject::isActive() const
+{
+ return selectedForSynchronization;
+}
- inline
- bool FileSystemObject::isEmpty() const
- {
- return isEmptyL() && isEmptyR();
- }
+inline
+void FileSystemObject::setActive(bool active)
+{
+ selectedForSynchronization = active;
+}
- template <SelectedSide side>
- inline
- const Zstring& FileSystemObject::getShortName() const
- {
- return side == LEFT_SIDE ? getShortNameL() : getShortNameR();
- }
+inline
+SyncOperation FileSystemObject::getSyncOperation() const
+{
+ return getSyncOperation(getCategory(), selectedForSynchronization, syncDir);
+}
- template <SelectedSide side>
- inline
- const Zstring FileSystemObject::getRelativeName() const
- {
- return isEmpty<side>() ? Zstring() : nameBuffer.parentRelNamePf + getShortName<side>();
- }
+inline
+SyncOperation FileSystemObject::testSyncOperation(bool selected, SyncDirection proposedDir) const
+{
+ return getSyncOperation(getCategory(), selected, static_cast<SyncDirectionIntern>(proposedDir)); //should be safe by design
+}
- template <SelectedSide side>
- inline
- const Zstring FileSystemObject::getParentRelativeName() const
- {
- return nameBuffer.parentRelNamePf.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR); //returns empty string if char not found
- }
+template <>
+inline
+bool FileSystemObject::isEmpty<LEFT_SIDE>() const
+{
+ return !existsLeft_;
+}
- template <SelectedSide side>
- inline
- const Zstring FileSystemObject::getFullName() const
- {
- return isEmpty<side>() ? Zstring() : getBaseDirPf<side>() + nameBuffer.parentRelNamePf + getShortName<side>();
- }
+template <>
+inline
+bool FileSystemObject::isEmpty<RIGHT_SIDE>() const
+{
+ return !existsRight_;
+}
- template <SelectedSide side>
- inline
- const Zstring& FileSystemObject::getBaseDirPf() const
- {
- return side == LEFT_SIDE ? nameBuffer.baseDirPfL : nameBuffer.baseDirPfR;
- }
+inline
+bool FileSystemObject::isEmpty() const
+{
+ return isEmpty<LEFT_SIDE>() && isEmpty<RIGHT_SIDE>();
+}
- template <SelectedSide side>
- inline
- void FileSystemObject::removeObject()
- {
- if (side == LEFT_SIDE)
- removeObjectL();
- else
- removeObjectR();
- }
+template <SelectedSide side>
+inline
+const Zstring& FileSystemObject::getShortName() const
+{
+ static Zstring null;
+ return isEmpty<side>() ? null : shortName_;
+}
- template <SelectedSide side>
- inline
- void FileSystemObject::copyTo()
- {
- syncDir = SYNC_DIR_NONE;
- if (side == LEFT_SIDE)
- copyToL();
- else
- copyToR();
- }
+template <SelectedSide side>
+inline
+const Zstring FileSystemObject::getRelativeName() const
+{
+ return isEmpty<side>() ? Zstring() : nameBuffer.parentRelNamePf + shortName_;
+}
- inline
- void FileSystemObject::swap()
- {
- //swap file descriptors
- swapDescriptors();
- }
+inline
+const Zstring FileSystemObject::getObjRelativeName() const
+{
+ return nameBuffer.parentRelNamePf + shortName_;
+}
- inline
- DirMapping& HierarchyObject::addSubDir(const DirDescriptor& left,
- CompareDirResult defaultCmpResult,
- const DirDescriptor& right,
- const RelNamesBuffered& relNameBuff)
- {
- subDirs.push_back(DirMapping(left, defaultCmpResult, right, relNameBuff));
- return subDirs.back();
- }
+inline
+const Zstring& FileSystemObject::getObjShortName() const
+{
+ return shortName_;
+}
- inline
- FileMapping& HierarchyObject::addSubFile(const FileDescriptor& left,
- CompareFilesResult defaultCmpResult,
- const FileDescriptor& right,
- const RelNamesBuffered& relNameBuff)
- {
- subFiles.push_back(FileMapping(left, defaultCmpResult, right, relNameBuff));
- return subFiles.back();
- }
+inline
+const Zstring FileSystemObject::getParentRelativeName() const
+{
+ return nameBuffer.parentRelNamePf.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR); //returns empty string if char not found
+}
- inline
- void DirMapping::swapDescriptors()
- {
- //swap compare result
- switch (cmpResult)
- {
- case DIR_LEFT_SIDE_ONLY:
- cmpResult = DIR_RIGHT_SIDE_ONLY;
- break;
- case DIR_RIGHT_SIDE_ONLY:
- cmpResult = DIR_LEFT_SIDE_ONLY;
- break;
- case DIR_EQUAL:
- break;
- }
-
- std::swap(dataLeft, dataRight);
- }
+template <SelectedSide side>
+inline
+const Zstring FileSystemObject::getFullName() const
+{
+ return isEmpty<side>() ? Zstring() : getBaseDirPf<side>() + nameBuffer.parentRelNamePf + shortName_;
+}
- inline
- const DirDescriptor& DirMapping::nullData()
- {
- static DirDescriptor output( static_cast<Zstring>(Zstring()));
- return output;
- }
+template <>
+inline
+const Zstring& FileSystemObject::getBaseDirPf<LEFT_SIDE>() const
+{
+ return nameBuffer.baseDirPfL;
+}
- inline
- void DirMapping::removeObjectL()
- {
- cmpResult = DIR_RIGHT_SIDE_ONLY;
- dataLeft = nullData();
- std::for_each(subFiles.begin(), subFiles.end(), std::mem_fun_ref(&FileSystemObject::removeObject<LEFT_SIDE>));
- std::for_each(subDirs.begin(), subDirs.end(), std::mem_fun_ref(&FileSystemObject::removeObject<LEFT_SIDE>));
- }
+template <>
+inline
+const Zstring& FileSystemObject::getBaseDirPf<RIGHT_SIDE>() const
+{
+ return nameBuffer.baseDirPfR;
+}
- inline
- void DirMapping::removeObjectR()
- {
- cmpResult = DIR_LEFT_SIDE_ONLY;
- dataRight = nullData();
- std::for_each(subFiles.begin(), subFiles.end(), std::mem_fun_ref(&FileSystemObject::removeObject<RIGHT_SIDE>));
- std::for_each(subDirs.begin(), subDirs.end(), std::mem_fun_ref(&FileSystemObject::removeObject<RIGHT_SIDE>));
- }
+template <>
+inline
+void FileSystemObject::removeObject<LEFT_SIDE>()
+{
+ existsLeft_ = false;
+ removeObjectL();
+}
- inline
- void DirMapping::copyToL()
- {
- cmpResult = DIR_EQUAL;
- dataLeft = dataRight;
- }
+template <>
+inline
+void FileSystemObject::removeObject<RIGHT_SIDE>()
+{
+ existsRight_ = false;
+ removeObjectR();
+}
- inline
- void DirMapping::copyToR()
- {
- cmpResult = DIR_EQUAL;
- dataRight = dataLeft;
- }
+inline
+void FileSystemObject::synchronizeSides()
+{
+ switch (syncDir)
+ {
+ case SYNC_DIR_INT_LEFT:
+ existsLeft_ = existsRight_;
+ copyToL();
+ break;
+ case SYNC_DIR_INT_RIGHT:
+ existsRight_ = existsLeft_;
+ copyToR();
+ break;
+ case SYNC_DIR_INT_NONE:
+ case SYNC_DIR_INT_CONFLICT:
+ assert(!"if nothing's todo then why arrive here?");
+ break;
+ }
+
+ syncDir = SYNC_DIR_INT_NONE;
+}
- inline
- const Zstring& DirMapping::getShortNameL() const
- {
- return dataLeft.shortName;
- }
+inline
+void FileSystemObject::swap()
+{
+ std::swap(nameBuffer.baseDirPfL, nameBuffer.baseDirPfR);
+ std::swap(existsLeft_, existsRight_);
+}
- inline
- const Zstring& DirMapping::getShortNameR() const
- {
- return dataRight.shortName;
- }
+inline
+void HierarchyObject::swap()
+{
+ std::swap(baseDirLeft, baseDirRight);
+ //files
+ std::for_each(subFiles.begin(), subFiles.end(), std::mem_fun_ref(&FileMapping::swap));
+ //directories
+ std::for_each(subDirs.begin(), subDirs.end(), std::mem_fun_ref(&DirMapping::swap));
+}
- inline
- bool DirMapping::isEmptyL() const
- {
- return dataLeft.shortName.empty();
- }
+inline
+const Zstring& HierarchyObject::getRelativeNamePf() const
+{
+ return relNamePf;
+}
- inline
- bool DirMapping::isEmptyR() const
- {
- return dataRight.shortName.empty();
- }
+inline
+DirMapping& HierarchyObject::addSubDir(bool existsLeft,
+ const Zstring& dirNameShort,
+ bool existsRight)
+{
+ subDirs.push_back(DirMapping(existsLeft, dirNameShort, existsRight, *this));
+ return subDirs.back();
+}
- template <SelectedSide side>
- inline
- const Zstring& BaseDirMapping::getBaseDir() const
- {
- return side == LEFT_SIDE ? baseDirLeft : baseDirRight;
- }
+inline
+FileMapping& HierarchyObject::addSubFile(const FileDescriptor& left, //file exists on both sides
+ const Zstring& fileNameShort,
+ CompareFilesResult defaultCmpResult,
+ const FileDescriptor& right)
+{
+ subFiles.push_back(FileMapping(left, fileNameShort, defaultCmpResult, right, *this));
+ return subFiles.back();
+}
+
+
+inline
+void HierarchyObject::addSubFile(const FileDescriptor& left, //file exists on left side only
+ const Zstring& fileNameShort)
+{
+ subFiles.push_back(FileMapping(left, fileNameShort, *this));
+}
+
+
+inline
+void HierarchyObject::addSubFile(const Zstring& fileNameShort, //file exists on right side only
+ const FileDescriptor& right)
+{
+ subFiles.push_back(FileMapping(fileNameShort, right, *this));
+}
+
+
+inline
+void BaseDirMapping::swap()
+{
+ //call base class versions
+ HierarchyObject::swap();
+}
- inline
- void FileMapping::swapDescriptors()
- {
- //swap compare result
- switch (cmpResult)
- {
- case FILE_LEFT_SIDE_ONLY:
- cmpResult = FILE_RIGHT_SIDE_ONLY;
- break;
- case FILE_RIGHT_SIDE_ONLY:
- cmpResult = FILE_LEFT_SIDE_ONLY;
- break;
- case FILE_LEFT_NEWER:
- cmpResult = FILE_RIGHT_NEWER;
- break;
- case FILE_RIGHT_NEWER:
- cmpResult = FILE_LEFT_NEWER;
- break;
- case FILE_DIFFERENT:
- case FILE_EQUAL:
- case FILE_CONFLICT:
- break;
- }
-
- std::swap(dataLeft, dataRight);
- }
+inline
+void DirMapping::swap()
+{
+ //call base class versions
+ HierarchyObject::swap();
+ FileSystemObject::swap();
- inline
- void FileMapping::removeObjectL()
+ //swap compare result
+ switch (cmpResult)
{
- cmpResult = FILE_RIGHT_SIDE_ONLY;
- dataLeft = nullData();
+ case DIR_LEFT_SIDE_ONLY:
+ cmpResult = DIR_RIGHT_SIDE_ONLY;
+ break;
+ case DIR_RIGHT_SIDE_ONLY:
+ cmpResult = DIR_LEFT_SIDE_ONLY;
+ break;
+ case DIR_EQUAL:
+ break;
}
+}
+
+
+inline
+void DirMapping::removeObjectL()
+{
+ cmpResult = DIR_RIGHT_SIDE_ONLY;
+ std::for_each(subFiles.begin(), subFiles.end(), std::mem_fun_ref(&FileSystemObject::removeObject<LEFT_SIDE>));
+ std::for_each(subDirs.begin(), subDirs.end(), std::mem_fun_ref(&FileSystemObject::removeObject<LEFT_SIDE>));
+}
+
+
+inline
+void DirMapping::removeObjectR()
+{
+ cmpResult = DIR_LEFT_SIDE_ONLY;
+ std::for_each(subFiles.begin(), subFiles.end(), std::mem_fun_ref(&FileSystemObject::removeObject<RIGHT_SIDE>));
+ std::for_each(subDirs.begin(), subDirs.end(), std::mem_fun_ref(&FileSystemObject::removeObject<RIGHT_SIDE>));
+}
+
+
+inline
+void DirMapping::copyToL()
+{
+ cmpResult = DIR_EQUAL;
+}
+
+
+inline
+void DirMapping::copyToR()
+{
+ cmpResult = DIR_EQUAL;
+}
+
+
+inline
+const BaseDirMapping::FilterSettings& BaseDirMapping::getFilter() const
+{
+ return filter;
+}
+
+
+template <SelectedSide side>
+inline
+Zstring BaseDirMapping::getDBFilename() const
+{
+ return getBaseDir<side>() + getSyncDBFilename();
+}
- inline
- void FileMapping::removeObjectR()
+inline
+void FileMapping::swap()
+{
+ //call base class version
+ FileSystemObject::swap();
+
+ //swap compare result
+ switch (cmpResult)
{
+ case FILE_LEFT_SIDE_ONLY:
+ cmpResult = FILE_RIGHT_SIDE_ONLY;
+ break;
+ case FILE_RIGHT_SIDE_ONLY:
cmpResult = FILE_LEFT_SIDE_ONLY;
- dataRight = nullData();
- }
+ break;
+ case FILE_LEFT_NEWER:
+ cmpResult = FILE_RIGHT_NEWER;
+ break;
+ case FILE_RIGHT_NEWER:
+ cmpResult = FILE_LEFT_NEWER;
+ break;
+ case FILE_DIFFERENT:
+ case FILE_EQUAL:
+ case FILE_CONFLICT:
+ break;
+ }
+
+ std::swap(dataLeft, dataRight);
+}
- inline
- void FileMapping::copyToL()
- {
- cmpResult = FILE_EQUAL;
- dataLeft = dataRight;
- }
+template <CompareFilesResult res>
+inline
+void FileMapping::setCategory()
+{
+ cmpResult = res;
+}
+template <>
+inline
+void FileMapping::setCategory<FILE_CONFLICT>(); //if conflict is detected, use setCategoryConflict! => method is not defined!
- inline
- void FileMapping::copyToR()
- {
- cmpResult = FILE_EQUAL;
- dataRight = dataLeft;
- }
+inline
+void FileMapping::setCategoryConflict(const wxString& description)
+{
+ cmpResult = FILE_CONFLICT;
+ cmpConflictDescr = description;
+}
- inline
- const FileDescriptor& FileMapping::nullData()
- {
- static FileDescriptor output(Zstring(), 0, 0);
- return output;
- }
+inline
+void FileMapping::removeObjectL()
+{
+ cmpResult = FILE_RIGHT_SIDE_ONLY;
+ dataLeft = FileDescriptor(0, 0);
+}
- inline
- const Zstring& FileMapping::getShortNameL() const
- {
- return dataLeft.shortName;
- }
+inline
+void FileMapping::removeObjectR()
+{
+ cmpResult = FILE_LEFT_SIDE_ONLY;
+ dataRight = FileDescriptor(0, 0);
+}
- inline
- const Zstring& FileMapping::getShortNameR() const
- {
- return dataRight.shortName;
- }
+inline
+void FileMapping::copyToL()
+{
+ cmpResult = FILE_EQUAL;
+ dataLeft = dataRight;
+}
- inline
- bool FileMapping::isEmptyL() const
- {
- return dataLeft.shortName.empty();
- }
+inline
+void FileMapping::copyToR()
+{
+ cmpResult = FILE_EQUAL;
+ dataRight = dataLeft;
+}
- inline
- bool FileMapping::isEmptyR() const
- {
- return dataRight.shortName.empty();
- }
+template <>
+inline
+const wxLongLong& FileMapping::getLastWriteTime<LEFT_SIDE>() const
+{
+ return dataLeft.lastWriteTimeRaw;
+}
- template <SelectedSide side>
- inline
- const wxLongLong& FileMapping::getLastWriteTime() const
- {
- return side == LEFT_SIDE ? dataLeft.lastWriteTimeRaw : dataRight.lastWriteTimeRaw;
- }
+
+template <>
+inline
+const wxLongLong& FileMapping::getLastWriteTime<RIGHT_SIDE>() const
+{
+ return dataRight.lastWriteTimeRaw;
+}
- template <SelectedSide side>
- inline
- const wxULongLong& FileMapping::getFileSize() const
- {
- return side == LEFT_SIDE ? dataLeft.fileSize : dataRight.fileSize;
- }
+template <>
+inline
+const wxULongLong& FileMapping::getFileSize<LEFT_SIDE>() const
+{
+ return dataLeft.fileSize;
+}
+
+
+template <>
+inline
+const wxULongLong& FileMapping::getFileSize<RIGHT_SIDE>() const
+{
+ return dataRight.fileSize;
+}
}
#endif // FILEHIERARCHY_H_INCLUDED
bgstack15