1c540156cSNicolas Bonnefon #ifndef WATCHTOWERLIST_H 2c540156cSNicolas Bonnefon #define WATCHTOWERLIST_H 3c540156cSNicolas Bonnefon 4c540156cSNicolas Bonnefon // Utility classes for the WatchTower implementations 5c540156cSNicolas Bonnefon 6c540156cSNicolas Bonnefon #include <functional> 7c540156cSNicolas Bonnefon #include <string> 8c540156cSNicolas Bonnefon #include <vector> 9c540156cSNicolas Bonnefon #include <map> 10c540156cSNicolas Bonnefon #include <list> 11c540156cSNicolas Bonnefon #include <memory> 12c540156cSNicolas Bonnefon #include <algorithm> 13c540156cSNicolas Bonnefon 14*b278d183SNicolas Bonnefon // FIXME 15*b278d183SNicolas Bonnefon #include "inotifywatchtowerdriver.h" 16*b278d183SNicolas Bonnefon 17c540156cSNicolas Bonnefon // Utility classes 18c540156cSNicolas Bonnefon struct ProtocolInfo { 19c540156cSNicolas Bonnefon // Win32 notification variables 20c540156cSNicolas Bonnefon static const int READ_DIR_CHANGE_BUFFER_SIZE = 4096; 21c540156cSNicolas Bonnefon 22c540156cSNicolas Bonnefon void* handle_; 23c540156cSNicolas Bonnefon static const unsigned long buffer_length_ = READ_DIR_CHANGE_BUFFER_SIZE; 24c540156cSNicolas Bonnefon char buffer_[buffer_length_]; 25c540156cSNicolas Bonnefon }; 26c540156cSNicolas Bonnefon 27c540156cSNicolas Bonnefon // List of files and observers 28c540156cSNicolas Bonnefon struct ObservedDir { 29c540156cSNicolas Bonnefon ObservedDir( const std::string this_path ) : path { this_path } {} 30c540156cSNicolas Bonnefon 31c540156cSNicolas Bonnefon // Returns the address of the protocol specific informations 32c540156cSNicolas Bonnefon ProtocolInfo* protocolInfo() { return &protocol_info_; } 33c540156cSNicolas Bonnefon 34c540156cSNicolas Bonnefon std::string path; 35*b278d183SNicolas Bonnefon INotifyWatchTowerDriver::DirId dir_id_; 36c540156cSNicolas Bonnefon // Contains data specific to the protocol (inotify/Win32...) 37c540156cSNicolas Bonnefon ProtocolInfo protocol_info_; 38c540156cSNicolas Bonnefon }; 39c540156cSNicolas Bonnefon 40c540156cSNicolas Bonnefon struct ObservedFile { 41c540156cSNicolas Bonnefon ObservedFile( 42c540156cSNicolas Bonnefon const std::string& file_name, 43c540156cSNicolas Bonnefon std::shared_ptr<void> callback, 44*b278d183SNicolas Bonnefon INotifyWatchTowerDriver::FileId file_id, 45*b278d183SNicolas Bonnefon INotifyWatchTowerDriver::SymlinkId symlink_id ) 46*b278d183SNicolas Bonnefon : file_name_( file_name ) { 47c540156cSNicolas Bonnefon addCallback( callback ); 48c540156cSNicolas Bonnefon 49*b278d183SNicolas Bonnefon file_id_ = file_id; 50*b278d183SNicolas Bonnefon symlink_id_ = symlink_id; 51c540156cSNicolas Bonnefon dir_ = nullptr; 52c540156cSNicolas Bonnefon } 53c540156cSNicolas Bonnefon 54c540156cSNicolas Bonnefon void addCallback( std::shared_ptr<void> callback ) { 55c540156cSNicolas Bonnefon callbacks.push_back( callback ); 56c540156cSNicolas Bonnefon } 57c540156cSNicolas Bonnefon 58c540156cSNicolas Bonnefon std::string file_name_; 59c540156cSNicolas Bonnefon // List of callbacks for this file 60c540156cSNicolas Bonnefon std::vector<std::shared_ptr<void>> callbacks; 61c540156cSNicolas Bonnefon 62c540156cSNicolas Bonnefon // watch descriptor for the file itself 63*b278d183SNicolas Bonnefon INotifyWatchTowerDriver::FileId file_id_; 64c540156cSNicolas Bonnefon // watch descriptor for the symlink (if file is a symlink) 65*b278d183SNicolas Bonnefon INotifyWatchTowerDriver::SymlinkId symlink_id_; 66c540156cSNicolas Bonnefon 67c540156cSNicolas Bonnefon // link to the dir containing the file 68c540156cSNicolas Bonnefon std::shared_ptr<ObservedDir> dir_; 69c540156cSNicolas Bonnefon }; 70c540156cSNicolas Bonnefon 71c540156cSNicolas Bonnefon // A list of the observed files and directories 72c540156cSNicolas Bonnefon // This class is not thread safe 73c540156cSNicolas Bonnefon class ObservedFileList { 74c540156cSNicolas Bonnefon public: 75c540156cSNicolas Bonnefon ObservedFileList() = default; 76c540156cSNicolas Bonnefon ~ObservedFileList() = default; 77c540156cSNicolas Bonnefon 78c540156cSNicolas Bonnefon ObservedFile* searchByName( const std::string& file_name ); 79*b278d183SNicolas Bonnefon ObservedFile* searchByFileOrSymlinkWd( 80*b278d183SNicolas Bonnefon INotifyWatchTowerDriver::FileId file_id, 81*b278d183SNicolas Bonnefon INotifyWatchTowerDriver::SymlinkId symlink_id ); 82*b278d183SNicolas Bonnefon ObservedFile* searchByDirWdAndName( 83*b278d183SNicolas Bonnefon INotifyWatchTowerDriver::DirId id, const char* name ); 84c540156cSNicolas Bonnefon 85c540156cSNicolas Bonnefon ObservedFile* addNewObservedFile( ObservedFile new_observed ); 86c540156cSNicolas Bonnefon // Remove a callback, remove and returns the file object if 87c540156cSNicolas Bonnefon // it was the last callback on this object, nullptr if not. 88c540156cSNicolas Bonnefon // The caller has ownership of the object. 89c540156cSNicolas Bonnefon std::shared_ptr<ObservedFile> removeCallback( 90c540156cSNicolas Bonnefon std::shared_ptr<void> callback ); 91c540156cSNicolas Bonnefon 92c540156cSNicolas Bonnefon // Return the watched directory if it is watched, or nullptr 93c540156cSNicolas Bonnefon std::shared_ptr<ObservedDir> watchedDirectory( const std::string& dir_name ); 94c540156cSNicolas Bonnefon // Create a new watched directory for dir_name 95c540156cSNicolas Bonnefon std::shared_ptr<ObservedDir> addWatchedDirectory( const std::string& dir_name ); 96c540156cSNicolas Bonnefon 97c540156cSNicolas Bonnefon std::shared_ptr<ObservedDir> watchedDirectoryForFile( const std::string& file_name ); 98c540156cSNicolas Bonnefon std::shared_ptr<ObservedDir> addWatchedDirectoryForFile( const std::string& file_name ); 99c540156cSNicolas Bonnefon 100c540156cSNicolas Bonnefon private: 101c540156cSNicolas Bonnefon // List of observed files 102c540156cSNicolas Bonnefon std::list<ObservedFile> observed_files_; 103c540156cSNicolas Bonnefon 104c540156cSNicolas Bonnefon // List of observed dirs, key-ed by name 105c540156cSNicolas Bonnefon std::map<std::string, std::weak_ptr<ObservedDir>> observed_dirs_; 106c540156cSNicolas Bonnefon 107c540156cSNicolas Bonnefon // Map the inotify file (including symlinks) wds to the observed file 108c540156cSNicolas Bonnefon std::map<int, ObservedFile*> by_file_wd_; 109c540156cSNicolas Bonnefon // Map the inotify directory wds to the observed files 110c540156cSNicolas Bonnefon std::map<int, ObservedFile*> by_dir_wd_; 111c540156cSNicolas Bonnefon }; 112c540156cSNicolas Bonnefon 113c540156cSNicolas Bonnefon #endif 114