MCPcopy Create free account
hub / github.com/defold/defold / CopyBuffer

Function CopyBuffer

engine/gamesys/src/gamesys/scripts/script_buffer.cpp:596–681  ·  view source on GitHub ↗

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

Source from the content-addressed store, hash-verified

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);

Callers

nothing calls this directly

Calls 10

CheckBufferUnpackFunction · 0.85
GetCountFunction · 0.85
GetNumStreamsFunction · 0.85
GetStreamNameFunction · 0.85
dmHashReverseSafe64Function · 0.85
GetResultStringFunction · 0.85
GetStreamTypeFunction · 0.85
GetValueTypeStringFunction · 0.85
CopyStreamInternalFunction · 0.85
GetStreamFunction · 0.70

Tested by

no test coverage detected