diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-11-08 09:13:44 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-08 09:13:44 -0500 |
| commit | 0ac010a72e777b2c284583fcb8554abee83d8ff5 (patch) | |
| tree | 7133e5c3117c180d19ce11841187ff3f9d2ec5fe /source/core/slang-riff.cpp | |
| parent | 99c295477fa1f6c5ce47e0d1c8fb3eea9d5e5f98 (diff) | |
Riff Container Stream Writing (#1116)
* * Added option to get random bytes from RandomGenerator
* Added ability to allocate only in current block on MemoryArena
* Allowed RiffContainer to not allocate new Data blocks, if can just extend the Data it has (because it's at the end of current block and there is space for the new data).
* Added coverage for change on Riff unit test
* Add test coverage for allocations over multiple Data blocks.
* Improve comment on riff unit tests.
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); } |
