// File: /workspace/github_c_makefile_star2_O3/jsummers[P]deark/src/deark-zip.c
// Function: zipw_add_memberfile
static void zipw_add_memberfile(deark *c, struct zipw_ctx *zzz, struct zipw_md *md,
	dbuf *f, const char *name, unsigned int level_and_flags)
{
	i64 ldir_offset;
	i64 fnlen;
	u32 crc;
	int try_compression = 0;
	int using_compression = 0;
	dbuf *cmpr_data = NULL;
	i64 cmpr_len;
	unsigned int bit_flags = 0;
	unsigned int ext_attributes;
	unsigned int ver_needed;

	// Just a sanity check; we'll run into some other limit long before this
	if(zzz->membercount >= 0x7fffffff) {
		de_err(c, "Maximum number of ZIP member files exceeded");
		goto done;
	}

	de_crcobj_reset(zzz->crc32o);
	de_crcobj_addslice(zzz->crc32o, f, 0, f->len);
	crc = de_crcobj_getval(zzz->crc32o);

	ldir_offset = zzz->outf->len;
	if(ldir_offset > 0xffffffffLL) {
		de_err(c, "Maximum ZIP file size exceeded");
		goto done;
	}
	if(f->len > 0xffffffffLL) {
		de_err(c, "Maximum ZIP member file size exceeded");
		goto done;
	}
	cmpr_len = f->len; // default

	if(f->len>5 && !md->is_directory) {
		try_compression = 1;
	}

	if(try_compression) {
		unsigned int level;

		cmpr_data = dbuf_create_membuf(c, 0, 0);

		if ((int)level_and_flags < 0)
			level_and_flags = MZ_DEFAULT_LEVEL;
		level = level_and_flags & 0xF;

		zipw_deflate(c, zzz, f, cmpr_data, level);

		if(cmpr_data->len < f->len) {
			using_compression = 1;
			cmpr_len = cmpr_data->len;

			// This is the logic used by Info-Zip
			if(level<=2) bit_flags |= 4;
			else if(level>=8) bit_flags |= 2;
		}
		else { // No savings - Discard compressed data
			dbuf_close(cmpr_data);
			cmpr_data = NULL;
		}
	}

	bit_flags |= 0x0800; // Use UTF-8 filenames

	dbuf_writeu32le(zzz->cdir, CODE_PK12);
	dbuf_writeu32le(zzz->outf, CODE_PK34);
	dbuf_writeu16le(zzz->cdir, (md->is_volume_label ?
		ZIPENC_VOLLABEL_VER_MADE_BY : ZIPENC_VER_MADE_BY));

	if(using_compression) ver_needed = 20;
	else if(md->is_directory) ver_needed = 20;
	else if(md->is_volume_label) ver_needed = 11;
	else ver_needed = 10;

	dbuf_writeu16le(zzz->cdir, ver_needed);
	dbuf_writeu16le(zzz->outf, ver_needed);

	dbuf_writeu16le(zzz->cdir, bit_flags);
	dbuf_writeu16le(zzz->outf, bit_flags);

	dbuf_writeu16le(zzz->cdir, using_compression?8:0); // cmpr method
	dbuf_writeu16le(zzz->outf, using_compression?8:0);

	dbuf_writeu16le(zzz->cdir, md->modtime_dostime);
	dbuf_writeu16le(zzz->outf, md->modtime_dostime);
	dbuf_writeu16le(zzz->cdir, md->modtime_dosdate);
	dbuf_writeu16le(zzz->outf, md->modtime_dosdate);

	dbuf_writeu32le(zzz->cdir, crc); // crc
	dbuf_writeu32le(zzz->outf, crc);

	dbuf_writeu32le(zzz->cdir, cmpr_len); // cmpr size
	dbuf_writeu32le(zzz->outf, cmpr_len);
	dbuf_writeu32le(zzz->cdir, f->len); // uncmpr size
	dbuf_writeu32le(zzz->outf, f->len);

	fnlen = de_strlen(name);
	dbuf_writeu16le(zzz->cdir, fnlen);
	dbuf_writeu16le(zzz->outf, fnlen);

	dbuf_writeu16le(zzz->cdir, md->efcentral->len); // eflen
	dbuf_writeu16le(zzz->outf, md->eflocal->len);

	dbuf_writeu16le(zzz->cdir, 0); // file comment len
	dbuf_writeu16le(zzz->cdir, 0); // disk number start

	dbuf_writeu16le(zzz->cdir, 0); // int attrib

	// Set the Unix (etc.) file attributes to "-rw-r--r--" or
	// "-rwxr-xr-x", etc.
	if(md->is_directory)
		ext_attributes = (0040755U << 16) | 0x10;
	else if(md->is_volume_label)
		ext_attributes = 0x28;
	else if(md->is_executable)
		ext_attributes = (0100755U << 16);
	else
		ext_attributes = (0100644U << 16);

	dbuf_writeu32le(zzz->cdir, (i64)ext_attributes); // ext attrib

	dbuf_writeu32le(zzz->cdir, ldir_offset);

	dbuf_write(zzz->cdir, (const u8*)name, fnlen);
	dbuf_write(zzz->outf, (const u8*)name, fnlen);

	dbuf_copy(md->efcentral, 0, md->efcentral->len, zzz->cdir);
	dbuf_copy(md->eflocal, 0, md->eflocal->len, zzz->outf);

	if(using_compression) {
		if(cmpr_data) {
			dbuf_copy(cmpr_data, 0, cmpr_data->len, zzz->outf);
		}
	}
	else {
		dbuf_copy(f, 0, f->len, zzz->outf);
	}

	zzz->membercount++;

done:
	if(cmpr_data) dbuf_close(cmpr_data);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdi, %rbp
cmpq $0x7fffffff, 0x18(%rsi) # imm = 0x7FFFFFFF
jl 0xed4e8
leaq 0x5baf3(%rip), %rsi     # 0x148fd9
jmp 0xed552
movl %r9d, %r12d
movq %r8, %r13
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, %rbx
movq 0x30(%rsi), %rdi
callq 0xeb7fe
movq 0x30(%rbx), %rdi
movq 0x18(%r14), %rcx
movq %r14, %rsi
xorl %edx, %edx
callq 0xeb944
movq 0x30(%rbx), %rdi
callq 0xeb865
movl %eax, %edx
movq 0x20(%rbx), %rax
movq 0x18(%rax), %rcx
movabsq $0x100000000, %rax      # imm = 0x100000000
cmpq %rax, %rcx
jl 0xed53d
leaq 0x5baca(%rip), %rsi     # 0x149005
jmp 0xed552
movq %r13, 0x28(%rsp)
movq 0x18(%r14), %r13
cmpq %rax, %r13
jl 0xed56a
leaq 0x5bad2(%rip), %rsi     # 0x149024
movq %rbp, %rdi
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xe9295
movl $0x800, %eax            # imm = 0x800
movq %rax, 0x18(%rsp)
movb $0x1, %al
movl %eax, 0xc(%rsp)
cmpq $0x6, %r13
movq %rcx, 0x30(%rsp)
movl %edx, 0x24(%rsp)
jl 0xed651
cmpb $0x0, 0x59(%r15)
jne 0xed651
movq %rbp, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xf09c5
movq %rax, 0x10(%rsp)
movl %r12d, %eax
andl $0xf, %eax
testl %r12d, %r12d
movl $0x6, %edi
cmovnsl %eax, %edi
movl %edi, 0x20(%rsp)
movl $0xfffffff1, %esi       # imm = 0xFFFFFFF1
xorl %edx, %edx
callq 0x10ddd7
movq %rbp, %rdi
movq 0x10(%rsp), %rsi
movl %eax, %edx
callq 0x10dd3f
movq %rax, %r12
movq %r14, %rdi
callq 0xf148f
movq 0x18(%r14), %rdx
testq %rax, %rax
je 0xed604
movq %r12, %rdi
movq %rax, %rsi
movl $0x4, %ecx
callq 0x10dd9f
cmpl $0x1, %eax
jne 0xed60d
jmp 0xed61e
testq %rdx, %rdx
je 0xed918
leaq 0x5ba36(%rip), %rsi     # 0x14904a
movq %rbp, %rdi
xorl %eax, %eax
callq 0xe9295
movq %r12, %rdi
callq 0x10ddc6
movq 0x10(%rsp), %rdi
movq 0x18(%rdi), %rax
cmpq 0x18(%r14), %rax
jge 0xed64c
movl 0x20(%rsp), %edx
cmpl $0x3, %edx
jae 0xed8f3
movl $0x804, %ecx            # imm = 0x804
jmp 0xed903
callq 0xf052b
movq $0x0, 0x10(%rsp)
movq 0x28(%rbx), %rdi
movl $0x2014b50, %esi        # imm = 0x2014B50
callq 0xf1042
movq 0x20(%rbx), %rdi
movl $0x4034b50, %esi        # imm = 0x4034B50
callq 0xf1042
movq 0x28(%rbx), %rdi
cmpb $0x0, 0x5a(%r15)
movl $0x33f, %eax            # imm = 0x33F
movl $0x3f, %esi
cmoveq %rax, %rsi
callq 0xf0f95
movl $0x14, %ebp
movl $0x8, %r12d
cmpb $0x0, 0xc(%rsp)
je 0xed6bc
cmpb $0x0, 0x59(%r15)
jne 0xed6b9
cmpb $0x1, 0x5a(%r15)
movl $0xb, %ebp
sbbq $0x0, %rbp
xorl %r12d, %r12d
movq 0x28(%rbx), %rdi
movq %rbp, %rsi
callq 0xf0f95
movq 0x20(%rbx), %rdi
movq %rbp, %rsi
callq 0xf0f95
movq 0x28(%rbx), %rdi
movq 0x18(%rsp), %rbp
movq %rbp, %rsi
callq 0xf0f95
movq 0x20(%rbx), %rdi
movq %rbp, %rsi
callq 0xf0f95
movq 0x28(%rbx), %rdi
movq %r12, %rsi
callq 0xf0f95
movq 0x20(%rbx), %rdi
movq %r12, %rsi
callq 0xf0f95
movq 0x28(%rbx), %rdi
movl 0x3c(%r15), %esi
callq 0xf0f95
movq 0x20(%rbx), %rdi
movl 0x3c(%r15), %esi
callq 0xf0f95
movq 0x28(%rbx), %rdi
movl 0x38(%r15), %esi
callq 0xf0f95
movq 0x20(%rbx), %rdi
movl 0x38(%r15), %esi
callq 0xf0f95
movq 0x28(%rbx), %rdi
movl 0x24(%rsp), %r12d
movq %r12, %rsi
callq 0xf1042
movq 0x20(%rbx), %rdi
movq %r12, %rsi
callq 0xf1042
movq 0x28(%rbx), %rdi
movq %r13, %rsi
callq 0xf1042
movq 0x20(%rbx), %rdi
movq %r13, %rsi
callq 0xf1042
movq 0x28(%rbx), %rdi
movq 0x18(%r14), %rsi
callq 0xf1042
movq 0x20(%rbx), %rdi
movq 0x18(%r14), %rsi
callq 0xf1042
movq 0x28(%rsp), %rdi
callq 0x180e0
movq %rax, %r13
movq 0x28(%rbx), %rdi
movq %rax, %rsi
callq 0xf0f95
movq 0x20(%rbx), %rdi
movq %r13, %rsi
callq 0xf0f95
movq 0x28(%rbx), %rdi
movq 0x68(%r15), %rax
movq 0x18(%rax), %rsi
callq 0xf0f95
movq 0x20(%rbx), %rdi
movq 0x60(%r15), %rax
movq 0x18(%rax), %rsi
callq 0xf0f95
movq 0x28(%rbx), %rdi
xorl %esi, %esi
callq 0xf0f95
movq 0x28(%rbx), %rdi
xorl %esi, %esi
callq 0xf0f95
movq 0x28(%rbx), %rdi
xorl %esi, %esi
callq 0xf0f95
movl $0x41ed0010, %esi       # imm = 0x41ED0010
cmpb $0x0, 0x59(%r15)
jne 0xed821
movl $0x28, %esi
cmpb $0x0, 0x5a(%r15)
jne 0xed821
movl $0x81a40000, %eax       # imm = 0x81A40000
leaq 0x490000(%rax), %rsi
cmpb $0x0, 0x58(%r15)
cmoveq %rax, %rsi
movq 0x28(%rbx), %rdi
callq 0xf1042
movq 0x28(%rbx), %rdi
movq 0x30(%rsp), %rsi
callq 0xf1042
movq 0x28(%rbx), %rdi
movq 0x28(%rsp), %r12
movq %r12, %rsi
movq %r13, %rdx
callq 0xef547
movq 0x20(%rbx), %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0xef547
movq 0x68(%r15), %rdi
movq 0x18(%rdi), %rdx
movq 0x28(%rbx), %rcx
xorl %esi, %esi
callq 0xef481
movq 0x60(%r15), %rdi
movq 0x18(%rdi), %rdx
movq 0x20(%rbx), %rcx
xorl %esi, %esi
callq 0xef481
cmpb $0x0, 0xc(%rsp)
je 0xed8aa
movq 0x18(%r14), %rdx
movq 0x20(%rbx), %rcx
movq %r14, %rdi
xorl %esi, %esi
callq 0xef481
incq 0x18(%rbx)
movq 0x10(%rsp), %r14
testq %r14, %r14
jne 0xed8ca
jmp 0xed8e4
movq 0x10(%rsp), %r14
testq %r14, %r14
je 0xed8e0
movq 0x18(%r14), %rdx
movq 0x20(%rbx), %rcx
movq %r14, %rdi
xorl %esi, %esi
callq 0xef481
incq 0x18(%rbx)
movq %r14, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xf052b
incq 0x18(%rbx)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %ecx, %ecx
cmpl $0x8, %edx
setae %cl
leaq 0x800(,%rcx,2), %rcx
movq %rcx, 0x18(%rsp)
movl $0x0, 0xc(%rsp)
movq %rax, %r13
jmp 0xed65a
xorl %edx, %edx
jmp 0xed5ed