diff options
Diffstat (limited to 'source/core/slang-riff.cpp')
| -rw-r--r-- | source/core/slang-riff.cpp | 102 |
1 files changed, 75 insertions, 27 deletions
diff --git a/source/core/slang-riff.cpp b/source/core/slang-riff.cpp index 9849cfc26..3a3722bb8 100644 --- a/source/core/slang-riff.cpp +++ b/source/core/slang-riff.cpp @@ -175,7 +175,7 @@ struct DumpVisitor : public RiffContainer::Visitor // If it's the root it's 'riff' _dumpRiffType(list == m_rootChunk ? RiffFourCC::kRiff : RiffFourCC::kList); m_writer.put(" "); - _dumpRiffType(list->m_subType); + _dumpRiffType(list->getSubType()); m_writer.put("\n"); m_indent++; return SLANG_OK; @@ -184,10 +184,9 @@ struct DumpVisitor : public RiffContainer::Visitor { _dumpIndent(); // Write out the name - _dumpRiffType(data->m_type); + _dumpRiffType(data->m_fourCC); m_writer.put(" "); - int hash = data->calcHash(); // We don't know in general what the contents is or means... but we can display a hash @@ -250,7 +249,7 @@ struct DumpVisitor : public RiffContainer::Visitor listHeader.chunk.type = isRoot ? RiffFourCC::kRiff : RiffFourCC::kList; listHeader.chunk.size = uint32_t(list->m_payloadSize); - listHeader.subType = list->m_subType; + listHeader.subType = list->getSubType(); try { @@ -276,7 +275,7 @@ struct DumpVisitor : public RiffContainer::Visitor // Must be a regular chunk with data RiffHeader chunkHeader; - chunkHeader.type = dataChunk->m_type; + chunkHeader.type = dataChunk->m_fourCC; chunkHeader.size = uint32_t(dataChunk->m_payloadSize); stream->write(&chunkHeader, sizeof(chunkHeader)); @@ -386,7 +385,9 @@ struct DumpVisitor : public RiffContainer::Visitor else { ScopeChunk scopeChunk(&outContainer, Chunk::Kind::Data, header.chunk.type); - RiffContainer::Data* data = outContainer.addData(header.chunk.size); + RiffContainer::Data* data = outContainer.addData(); + + outContainer.setPayload(data, nullptr, header.chunk.size); size_t readSize; SLANG_RETURN_ON_FAIL(readPayload(stream, header.chunk.size, data->getPayload(), readSize)); @@ -520,15 +521,12 @@ size_t RiffContainer::ListChunk::calcPayloadSize() return size; } -RiffContainer::Chunk* RiffContainer::ListChunk::findContained(FourCC type) const +RiffContainer::Chunk* RiffContainer::ListChunk::findContained(FourCC fourCC) const { Chunk* chunk = m_containedChunks; while (chunk) { - const FourCC checkType = (chunk->m_kind == Chunk::Kind::Data) ? - static_cast<RiffContainer::DataChunk*>(chunk)->m_type : - static_cast<RiffContainer::ListChunk*>(chunk)->m_subType; - if (checkType == type) + if (chunk->m_fourCC == fourCC) { return chunk; } @@ -568,7 +566,7 @@ static RiffContainer::ListChunk* _findListRec(RiffContainer::ListChunk* list, Fo if (auto childList = as<RiffContainer::ListChunk>(chunk)) { // Test if the child is the subtype, if so we are done - if (childList->m_subType == subType) + if (childList->getSubType() == subType) { return childList; } @@ -585,23 +583,25 @@ static RiffContainer::ListChunk* _findListRec(RiffContainer::ListChunk* list, Fo /* static */RiffContainer::ListChunk* RiffContainer::ListChunk::findListRec(FourCC subType) { - return (m_subType == subType) ? this : _findListRec(this, subType); + return (getSubType() == subType) ? this : _findListRec(this, subType); } // !!!!!!!!!!!!!!!!!!!!!!!!!!! RiffContainer::DataChunk !!!!!!!!!!!!!!!!!!!!!! RiffContainer::Data* RiffContainer::DataChunk::getSingleData() const { - if (m_kind == Kind::Data) + Data* data = m_dataList; + return (data && data->m_next == nullptr) ? data : nullptr; +} + +RiffReadHelper RiffContainer::DataChunk::asReadHelper() const +{ + Data* data = getSingleData(); + if (data) { - auto dataChunk = static_cast<const DataChunk*>(this); - Data* data = dataChunk->m_dataList; - if (data && data->m_next == nullptr) - { - return data; - } + return RiffReadHelper((const uint8_t*)data->getPayload(), data->getSize()); } - return nullptr; + return RiffReadHelper(nullptr, 0); } int RiffContainer::DataChunk::calcHash() const @@ -765,19 +765,67 @@ void RiffContainer::endChunk() SLANG_ASSERT(isChunkOk(chunk)); } -RiffContainer::Data* RiffContainer::addData(size_t size) +void RiffContainer::setPayload(Data* data, const void* payload, size_t size) { - // We must be in a chunk + // We must be in a data chunk SLANG_ASSERT(m_dataChunk); + // The data shouldn't be set up + SLANG_ASSERT(data->m_ownership == Ownership::Uninitialized); // Add current chunks data m_dataChunk->m_payloadSize += size; - Data* data = (Data*)m_arena.allocate(sizeof(Data) + size); + data->m_ownership = Ownership::Arena; + data->m_size = size; + + data->m_payload = m_arena.allocate(size); + + if (payload) + { + ::memcpy(data->m_payload, payload, size); + } +} - data->m_next = nullptr; +void RiffContainer::moveOwned(Data* data, void* payload, size_t size) +{ + // We must be in a data chunk + SLANG_ASSERT(m_dataChunk); + // The data shouldn't be set up + SLANG_ASSERT(data->m_ownership == Ownership::Uninitialized); + + // Add current chunks data + m_dataChunk->m_payloadSize += size; + + data->m_ownership = Ownership::Owned; data->m_size = size; + // The area will manage this block + m_arena.addExternalBlock(payload, size); + data->m_payload = payload; +} + +void RiffContainer::setUnowned(Data* data, void* payload, size_t size) +{ + // We must be in a data chunk + SLANG_ASSERT(m_dataChunk); + // The data shouldn't be set up + SLANG_ASSERT(data->m_ownership == Ownership::Uninitialized); + // Add current chunks data + m_dataChunk->m_payloadSize += size; + + data->m_ownership = Ownership::NotOwned; + data->m_size = size; + data->m_payload = payload; +} + +RiffContainer::Data* RiffContainer::addData() +{ + // We must be in a chunk + SLANG_ASSERT(m_dataChunk); + + Data* data = (Data*)m_arena.allocate(sizeof(Data)); + data->init(); + Data*& next = m_dataChunk->m_endData ? m_dataChunk->m_endData->m_next : m_dataChunk->m_dataList; SLANG_ASSERT(next == nullptr); @@ -790,8 +838,8 @@ RiffContainer::Data* RiffContainer::addData(size_t size) void RiffContainer::write(const void* inData, size_t size) { - auto data = addData(size); - ::memcpy(data->getPayload(), inData, size); + auto data = addData(); + setPayload(data, inData, size); } static SlangResult _isChunkOk(RiffContainer::Chunk* chunk, void* data) |
