diff options
| author | Li Jin <dragon-fly@qq.com> | 2022-11-15 17:23:46 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2022-11-15 17:52:09 +0800 |
| commit | 94f8330613877b3582d32bd11abd83a97b4399ad (patch) | |
| tree | 5359de314be1ebde17f8d1e48632a97d18f9e50f /src/3rdParty/efsw/DirectorySnapshot.cpp | |
| parent | 60f8f00a022ac08701792b2897b72d8c99b50f52 (diff) | |
| download | yuescript-94f8330613877b3582d32bd11abd83a97b4399ad.tar.gz yuescript-94f8330613877b3582d32bd11abd83a97b4399ad.tar.bz2 yuescript-94f8330613877b3582d32bd11abd83a97b4399ad.zip | |
adding -w option to Yuescript tool.
Diffstat (limited to 'src/3rdParty/efsw/DirectorySnapshot.cpp')
| -rwxr-xr-x | src/3rdParty/efsw/DirectorySnapshot.cpp | 212 |
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 | |||
| 4 | namespace efsw { | ||
| 5 | |||
| 6 | DirectorySnapshot::DirectorySnapshot() {} | ||
| 7 | |||
| 8 | DirectorySnapshot::DirectorySnapshot( std::string directory ) { | ||
| 9 | init( directory ); | ||
| 10 | } | ||
| 11 | |||
| 12 | DirectorySnapshot::~DirectorySnapshot() {} | ||
| 13 | |||
| 14 | void DirectorySnapshot::init( std::string directory ) { | ||
| 15 | setDirectoryInfo( directory ); | ||
| 16 | initFiles(); | ||
| 17 | } | ||
| 18 | |||
| 19 | bool DirectorySnapshot::exists() { | ||
| 20 | return DirectoryInfo.exists(); | ||
| 21 | } | ||
| 22 | |||
| 23 | void 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 | |||
| 39 | void DirectorySnapshot::setDirectoryInfo( std::string directory ) { | ||
| 40 | DirectoryInfo = FileInfo( directory ); | ||
| 41 | } | ||
| 42 | |||
| 43 | void 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 | |||
| 62 | DirectorySnapshotDiff 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 | |||
| 174 | FileInfoMap::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 | |||
| 188 | void DirectorySnapshot::addFile( std::string path ) { | ||
| 189 | std::string name( FileSystem::fileNameFromPath( path ) ); | ||
| 190 | Files[name] = FileInfo( path ); | ||
| 191 | } | ||
| 192 | |||
| 193 | void 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 | |||
| 203 | void DirectorySnapshot::moveFile( std::string oldPath, std::string newPath ) { | ||
| 204 | removeFile( oldPath ); | ||
| 205 | addFile( newPath ); | ||
| 206 | } | ||
| 207 | |||
| 208 | void DirectorySnapshot::updateFile( std::string path ) { | ||
| 209 | addFile( path ); | ||
| 210 | } | ||
| 211 | |||
| 212 | } // namespace efsw | ||
