// File: /workspace/github_c_makefile_star2_O3/jsummers[P]deark/src/fmtutil-advfile.c
// Function: de_advfile_run_applesd
static void de_advfile_run_applesd(deark *c, struct de_advfile *advf, int is_appledouble)
{
	de_ucstring *fname = NULL;
	struct de_advfile_cbparams *afp_main = NULL;
	struct de_advfile_cbparams *afp_rsrc = NULL;
	dbuf *outf = NULL;
	i64 cur_data_pos;
	size_t num_entries = 0;
	size_t k;
	char commentstr[80];
	size_t comment_strlen;
	struct applesd_entry entry_info[16];

	fname = ucstring_create(c);
	ucstring_append_ucstring(fname, advf->filename);
	if(fname->len<1) {
		ucstring_append_sz(fname, "_", DE_ENCODING_LATIN1);
	}
	if(is_appledouble) {
		// TODO: Consider using "._" prefix when writing to ZIP/tar
		ucstring_append_sz(fname, ".adf", DE_ENCODING_LATIN1);
	}
	else {
		ucstring_append_sz(fname, ".as", 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;
	outf = dbuf_create_output_file(c, NULL, advf->mainfork.fi, advf->createflags);
	if(advf->enable_wbuffer) dbuf_enable_wbuffer(outf);

	if(is_appledouble) { // signature
		dbuf_writeu32be(outf, 0x00051607U);
	}
	else {
		dbuf_writeu32be(outf, 0x00051600U);
	}
	dbuf_writeu32be(outf, 0x00020000U); // version
	dbuf_write_zeroes(outf, 16); // filler

	// Decide what entries we will write, and in what order, and their data length.

	de_snprintf(commentstr, sizeof(commentstr), "Apple%s container generated by Deark",
		is_appledouble?"Double":"Single");
	comment_strlen = de_strlen(commentstr);

	if(advf->orig_filename) {
		entry_info[num_entries].id = SDID_REALNAME;
		entry_info[num_entries].len = (i64)advf->orig_filename_len;
		num_entries++;
	}

	entry_info[num_entries].id = SDID_COMMENT;
	entry_info[num_entries].len = (i64)comment_strlen;
	num_entries++;

	if(advf->mainfork.fi->timestamp[DE_TIMESTAMPIDX_CREATE].is_valid ||
		advf->mainfork.fi->timestamp[DE_TIMESTAMPIDX_MODIFY].is_valid ||
		advf->mainfork.fi->timestamp[DE_TIMESTAMPIDX_BACKUP].is_valid ||
		advf->mainfork.fi->timestamp[DE_TIMESTAMPIDX_ACCESS].is_valid)
	{
		entry_info[num_entries].id = SDID_FILEDATES;
		entry_info[num_entries].len = 16;
		num_entries++;
	}
	if((advf->has_typecode || advf->has_creatorcode || advf->has_finderflags) &&
		!advf->mainfork.fi->is_directory)
	{
		entry_info[num_entries].id = SDID_FINDERINFO;
		entry_info[num_entries].len = 32;
		num_entries++;
	}
	if(advf->rsrcfork.fork_exists) {
		entry_info[num_entries].id = SDID_RESOURCEFORK;
		entry_info[num_entries].len = advf->rsrcfork.fork_len;
		num_entries++;
	};
	if(advf->mainfork.fork_exists && !is_appledouble) {
		entry_info[num_entries].id = SDID_DATAFORK;
		entry_info[num_entries].len = advf->mainfork.fork_len;
		num_entries++;
	};

	dbuf_writeu16be(outf, (i64)num_entries);

	// Figure out where the each data element will be written.
	cur_data_pos = 26 + 12*(i64)num_entries;
	for(k=0; k<num_entries; k++) {
		entry_info[k].offset = cur_data_pos;
		cur_data_pos += entry_info[k].len;
	};

	// Write the element table
	for(k=0; k<num_entries; k++) {
		dbuf_writeu32be(outf, (i64)entry_info[k].id);
		if(entry_info[k].offset>0xffffffffLL || entry_info[k].len>0xffffffffLL) {
			de_err(c, "File too large to write to AppleSingle/AppleDouble format");
			goto done;
		}
		dbuf_writeu32be(outf, entry_info[k].offset);
		dbuf_writeu32be(outf, entry_info[k].len);
	}

	// Write the elements' data
	for(k=0; k<num_entries; k++) {
		switch(entry_info[k].id) {
		case SDID_DATAFORK:
			afp_main = de_malloc(c, sizeof(struct de_advfile_cbparams));
			afp_main->whattodo = DE_ADVFILE_WRITEMAIN;
			dbuf_set_writelistener(outf, advf->mainfork.writelistener_cb,
				advf->mainfork.userdata_for_writelistener);
			afp_main->outf = outf;
			if(advf->writefork_cbfn && advf->mainfork.fork_len>0) {
				advf->writefork_cbfn(c, advf, afp_main);
			}
			dbuf_set_writelistener(outf, NULL, NULL);
			break;

		case SDID_RESOURCEFORK:
			afp_rsrc = de_malloc(c, sizeof(struct de_advfile_cbparams));
			afp_rsrc->whattodo = DE_ADVFILE_WRITERSRC;
			dbuf_set_writelistener(outf, advf->rsrcfork.writelistener_cb,
				advf->rsrcfork.userdata_for_writelistener);
			afp_rsrc->outf = outf;
			if(advf->writefork_cbfn && advf->rsrcfork.fork_len>0) {
				advf->writefork_cbfn(c, advf, afp_rsrc);
			}
			dbuf_set_writelistener(outf, NULL, NULL);
			break;

		case SDID_REALNAME:
			// If you think this code might be wrong, first review the comments
			// in applesd.c regarding Pascal strings.
			dbuf_write(outf, advf->orig_filename, (i64)advf->orig_filename_len);
			break;

		case SDID_COMMENT:
			dbuf_write(outf, (const u8*)commentstr, (i64)comment_strlen);
			break;

		case SDID_FILEDATES:
			dbuf_writei32be(outf, timestamp_to_applesd_date(c, &advf->mainfork.fi->timestamp[DE_TIMESTAMPIDX_CREATE]));
			dbuf_writei32be(outf, timestamp_to_applesd_date(c, &advf->mainfork.fi->timestamp[DE_TIMESTAMPIDX_MODIFY]));
			dbuf_writei32be(outf, timestamp_to_applesd_date(c, &advf->mainfork.fi->timestamp[DE_TIMESTAMPIDX_BACKUP]));
			dbuf_writei32be(outf, timestamp_to_applesd_date(c, &advf->mainfork.fi->timestamp[DE_TIMESTAMPIDX_ACCESS]));
			break;

		case SDID_FINDERINFO:
			if(advf->has_typecode)
				dbuf_write(outf, advf->typecode, 4);
			else
				dbuf_write_zeroes(outf, 4);
			if(advf->has_creatorcode)
				dbuf_write(outf, advf->creatorcode, 4);
			else
				dbuf_write_zeroes(outf, 4);
			dbuf_writeu16be(outf, advf->has_finderflags?((i64)advf->finderflags):0);
			dbuf_write_zeroes(outf, 6 + 16);
			break;
		}

		// In case something went wrong, try to make sure we're at the expected
		// file position.
		// Note: This might not compensate for all failures, as dbuf_truncate
		// might not be fully implemented for this output type.
		dbuf_truncate(outf, entry_info[k].offset + entry_info[k].len);
	}

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

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x218, %rsp            # imm = 0x218
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %r15
callq 0xf6410
movq %rax, %rbx
movq 0x68(%r14), %rsi
movq %rax, %rdi
callq 0xf6509
cmpq $0x0, 0x10(%rbx)
jg 0xfcbfc
leaq 0x31d95(%rip), %rsi     # 0x12e984
movq %rbx, %rdi
movl $0x5, %edx
callq 0xf65e3
testl %ebp, %ebp
leaq 0x4e24c(%rip), %rax     # 0x14ae51
leaq 0x4e24a(%rip), %rsi     # 0x14ae56
cmovneq %rax, %rsi
movq %rbx, %rdi
movl $0x5, %edx
callq 0xf65e3
movq 0x20(%r14), %rsi
movl 0x70(%r14), %ecx
movq %r15, %rdi
movq %rbx, 0x38(%rsp)
movq %rbx, %rdx
callq 0xea53f
movb 0x79(%r14), %al
movq 0x20(%r14), %rdx
movb %al, 0x8(%rdx)
movl 0x74(%r14), %ecx
movq %r15, %rdi
xorl %esi, %esi
callq 0xefda1
movq %rax, %r12
movq %r14, 0x8(%rsp)
cmpb $0x0, 0x78(%r14)
je 0xfcc65
movq %r12, %rdi
callq 0xf0855
testl %ebp, %ebp
movl $0x51607, %eax          # imm = 0x51607
movl $0x51600, %esi          # imm = 0x51600
cmovneq %rax, %rsi
leaq 0x19db3(%rip), %rax     # 0x116a2f
leaq 0x19de4(%rip), %rbx     # 0x116a67
cmovneq %rax, %rbx
movq %r12, %rdi
callq 0xf1026
movl $0x20000, %esi          # imm = 0x20000
movq %r12, %rdi
callq 0xf1026
movl $0x10, %esi
movq %r12, %rdi
callq 0xf0d35
leaq 0x4e1aa(%rip), %rdx     # 0x14ae5a
xorl %r14d, %r14d
leaq 0x1c0(%rsp), %r13
movl $0x50, %esi
movq %r13, %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0xe8193
movq %r13, %rdi
callq 0x180e0
movq %rax, 0x18(%rsp)
movq 0x8(%rsp), %rdx
cmpq $0x0, 0x88(%rdx)
je 0xfcd08
leaq 0x58(%rsp), %rax
movl $0x3, -0x18(%rax)
movq 0x80(%rdx), %rcx
movq %rcx, -0x8(%rax)
movl $0x1, %r14d
jmp 0xfcd0d
leaq 0x40(%rsp), %rax
movl $0x4, (%rax)
movq 0x18(%rsp), %rcx
movq %rcx, 0x10(%rax)
leaq 0x1(%r14), %rbx
movq 0x20(%rdx), %rax
cmpb $0x0, 0x28(%rax)
jne 0xfcd3c
cmpb $0x0, 0x18(%rax)
jne 0xfcd3c
cmpb $0x0, 0x58(%rax)
jne 0xfcd3c
cmpb $0x0, 0x38(%rax)
je 0xfcd58
leaq (%rbx,%rbx,2), %rcx
movl $0x8, 0x40(%rsp,%rcx,8)
movq $0x10, 0x50(%rsp,%rcx,8)
orq $0x2, %r14
movq %r14, %rbx
cmpb $0x0, 0x7b(%rdx)
jne 0xfcd6a
cmpb $0x0, 0x7c(%rdx)
jne 0xfcd6a
cmpb $0x0, 0x7d(%rdx)
je 0xfcd88
cmpb $0x0, 0x9(%rax)
jne 0xfcd88
leaq (%rbx,%rbx,2), %rax
movl $0x9, 0x40(%rsp,%rax,8)
movq $0x20, 0x50(%rsp,%rax,8)
incq %rbx
cmpb $0x0, 0x38(%rdx)
je 0xfcda6
leaq (%rbx,%rbx,2), %rax
movl $0x2, 0x40(%rsp,%rax,8)
movq 0x40(%rdx), %rcx
movq %rcx, 0x50(%rsp,%rax,8)
incq %rbx
testl %ebp, %ebp
jne 0xfcdc8
cmpb $0x0, 0x10(%rdx)
je 0xfcdc8
leaq (%rbx,%rbx,2), %rax
movl $0x1, 0x40(%rsp,%rax,8)
movq 0x18(%rdx), %rcx
movq %rcx, 0x50(%rsp,%rax,8)
incq %rbx
movq %r15, 0x10(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xf0fad
leaq (%rbx,%rbx,2), %rax
leaq 0x1a(,%rax,4), %rax
leal (,%rbx,8), %ecx
leaq (%rcx,%rcx,2), %rcx
xorl %edx, %edx
movq %rax, 0x48(%rsp,%rdx)
addq 0x50(%rsp,%rdx), %rax
addq $0x18, %rdx
cmpq %rdx, %rcx
jne 0xfcdf1
movq %rbx, (%rsp)
leal (,%rbx,8), %eax
leaq (%rax,%rax,2), %r14
xorl %ebp, %ebp
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
movabsq $0x100000000, %r13      # imm = 0x100000000
movl 0x40(%rsp,%rbp), %esi
movq %r12, %rdi
callq 0xf1026
movq 0x48(%rsp,%rbp), %rsi
cmpq %r15, %rsi
jg 0xfd19e
movq 0x50(%rsp,%rbp), %rbx
cmpq %r13, %rbx
jge 0xfd19e
movq %r12, %rdi
callq 0xf1026
movq %r12, %rdi
movq %rbx, %rsi
callq 0xf1026
addq $0x18, %rbp
cmpq %rbp, %r14
jne 0xfce25
movq 0x8(%rsp), %rbx
leaq 0x90(%rbx), %rax
movq %rax, 0x28(%rsp)
leaq 0x94(%rbx), %rax
movq %rax, 0x20(%rsp)
movq (%rsp), %rax
shll $0x3, %eax
leaq (%rax,%rax,2), %r14
xorl %ebp, %ebp
xorl %r13d, %r13d
movq $0x0, (%rsp)
movq 0x10(%rsp), %r15
movq %r14, 0x30(%rsp)
movl 0x40(%rsp,%rbp), %eax
decl %eax
cmpl $0x8, %eax
ja 0xfd17d
leaq 0x4df62(%rip), %rcx     # 0x14ae20
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %r13, %r14
movl $0x10, %esi
movq %r15, %rdi
callq 0xe8b2b
movq %r15, %r13
movq %rax, %r15
movl $0x1, (%rax)
movq 0x28(%rbx), %rdx
movq 0x30(%rbx), %rsi
movq %r12, %rdi
callq 0xf1412
movq %r15, (%rsp)
movq %r12, 0x8(%r15)
movq %r13, %r15
movq 0x60(%rbx), %rax
testq %rax, %rax
je 0xfcf1a
cmpq $0x0, 0x18(%rbx)
jle 0xfcf1a
movq %r15, %rdi
movq %rbx, %rsi
movq (%rsp), %rdx
callq *%rax
movq %r12, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xf1412
movq %r14, %r13
movq 0x30(%rsp), %r14
jmp 0xfd17d
movq 0x80(%rbx), %rdx
movq 0x88(%rbx), %rsi
movq %r12, %rdi
jmp 0xfcfd0
cmpb $0x0, 0x7b(%rbx)
je 0xfd126
movl $0x4, %edx
movq %r12, %rdi
movq 0x28(%rsp), %rsi
callq 0xef547
jmp 0xfd133
movl $0x10, %esi
movq %r15, %rdi
callq 0xe8b2b
movq %rax, %r13
movl $0x2, (%rax)
movq 0x50(%rbx), %rdx
movq 0x58(%rbx), %rsi
movq %r12, %rdi
callq 0xf1412
movq %r12, 0x8(%r13)
movq 0x60(%rbx), %rax
testq %rax, %rax
je 0xfcfaf
cmpq $0x0, 0x40(%rbx)
jle 0xfcfaf
movq %r15, %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq *%rax
movq %r12, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xf1412
jmp 0xfd17d
movq %r12, %rdi
leaq 0x1c0(%rsp), %rsi
movq 0x18(%rsp), %rdx
callq 0xef547
jmp 0xfd17d
movq 0x20(%rbx), %rdi
movq $-0x80000000, %rbx      # imm = 0x80000000
cmpb $0x0, 0x28(%rdi)
movq $-0x80000000, %rsi      # imm = 0x80000000
je 0xfd025
addq $0x28, %rdi
callq 0xeacfd
movabsq $-0xffffffff, %rdx      # imm = 0xFFFFFFFF00000001
leaq (%rdx,%rax), %rcx
addq $0x4792bc7f, %rcx       # imm = 0x4792BC7F
movq $-0x80000000, %rsi      # imm = 0x80000000
cmpq %rdx, %rcx
jb 0xfd025
addq $-0x386d4380, %rax      # imm = 0xC792BC80
movq %rax, %rsi
movq %r12, %rdi
callq 0xf1096
movq 0x8(%rsp), %rax
movq 0x20(%rax), %rdi
cmpb $0x0, 0x18(%rdi)
je 0xfd06f
addq $0x18, %rdi
callq 0xeacfd
movabsq $-0xffffffff, %rdx      # imm = 0xFFFFFFFF00000001
leaq (%rdx,%rax), %rcx
addq $0x4792bc7f, %rcx       # imm = 0x4792BC7F
movq $-0x80000000, %rbx      # imm = 0x80000000
cmpq %rdx, %rcx
jb 0xfd06f
addq $-0x386d4380, %rax      # imm = 0xC792BC80
movq %rax, %rbx
movq %r12, %rdi
movq %rbx, %rsi
callq 0xf1096
movq 0x8(%rsp), %rax
movq 0x20(%rax), %rdi
movq $-0x80000000, %rbx      # imm = 0x80000000
cmpb $0x0, 0x58(%rdi)
movq $-0x80000000, %rsi      # imm = 0x80000000
je 0xfd0ca
addq $0x58, %rdi
callq 0xeacfd
movabsq $-0xffffffff, %rdx      # imm = 0xFFFFFFFF00000001
leaq (%rdx,%rax), %rcx
addq $0x4792bc7f, %rcx       # imm = 0x4792BC7F
movq $-0x80000000, %rsi      # imm = 0x80000000
cmpq %rdx, %rcx
jb 0xfd0ca
addq $-0x386d4380, %rax      # imm = 0xC792BC80
movq %rax, %rsi
movq %r12, %rdi
callq 0xf1096
movq 0x8(%rsp), %rax
movq 0x20(%rax), %rdi
cmpb $0x0, 0x38(%rdi)
je 0xfd114
addq $0x38, %rdi
callq 0xeacfd
movabsq $-0xffffffff, %rdx      # imm = 0xFFFFFFFF00000001
leaq (%rdx,%rax), %rcx
addq $0x4792bc7f, %rcx       # imm = 0x4792BC7F
movq $-0x80000000, %rbx      # imm = 0x80000000
cmpq %rdx, %rcx
jb 0xfd114
addq $-0x386d4380, %rax      # imm = 0xC792BC80
movq %rax, %rbx
movq %r12, %rdi
movq %rbx, %rsi
callq 0xf1096
movq 0x8(%rsp), %rbx
jmp 0xfd17d
movl $0x4, %esi
movq %r12, %rdi
callq 0xf0d35
cmpb $0x0, 0x7c(%rbx)
je 0xfd14d
movl $0x4, %edx
movq %r12, %rdi
movq 0x20(%rsp), %rsi
callq 0xef547
jmp 0xfd15a
movl $0x4, %esi
movq %r12, %rdi
callq 0xf0d35
cmpb $0x0, 0x7d(%rbx)
je 0xfd166
movzwl 0x7e(%rbx), %esi
jmp 0xfd168
xorl %esi, %esi
movq %r12, %rdi
callq 0xf0fad
movl $0x16, %esi
movq %r12, %rdi
callq 0xf0d35
movq 0x50(%rsp,%rbp), %rsi
addq 0x48(%rsp,%rbp), %rsi
movq %r12, %rdi
callq 0xf0f27
addq $0x18, %rbp
cmpq %rbp, %r14
jne 0xfcea8
jmp 0xfd1bf
leaq 0x4dcda(%rip), %rsi     # 0x14ae7f
movq $0x0, (%rsp)
movq 0x10(%rsp), %r15
movq %r15, %rdi
xorl %eax, %eax
callq 0xe9295
xorl %r13d, %r13d
movq %r12, %rdi
callq 0xf052b
movq %r15, %rdi
movq (%rsp), %rsi
callq 0xe8be2
movq %r15, %rdi
movq %r13, %rsi
callq 0xe8be2
movq 0x38(%rsp), %rdi
callq 0xf6753
addq $0x218, %rsp            # imm = 0x218
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq