// File: /workspace/github_c_makefile_star2_O1/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, %rbx
callq 0xf6870
movq %rax, %r15
movq 0x68(%r14), %rsi
movq %rax, %rdi
callq 0xf6969
cmpq $0x0, 0x10(%r15)
jg 0xfd1e9
leaq 0x31498(%rip), %rsi     # 0x12e674
movq %r15, %rdi
movl $0x5, %edx
callq 0xf6a40
testl %ebp, %ebp
leaq 0x4d6af(%rip), %rax     # 0x14a8a1
leaq 0x4d6ad(%rip), %rsi     # 0x14a8a6
cmovneq %rax, %rsi
movq %r15, %rdi
movl $0x5, %edx
callq 0xf6a40
movq 0x20(%r14), %rsi
movl 0x70(%r14), %ecx
movq %rbx, %rdi
movq %r15, 0x38(%rsp)
movq %r15, %rdx
callq 0xea9e4
movb 0x79(%r14), %al
movq 0x20(%r14), %rdx
movb %al, 0x8(%rdx)
movl 0x74(%r14), %ecx
movq %rbx, 0x8(%rsp)
movq %rbx, %rdi
xorl %esi, %esi
callq 0xf037a
movq %rax, %r12
movq %r14, (%rsp)
cmpb $0x0, 0x78(%r14)
je 0xfd256
movq %r12, %rdi
callq 0xf0e3f
testl %ebp, %ebp
movl $0x51607, %eax          # imm = 0x51607
movl $0x51600, %esi          # imm = 0x51600
cmovneq %rax, %rsi
leaq 0x19712(%rip), %rax     # 0x11697f
leaq 0x19743(%rip), %rbx     # 0x1169b7
cmovneq %rax, %rbx
movq %r12, %rdi
callq 0xf1629
movl $0x20000, %esi          # imm = 0x20000
movq %r12, %rdi
callq 0xf1629
movl $0x10, %esi
movq %r12, %rdi
callq 0xf1346
leaq 0x4d609(%rip), %rdx     # 0x14a8aa
xorl %r14d, %r14d
leaq 0x1c0(%rsp), %r13
movl $0x50, %esi
movq %r13, %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0xe8d67
movq %r13, %rdi
callq 0x180e0
movq (%rsp), %rdx
cmpq $0x0, 0x88(%rdx)
je 0xfd2f3
leaq 0x58(%rsp), %rsi
movl $0x3, -0x18(%rsi)
movq 0x80(%rdx), %rcx
movq %rcx, -0x8(%rsi)
movl $0x1, %r14d
jmp 0xfd2f8
leaq 0x40(%rsp), %rsi
movl $0x4, (%rsi)
movq %rax, 0x10(%rsi)
leaq 0x1(%r14), %r13
movq 0x20(%rdx), %rsi
cmpb $0x0, 0x28(%rsi)
movq 0x8(%rsp), %r15
jne 0xfd327
cmpb $0x0, 0x18(%rsi)
jne 0xfd327
cmpb $0x0, 0x58(%rsi)
jne 0xfd327
cmpb $0x0, 0x38(%rsi)
je 0xfd34a
leaq (,%r13,2), %rcx
addq %r13, %rcx
movl $0x8, 0x40(%rsp,%rcx,8)
movq $0x10, 0x50(%rsp,%rcx,8)
orq $0x2, %r14
movq %r14, %r13
movq (%rsp), %rdx
cmpb $0x0, 0x7b(%rdx)
jne 0xfd360
cmpb $0x0, 0x7c(%rdx)
jne 0xfd360
cmpb $0x0, 0x7d(%rdx)
je 0xfd385
cmpb $0x0, 0x9(%rsi)
jne 0xfd385
leaq (,%r13,2), %rcx
addq %r13, %rcx
movl $0x9, 0x40(%rsp,%rcx,8)
movq $0x20, 0x50(%rsp,%rcx,8)
incq %r13
cmpb $0x0, 0x38(%rdx)
je 0xfd3aa
leaq (,%r13,2), %rsi
addq %r13, %rsi
movl $0x2, 0x40(%rsp,%rsi,8)
movq 0x40(%rdx), %rcx
movq %rcx, 0x50(%rsp,%rsi,8)
incq %r13
testl %ebp, %ebp
movq %rax, 0x30(%rsp)
jne 0xfd3d8
cmpb $0x0, 0x10(%rdx)
je 0xfd3d8
leaq (,%r13,2), %rax
addq %r13, %rax
movl $0x1, 0x40(%rsp,%rax,8)
movq 0x18(%rdx), %rcx
movq %rcx, 0x50(%rsp,%rax,8)
incq %r13
movq %r12, %rdi
movq %r13, %rsi
callq 0xf15b0
testq %r13, %r13
je 0xfd813
leaq (,%r13,2), %rax
addq %r13, %rax
leaq 0x1a(,%rax,4), %rax
leal (,%r13,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 0xfd40d
leal (,%r13,8), %eax
leaq (%rax,%rax,2), %r14
xorl %ebp, %ebp
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
movl 0x40(%rsp,%rbp), %esi
movq %r12, %rdi
callq 0xf1629
movq 0x48(%rsp,%rbp), %rsi
cmpq %r15, %rsi
jg 0xfd7f2
movq 0x50(%rsp,%rbp), %rbx
movabsq $0x100000000, %rax      # imm = 0x100000000
cmpq %rax, %rbx
jge 0xfd7f2
movq %r12, %rdi
callq 0xf1629
movq %r12, %rdi
movq %rbx, %rsi
callq 0xf1629
addq $0x18, %rbp
cmpq %rbp, %r14
jne 0xfd434
movq (%rsp), %rax
leaq 0x90(%rax), %rcx
movq %rcx, 0x28(%rsp)
addq $0x94, %rax
movq %rax, 0x20(%rsp)
shll $0x3, %r13d
leaq (%r13,%r13,2), %r13
xorl %ebp, %ebp
leaq 0x4d3c1(%rip), %rbx     # 0x14a870
xorl %r14d, %r14d
movq $0x0, 0x10(%rsp)
movq 0x8(%rsp), %r15
movq %r13, 0x18(%rsp)
movl 0x40(%rsp,%rbp), %eax
decl %eax
cmpl $0x8, %eax
ja 0xfd7d1
movslq (%rbx,%rax,4), %rax
addq %rbx, %rax
jmpq *%rax
movq %r14, %rbx
movl $0x10, %esi
movq %r15, %r14
movq %r15, %rdi
callq 0xe969b
movq %rax, %r13
movl $0x1, (%rax)
movq (%rsp), %r15
movq 0x28(%r15), %rdx
movq 0x30(%r15), %rsi
movq %r12, %rdi
callq 0xf1a12
movq %r13, 0x10(%rsp)
movq %r12, 0x8(%r13)
movq 0x60(%r15), %rax
testq %rax, %rax
je 0xfd533
cmpq $0x0, 0x18(%r15)
jle 0xfd533
movq %r14, %rdi
movq %r15, %rsi
movq 0x10(%rsp), %rdx
callq *%rax
movq %r12, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xf1a12
movq %rbx, %rax
movq 0x18(%rsp), %r13
leaq 0x4d322(%rip), %rbx     # 0x14a870
movq %r14, %r15
movq %rax, %r14
jmp 0xfd7d1
movq (%rsp), %rax
movq 0x80(%rax), %rdx
movq 0x88(%rax), %rsi
movq %r12, %rdi
jmp 0xfd614
movq (%rsp), %rax
cmpb $0x0, 0x7b(%rax)
je 0xfd772
movl $0x4, %edx
movq %r12, %rdi
movq 0x28(%rsp), %rsi
callq 0xefb82
jmp 0xfd77f
movl $0x10, %esi
movq %r15, %rdi
callq 0xe969b
movq %rax, %r14
movl $0x2, (%rax)
movq (%rsp), %r15
movq 0x50(%r15), %rdx
movq 0x58(%r15), %rsi
movq %r12, %rdi
callq 0xf1a12
movq %r14, %r13
movq %r12, 0x8(%r14)
movq 0x60(%r15), %rax
testq %rax, %rax
je 0xfd5e6
cmpq $0x0, 0x40(%r15)
jle 0xfd5e6
movq 0x8(%rsp), %rdi
movq %r15, %rsi
movq %r13, %rdx
callq *%rax
movq %r12, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xf1a12
movq 0x8(%rsp), %r15
movq %r13, %r14
movq 0x18(%rsp), %r13
jmp 0xfd7d1
movq %r12, %rdi
leaq 0x1c0(%rsp), %rsi
movq 0x30(%rsp), %rdx
callq 0xefb82
jmp 0xfd7d1
movq (%rsp), %rax
movq 0x20(%rax), %rdi
movq $-0x80000000, %rbx      # imm = 0x80000000
cmpb $0x0, 0x28(%rdi)
movq $-0x80000000, %rsi      # imm = 0x80000000
je 0xfd66d
addq $0x28, %rdi
callq 0xeb296
movabsq $-0xffffffff, %rdx      # imm = 0xFFFFFFFF00000001
leaq (%rdx,%rax), %rcx
addq $0x4792bc7f, %rcx       # imm = 0x4792BC7F
movq $-0x80000000, %rsi      # imm = 0x80000000
cmpq %rdx, %rcx
jb 0xfd66d
addq $-0x386d4380, %rax      # imm = 0xC792BC80
movq %rax, %rsi
movq %r12, %rdi
callq 0xf1699
movq (%rsp), %rax
movq 0x20(%rax), %rdi
cmpb $0x0, 0x18(%rdi)
je 0xfd6b6
addq $0x18, %rdi
callq 0xeb296
movabsq $-0xffffffff, %rdx      # imm = 0xFFFFFFFF00000001
leaq (%rdx,%rax), %rcx
addq $0x4792bc7f, %rcx       # imm = 0x4792BC7F
movq $-0x80000000, %rbx      # imm = 0x80000000
cmpq %rdx, %rcx
jb 0xfd6b6
addq $-0x386d4380, %rax      # imm = 0xC792BC80
movq %rax, %rbx
movq %r12, %rdi
movq %rbx, %rsi
callq 0xf1699
movq (%rsp), %rax
movq 0x20(%rax), %rdi
movq $-0x80000000, %rbx      # imm = 0x80000000
cmpb $0x0, 0x58(%rdi)
movq $-0x80000000, %rsi      # imm = 0x80000000
je 0xfd710
addq $0x58, %rdi
callq 0xeb296
movabsq $-0xffffffff, %rdx      # imm = 0xFFFFFFFF00000001
leaq (%rdx,%rax), %rcx
addq $0x4792bc7f, %rcx       # imm = 0x4792BC7F
movq $-0x80000000, %rsi      # imm = 0x80000000
cmpq %rdx, %rcx
jb 0xfd710
addq $-0x386d4380, %rax      # imm = 0xC792BC80
movq %rax, %rsi
movq %r12, %rdi
callq 0xf1699
movq (%rsp), %rax
movq 0x20(%rax), %rdi
cmpb $0x0, 0x38(%rdi)
je 0xfd759
addq $0x38, %rdi
callq 0xeb296
movabsq $-0xffffffff, %rdx      # imm = 0xFFFFFFFF00000001
leaq (%rdx,%rax), %rcx
addq $0x4792bc7f, %rcx       # imm = 0x4792BC7F
movq $-0x80000000, %rbx      # imm = 0x80000000
cmpq %rdx, %rcx
jb 0xfd759
addq $-0x386d4380, %rax      # imm = 0xC792BC80
movq %rax, %rbx
movq %r12, %rdi
movq %rbx, %rsi
callq 0xf1699
movq 0x8(%rsp), %r15
leaq 0x4d100(%rip), %rbx     # 0x14a870
jmp 0xfd7d1
movl $0x4, %esi
movq %r12, %rdi
callq 0xf1346
movq (%rsp), %rax
cmpb $0x0, 0x7c(%rax)
je 0xfd79d
movl $0x4, %edx
movq %r12, %rdi
movq 0x20(%rsp), %rsi
callq 0xefb82
jmp 0xfd7aa
movl $0x4, %esi
movq %r12, %rdi
callq 0xf1346
movq (%rsp), %rax
cmpb $0x0, 0x7d(%rax)
je 0xfd7ba
movzwl 0x7e(%rax), %esi
jmp 0xfd7bc
xorl %esi, %esi
movq %r12, %rdi
callq 0xf15b0
movl $0x16, %esi
movq %r12, %rdi
callq 0xf1346
movq 0x50(%rsp,%rbp), %rsi
addq 0x48(%rsp,%rbp), %rsi
movq %r12, %rdi
callq 0xf152a
addq $0x18, %rbp
cmpq %rbp, %r13
jne 0xfd4c5
jmp 0xfd81f
leaq 0x4d0d6(%rip), %rsi     # 0x14a8cf
movq $0x0, 0x10(%rsp)
movq 0x8(%rsp), %r15
movq %r15, %rdi
xorl %eax, %eax
callq 0xe9df7
jmp 0xfd81c
movq $0x0, 0x10(%rsp)
xorl %r14d, %r14d
movq %r12, %rdi
callq 0xf0b13
movq %r15, %rdi
movq 0x10(%rsp), %rsi
callq 0xe9752
movq %r15, %rdi
movq %r14, %rsi
callq 0xe9752
movq 0x38(%rsp), %rdi
callq 0xf6bb0
addq $0x218, %rsp            # imm = 0x218
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq