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
|
#ifdef _WIN32
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
|
|
||||||
|
#include <codecvt>
|
||||||
|
#include <locale>
|
||||||
#else
|
#else
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
@ -86,11 +89,32 @@ class DirectoryListing {
|
||||||
struct dirent* next_entry_ = nullptr;
|
struct dirent* next_entry_ = nullptr;
|
||||||
};
|
};
|
||||||
#else
|
#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 {
|
class DirectoryListing {
|
||||||
public:
|
public:
|
||||||
explicit DirectoryListing(const std::string& directory) {
|
explicit DirectoryListing(const std::string& directory)
|
||||||
directory_ = directory;
|
: directory_(Utf8ToNative(directory)) {
|
||||||
std::string search_string = directory + "\\*.*";
|
PathString search_string = directory_ + Utf8ToNative("\\*.*");
|
||||||
find_handle_ = FindFirstFile(search_string.c_str(), &find_data_);
|
find_handle_ = FindFirstFile(search_string.c_str(), &find_data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,10 +131,10 @@ class DirectoryListing {
|
||||||
// after the one that is returned, if it exists.
|
// after the one that is returned, if it exists.
|
||||||
std::string NextEntry() {
|
std::string NextEntry() {
|
||||||
if (HasNextEntry()) {
|
if (HasNextEntry()) {
|
||||||
std::string result =
|
PathString result =
|
||||||
std::string(directory_ + "\\" + find_data_.cFileName);
|
directory_ + Utf8ToNative("\\") + PathString(find_data_.cFileName);
|
||||||
ReadNextEntry();
|
ReadNextEntry();
|
||||||
return result;
|
return NativeToUtf8(result);
|
||||||
} else {
|
} else {
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
@ -119,8 +143,9 @@ class DirectoryListing {
|
||||||
private:
|
private:
|
||||||
void ReadNextEntry() {
|
void ReadNextEntry() {
|
||||||
int find_result = FindNextFile(find_handle_, &find_data_);
|
int find_result = FindNextFile(find_handle_, &find_data_);
|
||||||
while (find_result != 0 && (std::string(find_data_.cFileName) == "." ||
|
while (find_result != 0 &&
|
||||||
std::string(find_data_.cFileName) == "..")) {
|
(PathString(find_data_.cFileName) == FILE_PATH_LITERAL(".") ||
|
||||||
|
PathString(find_data_.cFileName) == FILE_PATH_LITERAL(".."))) {
|
||||||
find_result = FindNextFile(find_handle_, &find_data_);
|
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;
|
HANDLE find_handle_ = INVALID_HANDLE_VALUE;
|
||||||
WIN32_FIND_DATA find_data_;
|
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::Status SetContents(absl::string_view file_name,
|
||||||
absl::string_view content) {
|
absl::string_view content) {
|
||||||
FILE* fp = fopen(file_name.data(), "w");
|
FILE* fp = fopen(file_name.data(), "wb");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
return mediapipe::InvalidArgumentErrorBuilder(MEDIAPIPE_LOC)
|
return mediapipe::InvalidArgumentErrorBuilder(MEDIAPIPE_LOC)
|
||||||
<< "Can't open file: " << file_name;
|
<< "Can't open file: " << file_name;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user