#include "quiche_platform_impl/quiche_file_utils_impl.h"
#if defined(_WIN32)
#include <windows.h>
#else
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#include <fstream>
#include <ios>
#include <iostream>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
namespace quiche {
#if defined(_WIN32)
std::string JoinPathImpl(absl::string_view a, absl::string_view b) {
if (a.empty()) {
return std::string(b);
}
if (b.empty()) {
return std::string(a);
}
a = absl::StripSuffix(a, "/");
a = absl::StripSuffix(a, "\\");
return absl::StrCat(a, "\\", b);
}
#else
std::string JoinPathImpl(absl::string_view a, absl::string_view b) { … }
#endif
std::optional<std::string> ReadFileContentsImpl(absl::string_view file) { … }
#if defined(_WIN32)
class ScopedDir {
public:
ScopedDir(HANDLE dir) : dir_(dir) {}
~ScopedDir() {
if (dir_ != INVALID_HANDLE_VALUE) {
FindClose(dir_);
dir_ = INVALID_HANDLE_VALUE;
}
}
HANDLE get() { return dir_; }
private:
HANDLE dir_;
};
bool EnumerateDirectoryImpl(absl::string_view path,
std::vector<std::string>& directories,
std::vector<std::string>& files) {
std::string path_owned(path);
DWORD attributes = GetFileAttributesA(path_owned.c_str());
if (attributes == INVALID_FILE_ATTRIBUTES) {
return false;
}
if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
return false;
}
std::string search_path = JoinPathImpl(path, "*");
WIN32_FIND_DATAA file_data;
ScopedDir dir(FindFirstFileA(search_path.c_str(), &file_data));
if (dir.get() == INVALID_HANDLE_VALUE) {
return GetLastError() == ERROR_FILE_NOT_FOUND;
}
do {
std::string filename(file_data.cFileName);
if (filename == "." || filename == "..") {
continue;
}
if ((file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
directories.push_back(std::move(filename));
} else {
files.push_back(std::move(filename));
}
} while (FindNextFileA(dir.get(), &file_data));
return GetLastError() == ERROR_NO_MORE_FILES;
}
#else
class ScopedDir { … };
bool EnumerateDirectoryImpl(absl::string_view path,
std::vector<std::string>& directories,
std::vector<std::string>& files) { … }
#endif
}