diff --git a/include/libweaver/interleaf.h b/include/libweaver/interleaf.h index 356d952..7df3874 100644 --- a/include/libweaver/interleaf.h +++ b/include/libweaver/interleaf.h @@ -32,7 +32,8 @@ class Interleaf : public Core { IncludeData = 1, IncludeInfo = 2, - ObjectsOnly = 4 + ObjectsOnly = 4, + HeaderOnly = 8 }; LIBWEAVER_EXPORT Interleaf(); @@ -50,6 +51,8 @@ class Interleaf : public Core Error Read(FileBase *is, int flags = IncludeData | IncludeInfo); Error Write(FileBase *os) const; + LIBWEAVER_EXPORT Error ReadObject(FileBase *f, uint32_t slot); + Info *GetInformation() { return &m_Info; } private: @@ -75,6 +78,8 @@ class Interleaf : public Core std::map m_ObjectOffsetTable; std::map m_ObjectIDTable; + std::vector m_SlotOffsets; + uint32_t m_JoiningProgress; uint32_t m_JoiningSize; diff --git a/lib/interleaf.cpp b/lib/interleaf.cpp index c7379e4..e1b2e20 100644 --- a/lib/interleaf.cpp +++ b/lib/interleaf.cpp @@ -25,6 +25,7 @@ void Interleaf::Clear() m_JoiningSize = 0; m_ObjectOffsetTable.clear(); m_ObjectIDTable.clear(); + m_SlotOffsets.clear(); DeleteChildren(); } @@ -125,6 +126,7 @@ Interleaf::Error Interleaf::ReadChunk(Core *parent, FileBase *f, Info *info) if (choffset) { m_ObjectOffsetTable[choffset] = o; } + m_SlotOffsets.push_back(choffset); desc << std::endl << i << ": 0x" << std::hex << choffset; } break; @@ -305,6 +307,13 @@ Interleaf::Error Interleaf::ReadChunk(Core *parent, FileBase *f, Info *info) } } + // Stop after reading just the header (MxHd + MxOf) + if (m_readFlags & HeaderOnly) { + if (static_cast(id) == RIFF::MxOf) { + f->seek(0, FileBase::SeekEnd); + } + } + return ERROR_SUCCESS; } @@ -370,6 +379,20 @@ Object *Interleaf::ReadObject(FileBase *f, Object *o, std::ostream &desc) return o; } +Interleaf::Error Interleaf::ReadObject(FileBase *f, uint32_t slot) +{ + if (slot >= m_SlotOffsets.size() || m_SlotOffsets[slot] == 0) { + return ERROR_INVALID_INPUT; + } + + m_JoiningProgress = 0; + m_JoiningSize = 0; + m_readFlags = IncludeData; + + f->seek(m_SlotOffsets[slot], FileBase::SeekStart); + return ReadChunk(this, f, NULL); +} + Interleaf::Error Interleaf::Read(FileBase *f, int flags) { Clear();