#pragma once #include #include #ifdef USE_GHC_FILESYSTEM #include namespace fs = ghc::filesystem; #else #include namespace fs { using namespace std::filesystem; using ifstream = std::ifstream; using ofstream = std::ofstream; using fstream = std::fstream; } // namespace fs #endif #ifndef _MSC_VER #include #endif #include namespace llarp { namespace util { struct FileHash { size_t operator()(const fs::path& f) const { std::hash h; return h(f.string()); } }; using error_code_t = std::error_code; /// Ensure that a file exists and has correct permissions /// return any error code or success error_code_t EnsurePrivateFile(fs::path pathname); /// open a stream to a file and ensure it exists before open /// sets any permissions on creation template std::optional OpenFileStream(fs::path pathname, std::ios::openmode mode) { if (EnsurePrivateFile(pathname)) return {}; return std::make_optional(pathname, mode); } template static void IterDir(const fs::path& path, PathVisitor visit) { DIR* d = opendir(path.string().c_str()); if (d == nullptr) return; struct dirent* ent = nullptr; std::set entries; do { ent = readdir(d); if (not ent) break; if (ent->d_name[0] == '.') continue; entries.emplace(path / fs::path{ent->d_name}); } while (ent); closedir(d); for (const auto& p : entries) { if (not visit(p)) return; } }; } // namespace util } // namespace llarp