Something went wrong. Try again.
Monorepo for PackTools - tooling for Minecraft Modpacks!
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697// The platform-independent half of fs.hpp. AI-authored (Claude).#include "fs.hpp"
#include <chrono>#include <cstddef>#include <cstdint>#include <optional>#include <string>#include <string_view>#include <thread>#include <vector>
namespace packutils::fs {
std::string join(std::string_view a, std::string_view b) { std::string out(a); const bool ends = !out.empty() && (out.back() == '/' || out.back() == separator); if (!out.empty() && !ends && !b.empty()) { out.push_back(separator); } out += b; return out;}
void pause(std::uint32_t milliseconds) { std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));}
namespace {
constexpr std::uint32_t mount_point_tag = 0xA0000003U;/// The tag, length and reserved fields, then four name offsets and lengths.constexpr std::size_t mount_point_header = 8 + 8;constexpr std::size_t max_reparse_bytes = std::size_t{16} * 1024;
void put16(std::vector<std::uint8_t> &out, std::size_t at, std::size_t value) { out.at(at) = static_cast<std::uint8_t>(value & 0xFFU); out.at(at + 1) = static_cast<std::uint8_t>((value >> 8U) & 0xFFU);}
} // namespace
std::optional<std::vector<std::uint8_t>> junction_buffer(const std::u16string &substitute, const std::u16string &print) { const std::size_t path_bytes = (substitute.size() + 1 + print.size() + 1) * 2; const std::size_t total = mount_point_header + path_bytes; if (total > max_reparse_bytes || total - 8 > 0xFFFFU) { return std::nullopt; } std::vector<std::uint8_t> out(total, 0); put16(out, 0, mount_point_tag & 0xFFFFU); put16(out, 2, mount_point_tag >> 16U); put16(out, 4, total - 8); put16(out, 6, 0); put16(out, 8, 0); put16(out, 10, substitute.size() * 2); put16(out, 12, (substitute.size() + 1) * 2); put16(out, 14, print.size() * 2); std::size_t at = mount_point_header; for (const std::u16string *name : {&substitute, &print}) { for (const char16_t unit : *name) { put16(out, at, unit); at += 2; } at += 2; // The NUL, already zero. } return out;}
bool same_path(std::string_view a, std::string_view b) { const auto trim = [](std::string_view path) { if (path.size() > 1 && (path.back() == '/' || path.back() == '\\')) { path.remove_suffix(1); } return path; }; const std::string_view x = trim(a); const std::string_view y = trim(b);#ifdef _WIN32 if (x.size() != y.size()) { return false; } const auto lower = [](char c) { return c >= 'A' && c <= 'Z' ? static_cast<char>(c + 32) : c; }; for (std::size_t i = 0; i < x.size(); ++i) { const bool separators = (x[i] == '/' || x[i] == '\\') && (y[i] == '/' || y[i] == '\\'); if (!separators && lower(x[i]) != lower(y[i])) { return false; } } return true;#else return x == y;#endif}
} // namespace packutils::fs