// File: /workspace/github_c_makefile_star2_O1/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, %r13
cmpq $0x7fffffff, 0x18(%rsi) # imm = 0x7FFFFFFF
jl 0xedb4d
leaq 0x5aef6(%rip), %rsi     # 0x148a41
jmp 0xedbb2
movl %r9d, %ebp
movq %r8, %r15
movq %rcx, %r14
movq %rdx, %r12
movq %rsi, %rbx
movq 0x30(%rsi), %rdi
callq 0xebdc3
movq 0x30(%rbx), %rdi
movq 0x18(%r14), %rcx
movq %r14, %rsi
xorl %edx, %edx
callq 0xebf09
movq 0x30(%rbx), %rdi
callq 0xebe2a
movl %eax, %edx
movq 0x20(%rbx), %rax
movq 0x18(%rax), %rcx
movabsq $0x100000000, %rax      # imm = 0x100000000
cmpq %rax, %rcx
jl 0xedba2
leaq 0x5aecd(%rip), %rsi     # 0x148a6d
jmp 0xedbb2
movq 0x18(%r14), %rsi
cmpq %rax, %rsi
jl 0xedbe9
leaq 0x5aeda(%rip), %rsi     # 0x148a8c
xorl %r15d, %r15d
movq %r13, %rdi
xorl %eax, %eax
callq 0xe9df7
testq %r15, %r15
je 0xedbda
movq %r15, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xf0b13
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x800, %eax            # imm = 0x800
movq %rax, 0x10(%rsp)
movb $0x1, %al
movl %eax, 0xc(%rsp)
cmpq $0x6, %rsi
movq %r15, 0x28(%rsp)
movq %rcx, 0x30(%rsp)
movl %edx, 0x24(%rsp)
movq %rsi, 0x18(%rsp)
jl 0xedcd1
cmpb $0x0, 0x59(%r12)
jne 0xedcd1
movq %r13, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xf0faf
movq %rax, %r15
movl %ebp, %eax
andl $0xf, %eax
testl %ebp, %ebp
movl $0x6, %edi
cmovnsl %eax, %edi
movl %edi, 0x20(%rsp)
movl $0xfffffff1, %esi       # imm = 0xFFFFFFF1
xorl %edx, %edx
callq 0x10defb
movq %r13, %rdi
movq %r15, %rsi
movl %eax, %edx
callq 0x10de63
movq %rax, %rbp
movq %r14, %rdi
callq 0xf1a8f
testq %rax, %rax
je 0xedc88
movq 0x18(%r14), %rdx
movq %rbp, %rdi
movq %rax, %rsi
movl $0x4, %ecx
callq 0x10dec3
cmpl $0x1, %eax
jne 0xedc8f
jmp 0xedca0
cmpq $0x0, 0x18(%r14)
je 0xedc6d
leaq 0x5ae1c(%rip), %rsi     # 0x148ab2
movq %r13, %rdi
xorl %eax, %eax
callq 0xe9df7
movq %rbp, %rdi
callq 0x10deea
movq 0x18(%r15), %rax
cmpq 0x18(%r14), %rax
jge 0xedcc9
movl 0x20(%rsp), %edx
cmpl $0x3, %edx
jae 0xedf42
movl $0x804, %ecx            # imm = 0x804
jmp 0xedf52
movq %r15, %rdi
callq 0xf0b13
xorl %r15d, %r15d
movq 0x28(%rbx), %rdi
movl $0x2014b50, %esi        # imm = 0x2014B50
callq 0xf1645
movq 0x20(%rbx), %rdi
movl $0x4034b50, %esi        # imm = 0x4034B50
callq 0xf1645
movq 0x28(%rbx), %rdi
cmpb $0x0, 0x5a(%r12)
movl $0x33f, %eax            # imm = 0x33F
movl $0x3f, %esi
cmoveq %rax, %rsi
callq 0xf1598
movl $0x14, %ebp
movl $0x8, %r13d
cmpb $0x0, 0xc(%rsp)
je 0xedd39
cmpb $0x0, 0x59(%r12)
jne 0xedd36
cmpb $0x1, 0x5a(%r12)
movl $0xb, %ebp
sbbq $0x0, %rbp
xorl %r13d, %r13d
movq 0x28(%rbx), %rdi
movq %rbp, %rsi
callq 0xf1598
movq 0x20(%rbx), %rdi
movq %rbp, %rsi
callq 0xf1598
movq 0x28(%rbx), %rdi
movq 0x10(%rsp), %rbp
movq %rbp, %rsi
callq 0xf1598
movq 0x20(%rbx), %rdi
movq %rbp, %rsi
callq 0xf1598
movq 0x28(%rbx), %rdi
movq %r13, %rsi
callq 0xf1598
movq 0x20(%rbx), %rdi
movq %r13, %rsi
callq 0xf1598
movq 0x28(%rbx), %rdi
movl 0x3c(%r12), %esi
callq 0xf1598
movq 0x20(%rbx), %rdi
movl 0x3c(%r12), %esi
callq 0xf1598
movq 0x28(%rbx), %rdi
movl 0x38(%r12), %esi
callq 0xf1598
movq 0x20(%rbx), %rdi
movl 0x38(%r12), %esi
callq 0xf1598
movq 0x28(%rbx), %rdi
movl 0x24(%rsp), %r13d
movq %r13, %rsi
callq 0xf1645
movq 0x20(%rbx), %rdi
movq %r13, %rsi
callq 0xf1645
movq 0x28(%rbx), %rdi
movq 0x18(%rsp), %r13
movq %r13, %rsi
callq 0xf1645
movq 0x20(%rbx), %rdi
movq %r13, %rsi
callq 0xf1645
movq 0x28(%rbx), %rdi
movq 0x18(%r14), %rsi
callq 0xf1645
movq 0x20(%rbx), %rdi
movq 0x18(%r14), %rsi
callq 0xf1645
movq 0x28(%rsp), %rdi
callq 0x180e0
movq %rax, %r13
movq 0x28(%rbx), %rdi
movq %rax, %rsi
callq 0xf1598
movq 0x20(%rbx), %rdi
movq %r13, %rsi
callq 0xf1598
movq 0x28(%rbx), %rdi
movq 0x68(%r12), %rax
movq 0x18(%rax), %rsi
callq 0xf1598
movq 0x20(%rbx), %rdi
movq 0x60(%r12), %rax
movq 0x18(%rax), %rsi
callq 0xf1598
movq 0x28(%rbx), %rdi
xorl %esi, %esi
callq 0xf1598
movq 0x28(%rbx), %rdi
xorl %esi, %esi
callq 0xf1598
movq 0x28(%rbx), %rdi
xorl %esi, %esi
callq 0xf1598
movl $0x41ed0010, %esi       # imm = 0x41ED0010
cmpb $0x0, 0x59(%r12)
jne 0xedeac
movl $0x28, %esi
cmpb $0x0, 0x5a(%r12)
jne 0xedeac
movl $0x81a40000, %eax       # imm = 0x81A40000
leaq 0x490000(%rax), %rsi
cmpb $0x0, 0x58(%r12)
cmoveq %rax, %rsi
movq 0x28(%rbx), %rdi
callq 0xf1645
movq 0x28(%rbx), %rdi
movq 0x30(%rsp), %rsi
callq 0xf1645
movq 0x28(%rbx), %rdi
movq 0x28(%rsp), %rbp
movq %rbp, %rsi
movq %r13, %rdx
callq 0xefb82
movq 0x20(%rbx), %rdi
movq %rbp, %rsi
movq %r13, %rdx
callq 0xefb82
movq 0x68(%r12), %rdi
movq 0x18(%rdi), %rdx
movq 0x28(%rbx), %rcx
xorl %esi, %esi
callq 0xefabc
movq 0x60(%r12), %rdi
movq 0x18(%rdi), %rdx
movq 0x20(%rbx), %rcx
xorl %esi, %esi
callq 0xefabc
cmpb $0x0, 0xc(%rsp)
je 0xedf22
movq 0x18(%r14), %rdx
movq 0x20(%rbx), %rcx
movq %r14, %rdi
jmp 0xedf32
testq %r15, %r15
je 0xedf39
movq 0x18(%r15), %rdx
movq 0x20(%rbx), %rcx
movq %r15, %rdi
xorl %esi, %esi
callq 0xefabc
incq 0x18(%rbx)
jmp 0xedbbf
xorl %ecx, %ecx
cmpl $0x8, %edx
setae %cl
leaq 0x800(,%rcx,2), %rcx
movq %rcx, 0x10(%rsp)
movl $0x0, 0xc(%rsp)
movq %rax, 0x18(%rsp)
jmp 0xedcd4