// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %rax
testq %rsi, %rsi
je 0x47b2
movl %ecx, %r15d
movq %rdx, %r13
movq %rsi, %rbp
movq 0x18(%rdx), %rbx
movq 0x20(%rdx), %rax
subq %rbx, %rax
pushq $0xf
popq %rcx
cqto
idivq %rcx
movq %rax, %r14
leaq 0x5(%rbx), %rcx
xorl %eax, %eax
movq %r14, %rdx
subq $0x1, %rdx
jb 0x46fe
movzwl (%rcx), %esi
addq %rsi, %rax
addq $0x7, %rax
addq $0xf, %rcx
jmp 0x46e8
movzbl %r15b, %ecx
leaq (%rax,%rcx,4), %r12
addq $0x12, %r12
movq %r12, %rdi
callq 0x21d0
movq %rax, (%rbp)
testq %rax, %rax
je 0x47b6
movl %r15d, 0x4(%rsp)
movl %r12d, 0x8(%rbp)
movzwl 0x10(%r13), %ecx
movw %cx, 0x10(%rax)
movups (%r13), %xmm0
movups %xmm0, (%rax)
movq %rax, %rbp
addq $0x12, %rbp
addq $0x7, %rbx
subq $0x1, %r14
jb 0x478d
movl -0x7(%rbx), %ecx
movl %ecx, (%rbp)
movb -0x3(%rbx), %cl
movb %cl, 0x4(%rbp)
movzwl -0x2(%rbx), %r13d
movw %r13w, 0x5(%rbp)
pushq $0x7
popq %rcx
testq %r13, %r13
je 0x4784
leaq 0x7(%rbp), %rdi
movq %rax, %r15
movq (%rbx), %rsi
movq %r13, %rdx
callq 0x2120
movq %r15, %rax
addq $0x7, %r13
movq %r13, %rcx
addq %rcx, %rbp
addq $0xf, %rbx
jmp 0x4744
xorl %ebp, %ebp
cmpb $0x0, 0x4(%rsp)
je 0x47b9
leal -0x4(%r12), %ecx
movzwl %cx, %edx
movq %rax, %rbx
movq %rax, %rsi
callq 0x43d0
movl %r12d, %ecx
movl %eax, -0x4(%rbx,%rcx)
jmp 0x47b9
pushq $-0x1
jmp 0x47b8
pushq $-0x2
popq %rbp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq