// File: /workspace/github_cpp_makefile_star2_O3/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 %rdi, %rbx
pxor %xmm0, %xmm0
movdqu %xmm0, (%rdi)
movdqa %xmm0, 0x30(%rsp)
cmpq $0x0, 0x8(%rsi)
je 0x1ceee
movq %rsi, %r14
xorl %r15d, %r15d
movq %rsp, %r12
movq 0x8(%rbx), %r13
movq 0x38(%rsp), %rbp
leaq 0x1(%rbp), %rsi
leaq 0x30(%rsp), %rdi
callq 0x10ee8
movq 0x30(%rsp), %rax
leaq (%rax,%rbp,8), %rsi
leaq (%rax,%rbp,8), %rdi
addq $0x8, %rdi
movq %rbp, %rdx
notq %rdx
addq 0x38(%rsp), %rdx
shlq $0x3, %rdx
callq 0x3600
movq 0x30(%rsp), %rax
movq %r13, (%rax,%rbp,8)
movq 0x10(%r14), %r13
movq %r15, %rcx
shlq $0x5, %rcx
movl $0x4034b50, (%rsp)      # imm = 0x4034B50
cmpw $0x8, 0x4(%r13,%rcx)
movl $0xa, %eax
movl $0x14, %edx
cmovel %edx, %eax
movw %ax, 0x4(%rsp)
movq (%r14), %rax
movq %r15, %rbp
shlq $0x4, %rbp
movq (%rax,%rbp), %rdx
movq 0x8(%rax,%rbp), %rsi
movq %rdx, 0x40(%rsp)
movq %rsi, 0x48(%rsp)
movq %rsi, %rdi
shrq $0x38, %rdi
xorq $0xf, %rdi
testq %rsi, %rsi
leaq 0x40(%rsp), %r8
cmovnsq %r8, %rdx
movl %esi, %esi
cmovnsq %rdi, %rsi
testq %rsi, %rsi
je 0x1ccb8
xorl %edi, %edi
movb (%rdx,%rdi), %r8b
addb $-0x20, %r8b
cmpb $0x5f, %r8b
jae 0x1ccbc
incq %rdi
cmpq %rdi, %rsi
jne 0x1cca2
xorl %edx, %edx
jmp 0x1ccc0
movw $0x800, %dx             # imm = 0x800
addq %rcx, %r13
addq %rbp, %rax
movw %dx, 0x6(%rsp)
movzwl 0x4(%r13), %ecx
movw %cx, 0x8(%rsp)
movq 0x18(%r13), %xmm0
pshufd $0xe1, %xmm0, %xmm0     # xmm0 = xmm0[1,0,2,3]
movq %xmm0, 0xa(%rsp)
movl 0x10(%r13), %ecx
movl %ecx, 0x12(%rsp)
movl (%r13), %ecx
movl %ecx, 0x16(%rsp)
movzbl 0xf(%rax), %ecx
testb %cl, %cl
js 0x1cd03
xorl $0xf, %ecx
jmp 0x1cd06
movl 0x8(%rax), %ecx
movw %cx, 0x1a(%rsp)
movw $0x0, 0x1c(%rsp)
movl $0x1e, %edx
movq %rbx, %rdi
movq %r12, %rsi
callq 0xe3cc
movq (%r14), %rax
leaq (%rax,%rbp), %rsi
movzbl 0xf(%rax,%rbp), %edx
testb %dl, %dl
js 0x1cd38
xorq $0xf, %rdx
jmp 0x1cd3e
movl 0x8(%rsi), %edx
movq (%rsi), %rsi
movq %rbx, %rdi
callq 0xe3cc
movq 0x8(%r13), %rsi
movq 0x10(%r13), %rdx
movq %rbx, %rdi
callq 0xe3cc
incq %r15
movq 0x8(%r14), %rax
cmpq %rax, %r15
jb 0x1cbf1
movq 0x8(%rbx), %rdx
testq %rax, %rax
je 0x1cef0
movq %rdx, 0x50(%rsp)
xorl %r12d, %r12d
movq %rsp, %r15
movq 0x10(%r14), %rax
movq %r12, %rcx
shlq $0x5, %rcx
movl $0x2014b50, (%rsp)      # imm = 0x2014B50
movw $0x3f, 0x4(%rsp)
cmpw $0x8, 0x4(%rax,%rcx)
movl $0xa, %edx
movl $0x14, %esi
cmovel %esi, %edx
movw %dx, 0x6(%rsp)
movq (%r14), %rbp
movq %r12, %r13
shlq $0x4, %r13
movq (%rbp,%r13), %rdx
movq 0x8(%rbp,%r13), %rsi
movq %rdx, 0x40(%rsp)
movq %rsi, 0x48(%rsp)
movq %rsi, %rdi
shrq $0x38, %rdi
xorq $0xf, %rdi
testq %rsi, %rsi
leaq 0x40(%rsp), %r8
cmovnsq %r8, %rdx
movl %esi, %esi
cmovnsq %rdi, %rsi
testq %rsi, %rsi
je 0x1ce07
xorl %edi, %edi
movb (%rdx,%rdi), %r8b
addb $-0x20, %r8b
cmpb $0x5f, %r8b
jae 0x1ce0b
incq %rdi
cmpq %rdi, %rsi
jne 0x1cdf1
xorl %edx, %edx
jmp 0x1ce0f
movw $0x800, %dx             # imm = 0x800
addq %rcx, %rax
addq %r13, %rbp
movw %dx, 0x8(%rsp)
movzwl 0x4(%rax), %ecx
movw %cx, 0xa(%rsp)
movq 0x18(%rax), %xmm0
pshufd $0xe1, %xmm0, %xmm0     # xmm0 = xmm0[1,0,2,3]
movq %xmm0, 0xc(%rsp)
movl 0x10(%rax), %ecx
movl %ecx, 0x14(%rsp)
movl (%rax), %eax
movl %eax, 0x18(%rsp)
movzbl 0xf(%rbp), %eax
testb %al, %al
js 0x1ce4d
xorl $0xf, %eax
jmp 0x1ce50
movl 0x8(%rbp), %eax
movw %ax, 0x1c(%rsp)
movq $0x0, 0x1e(%rsp)
movl $0x1, %edx
leaq 0x58(%rsp), %rdi
leaq 0x131b1(%rip), %rsi     # 0x30020
movl $0x1, %ecx
callq 0x5990
movq 0x58(%rsp), %rsi
movq 0x60(%rsp), %rdx
movq %rbp, %rdi
callq 0x19952
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 %rbx, %rdi
movq %r15, %rsi
callq 0xe3cc
movq (%r14), %rax
leaq (%rax,%r13), %rsi
movzbl 0xf(%rax,%r13), %edx
testb %dl, %dl
js 0x1cec9
xorq $0xf, %rdx
jmp 0x1cecf
movl 0x8(%rsi), %edx
movq (%rsi), %rsi
movq %rbx, %rdi
callq 0xe3cc
incq %r12
movq 0x8(%r14), %rax
cmpq %rax, %r12
jb 0x1cd7e
movq 0x50(%rsp), %rdx
jmp 0x1cef2
xorl %edx, %edx
xorl %eax, %eax
movl 0x8(%rbx), %ecx
movq %rsp, %rsi
movq $0x6054b50, (%rsi)      # imm = 0x6054B50
movw %ax, 0x8(%rsi)
movw %ax, 0xa(%rsi)
subl %edx, %ecx
movl %ecx, 0xc(%rsi)
movl %edx, 0x10(%rsi)
movw $0x0, 0x14(%rsi)
movl $0x16, %edx
movq %rbx, %rdi
callq 0xe3cc
movq 0x30(%rsp), %rdi
callq 0x3430
movq %rbx, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq