aboutsummaryrefslogtreecommitdiff
path: root/src/rez/io.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/io.cpp
downloadglobalops-main.tar.gz
First commitHEADabcmain
Diffstat (limited to 'src/rez/io.cpp')
-rw-r--r--src/rez/io.cpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/rez/io.cpp b/src/rez/io.cpp
new file mode 100644
index 0000000..019fdab
--- /dev/null
+++ b/src/rez/io.cpp
@@ -0,0 +1,174 @@
+#include <rez/io.h>
+#include <cerrno>
+#include <cstring>
+#include <fstream>
+#include <iostream>
+
+int rez::io::read(unsigned char &b)
+{
+ std::ifstream::pos_type off = f.tellg();
+
+ f.read((char *)&b, sizeof b);
+
+ if (!f || f.eof())
+ {
+ std::cerr << m_path << ": failed to read at offset " << off
+ << ", eof=" << f.eof() << std::endl;
+ return -1;
+ }
+
+ return 0;
+}
+
+int rez::io::check(char byte)
+{
+ char b;
+ std::ifstream::pos_type off = f.tellg();
+
+ f.read(&b, sizeof b);
+
+ if (!f || f.eof())
+ {
+ std::cerr << m_path << ": failed to read at offset " << off
+ << ", eof=" << f.eof() << std::endl;
+ return -1;
+ }
+ else if (b != byte)
+ {
+ std::cerr << m_path << ": expected " << byte << " at offset: " << off
+ << ", got " << b << std::endl;
+ return -1;
+ }
+
+ return 0;
+}
+
+int rez::io::check(const char *s)
+{
+ while (*s)
+ if (check(*s++))
+ return -1;
+
+ return 0;
+}
+
+int rez::io::read_le(uint32_t &w)
+{
+ std::ifstream::pos_type off = f.tellg();
+ unsigned char buf[sizeof w];
+
+ f.read((char *)buf, sizeof buf);
+
+ if (!f || f.eof())
+ {
+ std::cerr << m_path << ": failed to read word at offset " << off
+ << ", eof=" << f.eof() << std::endl;
+ return -1;
+ }
+
+ w = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+ return 0;
+}
+
+int rez::io::read(std::string &s, unsigned maxlen)
+{
+ unsigned i = 0;
+
+ while (i++ < maxlen)
+ {
+ unsigned char b;
+
+ if (read(b))
+ return -1;
+ else if (!b)
+ return 0;
+
+ s += b;
+ }
+
+ std::cerr << m_path << ": exceeded maximum string length (" << maxlen
+ << "): \"" << s << "\"" << std::endl;
+ return -1;
+}
+
+int rez::io::read(void *b, size_t n)
+{
+ std::ifstream::pos_type off = f.tellg();
+
+ f.read((char *)(b), n);
+
+ if (!f)
+ {
+ std::cerr << m_path << ": failed to read " << n << " bytes at offset "
+ << off << ", eof=" << f.eof() << std::endl;
+ return -1;
+ }
+
+ return 0;
+}
+
+long rez::io::tell()
+{
+ std::ifstream::pos_type offset = f.tellg();
+
+ if (!f)
+ {
+ std::cerr << m_path << ": failed to retrieve offset" << std::endl;
+ return -1;
+ }
+
+ return offset;
+}
+
+int rez::io::seek(long offset)
+{
+ long cur = f.tellg();
+
+ if (!f)
+ {
+ std::cerr << m_path << ": failed to tell offset " << std::endl;
+ return -1;
+ }
+ else if (cur != offset)
+ {
+ f.seekg(static_cast<std::ifstream::pos_type>(offset));
+
+ if (!f)
+ {
+ std::cerr << m_path << ": failed to seek to offset " << offset
+ << std::endl;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int rez::io::open()
+{
+ if (!f.is_open())
+ {
+ const char *error;
+
+#ifdef _WIN32
+ error = GetLastError();
+#else
+ error = strerror(errno);
+#endif
+ std::cerr << "Failed to open " << m_path << ": " << error << std::endl;
+ return -1;
+ }
+
+ return 0;
+}
+
+const std::string &rez::io::path() const
+{
+ return m_path;
+}
+
+rez::io::io(const char *path) :
+ f(path, std::ios::binary),
+ m_path(path)
+{
+}