// File: /workspace/github_c_makefile_star2_O2/jsummers[P]deark/modules/zip.c
// Function: ef_infozipmac
static void ef_infozipmac(deark *c, lctx *d, struct extra_item_info_struct *eii)
{
	i64 pos = eii->dpos;
	i64 dpos;
	i64 ulen;
	i64 cmpr_attr_size;
	UI flags;
	int cmpr_meth;
	const struct cmpr_meth_info *cmi = NULL;
	struct de_fourcc filetype;
	struct de_fourcc creator;
	de_ucstring *flags_str = NULL;
	dbuf *attr_data = NULL;
	int ret;
	i64 create_time_raw;
	i64 create_time_offset;
	i64 mod_time_raw;
	i64 mod_time_offset;
	i64 backup_time_raw;
	i64 backup_time_offset;
	struct de_timestamp tmp_timestamp;
	int charset;
	u32 crc_reported = 0;
	UI dcflags = 0;
	struct de_stringreaderdata *srd;

	if(eii->dlen<14) goto done;

	ulen = de_getu32le_p(&pos);
	de_dbg(c, "uncmpr. finder attr. size: %d", (int)ulen);

	flags = (UI)de_getu16le_p(&pos);
	flags_str = ucstring_create(c);
	if(flags&0x0001) ucstring_append_flags_item(flags_str, "data_fork");
	if(flags&0x0002) ucstring_append_flags_item(flags_str, "0x0002"); // something about the filename
	ucstring_append_flags_item(flags_str,
		(flags&0x0004)?"uncmpressed_attribute_data":"compressed_attribute_data");
	if(flags&0x0008) ucstring_append_flags_item(flags_str, "64-bit_times");
	if(flags&0x0010) ucstring_append_flags_item(flags_str, "no_timezone_offsets");
	de_dbg(c, "flags: 0x%04x (%s)", flags, ucstring_getpsz(flags_str));

	dbuf_read_fourcc(c->infile, pos, &filetype, 4, 0x0);
	de_dbg(c, "filetype: '%s'", filetype.id_dbgstr);
	pos += 4;
	dbuf_read_fourcc(c->infile, pos, &creator, 4, 0x0);
	de_dbg(c, "creator: '%s'", creator.id_dbgstr);
	pos += 4;

	if(eii->is_central) goto done;

	if(flags&0x0004) { // Uncompressed attribute data
		cmpr_meth = 0;
	}
	else {
		dcflags |= 0x1; // CRC is known
		cmpr_meth = (int)de_getu16le_p(&pos);
		cmi = get_cmpr_meth_info(cmpr_meth);
		de_dbg(c, "finder attr. cmpr. method: %d (%s)", cmpr_meth, (cmi ? cmi->name : "?"));

		crc_reported = (u32)de_getu32le_p(&pos);
		de_dbg(c, "finder attr. data crc (reported): 0x%08x", (UI)crc_reported);
	}

	// The rest of the data is Finder attribute data
	cmpr_attr_size = eii->dpos+eii->dlen - pos;
	de_dbg(c, "cmpr. finder attr. size: %d", (int)cmpr_attr_size);
	if(ulen<1 || ulen>1000000) goto done;

	// Type 6 (implode) compression won't work here, because it needs
	// additional parameters seemingly not provided by the Finder attr data.
	if(cmpr_meth==6 || !is_compression_method_supported(d, cmi)) {
		de_warn(c, "Finder attribute data: Unsupported compression method: %d (%s)",
			cmpr_meth, (cmi ? cmi->name : "?"));
		goto done;
	}

	// Decompress and decode the Finder attribute data
	attr_data = dbuf_create_membuf(c, ulen, 0x1);
	ret = do_decompress_attrib_data(c, d, pos, cmpr_attr_size,
		attr_data, ulen, crc_reported, cmpr_meth, cmi, dcflags, "finder attr. data");
	if(!ret) {
		de_warn(c, "Failed to decompress finder attribute data");
		goto done;
	}

	dpos = 0;
	dpos += 2; // Finder flags
	dpos += 4; // Icon location
	dpos += 2; // Folder
	dpos += 16; // FXInfo
	dpos += 1; // file version number
	dpos += 1; // dir access rights

	if(flags&0x0008) goto done; // We don't support 64-bit times
	if(flags&0x0010) goto done; // We want timezone offsets
	if(attr_data->len - dpos < 6*4) goto done;

	create_time_raw = dbuf_getu32le_p(attr_data, &dpos);
	mod_time_raw    = dbuf_getu32le_p(attr_data, &dpos);
	backup_time_raw = dbuf_getu32le_p(attr_data, &dpos);
	create_time_offset = dbuf_geti32le(attr_data, dpos); dpos += 4;
	mod_time_offset    = dbuf_geti32le(attr_data, dpos); dpos += 4;
	backup_time_offset = dbuf_geti32le(attr_data, dpos); dpos += 4;

	handle_mac_time(c, d, create_time_raw, create_time_offset, &tmp_timestamp, "create time");
	if(create_time_raw>0) {
		apply_timestamp(c, d, eii->md, DE_TIMESTAMPIDX_CREATE, &tmp_timestamp, 40);
	}
	handle_mac_time(c, d, mod_time_raw,    mod_time_offset,    &tmp_timestamp, "mod time   ");
	if(mod_time_raw>0) {
		apply_timestamp(c, d, eii->md, DE_TIMESTAMPIDX_MODIFY, &tmp_timestamp, 40);
	}
	handle_mac_time(c, d, backup_time_raw, backup_time_offset, &tmp_timestamp, "backup time");
	if(backup_time_raw>0) {
		apply_timestamp(c, d, eii->md, DE_TIMESTAMPIDX_BACKUP, &tmp_timestamp, 40);
	}

	// Expecting 2 bytes for charset, and at least 2 more for the 2 NUL-terminated
	// strings that follow.
	if(attr_data->len - dpos < 4) goto done;

	charset = (int)dbuf_getu16le_p(attr_data, &dpos);
	de_dbg(c, "charset for fullpath/comment: %d", charset);

	// TODO: Can we use the correct encoding?
	srd = dbuf_read_string(attr_data, dpos, attr_data->len-dpos, DE_DBG_MAX_STRLEN,
		DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII);
	de_dbg(c, "fullpath: \"%s\"", ucstring_getpsz(srd->str));
	dpos += srd->bytes_consumed;
	de_destroy_stringreaderdata(c, srd);

	srd = dbuf_read_string(attr_data, dpos, attr_data->len-dpos, DE_DBG_MAX_STRLEN,
		DE_CONVFLAG_STOP_AT_NUL, DE_ENCODING_ASCII);
	de_dbg(c, "comment: \"%s\"", ucstring_getpsz(srd->str));
	dpos += srd->bytes_consumed;
	de_destroy_stringreaderdata(c, srd);

done:
	ucstring_destroy(flags_str);
	dbuf_close(attr_data);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq 0x8(%rdx), %rax
movq %rax, 0x8(%rsp)
cmpq $0xe, 0x10(%rdx)
jge 0xd5865
xorl %r12d, %r12d
xorl %ebx, %ebx
jmp 0xd5dba
movq %rdx, %r15
movq %rsi, %r13
movq %rdi, %r14
movq 0x18(%rdi), %rdi
leaq 0x8(%rsp), %rbx
movq %rbx, %rsi
callq 0xe40bf
leaq 0x614d5(%rip), %rsi     # 0x136d5b
movq %r14, %rdi
movq %rax, 0x20(%rsp)
movl %eax, %edx
xorl %eax, %eax
callq 0xde896
movq 0x18(%r14), %rdi
movq %rbx, %rsi
callq 0xe3fc4
movq %rax, %rbp
movq %r14, %rdi
callq 0xeac74
movq %rax, %rbx
testb $0x1, %bpl
je 0xd58c6
leaq 0x614bb(%rip), %rsi     # 0x136d79
movq %rbx, %rdi
callq 0xeb884
testb $0x2, %bpl
je 0xd58db
leaq 0x614b0(%rip), %rsi     # 0x136d83
movq %rbx, %rdi
callq 0xeb884
testb $0x4, %bpl
leaq 0x614bf(%rip), %rax     # 0x136da5
leaq 0x6149d(%rip), %rsi     # 0x136d8a
cmoveq %rax, %rsi
movq %rbx, %rdi
callq 0xeb884
testb $0x8, %bpl
je 0xd590e
leaq 0x614b9(%rip), %rsi     # 0x136dbf
movq %rbx, %rdi
callq 0xeb884
testb $0x10, %bpl
je 0xd5923
leaq 0x614b1(%rip), %rsi     # 0x136dcc
movq %rbx, %rdi
callq 0xeb884
movq %rbx, %rdi
callq 0xeb7e4
leaq 0x625dc(%rip), %rsi     # 0x137f0e
movq %r14, %rdi
movl %ebp, %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0xde896
movq 0x18(%r14), %rdi
movq 0x8(%rsp), %rsi
leaq 0x88(%rsp), %rdx
pushq $0x4
popq %r12
movl %r12d, %ecx
xorl %r8d, %r8d
callq 0xe657c
leaq 0x98(%rsp), %rdx
leaq 0x31f40(%rip), %rsi     # 0x1078b0
movq %r14, %rdi
xorl %eax, %eax
callq 0xde896
movq 0x8(%rsp), %rsi
addq $0x4, %rsi
movq %rsi, 0x8(%rsp)
movq 0x18(%r14), %rdi
leaq 0x58(%rsp), %rdx
movl %r12d, %ecx
xorl %r8d, %r8d
callq 0xe657c
leaq 0x68(%rsp), %rdx
leaq 0x5166b(%rip), %rsi     # 0x127013
movq %r14, %rdi
xorl %eax, %eax
callq 0xde896
movq 0x8(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x8(%rsp)
cmpl $0x0, 0x30(%r15)
je 0xd59cf
xorl %r12d, %r12d
jmp 0xd5dba
movq $0x0, 0x28(%rsp)
testb $0x4, %bpl
movq %r13, 0x40(%rsp)
jne 0xd5a0d
movq 0x18(%r14), %rdi
leaq 0x8(%rsp), %rsi
callq 0xe3fc4
movq %rax, 0x18(%rsp)
movl %eax, %edi
callq 0xd4ec7
testq %rax, %rax
movq %rax, 0x10(%rsp)
je 0xd5a2a
movq 0x8(%rax), %rcx
jmp 0xd5a31
movq $0x0, 0x10(%rsp)
movq $0x0, 0x50(%rsp)
movq $0x0, 0x18(%rsp)
jmp 0xd5a7c
leaq 0x494b0(%rip), %rcx     # 0x11eee1
pushq $0x1
popq %rax
movq %rax, 0x50(%rsp)
leaq 0x613a0(%rip), %rsi     # 0x136de0
movq %r14, %rdi
movq 0x18(%rsp), %rdx
xorl %eax, %eax
callq 0xde896
movq 0x18(%r14), %rdi
leaq 0x8(%rsp), %r12
movq %r12, %rsi
callq 0xe40bf
leaq 0x6139c(%rip), %rsi     # 0x136e03
movq %r14, %rdi
movq %rax, 0x28(%rsp)
movl %eax, %edx
xorl %eax, %eax
callq 0xde896
movq (%r12), %rax
movq 0x10(%r15), %r13
addq 0x8(%r15), %r13
subq %rax, %r13
leaq 0x612cf(%rip), %rsi     # 0x136d5d
xorl %r12d, %r12d
movq %r14, %rdi
movl %r13d, %edx
xorl %eax, %eax
callq 0xde896
movq 0x20(%rsp), %rax
addq $-0xf4241, %rax         # imm = 0xFFF0BDBF
cmpq $-0xf4240, %rax         # imm = 0xFFF0BDC0
jb 0xd5dba
cmpl $0x6, 0x18(%rsp)
jne 0xd5acf
movq 0x10(%rsp), %rax
testq %rax, %rax
jne 0xd5d94
jmp 0xd5d9a
movq 0x10(%rsp), %rax
testq %rax, %rax
je 0xd5d9a
cmpq $0x0, 0x10(%rax)
je 0xd5d94
pushq $0x1
popq %rdx
movq %r14, %rdi
movq 0x20(%rsp), %rsi
movq %rax, 0x10(%rsp)
callq 0xe59cd
movq %rax, %r12
movq 0x8(%rsp), %rdx
subq $0x8, %rsp
leaq 0x6135b(%rip), %rax     # 0x136e6b
movq %r14, %rdi
movq 0x48(%rsp), %rsi
movq %r13, %rcx
movq %r12, %r8
movq 0x28(%rsp), %r9
pushq %rax
pushq 0x60(%rsp)
pushq 0x28(%rsp)
pushq 0x38(%rsp)
pushq 0x50(%rsp)
callq 0xd6409
addq $0x30, %rsp
testl %eax, %eax
je 0xd5ddc
movq $0x1a, 0x48(%rsp)
testb $0x18, %bpl
jne 0xd5dba
cmpq $0x32, 0x18(%r12)
jl 0xd5dba
leaq 0x48(%rsp), %rbp
movq %r12, %rdi
movq %rbp, %rsi
callq 0xe40bf
movq %rax, %r13
movq %r12, %rdi
movq %rbp, %rsi
callq 0xe40bf
movq %rax, 0x18(%rsp)
movq %r12, %rdi
movq %rbp, %rsi
callq 0xe40bf
movq %rax, 0x20(%rsp)
movq (%rbp), %rsi
movq %r12, %rdi
callq 0xe40f2
movq %rax, 0x40(%rsp)
movq (%rbp), %rsi
addq $0x4, %rsi
movq %rsi, (%rbp)
movq %r12, %rdi
callq 0xe40f2
movq %rax, 0x28(%rsp)
movq (%rbp), %rsi
addq $0x4, %rsi
movq %rsi, (%rbp)
movq %r12, %rdi
callq 0xe40f2
movq %rax, 0x10(%rsp)
addq $0x4, (%rbp)
leaq 0x4c5b2(%rip), %r8      # 0x122198
leaq 0x30(%rsp), %rcx
movq %r14, %rdi
movq %r13, %rsi
movq 0x40(%rsp), %rdx
callq 0xd6609
testq %r13, %r13
jle 0xd5c21
cmpb $0x0, 0x30(%rsp)
je 0xd5c21
movq 0x20(%r15), %rax
cmpl $0x28, 0x70(%rax)
jg 0xd5c21
movups 0x30(%rsp), %xmm0
movups %xmm0, 0x60(%rax)
movl $0x28, 0x70(%rax)
leaq 0x494f4(%rip), %r8      # 0x11f11c
leaq 0x30(%rsp), %rcx
movq %r14, %rdi
movq 0x18(%rsp), %r13
movq %r13, %rsi
movq 0x28(%rsp), %rdx
callq 0xd6609
testq %r13, %r13
jle 0xd5c68
cmpb $0x0, 0x30(%rsp)
je 0xd5c68
movq 0x20(%r15), %rax
cmpl $0x28, 0x58(%rax)
jg 0xd5c68
movups 0x30(%rsp), %xmm0
movups %xmm0, 0x48(%rax)
movl $0x28, 0x58(%rax)
leaq 0x61239(%rip), %r8      # 0x136ea8
leaq 0x30(%rsp), %rcx
movq %r14, %rdi
movq 0x20(%rsp), %r13
movq %r13, %rsi
movq 0x10(%rsp), %rdx
callq 0xd6609
testq %r13, %r13
jle 0xd5cb8
cmpb $0x0, 0x30(%rsp)
je 0xd5cb8
movq 0x20(%r15), %rax
cmpl $0x28, 0xb8(%rax)
jg 0xd5cb8
movups 0x30(%rsp), %xmm0
movups %xmm0, 0xa8(%rax)
movl $0x28, 0xb8(%rax)
movq 0x18(%r12), %rax
subq 0x48(%rsp), %rax
cmpq $0x4, %rax
jl 0xd5dba
leaq 0x48(%rsp), %r15
movq %r12, %rdi
movq %r15, %rsi
callq 0xe3fc4
leaq 0x611d1(%rip), %rsi     # 0x136eb4
movq %r14, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0xde896
movq (%r15), %rsi
movq 0x18(%r12), %rdx
subq %rsi, %rdx
pushq $0x1
popq %rbp
movl $0x1f4, %ecx            # imm = 0x1F4
movq %r12, %rdi
movl %ebp, %r8d
movl %ebp, %r9d
callq 0xe495c
movq %rax, %r13
movq 0x18(%rax), %rdi
callq 0xeb7e4
leaq 0x611b2(%rip), %rsi     # 0x136ed5
movq %r14, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0xde896
movq (%r13), %rax
addq %rax, (%r15)
movq %r14, %rdi
movq %r13, %rsi
callq 0xe4b94
movq (%r15), %rsi
movq 0x18(%r12), %rdx
subq %rsi, %rdx
movl $0x1f4, %ecx            # imm = 0x1F4
movq %r12, %rdi
movl %ebp, %r8d
movl %ebp, %r9d
callq 0xe495c
movq %rax, %r13
movq 0x18(%rax), %rdi
callq 0xeb7e4
leaq 0x31a82(%rip), %rsi     # 0x1077f5
movq %r14, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0xde896
movq (%r13), %rax
addq %rax, (%r15)
movq %r14, %rdi
movq %r13, %rsi
callq 0xe4b94
jmp 0xd5dba
movq 0x8(%rax), %rcx
jmp 0xd5da1
leaq 0x49140(%rip), %rcx     # 0x11eee1
leaq 0x61084(%rip), %rsi     # 0x136e2c
xorl %r12d, %r12d
movq %r14, %rdi
movq 0x18(%rsp), %rdx
xorl %eax, %eax
callq 0xdf05a
movq %rbx, %rdi
callq 0xeaf3c
movq %r12, %rdi
callq 0xe5591
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x6109a(%rip), %rsi     # 0x136e7d
movq %r14, %rdi
xorl %eax, %eax
callq 0xdf05a
jmp 0xd5dba