Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: src/DefaultFileSystem.cpp

Issue 29449592: Issue 5183 - Provide async interface for FileSystem (Closed) Base URL: https://hg.adblockplus.org/libadblockplus/
Patch Set: Remove a #include Utils.h from test. Created June 2, 2017, 7:38 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
@@ -62,47 +64,48 @@
std::string NormalizePath(const std::string& path)
{
return path;
}
#endif
}
std::shared_ptr<std::istream>
-DefaultFileSystem::Read(const std::string& path) const
+DefaultFileSystemSync::Read(const std::string& path) const
{
std::shared_ptr<std::istream> result(new std::ifstream(NormalizePath(path).c_str()));
if (result->fail())
throw RuntimeErrorWithErrno("Failed to open " + path);
return result;
}
-void DefaultFileSystem::Write(const std::string& path,
- std::istream& data)
+
+void DefaultFileSystemSync::Write(const std::string& path,
+ std::istream& data)
{
std::ofstream file(NormalizePath(path).c_str(), std::ios_base::out | std::ios_base::binary);
file << Utils::Slurp(data);
}
-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)
@@ -156,17 +159,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
@@ -179,18 +182,151 @@
}
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 result = impl->Read(path);
+ std::stringstream output;
+ output << result->rdbuf();
+ std::string buffer = output.str();
+ callback(std::move(buffer), error);
+ return;
+ }
+ catch (std::exception& e)
+ {
+ error = e.what();
+ }
+ catch (...)
+ {
+ error = "Unknown error while reading from " + path;
+ }
+ callback(std::string(), error);
+ }).detach();
+}
+
+void DefaultFileSystem::Write(const std::string& path,
+ std::shared_ptr<std::istream> 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);
+}

Powered by Google App Engine
This is Rietveld