// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/src/fmtutil-huffman.c
// Function: fmtutil_huffman_add_code
int fmtutil_huffman_add_code(deark *c, struct fmtutil_huffman_codebook *bk,
	u64 code, UI code_nbits, fmtutil_huffman_valtype val)
{
	UI k;
	NODE_REF_TYPE curr_noderef = 0; // Note that this may temporarily point to an unallocated node
	int retval = 0;

	if(code_nbits>FMTUTIL_HUFFMAN_MAX_CODE_LENGTH) goto done;

	if(code_nbits<1) {
		bk->value_of_null_code = val;
		bk->has_null_code = 1;
		retval = 1;
		goto done;
	}
	bk->has_null_code = 0;

	if(code_nbits > bk->max_bits) {
		bk->max_bits = code_nbits;
	}

	// Iterate through the bits, high bit first.
	for(k=0; k<code_nbits; k++) {
		UI child_idx; // 0 or 1

		// Make sure the current node exists
		if(curr_noderef >= bk->nodes_alloc) {
			if(!huffman_ensure_alloc(c, bk, curr_noderef+1)) goto done;
		}
		// Claim the current node, if necessary
		if(curr_noderef >= bk->next_avail_node) {
			bk->next_avail_node = curr_noderef+1;
			bk->nodes[curr_noderef].depth = (u8)k;
		}

		child_idx = (code>>(code_nbits-1-k))&0x1;

		if(k==code_nbits-1) {
			// Reached the "leaf" node. Set the value for this child_idx.
			huffman_setchildstatus(bk, curr_noderef, child_idx, CHILDSTATUS_VALUE);
			bk->nodes[curr_noderef].child[child_idx].hnvd.value = val;
		}
		else {
			// Not at the leaf node yet.
			if(bk->nodes[curr_noderef].child_status[child_idx]==CHILDSTATUS_POINTER) {
				// It's already a pointer.
				curr_noderef = bk->nodes[curr_noderef].child[child_idx].hnpd.noderef;
			}
			else {
				NODE_REF_TYPE next_noderef;

				// It's not a pointer -- make it one.
				if(bk->next_avail_node >= bk->max_nodes) goto done;
				next_noderef = bk->next_avail_node;
				huffman_setchildstatus(bk, curr_noderef, child_idx, CHILDSTATUS_POINTER);
				bk->nodes[curr_noderef].child[child_idx].hnpd.noderef = next_noderef;
				curr_noderef = next_noderef;
			}
		}
	}

	retval = 1;

done:
	return retval;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
movl $0x0, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
cmpl $0x30, -0x1c(%rbp)
jbe 0x187754
jmp 0x18790f
cmpl $0x1, -0x1c(%rbp)
jae 0x187778
movl -0x20(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x1c(%rax)
movq -0x10(%rbp), %rax
movb $0x1, 0x18(%rax)
movl $0x1, -0x2c(%rbp)
jmp 0x18790f
movq -0x10(%rbp), %rax
movb $0x0, 0x18(%rax)
movl -0x1c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x28(%rcx), %eax
jbe 0x187796
movl -0x1c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x28(%rax)
movl $0x0, -0x24(%rbp)
movl -0x24(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jae 0x187908
movl -0x28(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0xc(%rcx), %eax
jb 0x1877d4
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x28(%rbp), %edx
addl $0x1, %edx
callq 0x187920
cmpl $0x0, %eax
jne 0x1877d2
jmp 0x18790f
jmp 0x1877d4
movl -0x28(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jb 0x187807
movl -0x28(%rbp), %ecx
addl $0x1, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
movl -0x24(%rbp), %eax
movb %al, %cl
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x28(%rbp), %edx
imulq $0xc, %rdx, %rdx
addq %rdx, %rax
movb %cl, 0x2(%rax)
movq -0x18(%rbp), %rax
movl -0x1c(%rbp), %ecx
subl $0x1, %ecx
subl -0x24(%rbp), %ecx
movl %ecx, %ecx
shrq %cl, %rax
andq $0x1, %rax
movl %eax, -0x30(%rbp)
movl -0x24(%rbp), %eax
movl -0x1c(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x187865
movq -0x10(%rbp), %rdi
movl -0x28(%rbp), %esi
movl -0x30(%rbp), %eax
movl $0x2, %ecx
movzbl %al, %edx
callq 0x187a00
movl -0x20(%rbp), %edx
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x28(%rbp), %ecx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl -0x30(%rbp), %ecx
movl %edx, 0x4(%rax,%rcx,4)
jmp 0x1878f8
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x28(%rbp), %ecx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl -0x30(%rbp), %ecx
movzbl (%rax,%rcx), %eax
cmpl $0x1, %eax
jne 0x1878a1
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x28(%rbp), %ecx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl -0x30(%rbp), %ecx
movl 0x4(%rax,%rcx,4), %eax
movl %eax, -0x28(%rbp)
jmp 0x1878f6
movq -0x10(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x10(%rbp), %rcx
cmpq (%rcx), %rax
jl 0x1878b3
jmp 0x18790f
movq -0x10(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x34(%rbp)
movq -0x10(%rbp), %rdi
movl -0x28(%rbp), %esi
movl -0x30(%rbp), %eax
movl $0x1, %ecx
movzbl %al, %edx
callq 0x187a00
movl -0x34(%rbp), %edx
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x28(%rbp), %ecx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movl -0x30(%rbp), %ecx
movl %edx, 0x4(%rax,%rcx,4)
movl -0x34(%rbp), %eax
movl %eax, -0x28(%rbp)
jmp 0x1878f8
jmp 0x1878fa
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x18779d
movl $0x1, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax,%rax)