// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/src/fmtutil-advfile.c
// Function: de_advfile_run_macbinary
static void de_advfile_run_macbinary(deark *c, struct de_advfile *advf)
{
	struct de_advfile_cbparams *afp_main = NULL;
	struct de_advfile_cbparams *afp_rsrc = NULL;
	dbuf *outf = NULL;
	de_ucstring *fname = NULL;
	i64 main_amt_padding;
	//i64 rsrc_amt_padding;
	i64 main_fork_len, rsrc_fork_len;
	dbuf *hdr = NULL;
	struct de_crcobj *crco = NULL;
	u32 crc_calc;

	if(advf->mainfork.fork_exists) {
		main_fork_len = advf->mainfork.fork_len;
	}
	else {
		main_fork_len = 0;
	}
	if(advf->rsrcfork.fork_exists) {
		rsrc_fork_len = advf->rsrcfork.fork_len;
	}
	else {
		rsrc_fork_len = 0;
	}

	if(main_fork_len>0xffffffffLL || rsrc_fork_len>0xffffffffLL) {
		de_err(c, "File too large to write to MacBinary format");
		goto done;
	}

	main_amt_padding = advf->mainfork.fork_len % 128;
	if(main_amt_padding > 0) main_amt_padding = 128-main_amt_padding;
	//rsrc_amt_padding = advf->rsrcfork.fork_len % 128;
	//if(rsrc_amt_padding > 0) rsrc_amt_padding = 128-rsrc_amt_padding;

	fname = ucstring_create(c);
	ucstring_append_ucstring(fname, advf->filename);
	if(fname->len<1) {
		ucstring_append_sz(fname, "_", DE_ENCODING_LATIN1);
	}
	ucstring_append_sz(fname, ".bin", DE_ENCODING_LATIN1);
	de_finfo_set_name_from_ucstring(c, advf->mainfork.fi, fname, advf->snflags);
	advf->mainfork.fi->original_filename_flag = advf->original_filename_flag;

	// Construct 128-byte header
	hdr = dbuf_create_membuf(c, 128, 0);
	dbuf_writebyte(hdr, 0);

	// Filename
	if(advf->orig_filename && advf->orig_filename_len>0) {
		i64 fnlen = advf->orig_filename_len;

		if(fnlen>63) fnlen=63;
		dbuf_writebyte(hdr, (u8)fnlen);
		dbuf_write(hdr, advf->orig_filename, fnlen);
	}
	else {
		// TODO: Get the name from elsewhere?
		dbuf_writebyte(hdr, 7);
		dbuf_puts(hdr, "Unnamed");
	}
	dbuf_truncate(hdr, 65);

	// type/creator
	if(advf->has_typecode) {
		dbuf_write(hdr, advf->typecode, 4);
	}
	dbuf_truncate(hdr, 69);
	if(advf->has_creatorcode) {
		dbuf_write(hdr, advf->creatorcode, 4);
	}

	dbuf_truncate(hdr, 73); // high byte of finder flags
	if(advf->has_finderflags) {
		dbuf_writebyte(hdr, (u8)(advf->finderflags >> 8));
	}

	dbuf_truncate(hdr, 83);
	dbuf_writeu32be(hdr, main_fork_len);
	dbuf_writeu32be(hdr, rsrc_fork_len);

	dbuf_truncate(hdr, 91);
	dbuf_writeu32be(hdr, timestamp_to_mac_time(&advf->mainfork.fi->timestamp[DE_TIMESTAMPIDX_CREATE]));
	dbuf_writeu32be(hdr, timestamp_to_mac_time(&advf->mainfork.fi->timestamp[DE_TIMESTAMPIDX_MODIFY]));

	dbuf_truncate(hdr, 101); // low byte of finder flags
	if(advf->has_finderflags) {
		dbuf_writebyte(hdr, (u8)(advf->finderflags & 0xff));
	}

	dbuf_truncate(hdr, 102);
	dbuf_write(hdr, (const u8*)"mBIN", 4);

	dbuf_truncate(hdr, 122);
	dbuf_writebyte(hdr, 130); // version (III)
	dbuf_writebyte(hdr, 129); // compatible version (II)

	crco = de_crcobj_create(c, DE_CRCOBJ_CRC16_XMODEM);
	de_crcobj_addslice(crco, hdr, 0, 124);
	crc_calc = de_crcobj_getval(crco);
	dbuf_writeu16be(hdr, (i64)crc_calc);

	dbuf_truncate(hdr, 128);
	outf = dbuf_create_output_file(c, NULL, advf->mainfork.fi, advf->createflags);
	if(advf->enable_wbuffer) dbuf_enable_wbuffer(outf);
	dbuf_copy(hdr, 0, 128, outf);

	afp_main = de_malloc(c, sizeof(struct de_advfile_cbparams));
	afp_rsrc = de_malloc(c, sizeof(struct de_advfile_cbparams));
	afp_main->whattodo = DE_ADVFILE_WRITEMAIN;
	afp_rsrc->whattodo = DE_ADVFILE_WRITERSRC;

	dbuf_set_writelistener(outf, advf->mainfork.writelistener_cb,
		advf->mainfork.userdata_for_writelistener);
	afp_main->outf = outf;
	if(advf->writefork_cbfn && main_fork_len>0) {
		advf->writefork_cbfn(c, advf, afp_main);
	}
	dbuf_set_writelistener(outf, NULL, NULL);
	dbuf_write_zeroes(outf, main_amt_padding);

	dbuf_set_writelistener(outf, advf->rsrcfork.writelistener_cb,
		advf->rsrcfork.userdata_for_writelistener);
	afp_rsrc->outf = outf;
	if(advf->writefork_cbfn && rsrc_fork_len>0) {
		advf->writefork_cbfn(c, advf, afp_rsrc);
	}
	dbuf_set_writelistener(outf, NULL, NULL);

done:
	dbuf_close(hdr);
	dbuf_close(outf);
	de_free(c, afp_main);
	de_free(c, afp_rsrc);
	ucstring_destroy(fname);
	de_crcobj_destroy(crco);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq $0x0, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x50(%rbp)
movq $0x0, -0x58(%rbp)
movq -0x10(%rbp), %rax
cmpb $0x0, 0x10(%rax)
je 0x17ba3b
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x17ba43
movq $0x0, -0x40(%rbp)
movq -0x10(%rbp), %rax
cmpb $0x0, 0x38(%rax)
je 0x17ba5b
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x17ba63
movq $0x0, -0x48(%rbp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq %rax, -0x40(%rbp)
jg 0x17ba79
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq %rax, -0x48(%rbp)
jle 0x17ba90
movq -0x8(%rbp), %rdi
leaq 0x5aeb1(%rip), %rsi     # 0x1d6935
movb $0x0, %al
callq 0x15bfb0
jmp 0x17bf07
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movl $0x80, %ecx
cqto
idivq %rcx
movq %rdx, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jle 0x17baba
movl $0x80, %eax
subq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
callq 0x1711d0
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x68(%rax), %rsi
callq 0x171460
movq -0x30(%rbp), %rax
cmpq $0x1, 0x10(%rax)
jge 0x17baf8
movq -0x30(%rbp), %rdi
leaq 0x3af18(%rip), %rsi     # 0x1b6a06
movl $0x5, %edx
callq 0x1715e0
movq -0x30(%rbp), %rdi
leaq 0x45703(%rip), %rsi     # 0x1c1206
movl $0x5, %edx
callq 0x1715e0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rsi
movq -0x30(%rbp), %rdx
movq -0x10(%rbp), %rax
movl 0x70(%rax), %ecx
callq 0x15d2c0
movq -0x10(%rbp), %rax
movb 0x79(%rax), %cl
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movb %cl, 0x8(%rax)
movq -0x8(%rbp), %rdi
movl $0x80, %esi
xorl %edx, %edx
callq 0x168020
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
xorl %esi, %esi
callq 0x168380
movq -0x10(%rbp), %rax
cmpq $0x0, 0x88(%rax)
je 0x17bbbe
movq -0x10(%rbp), %rax
cmpq $0x0, 0x80(%rax)
jbe 0x17bbbe
movq -0x10(%rbp), %rax
movq 0x80(%rax), %rax
movq %rax, -0x68(%rbp)
cmpq $0x3f, -0x68(%rbp)
jle 0x17bb94
movq $0x3f, -0x68(%rbp)
movq -0x50(%rbp), %rdi
movq -0x68(%rbp), %rax
movzbl %al, %esi
callq 0x168380
movq -0x50(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x88(%rax), %rsi
movq -0x68(%rbp), %rdx
callq 0x166170
jmp 0x17bbdc
movq -0x50(%rbp), %rdi
movl $0x7, %esi
callq 0x168380
movq -0x50(%rbp), %rdi
leaq 0x5ad8a(%rip), %rsi     # 0x1d6961
callq 0x168da0
movq -0x50(%rbp), %rdi
movl $0x41, %esi
callq 0x168900
movq -0x10(%rbp), %rax
cmpb $0x0, 0x7b(%rax)
je 0x17bc0d
movq -0x50(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x90, %rsi
movl $0x4, %edx
callq 0x166170
movq -0x50(%rbp), %rdi
movl $0x45, %esi
callq 0x168900
movq -0x10(%rbp), %rax
cmpb $0x0, 0x7c(%rax)
je 0x17bc3e
movq -0x50(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x94, %rsi
movl $0x4, %edx
callq 0x166170
movq -0x50(%rbp), %rdi
movl $0x49, %esi
callq 0x168900
movq -0x10(%rbp), %rax
cmpb $0x0, 0x7d(%rax)
je 0x17bc6d
movq -0x50(%rbp), %rdi
movq -0x10(%rbp), %rax
movzwl 0x7e(%rax), %eax
sarl $0x8, %eax
movzbl %al, %esi
callq 0x168380
movq -0x50(%rbp), %rdi
movl $0x53, %esi
callq 0x168900
movq -0x50(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x168b80
movq -0x50(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x168b80
movq -0x50(%rbp), %rdi
movl $0x5b, %esi
callq 0x168900
movq -0x50(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
addq $0x18, %rdi
addq $0x10, %rdi
callq 0x17c0d0
movq -0x78(%rbp), %rdi
movq %rax, %rsi
callq 0x168b80
movq -0x50(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
addq $0x18, %rdi
callq 0x17c0d0
movq -0x70(%rbp), %rdi
movq %rax, %rsi
callq 0x168b80
movq -0x50(%rbp), %rdi
movl $0x65, %esi
callq 0x168900
movq -0x10(%rbp), %rax
cmpb $0x0, 0x7d(%rax)
je 0x17bd22
movq -0x50(%rbp), %rdi
movq -0x10(%rbp), %rax
movzwl 0x7e(%rax), %eax
andl $0xff, %eax
movzbl %al, %esi
callq 0x168380
movq -0x50(%rbp), %rdi
movl $0x66, %esi
callq 0x168900
movq -0x50(%rbp), %rdi
leaq 0x3e8e4(%rip), %rsi     # 0x1ba61f
movl $0x4, %edx
callq 0x166170
movq -0x50(%rbp), %rdi
movl $0x7a, %esi
callq 0x168900
movq -0x50(%rbp), %rdi
movl $0x82, %esi
callq 0x168380
movq -0x50(%rbp), %rdi
movl $0x81, %esi
callq 0x168380
movq -0x8(%rbp), %rdi
movl $0x20, %esi
callq 0x15eac0
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
movq -0x50(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
movl $0x7c, %ecx
callq 0x15f500
movq -0x58(%rbp), %rdi
callq 0x15f340
movl %eax, -0x5c(%rbp)
movq -0x50(%rbp), %rdi
movl -0x5c(%rbp), %eax
movl %eax, %esi
callq 0x168a50
movq -0x50(%rbp), %rdi
movl $0x80, %esi
callq 0x168900
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdx
movq -0x10(%rbp), %rax
movl 0x74(%rax), %ecx
xorl %eax, %eax
movl %eax, %esi
callq 0x166c60
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
cmpb $0x0, 0x78(%rax)
je 0x17bdf2
movq -0x28(%rbp), %rdi
callq 0x167b90
movq -0x50(%rbp), %rdi
movq -0x28(%rbp), %rcx
xorl %eax, %eax
movl %eax, %esi
movl $0x80, %edx
callq 0x166070
movq -0x8(%rbp), %rdi
movl $0x10, %esi
callq 0x15b780
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movl $0x10, %esi
callq 0x15b780
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movl $0x1, (%rax)
movq -0x20(%rbp), %rax
movl $0x2, (%rax)
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdx
callq 0x169280
movq -0x28(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x60(%rax)
je 0x17be8d
cmpq $0x0, -0x40(%rbp)
jle 0x17be8d
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq *%rax
movq -0x28(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x169280
movq -0x28(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x1685f0
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rdx
callq 0x169280
movq -0x28(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x60(%rax)
je 0x17bef7
cmpq $0x0, -0x48(%rbp)
jle 0x17bef7
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq *%rax
movq -0x28(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x169280
movq -0x50(%rbp), %rdi
callq 0x1676a0
movq -0x28(%rbp), %rdi
callq 0x1676a0
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x15b820
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x15b820
movq -0x30(%rbp), %rdi
callq 0x171750
movq -0x58(%rbp), %rdi
callq 0x15f2e0
addq $0x80, %rsp
popq %rbp
retq
nop