// File: /workspace/github_cpp_makefile_star2_O2/rellla[P]E3DC-Rscp/RscpProtocol.cpp
// Function: RscpProtocol::parseFrame(unsigned char const*, unsigned int const&, SRscpFrame*)
int32_t RscpProtocol::parseFrame(const uint8_t* data, const uint32_t & length, SRscpFrame* frame) {
	// sanity check
	if((data == NULL) || (frame == NULL)) {
		return RSCP::ERR_INVALID_INPUT;
	}
	// check first that at least the header size is in the frame
	if(sizeof(SRscpFrameHeader) > length) {
		return RSCP::ERR_INVALID_FRAME_LENGTH;
	}
	// assign pointer to the data struct
	SRscpFrame* inFrame = reinterpret_cast<SRscpFrame*>((uint8_t*)data);
	// check if the magic matches
	if(inFrame->header.magic != RSCP::MAGIC) {
		return RSCP::ERR_INVALID_MAGIC;
	}
	// check the frame version number
	if(inFrame->header.ctrl.bits.version != RSCP::VERSION) {
		return RSCP::ERR_PROT_VERSION_MISMATCH;
	}
	// check the frame length
	uint32_t frameLength = sizeof(SRscpFrameHeader) + inFrame->header.dataLength + ((inFrame->header.ctrl.bits.crc != 0) ? sizeof(uint32_t) : 0);
	if(frameLength > length) {
		return RSCP::ERR_INVALID_FRAME_LENGTH;
	}
	// check that CRC matches before starting to parse
	if(inFrame->header.ctrl.bits.crc != 0) {
		uint32_t calcCRC32 = calculateCRC32(data, frameLength - sizeof(uint32_t));
		uint32_t frameCRC32;
		memcpy(&frameCRC32, data + frameLength - sizeof(uint32_t), sizeof(uint32_t));
		// compare CRC
		if(frameCRC32 != calcCRC32) {
			return RSCP::ERR_INVALID_CRC;
		}
		// CRC matches set the CRC inside the output frame
		frame->CRC = frameCRC32;
	}
	else {
		// no CRC inside the frame -> set 0 for output frame
		frame->CRC = 0;
	}
	// copy header information
	memcpy(&frame->header, &inFrame->header, sizeof(SRscpFrameHeader));
	// parse the SRscpValues
	int32_t iResult = parseData((uint8_t*)(&inFrame->header + 1), inFrame->header.dataLength, frame->data);
	if(iResult < 0) {
		return iResult;
	}
	// parsing done return OK
	frameLength = (sizeof(SRscpFrameHeader) + iResult + ((inFrame->header.ctrl.bits.crc != 0) ? sizeof(uint32_t) : 0));
	return frameLength;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, %r14
testq %rsi, %rsi
sete %al
testq %rcx, %rcx
sete %cl
orb %al, %cl
je 0x495a
pushq $-0x1
popq %rax
jmp 0x4964
movl (%rdx), %ecx
pushq $-0x5
popq %rax
cmpl $0x12, %ecx
jae 0x4970
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq %rsi, %rbx
cmpw $0xdce3, (%rsi)         # imm = 0xDCE3
jne 0x49cc
movzwl 0x2(%rbx), %edx
movl %edx, %esi
andl $0xf00, %esi            # imm = 0xF00
cmpw $0x100, %si             # imm = 0x100
jne 0x49d0
movq %rdi, %r15
movzwl 0x10(%rbx), %esi
andl $0x1000, %edx           # imm = 0x1000
movl %edx, %edi
shrl $0xa, %edi
leaq (%rsi,%rdi), %r12
addq $0x12, %r12
cmpl %ecx, %r12d
ja 0x4964
testw %dx, %dx
je 0x49d4
leal -0x4(%r12), %eax
movzwl %ax, %edx
movq %rbx, %rsi
callq 0x43d0
cmpl %eax, -0x4(%rbx,%r12)
je 0x49d6
pushq $-0x6
jmp 0x4957
pushq $-0x3
jmp 0x4957
pushq $-0x4
jmp 0x4957
xorl %eax, %eax
movl %eax, 0x30(%r14)
movups (%rbx), %xmm0
movups %xmm0, (%r14)
movzwl 0x10(%rbx), %eax
movw %ax, 0x10(%r14)
leaq 0x12(%rbx), %rsi
movzwl 0x10(%rbx), %eax
leaq 0x4(%rsp), %rdx
movl %eax, (%rdx)
addq $0x18, %r14
movq %r15, %rdi
movq %r14, %rcx
callq 0x4a24
testl %eax, %eax
js 0x4964
movzwl 0x2(%rbx), %ecx
shrl $0xa, %ecx
andl $0x4, %ecx
addl %ecx, %eax
addl $0x12, %eax
jmp 0x4964