// File: /workspace/github_cpp_makefile_star2_O2/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 $0x58, %rsp
cmpb $0x0, 0x8(%rdi)
je 0x647d1
movq %rcx, %rbx
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, %r14
cmpb $0x1, 0x18(%rdi)
jne 0x647e4
movq 0x20(%r14), %rcx
movq 0x28(%r14), %rax
cmpq %rax, %rcx
je 0x647e4
movslq (%r12), %rsi
testq %rsi, %rsi
js 0x648cb
subq %rcx, %rax
pushq $0x38
popq %rcx
cqto
idivq %rcx
cmpl %eax, %esi
jge 0x648cb
leaq 0x20(%r14), %rdi
callq 0x65004
movq %rax, %rcx
movl (%r15), %eax
testl %eax, %eax
js 0x648ec
cmpl 0x20(%rcx), %eax
jg 0x648ec
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 0x35a60
testl %eax, %eax
je 0x64904
movq 0x3081b(%rip), %rdi     # 0x94fe0
leaq 0x11558(%rip), %rsi     # 0x75d24
jmp 0x64874
movq 0x30808(%rip), %rdi     # 0x94fe0
leaq 0x114cc(%rip), %rsi     # 0x75cab
jmp 0x64874
movq %r14, %rdi
callq 0x641b2
testb %al, %al
je 0x64866
movq %rbx, 0x10(%rsp)
leaq 0x11ffb(%rip), %r13     # 0x767f7
leaq 0x38(%rsp), %rdi
leaq 0x18(%rsp), %rdx
movq %r13, %rsi
callq 0x35280
leaq 0x18(%rsp), %rdi
leaq 0xf(%rsp), %rdx
movq %r13, %rsi
callq 0x35280
leaq 0x38(%rsp), %rsi
movq %r14, %rdi
callq 0x641d2
leaq 0x18(%rsp), %rsi
movq %r14, %rdi
callq 0x64428
xorl %ebx, %ebx
leaq 0x38(%rsp), %r13
leaq 0x18(%rsp), %rbp
cmpl (%r12), %ebx
je 0x64894
movq %r14, %rdi
movq %r13, %rsi
callq 0x641d2
movq %r14, %rdi
movq %rbp, %rsi
callq 0x64428
incl %ebx
jmp 0x64846
movq 0x30773(%rip), %rdi     # 0x94fe0
leaq 0x1131d(%rip), %rsi     # 0x75b91
callq 0x355b0
movq %rax, %rdi
callq 0x35300
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movslq (%r15), %rsi
cmpq %rsi, 0x20(%rsp)
setae %bpl
jb 0x648b5
leaq 0x18(%rsp), %rdi
callq 0x35c50
movb (%rax), %al
movq 0x10(%rsp), %rcx
movb %al, (%rcx)
leaq 0x18(%rsp), %rdi
callq 0x35730
leaq 0x38(%rsp), %rdi
callq 0x35730
jmp 0x64883
movq 0x3070e(%rip), %rdi     # 0x94fe0
leaq 0x113fa(%rip), %rsi     # 0x75cd3
callq 0x355b0
movl (%r12), %esi
movq %rax, %rdi
callq 0x35b00
jmp 0x64879
movq 0x306ed(%rip), %rdi     # 0x94fe0
leaq 0x11400(%rip), %rsi     # 0x75cfa
callq 0x355b0
movl (%r15), %esi
jmp 0x648e2
movq (%r14), %rdi
callq 0x351d0
movb %al, (%rbx)
movb $0x1, %bpl
jmp 0x64883
jmp 0x64918
movq %rax, %rbx
jmp 0x6492c
jmp 0x6491f
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x35730
leaq 0x38(%rsp), %rdi
callq 0x35730
movq %rbx, %rdi
callq 0x35b50
movq %rax, %rdi
callq 0x3a198