#include "util.h" #include #include #include #include #include namespace m2pack { [[noreturn]] void fail(const std::string& message) { throw std::runtime_error(message); } std::vector read_file(const std::string& path) { std::ifstream input(path, std::ios::binary); if (!input) { fail("Failed to open file for reading: " + path); } input.seekg(0, std::ios::end); const auto size = static_cast(input.tellg()); input.seekg(0, std::ios::beg); std::vector bytes(size); if (!bytes.empty()) { input.read(reinterpret_cast(bytes.data()), static_cast(bytes.size())); } if (!input.good() && !input.eof()) { fail("Failed to read file: " + path); } return bytes; } void write_file(const std::string& path, const std::vector& data) { std::filesystem::create_directories(std::filesystem::path(path).parent_path()); std::ofstream output(path, std::ios::binary); if (!output) { fail("Failed to open file for writing: " + path); } if (!data.empty()) { output.write(reinterpret_cast(data.data()), static_cast(data.size())); } if (!output.good()) { fail("Failed to write file: " + path); } } std::string json_escape(std::string_view value) { std::string out; out.reserve(value.size() + 8); for (const char ch : value) { switch (ch) { case '\\': out += "\\\\"; break; case '"': out += "\\\""; break; case '\n': out += "\\n"; break; case '\r': out += "\\r"; break; case '\t': out += "\\t"; break; default: out += ch; break; } } return out; } void write_stdout(const std::vector& data) { std::cout.write(reinterpret_cast(data.data()), static_cast(data.size())); } } // namespace m2pack