// File: /workspace/github_c_makefile_star2_O3/jsummers[P]deark/modules/zip.c
// Function: zip_wcd_run
static void zip_wcd_run(deark *c, struct zip_wcd_ctx *wcdctx)
{
	i64 pos;
	u32 expected_sig;
	u8 unexpected_eof_flag = 0;

	pos = wcdctx->inf_startpos;
	wcdctx->endpos_of_last_completed_entry = pos;
	expected_sig = wcdctx->is_resof?CODE_PK14:CODE_PK12;

	while(1) {
		u32 sig;
		i64 len_avail;

		if(wcdctx->stop_flag || wcdctx->errflag) goto done;
		if(wcdctx->num_entries_completed >= wcdctx->max_entries) goto done;

		wcdctx->entry_pos = pos;
		len_avail = wcdctx->inf_endpos - wcdctx->entry_pos;
		if(len_avail < 46) {
			// Not enough space even for the invariant part of the entry
			if(!wcdctx->multisegment_mode) {
				wcdctx->errflag = 1;
				wcdctx->need_errmsg = 1;
				unexpected_eof_flag = 1;
			}
			goto done;
		}
		sig=(u32)dbuf_getu32be(wcdctx->inf, pos);
		if(sig==0 && wcdctx->multisegment_mode) {
			// I haven't seen this, but I think it makes sense to tolerate
			// zero-padding.
			goto done;
		}
		if(sig!=expected_sig) {
			wcdctx->errflag = 1;
			if(wcdctx->report_errors) {
				de_err(c, "Central dir file header not found at %"I64_FMT,
					wcdctx->entry_pos);
			}
			else {
				wcdctx->need_errmsg = 1;
			}
			goto done;
		}
		wcdctx->fn_len = dbuf_getu16le(wcdctx->inf, pos+28);
		wcdctx->extra_len = dbuf_getu16le(wcdctx->inf, pos+30);
		wcdctx->comment_len = dbuf_getu16le(wcdctx->inf, pos+32);
		wcdctx->entry_size = 46 + wcdctx->fn_len + wcdctx->extra_len +
			wcdctx->comment_len;
		if(wcdctx->entry_size > len_avail) {
			if(!wcdctx->multisegment_mode) {
				wcdctx->errflag = 1;
				wcdctx->need_errmsg = 1;
				unexpected_eof_flag = 1;
			}
			goto done;
		}
		if(wcdctx->cbfn) {
			wcdctx->cbfn(c, wcdctx);
			// If callback set stop_flag, we assume it did *not* process
			// this item.
			if(wcdctx->stop_flag || wcdctx->errflag) goto done;
		}

		pos += wcdctx->entry_size;
		wcdctx->num_entries_completed++;
		wcdctx->endpos_of_last_completed_entry = pos;
	}

done:
	if(unexpected_eof_flag && wcdctx->report_errors) {
		de_err(c, "Central dir file header exceeds its bounds");
		wcdctx->need_errmsg = 0;
	}
	wcdctx->entry_pos = 0;
	wcdctx->entry_size = 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rsi, %rbx
movq 0x20(%rsi), %r15
movq %r15, 0x48(%rsi)
xorl %eax, %eax
cmpb $0x0, 0x16(%rsi)
setne %cl
cmpb $0x0, 0x38(%rsi)
jne 0xdcd3d
cmpb $0x0, 0x39(%rbx)
je 0xdcd4d
xorps %xmm0, %xmm0
movups %xmm0, 0x50(%rbx)
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq %rdi, %r14
movb %cl, %al
leal 0x504b0102(,%rax,2), %ebp
movq 0x40(%rbx), %rax
cmpq 0x30(%rbx), %rax
jge 0xdcd3d
movq %r15, 0x50(%rbx)
movq 0x28(%rbx), %r12
subq %r15, %r12
cmpq $0x2d, %r12
jle 0xdce37
movq 0x18(%rbx), %rdi
movq %r15, %rsi
callq 0xeed0d
testl %eax, %eax
jne 0xdcd8e
cmpb $0x0, 0x15(%rbx)
jne 0xdcd3d
cmpl %eax, %ebp
jne 0xdce6b
movq 0x18(%rbx), %rdi
leaq 0x1c(%r15), %rsi
callq 0xeebc8
movq %rax, 0x60(%rbx)
movq 0x18(%rbx), %rdi
leaq 0x1e(%r15), %rsi
callq 0xeebc8
movq %rax, 0x68(%rbx)
movq 0x18(%rbx), %rdi
leaq 0x20(%r15), %rsi
callq 0xeebc8
movq %rax, 0x70(%rbx)
addq 0x60(%rbx), %rax
movq 0x68(%rbx), %rcx
addq %rcx, %rax
addq $0x2e, %rax
movq %rax, 0x58(%rbx)
cmpq %r12, %rax
jg 0xdce37
movq (%rbx), %rcx
testq %rcx, %rcx
je 0xdce13
movq %r14, %rdi
movq %rbx, %rsi
callq *%rcx
cmpb $0x0, 0x38(%rbx)
jne 0xdcd3d
cmpb $0x0, 0x39(%rbx)
jne 0xdcd3d
addq 0x58(%rbx), %r15
incq 0x40(%rbx)
movq %r15, 0x48(%rbx)
jmp 0xdce28
incq 0x40(%rbx)
addq %rax, %r15
cmpb $0x0, 0x38(%rbx)
movq %r15, 0x48(%rbx)
jne 0xdcd3d
cmpb $0x0, 0x39(%rbx)
je 0xdcd59
jmp 0xdcd3d
cmpb $0x0, 0x15(%rbx)
jne 0xdcd3d
movw $0x101, 0x39(%rbx)      # imm = 0x101
cmpb $0x0, 0x14(%rbx)
je 0xdcd3d
leaq 0x66695(%rip), %rsi     # 0x1434ed
movq %r14, %rdi
xorl %eax, %eax
callq 0xe9295
movb $0x0, 0x3a(%rbx)
jmp 0xdcd3d
movb $0x1, 0x39(%rbx)
cmpb $0x0, 0x14(%rbx)
je 0xdce8f
movq 0x50(%rbx), %rdx
leaq 0x66644(%rip), %rsi     # 0x1434c4
movq %r14, %rdi
xorl %eax, %eax
callq 0xe9295
jmp 0xdcd3d
movb $0x1, 0x3a(%rbx)
jmp 0xdcd3d