// File: BenLangmead[P]bowtie/ref_read.cpp
// Function: fastaRefReadSize(FileBuf&, RefReadInParams const&, bool, BitpairOutFileBuf*)
RefRecord fastaRefReadSize(FileBuf& in,
                           const RefReadInParams& rparms,
                           bool first,
                           BitpairOutFileBuf* bpout)
{
	int c;
	static int lastc = '>'; // last character seen

	// RefRecord params
	TIndexOffU len = 0; // 'len' counts toward total length
	// 'off' counts number of ambiguous characters before first
	// unambiguous character
	size_t off = 0;

	// Pick off the first carat and any preceding whitespace
	if(first) {
		assert(!in.eof());
		lastc = '>';
		c = in.getPastWhitespace();
		if(in.eof()) {
			// Got eof right away; emit warning
			cerr << "Warning: Empty input file" << endl;
			lastc = -1;
			return RefRecord(0, 0, true);
		}
		assert(c == '>');
	}

	first = true;
	// Skip to the end of the id line; if the next line is either
	// another id line or a comment line, keep skipping
	if(lastc == '>') {
		// Skip to the end of the name line
		do {
			if((c = in.getPastNewline()) == -1) {
				// No more input
				cerr << "Warning: Encountered empty reference sequence" << endl;
				lastc = -1;
				return RefRecord(0, 0, true);
			}
			if(c == '>') {
				cerr << "Warning: Encountered empty reference sequence" << endl;
			}
			// continue until a non-name, non-comment line
		} while (c == '>');
	} else {
		first = false; // not the first in a sequence
		off = 1; // The gap has already been consumed, so count it
		if((c = in.get()) == -1) {
			// Don't emit a warning, since this might legitimately be
			// a gap on the end of the final sequence in the file
			lastc = -1;
			return RefRecord((TIndexOffU)off, (TIndexOffU)len, first);
		}
	}

	// Now skip to the first DNA character, counting gap characters
	// as we go
	while(true) {
		int cat = dna4Cat[c];
		if(rparms.nsToAs && cat == 2) c = 'A';
		if(cat == 1) {
			// This is a DNA character
			break; // to read-in loop
                } else if (cat == 2) {
			off++; // skip over gap character and increment
                } else if (c == '>') {
                  if (off > 0 && lastc == '>') {
                    cerr << "Warning: Encountered reference sequence with only "
                            "gaps"
                         << endl;
                  } else if (lastc == '>') {
                    cerr << "Warning: Encountered empty reference sequence"
                         << endl;
                  }
                  lastc = '>';
                  return RefRecord((TIndexOffU)off, 0, first);
                }
                c = in.get();
		if(c == -1) {
			// End-of-file
			if(off > 0 && lastc == '>') {
				cerr << "Warning: Encountered reference sequence with only gaps" << endl;
			} else if(lastc == '>') {
				cerr << "Warning: Encountered empty reference sequence" << endl;
			}
			lastc = -1;
			return RefRecord((TIndexOffU)off, 0, first);
		}
	}
	assert_eq(1, dna4Cat[c]); // C must be unambiguous base

	// in now points just past the first character of a sequence
	// line, and c holds the first character
	while(c != -1 && c != '>') {
		if(rparms.nsToAs && dna4Cat[c] == 2) c = 'A';
		uint8_t cat = dna4Cat[c];
		int cc = toupper(c);
		if(rparms.bisulfite && cc == 'C') c = cc = 'T';
		if(cat == 1) {
			// It's a DNA character
			assert(cc == 'A' || cc == 'C' || cc == 'G' || cc == 'T');
			// Consume it
			len++;
			// Output it
			if(bpout != NULL) {
				// output nucleotide
				bpout->write(asc2dna[c]);
			}
		} else if(cat == 2) {
			// It's an N or a gap
			lastc = c;
			assert(cc != 'A' && cc != 'C' && cc != 'G' && cc != 'T');
			return RefRecord((TIndexOffU)off, (TIndexOffU)len, first);
		} else {
			// Not DNA and not a gap, ignore it
#ifndef NDEBUG
			if(!isspace(c)) {
				cerr << "Unexpected character in sequence: ";
				if(isprint(c)) {
					cerr << ((char)c) << endl;
				} else {
					cerr << "(" << c << ")" << endl;
				}
			}
#endif
		}
		c = in.get();
	}
	lastc = c;
	return RefRecord((TIndexOffU)off, (TIndexOffU)len, first);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x58(%rbp)
movb %cl, %al
movq %rdi, -0x50(%rbp)
movq %rsi, -0x8(%rbp)
movq %rdx, -0x10(%rbp)
andb $0x1, %al
movb %al, -0x11(%rbp)
movq %r8, -0x20(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
testb $0x1, -0x11(%rbp)
je 0x3a693
movq -0x8(%rbp), %rdi
callq 0x2e870
xorb $-0x1, %al
testb $0x1, %al
jne 0x3a5de
jmp 0x3a5e0
jmp 0x3a5ff
leaq 0x8dcd(%rip), %rdi      # 0x433b4
leaq 0x8dd0(%rip), %rsi      # 0x433be
movl $0x1a, %edx
leaq 0x8dd1(%rip), %rcx      # 0x433cb
callq 0x51e0
movl $0x3e, 0x11007(%rip)    # 0x4b610
movq -0x8(%rbp), %rdi
callq 0x3c590
movl %eax, -0x24(%rbp)
movq -0x8(%rbp), %rdi
callq 0x2e870
testb $0x1, %al
jne 0x3a624
jmp 0x3a66a
movq 0xf9c5(%rip), %rdi      # 0x49ff0
leaq 0x8df3(%rip), %rsi      # 0x43425
callq 0x5360
movq %rax, %rdi
movq 0xf93f(%rip), %rsi      # 0x49f80
callq 0x53c0
movq -0x58(%rbp), %rdi
movl $0xffffffff, 0x10fbc(%rip) # imm = 0xFFFFFFFF
xorl %eax, %eax
movl %eax, %edx
movl $0x1, %ecx
movq %rdx, %rsi
callq 0x3c5f0
jmp 0x3acbf
cmpl $0x3e, -0x24(%rbp)
jne 0x3a672
jmp 0x3a691
leaq 0x8dc6(%rip), %rdi      # 0x4343f
leaq 0x8d3e(%rip), %rsi      # 0x433be
movl $0x23, %edx
leaq 0x8d3f(%rip), %rcx      # 0x433cb
callq 0x51e0
jmp 0x3a693
movb $0x1, -0x11(%rbp)
cmpl $0x3e, 0x10f72(%rip)    # 0x4b610
jne 0x3a733
jmp 0x3a6a6
movq -0x8(%rbp), %rdi
callq 0x3c630
movl %eax, -0x24(%rbp)
cmpl $-0x1, %eax
jne 0x3a6fd
movq 0xf932(%rip), %rdi      # 0x49ff0
leaq 0x8d83(%rip), %rsi      # 0x43448
callq 0x5360
movq %rax, %rdi
movq 0xf8ac(%rip), %rsi      # 0x49f80
callq 0x53c0
movq -0x58(%rbp), %rdi
movl $0xffffffff, 0x10f29(%rip) # imm = 0xFFFFFFFF
xorl %eax, %eax
movl %eax, %edx
movl $0x1, %ecx
movq %rdx, %rsi
callq 0x3c5f0
jmp 0x3acbf
cmpl $0x3e, -0x24(%rbp)
jne 0x3a725
movq 0xf8e6(%rip), %rdi      # 0x49ff0
leaq 0x8d37(%rip), %rsi      # 0x43448
callq 0x5360
movq %rax, %rdi
movq 0xf860(%rip), %rsi      # 0x49f80
callq 0x53c0
jmp 0x3a727
cmpl $0x3e, -0x24(%rbp)
je 0x3a6a6
jmp 0x3a77a
movb $0x0, -0x11(%rbp)
movq $0x1, -0x38(%rbp)
movq -0x8(%rbp), %rdi
callq 0x2f2b0
movl %eax, -0x24(%rbp)
cmpl $-0x1, %eax
jne 0x3a778
movq -0x58(%rbp), %rdi
movl $0xffffffff, 0x10eb2(%rip) # imm = 0xFFFFFFFF
movq -0x38(%rbp), %rsi
movq -0x30(%rbp), %rdx
movb -0x11(%rbp), %al
andb $0x1, %al
movzbl %al, %ecx
callq 0x3c5f0
jmp 0x3acbf
jmp 0x3a77a
jmp 0x3a77c
movslq -0x24(%rbp), %rcx
leaq 0x10e99(%rip), %rax     # 0x4b620
movzbl (%rax,%rcx), %eax
movl %eax, -0x3c(%rbp)
movq -0x10(%rbp), %rax
testb $0x1, 0x4(%rax)
je 0x3a7a5
cmpl $0x2, -0x3c(%rbp)
jne 0x3a7a5
movl $0x41, -0x24(%rbp)
cmpl $0x1, -0x3c(%rbp)
jne 0x3a7b0
jmp 0x3a902
cmpl $0x2, -0x3c(%rbp)
jne 0x3a7c7
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x3a85c
cmpl $0x3e, -0x24(%rbp)
jne 0x3a85a
cmpq $0x0, -0x38(%rbp)
jbe 0x3a805
cmpl $0x3e, 0x10e31(%rip)    # 0x4b610
jne 0x3a805
movq 0xf808(%rip), %rdi      # 0x49ff0
leaq 0x8c87(%rip), %rsi      # 0x43476
callq 0x5360
movq %rax, %rdi
movq 0xf782(%rip), %rsi      # 0x49f80
callq 0x53c0
jmp 0x3a832
cmpl $0x3e, 0x10e04(%rip)    # 0x4b610
jne 0x3a830
movq 0xf7db(%rip), %rdi      # 0x49ff0
leaq 0x8c2c(%rip), %rsi      # 0x43448
callq 0x5360
movq %rax, %rdi
movq 0xf755(%rip), %rsi      # 0x49f80
callq 0x53c0
jmp 0x3a832
movq -0x58(%rbp), %rdi
movl $0x3e, 0x10dd0(%rip)    # 0x4b610
movq -0x38(%rbp), %rsi
movb -0x11(%rbp), %al
xorl %ecx, %ecx
movl %ecx, %edx
andb $0x1, %al
movzbl %al, %ecx
callq 0x3c5f0
jmp 0x3acbf
jmp 0x3a85c
jmp 0x3a85e
movq -0x8(%rbp), %rdi
callq 0x2f2b0
movl %eax, -0x24(%rbp)
cmpl $-0x1, -0x24(%rbp)
jne 0x3a8fd
cmpq $0x0, -0x38(%rbp)
jbe 0x3a8a8
cmpl $0x3e, 0x10d8e(%rip)    # 0x4b610
jne 0x3a8a8
movq 0xf765(%rip), %rdi      # 0x49ff0
leaq 0x8be4(%rip), %rsi      # 0x43476
callq 0x5360
movq %rax, %rdi
movq 0xf6df(%rip), %rsi      # 0x49f80
callq 0x53c0
jmp 0x3a8d5
cmpl $0x3e, 0x10d61(%rip)    # 0x4b610
jne 0x3a8d3
movq 0xf738(%rip), %rdi      # 0x49ff0
leaq 0x8b89(%rip), %rsi      # 0x43448
callq 0x5360
movq %rax, %rdi
movq 0xf6b2(%rip), %rsi      # 0x49f80
callq 0x53c0
jmp 0x3a8d5
movq -0x58(%rbp), %rdi
movl $0xffffffff, 0x10d2d(%rip) # imm = 0xFFFFFFFF
movq -0x38(%rbp), %rsi
movb -0x11(%rbp), %al
xorl %ecx, %ecx
movl %ecx, %edx
andb $0x1, %al
movzbl %al, %ecx
callq 0x3c5f0
jmp 0x3acbf
jmp 0x3a77c
movslq -0x24(%rbp), %rcx
leaq 0x10d13(%rip), %rax     # 0x4b620
movzbl (%rax,%rcx), %ecx
movl $0x1, %eax
cmpl %ecx, %eax
je 0x3aa5d
movq 0xf69b(%rip), %rdi      # 0x49fc0
leaq 0x47ed(%rip), %rsi      # 0x3f119
callq 0x5360
movq %rax, %rdi
movl $0x1, %esi
callq 0x5750
movq %rax, %rdi
leaq 0x47e7(%rip), %rsi      # 0x3f12f
callq 0x5360
movq %rax, %rdi
leaq -0x22177(%rip), %rsi    # 0x187e0
callq 0x5120
movq %rax, %rdi
movl $0x1, %esi
callq 0x5750
movq %rax, %rdi
leaq -0x22163(%rip), %rsi    # 0x18810
callq 0x5120
movq %rax, %rdi
leaq 0x47b2(%rip), %rsi      # 0x3f134
callq 0x5360
movq %rax, %rdi
movslq -0x24(%rbp), %rcx
leaq 0x10c8b(%rip), %rax     # 0x4b620
movzbl (%rax,%rcx), %esi
callq 0x5620
movq %rax, %rdi
leaq 0x4787(%rip), %rsi      # 0x3f12f
callq 0x5360
movq %rax, %rdi
leaq -0x221d7(%rip), %rsi    # 0x187e0
callq 0x5120
movq %rax, %rdi
movslq -0x24(%rbp), %rcx
leaq 0x10c56(%rip), %rax     # 0x4b620
movzbl (%rax,%rcx), %esi
callq 0x5620
movq %rax, %rdi
leaq -0x221cd(%rip), %rsi    # 0x18810
callq 0x5120
movq %rax, %rdi
leaq 0x6bcc(%rip), %rsi      # 0x415b8
callq 0x5360
movq %rax, %rdi
movq 0xf585(%rip), %rsi      # 0x49f80
callq 0x53c0
movq 0xf5b9(%rip), %rdi      # 0x49fc0
leaq 0x89b0(%rip), %rsi      # 0x433be
callq 0x5360
movq %rax, %rdi
leaq 0x5d6d(%rip), %rsi      # 0x4078a
callq 0x5360
movq %rax, %rdi
movl $0x64, %esi
callq 0x5750
movq %rax, %rdi
movq 0xf547(%rip), %rsi      # 0x49f80
callq 0x53c0
leaq 0x5c25(%rip), %rdi      # 0x4066a
leaq 0x8972(%rip), %rsi      # 0x433be
movl $0x64, %edx
leaq 0x8973(%rip), %rcx      # 0x433cb
callq 0x51e0
jmp 0x3aa5f
xorl %eax, %eax
cmpl $-0x1, -0x24(%rbp)
movb %al, -0x59(%rbp)
je 0x3aa74
cmpl $0x3e, -0x24(%rbp)
setne %al
movb %al, -0x59(%rbp)
movb -0x59(%rbp), %al
testb $0x1, %al
jne 0x3aa80
jmp 0x3ac9d
movq -0x10(%rbp), %rax
testb $0x1, 0x4(%rax)
je 0x3aaa5
movslq -0x24(%rbp), %rcx
leaq 0x10b8b(%rip), %rax     # 0x4b620
movzbl (%rax,%rcx), %eax
cmpl $0x2, %eax
jne 0x3aaa5
movl $0x41, -0x24(%rbp)
movslq -0x24(%rbp), %rcx
leaq 0x10b70(%rip), %rax     # 0x4b620
movb (%rax,%rcx), %al
movb %al, -0x3d(%rbp)
movl -0x24(%rbp), %edi
callq 0x57c0
movl %eax, -0x44(%rbp)
movq -0x10(%rbp), %rax
testb $0x1, 0x5(%rax)
je 0x3aadf
cmpl $0x43, -0x44(%rbp)
jne 0x3aadf
movl $0x54, -0x44(%rbp)
movl $0x54, -0x24(%rbp)
movzbl -0x3d(%rbp), %eax
cmpl $0x1, %eax
jne 0x3ab71
movb $0x1, %al
cmpl $0x41, -0x44(%rbp)
movb %al, -0x5a(%rbp)
je 0x3ab17
movb $0x1, %al
cmpl $0x43, -0x44(%rbp)
movb %al, -0x5a(%rbp)
je 0x3ab17
movb $0x1, %al
cmpl $0x47, -0x44(%rbp)
movb %al, -0x5a(%rbp)
je 0x3ab17
cmpl $0x54, -0x44(%rbp)
sete %al
movb %al, -0x5a(%rbp)
movb -0x5a(%rbp), %al
testb $0x1, %al
jne 0x3ab20
jmp 0x3ab22
jmp 0x3ab41
leaq 0x8984(%rip), %rdi      # 0x434ad
leaq 0x888e(%rip), %rsi      # 0x433be
movl $0x6f, %edx
leaq 0x888f(%rip), %rcx      # 0x433cb
callq 0x51e0
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x3ab6c
movq -0x20(%rbp), %rdi
movslq -0x24(%rbp), %rcx
leaq 0x10ebd(%rip), %rax     # 0x4ba20
movzbl (%rax,%rcx), %esi
callq 0x3c910
jmp 0x3ac8c
movzbl -0x3d(%rbp), %eax
cmpl $0x2, %eax
jne 0x3abf6
movl -0x24(%rbp), %eax
movl %eax, 0x10a8d(%rip)     # 0x4b610
xorl %eax, %eax
cmpl $0x41, -0x44(%rbp)
movb %al, -0x5b(%rbp)
je 0x3abae
xorl %eax, %eax
cmpl $0x43, -0x44(%rbp)
movb %al, -0x5b(%rbp)
je 0x3abae
xorl %eax, %eax
cmpl $0x47, -0x44(%rbp)
movb %al, -0x5b(%rbp)
je 0x3abae
cmpl $0x54, -0x44(%rbp)
setne %al
movb %al, -0x5b(%rbp)
movb -0x5b(%rbp), %al
testb $0x1, %al
jne 0x3abb7
jmp 0x3abb9
jmp 0x3abd8
leaq 0x891e(%rip), %rdi      # 0x434de
leaq 0x87f7(%rip), %rsi      # 0x433be
movl $0x7a, %edx
leaq 0x87f8(%rip), %rcx      # 0x433cb
callq 0x51e0
movq -0x58(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq -0x30(%rbp), %rdx
movb -0x11(%rbp), %al
andb $0x1, %al
movzbl %al, %ecx
callq 0x3c5f0
jmp 0x3acbf
movl -0x24(%rbp), %edi
callq 0x5060
cmpl $0x0, %eax
jne 0x3ac88
movq 0xf3e2(%rip), %rdi      # 0x49ff0
leaq 0x88fa(%rip), %rsi      # 0x4350f
callq 0x5360
movl -0x24(%rbp), %edi
callq 0x5770
cmpl $0x0, %eax
je 0x3ac4a
movl -0x24(%rbp), %eax
movq 0xf3bf(%rip), %rdi      # 0x49ff0
movsbl %al, %esi
callq 0x54a0
movq %rax, %rdi
movq 0xf33d(%rip), %rsi      # 0x49f80
callq 0x53c0
jmp 0x3ac86
movq 0xf39f(%rip), %rdi      # 0x49ff0
leaq 0x516e(%rip), %rsi      # 0x3fdc6
callq 0x5360
movq %rax, %rdi
movl -0x24(%rbp), %esi
callq 0x5750
movq %rax, %rdi
leaq 0x6946(%rip), %rsi      # 0x415b8
callq 0x5360
movq %rax, %rdi
movq 0xf2ff(%rip), %rsi      # 0x49f80
callq 0x53c0
jmp 0x3ac88
jmp 0x3ac8a
jmp 0x3ac8c
movq -0x8(%rbp), %rdi
callq 0x2f2b0
movl %eax, -0x24(%rbp)
jmp 0x3aa5f
movq -0x58(%rbp), %rdi
movl -0x24(%rbp), %eax
movl %eax, 0x10966(%rip)     # 0x4b610
movq -0x38(%rbp), %rsi
movq -0x30(%rbp), %rdx
movb -0x11(%rbp), %al
andb $0x1, %al
movzbl %al, %ecx
callq 0x3c5f0
movq -0x50(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)