| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
| 3  * Copyright (C) 2006-2017 eyeo GmbH | 3  * Copyright (C) 2006-2017 eyeo GmbH | 
| 4  * | 4  * | 
| 5  * Adblock Plus is free software: you can redistribute it and/or modify | 5  * Adblock Plus is free software: you can redistribute it and/or modify | 
| 6  * it under the terms of the GNU General Public License version 3 as | 6  * it under the terms of the GNU General Public License version 3 as | 
| 7  * published by the Free Software Foundation. | 7  * published by the Free Software Foundation. | 
| 8  * | 8  * | 
| 9  * Adblock Plus is distributed in the hope that it will be useful, | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
| 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 12  * GNU General Public License for more details. | 12  * GNU General Public License for more details. | 
| 13  * | 13  * | 
| 14  * You should have received a copy of the GNU General Public License | 14  * You should have received a copy of the GNU General Public License | 
| 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| 16  */ | 16  */ | 
| 17 | 17 | 
| 18 #include <AdblockPlus/DefaultFileSystem.h> | 18 #include <AdblockPlus/DefaultFileSystem.h> | 
| 19 #include <cstdio> | 19 #include <cstdio> | 
| 20 #include <cstring> | 20 #include <cstring> | 
| 21 #include <fstream> | 21 #include <fstream> | 
|  | 22 #include <sstream> | 
| 22 #include <stdexcept> | 23 #include <stdexcept> | 
|  | 24 #include <thread> | 
| 23 | 25 | 
| 24 #include <sys/types.h> | 26 #include <sys/types.h> | 
| 25 | 27 | 
| 26 #ifdef _WIN32 | 28 #ifdef _WIN32 | 
| 27 #include <windows.h> | 29 #include <windows.h> | 
| 28 #include <Shlobj.h> | 30 #include <Shlobj.h> | 
| 29 #include <Shlwapi.h> | 31 #include <Shlwapi.h> | 
| 30 #else | 32 #else | 
| 31 #include <sys/stat.h> | 33 #include <sys/stat.h> | 
| 32 #include <cerrno> | 34 #include <cerrno> | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 60   // POSIX systems: assume that file system encoding is UTF-8 and just use the | 62   // POSIX systems: assume that file system encoding is UTF-8 and just use the | 
| 61   // file paths as they are. | 63   // file paths as they are. | 
| 62   std::string NormalizePath(const std::string& path) | 64   std::string NormalizePath(const std::string& path) | 
| 63   { | 65   { | 
| 64     return path; | 66     return path; | 
| 65   } | 67   } | 
| 66 #endif | 68 #endif | 
| 67 } | 69 } | 
| 68 | 70 | 
| 69 std::shared_ptr<std::istream> | 71 std::shared_ptr<std::istream> | 
| 70 DefaultFileSystem::Read(const std::string& path) const | 72 DefaultFileSystemSync::Read(const std::string& path) const | 
| 71 { | 73 { | 
| 72   std::shared_ptr<std::istream> result(new std::ifstream(NormalizePath(path).c_s
     tr())); | 74   std::shared_ptr<std::istream> result(new std::ifstream(NormalizePath(path).c_s
     tr())); | 
| 73   if (result->fail()) | 75   if (result->fail()) | 
| 74     throw RuntimeErrorWithErrno("Failed to open " + path); | 76     throw RuntimeErrorWithErrno("Failed to open " + path); | 
| 75   return result; | 77   return result; | 
| 76 } | 78 } | 
| 77 | 79 | 
| 78 void DefaultFileSystem::Write(const std::string& path, | 80 | 
| 79                               std::istream& data) | 81 void DefaultFileSystemSync::Write(const std::string& path, | 
|  | 82                                   std::istream& data) | 
| 80 { | 83 { | 
| 81   std::ofstream file(NormalizePath(path).c_str(), std::ios_base::out | std::ios_
     base::binary); | 84   std::ofstream file(NormalizePath(path).c_str(), std::ios_base::out | std::ios_
     base::binary); | 
| 82   file << Utils::Slurp(data); | 85   file << Utils::Slurp(data); | 
| 83 } | 86 } | 
| 84 | 87 | 
| 85 void DefaultFileSystem::Move(const std::string& fromPath, | 88 void DefaultFileSystemSync::Move(const std::string& fromPath, | 
| 86                              const std::string& toPath) | 89                                  const std::string& toPath) | 
| 87 { | 90 { | 
| 88   if (rename(NormalizePath(fromPath).c_str(), NormalizePath(toPath).c_str())) | 91   if (rename(NormalizePath(fromPath).c_str(), NormalizePath(toPath).c_str())) | 
| 89     throw RuntimeErrorWithErrno("Failed to move " + fromPath + " to " + toPath); | 92     throw RuntimeErrorWithErrno("Failed to move " + fromPath + " to " + toPath); | 
| 90 } | 93 } | 
| 91 | 94 | 
| 92 void DefaultFileSystem::Remove(const std::string& path) | 95 void DefaultFileSystemSync::Remove(const std::string& path) | 
| 93 { | 96 { | 
| 94   if (remove(NormalizePath(path).c_str())) | 97   if (remove(NormalizePath(path).c_str())) | 
| 95     throw RuntimeErrorWithErrno("Failed to remove " + path); | 98     throw RuntimeErrorWithErrno("Failed to remove " + path); | 
| 96 } | 99 } | 
| 97 | 100 | 
| 98 FileSystem::StatResult DefaultFileSystem::Stat(const std::string& path) const | 101 IFileSystem::StatResult DefaultFileSystemSync::Stat(const std::string& path) con
     st | 
| 99 { | 102 { | 
| 100   FileSystem::StatResult result; | 103   IFileSystem::StatResult result; | 
| 101 #ifdef WIN32 | 104 #ifdef WIN32 | 
| 102   WIN32_FILE_ATTRIBUTE_DATA data; | 105   WIN32_FILE_ATTRIBUTE_DATA data; | 
| 103   if (!GetFileAttributesExW(NormalizePath(path).c_str(), GetFileExInfoStandard, 
     &data)) | 106   if (!GetFileAttributesExW(NormalizePath(path).c_str(), GetFileExInfoStandard, 
     &data)) | 
| 104   { | 107   { | 
| 105     DWORD err = GetLastError(); | 108     DWORD err = GetLastError(); | 
| 106     if (err == ERROR_FILE_NOT_FOUND || | 109     if (err == ERROR_FILE_NOT_FOUND || | 
| 107         err == ERROR_PATH_NOT_FOUND || | 110         err == ERROR_PATH_NOT_FOUND || | 
| 108         err == ERROR_INVALID_DRIVE) | 111         err == ERROR_INVALID_DRIVE) | 
| 109     { | 112     { | 
| 110       return result; | 113       return result; | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 154 #if _POSIX_C_SOURCE >= 200809L | 157 #if _POSIX_C_SOURCE >= 200809L | 
| 155   result.lastModified = static_cast<int64_t>(nativeStat.st_mtim.tv_sec) * MSEC_I
     N_SEC | 158   result.lastModified = static_cast<int64_t>(nativeStat.st_mtim.tv_sec) * MSEC_I
     N_SEC | 
| 156                       +  static_cast<int64_t>(nativeStat.st_mtim.tv_nsec) / NSEC
     _IN_MSEC; | 159                       +  static_cast<int64_t>(nativeStat.st_mtim.tv_nsec) / NSEC
     _IN_MSEC; | 
| 157 #else | 160 #else | 
| 158   result.lastModified = static_cast<int64_t>(nativeStat.st_mtime) * MSEC_IN_SEC; | 161   result.lastModified = static_cast<int64_t>(nativeStat.st_mtime) * MSEC_IN_SEC; | 
| 159 #endif | 162 #endif | 
| 160   return result; | 163   return result; | 
| 161 #endif | 164 #endif | 
| 162 } | 165 } | 
| 163 | 166 | 
| 164 std::string DefaultFileSystem::Resolve(const std::string& path) const | 167 std::string DefaultFileSystemSync::Resolve(const std::string& path) const | 
| 165 { | 168 { | 
| 166   if (basePath == "") | 169   if (basePath == "") | 
| 167   { | 170   { | 
| 168     return path; | 171     return path; | 
| 169   } | 172   } | 
| 170   else | 173   else | 
| 171   { | 174   { | 
| 172 #ifdef _WIN32 | 175 #ifdef _WIN32 | 
| 173   if (PathIsRelative(NormalizePath(path).c_str())) | 176   if (PathIsRelative(NormalizePath(path).c_str())) | 
| 174 #else | 177 #else | 
| 175   if (path.length() && *path.begin() != PATH_SEPARATOR) | 178   if (path.length() && *path.begin() != PATH_SEPARATOR) | 
| 176 #endif | 179 #endif | 
| 177     { | 180     { | 
| 178       return basePath + PATH_SEPARATOR + path; | 181       return basePath + PATH_SEPARATOR + path; | 
| 179     } | 182     } | 
| 180     else | 183     else | 
| 181     { | 184     { | 
| 182       return path; | 185       return path; | 
| 183     } | 186     } | 
| 184   } | 187   } | 
| 185 } | 188 } | 
| 186 | 189 | 
| 187 void DefaultFileSystem::SetBasePath(const std::string& path) | 190 void DefaultFileSystemSync::SetBasePath(const std::string& path) | 
| 188 { | 191 { | 
| 189   basePath = path; | 192   basePath = path; | 
| 190 | 193 | 
| 191   if (*basePath.rbegin() == PATH_SEPARATOR) | 194   if (*basePath.rbegin() == PATH_SEPARATOR) | 
| 192   { | 195   { | 
| 193     basePath.resize(basePath.size() - 1); | 196     basePath.resize(basePath.size() - 1); | 
| 194   } | 197   } | 
| 195 } | 198 } | 
| 196 | 199 | 
|  | 200 DefaultFileSystem::DefaultFileSystem(const FileSystemSyncPtr& syncImpl) | 
|  | 201   : syncImpl(syncImpl) | 
|  | 202 { | 
|  | 203 } | 
|  | 204 | 
|  | 205 void DefaultFileSystem::Read(const std::string& path, | 
|  | 206                              const ReadCallback& callback) const | 
|  | 207 { | 
|  | 208   auto impl = syncImpl; | 
|  | 209   std::thread([impl, path, callback] | 
|  | 210   { | 
|  | 211     std::string error; | 
|  | 212     try | 
|  | 213     { | 
|  | 214       auto result = impl->Read(path); | 
|  | 215       std::stringstream output; | 
|  | 216       output << result->rdbuf(); | 
|  | 217       std::string buffer = output.str(); | 
|  | 218       callback(std::move(buffer), error); | 
|  | 219       return; | 
|  | 220     } | 
|  | 221     catch (std::exception& e) | 
|  | 222     { | 
|  | 223       error = e.what(); | 
|  | 224     } | 
|  | 225     catch (...) | 
|  | 226     { | 
|  | 227       error =  "Unknown error while reading from " + path; | 
|  | 228     } | 
|  | 229     callback(std::string(), error); | 
|  | 230   }).detach(); | 
|  | 231 } | 
|  | 232 | 
|  | 233 void DefaultFileSystem::Write(const std::string& path, | 
|  | 234                               std::shared_ptr<std::istream> data, | 
|  | 235                               const Callback& callback) | 
|  | 236 { | 
|  | 237   auto impl = syncImpl; | 
|  | 238   std::thread([impl, path, data, callback] | 
|  | 239   { | 
|  | 240     std::string error; | 
|  | 241     try | 
|  | 242     { | 
|  | 243       impl->Write(path, *data); | 
|  | 244     } | 
|  | 245     catch (std::exception& e) | 
|  | 246     { | 
|  | 247       error = e.what(); | 
|  | 248     } | 
|  | 249     catch (...) | 
|  | 250     { | 
|  | 251       error = "Unknown error while writing to " + path; | 
|  | 252     } | 
|  | 253     callback(error); | 
|  | 254   }).detach(); | 
|  | 255 } | 
|  | 256 | 
|  | 257 void DefaultFileSystem::Move(const std::string& fromPath, | 
|  | 258                              const std::string& toPath, | 
|  | 259                              const Callback& callback) | 
|  | 260 { | 
|  | 261   auto impl = syncImpl; | 
|  | 262   std::thread([impl, fromPath, toPath, callback] | 
|  | 263   { | 
|  | 264     std::string error; | 
|  | 265     try | 
|  | 266     { | 
|  | 267       impl->Move(fromPath, toPath); | 
|  | 268     } | 
|  | 269     catch (std::exception& e) | 
|  | 270     { | 
|  | 271       error = e.what(); | 
|  | 272     } | 
|  | 273     catch (...) | 
|  | 274     { | 
|  | 275       error = "Unknown error while moving " + fromPath + " to " + toPath; | 
|  | 276     } | 
|  | 277     callback(error); | 
|  | 278   }).detach(); | 
|  | 279 } | 
|  | 280 | 
|  | 281 void DefaultFileSystem::Remove(const std::string& path, | 
|  | 282                                const Callback& callback) | 
|  | 283 { | 
|  | 284   auto impl = syncImpl; | 
|  | 285   std::thread([impl, path, callback] | 
|  | 286   { | 
|  | 287     std::string error; | 
|  | 288     try | 
|  | 289     { | 
|  | 290       impl->Remove(path); | 
|  | 291     } | 
|  | 292     catch (std::exception& e) | 
|  | 293     { | 
|  | 294       error = e.what(); | 
|  | 295     } | 
|  | 296     catch (...) | 
|  | 297     { | 
|  | 298       error = "Unknown error while removing " + path; | 
|  | 299     } | 
|  | 300     callback(error); | 
|  | 301   }).detach(); | 
|  | 302 } | 
|  | 303 | 
|  | 304 void DefaultFileSystem::Stat(const std::string& path, | 
|  | 305                              const StatCallback& callback) const | 
|  | 306 { | 
|  | 307   auto impl = syncImpl; | 
|  | 308   std::thread([impl, path, callback] | 
|  | 309   { | 
|  | 310     std::string error; | 
|  | 311     try | 
|  | 312     { | 
|  | 313       auto result = impl->Stat(path); | 
|  | 314       callback(result, error); | 
|  | 315       return; | 
|  | 316     } | 
|  | 317     catch (std::exception& e) | 
|  | 318     { | 
|  | 319       error = e.what(); | 
|  | 320     } | 
|  | 321     catch (...) | 
|  | 322     { | 
|  | 323       error = "Unknown error while calling stat on " + path; | 
|  | 324     } | 
|  | 325     callback(StatResult(), error); | 
|  | 326   }).detach(); | 
|  | 327 } | 
|  | 328 | 
|  | 329 std::string DefaultFileSystem::Resolve(const std::string& path) const | 
|  | 330 { | 
|  | 331   return syncImpl->Resolve(path); | 
|  | 332 } | 
| OLD | NEW | 
|---|