// File: /workspace/github_cpp_makefile_star2_O3/zeeev[P]DASVC/bamtools/src/utils/bamtools_fasta.cpp
// Function: BamTools::Fasta::FastaPrivate::GetBase(int const&, int const&, char&)
bool Fasta::FastaPrivate::GetBase(const int& refId, const int& position, char& base) {
  
    // make sure FASTA file is open
    if ( !IsOpen ) {
        cerr << "FASTA error : file not open for reading" << endl;
        return false;
    }
  
    // use index if available
    if ( HasIndex && !Index.empty() ) {
        
        // validate reference id 
        if ( (refId < 0) || (refId >= (int)Index.size()) ) {
            cerr << "FASTA error: invalid refId specified: " << refId << endl;
            return false;
        }
        
        // retrieve reference index data
        const FastaIndexData& referenceData = Index.at(refId);
        
        // validate position 
        if ( (position < 0) || (position > referenceData.Length) ) {
            cerr << "FASTA error: invalid position specified: " << position << endl;
            return false;
        }

        // calculate seek position & attempt jump
        const int64_t lines = position / referenceData.LineLength;
        const int64_t lineOffset = position % referenceData.LineLength;
        const int64_t seekTo = referenceData.Offset + (lines*referenceData.ByteLength) + lineOffset;
        if ( fseek64(Stream, seekTo, SEEK_SET) != 0 ) {
            cerr << "FASTA error : could not seek in file" << endl;
            return false;
        }
        
        // set base & return success
        base = getc(Stream);
        return true;
    }
    
    // else plow through sequentially
    else {
      
        // rewind FASTA file
        if ( !Rewind() ) {
            cerr << "FASTA error : could not rewind FASTA file" << endl;
            return false;
        }
        
        // iterate through fasta entries
        int currentId = 0;
        string header = "";
        string sequence = "";
        
        // get first entry
        GetNextHeader(header);
        GetNextSequence(sequence);
        
        while ( currentId != refId ) {
            GetNextHeader(header);
            GetNextSequence(sequence);
            ++currentId;
        }
        
        // get desired base from sequence 
        // TODO: error reporting on invalid position
        if ( currentId == refId && (sequence.length() >= (size_t)position) ) {          
            base = sequence.at(position);
            return true;
        }
      
        // could not get sequence
        return false;
    }
 
    // return success
    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
cmpb $0x0, 0x8(%rdi)
je 0x624e5
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, %r14
movq %rcx, (%rsp)
cmpb $0x1, 0x18(%rdi)
jne 0x624fa
movq 0x20(%r14), %rcx
movq 0x28(%r14), %rax
cmpq %rax, %rcx
je 0x624fa
movslq (%r12), %rsi
testq %rsi, %rsi
js 0x6260a
subq %rcx, %rax
sarq $0x3, %rax
movabsq $0x6db6db6db6db6db7, %rdx # imm = 0x6DB6DB6DB6DB6DB7
imulq %rax, %rdx
cmpl %edx, %esi
jge 0x6260a
cmpq %rsi, %rdx
jbe 0x626c4
movl (%r15), %eax
testl %eax, %eax
js 0x6266d
imulq $0x38, %rsi, %rdx
cmpl 0x20(%rcx,%rdx), %eax
jg 0x6266d
addq %rdx, %rcx
cltd
idivl 0x30(%rcx)
cltq
movslq 0x34(%rcx), %rsi
imulq %rax, %rsi
addq 0x28(%rcx), %rdx
addq %rdx, %rsi
movq (%r14), %rdi
xorl %edx, %edx
callq 0x27a30
testl %eax, %eax
je 0x626a0
movq 0x2cb17(%rip), %rbx     # 0x8efe0
leaq 0x1388e(%rip), %rsi     # 0x75d5e
movl $0x24, %edx
movq %rbx, %rdi
callq 0x276b0
movq %rbx, %rdi
jmp 0x62696
movq 0x2caf4(%rip), %rbx     # 0x8efe0
leaq 0x137f2(%rip), %rsi     # 0x75ce5
movl $0x27, %edx
jmp 0x6251d
movq (%r14), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x27a30
testl %eax, %eax
je 0x6255f
movq 0x2cacf(%rip), %rbx     # 0x8efe0
leaq 0x136b3(%rip), %rsi     # 0x75bcb
movl $0x29, %edx
movq %rbx, %rdi
callq 0x276b0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x27590
movsbl %al, %esi
movq %rbx, %rdi
callq 0x27040
movq %rax, %rdi
callq 0x27410
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x38(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x142a8(%rip), %r13     # 0x76817
leaq 0x28(%rsp), %rdi
movq %r13, %rsi
movq %r13, %rdx
callq 0x2f1a0
leaq 0x18(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x8(%rsp), %rdi
movq %r13, %rsi
movq %r13, %rdx
callq 0x2f1a0
leaq 0x28(%rsp), %rsi
movq %r14, %rdi
callq 0x61d2c
leaq 0x8(%rsp), %rsi
movq %r14, %rdi
callq 0x62068
cmpl $0x0, (%r12)
je 0x625e3
xorl %ebx, %ebx
leaq 0x28(%rsp), %r13
leaq 0x8(%rsp), %rbp
movq %r14, %rdi
movq %r13, %rsi
callq 0x61d2c
movq %r14, %rdi
movq %rbp, %rsi
callq 0x62068
incl %ebx
cmpl (%r12), %ebx
jne 0x625c5
movq 0x10(%rsp), %rdx
movslq (%r15), %rsi
cmpq %rsi, %rdx
setae %bpl
jb 0x6263c
jbe 0x626b6
movq 0x8(%rsp), %rdi
movb (%rdi,%rsi), %al
movq (%rsp), %rcx
movb %al, (%rcx)
jmp 0x62641
movq 0x2c9cf(%rip), %rbx     # 0x8efe0
leaq 0x136f5(%rip), %rsi     # 0x75d0d
movl $0x26, %edx
movq %rbx, %rdi
callq 0x276b0
movl (%r12), %esi
movq %rbx, %rdi
callq 0x27ab0
movq %rax, %rbx
movq (%rax), %rax
jmp 0x62528
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x62650
callq 0x27560
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0x6254e
callq 0x27560
jmp 0x6254e
movq 0x2c96c(%rip), %rbx     # 0x8efe0
leaq 0x136b9(%rip), %rsi     # 0x75d34
movl $0x29, %edx
movq %rbx, %rdi
callq 0x276b0
movl (%r15), %esi
movq %rbx, %rdi
callq 0x27ab0
movq %rax, %rdi
callq 0x27310
jmp 0x6254c
movq (%r14), %rdi
callq 0x271d0
movq (%rsp), %rcx
movb %al, (%rcx)
movb $0x1, %bpl
jmp 0x6254e
leaq 0xf04b(%rip), %rdi      # 0x71708
xorl %eax, %eax
callq 0x278b0
leaq 0xf09b(%rip), %rdi      # 0x71766
xorl %eax, %eax
callq 0x278b0
movq %rax, %rbx
jmp 0x626f0
jmp 0x626d9
movq %rax, %rbx
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x626f0
callq 0x27560
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0x62704
callq 0x27560
movq %rbx, %rdi
callq 0x27b10