sots-engine/src/game/config/manifest_loader.cpp

57 lines
1.8 KiB
C++

#include "game/config/manifest_loader.h"
#include "mars/parse/script.h"
namespace game::config {
int manifest_atoi(std::string_view text) {
std::size_t i = 0;
auto is_ws = [](char c) { return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f'; };
while (i < text.size() && is_ws(text[i])) ++i;
bool neg = false;
if (i < text.size() && (text[i] == '+' || text[i] == '-')) {
neg = text[i] == '-';
++i;
}
std::uint32_t acc = 0;
for (; i < text.size() && text[i] >= '0' && text[i] <= '9'; ++i)
acc = acc * 10u + static_cast<std::uint32_t>(text[i] - '0');
const std::uint32_t v = neg ? (0u - acc) : acc;
return static_cast<int>(static_cast<std::int32_t>(v));
}
namespace {
std::string_view clip(std::string_view t) {
return t.size() > kManifestTokenMax ? t.substr(0, kManifestTokenMax) : t;
}
} // namespace
std::vector<ManifestPair> manifest_pairs(std::string_view text) {
using mars::parse::ReadStatus;
using mars::parse::Script;
std::vector<ManifestPair> out;
Script s(text);
int id = 0; // only ever observed after a successful read (a failed first read ends the loop)
for (;;) {
Script::Raw t;
if (s.read_token(t) == ReadStatus::Ok) id = manifest_atoi(clip(t.text));
Script::Raw f;
if (s.read_token(f) != ReadStatus::Ok) break;
out.push_back(ManifestPair{id, std::string(clip(f.text))});
}
return out;
}
std::string weapon_path(std::string_view file) { return "Weapons/" + std::string(file); }
std::string section_manifest_path(std::string_view dir) {
return std::string(dir) + "/" + kSectionManifestFile;
}
std::string section_path(std::string_view dir, std::string_view file) {
return std::string(dir) + "/" + std::string(file);
}
} // namespace game::config