aboutsummaryrefslogtreecommitdiff
path: root/src/3rdParty/efsw/DirectorySnapshot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdParty/efsw/DirectorySnapshot.cpp')
-rwxr-xr-xsrc/3rdParty/efsw/DirectorySnapshot.cpp212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/3rdParty/efsw/DirectorySnapshot.cpp b/src/3rdParty/efsw/DirectorySnapshot.cpp
new file mode 100755
index 0000000..6049e4a
--- /dev/null
+++ b/src/3rdParty/efsw/DirectorySnapshot.cpp
@@ -0,0 +1,212 @@
1#include <efsw/DirectorySnapshot.hpp>
2#include <efsw/FileSystem.hpp>
3
4namespace efsw {
5
6DirectorySnapshot::DirectorySnapshot() {}
7
8DirectorySnapshot::DirectorySnapshot( std::string directory ) {
9 init( directory );
10}
11
12DirectorySnapshot::~DirectorySnapshot() {}
13
14void DirectorySnapshot::init( std::string directory ) {
15 setDirectoryInfo( directory );
16 initFiles();
17}
18
19bool DirectorySnapshot::exists() {
20 return DirectoryInfo.exists();
21}
22
23void DirectorySnapshot::deleteAll( DirectorySnapshotDiff& Diff ) {
24 FileInfo fi;
25
26 for ( FileInfoMap::iterator it = Files.begin(); it != Files.end(); it++ ) {
27 fi = it->second;
28
29 if ( fi.isDirectory() ) {
30 Diff.DirsDeleted.push_back( fi );
31 } else {
32 Diff.FilesDeleted.push_back( fi );
33 }
34 }
35
36 Files.clear();
37}
38
39void DirectorySnapshot::setDirectoryInfo( std::string directory ) {
40 DirectoryInfo = FileInfo( directory );
41}
42
43void DirectorySnapshot::initFiles() {
44 Files = FileSystem::filesInfoFromPath( DirectoryInfo.Filepath );
45
46 FileInfoMap::iterator it = Files.begin();
47 std::list<std::string> eraseFiles;
48
49 /// Remove all non regular files and non directories
50 for ( ; it != Files.end(); it++ ) {
51 if ( !it->second.isRegularFile() && !it->second.isDirectory() ) {
52 eraseFiles.push_back( it->first );
53 }
54 }
55
56 for ( std::list<std::string>::iterator eit = eraseFiles.begin(); eit != eraseFiles.end();
57 eit++ ) {
58 Files.erase( *eit );
59 }
60}
61
62DirectorySnapshotDiff DirectorySnapshot::scan() {
63 DirectorySnapshotDiff Diff;
64
65 Diff.clear();
66
67 FileInfo curFI( DirectoryInfo.Filepath );
68
69 Diff.DirChanged = DirectoryInfo != curFI;
70
71 if ( Diff.DirChanged ) {
72 DirectoryInfo = curFI;
73 }
74
75 /// If the directory was erased, create the events for files and directories deletion
76 if ( !curFI.exists() ) {
77 deleteAll( Diff );
78
79 return Diff;
80 }
81
82 FileInfoMap files = FileSystem::filesInfoFromPath( DirectoryInfo.Filepath );
83
84 if ( files.empty() && Files.empty() ) {
85 return Diff;
86 }
87
88 FileInfo fi;
89 FileInfoMap FilesCpy;
90 FileInfoMap::iterator it;
91 FileInfoMap::iterator fiIt;
92
93 if ( Diff.DirChanged ) {
94 FilesCpy = Files;
95 }
96
97 for ( it = files.begin(); it != files.end(); it++ ) {
98 fi = it->second;
99
100 /// File existed before?
101 fiIt = Files.find( it->first );
102
103 if ( fiIt != Files.end() ) {
104 /// Erase from the file list copy
105 FilesCpy.erase( it->first );
106
107 /// File changed?
108 if ( ( *fiIt ).second != fi ) {
109 /// Update the new file info
110 Files[it->first] = fi;
111
112 /// handle modified event
113 if ( fi.isDirectory() ) {
114 Diff.DirsModified.push_back( fi );
115 } else {
116 Diff.FilesModified.push_back( fi );
117 }
118 }
119 }
120 /// Only add regular files or directories
121 else if ( fi.isRegularFile() || fi.isDirectory() ) {
122 /// New file found
123 Files[it->first] = fi;
124
125 FileInfoMap::iterator fit;
126 std::string oldFile = "";
127
128 /// Check if the same inode already existed
129 if ( ( fit = nodeInFiles( fi ) ) != Files.end() ) {
130 oldFile = fit->first;
131
132 /// Avoid firing a Delete event
133 FilesCpy.erase( fit->first );
134
135 /// Delete the old file name
136 Files.erase( fit->first );
137
138 if ( fi.isDirectory() ) {
139 Diff.DirsMoved.push_back( std::make_pair( oldFile, fi ) );
140 } else {
141 Diff.FilesMoved.push_back( std::make_pair( oldFile, fi ) );
142 }
143 } else {
144 if ( fi.isDirectory() ) {
145 Diff.DirsCreated.push_back( fi );
146 } else {
147 Diff.FilesCreated.push_back( fi );
148 }
149 }
150 }
151 }
152
153 if ( !Diff.DirChanged ) {
154 return Diff;
155 }
156
157 /// The files or directories that remains were deleted
158 for ( it = FilesCpy.begin(); it != FilesCpy.end(); it++ ) {
159 fi = it->second;
160
161 if ( fi.isDirectory() ) {
162 Diff.DirsDeleted.push_back( fi );
163 } else {
164 Diff.FilesDeleted.push_back( fi );
165 }
166
167 /// Remove the file or directory from the list of files
168 Files.erase( it->first );
169 }
170
171 return Diff;
172}
173
174FileInfoMap::iterator DirectorySnapshot::nodeInFiles( FileInfo& fi ) {
175 FileInfoMap::iterator it;
176
177 if ( FileInfo::inodeSupported() ) {
178 for ( it = Files.begin(); it != Files.end(); it++ ) {
179 if ( it->second.sameInode( fi ) && it->second.Filepath != fi.Filepath ) {
180 return it;
181 }
182 }
183 }
184
185 return Files.end();
186}
187
188void DirectorySnapshot::addFile( std::string path ) {
189 std::string name( FileSystem::fileNameFromPath( path ) );
190 Files[name] = FileInfo( path );
191}
192
193void DirectorySnapshot::removeFile( std::string path ) {
194 std::string name( FileSystem::fileNameFromPath( path ) );
195
196 FileInfoMap::iterator it = Files.find( name );
197
198 if ( Files.end() != it ) {
199 Files.erase( it );
200 }
201}
202
203void DirectorySnapshot::moveFile( std::string oldPath, std::string newPath ) {
204 removeFile( oldPath );
205 addFile( newPath );
206}
207
208void DirectorySnapshot::updateFile( std::string path ) {
209 addFile( path );
210}
211
212} // namespace efsw