// File: /workspace/github_c_makefile_star2_O2/jsummers[P]deark/modules/dms.c
// Function: mediumlz77_codec_addbuf
static void mediumlz77_codec_addbuf(struct de_dfilter_ctx *dfctx,
	const u8 *buf, i64 buf_len)
{
	struct medium_ctx *mctx = (struct medium_ctx *)dfctx->codec_private;
	struct medium_state_machine *mdst = &mctx->mdst;
	i64 bufpos = 0;
	UI n;
	UI offset_rel;
	UI length;

	if(dfctx->finished_flag || mctx->errflag) {
		goto done;
	}

	while(1) {
		if(medium_have_enough_output(mctx)) {
			dfctx->finished_flag = 1;
			goto done;
		}

		// Top off the bitbuf, if possible. 32 is an arbitrary number that's
		// large enough for this format.
		while(bufpos<buf_len && mctx->bbll.nbits_in_bitbuf<32) {
			de_bitbuf_lowlevel_add_byte(&mctx->bbll, buf[bufpos++]);
		}

		if(mdst->state==MEDLZST_WAITING_FOR_OCODE1) goto read_ocode1;
		if(mdst->state==MEDLZST_WAITING_FOR_OCODE2) goto read_ocode2;

		// Make sure we have enough source data to read the flag bit,
		// plus either the literal byte or the first_code.
		if(mctx->bbll.nbits_in_bitbuf < 9) goto done;

		n = (UI)de_bitbuf_lowlevel_get_bits(&mctx->bbll, 1);

		if(n) { // literal byte
			u8 b;

			b = (u8)de_bitbuf_lowlevel_get_bits(&mctx->bbll, 8);
			de_lz77buffer_add_literal_byte(mctx->ringbuf, (u8)b);
			continue;
		}

		// TODO: This seems overly complicated. Is there a simpler way to
		// implement this?

		mdst->first_code = (UI)de_bitbuf_lowlevel_get_bits(&mctx->bbll, 8);
		fmtutil_get_lzhuf_d_code_and_len(mdst->first_code, &mdst->d_code1, &mdst->d_len1);

	read_ocode1:
		mdst->ocode1_nbits = mdst->d_len1;
		if(mctx->bbll.nbits_in_bitbuf < mdst->ocode1_nbits) {
			mdst->state = MEDLZST_WAITING_FOR_OCODE1;
			goto done;
		}
		mdst->ocode1 = (UI)de_bitbuf_lowlevel_get_bits(&mctx->bbll, mdst->ocode1_nbits);

		mdst->tmp_code = ((mdst->first_code << mdst->ocode1_nbits) | mdst->ocode1) & 0xff;
		fmtutil_get_lzhuf_d_code_and_len(mdst->tmp_code, &mdst->d_code2, &mdst->d_len2);

	read_ocode2:
		mdst->ocode2_nbits = mdst->d_len2;
		if(mctx->bbll.nbits_in_bitbuf < mdst->ocode2_nbits) {
			mdst->state = MEDLZST_WAITING_FOR_OCODE2;
			goto done;
		}
		mdst->ocode2 = (UI)de_bitbuf_lowlevel_get_bits(&mctx->bbll, mdst->ocode2_nbits);

		offset_rel = (mdst->d_code2 << 8) | (((mdst->tmp_code << mdst->ocode2_nbits) | mdst->ocode2) & 0xff);
		length = mdst->d_code1 + 3;
		de_lz77buffer_copy_from_hist(mctx->ringbuf, mctx->ringbuf->curpos - 1 - offset_rel, length);
		mdst->state = MEDLZST_NEUTRAL;
	}

done:
	if(!dfctx->finished_flag && !mctx->errflag) {
		if(bufpos<buf_len) {
			// It shouldn't be possible to get here. If we do, it means some input
			// bytes will be lost.
			de_dfilter_set_generic_error(dfctx->c, mctx->dres, mctx->modname);
			mctx->errflag = 1;
		}
	}
}

// Assembly:
cmpb $0x0, 0x20(%rdi)
je 0x47818
retq
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdx, %r15
movq 0x28(%rdi), %rbx
cmpl $0x0, 0x20(%rbx)
je 0x4783b
xorl %r14d, %r14d
jmp 0x47996
movq %rsi, %r12
movq %rdi, (%rsp)
leaq 0x38(%rbx), %r13
leaq 0x64(%rbx), %rax
movq %rax, 0x10(%rsp)
leaq 0x68(%rbx), %rax
movq %rax, 0x8(%rsp)
leaq 0x6c(%rbx), %rax
movq %rax, 0x20(%rsp)
leaq 0x70(%rbx), %rax
movq %rax, 0x18(%rsp)
xorl %r14d, %r14d
pushq $0x1
popq %rbp
movq %rbx, %rdi
callq 0x477f6
testl %eax, %eax
jne 0x47982
cmpq %r15, %r14
jge 0x4789d
cmpl $0x1f, 0x3c(%rbx)
ja 0x4789d
movzbl (%r12,%r14), %esi
incq %r14
movq %r13, %rdi
callq 0xe69c4
jmp 0x47880
movl 0x48(%rbx), %eax
cmpl $0x1, %eax
je 0x478eb
cmpl $0x2, %eax
je 0x47926
cmpl $0x9, 0x3c(%rbx)
jb 0x47992
movq %r13, %rdi
movl %ebp, %esi
callq 0xe69f9
movq %rax, %rbp
movq %r13, %rdi
pushq $0x8
popq %rsi
callq 0xe69f9
testl %ebp, %ebp
jne 0x47971
movl %eax, 0x4c(%rbx)
movl %eax, %edi
movq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdx
callq 0xf9ee0
pushq $0x1
popq %rbp
movl 0x3c(%rbx), %eax
movl 0x68(%rbx), %esi
movl %esi, 0x50(%rbx)
cmpl %esi, %eax
jb 0x4798f
movq %r13, %rdi
callq 0xe69f9
movl %eax, 0x54(%rbx)
movl 0x4c(%rbx), %edx
movb 0x50(%rbx), %cl
shll %cl, %edx
orl %eax, %edx
movzbl %dl, %edi
movl %edi, 0x60(%rbx)
movq 0x20(%rsp), %rsi
movq 0x18(%rsp), %rdx
callq 0xf9ee0
movl 0x3c(%rbx), %eax
movl 0x70(%rbx), %esi
movl %esi, 0x58(%rbx)
cmpl %esi, %eax
jb 0x4798c
movq %r13, %rdi
callq 0xe69f9
movl %eax, 0x5c(%rbx)
movl 0x6c(%rbx), %edx
shll $0x8, %edx
movl 0x60(%rbx), %esi
movb 0x58(%rbx), %cl
shll %cl, %esi
orl %eax, %esi
movzbl %sil, %esi
orl %edx, %esi
movl 0x64(%rbx), %edx
addl $0x3, %edx
movq 0x30(%rbx), %rdi
notl %esi
addl 0x10(%rdi), %esi
callq 0xef363
andl $0x0, 0x48(%rbx)
jmp 0x47870
movq 0x30(%rbx), %rdi
movzbl %al, %esi
callq 0xef336
jmp 0x4786d
movq (%rsp), %rax
movb $0x1, 0x20(%rax)
jmp 0x479be
pushq $0x2
popq %rbp
movl %ebp, 0x48(%rbx)
movq (%rsp), %rdi
cmpb $0x0, 0x20(%rdi)
jne 0x479be
cmpq %r15, %r14
jge 0x479be
cmpl $0x0, 0x20(%rbx)
jne 0x479be
movq (%rdi), %rdi
movq 0x8(%rbx), %rdx
movq 0x18(%rbx), %rsi
callq 0xee91c
movl $0x1, 0x20(%rbx)
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq