diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-12-04 13:58:02 +0100 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-12-15 23:04:39 +0100 |
| commit | 600ff28dd73f2cf17725382b68a4b1b2573f2e34 (patch) | |
| tree | a105c686458d8998438652aeca6299cf9000edcd /src/rez/rez.cpp | |
| download | globalops-main.tar.gz | |
Diffstat (limited to 'src/rez/rez.cpp')
| -rw-r--r-- | src/rez/rez.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/rez/rez.cpp b/src/rez/rez.cpp new file mode 100644 index 0000000..2351c05 --- /dev/null +++ b/src/rez/rez.cpp @@ -0,0 +1,124 @@ +#include <rez.h> +#include <rez/dir.h> +#include <rez/io.h> +#include <cctype> +#include <iostream> +#include <memory> +#include <sstream> +#include <variant> + +std::string rez::ball::toupper(const std::string &s) const +{ + std::string ret; + + // Assume ASCII encoding. + for (const auto &c: s) + ret += std::toupper(c); + + return ret; +} + +std::unique_ptr<rez::file> rez::ball::open(const char *path) +{ + std::istringstream stream(path); + std::string token; + const rez::dir *dir = &root_dir; + const rez::resource *resource = nullptr; + + while (std::getline(stream, token, '/')) + { + std::string uctoken = toupper(token); + const auto &map = dir->entries(); + auto it = map.find(uctoken); + + if (it == map.end()) + return nullptr; + + const rez::dir::direntry &de = it->second; + + if (std::holds_alternative<rez::dir>(de)) + dir = &std::get<rez::dir>(de); + else if (std::holds_alternative<rez::resource>(de)) + { + dir = nullptr; + resource = &std::get<rez::resource>(de); + } + } + + if (dir) + { + std::cerr << path << " is a directory\n"; + return nullptr; + } + else if (!resource) + { + std::cerr << io.path() << ": could not find " << path << '\n'; + return nullptr; + } + + return std::make_unique<rez::file>(*resource, io); +} + +int rez::ball::parse() +{ + static const char title[63] = + "\r\nRezMgr Version 1 Copyright (C) 1995 MONOLITH INC. ", + subtitle[65] = + "\r\nLithTech Resource File \r\n"; + + if (io.open()) + return -1; + else if (io.check(title)) + { + std::cerr << path << ": wrong title\n"; + return -1; + } + else if (io.check(subtitle)) + { + std::cerr << path << ": wrong subtitle\n"; + return -1; + } + else if (io.check(0x1a)) + { + std::cerr << path << ": wrong EOF\n"; + return -1; + } + + struct + { + uint32_t w[N_WORDS]; + uint8_t is_sorted; + } header; + + for (auto &w : header.w) + if (io.read_le(w)) + return -1; + + if (header.w[FILE_FORMAT_VERSION] != 1) + { + std::cerr << path << ": expected file format version 1, got " + << header.w[FILE_FORMAT_VERSION] << '\n'; + return -1; + } + else if (io.read(header.is_sorted)) + { + std::cerr << path << ": could not read sorted flag" << '\n'; + return -1; + } + + struct rez::entry::cfg cfg = {0}; + + cfg.size = header.w[ROOT_DIR_SIZE]; + cfg.offset = header.w[ROOT_DIR_POS]; + cfg.maxcomlen = header.w[MAX_COMMENT_SIZE]; + cfg.maxdirlen = header.w[MAX_DIR_NAME_SIZE]; + cfg.maxreslen = header.w[MAX_REZ_NAME_SIZE]; + root_dir.read(cfg, io, 0); + return 0; +} + +rez::ball::ball(const char *path) : + path(path), + io(path) +{ +} |
