// File: 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
movq %rsp, %rbp
subq $0x310, %rsp            # imm = 0x310
movq %rdi, -0x278(%rbp)
movq %rdi, %rax
movq %rax, -0x270(%rbp)
movq %rdi, -0xe0(%rbp)
movq %rsi, -0xe8(%rbp)
movq -0xe8(%rbp), %rax
movq %rax, -0x268(%rbp)
movb $0x0, -0xe9(%rbp)
callq 0x74b0
leaq -0x100(%rbp), %rdi
callq 0x23d20
movq $0x0, -0x108(%rbp)
movq -0x268(%rbp), %rdi
movq -0x108(%rbp), %rax
movq %rax, -0x280(%rbp)
callq 0x27270
movq %rax, %rcx
movq -0x280(%rbp), %rax
cmpq %rcx, %rax
jae 0x452e8
movq -0x278(%rbp), %rdi
callq 0x6290
movq %rax, -0x110(%rbp)
leaq -0x100(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x234a0
movq -0x268(%rbp), %rdi
addq $0x10, %rdi
movq -0x108(%rbp), %rsi
callq 0x459e0
movq %rax, -0x118(%rbp)
leaq -0x136(%rbp), %rdi
movl $0x4034b50, %esi        # imm = 0x4034B50
callq 0x45b80
leaq -0x136(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x2a8(%rbp)
movq -0x118(%rbp), %rdi
callq 0x44980
movq -0x2a8(%rbp), %rdi
movzwl %ax, %esi
callq 0x45bb0
movq -0x268(%rbp), %rdi
leaq -0x136(%rbp), %rax
addq $0x6, %rax
movq %rax, -0x2a0(%rbp)
movq -0x108(%rbp), %rsi
callq 0x276f0
movq (%rax), %rcx
movq %rcx, -0x148(%rbp)
movq 0x8(%rax), %rax
movq %rax, -0x140(%rbp)
movq -0x148(%rbp), %rdi
movq -0x140(%rbp), %rsi
callq 0x449b0
movq -0x2a0(%rbp), %rdi
movb %al, %dl
movl $0x800, %eax            # imm = 0x800
xorl %ecx, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movzwl %ax, %esi
callq 0x45bb0
leaq -0x136(%rbp), %rdi
addq $0x8, %rdi
movq -0x118(%rbp), %rax
movzwl 0x4(%rax), %esi
callq 0x45bb0
leaq -0x136(%rbp), %rdi
addq $0xa, %rdi
movq -0x118(%rbp), %rax
movl 0x1c(%rax), %esi
callq 0x45b80
leaq -0x136(%rbp), %rdi
addq $0xe, %rdi
movq -0x118(%rbp), %rax
movl 0x18(%rax), %esi
callq 0x45b80
leaq -0x136(%rbp), %rax
addq $0x12, %rax
movq %rax, -0x298(%rbp)
movq -0x118(%rbp), %rdi
addq $0x8, %rdi
callq 0x6290
movq -0x298(%rbp), %rdi
movl %eax, %esi
callq 0x45b80
leaq -0x136(%rbp), %rdi
addq $0x16, %rdi
movq -0x118(%rbp), %rax
movl (%rax), %esi
callq 0x45b80
movq -0x268(%rbp), %rdi
leaq -0x136(%rbp), %rax
addq $0x1a, %rax
movq %rax, -0x290(%rbp)
movq -0x108(%rbp), %rsi
callq 0x276f0
movq %rax, -0xc8(%rbp)
movq -0xc8(%rbp), %rax
movq %rax, -0x288(%rbp)
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
cmpl $0x0, %eax
jl 0x45141
movq -0x288(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
xorl $0xf, %eax
movzbl %al, %eax
movl %eax, -0xbc(%rbp)
jmp 0x45151
movq -0x288(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0xbc(%rbp)
movq -0x290(%rbp), %rdi
movl -0xbc(%rbp), %eax
movzwl %ax, %esi
callq 0x45bb0
leaq -0x136(%rbp), %rdi
addq $0x1c, %rdi
xorl %esi, %esi
callq 0x45bb0
leaq -0x158(%rbp), %rdi
leaq -0x136(%rbp), %rsi
movl $0x1e, %edx
callq 0x5d70
movq -0x278(%rbp), %rdi
movq -0x158(%rbp), %rax
movq %rax, -0x168(%rbp)
movq -0x150(%rbp), %rax
movq %rax, -0x160(%rbp)
movq -0x168(%rbp), %rsi
movq -0x160(%rbp), %rdx
callq 0x1d5f0
movq -0x268(%rbp), %rdi
movq -0x108(%rbp), %rsi
callq 0x276f0
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
leaq -0x88(%rbp), %rcx
movq %rcx, -0x58(%rbp)
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x2b0(%rbp)
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
cmpl $0x0, %eax
jl 0x45244
movq -0x2b0(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
callq 0x5cc0
movq -0x2b0(%rbp), %rsi
movsbl %al, %eax
xorl $0xf, %eax
movzbl %al, %eax
movl %eax, %edx
leaq -0x88(%rbp), %rdi
callq 0x5ed0
jmp 0x4525f
movq -0x2b0(%rbp), %rax
movq (%rax), %rsi
movl 0x8(%rax), %eax
movl %eax, %edx
leaq -0x88(%rbp), %rdi
callq 0x5ed0
movq -0x278(%rbp), %rdi
movups -0x88(%rbp), %xmm0
movaps %xmm0, -0x70(%rbp)
movq -0x70(%rbp), %rcx
movq -0x68(%rbp), %rax
movq %rcx, -0x178(%rbp)
movq %rax, -0x170(%rbp)
movq -0x178(%rbp), %rsi
movq -0x170(%rbp), %rdx
callq 0x1d5f0
movq -0x278(%rbp), %rdi
movq -0x118(%rbp), %rax
movq 0x8(%rax), %rcx
movq %rcx, -0x188(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x180(%rbp)
movq -0x188(%rbp), %rsi
movq -0x180(%rbp), %rdx
callq 0x1d5f0
movq -0x108(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x108(%rbp)
jmp 0x44f1b
movq -0x278(%rbp), %rdi
callq 0x6290
movq %rax, -0x190(%rbp)
movq $0x0, -0x198(%rbp)
movq -0x268(%rbp), %rdi
movq -0x198(%rbp), %rax
movq %rax, -0x2b8(%rbp)
callq 0x27270
movq %rax, %rcx
movq -0x2b8(%rbp), %rax
cmpq %rcx, %rax
jae 0x4577a
movq -0x268(%rbp), %rdi
addq $0x10, %rdi
movq -0x198(%rbp), %rsi
callq 0x459e0
movq %rax, -0x1a0(%rbp)
leaq -0x1ce(%rbp), %rdi
movl $0x2014b50, %esi        # imm = 0x2014B50
callq 0x45b80
leaq -0x1ce(%rbp), %rdi
addq $0x4, %rdi
movl $0x3f, %esi
callq 0x45bb0
leaq -0x1ce(%rbp), %rax
addq $0x6, %rax
movq %rax, -0x2e0(%rbp)
movq -0x1a0(%rbp), %rdi
callq 0x44980
movq -0x2e0(%rbp), %rdi
movzwl %ax, %esi
callq 0x45bb0
movq -0x268(%rbp), %rdi
leaq -0x1ce(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x2d8(%rbp)
movq -0x198(%rbp), %rsi
callq 0x276f0
movq (%rax), %rcx
movq %rcx, -0x1e0(%rbp)
movq 0x8(%rax), %rax
movq %rax, -0x1d8(%rbp)
movq -0x1e0(%rbp), %rdi
movq -0x1d8(%rbp), %rsi
callq 0x449b0
movq -0x2d8(%rbp), %rdi
movb %al, %dl
movl $0x800, %eax            # imm = 0x800
xorl %ecx, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movzwl %ax, %esi
callq 0x45bb0
leaq -0x1ce(%rbp), %rdi
addq $0xa, %rdi
movq -0x1a0(%rbp), %rax
movzwl 0x4(%rax), %esi
callq 0x45bb0
leaq -0x1ce(%rbp), %rdi
addq $0xc, %rdi
movq -0x1a0(%rbp), %rax
movl 0x1c(%rax), %esi
callq 0x45b80
leaq -0x1ce(%rbp), %rdi
addq $0x10, %rdi
movq -0x1a0(%rbp), %rax
movl 0x18(%rax), %esi
callq 0x45b80
leaq -0x1ce(%rbp), %rax
addq $0x14, %rax
movq %rax, -0x2d0(%rbp)
movq -0x1a0(%rbp), %rdi
addq $0x8, %rdi
callq 0x6290
movq -0x2d0(%rbp), %rdi
movl %eax, %esi
callq 0x45b80
leaq -0x1ce(%rbp), %rdi
addq $0x18, %rdi
movq -0x1a0(%rbp), %rax
movl (%rax), %esi
callq 0x45b80
movq -0x268(%rbp), %rdi
leaq -0x1ce(%rbp), %rax
addq $0x1c, %rax
movq %rax, -0x2c8(%rbp)
movq -0x198(%rbp), %rsi
callq 0x276f0
movq %rax, -0xd8(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0x2c0(%rbp)
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
cmpl $0x0, %eax
jl 0x4551b
movq -0x2c0(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
xorl $0xf, %eax
movzbl %al, %eax
movl %eax, -0xcc(%rbp)
jmp 0x4552b
movq -0x2c0(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0xcc(%rbp)
movq -0x2c8(%rbp), %rdi
movl -0xcc(%rbp), %eax
movzwl %ax, %esi
callq 0x45bb0
leaq -0x1ce(%rbp), %rdi
addq $0x1e, %rdi
xorl %esi, %esi
callq 0x45bb0
leaq -0x1ce(%rbp), %rdi
addq $0x20, %rdi
xorl %esi, %esi
callq 0x45bb0
leaq -0x1ce(%rbp), %rdi
addq $0x22, %rdi
xorl %esi, %esi
callq 0x45bb0
leaq -0x1ce(%rbp), %rdi
addq $0x24, %rdi
xorl %esi, %esi
callq 0x45bb0
movq -0x268(%rbp), %rdi
leaq -0x1ce(%rbp), %rax
addq $0x26, %rax
movq %rax, -0x2f8(%rbp)
movq -0x198(%rbp), %rsi
callq 0x276f0
movq %rax, -0x300(%rbp)
leaq -0x1f0(%rbp), %rdi
leaq 0x1ea18(%rip), %rsi     # 0x63fda
callq 0x58c0
movq -0x300(%rbp), %rdi
movq -0x1f0(%rbp), %rsi
movq -0x1e8(%rbp), %rdx
callq 0x38070
movq -0x2f8(%rbp), %rdi
movb %al, %cl
xorl %esi, %esi
movl $0x10, %eax
testb $0x1, %cl
cmovnel %eax, %esi
callq 0x45b80
leaq -0x1ce(%rbp), %rax
addq $0x2a, %rax
movq %rax, -0x2f0(%rbp)
movq -0x198(%rbp), %rsi
leaq -0x100(%rbp), %rdi
callq 0x231d0
movq -0x2f0(%rbp), %rdi
movq (%rax), %rax
movl %eax, %esi
callq 0x45b80
leaq -0x200(%rbp), %rdi
leaq -0x1ce(%rbp), %rsi
movl $0x2e, %edx
callq 0x5d70
movq -0x278(%rbp), %rdi
movq -0x200(%rbp), %rax
movq %rax, -0x210(%rbp)
movq -0x1f8(%rbp), %rax
movq %rax, -0x208(%rbp)
movq -0x210(%rbp), %rsi
movq -0x208(%rbp), %rdx
callq 0x1d5f0
movq -0x268(%rbp), %rdi
movq -0x198(%rbp), %rsi
callq 0x276f0
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
leaq -0xb8(%rbp), %rcx
movq %rcx, -0x48(%rbp)
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x2e8(%rbp)
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
callq 0x5cc0
movsbl %al, %eax
cmpl $0x0, %eax
jl 0x45704
movq -0x2e8(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
callq 0x5cc0
movq -0x2e8(%rbp), %rsi
movsbl %al, %eax
xorl $0xf, %eax
movzbl %al, %eax
movl %eax, %edx
leaq -0xb8(%rbp), %rdi
callq 0x5ed0
jmp 0x4571f
movq -0x2e8(%rbp), %rax
movq (%rax), %rsi
movl 0x8(%rax), %eax
movl %eax, %edx
leaq -0xb8(%rbp), %rdi
callq 0x5ed0
movq -0x278(%rbp), %rdi
movups -0xb8(%rbp), %xmm0
movaps %xmm0, -0xa0(%rbp)
movq -0xa0(%rbp), %rcx
movq -0x98(%rbp), %rax
movq %rcx, -0x220(%rbp)
movq %rax, -0x218(%rbp)
movq -0x220(%rbp), %rsi
movq -0x218(%rbp), %rdx
callq 0x1d5f0
movq -0x198(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x198(%rbp)
jmp 0x45306
movq -0x278(%rbp), %rdi
callq 0x6290
movq %rax, -0x228(%rbp)
leaq -0x23e(%rbp), %rdi
movl $0x6054b50, %esi        # imm = 0x6054B50
callq 0x45b80
leaq -0x23e(%rbp), %rdi
addq $0x4, %rdi
xorl %esi, %esi
callq 0x45bb0
leaq -0x23e(%rbp), %rdi
addq $0x6, %rdi
xorl %esi, %esi
callq 0x45bb0
movq -0x268(%rbp), %rdi
leaq -0x23e(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x310(%rbp)
callq 0x27270
movq -0x310(%rbp), %rdi
movzwl %ax, %esi
callq 0x45bb0
movq -0x268(%rbp), %rdi
leaq -0x23e(%rbp), %rax
addq $0xa, %rax
movq %rax, -0x308(%rbp)
callq 0x27270
movq -0x308(%rbp), %rdi
movzwl %ax, %esi
callq 0x45bb0
leaq -0x23e(%rbp), %rdi
addq $0xc, %rdi
movq -0x228(%rbp), %rax
subq -0x190(%rbp), %rax
movl %eax, %esi
callq 0x45b80
leaq -0x23e(%rbp), %rdi
addq $0x10, %rdi
movq -0x190(%rbp), %rax
movl %eax, %esi
callq 0x45b80
leaq -0x23e(%rbp), %rdi
addq $0x14, %rdi
xorl %esi, %esi
callq 0x45bb0
leaq -0x250(%rbp), %rdi
leaq -0x23e(%rbp), %rsi
movl $0x16, %edx
callq 0x5d70
movq -0x278(%rbp), %rdi
movq -0x250(%rbp), %rax
movq %rax, -0x260(%rbp)
movq -0x248(%rbp), %rax
movq %rax, -0x258(%rbp)
movq -0x260(%rbp), %rsi
movq -0x258(%rbp), %rdx
callq 0x1d5f0
movb $0x1, -0xe9(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x23c00
testb $0x1, -0xe9(%rbp)
jne 0x458dd
movq -0x278(%rbp), %rdi
callq 0x1d720
movq -0x270(%rbp), %rax
addq $0x310, %rsp            # imm = 0x310
popq %rbp
retq
nopl (%rax)