// File: /workspace/github_cpp_makefile_star2_O3/rellla[P]E3DC-Rscp/RscpProtocol.cpp
// Function: RscpProtocol::createFrameAsBuffer(SRscpFrameBuffer*, SRscpFrame const&, bool)
int32_t RscpProtocol::createFrameAsBuffer(SRscpFrameBuffer *frameBuffer, const SRscpFrame & frame, bool calcCRC) {

	if(frameBuffer == NULL) {
		return RSCP::ERR_INVALID_INPUT;
	}

	// calculate the required frame size
	size_t sFrameSize =  sizeof(SRscpFrameHeader);

	// calculate the complete data size
	size_t sDataSize = 0;
	for(size_t i = 0; i < frame.data.size(); ++i) {
		sDataSize += sizeof(SRscpValue) - sizeof(frame.data[i].data) + frame.data[i].length;
	}

	// allocate the required memory
	frameBuffer->data = (uint8_t *) malloc(sFrameSize + sDataSize + (calcCRC ? 4 : 0));
	if(frameBuffer->data == NULL) {
		return RSCP::ERR_NO_MEMORY;
	}
	// set the memory size
	frameBuffer->dataLength = sFrameSize + sDataSize + (calcCRC ? 4 : 0);

	// copy header information
	memcpy(frameBuffer->data, &frame.header, sFrameSize);

	// insert data from the SRscpValues
	uint8_t *dataPtr = frameBuffer->data + sFrameSize;
	for(size_t i = 0; i < frame.data.size(); ++i) {
		SRscpValue *value = reinterpret_cast<SRscpValue *>(dataPtr);
		value->tag = frame.data[i].tag;
		value->dataType = frame.data[i].dataType;
		value->length = frame.data[i].length;
		if(value->length > 0) {
			// copy into the position of the data pointer and not into the data pointer itself as the data is appended
			memcpy(&value->data, frame.data[i].data, frame.data[i].length);
		}
		dataPtr += sizeof(SRscpValue) - sizeof(frame.data[i].data) + frame.data[i].length;
	}

	// calculate CRC if necessary and add to the frame
	if(calcCRC) {
		uint32_t uCRC32 = calculateCRC32(frameBuffer->data, frameBuffer->dataLength - sizeof(uint32_t));
		memcpy(frameBuffer->data + frameBuffer->dataLength - sizeof(uCRC32), &uCRC32, sizeof(uCRC32));
	}

	return RSCP::OK;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
testq %rsi, %rsi
je 0x4e25
movq %rdx, %r12
movq %rsi, %r13
movq 0x18(%rdx), %rbp
movq 0x20(%rdx), %rdx
movq %rdx, %rax
subq %rbp, %rax
movabsq $-0x1111111111111111, %rbx # imm = 0xEEEEEEEEEEEEEEEF
imulq %rax, %rbx
movq %rdx, 0x10(%rsp)
cmpq %rbp, %rdx
je 0x4e2f
cmpq $0x1, %rbx
movq %rbx, %rdi
adcq $0x0, %rdi
leaq 0x5(%rbp), %rdx
xorl %eax, %eax
movzwl (%rdx), %esi
addq %rsi, %rax
addq $0x7, %rax
addq $0xf, %rdx
decq %rdi
jne 0x4e10
jmp 0x4e31
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
jmp 0x4ef8
xorl %eax, %eax
movl %ecx, 0xc(%rsp)
movzbl %cl, %ecx
leaq (%rax,%rcx,4), %r14
addq $0x12, %r14
movq %r14, %rdi
callq 0x2190
movq %rax, (%r13)
testq %rax, %rax
je 0x4ef3
movq %rax, %r15
movl %r14d, 0x8(%r13)
movzwl 0x10(%r12), %eax
movw %ax, 0x10(%r15)
movups (%r12), %xmm0
movups %xmm0, (%r15)
cmpq %rbp, 0x10(%rsp)
movq %r14, %r13
je 0x4ed1
movq %r15, %r14
addq $0x12, %r14
cmpq $0x1, %rbx
adcq $0x0, %rbx
addq $0x7, %rbp
movl -0x7(%rbp), %eax
movl %eax, (%r14)
movb -0x3(%rbp), %al
movb %al, 0x4(%r14)
movzwl -0x2(%rbp), %r12d
movw %r12w, 0x5(%r14)
testq %r12, %r12
je 0x4ebf
leaq 0x7(%r14), %rdi
movq (%rbp), %rsi
movq %r12, %rdx
callq 0x20f0
addq $0x7, %r12
jmp 0x4ec5
movl $0x7, %r12d
addq %r12, %r14
addq $0xf, %rbp
decq %rbx
jne 0x4e8d
xorl %ebp, %ebp
cmpb $0x0, 0xc(%rsp)
je 0x4ef8
leal -0x4(%r13), %eax
movzwl %ax, %edx
movq %r15, %rsi
callq 0x4a32
movl %r13d, %ecx
movl %eax, -0x4(%r15,%rcx)
jmp 0x4ef8
movl $0xfffffffe, %ebp       # imm = 0xFFFFFFFE
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop