diff --git a/bazaar/FSMonTest/FSMonSync.h b/bazaar/FSMonTest/FSMonSync.h new file mode 100755 index 000000000..ffe25fb47 --- /dev/null +++ b/bazaar/FSMonTest/FSMonSync.h @@ -0,0 +1,40 @@ +#ifndef _FSMonTest_FSMonSync_h +#define _FSMonTest_FSMonSync_h + +#include + +using namespace Upp; + +#define LAYOUTFILE +#include + + + +class FSMonSync : public WithFSMonSyncLayout +{ + private: + void Log(String const &s); + + void startCb(void); + void stopCb(void); + void quitCb(void); + + FSMon fsmMon; + + void monitorCb(void); + + String srcFolder, dstFolder; + + // gets destination path given source one + String GetDestPath(String const &srcPath); + + bool started; + + protected: + public: + typedef FSMonSync CLASSNAME; + + FSMonSync(); +}; + +#endif diff --git a/bazaar/FSMonTest/FSMonTest.lay b/bazaar/FSMonTest/FSMonSync.lay similarity index 88% rename from bazaar/FSMonTest/FSMonTest.lay rename to bazaar/FSMonTest/FSMonSync.lay index 95a382704..cee6637d3 100644 --- a/bazaar/FSMonTest/FSMonTest.lay +++ b/bazaar/FSMonTest/FSMonSync.lay @@ -1,4 +1,4 @@ -LAYOUT(FSMonTestLayout, 504, 288) +LAYOUT(FSMonSyncLayout, 504, 288) ITEM(LineEdit, logEdit, LeftPosZ(8, 488).TopPosZ(4, 256)) ITEM(Button, stopBtn, SetLabel(t_("Stop")).LeftPosZ(76, 60).TopPosZ(264, 20)) ITEM(Button, quitBtn, SetLabel(t_("Quit")).LeftPosZ(436, 60).TopPosZ(264, 20)) diff --git a/bazaar/FSMonTest/FSMonSync.upp b/bazaar/FSMonTest/FSMonSync.upp new file mode 100644 index 000000000..75951ce80 --- /dev/null +++ b/bazaar/FSMonTest/FSMonSync.upp @@ -0,0 +1,16 @@ +description "Rudimentary file synchronization test for FSMon Filesystem Monitor Package\377"; + +uses + CtrlLib, + FSMon; + +file + SyncUtils.h, + SyncUtils.cpp, + FSMonSync.lay, + FSMonSync.h, + main.cpp; + +mainconfig + "" = "GUI MT"; + diff --git a/bazaar/FSMonTest/FSMonTest.h b/bazaar/FSMonTest/FSMonTest.h deleted file mode 100644 index 1d20dbb7d..000000000 --- a/bazaar/FSMonTest/FSMonTest.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _FSMonTest_FSMonTest_h -#define _FSMonTest_FSMonTest_h - -#include - -using namespace Upp; - -#define LAYOUTFILE -#include - - - -class FSMonTest : public WithFSMonTestLayout -{ - private: - void Log(String const &s); - - void startCb(void); - void stopCb(void); - void quitCb(void); - - FSMon fsmMon; - - void monitorCb(void); - - protected: - public: - typedef FSMonTest CLASSNAME; - - FSMonTest(); -}; - -#endif diff --git a/bazaar/FSMonTest/FSMonTest.upp b/bazaar/FSMonTest/FSMonTest.upp deleted file mode 100644 index 6b67ca516..000000000 --- a/bazaar/FSMonTest/FSMonTest.upp +++ /dev/null @@ -1,14 +0,0 @@ -description "Test FSMon Filesystem Monitor Package\377"; - -uses - CtrlLib, - FSMon; - -file - FSMonTest.lay, - FSMonTest.h, - main.cpp; - -mainconfig - "" = "GUI MT"; - diff --git a/bazaar/FSMonTest/SyncUtils.cpp b/bazaar/FSMonTest/SyncUtils.cpp new file mode 100644 index 000000000..a0fbe5dd4 --- /dev/null +++ b/bazaar/FSMonTest/SyncUtils.cpp @@ -0,0 +1,80 @@ +#include "SyncUtils.h" + +// synchronize a source file with a dest one +// checks filestamp, size and attributes +bool SyncFile(String const &src, String const &dst) +{ + Time srcTime; + + if(src == dst) + return false; + if(!FileExists(src)) + { + if(FileExists(dst)) + { + FileDelete(dst); + return true; + } + return false; + } + bool shallCopy = false; + if(!FileExists(dst)) + shallCopy = true; + else + { + srcTime = FileGetTime(src); + int64 srcLen = GetFileLength(src); + + Time dstTime = FileGetTime(dst); + int64 dstLen = GetFileLength(dst); + + if(srcTime != dstTime || srcLen != dstLen) + shallCopy = true; + } + if(shallCopy) + { + if(!RealizePath(dst)) + return false; + if(FileCopy(src, dst)) + return FileSetTime(dst, srcTime); + else + return false; + } + return true; +} + +// synchronizes a whole source folder with a dest one +// uses SyncFile for single files synchronization +bool SyncFolder(String const &src, String const &dst) +{ + bool res = true; + +#ifdef PLATFORM_POSIX + FindFile ff(AppendFileName(src, "*")); +#else + FindFile ff(AppendFileName(src, "*.*")); +#endif + + if(!DirectoryExists(dst)) + { + if(!RealizeDirectory(dst)) + return false; + } + while(ff) + { + // skip . and .. folders... + if(ff.GetName() == "." || ff.GetName() == "..") + { + ff.Next(); + continue; + } + String srcPath = AppendFileName(src, ff.GetName()); + String dstPath = AppendFileName(dst, ff.GetName()); + if(ff.IsFolder()) + res &= SyncFolder(srcPath, dstPath); + else + res &= SyncFile(srcPath, dstPath); + ff.Next(); + } + return res; +} diff --git a/bazaar/FSMonTest/SyncUtils.h b/bazaar/FSMonTest/SyncUtils.h new file mode 100644 index 000000000..6b72b6f4d --- /dev/null +++ b/bazaar/FSMonTest/SyncUtils.h @@ -0,0 +1,16 @@ +#ifndef _FSMonSync_SyncUtils_h_ +#define _FSMonSync_SyncUtils_h_ + +#include + +using namespace Upp; + +// synchronize a source file with a dest one +// checks filestamp, size and attributes +bool SyncFile(String const &src, String const &dst); + +// synchronizes a whole source folder with a dest one +// uses SyncFile for single files synchronization +bool SyncFolder(String const &src, String const &dst); + +#endif diff --git a/bazaar/FSMonTest/init b/bazaar/FSMonTest/init index 56ae17a5a..34a39361e 100644 --- a/bazaar/FSMonTest/init +++ b/bazaar/FSMonTest/init @@ -1,5 +1,5 @@ -#ifndef _FSMonTest_icpp_init_stub -#define _FSMonTest_icpp_init_stub +#ifndef _FSMonSync_icpp_init_stub +#define _FSMonSync_icpp_init_stub #include "CtrlLib/init" #include "FSMon/init" #endif diff --git a/bazaar/FSMonTest/main.cpp b/bazaar/FSMonTest/main.cpp index a298c7adc..32e34482e 100644 --- a/bazaar/FSMonTest/main.cpp +++ b/bazaar/FSMonTest/main.cpp @@ -1,82 +1,137 @@ -#include "FSMonTest.h" - -void FSMonTest::Log(String const &s) -{ - logEdit.Set(logEdit.Get() + s + "\n"); - logEdit.SetCursor(INT_MAX); -} - -void FSMonTest::startCb(void) -{ - String path = AppendFileName(GetHomeDirectory(), "FSMonTest_A"); - Log("Starting monitor for '" + path + "'"); - if(!DirectoryExists(path)) - RealizeDirectory(path); - fsmMon.Add(path); -} - -void FSMonTest::stopCb(void) -{ - Log("Stopping\n"); - String path = AppendFileName(GetHomeDirectory(), "FSMonTest_A"); - fsmMon.Remove(path); -} - -void FSMonTest::quitCb(void) -{ - stopCb(); - Break(); -} - -void FSMonTest::monitorCb() -{ - Vector infos = fsmMon.GetChanged(); - for(int iChange = 0; iChange < infos.GetCount(); iChange++) - { - FSMon::Info const &info = infos[iChange]; - switch(info.flags) - { - case FSMon::FSM_NOP : - Log(String("NO-OP EVENT")); - break; - case FSMon::FSM_Created : - Log(String("Creating file '") + info.path + "'"); - break; - case FSMon::FSM_Deleted : - Log(String("Deleting file '") + info.path + "'"); - break; - case FSMon::FSM_Moved : - Log(String("Moving file '") + info.path + "' to '" + info.newPath + "'"); - break; - case FSMon::FSM_FolderCreated : - Log(String("Creating folder '") + info.path + "'"); - break; - case FSMon::FSM_FolderDeleted : - Log(String("Deleting folder '") + info.path + "'"); - break; - case FSMon::FSM_FolderMoved : - Log(String("Moving folder '") + info.path + "' to '" + info.newPath + "'"); - break; - case FSMon::FSM_Modified : - Log(String("Modifying file '") + info.path + "'"); - break; - case FSMon::FSM_AttribChange : - Log(String("Modifying file attributes for '") + info.path + "'"); - break; - } - } -} - -FSMonTest::FSMonTest() -{ - CtrlLayout(*this, "Window title"); - fsmMon.EventHandler = THISBACK(monitorCb); - startBtn <<= THISBACK(startCb); - stopBtn <<= THISBACK(stopCb); - quitBtn <<= THISBACK(quitCb); -} - -GUI_APP_MAIN -{ - FSMonTest().Run(); -} +#include "FSMonSync.h" +#include "SyncUtils.h" + +void FSMonSync::Log(String const &s) +{ + logEdit.Set(logEdit.Get() + s); + logEdit.SetCursor(INT_MAX); +} + +// gets destination path given source one +String FSMonSync::GetDestPath(String const &srcPath) +{ + ASSERT(srcPath.StartsWith(srcFolder)); + String res = srcPath.Mid(srcFolder.GetCount()); + return AppendFileName(dstFolder, res); +} + +void FSMonSync::startCb(void) +{ + srcFolder = AppendFileName(GetHomeDirectory(), "FSMonTest_A"); + if(!DirectoryExists(srcFolder)) + RealizeDirectory(srcFolder); + dstFolder = AppendFileName(GetHomeDirectory(), "FSMonTest_B"); + if(!DirectoryExists(dstFolder)) + RealizeDirectory(dstFolder); + Log("Starting syncinc '" + srcFolder + "' to '" + dstFolder + "'\n"); + Log("Initial sync....."); + ProcessEvents(); + SyncFolder(srcFolder, dstFolder); + Log("DONE\n"); + ProcessEvents(); + fsmMon.Add(srcFolder); + + started = true; + stopBtn.Enable(); + startBtn.Disable(); +} + +void FSMonSync::stopCb(void) +{ + Log("Stopping\n\n"); + fsmMon.Remove(srcFolder); + started = false; + stopBtn.Disable(); + startBtn.Enable(); +} + +void FSMonSync::quitCb(void) +{ + if(started) + stopCb(); + Break(); +} + +void FSMonSync::monitorCb() +{ + Vector infos = fsmMon.GetChanged(); + for(int iChange = 0; iChange < infos.GetCount(); iChange++) + { + FSMon::Info const &info = infos[iChange]; + switch(info.flags) + { + case FSMon::FSM_NOP : + Log("NO-OP EVENT\n"); + break; + case FSMon::FSM_Created : + Log("Syncing created file '" + info.path + "'....."); + if(SyncFile(info.path, GetDestPath(info.path))) + Log("DONE\n"); + else + Log("FAILED\n"); + break; + case FSMon::FSM_Deleted : + Log("Syncing deleted file '" + info.path + "'....."); + if(SyncFile(info.path, GetDestPath(info.path))) + Log("DONE\n"); + else + Log("FAILED\n"); + break; + case FSMon::FSM_Moved : + Log("Syncing file move from '" + info.path + "' to '" + info.newPath + "'....."); + if(FileMove(GetDestPath(info.path), GetDestPath(info.newPath))) + Log("DONE\n"); + else + Log("FAILED\n"); + break; + case FSMon::FSM_FolderCreated : + Log("Syncing created folder '" + info.path + "'....."); + if(SyncFolder(info.path, GetDestPath(info.path))) + Log("DONE\n"); + else + Log("FAILED\n"); + break; + case FSMon::FSM_FolderDeleted : + Log("Syncing deleted file '" + info.path + "'....."); + if(DeleteFolderDeep(GetDestPath(info.path))) + Log("DONE\n"); + else + Log("FAILED\n"); + break; + case FSMon::FSM_FolderMoved : + Log("Syncing folder move from '" + info.path + "' to '" + info.newPath + "'....."); + if(FileMove(GetDestPath(info.path), GetDestPath(info.newPath))) + Log("DONE\n"); + else + Log("FAILED\n"); + break; + case FSMon::FSM_Modified : + Log("Syncing modified file '" + info.path + "'....."); + if(SyncFile(info.path, GetDestPath(info.path))) + Log("DONE\n"); + else + Log("FAILED\n"); + break; + case FSMon::FSM_AttribChange : + Log("Attribute syncing not supported\n"); + break; + } + } +} + +FSMonSync::FSMonSync() +{ + CtrlLayout(*this, "Window title"); + fsmMon.EventHandler = THISBACK(monitorCb); + startBtn <<= THISBACK(startCb); + stopBtn <<= THISBACK(stopCb); + quitBtn <<= THISBACK(quitCb); + + started = false; + stopBtn.Disable(); +} + +GUI_APP_MAIN +{ + FSMonSync().Run(); +}