diff --git a/TreFile.cc b/TreFile.cc index fd91676..558fbca 100644 --- a/TreFile.cc +++ b/TreFile.cc @@ -79,7 +79,19 @@ TreFile::TreFile(char const* base, size_t length) fprintf(stderr, "Data length exceeds file length: %.8x %.8x\n", dataPtr, length); } - table3_.emplace_back(dataPtr, length, flags); + if (!table3_.empty()) { + uint32_t lastPtr, lastLen; + uint8_t lastFlags; + std::tie(lastPtr, std::ignore, lastLen, lastFlags) = table3_.back(); + if (lastPtr+lastLen > dataPtr) { + if (lastFlags&0x80) + std::get<2>(table3_.back()) = dataPtr - lastPtr; + else + fprintf(stderr, "Overlap? %u %u (%hhu) -> %u\n",lastPtr, lastLen, lastFlags, dataPtr); + } + } + + table3_.emplace_back(dataPtr, length, length, flags); } // Read Table 2 @@ -258,7 +270,7 @@ void TreFile::printStructure() printf("\t%.8x -> (ofs %.8x, len %.8x, flags %.2hhx)\n", ent.first, std::get<0>(table3_[ent.second]), std::get<1>(table3_[ent.second]), - std::get<2>(table3_[ent.second])); + std::get<3>(table3_[ent.second])); } printf("Files by Name:\n"); @@ -266,7 +278,7 @@ void TreFile::printStructure() printf("\t%s -> (ofs %.8x, len %.8x, flags %.2hhx)\n", ent.first.c_str(), std::get<0>(table3_[ent.second]), std::get<1>(table3_[ent.second]), - std::get<2>(table3_[ent.second])); + std::get<3>(table3_[ent.second])); } } @@ -293,34 +305,34 @@ size_t TreFile::findCRC_(uint32_t crc) const void TreFile::dumpIdx_(std::string const& name, size_t table3Idx) const { - uint32_t dataPtr, length; + uint32_t dataPtr, length, clength; uint8_t flags; - std::tie(dataPtr, length, flags) = table3_[table3Idx]; + std::tie(dataPtr, length, clength, flags) = table3_[table3Idx]; - if(flags&0x80) - throw Exception{"Compressed TRE objects NYI"}; + // if(flags&0x80) + // throw Exception{"Compressed TRE objects NYI"}; - if ((dataPtr + length) > length_) + if ((dataPtr + clength) > length_) throw FormatException{"length exceeds file size"}; FILEUPtr outFile{fopen(name.c_str(), "wb")}; if (!outFile) throw POSIXException{errno, "Could not open " + name}; - if (fwrite(base_+dataPtr, length, 1, outFile.get()) != 1) + if (fwrite(base_+dataPtr, clength, 1, outFile.get()) != 1) throw POSIXException{errno, "Could not write"}; } TreFile::Object TreFile::openIdx_(size_t table3Idx) const { - uint32_t dataPtr, length; + uint32_t dataPtr, length, clength; uint8_t flags; - std::tie(dataPtr, length, flags) = table3_[table3Idx]; + std::tie(dataPtr, length, clength, flags) = table3_[table3Idx]; if(flags&0x80) throw Exception{"Compressed TRE objects NYI"}; - if ((dataPtr + length) > length_) + if ((dataPtr + clength) > length_) throw FormatException{"length exceeds file size"}; return Object(base_+dataPtr, @@ -330,7 +342,7 @@ TreFile::Object TreFile::openIdx_(size_t table3Idx) const TreFile::Stat TreFile::statIdx_(size_t table3Idx) const { Stat ret; - std::tie(std::ignore, ret.size, ret.flags) = table3_[table3Idx]; + std::tie(std::ignore, ret.size, ret.csize, ret.flags) = table3_[table3Idx]; return ret; } diff --git a/TreFile.hh b/TreFile.hh index e1575e1..b97b292 100644 --- a/TreFile.hh +++ b/TreFile.hh @@ -71,6 +71,7 @@ public: struct Stat { uint32_t size; + uint32_t csize; uint8_t flags; }; @@ -89,7 +90,8 @@ private: std::map table1_; std::map table2_; - std::vector > table3_; + // base, size, comp. size, flags + std::vector > table3_; char const* base_; size_t length_;