2 #ifndef ENIGMA_FILE_UTILS_H
3 #define ENIGMA_FILE_UTILS_H
10 #if defined(__cpp_lib_filesystem)
12 namespace fs = std::filesystem;
13 #elif defined(__cpp_lib_experimental_filesystem)
14 #include <experimental/filesystem>
15 namespace fs = std::experimental::filesystem;
17 #error compiler does not support std::filesystem
26 static bool Read(
const fs::path& filename, std::vector<byte>& buffer) {
27 if (std::ifstream ifs{filename, std::ios::binary | std::ios::ate})
29 const std::size_t file_size =
static_cast<std::size_t
>(ifs.tellg());
30 buffer.resize(file_size,
'\000');
31 ifs.seekg(0, std::ios::beg);
32 ifs.read(
reinterpret_cast<char *
>(buffer.data()), file_size);
36 ENIGMA_ERROR(
"Failed to read file {}", filename.string());
41 static bool ReadString(
const fs::path& filename, std::string& buffer) {
42 if (std::ifstream ifs{filename, std::ios::binary | std::ios::ate})
44 const std::size_t file_size =
static_cast<std::size_t
>(ifs.tellg());
45 buffer.resize(file_size,
'\000');
46 ifs.seekg(0, std::ios::beg);
47 ifs.read(
reinterpret_cast<char *
>(buffer.data()), file_size);
51 ENIGMA_ERROR(
"Failed to read file {}", filename.string());
56 static bool Write(
const fs::path& filename,
const std::vector<byte>& buffer) {
57 if (std::ofstream ofs{filename, std::ios::binary}) {
58 ofs.write(
reinterpret_cast<const char *
>(buffer.data()), buffer.size());
62 ENIGMA_ERROR(
"Failed to write file {}", filename.string());
67 static bool WriteString(
const fs::path& filename,
const std::string& buffer) {
68 if (std::ofstream ofs{filename, std::ios::binary}) {
69 ofs.write(
reinterpret_cast<const char *
>(buffer.data()), buffer.size());
73 ENIGMA_ERROR(
"Failed to write file {}", filename.string());
81 static void ReadChunksFstream(
const fs::path& filename,
const std::size_t max_chunk_size,
const std::function<
bool(std::vector<byte>&&)>& callback) {
82 if (std::ifstream ifs{filename, std::ios::binary}) {
84 std::vector<Enigma::byte> chunk(max_chunk_size,
'\000');
85 ifs.read(
reinterpret_cast<char *
>(chunk.data()), chunk.size());
88 const auto bytes_read =
static_cast<std::size_t
>(ifs.gcount());
89 if (bytes_read < max_chunk_size)
90 chunk.resize(bytes_read);
93 if (!callback(std::move(chunk)))
break;
97 ENIGMA_ERROR(
"Failed to read file chunks {}", filename.string());
104 static void ReadChunks(
const fs::path& filename,
const std::size_t max_chunk_size,
const std::function<
bool(std::vector<byte>&&)>& callback) {
106 std::FILE *file = std::fopen(filename.string().c_str(),
"rb");
108 ENIGMA_ERROR(
"Failed to read file chunks {}", filename.string());
116 while (!std::feof(file)) {
118 std::vector<Enigma::byte> chunk(max_chunk_size,
'\000');
121 const std::size_t bytes_read = std::fread(chunk.data(),
sizeof(
Enigma::byte), max_chunk_size, file);
123 if (bytes_read < max_chunk_size)
124 chunk.resize(bytes_read);
127 if (!callback(std::move(chunk)))
break;
#define ENIGMA_ERROR(...)
#define NS_ENIGMA_BEGIN
Enable/Disable Assertions.
static bool WriteString(const fs::path &filename, const std::string &buffer)
static bool Write(const fs::path &filename, const std::vector< byte > &buffer)
static void ReadChunks(const fs::path &filename, const std::size_t max_chunk_size, const std::function< bool(std::vector< byte > &&)> &callback)
static bool ReadString(const fs::path &filename, std::string &buffer)
static void ReadChunksFstream(const fs::path &filename, const std::size_t max_chunk_size, const std::function< bool(std::vector< byte > &&)> &callback)
static bool Read(const fs::path &filename, std::vector< byte > &buffer)
Executes a function at the end of the scope (deferred) using RAII gsl libs.