Fixes two issues with file handling on windows:
. If UNICODE is set, then win32 functions taking file paths use wide (utf-16) strings. For example, FindFirstFile really calls to FindFirstFileW, which takes a wchar_t*. This adds support for the unicode path. . SetContents() changes from "w" to "wb". This is necessary as windows will do some amount of encoding without "b", which results in much different values being written. PiperOrigin-RevId: 564842317
This commit is contained in:
parent
dbcdb44f7c
commit
5b08a09446
|
@ -17,6 +17,9 @@
|
|||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#include <direct.h>
|
||||
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif // _WIN32
|
||||
|
@ -86,11 +89,32 @@ class DirectoryListing {
|
|||
struct dirent* next_entry_ = nullptr;
|
||||
};
|
||||
#else
|
||||
#if defined(UNICODE)
|
||||
using PathString = std::wstring;
|
||||
|
||||
PathString Utf8ToNative(const std::string& string) {
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
|
||||
return converter.from_bytes(string.data(), string.data() + string.size());
|
||||
}
|
||||
std::string NativeToUtf8(const PathString& string) {
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
|
||||
return converter.to_bytes(string.data(), string.data() + string.size());
|
||||
}
|
||||
#define FILE_PATH_LITERAL_INTERNAL(x) L##x
|
||||
#define FILE_PATH_LITERAL(x) FILE_PATH_LITERAL_INTERNAL(x)
|
||||
#else
|
||||
using PathString = std::string;
|
||||
PathString Utf8ToNative(const std::string& string) { return string; }
|
||||
std::string NativeToUtf8(const PathString& string) { return string; }
|
||||
#define FILE_PATH_LITERAL_INTERNAL(x) ##x
|
||||
#define FILE_PATH_LITERAL(x) FILE_PATH_LITERAL_INTERNAL(x)
|
||||
#endif
|
||||
|
||||
class DirectoryListing {
|
||||
public:
|
||||
explicit DirectoryListing(const std::string& directory) {
|
||||
directory_ = directory;
|
||||
std::string search_string = directory + "\\*.*";
|
||||
explicit DirectoryListing(const std::string& directory)
|
||||
: directory_(Utf8ToNative(directory)) {
|
||||
PathString search_string = directory_ + Utf8ToNative("\\*.*");
|
||||
find_handle_ = FindFirstFile(search_string.c_str(), &find_data_);
|
||||
}
|
||||
|
||||
|
@ -107,10 +131,10 @@ class DirectoryListing {
|
|||
// after the one that is returned, if it exists.
|
||||
std::string NextEntry() {
|
||||
if (HasNextEntry()) {
|
||||
std::string result =
|
||||
std::string(directory_ + "\\" + find_data_.cFileName);
|
||||
PathString result =
|
||||
directory_ + Utf8ToNative("\\") + PathString(find_data_.cFileName);
|
||||
ReadNextEntry();
|
||||
return result;
|
||||
return NativeToUtf8(result);
|
||||
} else {
|
||||
return std::string();
|
||||
}
|
||||
|
@ -119,8 +143,9 @@ class DirectoryListing {
|
|||
private:
|
||||
void ReadNextEntry() {
|
||||
int find_result = FindNextFile(find_handle_, &find_data_);
|
||||
while (find_result != 0 && (std::string(find_data_.cFileName) == "." ||
|
||||
std::string(find_data_.cFileName) == "..")) {
|
||||
while (find_result != 0 &&
|
||||
(PathString(find_data_.cFileName) == FILE_PATH_LITERAL(".") ||
|
||||
PathString(find_data_.cFileName) == FILE_PATH_LITERAL(".."))) {
|
||||
find_result = FindNextFile(find_handle_, &find_data_);
|
||||
}
|
||||
|
||||
|
@ -130,7 +155,7 @@ class DirectoryListing {
|
|||
}
|
||||
}
|
||||
|
||||
std::string directory_;
|
||||
const PathString directory_;
|
||||
HANDLE find_handle_ = INVALID_HANDLE_VALUE;
|
||||
WIN32_FIND_DATA find_data_;
|
||||
};
|
||||
|
@ -162,7 +187,7 @@ absl::Status GetContents(absl::string_view file_name, std::string* output,
|
|||
|
||||
absl::Status SetContents(absl::string_view file_name,
|
||||
absl::string_view content) {
|
||||
FILE* fp = fopen(file_name.data(), "w");
|
||||
FILE* fp = fopen(file_name.data(), "wb");
|
||||
if (fp == NULL) {
|
||||
return mediapipe::InvalidArgumentErrorBuilder(MEDIAPIPE_LOC)
|
||||
<< "Can't open file: " << file_name;
|
||||
|
|
Loading…
Reference in New Issue
Block a user