copies one buffer to another * * Copy all data streams from one buffer to another, element wise. * * [icon:attention] Each of the source streams must have a matching stream in the * destination buffer. The streams must match in both type and size. * The source and destination buffer can be the same. * * @name buffer.copy_buffer * @param dst [type:buffer
| 594 | * ``` |
| 595 | */ |
| 596 | static int CopyBuffer(lua_State* L) |
| 597 | { |
| 598 | DM_LUA_STACK_CHECK(L, 0); |
| 599 | |
| 600 | dmBuffer::HBuffer dst_hbuffer = dmScript::CheckBufferUnpack(L, 1); |
| 601 | dmBuffer::HBuffer src_hbuffer = dmScript::CheckBufferUnpack(L, 3); |
| 602 | dmBuffer::HBuffer dstbuffer = dst_hbuffer; |
| 603 | dmBuffer::HBuffer srcbuffer = src_hbuffer; |
| 604 | int dstoffset = luaL_checkint(L, 2); |
| 605 | int srcoffset = luaL_checkint(L, 4); |
| 606 | int count = luaL_checkint(L, 5); |
| 607 | |
| 608 | // Validate first |
| 609 | if( count <= 0 ) |
| 610 | { |
| 611 | return DM_LUA_ERROR("Invalid elements to copy: %u", count); |
| 612 | } |
| 613 | |
| 614 | dmBuffer::Result r; |
| 615 | uint32_t dstcount; |
| 616 | uint32_t srccount; |
| 617 | dmBuffer::GetCount(dstbuffer, &dstcount); |
| 618 | dmBuffer::GetCount(srcbuffer, &srccount); |
| 619 | if( (dstoffset + count) > (int)dstcount ) |
| 620 | { |
| 621 | return DM_LUA_ERROR("Trying to write too many elements: Destination buffer length: %u, Offset: %u, Values to copy: %u", dstcount, dstoffset, count); |
| 622 | } |
| 623 | if( (srcoffset + count) > (int)srccount ) |
| 624 | { |
| 625 | return DM_LUA_ERROR("Trying to read too many elements: Destination buffer length: %u, Offset: %u, Values to copy: %u", dstcount, dstoffset, count); |
| 626 | } |
| 627 | |
| 628 | // Validate that target buffer has those stream names |
| 629 | uint32_t num_streams; |
| 630 | dmBuffer::GetNumStreams(srcbuffer, &num_streams); |
| 631 | |
| 632 | // Simple optimisation: Reusing this struct to hold some data between the validation step and the actual copy step |
| 633 | BufferStream* stream_info = (BufferStream*)alloca( num_streams * 2 * sizeof(BufferStream) ); |
| 634 | |
| 635 | for( uint32_t i = 0; i < num_streams; ++i ) |
| 636 | { |
| 637 | BufferStream* dststream = &stream_info[i*2 + 0]; |
| 638 | BufferStream* srcstream = &stream_info[i*2 + 1]; |
| 639 | |
| 640 | dmBuffer::GetStreamName(srcbuffer, i, &srcstream->m_Name); |
| 641 | dmhash_t stream_name = srcstream->m_Name; |
| 642 | |
| 643 | r = dmBuffer::GetStream(dstbuffer, stream_name, (void**)&dststream->m_Data, &dststream->m_Count, &dststream->m_TypeCount, &dststream->m_Stride); |
| 644 | if( r == dmBuffer::RESULT_STREAM_MISSING ) |
| 645 | { |
| 646 | return DM_LUA_ERROR("buffer.copy_buffer: Destination buffer has no stream named: %s", dmHashReverseSafe64(stream_name)); |
| 647 | } |
| 648 | else if( r != dmBuffer::RESULT_OK ) |
| 649 | { |
| 650 | return DM_LUA_ERROR("buffer.copy_buffer: Failed getting destination byte array: %s", dmBuffer::GetResultString(r)); |
| 651 | } |
| 652 | |
| 653 | dmBuffer::GetStream(srcbuffer, stream_name, (void**)&srcstream->m_Data, &srcstream->m_Count, &srcstream->m_TypeCount, &srcstream->m_Stride); |
nothing calls this directly
no test coverage detected