aboutsummaryrefslogtreecommitdiff
path: root/src/rez/rez.cpp
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2025-12-04 13:58:02 +0100
committerXavier Del Campo Romero <xavi92@disroot.org>2025-12-15 23:04:39 +0100
commit600ff28dd73f2cf17725382b68a4b1b2573f2e34 (patch)
treea105c686458d8998438652aeca6299cf9000edcd /src/rez/rez.cpp
downloadglobalops-main.tar.gz
First commitHEADabcmain
Diffstat (limited to 'src/rez/rez.cpp')
-rw-r--r--src/rez/rez.cpp124
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)
+{
+}