diff options
Diffstat (limited to 'src/3rdParty/efsw/efsw.hpp')
-rw-r--r--[-rwxr-xr-x] | src/3rdParty/efsw/efsw.hpp | 456 |
1 files changed, 261 insertions, 195 deletions
diff --git a/src/3rdParty/efsw/efsw.hpp b/src/3rdParty/efsw/efsw.hpp index 12af116..11a5dec 100755..100644 --- a/src/3rdParty/efsw/efsw.hpp +++ b/src/3rdParty/efsw/efsw.hpp | |||
@@ -1,195 +1,261 @@ | |||
1 | /** | 1 | /** |
2 | @author Martín Lucas Golini | 2 | @author Martín Lucas Golini |
3 | 3 | ||
4 | Copyright (c) 2013 Martín Lucas Golini | 4 | Copyright (c) 2024 Martín Lucas Golini |
5 | 5 | ||
6 | Permission is hereby granted, free of charge, to any person obtaining a copy | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | of this software and associated documentation files (the "Software"), to deal | 7 | of this software and associated documentation files (the "Software"), to deal |
8 | in the Software without restriction, including without limitation the rights | 8 | in the Software without restriction, including without limitation the rights |
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
10 | copies of the Software, and to permit persons to whom the Software is | 10 | copies of the Software, and to permit persons to whom the Software is |
11 | furnished to do so, subject to the following conditions: | 11 | furnished to do so, subject to the following conditions: |
12 | 12 | ||
13 | The above copyright notice and this permission notice shall be included in | 13 | The above copyright notice and this permission notice shall be included in |
14 | all copies or substantial portions of the Software. | 14 | all copies or substantial portions of the Software. |
15 | 15 | ||
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
22 | THE SOFTWARE. | 22 | THE SOFTWARE. |
23 | 23 | ||
24 | This software is a fork of the "simplefilewatcher" by James Wynn (james@jameswynn.com) | 24 | This software is a fork of the "simplefilewatcher" by James Wynn (james@jameswynn.com) |
25 | http://code.google.com/p/simplefilewatcher/ also MIT licensed. | 25 | http://code.google.com/p/simplefilewatcher/ also MIT licensed. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #ifndef ESFW_HPP | 28 | #ifndef ESFW_HPP |
29 | #define ESFW_HPP | 29 | #define ESFW_HPP |
30 | 30 | ||
31 | #include <list> | 31 | #include <string> |
32 | #include <string> | 32 | #include <vector> |
33 | 33 | ||
34 | #if defined( _WIN32 ) | 34 | #if defined( _WIN32 ) |
35 | #ifdef EFSW_DYNAMIC | 35 | #ifdef EFSW_DYNAMIC |
36 | // Windows platforms | 36 | // Windows platforms |
37 | #ifdef EFSW_EXPORTS | 37 | #ifdef EFSW_EXPORTS |
38 | // From DLL side, we must export | 38 | // From DLL side, we must export |
39 | #define EFSW_API __declspec( dllexport ) | 39 | #define EFSW_API __declspec( dllexport ) |
40 | #else | 40 | #else |
41 | // From client application side, we must import | 41 | // From client application side, we must import |
42 | #define EFSW_API __declspec( dllimport ) | 42 | #define EFSW_API __declspec( dllimport ) |
43 | #endif | 43 | #endif |
44 | #else | 44 | #else |
45 | // No specific directive needed for static build | 45 | // No specific directive needed for static build |
46 | #ifndef EFSW_API | 46 | #ifndef EFSW_API |
47 | #define EFSW_API | 47 | #define EFSW_API |
48 | #endif | 48 | #endif |
49 | #endif | 49 | #endif |
50 | #else | 50 | #else |
51 | #if ( __GNUC__ >= 4 ) && defined( EFSW_EXPORTS ) | 51 | #if ( __GNUC__ >= 4 ) && defined( EFSW_EXPORTS ) |
52 | #ifndef EFSW_API | 52 | #ifndef EFSW_API |
53 | #define EFSW_API __attribute__( ( visibility( "default" ) ) ) | 53 | #define EFSW_API __attribute__( ( visibility( "default" ) ) ) |
54 | #endif | 54 | #endif |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | // Other platforms don't need to define anything | 57 | // Other platforms don't need to define anything |
58 | #ifndef EFSW_API | 58 | #ifndef EFSW_API |
59 | #define EFSW_API | 59 | #define EFSW_API |
60 | #endif | 60 | #endif |
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | namespace efsw { | 63 | namespace efsw { |
64 | 64 | ||
65 | /// Type for a watch id | 65 | /// Type for a watch id |
66 | typedef long WatchID; | 66 | typedef long WatchID; |
67 | 67 | ||
68 | // forward declarations | 68 | // forward declarations |
69 | class FileWatcherImpl; | 69 | class FileWatcherImpl; |
70 | class FileWatchListener; | 70 | class FileWatchListener; |
71 | 71 | class WatcherOption; | |
72 | /// Actions to listen for. Rename will send two events, one for | 72 | |
73 | /// the deletion of the old file, and one for the creation of the | 73 | /// Actions to listen for. Rename will send two events, one for |
74 | /// new file. | 74 | /// the deletion of the old file, and one for the creation of the |
75 | namespace Actions { | 75 | /// new file. |
76 | enum Action { | 76 | namespace Actions { |
77 | /// Sent when a file is created or renamed | 77 | enum Action { |
78 | Add = 1, | 78 | /// Sent when a file is created or renamed |
79 | /// Sent when a file is deleted or renamed | 79 | Add = 1, |
80 | Delete = 2, | 80 | /// Sent when a file is deleted or renamed |
81 | /// Sent when a file is modified | 81 | Delete = 2, |
82 | Modified = 3, | 82 | /// Sent when a file is modified |
83 | /// Sent when a file is moved | 83 | Modified = 3, |
84 | Moved = 4 | 84 | /// Sent when a file is moved |
85 | }; | 85 | Moved = 4 |
86 | } | 86 | }; |
87 | typedef Actions::Action Action; | 87 | } |
88 | 88 | typedef Actions::Action Action; | |
89 | /// Errors log namespace | 89 | |
90 | namespace Errors { | 90 | /// Errors log namespace |
91 | 91 | namespace Errors { | |
92 | enum Error { | 92 | |
93 | FileNotFound = -1, | 93 | enum Error { |
94 | FileRepeated = -2, | 94 | NoError = 0, |
95 | FileOutOfScope = -3, | 95 | FileNotFound = -1, |
96 | FileNotReadable = -4, | 96 | FileRepeated = -2, |
97 | FileRemote = -5, /** Directory in remote file system ( create a generic FileWatcher instance to | 97 | FileOutOfScope = -3, |
98 | watch this directory ). */ | 98 | FileNotReadable = -4, |
99 | Unspecified = -6 | 99 | /// Directory in remote file system |
100 | }; | 100 | /// ( create a generic FileWatcher instance to watch this directory ). |
101 | 101 | FileRemote = -5, | |
102 | class EFSW_API Log { | 102 | /// File system watcher failed to watch for changes. |
103 | public: | 103 | WatcherFailed = -6, |
104 | /// @return The last error logged | 104 | Unspecified = -7 |
105 | static std::string getLastErrorLog(); | 105 | }; |
106 | 106 | ||
107 | /// Creates an error of the type specified | 107 | class EFSW_API Log { |
108 | static Error createLastError( Error err, std::string log ); | 108 | public: |
109 | }; | 109 | /// @return The last error logged |
110 | 110 | static std::string getLastErrorLog(); | |
111 | } // namespace Errors | 111 | |
112 | typedef Errors::Error Error; | 112 | /// @return The code of the last error logged |
113 | 113 | static Error getLastErrorCode(); | |
114 | /// Listens to files and directories and dispatches events | 114 | |
115 | /// to notify the listener of files and directories changes. | 115 | /// Reset last error |
116 | /// @class FileWatcher | 116 | static void clearLastError(); |
117 | class EFSW_API FileWatcher { | 117 | |
118 | public: | 118 | /// Creates an error of the type specified |
119 | /// Default constructor, will use the default platform file watcher | 119 | static Error createLastError( Error err, std::string log ); |
120 | FileWatcher(); | 120 | }; |
121 | 121 | ||
122 | /// Constructor that lets you force the use of the Generic File Watcher | 122 | } // namespace Errors |
123 | explicit FileWatcher( bool useGenericFileWatcher ); | 123 | typedef Errors::Error Error; |
124 | 124 | ||
125 | virtual ~FileWatcher(); | 125 | /// Optional file watcher settings. |
126 | 126 | namespace Options { | |
127 | /// Add a directory watch. Same as the other addWatch, but doesn't have recursive option. | 127 | enum Option { |
128 | /// For backwards compatibility. | 128 | /// For Windows, the default buffer size of 63*1024 bytes sometimes is not enough and |
129 | /// On error returns WatchID with Error type. | 129 | /// file system events may be dropped. For that, using a different (bigger) buffer size |
130 | WatchID addWatch( const std::string& directory, FileWatchListener* watcher ); | 130 | /// can be defined here, but note that this does not work for network drives, |
131 | 131 | /// because a buffer larger than 64K will fail the folder being watched, see | |
132 | /// Add a directory watch | 132 | /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa365465(v=vs.85).aspx) |
133 | /// On error returns WatchID with Error type. | 133 | WinBufferSize = 1, |
134 | WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive ); | 134 | /// For Windows, per default all events are captured but we might only be interested |
135 | 135 | /// in a subset; the value of the option should be set to a bitwise or'ed set of | |
136 | /// Remove a directory watch. This is a brute force search O(nlogn). | 136 | /// FILE_NOTIFY_CHANGE_* flags. |
137 | void removeWatch( const std::string& directory ); | 137 | WinNotifyFilter = 2, |
138 | 138 | /// For macOS (FSEvents backend), per default all modified event types are capture but we might | |
139 | /// Remove a directory watch. This is a map lookup O(logn). | 139 | /// only be interested in a subset; the value of the option should be set to a set of bitwise |
140 | void removeWatch( WatchID watchid ); | 140 | /// from: |
141 | 141 | /// kFSEventStreamEventFlagItemFinderInfoMod | |
142 | /// Starts watching ( in other thread ) | 142 | /// kFSEventStreamEventFlagItemModified |
143 | void watch(); | 143 | /// kFSEventStreamEventFlagItemInodeMetaMod |
144 | 144 | /// Default configuration will set the 3 flags | |
145 | /// @return Returns a list of the directories that are being watched | 145 | MacModifiedFilter = 3, |
146 | std::list<std::string> directories(); | 146 | /// macOS sometimes informs incorrect or old file states that may confuse the consumer |
147 | 147 | /// The events sanitizer will try to sanitize incorrectly reported events in favor of reducing | |
148 | /** Allow recursive watchers to follow symbolic links to other directories | 148 | /// the number of events reported. This will have an small performance and memory impact as a |
149 | * followSymlinks is disabled by default | 149 | /// consequence. |
150 | */ | 150 | MacSanitizeEvents = 4, |
151 | void followSymlinks( bool follow ); | 151 | /// Linux does not support natively recursive watchers. This means that when using recursive |
152 | 152 | /// watches efsw registers new watchers for each directory. If new file are created between | |
153 | /** @return If can follow symbolic links to directorioes */ | 153 | /// the time efsw takes to register the new directory those events might be missed. To avoid |
154 | const bool& followSymlinks() const; | 154 | /// missing new file notifications efsw will trigger synthetic created file events for existing |
155 | 155 | /// files in the new directroy watched. This might have the unintended consequence of sending | |
156 | /** When enable this it will allow symlinks to watch recursively out of the pointed directory. | 156 | /// duplicated created events due to the system also emitting this event. |
157 | * follorSymlinks must be enabled to this work. | 157 | LinuxProduceSyntheticEvents = 5, |
158 | * For example, added symlink to /home/folder, and the symlink points to /, this by default is | 158 | }; |
159 | * not allowed, it's only allowed to symlink anything from /home/ and deeper. This is to avoid | 159 | } |
160 | * great levels of recursion. Enabling this could lead in infinite recursion, and crash the | 160 | typedef Options::Option Option; |
161 | * watcher ( it will try not to avoid this ). Buy enabling out of scope links, it will allow | 161 | |
162 | * this behavior. allowOutOfScopeLinks are disabled by default. | 162 | /// Listens to files and directories and dispatches events |
163 | */ | 163 | /// to notify the listener of files and directories changes. |
164 | void allowOutOfScopeLinks( bool allow ); | 164 | /// @class FileWatcher |
165 | 165 | class EFSW_API FileWatcher { | |
166 | /// @return Returns if out of scope links are allowed | 166 | public: |
167 | const bool& allowOutOfScopeLinks() const; | 167 | /// Default constructor, will use the default platform file watcher |
168 | 168 | FileWatcher(); | |
169 | private: | 169 | |
170 | /// The implementation | 170 | /// Constructor that lets you force the use of the Generic File Watcher |
171 | FileWatcherImpl* mImpl; | 171 | explicit FileWatcher( bool useGenericFileWatcher ); |
172 | bool mFollowSymlinks; | 172 | |
173 | bool mOutOfScopeLinks; | 173 | virtual ~FileWatcher(); |
174 | }; | 174 | |
175 | 175 | /// Add a directory watch. Same as the other addWatch, but doesn't have recursive option. | |
176 | /// Basic interface for listening for file events. | 176 | /// For backwards compatibility. |
177 | /// @class FileWatchListener | 177 | /// On error returns WatchID with Error type. |
178 | class FileWatchListener { | 178 | WatchID addWatch( const std::string& directory, FileWatchListener* watcher ); |
179 | public: | 179 | |
180 | virtual ~FileWatchListener() {} | 180 | /// Add a directory watch |
181 | 181 | /// On error returns WatchID with Error type. | |
182 | /// Handles the action file action | 182 | WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive ); |
183 | /// @param watchid The watch id for the directory | 183 | |
184 | /// @param dir The directory | 184 | /// Add a directory watch, allowing customization with options |
185 | /// @param filename The filename that was accessed (not full path) | 185 | /// @param directory The folder to be watched |
186 | /// @param action Action that was performed | 186 | /// @param watcher The listener to receive events |
187 | /// @param oldFilename The name of the file or directory moved | 187 | /// @param recursive Set this to true to include subdirectories |
188 | virtual void handleFileAction( WatchID watchid, const std::string& dir, | 188 | /// @param options Allows customization of a watcher |
189 | const std::string& filename, Action action, | 189 | /// @return Returns the watch id for the directory or, on error, a WatchID with Error type. |
190 | std::string oldFilename = "" ) = 0; | 190 | WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive, |
191 | }; | 191 | const std::vector<WatcherOption>& options ); |
192 | 192 | ||
193 | } // namespace efsw | 193 | /// Remove a directory watch. This is a brute force search O(nlogn). |
194 | 194 | void removeWatch( const std::string& directory ); | |
195 | #endif | 195 | |
196 | /// Remove a directory watch. This is a map lookup O(logn). | ||
197 | void removeWatch( WatchID watchid ); | ||
198 | |||
199 | /// Starts watching ( in other thread ) | ||
200 | void watch(); | ||
201 | |||
202 | /// @return Returns a list of the directories that are being watched | ||
203 | std::vector<std::string> directories(); | ||
204 | |||
205 | /** Allow recursive watchers to follow symbolic links to other directories | ||
206 | * followSymlinks is disabled by default | ||
207 | */ | ||
208 | void followSymlinks( bool follow ); | ||
209 | |||
210 | /** @return If can follow symbolic links to directorioes */ | ||
211 | const bool& followSymlinks() const; | ||
212 | |||
213 | /** When enable this it will allow symlinks to watch recursively out of the pointed directory. | ||
214 | * follorSymlinks must be enabled to this work. | ||
215 | * For example, added symlink to /home/folder, and the symlink points to /, this by default is | ||
216 | * not allowed, it's only allowed to symlink anything from /home/ and deeper. This is to avoid | ||
217 | * great levels of recursion. Enabling this could lead in infinite recursion, and crash the | ||
218 | * watcher ( it will try not to avoid this ). Buy enabling out of scope links, it will allow | ||
219 | * this behavior. allowOutOfScopeLinks are disabled by default. | ||
220 | */ | ||
221 | void allowOutOfScopeLinks( bool allow ); | ||
222 | |||
223 | /// @return Returns if out of scope links are allowed | ||
224 | const bool& allowOutOfScopeLinks() const; | ||
225 | |||
226 | private: | ||
227 | /// The implementation | ||
228 | FileWatcherImpl* mImpl; | ||
229 | bool mFollowSymlinks; | ||
230 | bool mOutOfScopeLinks; | ||
231 | }; | ||
232 | |||
233 | /// Basic interface for listening for file events. | ||
234 | /// @class FileWatchListener | ||
235 | class FileWatchListener { | ||
236 | public: | ||
237 | virtual ~FileWatchListener() {} | ||
238 | |||
239 | /// Handles the action file action | ||
240 | /// @param watchid The watch id for the directory | ||
241 | /// @param dir The directory | ||
242 | /// @param filename The filename that was accessed (not full path) | ||
243 | /// @param action Action that was performed | ||
244 | /// @param oldFilename The name of the file or directory moved | ||
245 | virtual void handleFileAction( WatchID watchid, const std::string& dir, | ||
246 | const std::string& filename, Action action, | ||
247 | std::string oldFilename = "" ) = 0; | ||
248 | }; | ||
249 | |||
250 | /// Optional, typically platform specific parameter for customization of a watcher. | ||
251 | /// @class WatcherOption | ||
252 | class WatcherOption { | ||
253 | public: | ||
254 | WatcherOption( Option option, int value ) : mOption( option ), mValue( value ){}; | ||
255 | Option mOption; | ||
256 | int mValue; | ||
257 | }; | ||
258 | |||
259 | } // namespace efsw | ||
260 | |||
261 | #endif | ||