// File: /workspace/github_cpp_makefile_star2_O1/jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_cursor_get
int
mdb_cursor_get(MDB_cursor *mc, MDB_val *key, MDB_val *data,
    MDB_cursor_op op)
{
	int		 rc;
	int		 exact = 0;
	int		 (*mfunc)(MDB_cursor *mc, MDB_val *key, MDB_val *data);

	if (mc == NULL)
		return EINVAL;

	if (mc->mc_txn->mt_flags & MDB_TXN_BLOCKED)
		return MDB_BAD_TXN;

	switch (op) {
	case MDB_GET_CURRENT:
		if (!(mc->mc_flags & C_INITIALIZED)) {
			rc = EINVAL;
		} else {
			MDB_page *mp = mc->mc_pg[mc->mc_top];
			int nkeys = NUMKEYS(mp);
			if (!nkeys || mc->mc_ki[mc->mc_top] >= nkeys) {
				mc->mc_ki[mc->mc_top] = nkeys;
				rc = MDB_NOTFOUND;
				break;
			}
			rc = MDB_SUCCESS;
			if (IS_LEAF2(mp)) {
				key->mv_size = mc->mc_db->md_pad;
				key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size);
			} else {
				MDB_node *leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
				MDB_GET_KEY(leaf, key);
				if (data) {
					if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
						if (mc->mc_flags & C_DEL)
							mdb_xcursor_init1(mc, leaf);
						rc = mdb_cursor_get(&mc->mc_xcursor->mx_cursor, data, NULL, MDB_GET_CURRENT);
					} else {
						rc = mdb_node_read(mc->mc_txn, leaf, data);
					}
				}
			}
		}
		break;
	case MDB_GET_BOTH:
	case MDB_GET_BOTH_RANGE:
		if (data == NULL) {
			rc = EINVAL;
			break;
		}
		if (mc->mc_xcursor == NULL) {
			rc = MDB_INCOMPATIBLE;
			break;
		}
		/* FALLTHRU */
	case MDB_SET:
	case MDB_SET_KEY:
	case MDB_SET_RANGE:
		if (key == NULL) {
			rc = EINVAL;
		} else {
			rc = mdb_cursor_set(mc, key, data, op,
				op == MDB_SET_RANGE ? NULL : &exact);
		}
		break;
	case MDB_GET_MULTIPLE:
		if (data == NULL || !(mc->mc_flags & C_INITIALIZED)) {
			rc = EINVAL;
			break;
		}
		if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) {
			rc = MDB_INCOMPATIBLE;
			break;
		}
		rc = MDB_SUCCESS;
		if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) ||
			(mc->mc_xcursor->mx_cursor.mc_flags & C_EOF))
			break;
		goto fetchm;
	case MDB_NEXT_MULTIPLE:
		if (data == NULL) {
			rc = EINVAL;
			break;
		}
		if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) {
			rc = MDB_INCOMPATIBLE;
			break;
		}
		if (!(mc->mc_flags & C_INITIALIZED))
			rc = mdb_cursor_first(mc, key, data);
		else
			rc = mdb_cursor_next(mc, key, data, MDB_NEXT_DUP);
		if (rc == MDB_SUCCESS) {
			if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) {
				MDB_cursor *mx;
fetchm:
				mx = &mc->mc_xcursor->mx_cursor;
				data->mv_size = NUMKEYS(mx->mc_pg[mx->mc_top]) *
					mx->mc_db->md_pad;
				data->mv_data = METADATA(mx->mc_pg[mx->mc_top]);
				mx->mc_ki[mx->mc_top] = NUMKEYS(mx->mc_pg[mx->mc_top])-1;
			} else {
				rc = MDB_NOTFOUND;
			}
		}
		break;
	case MDB_NEXT:
	case MDB_NEXT_DUP:
	case MDB_NEXT_NODUP:
		if (!(mc->mc_flags & C_INITIALIZED))
			rc = mdb_cursor_first(mc, key, data);
		else
			rc = mdb_cursor_next(mc, key, data, op);
		break;
	case MDB_PREV:
	case MDB_PREV_DUP:
	case MDB_PREV_NODUP:
		if (!(mc->mc_flags & C_INITIALIZED)) {
			rc = mdb_cursor_last(mc, key, data);
			if (rc)
				break;
			mc->mc_flags |= C_INITIALIZED;
			mc->mc_ki[mc->mc_top]++;
		}
		rc = mdb_cursor_prev(mc, key, data, op);
		break;
	case MDB_FIRST:
		rc = mdb_cursor_first(mc, key, data);
		break;
	case MDB_FIRST_DUP:
		mfunc = mdb_cursor_first;
	mmove:
		if (data == NULL || !(mc->mc_flags & C_INITIALIZED)) {
			rc = EINVAL;
			break;
		}
		if (mc->mc_xcursor == NULL) {
			rc = MDB_INCOMPATIBLE;
			break;
		}
		{
			MDB_node *leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
			if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) {
				MDB_GET_KEY(leaf, key);
				rc = mdb_node_read(mc->mc_txn, leaf, data);
				break;
			}
		}
		if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) {
			rc = EINVAL;
			break;
		}
		rc = mfunc(&mc->mc_xcursor->mx_cursor, data, NULL);
		break;
	case MDB_LAST:
		rc = mdb_cursor_last(mc, key, data);
		break;
	case MDB_LAST_DUP:
		mfunc = mdb_cursor_last;
		goto mmove;
	default:
		DPRINTF(("unhandled/unimplemented cursor operation %u", op));
		rc = EINVAL;
		break;
	}

	if (mc->mc_flags & C_DEL)
		mc->mc_flags ^= C_DEL;

	return rc;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x10, %rsp
movl $0x0, 0xc(%rsp)
testq %rdi, %rdi
je 0x6344
movq %rdi, %rbx
movq 0x18(%rdi), %rdi
movl $0xffff87c2, %eax       # imm = 0xFFFF87C2
testb $0x13, 0x7c(%rdi)
jne 0x6634
movl %ecx, %ebp
movl $0x16, %eax
cmpl $0x11, %ecx
ja 0x6626
movq %rdx, %r14
movq %rsi, %r15
movl %ebp, %ecx
leaq 0x9012(%rip), %rdx      # 0xf330
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
testb $0x1, 0x44(%rbx)
jne 0x63cf
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x67c9
jmp 0x6626
movl $0x16, %eax
jmp 0x6634
testb $0x1, 0x44(%rbx)
jne 0x637a
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x6b13
testl %eax, %eax
jne 0x6626
orb $0x1, 0x44(%rbx)
movzwl 0x42(%rbx), %eax
incw 0x148(%rbx,%rax,2)
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
movl %ebp, %ecx
callq 0x6c3e
jmp 0x6626
testq %r14, %r14
je 0x6626
cmpq $0x0, 0x10(%rbx)
je 0x6584
testq %r15, %r15
je 0x6626
xorl %eax, %eax
cmpl $0x11, %ebp
leaq 0xc(%rsp), %r8
cmoveq %rax, %r8
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
movl %ebp, %ecx
callq 0x5cd7
jmp 0x6626
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
movl %ebp, %ecx
callq 0x68e8
jmp 0x6626
testq %r14, %r14
je 0x6626
movq 0x28(%rbx), %rcx
movl $0xffff87c0, %eax       # imm = 0xFFFF87C0
testb $0x10, 0x4(%rcx)
je 0x6626
testb $0x1, 0x44(%rbx)
jne 0x65a1
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x67c9
jmp 0x65b4
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x6b13
jmp 0x6626
movl 0x44(%rbx), %ecx
testb $0x1, %cl
je 0x6626
movzwl 0x42(%rbx), %edx
movq 0x48(%rbx,%rdx,8), %rax
movzwl 0xc(%rax), %esi
addl $-0x10, %esi
movl %esi, %r8d
shrl %r8d
cmpl $0x2, %esi
jb 0x658e
movzwl 0x148(%rbx,%rdx,2), %esi
cmpl %esi, %r8d
jbe 0x658e
testb $0x20, 0xa(%rax)
jne 0x660c
movzwl 0x10(%rax,%rsi,2), %esi
addq %rax, %rsi
testq %r15, %r15
je 0x6492
movzwl 0x6(%rsi), %eax
movq %rax, (%r15)
leaq 0x8(%rsi), %rax
movq %rax, 0x8(%r15)
testq %r14, %r14
je 0x6624
testb $0x4, 0x4(%rsi)
jne 0x6641
movq %r14, %rdx
callq 0x6780
jmp 0x6626
leaq 0x310(%rip), %r12       # 0x67c9
jmp 0x64c2
leaq 0x651(%rip), %r12       # 0x6b13
testq %r14, %r14
je 0x6626
testb $0x1, 0x44(%rbx)
je 0x6626
cmpq $0x0, 0x10(%rbx)
je 0x6584
movzwl 0x42(%rbx), %eax
movq 0x48(%rbx,%rax,8), %rsi
movzwl 0x148(%rbx,%rax,2), %eax
movzwl 0x10(%rsi,%rax,2), %ecx
movzwl 0x4(%rsi,%rcx), %ebp
testb $0x4, %bpl
jne 0x6520
addq %rcx, %rsi
testq %r15, %r15
je 0x6518
movzwl 0x6(%rsi), %eax
movq %rax, (%r15)
leaq 0x8(%rsi), %rax
movq %rax, 0x8(%r15)
movq %r14, %rdx
callq 0x6780
testb $0x4, %bpl
je 0x6626
movq 0x10(%rbx), %rdi
testb $0x1, 0x44(%rdi)
movl $0x16, %eax
je 0x6626
movq %r14, %rsi
xorl %edx, %edx
callq *%r12
jmp 0x6626
testq %r14, %r14
je 0x6626
testb $0x1, 0x44(%rbx)
je 0x6626
movq 0x28(%rbx), %rcx
movl $0xffff87c0, %eax       # imm = 0xFFFF87C0
testb $0x10, 0x4(%rcx)
je 0x6626
movq 0x10(%rbx), %rax
movl 0x44(%rax), %eax
andl $0x3, %eax
cmpl $0x1, %eax
je 0x65c7
jmp 0x6624
movl $0xffff87c0, %eax       # imm = 0xFFFF87C0
jmp 0x6626
movw %r8w, 0x148(%rbx,%rdx,2)
movl $0xffff87b2, %eax       # imm = 0xFFFF87B2
jmp 0x6626
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
movl $0x9, %ecx
callq 0x68e8
testl %eax, %eax
jne 0x6626
movq 0x10(%rbx), %rcx
movl $0xffff87b2, %eax       # imm = 0xFFFF87B2
testb $0x1, 0x44(%rcx)
je 0x6626
movq 0x10(%rbx), %rax
movzwl 0x42(%rax), %ecx
movq 0x48(%rax,%rcx,8), %rdx
movzwl 0xc(%rdx), %esi
addl $-0x10, %esi
shrl %esi
movq 0x28(%rax), %rdi
imull (%rdi), %esi
movq %rsi, (%r14)
addq $0x10, %rdx
movq %rdx, 0x8(%r14)
movq 0x48(%rax,%rcx,8), %rdx
movzwl 0xc(%rdx), %edx
addl $0x1fff0, %edx          # imm = 0x1FFF0
shrl %edx
decl %edx
movw %dx, 0x148(%rax,%rcx,2)
jmp 0x6624
movq 0x28(%rbx), %rcx
movl (%rcx), %ecx
movq %rcx, (%r15)
imulq %rcx, %rsi
addq %rsi, %rax
addq $0x10, %rax
movq %rax, 0x8(%r15)
xorl %eax, %eax
movl 0x44(%rbx), %ecx
testb $0x8, %cl
je 0x6634
andl $-0x9, %ecx
movl %ecx, 0x44(%rbx)
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
testb $0x8, %cl
je 0x664e
movq %rbx, %rdi
callq 0x6663
movq 0x10(%rbx), %rdi
movq %r14, %rsi
xorl %edx, %edx
movl $0x4, %ecx
callq 0x62d0
jmp 0x6626