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/io.cpp | |
| download | globalops-main.tar.gz | |
Diffstat (limited to 'src/rez/io.cpp')
| -rw-r--r-- | src/rez/io.cpp | 174 |
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) +{ +} |
