// File: /workspace/github_c_makefile_star2_O2/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 0xe29d9
leaq 0x59132(%rip), %rsi     # 0x13bb09
jmp 0xe2a43
movl %r9d, %r12d
movq %r8, %r13
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, %rbx
movq 0x30(%rsi), %rdi
callq 0xe0e44
movq 0x30(%rbx), %rdi
movq 0x18(%r14), %rcx
movq %r14, %rsi
xorl %edx, %edx
callq 0xe0f33
movq 0x30(%rbx), %rdi
callq 0xe0e95
movl %eax, %edx
movq 0x20(%rbx), %rax
movq 0x18(%rax), %rcx
movabsq $0x100000000, %rax      # imm = 0x100000000
cmpq %rax, %rcx
jl 0xe2a2e
leaq 0x59109(%rip), %rsi     # 0x13bb35
jmp 0xe2a43
movq %r13, 0x20(%rsp)
movq 0x18(%r14), %r13
cmpq %rax, %r13
jl 0xe2a5b
leaq 0x59111(%rip), %rsi     # 0x13bb54
movq %rbp, %rdi
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xdf2a5
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, 0x2c(%rsp)
jl 0xe2b40
cmpb $0x0, 0x59(%r15)
jne 0xe2b40
movq %rbp, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xe59cd
movq %rax, 0x10(%rsp)
movl %r12d, %eax
andl $0xf, %eax
testl %r12d, %r12d
pushq $0x6
popq %rdi
cmovnsl %eax, %edi
pushq $-0xf
popq %rsi
movl %edi, 0x28(%rsp)
xorl %edx, %edx
callq 0x100c38
movq %rbp, %rdi
movq 0x10(%rsp), %rsi
movl %eax, %edx
callq 0x100ba4
movq %rax, %r12
movq %r14, %rdi
callq 0xe62e4
movq 0x18(%r14), %rdx
testq %rax, %rax
je 0xe2aef
pushq $0x4
popq %rcx
movq %r12, %rdi
movq %rax, %rsi
callq 0x100c02
cmpl $0x1, %eax
jne 0xe2af8
jmp 0xe2b09
testq %rdx, %rdx
je 0xe2de5
leaq 0x5907b(%rip), %rsi     # 0x13bb7a
movq %rbp, %rdi
xorl %eax, %eax
callq 0xdf2a5
movq %r12, %rdi
callq 0x100c27
movq 0x10(%rsp), %r12
movq 0x18(%r12), %rax
cmpq 0x18(%r14), %rax
jge 0xe2b38
movl 0x28(%rsp), %edx
cmpl $0x3, %edx
jae 0xe2dc0
movl $0x804, %ecx            # imm = 0x804
jmp 0xe2dd0
movq %r12, %rdi
callq 0xe5591
xorl %r12d, %r12d
movq 0x28(%rbx), %rdi
movl $0x2014b50, %esi        # imm = 0x2014B50
callq 0xe5f7f
movq 0x20(%rbx), %rdi
movl $0x4034b50, %esi        # imm = 0x4034B50
callq 0xe5f7f
movq 0x28(%rbx), %rdi
cmpb $0x0, 0x5a(%r15)
movl $0x33f, %eax            # imm = 0x33F
pushq $0x3f
popq %rsi
cmoveq %rax, %rsi
callq 0xe5f08
pushq $0x14
popq %rbp
cmpb $0x0, 0xc(%rsp)
movq %r12, 0x10(%rsp)
je 0xe2ba0
cmpb $0x0, 0x59(%r15)
jne 0xe2b9b
cmpb $0x1, 0x5a(%r15)
pushq $0xb
popq %rbp
sbbq $0x0, %rbp
xorl %r12d, %r12d
jmp 0xe2ba4
pushq $0x8
popq %r12
movq 0x28(%rbx), %rdi
movq %rbp, %rsi
callq 0xe5f08
movq 0x20(%rbx), %rdi
movq %rbp, %rsi
callq 0xe5f08
movq 0x28(%rbx), %rdi
movq 0x18(%rsp), %rbp
movq %rbp, %rsi
callq 0xe5f08
movq 0x20(%rbx), %rdi
movq %rbp, %rsi
callq 0xe5f08
movq 0x28(%rbx), %rdi
movq %r12, %rsi
callq 0xe5f08
movq 0x20(%rbx), %rdi
movq %r12, %rsi
callq 0xe5f08
movq 0x28(%rbx), %rdi
movl 0x3c(%r15), %esi
callq 0xe5f08
movq 0x20(%rbx), %rdi
movl 0x3c(%r15), %esi
callq 0xe5f08
movq 0x28(%rbx), %rdi
movl 0x38(%r15), %esi
callq 0xe5f08
movq 0x20(%rbx), %rdi
movl 0x38(%r15), %esi
callq 0xe5f08
movq 0x28(%rbx), %rdi
movl 0x2c(%rsp), %r12d
movq %r12, %rsi
callq 0xe5f7f
movq 0x20(%rbx), %rdi
movq %r12, %rsi
callq 0xe5f7f
movq 0x28(%rbx), %rdi
movq %r13, %rsi
callq 0xe5f7f
movq 0x20(%rbx), %rdi
movq %r13, %rsi
callq 0xe5f7f
movq 0x28(%rbx), %rdi
movq 0x18(%r14), %rsi
callq 0xe5f7f
movq 0x20(%rbx), %rdi
movq 0x18(%r14), %rsi
callq 0xe5f7f
movq 0x20(%rsp), %r12
movq %r12, %rdi
callq 0x180e0
movq %rax, %r13
movq 0x28(%rbx), %rdi
movq %rax, %rsi
callq 0xe5f08
movq 0x20(%rbx), %rdi
movq %r13, %rsi
callq 0xe5f08
movq 0x28(%rbx), %rdi
movq 0x68(%r15), %rax
movq 0x18(%rax), %rsi
callq 0xe5f08
movq 0x20(%rbx), %rdi
movq 0x60(%r15), %rax
movq 0x18(%rax), %rsi
callq 0xe5f08
movq 0x28(%rbx), %rdi
xorl %esi, %esi
callq 0xe5f08
movq 0x28(%rbx), %rdi
xorl %esi, %esi
callq 0xe5f08
movq 0x28(%rbx), %rdi
xorl %esi, %esi
callq 0xe5f08
movl $0x41ed0010, %esi       # imm = 0x41ED0010
cmpb $0x0, 0x59(%r15)
jne 0xe2d11
cmpb $0x0, 0x5a(%r15)
je 0xe2cf7
pushq $0x28
popq %rsi
jmp 0xe2d0c
movl $0x81a40000, %eax       # imm = 0x81A40000
leaq 0x490000(%rax), %rsi
cmpb $0x0, 0x58(%r15)
cmoveq %rax, %rsi
movq 0x20(%rsp), %r12
movq 0x28(%rbx), %rdi
callq 0xe5f7f
movq 0x28(%rbx), %rdi
movq 0x30(%rsp), %rsi
callq 0xe5f7f
movq 0x28(%rbx), %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0xe46ba
movq 0x20(%rbx), %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0xe46ba
movq 0x68(%r15), %rdi
movq 0x18(%rdi), %rdx
movq 0x28(%rbx), %rcx
xorl %esi, %esi
callq 0xe45f4
movq 0x60(%r15), %rdi
movq 0x18(%rdi), %rdx
movq 0x20(%rbx), %rcx
xorl %esi, %esi
callq 0xe45f4
cmpb $0x0, 0xc(%rsp)
movq 0x10(%rsp), %r15
jne 0xe2d80
testq %r15, %r15
je 0xe2d92
movq %r15, %r14
movq 0x18(%r14), %rdx
movq 0x20(%rbx), %rcx
movq %r14, %rdi
xorl %esi, %esi
callq 0xe45f4
incq 0x18(%rbx)
testq %r15, %r15
je 0xe2db1
movq %r15, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xe5591
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 0xe2b43
xorl %edx, %edx
jmp 0xe2ada