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

Unified Diff: src/DefaultFileSystem.cpp

Issue 10421060: Make sure to work properly with Unicode paths on Windows (Closed)
Patch Set: Created May 14, 2013, 1: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
« no previous file with comments | « no previous file | test/DefaultFileSystem.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/DefaultFileSystem.cpp
===================================================================
--- a/src/DefaultFileSystem.cpp
+++ b/src/DefaultFileSystem.cpp
@@ -41,51 +41,65 @@ namespace
class RuntimeErrorWithErrno : public std::runtime_error
{
public:
explicit RuntimeErrorWithErrno(const std::string& message)
: std::runtime_error(message + " (" + strerror(errno) + ")")
{
}
};
+
+#ifdef WIN32
+ // Paths need to be converted from UTF-8 to UTF-16 on Windows.
+ std::wstring NormalizePath(const std::string& path)
+ {
+ return Utils::ToUTF16String(path, path.length());
+ }
+
+ #define rename _wrename
+ #define remove _wremove
+#else
+ // POSIX systems: assume that file system encoding is UTF-8 and just use the
+ // file paths as they are.
+ #define NormalizePath(path) (path)
Felix Dahlke 2013/05/17 09:38:14 Would rather see a function here, macros can cause
+#endif
}
std::tr1::shared_ptr<std::istream>
DefaultFileSystem::Read(const std::string& path) const
{
- return std::tr1::shared_ptr<std::istream>(new std::ifstream(path.c_str()));
+ return std::tr1::shared_ptr<std::istream>(new std::ifstream(NormalizePath(path).c_str()));
}
void DefaultFileSystem::Write(const std::string& path,
std::tr1::shared_ptr<std::ostream> data)
{
- std::ofstream file(path.c_str());
+ std::ofstream file(NormalizePath(path).c_str());
file << Utils::Slurp(*data);
}
void DefaultFileSystem::Move(const std::string& fromPath,
const std::string& toPath)
{
- if (rename(fromPath.c_str(), toPath.c_str()))
+ 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)
{
- if (remove(path.c_str()))
+ if (remove(NormalizePath(path).c_str()))
throw RuntimeErrorWithErrno("Failed to remove " + path);
}
FileSystem::StatResult DefaultFileSystem::Stat(const std::string& path) const
{
FileSystem::StatResult result;
#ifdef WIN32
WIN32_FILE_ATTRIBUTE_DATA data;
- std::wstring wpath = Utils::ToUTF16String(path, path.length());
- if (!GetFileAttributesExW(wpath.c_str(), GetFileExInfoStandard, &data))
+ if (!GetFileAttributesExW(NormalizePath(path).c_str(), GetFileExInfoStandard, &data))
{
DWORD err = GetLastError();
if (err == ERROR_FILE_NOT_FOUND || ERROR_PATH_NOT_FOUND || ERROR_INVALID_DRIVE)
return result;
throw RuntimeErrorWithErrno("Unable to stat " + path);
}
result.exists = true;
@@ -106,17 +120,17 @@ FileSystem::StatResult DefaultFileSystem
ULARGE_INTEGER time;
time.LowPart = data.ftLastWriteTime.dwLowDateTime;
time.HighPart = data.ftLastWriteTime.dwHighDateTime;
result.lastModified = (time.QuadPart - FILE_TIME_TO_UNIX_EPOCH_OFFSET) /
FILE_TIME_TO_MILLISECONDS_FACTOR;
return result;
#else
struct stat nativeStat;
- const int failure = stat(path.c_str(), &nativeStat);
+ const int failure = stat(NormalizePath(path).c_str(), &nativeStat);
if (failure)
{
if (errno == ENOENT)
return result;
throw RuntimeErrorWithErrno("Unable to stat " + path);
}
result.exists = true;
result.isFile = S_ISREG(nativeStat.st_mode);
« no previous file with comments | « no previous file | test/DefaultFileSystem.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld