#include #include #include #include #include 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(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) { }