// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movl %r9d, -0x2c(%rbp)
movl $0x0, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
movq $0x0, -0x58(%rbp)
movl $0x0, -0x64(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x7fffffff, 0x18(%rax) # imm = 0x7FFFFFFF
jl 0x162e52
movq -0x8(%rbp), %rdi
leaq 0x71cf3(%rip), %rsi     # 0x1d4b39
movb $0x0, %al
callq 0x15bfb0
jmp 0x163363
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x15f250
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
movq -0x20(%rbp), %rsi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rcx
xorl %eax, %eax
movl %eax, %edx
callq 0x15f500
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x15f340
movl %eax, -0x44(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x18(%rax), %rax
movq %rax, -0x38(%rbp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq %rax, -0x38(%rbp)
jle 0x162ebe
movq -0x8(%rbp), %rdi
leaq 0x71cb3(%rip), %rsi     # 0x1d4b65
movb $0x0, %al
callq 0x15bfb0
jmp 0x163363
movq -0x20(%rbp), %rax
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpq %rcx, 0x18(%rax)
jle 0x162ee4
movq -0x8(%rbp), %rdi
leaq 0x71cac(%rip), %rsi     # 0x1d4b84
movb $0x0, %al
callq 0x15bfb0
jmp 0x163363
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x20(%rbp), %rax
cmpq $0x5, 0x18(%rax)
jle 0x162f0c
movq -0x18(%rbp), %rax
cmpb $0x0, 0x59(%rax)
jne 0x162f0c
movl $0x1, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
je 0x162fb4
movq -0x8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x168020
movq %rax, -0x58(%rbp)
cmpl $0x0, -0x2c(%rbp)
jge 0x162f36
movl $0x6, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
andl $0xf, %eax
movl %eax, -0x70(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x58(%rbp), %rcx
movl -0x70(%rbp), %r8d
callq 0x1637d0
movq -0x58(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x20(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jge 0x162fa1
movl $0x1, -0x4c(%rbp)
movq -0x58(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x60(%rbp)
cmpl $0x2, -0x70(%rbp)
ja 0x162f8e
movl -0x64(%rbp), %eax
orl $0x4, %eax
movl %eax, -0x64(%rbp)
jmp 0x162f9f
cmpl $0x8, -0x70(%rbp)
jb 0x162f9d
movl -0x64(%rbp), %eax
orl $0x2, %eax
movl %eax, -0x64(%rbp)
jmp 0x162f9f
jmp 0x162fb2
movq -0x58(%rbp), %rdi
callq 0x1676a0
movq $0x0, -0x58(%rbp)
jmp 0x162fb4
movl -0x64(%rbp), %eax
orl $0x800, %eax            # imm = 0x800
movl %eax, -0x64(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movl $0x2014b50, %esi        # imm = 0x2014B50
callq 0x168c30
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movl $0x4034b50, %esi        # imm = 0x4034B50
callq 0x168c30
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x18(%rbp), %rax
movzbl 0x5a(%rax), %edx
movl $0x33f, %eax            # imm = 0x33F
movl $0x3f, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movslq %eax, %rsi
callq 0x168a10
cmpl $0x0, -0x4c(%rbp)
je 0x16301a
movl $0x14, -0x6c(%rbp)
jmp 0x16304b
movq -0x18(%rbp), %rax
cmpb $0x0, 0x59(%rax)
je 0x16302d
movl $0x14, -0x6c(%rbp)
jmp 0x163049
movq -0x18(%rbp), %rax
cmpb $0x0, 0x5a(%rax)
je 0x163040
movl $0xb, -0x6c(%rbp)
jmp 0x163047
movl $0xa, -0x6c(%rbp)
jmp 0x163049
jmp 0x16304b
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movl -0x6c(%rbp), %eax
movl %eax, %esi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movl -0x6c(%rbp), %eax
movl %eax, %esi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movl -0x64(%rbp), %eax
movl %eax, %esi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movl -0x64(%rbp), %eax
movl %eax, %esi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movl -0x4c(%rbp), %edx
xorl %eax, %eax
movl $0x8, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movslq %eax, %rsi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movl -0x4c(%rbp), %edx
xorl %eax, %eax
movl $0x8, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movslq %eax, %rsi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x18(%rbp), %rax
movl 0x3c(%rax), %eax
movl %eax, %esi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x18(%rbp), %rax
movl 0x3c(%rax), %eax
movl %eax, %esi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x18(%rbp), %rax
movl 0x38(%rax), %eax
movl %eax, %esi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x18(%rbp), %rax
movl 0x38(%rax), %eax
movl %eax, %esi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movl -0x44(%rbp), %eax
movl %eax, %esi
callq 0x168c30
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movl -0x44(%rbp), %eax
movl %eax, %esi
callq 0x168c30
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x60(%rbp), %rsi
callq 0x168c30
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x60(%rbp), %rsi
callq 0x168c30
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rsi
callq 0x168c30
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rsi
callq 0x168c30
movq -0x28(%rbp), %rdi
callq 0x190e0
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x40(%rbp), %rsi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x40(%rbp), %rsi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x18(%rbp), %rax
movq 0x68(%rax), %rax
movq 0x18(%rax), %rsi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x18(%rbp), %rax
movq 0x60(%rax), %rax
movq 0x18(%rax), %rsi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x168a10
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x168a10
movq -0x18(%rbp), %rax
cmpb $0x0, 0x59(%rax)
je 0x163242
movl $0x41ed0010, -0x68(%rbp) # imm = 0x41ED0010
jmp 0x163273
movq -0x18(%rbp), %rax
cmpb $0x0, 0x5a(%rax)
je 0x163255
movl $0x28, -0x68(%rbp)
jmp 0x163271
movq -0x18(%rbp), %rax
cmpb $0x0, 0x58(%rax)
je 0x163268
movl $0x81ed0000, -0x68(%rbp) # imm = 0x81ED0000
jmp 0x16326f
movl $0x81a40000, -0x68(%rbp) # imm = 0x81A40000
jmp 0x163271
jmp 0x163273
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movl -0x68(%rbp), %eax
movl %eax, %esi
callq 0x168c30
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x38(%rbp), %rsi
callq 0x168c30
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x28(%rbp), %rsi
movq -0x40(%rbp), %rdx
callq 0x166170
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x28(%rbp), %rsi
movq -0x40(%rbp), %rdx
callq 0x166170
movq -0x18(%rbp), %rax
movq 0x68(%rax), %rdi
movq -0x18(%rbp), %rax
movq 0x68(%rax), %rax
movq 0x18(%rax), %rdx
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rcx
xorl %eax, %eax
movl %eax, %esi
callq 0x166070
movq -0x18(%rbp), %rax
movq 0x60(%rax), %rdi
movq -0x18(%rbp), %rax
movq 0x60(%rax), %rax
movq 0x18(%rax), %rdx
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rcx
xorl %eax, %eax
movl %eax, %esi
callq 0x166070
cmpl $0x0, -0x4c(%rbp)
je 0x163336
cmpq $0x0, -0x58(%rbp)
je 0x163334
movq -0x58(%rbp), %rdi
movq -0x58(%rbp), %rax
movq 0x18(%rax), %rdx
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rcx
xorl %eax, %eax
movl %eax, %esi
callq 0x166070
jmp 0x163353
movq -0x20(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rdx
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rcx
xorl %eax, %eax
movl %eax, %esi
callq 0x166070
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x18(%rax)
cmpq $0x0, -0x58(%rbp)
je 0x163373
movq -0x58(%rbp), %rdi
callq 0x1676a0
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax)