// File: /workspace/github_c_makefile_star2_O0/Tarsnap[P]kivaloo/kvlds/serialize.c
// Function: deserialize
int
deserialize(struct node * N, const uint8_t * buf, size_t buflen)
{
	uint8_t * p;
	size_t i;

	/*
	 * Clear errno; we will use it to distinguish between internal errors
	 * (i.e., ENOMEM) and invalid page data.
	 */
	errno = 0;

	/*
	 * Sanity check: We can only deserialize a page into a node which is
	 * being fetched (NODE_TYPE_READ) and clean (NODE_STATE_CLEAN).
	 */
	assert(N->type == NODE_TYPE_READ);
	assert(N->state == NODE_STATE_CLEAN);

	/* Copy the serialized page. */
	if ((N->pagebuf = malloc(buflen)) == NULL)
		goto err0;
	memcpy(N->pagebuf, buf, buflen);
	p = N->pagebuf;

	/* Check magic. */
	if (buflen < 6)
		goto err1;
	if (memcmp(p, "KVLDS\0", 6))
		goto err1;
	p += 6; buflen -= 6;

	/* Parse # of keys. */
	if (buflen < 2)
		goto err1;
	N->nkeys = be16dec(p);
	p += 2; buflen -= 2;

	/* Parse height and rootedness. */
	if (buflen < 1)
		goto err1;
	if (p[0] & 0x80)
		N->root = 1;
	else
		N->root = 0;
	N->height = p[0] & 0x7f;
	if (N->height)
		N->type = NODE_TYPE_PARENT;
	else
		N->type = NODE_TYPE_LEAF;
	p += 1; buflen -= 1;

	/* Parse matching prefix length. */
	N->mlen_t = p[0];
	p += 1; buflen -= 1;

	/* Skip root data if appropriate. */
	if (N->root) {
		p += 8;
		buflen -= 8;
	}

	/* Parse node data. */
	if (N->type == NODE_TYPE_LEAF) {
		/* Allocate array of key-value pairs. */
		if (IMALLOC(N->u.pairs, N->nkeys, struct kvpair_const))
			goto err1;

		/* Parse keys. */
		for (i = 0; i < N->nkeys; i++) {
			if (buflen == 0)
				goto err2;
			N->u.pairs[i].k = (struct kvldskey *)p;
			if (buflen < kvldskey_serial_size(N->u.pairs[i].k))
				goto err2;
			p += kvldskey_serial_size(N->u.pairs[i].k);
			buflen -= kvldskey_serial_size(N->u.pairs[i].k);
		}

		/* Parse values. */
		for (i = 0; i < N->nkeys; i++) {
			if (buflen == 0)
				goto err2;
			N->u.pairs[i].v = (struct kvldskey *)p;
			if (buflen < kvldskey_serial_size(N->u.pairs[i].v))
				goto err2;
			p += kvldskey_serial_size(N->u.pairs[i].v);
			buflen -= kvldskey_serial_size(N->u.pairs[i].v);
		}

		/* Figure out how far the keys match. */
		if (N->nkeys > 0) {
			N->mlen_n = (uint8_t)kvldskey_mlen(N->u.pairs[0].k,
			    N->u.pairs[N->nkeys - 1].k);
		} else {
			N->mlen_n = 255;
		}

		/* Make sure that the rest of the page is zeros. */
		while (buflen) {
			if (*p != 0)
				goto err2;
			p++; buflen--;
		}
	} else {
		/* Allocate array of keys. */
		if (IMALLOC(N->u.keys, N->nkeys, const struct kvldskey *))
			goto err1;

		/* Parse keys. */
		for (i = 0; i < N->nkeys; i++) {
			if (buflen == 0)
				goto err3;
			N->u.keys[i] = (struct kvldskey *)p;
			if (buflen < kvldskey_serial_size(N->u.keys[i]))
				goto err3;
			p += kvldskey_serial_size(N->u.keys[i]);
			buflen -= kvldskey_serial_size(N->u.keys[i]);
		}

		/* Allocate array of children. */
		if (IMALLOC(N->v.children, N->nkeys + 1, struct node *))
			goto err3;

		/* Initialize children to NULL to simplify error path. */
		for (i = 0; i <= N->nkeys; i++)
			N->v.children[i] = NULL;

		/* Parse children. */
		for (i = 0; i <= N->nkeys; i++) {
			/* Create child node. */
			if (buflen < SERIALIZE_PERCHILD)
				goto err4;
			if ((N->v.children[i] = node_alloc(be64dec(&p[0]),
			    be64dec(&p[8]), be32dec(&p[16]))) == NULL)
				goto err4;
			N->v.children[i]->p_shadow =
			    N->v.children[i]->p_dirty = N;
			p += SERIALIZE_PERCHILD;
			buflen -= SERIALIZE_PERCHILD;
		}

		/* Make sure that the rest of the page is zeros. */
		while (buflen) {
			if (*p != 0)
				goto err4;
			p++; buflen--;
		}
	}

	/* Success! */
	return (0);

	/*
	 * PARENT parsing error handling path.
	 */
err4:
	for (i = 0; i <= N->nkeys; i++)
		node_free(N->v.children[i]);
	free(N->v.children);
	N->v.children = NULL;

err3:
	free(N->u.keys);
	N->u.keys = NULL;
	goto err1;

	/*
	 * LEAF parsing error handling path.
	 */
err2:
	free(N->u.pairs);
	N->u.pairs = NULL;

	/*
	 * LEAF+PARENT merged error handling path.
	 */
err1:
	free(N->pagebuf);
	N->pagebuf = NULL;
	if (errno != 0)
		warnp("Error parsing page");
	else
		warn0("Invalid page read");
err0:
	/* Failure! */
	return (-1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
callq 0x20a0
movl $0x0, (%rax)
movq -0x10(%rbp), %rax
movb 0x1c(%rax), %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x3, %eax
jne 0xf072
jmp 0xf091
leaq 0x10ab9(%rip), %rdi     # 0x1fb32
leaq 0x109ec(%rip), %rsi     # 0x1fa6c
movl $0xc9, %edx
leaq 0x10ac0(%rip), %rcx     # 0x1fb4c
callq 0x21d0
movq -0x10(%rbp), %rax
movb 0x1c(%rax), %al
shrb $0x2, %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0xf0a7
jmp 0xf0c6
leaq 0x104be(%rip), %rdi     # 0x1f56c
leaq 0x109b7(%rip), %rsi     # 0x1fa6c
movl $0xca, %edx
leaq 0x10a8b(%rip), %rcx     # 0x1fb4c
callq 0x21d0
movq -0x20(%rbp), %rdi
callq 0x22a0
movq -0x10(%rbp), %rcx
movq %rax, 0x50(%rcx)
cmpq $0x0, %rax
jne 0xf0e2
jmp 0xf831
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x2280
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0x28(%rbp)
cmpq $0x6, -0x20(%rbp)
jae 0xf10f
jmp 0xf7b6
movq -0x28(%rbp), %rdi
leaq 0x10b0e(%rip), %rsi     # 0x1fc28
movl $0x6, %edx
callq 0x2240
cmpl $0x0, %eax
je 0xf12e
jmp 0xf7b6
movq -0x28(%rbp), %rax
addq $0x6, %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
subq $0x6, %rax
movq %rax, -0x20(%rbp)
cmpq $0x2, -0x20(%rbp)
jae 0xf152
jmp 0xf7b6
movq -0x28(%rbp), %rdi
callq 0xf850
movzwl %ax, %eax
movl %eax, %ecx
movq -0x10(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x28(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
subq $0x2, %rax
movq %rax, -0x20(%rbp)
cmpq $0x1, -0x20(%rbp)
jae 0xf18c
jmp 0xf7b6
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0xf1af
movq -0x10(%rbp), %rax
movb 0x1c(%rax), %cl
andb $-0x11, %cl
orb $0x10, %cl
movb %cl, 0x1c(%rax)
jmp 0xf1bf
movq -0x10(%rbp), %rax
movb 0x1c(%rax), %cl
andb $-0x11, %cl
orb $0x0, %cl
movb %cl, 0x1c(%rax)
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
andl $0x7f, %eax
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x1d(%rax)
movq -0x10(%rbp), %rax
cmpb $0x0, 0x1d(%rax)
je 0xf1ee
movq -0x10(%rbp), %rax
movb 0x1c(%rax), %cl
andb $-0x4, %cl
orb $0x0, %cl
movb %cl, 0x1c(%rax)
jmp 0xf1fe
movq -0x10(%rbp), %rax
movb 0x1c(%rax), %cl
andb $-0x4, %cl
orb $0x1, %cl
movb %cl, 0x1c(%rax)
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
subq $0x1, %rax
movq %rax, -0x20(%rbp)
movq -0x28(%rbp), %rax
movb (%rax), %cl
movq -0x10(%rbp), %rax
movb %cl, 0x1e(%rax)
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
subq $0x1, %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movb 0x1c(%rax), %al
shrb $0x4, %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0xf267
movq -0x28(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
subq $0x8, %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movb 0x1c(%rax), %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0xf4cb
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rdi
movl $0x10, %esi
callq 0xf880
movq -0x10(%rbp), %rcx
movq %rax, 0x40(%rcx)
cmpq $0x0, %rax
jne 0xf2ac
movq -0x10(%rbp), %rax
cmpq $0x0, 0x38(%rax)
jbe 0xf2ac
jmp 0xf7b6
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x38(%rcx), %rax
jae 0xf377
cmpq $0x0, -0x20(%rbp)
jne 0xf2d2
jmp 0xf79d
movq -0x28(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x30(%rbp), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x40(%rcx), %rcx
movq -0x30(%rbp), %rdx
shlq $0x4, %rdx
addq %rdx, %rcx
movq (%rcx), %rcx
movzbl (%rcx), %ecx
addq $0x1, %rcx
cmpq %rcx, %rax
jae 0xf317
jmp 0xf79d
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
movzbl (%rax), %eax
addq $0x1, %rax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
movzbl (%rax), %eax
movl %eax, %ecx
addq $0x1, %rcx
movq -0x20(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0xf2b4
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x38(%rcx), %rax
jae 0xf446
cmpq $0x0, -0x20(%rbp)
jne 0xf39d
jmp 0xf79d
movq -0x28(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x30(%rbp), %rdx
shlq $0x4, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x40(%rcx), %rcx
movq -0x30(%rbp), %rdx
shlq $0x4, %rdx
addq %rdx, %rcx
movq 0x8(%rcx), %rcx
movzbl (%rcx), %ecx
addq $0x1, %rcx
cmpq %rcx, %rax
jae 0xf3e4
jmp 0xf79d
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movzbl (%rax), %eax
addq $0x1, %rax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movzbl (%rax), %eax
movl %eax, %ecx
addq $0x1, %rcx
movq -0x20(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0xf37f
movq -0x10(%rbp), %rax
cmpq $0x0, 0x38(%rax)
jbe 0xf48a
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x38(%rcx), %rcx
subq $0x1, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rsi
callq 0x18730
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x1f(%rax)
jmp 0xf492
movq -0x10(%rbp), %rax
movb $-0x1, 0x1f(%rax)
jmp 0xf494
cmpq $0x0, -0x20(%rbp)
je 0xf4c6
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
je 0xf4ac
jmp 0xf79d
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0xf494
jmp 0xf724
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rdi
movl $0x8, %esi
callq 0xf880
movq -0x10(%rbp), %rcx
movq %rax, 0x40(%rcx)
cmpq $0x0, %rax
jne 0xf4fb
movq -0x10(%rbp), %rax
cmpq $0x0, 0x38(%rax)
jbe 0xf4fb
jmp 0xf7b6
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x38(%rcx), %rax
jae 0xf5ae
cmpq $0x0, -0x20(%rbp)
jne 0xf521
jmp 0xf782
movq -0x28(%rbp), %rdx
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x30(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x20(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x40(%rcx), %rcx
movq -0x30(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movzbl (%rcx), %ecx
addq $0x1, %rcx
cmpq %rcx, %rax
jae 0xf55a
jmp 0xf782
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movzbl (%rax), %eax
addq $0x1, %rax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movzbl (%rax), %eax
movl %eax, %ecx
addq $0x1, %rcx
movq -0x20(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0xf503
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rdi
addq $0x1, %rdi
movl $0x8, %esi
callq 0xf880
movq -0x10(%rbp), %rcx
movq %rax, 0x48(%rcx)
cmpq $0x0, %rax
jne 0xf5e9
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
addq $0x1, %rax
cmpq $0x0, %rax
jbe 0xf5e9
jmp 0xf782
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x38(%rcx), %rax
ja 0xf621
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x30(%rbp), %rcx
movq $0x0, (%rax,%rcx,8)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0xf5f1
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x38(%rcx), %rax
ja 0xf6f1
cmpq $0x14, -0x20(%rbp)
jae 0xf647
jmp 0xf730
movq -0x28(%rbp), %rdi
callq 0xf920
movq %rax, -0x40(%rbp)
movq -0x28(%rbp), %rdi
addq $0x8, %rdi
callq 0xf920
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rdi
addq $0x10, %rdi
callq 0xf9b0
movq -0x40(%rbp), %rdi
movq -0x38(%rbp), %rsi
movl %eax, %edx
callq 0xfa70
movq -0x10(%rbp), %rcx
movq 0x48(%rcx), %rcx
movq -0x30(%rbp), %rdx
movq %rax, (%rcx,%rdx,8)
cmpq $0x0, %rax
jne 0xf69c
jmp 0xf730
movq -0x10(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x30(%rbp), %rdx
movq (%rax,%rdx,8), %rax
movq %rcx, 0x28(%rax)
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x30(%rbp), %rdx
movq (%rax,%rdx,8), %rax
movq %rcx, 0x20(%rax)
movq -0x28(%rbp), %rax
addq $0x14, %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
subq $0x14, %rax
movq %rax, -0x20(%rbp)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0xf629
jmp 0xf6f3
cmpq $0x0, -0x20(%rbp)
je 0xf722
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
je 0xf708
jmp 0xf730
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0xf6f3
jmp 0xf724
movl $0x0, -0x4(%rbp)
jmp 0xf838
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x38(%rcx), %rax
ja 0xf769
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x30(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xfb50
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0xf738
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rdi
callq 0x2040
movq -0x10(%rbp), %rax
movq $0x0, 0x48(%rax)
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rdi
callq 0x2040
movq -0x10(%rbp), %rax
movq $0x0, 0x40(%rax)
jmp 0xf7b6
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rdi
callq 0x2040
movq -0x10(%rbp), %rax
movq $0x0, 0x40(%rax)
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rdi
callq 0x2040
movq -0x10(%rbp), %rax
movq $0x0, 0x50(%rax)
callq 0x20a0
cmpl $0x0, (%rax)
je 0xf812
jmp 0xf7db
callq 0x20a0
cmpl $0x0, (%rax)
je 0xf800
leaq 0x10398(%rip), %rdi     # 0x1fb84
movb $0x0, %al
callq 0x180a0
callq 0x20a0
movl $0x0, (%rax)
jmp 0xf80e
leaq 0x1037d(%rip), %rdi     # 0x1fb84
movb $0x0, %al
callq 0x182f0
jmp 0xf810
jmp 0xf82f
jmp 0xf814
leaq 0x1037c(%rip), %rdi     # 0x1fb97
movb $0x0, %al
callq 0x182f0
callq 0x20a0
movl $0x0, (%rax)
jmp 0xf82f
jmp 0xf831
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)