// File: xocoder[P]m_kcptun/vendor/kcp/ikcp.c
// Function: ikcp_parse_data(IKCPCB*, IKCPSEG*)
void ikcp_parse_data(ikcpcb *kcp, IKCPSEG *newseg)
{
	struct IQUEUEHEAD *p, *prev;
	IUINT32 sn = newseg->sn;
	int repeat = 0;
	
	if (_itimediff(sn, kcp->rcv_nxt + kcp->rcv_wnd) >= 0 ||
		_itimediff(sn, kcp->rcv_nxt) < 0) {
		ikcp_segment_delete(kcp, newseg);
		return;
	}

	for (p = kcp->rcv_buf.prev; p != &kcp->rcv_buf; p = prev) {
		IKCPSEG *seg = iqueue_entry(p, IKCPSEG, node);
		prev = p->prev;
		if (seg->sn == sn) {
			repeat = 1;
			break;
		}
		if (_itimediff(sn, seg->sn) > 0) {
			break;
		}
	}

	if (repeat == 0) {
		iqueue_init(&newseg->node);
		iqueue_add(&newseg->node, p);
		kcp->nrcv_buf++;
	}	else {
		ikcp_segment_delete(kcp, newseg);
	}

#if 0
	ikcp_qprint("rcvbuf", &kcp->rcv_buf);
	printf("rcv_nxt=%lu\n", kcp->rcv_nxt);
#endif

	// move available data from rcv_buf -> rcv_queue
	while (! iqueue_is_empty(&kcp->rcv_buf)) {
		IKCPSEG *seg = iqueue_entry(kcp->rcv_buf.next, IKCPSEG, node);
		if (seg->sn == kcp->rcv_nxt && kcp->nrcv_que < kcp->rcv_wnd) {
			iqueue_del(&seg->node);
			kcp->nrcv_buf--;
			iqueue_add_tail(&seg->node, &kcp->rcv_queue);
			kcp->nrcv_que++;
			kcp->rcv_nxt++;
		}	else {
			break;
		}
	}

#if 0
	ikcp_qprint("queue", &kcp->rcv_queue);
	printf("rcv_nxt=%lu\n", kcp->rcv_nxt);
#endif

#if 1
//	printf("snd(buf=%d, queue=%d)\n", kcp->nsnd_buf, kcp->nsnd_que);
//	printf("rcv(buf=%d, queue=%d)\n", kcp->nrcv_buf, kcp->nrcv_que);
#endif
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl 0x24(%rax), %eax
movl %eax, -0x24(%rbp)
movl $0x0, -0x28(%rbp)
movl -0x24(%rbp), %edi
movq -0x8(%rbp), %rax
movl 0x18(%rax), %esi
movq -0x8(%rbp), %rax
addl 0x3c(%rax), %esi
callq 0x4ae0
cmpq $0x0, %rax
jge 0x48d2
movl -0x24(%rbp), %edi
movq -0x8(%rbp), %rax
movl 0x18(%rax), %esi
callq 0x4ae0
cmpq $0x0, %rax
jge 0x48e4
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x3f30
jmp 0x4ace
movq -0x8(%rbp), %rax
movq 0xc0(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq -0x8(%rbp), %rcx
addq $0xb8, %rcx
cmpq %rcx, %rax
je 0x4953
movq -0x18(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x30(%rbp), %rax
movl 0x24(%rax), %eax
cmpl -0x24(%rbp), %eax
jne 0x4930
movl $0x1, -0x28(%rbp)
jmp 0x4953
movl -0x24(%rbp), %edi
movq -0x30(%rbp), %rax
movl 0x24(%rax), %esi
callq 0x4ae0
cmpq $0x0, %rax
jle 0x4947
jmp 0x4953
jmp 0x4949
movq -0x20(%rbp), %rax
movq %rax, -0x18(%rbp)
jmp 0x48f3
cmpl $0x0, -0x28(%rbp)
jne 0x49b3
movq -0x10(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rcx, 0x8(%rax)
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x8(%rbp), %rax
movl 0x5c(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x5c(%rax)
jmp 0x49c0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x3f30
jmp 0x49c2
movq -0x8(%rbp), %rax
addq $0xb8, %rax
movq -0x8(%rbp), %rcx
cmpq 0xb8(%rcx), %rax
sete %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x49e5
jmp 0x4ace
movq -0x8(%rbp), %rax
movq 0xb8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movl 0x24(%rax), %eax
movq -0x8(%rbp), %rcx
cmpl 0x18(%rcx), %eax
jne 0x4ac7
movq -0x8(%rbp), %rax
movl 0x64(%rax), %eax
movq -0x8(%rbp), %rcx
cmpl 0x3c(%rcx), %eax
jae 0x4ac7
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq %rcx, 0x8(%rax)
movq -0x38(%rbp), %rax
movq (%rax), %rcx
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rax
movq $0x0, (%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x8(%rbp), %rax
movl 0x5c(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0x5c(%rax)
movq -0x8(%rbp), %rax
movq 0xa0(%rax), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rcx
addq $0x98, %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rcx
movq -0x8(%rbp), %rax
movq 0xa0(%rax), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0xa0(%rax)
movq -0x8(%rbp), %rax
movl 0x64(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x64(%rax)
movq -0x8(%rbp), %rax
movl 0x18(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x18(%rax)
jmp 0x4ac9
jmp 0x4ace
jmp 0x49c2
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)