// File: /workspace/github_cpp_makefile_star2_O1/Alcaro[P]bridges/arlib/zip.cpp
// Function: zip::pack() const
array<uint8_t> zip::pack() const
{
	array<uint8_t> ret;
	
	array<size_t> headerstarts;
	for (size_t i=0;i<filenames.size();i++)
	{
		headerstarts.append(ret.size());
		
		const file& f = filedat[i];
		locfhead h = {
			/*signature*/   locfhead::signature_expected,
			/*vermin*/      fileminver(f), // also contains host OS, but not important. and even if it was, pointless field
			/*bitflags*/    strascii(filenames[i]) ? 0 : 1<<11, // UTF-8 filenames
			/*compmethod*/  f.method,
			/*modtime*/     //merged
			/*moddate*/     f.dosdate,
			/*crc32*/       f.crc32,
			/*size_comp*/   f.data.size(),
			/*size_decomp*/ f.decomplen,
			/*len_fname*/   filenames[i].length(),
			/*len_exfield*/ 0,
		};
		arrayview<uint8_t> hb((uint8_t*)&h, sizeof(h));
		ret += hb;
		ret += filenames[i].bytes();
		ret += f.data;
	}
	
	size_t cdrstart = ret.size();
	for (size_t i=0;i<filenames.size();i++)
	{
		const file& f = filedat[i];
		centdirrec cdr = {
			/*signature*/    centdirrec::signature_expected,
			/*verused*/      63, // I don't think anything cares about this, just use latest
			/*vermin*/       fileminver(f),
			/*bitflags*/     strascii(filenames[i]) ? 0 : 1<<11,
			/*compmethod*/   f.method,
			/*modtime*/      //merged
			/*moddate*/      f.dosdate,
			/*crc32*/        f.crc32,
			/*size_comp*/    f.data.size(),
			/*size_decomp*/  f.decomplen,
			/*len_fname*/    filenames[i].length(),
			/*len_exfield*/  0,
			/*len_fcomment*/ 0,
			/*disknr*/       0,
			/*attr_int*/     0,
			// the ZIP specification defines the low byte of external attributes to be the MS-DOS directory attribute byte
			// aka https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
			// upper three bytes are undefined and contradictorily used
			// Windows Explorer uses the lower 16 bits as is, probably all 32 but hard to test
			// Unix tools usually put the permission bits, as well as __S_IFDIR, in upper 16 (0o644 << 16)
			// at least one OSX tool sometimes sets the 0x4000 flag for some unknown purpose (which Windows misreads as F_A_ENCRYPTED)
			// only the is-directory flag makes sense in a zip, others should not be present in a distributable archive
			/*attr_ext*/     filenames[i].endswith("/") ? 0x10 : 0x00,
			/*header_start*/ headerstarts[i],
		};
		arrayview<uint8_t> cdrb((uint8_t*)&cdr, sizeof(cdr));
		ret += cdrb;
		ret += filenames[i].bytes();
	}
	size_t cdrend = ret.size();
	
	endofcdr eod = {
		/*signature*/         endofcdr::signature_expected,
		/*diskid_this*/       0,
		/*diskid_cdrst*/      0,
		/*numfiles_thisdisk*/ filenames.size(),
		/*numfiles*/          filenames.size(),
		/*cdrsize*/           cdrend-cdrstart,
		/*cdrstart_fromdisk*/ cdrstart,
		/*zipcommentlen*/     0,
	};
	arrayview<uint8_t> eodb((uint8_t*)&eod, sizeof(eod));
	ret += eodb;
	
	return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rsi, %rbx
movq %rdi, %r14
xorps %xmm0, %xmm0
movups %xmm0, (%rdi)
movaps %xmm0, 0x30(%rsp)
cmpq $0x0, 0x8(%rsi)
movq %rsi, 0x48(%rsp)
je 0x1d49d
xorl %r13d, %r13d
xorl %ebp, %ebp
movq 0x8(%r14), %r15
movq 0x38(%rsp), %r12
leaq 0x1(%r12), %rsi
leaq 0x30(%rsp), %rdi
callq 0x10b32
movq 0x30(%rsp), %rax
leaq (%rax,%r12,8), %rsi
leaq (%rax,%r12,8), %rdi
addq $0x8, %rdi
movq %r12, %rdx
notq %rdx
addq 0x38(%rsp), %rdx
shlq $0x3, %rdx
callq 0x3600
movq 0x30(%rsp), %rax
movq %r15, (%rax,%r12,8)
movq 0x10(%rbx), %r15
movl $0x4034b50, (%rsp)      # imm = 0x4034B50
movq %rbx, %rcx
movzwl 0x4(%r15,%r13,2), %ebx
cmpw $0x8, %bx
movl $0xa, %eax
movl $0x14, %edx
cmovel %edx, %eax
movw %ax, 0x4(%rsp)
movq (%rcx), %r12
movq (%r12,%r13), %rdi
movq 0x8(%r12,%r13), %rsi
callq 0x1cfe0
xorb $0x1, %al
movzbl %al, %eax
shll $0xb, %eax
movw %ax, 0x6(%rsp)
movw %bx, 0x8(%rsp)
movl 0x1c(%r15,%r13,2), %eax
movl %eax, 0xa(%rsp)
movl 0x18(%r15,%r13,2), %eax
movl %eax, 0xe(%rsp)
movl 0x10(%r15,%r13,2), %eax
movl %eax, 0x12(%rsp)
movl (%r15,%r13,2), %eax
movl %eax, 0x16(%rsp)
movzbl 0xf(%r12,%r13), %eax
testb %al, %al
js 0x1d42d
xorl $0xf, %eax
jmp 0x1d432
movl 0x8(%r12,%r13), %eax
movw %ax, 0x1a(%rsp)
movw $0x0, 0x1c(%rsp)
movl $0x1e, %edx
movq %r14, %rdi
movq %rsp, %rsi
callq 0xdfa6
movq 0x48(%rsp), %rbx
movq (%rbx), %rsi
movzbl 0xf(%rsi,%r13), %edx
testb %dl, %dl
js 0x1d469
addq %r13, %rsi
xorq $0xf, %rdx
jmp 0x1d472
movl 0x8(%rsi,%r13), %edx
movq (%rsi,%r13), %rsi
movq %r14, %rdi
callq 0xdfa6
movq 0x8(%r15,%r13,2), %rsi
movq 0x10(%r15,%r13,2), %rdx
movq %r14, %rdi
callq 0xdfa6
incq %rbp
addq $0x10, %r13
cmpq 0x8(%rbx), %rbp
jb 0x1d368
movq 0x8(%r14), %rax
movq %rax, 0x50(%rsp)
movq 0x8(%rbx), %rax
testq %rax, %rax
je 0x1d5f3
xorl %r15d, %r15d
xorl %r12d, %r12d
movq %r14, 0x40(%rsp)
movq 0x10(%rbx), %r13
movl $0x2014b50, (%rsp)      # imm = 0x2014B50
movw $0x3f, 0x4(%rsp)
movq %rbx, %rcx
movzwl 0x4(%r13,%r15,2), %ebx
cmpw $0x8, %bx
movl $0xa, %eax
movl $0x14, %edx
cmovel %edx, %eax
movw %ax, 0x6(%rsp)
movq (%rcx), %r14
leaq (%r14,%r15), %rbp
movq (%r14,%r15), %rdi
movq 0x8(%r14,%r15), %rsi
callq 0x1cfe0
xorb $0x1, %al
movzbl %al, %eax
shll $0xb, %eax
movw %ax, 0x8(%rsp)
movw %bx, 0xa(%rsp)
movl 0x1c(%r13,%r15,2), %eax
movl %eax, 0xc(%rsp)
movl 0x18(%r13,%r15,2), %eax
movl %eax, 0x10(%rsp)
movl 0x10(%r13,%r15,2), %eax
movl %eax, 0x14(%rsp)
movl (%r13,%r15,2), %eax
movl %eax, 0x18(%rsp)
movzbl 0xf(%r14,%r15), %eax
testb %al, %al
js 0x1d549
xorl $0xf, %eax
jmp 0x1d54c
movl 0x8(%rbp), %eax
movq 0x40(%rsp), %r14
movw %ax, 0x1c(%rsp)
movq $0x0, 0x1e(%rsp)
movl $0x1, %edx
leaq 0x58(%rsp), %rdi
leaq 0x12a60(%rip), %rsi     # 0x2ffd0
movl $0x1, %ecx
callq 0x5040
movq 0x58(%rsp), %rsi
movq 0x60(%rsp), %rdx
movq %rbp, %rdi
callq 0x19744
movzbl %al, %eax
shll $0x4, %eax
movl %eax, 0x26(%rsp)
movq 0x30(%rsp), %rax
movl (%rax,%r12,8), %eax
movl %eax, 0x2a(%rsp)
movl $0x2e, %edx
movq %r14, %rdi
movq %rsp, %rsi
callq 0xdfa6
movq 0x48(%rsp), %rbx
movq (%rbx), %rsi
movzbl 0xf(%rsi,%r15), %edx
testb %dl, %dl
js 0x1d5ce
addq %r15, %rsi
xorq $0xf, %rdx
jmp 0x1d5d7
movl 0x8(%rsi,%r15), %edx
movq (%rsi,%r15), %rsi
movq %r14, %rdi
callq 0xdfa6
incq %r12
movq 0x8(%rbx), %rax
addq $0x10, %r15
cmpq %rax, %r12
jb 0x1d4be
movl 0x8(%r14), %ecx
movq %rsp, %rsi
movq $0x6054b50, (%rsi)      # imm = 0x6054B50
movw %ax, 0x8(%rsi)
movw %ax, 0xa(%rsi)
movq 0x50(%rsp), %rax
subl %eax, %ecx
movl %ecx, 0xc(%rsi)
movl %eax, 0x10(%rsi)
movw $0x0, 0x14(%rsi)
movl $0x16, %edx
movq %r14, %rdi
callq 0xdfa6
movq 0x30(%rsp), %rdi
callq 0x3430
movq %r14, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop