// File: /workspace/github_c_makefile_star2_O3/jsummers[P]deark/src/deark-zip.c
// Function: de_zip_add_file_to_archive
void de_zip_add_file_to_archive(deark *c, dbuf *f)
{
	struct zipw_ctx *zzz;
	struct zipw_md *md = NULL;
	int write_ntfs_times = 0;
	int write_UT_time = 0;

	md = de_malloc(c, sizeof(struct zipw_md));

	if(!c->zip_data) {
		// ZIP file hasn't been created yet
		if(!de_zip_create_file(c)) {
			de_fatalerror(c);
			goto done;
		}
	}

	zzz = (struct zipw_ctx*)c->zip_data;

	de_dbg(c, "adding to zip: name=%s len=%"I64_FMT, f->name, f->len);

	if(f->fi_copy) {
		if(f->fi_copy->is_directory) {
			md->is_directory = 1;
		}
		else if(f->fi_copy->is_volume_label) {
			md->is_volume_label = 1;
		}

		if(f->fi_copy->mode_flags&DE_MODEFLAG_EXE) {
			md->is_executable = 1;
		}
	}

	if(c->preserve_file_times_archives && f->fi_copy && f->fi_copy->timestamp[DE_TIMESTAMPIDX_MODIFY].is_valid) {
		md->modtime = f->fi_copy->timestamp[DE_TIMESTAMPIDX_MODIFY];
		if(md->modtime.precision>DE_TSPREC_1SEC) {
			write_ntfs_times = 1;
		}
	}
	else if(c->reproducible_output) {
		de_get_reproducible_timestamp(c, &md->modtime);
	}
	else {
		de_cached_current_time_to_timestamp(c, &md->modtime);

		// We only write the current time because ZIP format leaves us little
		// choice.
		// Note that although c->current_time is probably high precision,
		// we don't consider that good enough reason to force NTFS timestamps
		// to be written.
	}

	// Note: Timestamps other than the modification time are a low priority.
	// We'll write them in some cases, when it is easy to do so.
	if(c->preserve_file_times_archives && f->fi_copy) {
		md->actime = f->fi_copy->timestamp[DE_TIMESTAMPIDX_ACCESS];
		md->crtime = f->fi_copy->timestamp[DE_TIMESTAMPIDX_CREATE];
	}

	md->modtime_unix = de_timestamp_to_unix_time(&md->modtime);
	set_dos_modtime(md);

	if(is_valid_32bit_unix_time(md->modtime_unix)) {
		// Always write a Unix timestamp if we can.
		write_UT_time = 1;

		if(md->modtime_unix < 0) {
			// This negative Unix time is in range, but problematic,
			// so write NTFS times as well.
			write_ntfs_times = 1;
		}
	}
	else { // Out of range of ZIP's (signed int32) Unix style timestamps
		write_ntfs_times = 1;
	}

	if(write_ntfs_times) {
		md->modtime_as_FILETIME = de_timestamp_to_FILETIME(&md->modtime);
		if(md->modtime_as_FILETIME == 0) {
			write_ntfs_times = 0;
		}
		else {
			md->actime_as_FILETIME = de_timestamp_to_FILETIME(&md->actime);
			md->crtime_as_FILETIME = de_timestamp_to_FILETIME(&md->crtime);
		}
	}

	// Create ZIP "extra data" "Extended Timestamp" and "NTFS" fields,
	// containing the UTC timestamp.

	// Use temporary dbufs to help construct the extra field data.
	md->eflocal = dbuf_create_membuf(c, 256, 0);
	md->efcentral = dbuf_create_membuf(c, 256, 0);

	if(write_UT_time) {
		do_UT_times(c, md, md->eflocal, 0);
		do_UT_times(c, md, md->efcentral, 1);
	}

	if(write_ntfs_times) {
		// Note: Info-ZIP says: "In the current implementations, this field [...]
		// is only stored as local extra field.
		// But 7-Zip supports it *only* as a central extra field.
		// So we'll write both.
		do_ntfs_times(c, md, md->eflocal, 0);
		do_ntfs_times(c, md, md->efcentral, 1);
	}

	if(f->fi_copy && f->fi_copy->has_riscos_data) {
		do_riscos_attribs(c, md, f->fi_copy, md->eflocal);
		do_riscos_attribs(c, md, f->fi_copy, md->efcentral);
	}

	if(md->is_directory) {
		size_t nlen;
		char *name2;

		// Append a "/" to the name
		nlen = de_strlen(f->name);
		name2 = de_malloc(c, (i64)nlen+2);
		de_snprintf(name2, nlen+2, "%s/", f->name);

		zipw_add_memberfile(c, zzz, md, f, name2, MZ_NO_COMPRESSION);

		de_free(c, name2);
	}
	else {
		zipw_add_memberfile(c, zzz, md, f, f->name, zzz->cmprlevel);
	}

done:
	if(md) {
		dbuf_close(md->eflocal);
		dbuf_close(md->efcentral);
		de_free(c, md);
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %r15
movq %rdi, %rbx
movl $0x70, %esi
callq 0xe8b2b
movq %rax, %r14
movq 0x138(%rbx), %rax
testq %rax, %rax
jne 0xecf47
movq %rbx, %rdi
callq 0xecdd0
testl %eax, %eax
je 0xed1fa
movq 0x138(%rbx), %rax
movq %rax, (%rsp)
movq 0x18(%r15), %rcx
movq 0x68(%r15), %rdx
leaq 0x5c04b(%rip), %rsi     # 0x148fa5
movq %rbx, %rdi
xorl %eax, %eax
callq 0xe8617
movq 0xd0(%r15), %rax
testq %rax, %rax
je 0xecf7d
cmpb $0x0, 0x9(%rax)
je 0xecf86
movb $0x1, 0x59(%r14)
jmp 0xecf91
leaq 0xdd(%rbx), %r13
jmp 0xecfc8
cmpb $0x0, 0xa(%rax)
je 0xecf91
movb $0x1, 0x5a(%r14)
testb $0x2, 0x14(%rax)
je 0xecf9c
movb $0x1, 0x58(%r14)
leaq 0xdd(%rbx), %r13
cmpb $0x0, 0xdd(%rbx)
je 0xecfc8
cmpb $0x0, 0x18(%rax)
je 0xecfc8
addq $0x18, %rax
movups (%rax), %xmm0
movups %xmm0, (%r14)
cmpb $0x1f, 0x2(%r14)
setb %r12b
jmp 0xecfec
cmpb $0x0, 0xdf(%rbx)
je 0xecfde
movq %rbx, %rdi
movq %r14, %rsi
callq 0xeb9eb
jmp 0xecfe9
movq %rbx, %rdi
movq %r14, %rsi
callq 0xeb0f7
movb $0x1, %r12b
cmpb $0x0, (%r13)
je 0xed018
movq 0xd0(%r15), %rax
testq %rax, %rax
je 0xed018
movups 0x38(%rax), %xmm0
movups %xmm0, 0x10(%r14)
movq 0xd0(%r15), %rax
movups 0x28(%rax), %xmm0
movups %xmm0, 0x20(%r14)
movq %r14, %rdi
callq 0xeacfd
movq %rax, 0x30(%r14)
movl $0x12cea600, %edi       # imm = 0x12CEA600
cmpq $0x12cea600, %rax       # imm = 0x12CEA600
jl 0xed043
movabsq $0x10391447e, %rdi      # imm = 0x10391447E
movq %r14, %r13
cmpq %rdi, %rax
jbe 0xed052
leaq 0x8(%rsp), %r13
movq %r13, %rsi
xorl %edx, %edx
callq 0xea7f5
leaq 0x18(%rsp), %rbp
movq %r13, %rdi
movq %rbp, %rsi
callq 0xead46
movl 0x10(%rbp), %eax
movl 0x14(%rbp), %ecx
shll $0xb, %eax
shll $0x5, %ecx
addl %eax, %ecx
movl 0x18(%rbp), %eax
sarl %eax
addl %ecx, %eax
movl %eax, 0x3c(%r14)
movl 0x4(%rbp), %eax
movl 0x8(%rbp), %ecx
shll $0x9, %eax
shll $0x5, %ecx
addl %eax, %ecx
movl 0xc(%rbp), %eax
addl %ecx, %eax
addl $0xfff08820, %eax       # imm = 0xFFF08820
movl %eax, 0x38(%r14)
movq 0x30(%r14), %r13
movl $0x80000000, %eax       # imm = 0x80000000
subq %rax, %r13
setb %al
movb $0x1, %bpl
testb %r12b, %al
jne 0xed0de
movq %r14, %rdi
callq 0xea8e9
movq %rax, 0x40(%r14)
testq %rax, %rax
je 0xed0de
leaq 0x10(%r14), %rdi
callq 0xea8e9
movq %rax, 0x48(%r14)
movq %r14, %rdi
addq $0x20, %rdi
callq 0xea8e9
movq %rax, 0x50(%r14)
xorl %ebp, %ebp
movl $0x100, %esi            # imm = 0x100
movq %rbx, %rdi
xorl %edx, %edx
callq 0xf09c5
movq %rax, 0x60(%r14)
movl $0x100, %esi            # imm = 0x100
movq %rbx, %rdi
xorl %edx, %edx
callq 0xf09c5
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
movq %rax, 0x68(%r14)
cmpq %rcx, %r13
jb 0xed132
movq 0x60(%r14), %rsi
movq %r14, %rdi
xorl %edx, %edx
callq 0xed233
movq 0x68(%r14), %rsi
movq %r14, %rdi
movl $0x1, %edx
callq 0xed233
testb %bpl, %bpl
jne 0xed14f
movq 0x60(%r14), %rsi
movq %r14, %rdi
callq 0xed3a1
movq 0x68(%r14), %rsi
movq %r14, %rdi
callq 0xed3a1
movq 0xd0(%r15), %rsi
testq %rsi, %rsi
je 0xed180
cmpb $0x0, 0x10(%rsi)
je 0xed180
movq 0x60(%r14), %rdx
movq %r14, %rdi
callq 0xed42a
movq 0xd0(%r15), %rsi
movq 0x68(%r14), %rdx
movq %r14, %rdi
callq 0xed42a
cmpb $0x0, 0x59(%r14)
movq 0x68(%r15), %r8
je 0xed1e2
movq %r8, %rdi
callq 0x180e0
leaq 0x2(%rax), %r13
movq %rbx, %rdi
movq %r13, %rsi
callq 0xe8b2b
movq %rax, %rbp
movq 0x68(%r15), %rcx
leaq 0x5be14(%rip), %rdx     # 0x148fc4
movq %rax, %rdi
movq %r13, %rsi
xorl %eax, %eax
callq 0xe8193
movq %rbx, %rdi
movq (%rsp), %rsi
movq %r14, %rdx
movq %r15, %rcx
movq %rbp, %r8
xorl %r9d, %r9d
callq 0xed4c4
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xe8be2
jmp 0xed207
movq (%rsp), %rsi
movl 0x10(%rsi), %r9d
movq %rbx, %rdi
movq %r14, %rdx
movq %r15, %rcx
callq 0xed4c4
jmp 0xed207
movq %rbx, %rdi
callq 0xe9522
testq %r14, %r14
je 0xed224
movq 0x60(%r14), %rdi
callq 0xf052b
movq 0x68(%r14), %rdi
callq 0xf052b
movq %rbx, %rdi
movq %r14, %rsi
callq 0xe8be2
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq