#pragma once #include #include #include #include #include #include // Shared yaml/text emission formatters #define YAML_HEX(num) YAML::Hex << (num) << YAML::Dec #define FORMAT_HEX(x, w) \ std::hex << std::uppercase << std::setfill('0') << std::setw(w) << x << std::nouppercase << std::dec namespace BK64 { // Emit a text string for modding yaml. inline void EmitText(YAML::Emitter& out, const std::string& str) { const char* s = str.c_str(); bool plain = true; for (const char* p = s; *p != '\0'; p++) { if (static_cast(*p) < 0x20 || static_cast(*p) > 0x7E || *p == '\\') { plain = false; break; } } if (plain) { out << YAML::DoubleQuoted << s; return; } std::string escaped; for (const char* p = s; *p != '\0'; p++) { const auto c = static_cast(*p); if (c == '\\') { escaped += "\\\\"; } else if (c < 0x20 || c > 0x7E) { char buf[5]; std::snprintf(buf, sizeof(buf), "\\x%02X", c); escaped += buf; } else { escaped += static_cast(c); } } out << YAML::SingleQuoted << escaped; } // Reverse EmitText's escapes on a string read back from modding yaml. inline std::string DecodeText(const std::string& str) { std::string out; out.reserve(str.size()); for (size_t i = 0; i < str.size(); i++) { if (str[i] == '\\' && i + 1 < str.size()) { if (str[i + 1] == '\\') { out += '\\'; i++; continue; } if ((str[i + 1] == 'x' || str[i + 1] == 'X') && i + 3 < str.size() && std::isxdigit(static_cast(str[i + 2])) && std::isxdigit(static_cast(str[i + 3]))) { out += static_cast(std::stoi(str.substr(i + 2, 2), nullptr, 16)); i += 3; continue; } } out += str[i]; } return out; } } // namespace BK64