#pragma once #include "fs.hpp" #include #include #include #include #ifndef _MSC_VER #include #endif namespace llarp::util { /// Reads a binary file from disk into a string. Throws on error. std::string file_to_string(const fs::path& filename); /// Reads a binary file from disk directly into a buffer. Throws a std::length_error if the /// file is bigger than the buffer. Returns the bytes copied on success. size_t file_to_buffer(const fs::path& filename, char* buffer, size_t buffer_size); /// Same, but for some non-char but single-byte char type (e.g. byte_t, std::byte, unsigned char). template < typename Char, std::enable_if_t, int> = 1> size_t file_to_buffer(const fs::path& filename, Char* buffer, size_t buffer_size) { return file_to_buffer(filename, reinterpret_cast(buffer), buffer_size); } /// Dumps binary string contents to disk. The file is overwritten if it already exists. Throws /// on error. void buffer_to_file(const fs::path& filename, std::string_view contents); /// Same as above, but works via char-like buffer template = 0> void buffer_to_file(const fs::path& filename, const Char* buffer, size_t buffer_size) { return buffer_to_file( filename, std::string_view{reinterpret_cast(buffer), buffer_size}); } 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); } } // namespace llarp::util