#pragma once #include #include namespace LXC::Util { // Error returned when Util::ReadFile runs into errors // struct FileReadError final { // Different reasons why the error can occur // enum Reason { FileNotFound, PermissionDenied, NotAFile }; // Constructor to pass arguments to the struct // FileReadError(const std::filesystem::path& _path, Reason _reason) : path(_path), reason(_reason) {} // Error information // const std::filesystem::path path; const Reason reason; // Turns the error into a c-string // inline static const char* const ReasonStr(Reason reason) { static const char* reasons[] = { "File cannot be found", "File reading permissions are denied", "Not a file" }; return reasons[reason]; } }; // Util function to read a file as quick as possible with error handling // inline ReturnVal ReadFile(const std::filesystem::path& filepath) { // Checks the file exists // if (!std::filesystem::exists(filepath)) return FunctionFail(std::filesystem::absolute(filepath), FileReadError::FileNotFound); // Checks it is a regular file // if (!std::filesystem::is_regular_file(filepath)) return FunctionFail(std::filesystem::absolute(filepath), FileReadError::NotAFile); // Checks it can open the file // std::ifstream file(filepath, std::ios::binary | std::ios::ate); if (!file) return FunctionFail(std::filesystem::absolute(filepath), FileReadError::PermissionDenied); // Copies the file to the output string // const std::streamsize len = file.tellg(); file.seekg(0, std::ios::beg); std::string contents(len, '\0'); file.read(&contents[0], len); return contents; } // Struct to hold a position within a file // struct FileLocation { unsigned short col; unsigned short line; }; // Finds the location of a given index within a file // inline bool GetFileLocationAtIndex(FileLocation& location, const std::string& file, uint32_t index) { // Resets location // location.line = 1; location.col = 1; // Returns false if outside the bounds // if (index < 0 || index > file.length()) return false; // Finds the location // uint32_t localIndex = 0; while (localIndex != index) { if (file[localIndex] == '\n') { location.line += 1; location.col = 0; } location.col++; localIndex++; } return true; } }