// File: /workspace/github_cpp_makefile_star2_O3/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
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jne 0x51d0
movl (%rdx), %ecx
movl $0xfffffffb, %eax       # imm = 0xFFFFFFFB
cmpl $0x12, %ecx
jb 0x51d0
movq %rsi, %rbx
movl $0xfffffffd, %eax       # imm = 0xFFFFFFFD
cmpw $0xdce3, (%rsi)         # imm = 0xDCE3
jne 0x51d0
movzwl 0x2(%rbx), %edx
movl %edx, %esi
andl $0xf00, %esi            # imm = 0xF00
movl $0xfffffffc, %eax       # imm = 0xFFFFFFFC
cmpl $0x100, %esi            # imm = 0x100
jne 0x51d0
movzwl 0x10(%rbx), %eax
andl $0x1000, %edx           # imm = 0x1000
movl %edx, %esi
shrl $0xa, %esi
leaq (%rax,%rsi), %r12
addq $0x12, %r12
movl $0xfffffffb, %eax       # imm = 0xFFFFFFFB
cmpl %ecx, %r12d
ja 0x51d0
movq %rdi, %r15
testw %dx, %dx
je 0x5189
leal -0x4(%r12), %eax
movzwl %ax, %edx
movq %rbx, %rsi
callq 0x4a32
movl %eax, %ecx
movl $0xfffffffa, %eax       # imm = 0xFFFFFFFA
cmpl %ecx, -0x4(%rbx,%r12)
je 0x518b
jmp 0x51d0
xorl %ecx, %ecx
movl %ecx, 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 0x51dc
testl %eax, %eax
js 0x51d0
movzwl 0x2(%rbx), %ecx
shrl $0xa, %ecx
andl $0x4, %ecx
addl %ecx, %eax
addl $0x12, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq