// File: BenLangmead[P]bowtie/./ebwt.h
// Function: Ebwt::writeFromMemory(bool, std::ostream&, std::ostream&) const
void Ebwt::writeFromMemory(bool justHeader,
			   ostream& out1,
			   ostream& out2) const
{
	const EbwtParams& eh = this->_eh;
	assert(eh.repOk());
	uint32_t be = this->toBe();
	assert(out1.good());
	assert(out2.good());

	// When building an Ebwt, these header parameters are known
	// "up-front", i.e., they can be written to disk immediately,
	// before we join() or buildToDisk()
	writeI<int32_t>(out1, 1, be); // endian hint for priamry stream
	writeI<int32_t>(out2, 1, be); // endian hint for secondary stream
	writeU<TIndexOffU>(out1, eh._len,          be); // length of string (and bwt and suffix array)
	writeI<int32_t>(out1, eh._lineRate,     be); // 2^lineRate = size in bytes of 1 line
	writeI<int32_t>(out1, eh._linesPerSide, be); // not used
	writeI<int32_t>(out1, eh._offRate,      be); // every 2^offRate chars is "marked"
	writeI<int32_t>(out1, eh._ftabChars,    be); // number of 2-bit chars used to address ftab
	int32_t flags = 1;
	if(eh._entireReverse) flags |= EBWT_ENTIRE_REV;
	writeI<int32_t>(out1, -flags, be); // BTL: chunkRate is now deprecated

	if(!justHeader) {
		assert(isInMemory());
		// These Ebwt parameters are known after the inputs strings have
		// been joined() but before they have been built().  These can
		// written to the disk next and then discarded from memory.
		writeU<TIndexOffU>(out1, this->_nPat,      be);
		for(TIndexOffU i = 0; i < this->_nPat; i++)
			writeU<TIndexOffU>(out1, this->_plen[i], be);
		assert_geq(this->_nFrag, this->_nPat);
		writeU<TIndexOffU>(out1, this->_nFrag, be);
		for(TIndexOffU i = 0; i < this->_nFrag*3; i++)
			writeU<TIndexOffU>(out1, this->_rstarts[i], be);

		// These Ebwt parameters are discovered only as the Ebwt is being
		// built (in buildToDisk()).  Of these, only 'offs' and 'ebwt' are
		// terribly large.  'ebwt' is written to the primary file and then
		// discarded from memory as it is built; 'offs' is similarly
		// written to the secondary file and discarded.
		out1.write((const char *)this->ebwt(), eh._ebwtTotLen);
		writeU<TIndexOffU>(out1, this->zOff(), be);
		TIndexOffU offsLen = eh._offsLen;
		for(TIndexOffU i = 0; i < offsLen; i++)
			writeU<TIndexOffU>(out2, this->_offs[i], be);
		uint32_t isaLen = eh._isaLen;
		for(TIndexOffU i = 0; i < isaLen; i++)
			writeU<TIndexOffU>(out2, this->_isa[i], be);

		// 'fchr', 'ftab' and 'eftab' are not fully determined until the
		// loop is finished, so they are written to the primary file after
		// all of 'ebwt' has already been written and only then discarded
		// from memory.
		for(int i = 0; i < 5; i++)
			writeU<TIndexOffU>(out1, this->_fchr[i], be);
		for(TIndexOffU i = 0; i < eh._ftabLen; i++)
			writeU<TIndexOffU>(out1, this->ftab()[i], be);
		for(TIndexOffU i = 0; i < eh._eftabLen; i++)
			writeU<TIndexOffU>(out1, this->eftab()[i], be);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
andb $0x1, %al
movb %al, -0x9(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x80(%rbp)
addq $0x108, %rax            # imm = 0x108
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x1bfc0
testb $0x1, %al
jne 0xe5e0
jmp 0xe5e2
jmp 0xe601
leaq 0x31655(%rip), %rdi     # 0x3fc3e
leaq 0x30acd(%rip), %rsi     # 0x3f0bd
movl $0xe17, %edx            # imm = 0xE17
leaq 0x3159f(%rip), %rcx     # 0x3fb9b
callq 0x51e0
movq -0x80(%rbp), %rdi
callq 0x1c820
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x2c(%rbp)
movq -0x18(%rbp), %rdi
movq (%rdi), %rax
addq -0x18(%rax), %rdi
callq 0x5710
testb $0x1, %al
jne 0xe628
jmp 0xe62a
jmp 0xe649
leaq 0x315a7(%rip), %rdi     # 0x3fbd8
leaq 0x30a85(%rip), %rsi     # 0x3f0bd
movl $0xe19, %edx            # imm = 0xE19
leaq 0x31557(%rip), %rcx     # 0x3fb9b
callq 0x51e0
movq -0x20(%rbp), %rdi
movq (%rdi), %rax
addq -0x18(%rax), %rdi
callq 0x5710
testb $0x1, %al
jne 0xe65f
jmp 0xe661
jmp 0xe680
leaq 0x3157c(%rip), %rdi     # 0x3fbe4
leaq 0x30a4e(%rip), %rsi     # 0x3f0bd
movl $0xe1a, %edx            # imm = 0xE1A
leaq 0x31520(%rip), %rcx     # 0x3fb9b
callq 0x51e0
movq -0x18(%rbp), %rdi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
movl $0x1, %esi
callq 0xeb90
movq -0x20(%rbp), %rdi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
movl $0x1, %esi
callq 0xeb90
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rax
movq (%rax), %rsi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xebe0
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rax
movl 0x20(%rax), %esi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xeb90
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rax
movl 0x24(%rax), %esi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xeb90
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rax
movl 0x2c(%rax), %esi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xeb90
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rax
movl 0x40(%rax), %esi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xeb90
movl $0x1, -0x30(%rbp)
movq -0x28(%rbp), %rax
testb $0x1, 0xb8(%rax)
je 0xe764
movl -0x30(%rbp), %eax
orl $0x4, %eax
movl %eax, -0x30(%rbp)
movq -0x18(%rbp), %rdi
xorl %esi, %esi
subl -0x30(%rbp), %esi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xeb90
testb $0x1, -0x9(%rbp)
jne 0xeb7a
movq -0x80(%rbp), %rdi
callq 0x18060
testb $0x1, %al
jne 0xe798
jmp 0xe79a
jmp 0xe7b9
leaq 0x3090f(%rip), %rdi     # 0x3f0b0
leaq 0x30915(%rip), %rsi     # 0x3f0bd
movl $0xe2b, %edx            # imm = 0xE2B
leaq 0x313e7(%rip), %rcx     # 0x3fb9b
callq 0x51e0
movq -0x80(%rbp), %rax
movq -0x18(%rbp), %rdi
movq 0x80(%rax), %rsi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xebe0
movq $0x0, -0x38(%rbp)
movq -0x80(%rbp), %rcx
movq -0x38(%rbp), %rax
cmpq 0x80(%rcx), %rax
jae 0xe82a
movq -0x80(%rbp), %rax
movq -0x18(%rbp), %rdi
movq 0x90(%rax), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xebe0
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0xe7e2
movq -0x80(%rbp), %rcx
movq 0x88(%rcx), %rax
cmpq 0x80(%rcx), %rax
jae 0xe905
movq 0x3b777(%rip), %rdi     # 0x49fc0
leaq 0x309b5(%rip), %rsi     # 0x3f205
callq 0x5360
movq %rax, %rdi
movq -0x80(%rbp), %rax
movq 0x88(%rax), %rsi
callq 0x50c0
movq %rax, %rdi
leaq 0x309aa(%rip), %rsi     # 0x3f21c
callq 0x5360
movq %rax, %rdi
movq -0x80(%rbp), %rax
movq 0x80(%rax), %rsi
callq 0x50c0
movq %rax, %rdi
leaq 0x32d24(%rip), %rsi     # 0x415b8
callq 0x5360
movq %rax, %rdi
movq 0x3b6dd(%rip), %rsi     # 0x49f80
callq 0x53c0
movq 0x3b711(%rip), %rdi     # 0x49fc0
leaq 0x30807(%rip), %rsi     # 0x3f0bd
callq 0x5360
movq %rax, %rdi
leaq 0x31ec5(%rip), %rsi     # 0x4078a
callq 0x5360
movq %rax, %rdi
movl $0xe32, %esi            # imm = 0xE32
callq 0x5750
movq %rax, %rdi
movq 0x3b69f(%rip), %rsi     # 0x49f80
callq 0x53c0
leaq 0x31d7d(%rip), %rdi     # 0x4066a
leaq 0x307c9(%rip), %rsi     # 0x3f0bd
movl $0xe32, %edx            # imm = 0xE32
leaq 0x3129b(%rip), %rcx     # 0x3fb9b
callq 0x51e0
movq -0x80(%rbp), %rax
movq -0x18(%rbp), %rdi
movq 0x88(%rax), %rsi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xebe0
movq $0x0, -0x40(%rbp)
movq -0x80(%rbp), %rcx
movq -0x40(%rbp), %rax
imulq $0x3, 0x88(%rcx), %rcx
cmpq %rcx, %rax
jae 0xe97a
movq -0x80(%rbp), %rax
movq -0x18(%rbp), %rdi
movq 0x98(%rax), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xebe0
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0xe92e
movq -0x80(%rbp), %rdi
movq -0x18(%rbp), %rax
movq %rax, -0x90(%rbp)
callq 0x1a9b0
movq -0x90(%rbp), %rdi
movq %rax, %rsi
movq -0x28(%rbp), %rax
movq 0xa8(%rax), %rdx
callq 0x5520
movq -0x80(%rbp), %rdi
movq -0x18(%rbp), %rax
movq %rax, -0x88(%rbp)
callq 0x1c840
movq -0x88(%rbp), %rdi
movq %rax, %rsi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xebe0
movq -0x28(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
cmpq -0x48(%rbp), %rax
jae 0xea2d
movq -0x80(%rbp), %rax
movq -0x20(%rbp), %rdi
movq 0xb8(%rax), %rax
movq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xebe0
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0xe9ec
movq -0x28(%rbp), %rax
movq 0x70(%rax), %rax
movl %eax, -0x54(%rbp)
movq $0x0, -0x60(%rbp)
movq -0x60(%rbp), %rax
movl -0x54(%rbp), %ecx
cmpq %rcx, %rax
jae 0xea83
movq -0x80(%rbp), %rax
movq -0x20(%rbp), %rdi
movq 0xc0(%rax), %rax
movq -0x60(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xebe0
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
jmp 0xea40
movl $0x0, -0x64(%rbp)
cmpl $0x5, -0x64(%rbp)
jge 0xeac4
movq -0x80(%rbp), %rax
movq -0x18(%rbp), %rdi
movq 0xa0(%rax), %rax
movslq -0x64(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xebe0
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0xea8a
movq $0x0, -0x70(%rbp)
movq -0x70(%rbp), %rax
movq -0x28(%rbp), %rcx
cmpq 0x50(%rcx), %rax
jae 0xeb1d
movq -0x80(%rbp), %rdi
movq -0x18(%rbp), %rax
movq %rax, -0x98(%rbp)
callq 0x1c860
movq -0x98(%rbp), %rdi
movq -0x70(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xebe0
movq -0x70(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x70(%rbp)
jmp 0xeacc
movq $0x0, -0x78(%rbp)
movq -0x78(%rbp), %rax
movq -0x28(%rbp), %rcx
movl 0x44(%rcx), %ecx
cmpq %rcx, %rax
jae 0xeb78
movq -0x80(%rbp), %rdi
movq -0x18(%rbp), %rax
movq %rax, -0xa0(%rbp)
callq 0x1c880
movq -0xa0(%rbp), %rdi
movq -0x78(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
cmpl $0x0, -0x2c(%rbp)
setne %al
movzbl %al, %edx
andl $0x1, %edx
callq 0xebe0
movq -0x78(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x78(%rbp)
jmp 0xeb25
jmp 0xeb7a
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)