#include #include #include const rez::dir::entrymap &rez::dir::entries() const { return m_entries; } const std::string &rez::dir::name() const { return m_name; } int rez::dir::read(const struct entry::cfg &cfg, rez::io &io, std::string &name, direntry &de, unsigned level) { rez::entry entry; if (entry.read(io)) return -1; switch (entry.type) { case entry::type::dir: { long offset; dir subdir; if (io.read(subdir.m_name, cfg.maxdirlen) || (offset = io.tell()) < 0) return -1; struct entry::cfg scfg = cfg; #if 0 for (unsigned i = 0; i < level + 1; i++) std::cout << "|\t"; std::cout << "name: " << subdir.m_name << std::endl; #endif subdir.entry = entry; scfg.size = entry.size; scfg.offset = entry.pos; if (subdir.read(scfg, io, level + 1) || io.seek(offset)) return -1; name = subdir.m_name; de = subdir; } break; case entry::type::resource: { resource resource; resource.entry = entry; if (resource.read(cfg, io)) return -1; #if 0 for (unsigned i = 0; i < level + 1; i++) std::cout << "|\t"; std::cout << "name: " << resource.name() << std::endl; #endif name = resource.name(); de = resource; } break; default: std::cerr << "Invalid entry type " << entry.type << std::endl; return -1; } return 0; } int rez::dir::read(const struct entry::cfg &cfg, rez::io &io, unsigned level) { unsigned long size = cfg.size; long before = cfg.offset; if (io.seek(cfg.offset)) return -1; while (size) { std::string name; direntry de; long after; if (read(cfg, io, name, de, level) || (after = io.tell()) < 0) return -1; unsigned long r = after - before; if (r > size) { std::cerr << m_name << ": exceeded maximum direntry length " "(" << cfg.size << ")" << std::endl; return -1; } m_entries[name] = de; before = after; size -= r; } return 0; }