diff options
Diffstat (limited to 'source/core/slang-riff.cpp')
| -rw-r--r-- | source/core/slang-riff.cpp | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/source/core/slang-riff.cpp b/source/core/slang-riff.cpp index 1de51d840..da547319b 100644 --- a/source/core/slang-riff.cpp +++ b/source/core/slang-riff.cpp @@ -665,6 +665,47 @@ size_t RiffContainer::DataChunk::calcPayloadSize() const return size; } +void RiffContainer::DataChunk::getPayload(void* inDst) const +{ + uint8_t* dst = (uint8_t*)inDst; + + Data* data = m_dataList; + while (data) + { + const size_t size = data->getSize(); + ::memcpy(dst, data->getPayload(), size); + + dst += size; + data = data->m_next; + } +} + +bool RiffContainer::DataChunk::isEqual(const void* inData, size_t count) const +{ + const uint8_t* src = (const uint8_t*)inData; + + Data* data = m_dataList; + while (data) + { + const size_t size = data->getSize(); + // Can't have more content than remaining + // Contents must match + if (size > count || ::memcmp(src, data->getPayload(), size) != 0) + { + return false; + } + + src += size; + count -= size; + + // Next data block + data = data->m_next; + } + + // If match must be at the end + return count == 0; +} + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RiffContainer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RiffContainer::RiffContainer() : @@ -862,8 +903,63 @@ RiffContainer::Data* RiffContainer::addData() return data; } +RiffContainer::Data* RiffContainer::makeSingleData(DataChunk* dataChunk) +{ + // There is no data + if (dataChunk->m_dataList == nullptr) + { + return nullptr; + } + + if (dataChunk->m_dataList->m_next == nullptr) + { + return dataChunk->m_dataList; + } + + { + Data* data = dataChunk->m_dataList; + + // Okay lets combine all into one block + const size_t payloadSize = dataChunk->calcPayloadSize(); + + void* dst = m_arena.allocate(payloadSize); + dataChunk->getPayload(dst); + + // Remove other datas + data->m_next = nullptr; + // Make this the end + dataChunk->m_endData = data; + + // Point to the block with all of the data + data->m_ownership = Ownership::Arena; + data->m_payload = dst; + data->m_size = payloadSize; + + return data; + } +} + void RiffContainer::write(const void* inData, size_t size) { + // We must be in a chunk + SLANG_ASSERT(m_dataChunk); + // Get the last data chunk + Data* endData = m_dataChunk->m_endData; + if (endData) + { + uint8_t* end = ((uint8_t*)endData->m_payload) + endData->m_size; + // See if can just add to end of current data + if ( end == m_arena.getCursor() && m_arena.allocateCurrentUnaligned(size)) + { + ::memcpy(end, inData, size); + endData->m_size += size; + + // Add current chunks data + m_dataChunk->m_payloadSize += size; + return; + } + } + auto data = addData(); setPayload(data, inData, size); } |
