| Index: src/DefaultFileSystem.cpp |
| =================================================================== |
| --- a/src/DefaultFileSystem.cpp |
| +++ b/src/DefaultFileSystem.cpp |
| @@ -14,17 +14,19 @@ |
| * You should have received a copy of the GNU General Public License |
| * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| #include <AdblockPlus/DefaultFileSystem.h> |
| #include <cstdio> |
| #include <cstring> |
| #include <fstream> |
| +#include <sstream> |
| #include <stdexcept> |
| +#include <thread> |
| #include <sys/types.h> |
| #ifdef _WIN32 |
| #include <windows.h> |
| #include <Shlobj.h> |
| #include <Shlwapi.h> |
| #else |
| @@ -61,57 +63,57 @@ |
| // file paths as they are. |
| std::string NormalizePath(const std::string& path) |
| { |
| return path; |
| } |
| #endif |
| } |
| -FileSystem::IOBuffer |
| -DefaultFileSystem::Read(const std::string& path) const |
| +IFileSystem::IOBuffer |
| +DefaultFileSystemSync::Read(const std::string& path) const |
|
sergei
2017/07/07 13:41:01
It's actually not our coding style, but I think it
|
| { |
| std::ifstream file(NormalizePath(path).c_str(), std::ios_base::binary); |
| if (file.fail()) |
| throw RuntimeErrorWithErrno("Failed to open " + path); |
| file.seekg(0, std::ios_base::end); |
| auto dataSize = file.tellg(); |
| file.seekg(0, std::ios_base::beg); |
| - IOBuffer data(dataSize); |
| + IFileSystem::IOBuffer data(dataSize); |
| file.read(reinterpret_cast<std::ifstream::char_type*>(data.data()), |
| data.size()); |
| return data; |
| } |
| -void DefaultFileSystem::Write(const std::string& path, |
| - const IOBuffer& data) |
| +void DefaultFileSystemSync::Write(const std::string& path, |
| + const IFileSystem::IOBuffer& data) |
| { |
| std::ofstream file(NormalizePath(path).c_str(), std::ios_base::out | std::ios_base::binary); |
| file.write(reinterpret_cast<const std::ofstream::char_type*>(data.data()), |
| data.size()); |
| } |
| -void DefaultFileSystem::Move(const std::string& fromPath, |
| - const std::string& toPath) |
| +void DefaultFileSystemSync::Move(const std::string& fromPath, |
| + const std::string& toPath) |
| { |
| if (rename(NormalizePath(fromPath).c_str(), NormalizePath(toPath).c_str())) |
| throw RuntimeErrorWithErrno("Failed to move " + fromPath + " to " + toPath); |
| } |
| -void DefaultFileSystem::Remove(const std::string& path) |
| +void DefaultFileSystemSync::Remove(const std::string& path) |
| { |
| if (remove(NormalizePath(path).c_str())) |
| throw RuntimeErrorWithErrno("Failed to remove " + path); |
| } |
| -FileSystem::StatResult DefaultFileSystem::Stat(const std::string& path) const |
| +IFileSystem::StatResult DefaultFileSystemSync::Stat(const std::string& path) const |
| { |
| - FileSystem::StatResult result; |
| + IFileSystem::StatResult result; |
| #ifdef WIN32 |
| WIN32_FILE_ATTRIBUTE_DATA data; |
| if (!GetFileAttributesExW(NormalizePath(path).c_str(), GetFileExInfoStandard, &data)) |
| { |
| DWORD err = GetLastError(); |
| if (err == ERROR_FILE_NOT_FOUND || |
| err == ERROR_PATH_NOT_FOUND || |
| err == ERROR_INVALID_DRIVE) |
| @@ -165,17 +167,17 @@ |
| + static_cast<int64_t>(nativeStat.st_mtim.tv_nsec) / NSEC_IN_MSEC; |
| #else |
| result.lastModified = static_cast<int64_t>(nativeStat.st_mtime) * MSEC_IN_SEC; |
| #endif |
| return result; |
| #endif |
| } |
| -std::string DefaultFileSystem::Resolve(const std::string& path) const |
| +std::string DefaultFileSystemSync::Resolve(const std::string& path) const |
| { |
| if (basePath == "") |
| { |
| return path; |
| } |
| else |
| { |
| #ifdef _WIN32 |
| @@ -188,18 +190,148 @@ |
| } |
| else |
| { |
| return path; |
| } |
| } |
| } |
| -void DefaultFileSystem::SetBasePath(const std::string& path) |
| +void DefaultFileSystemSync::SetBasePath(const std::string& path) |
| { |
| basePath = path; |
| if (*basePath.rbegin() == PATH_SEPARATOR) |
| { |
| basePath.resize(basePath.size() - 1); |
| } |
| } |
| +DefaultFileSystem::DefaultFileSystem(const FileSystemSyncPtr& syncImpl) |
| + : syncImpl(syncImpl) |
| +{ |
| +} |
| + |
| +void DefaultFileSystem::Read(const std::string& path, |
| + const ReadCallback& callback) const |
| +{ |
| + auto impl = syncImpl; |
| + std::thread([impl, path, callback] |
| + { |
| + std::string error; |
| + try |
| + { |
| + auto data = impl->Read(path); |
| + callback(std::move(data), error); |
| + return; |
| + } |
| + catch (std::exception& e) |
| + { |
| + error = e.what(); |
| + } |
| + catch (...) |
| + { |
| + error = "Unknown error while reading from " + path; |
| + } |
| + callback(IOBuffer(), error); |
| + }).detach(); |
| +} |
| + |
| +void DefaultFileSystem::Write(const std::string& path, |
| + const IOBuffer& data, |
| + const Callback& callback) |
| +{ |
| + auto impl = syncImpl; |
| + std::thread([impl, path, data, callback] |
| + { |
| + std::string error; |
| + try |
| + { |
| + impl->Write(path, data); |
| + } |
| + catch (std::exception& e) |
| + { |
| + error = e.what(); |
| + } |
| + catch (...) |
| + { |
| + error = "Unknown error while writing to " + path; |
| + } |
| + callback(error); |
| + }).detach(); |
| +} |
| + |
| +void DefaultFileSystem::Move(const std::string& fromPath, |
| + const std::string& toPath, |
| + const Callback& callback) |
| +{ |
| + auto impl = syncImpl; |
| + std::thread([impl, fromPath, toPath, callback] |
| + { |
| + std::string error; |
| + try |
| + { |
| + impl->Move(fromPath, toPath); |
| + } |
| + catch (std::exception& e) |
| + { |
| + error = e.what(); |
| + } |
| + catch (...) |
| + { |
| + error = "Unknown error while moving " + fromPath + " to " + toPath; |
| + } |
| + callback(error); |
| + }).detach(); |
| +} |
| + |
| +void DefaultFileSystem::Remove(const std::string& path, |
| + const Callback& callback) |
| +{ |
| + auto impl = syncImpl; |
| + std::thread([impl, path, callback] |
| + { |
| + std::string error; |
| + try |
| + { |
| + impl->Remove(path); |
| + } |
| + catch (std::exception& e) |
| + { |
| + error = e.what(); |
| + } |
| + catch (...) |
| + { |
| + error = "Unknown error while removing " + path; |
| + } |
| + callback(error); |
| + }).detach(); |
| +} |
| + |
| +void DefaultFileSystem::Stat(const std::string& path, |
| + const StatCallback& callback) const |
| +{ |
| + auto impl = syncImpl; |
| + std::thread([impl, path, callback] |
| + { |
| + std::string error; |
| + try |
| + { |
| + auto result = impl->Stat(path); |
| + callback(result, error); |
| + return; |
| + } |
| + catch (std::exception& e) |
| + { |
| + error = e.what(); |
| + } |
| + catch (...) |
| + { |
| + error = "Unknown error while calling stat on " + path; |
| + } |
| + callback(StatResult(), error); |
| + }).detach(); |
| +} |
| + |
| +std::string DefaultFileSystem::Resolve(const std::string& path) const |
| +{ |
| + return syncImpl->Resolve(path); |
| +} |