xref: /glogg/src/watchtowerlist.h (revision b278d1839115e4ea1ab008ee6886473f3dccbe8b)
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