// File: /workspace/github_cpp_makefile_star2_O1/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 0x62a31
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, %r14
movq %rcx, (%rsp)
cmpb $0x1, 0x18(%rdi)
jne 0x62a46
movq 0x20(%r14), %rcx
movq 0x28(%r14), %rax
cmpq %rax, %rcx
je 0x62a46
movslq (%r12), %rsi
testq %rsi, %rsi
js 0x62b85
subq %rcx, %rax
sarq $0x3, %rax
movabsq $0x6db6db6db6db6db7, %rdx # imm = 0x6DB6DB6DB6DB6DB7
imulq %rax, %rdx
cmpl %edx, %esi
jge 0x62b85
cmpq %rsi, %rdx
jbe 0x62c0e
movl (%r15), %eax
testl %eax, %eax
js 0x62bb7
imulq $0x38, %rsi, %rdx
cmpl 0x20(%rcx,%rdx), %eax
jg 0x62bb7
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 0x27a40
testl %eax, %eax
je 0x62bea
movq 0x2d5cb(%rip), %rbx     # 0x8ffe0
leaq 0x14342(%rip), %rsi     # 0x76d5e
movl $0x24, %edx
movq %rbx, %rdi
callq 0x276c0
movq %rbx, %rdi
jmp 0x62be0
movq 0x2d5a8(%rip), %rbx     # 0x8ffe0
leaq 0x142a6(%rip), %rsi     # 0x76ce5
movl $0x27, %edx
jmp 0x62a69
movq (%r14), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x27a40
testl %eax, %eax
je 0x62aab
movq 0x2d583(%rip), %rbx     # 0x8ffe0
leaq 0x14167(%rip), %rsi     # 0x76bcb
movl $0x29, %edx
movq %rbx, %rdi
callq 0x276c0
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 0x14d60(%rip), %r13     # 0x7781b
leaq 0x28(%rsp), %rdi
movq %r13, %rsi
movq %r13, %rdx
callq 0x2f1b2
leaq 0x18(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x8(%rsp), %rdi
movq %r13, %rsi
movq %r13, %rdx
callq 0x2f1b2
leaq 0x28(%rsp), %rsi
movq %r14, %rdi
callq 0x6224c
leaq 0x8(%rsp), %rsi
movq %r14, %rdi
callq 0x62594
cmpl $0x0, (%r12)
je 0x62b2f
xorl %ebx, %ebx
leaq 0x28(%rsp), %r13
leaq 0x8(%rsp), %rbp
movq %r14, %rdi
movq %r13, %rsi
callq 0x6224c
movq %r14, %rdi
movq %rbp, %rsi
callq 0x62594
incl %ebx
cmpl (%r12), %ebx
jne 0x62b11
movq 0x10(%rsp), %rdx
movslq (%r15), %rsi
cmpq %rsi, %rdx
setae %bpl
jb 0x62b54
jbe 0x62c00
movq 0x8(%rsp), %rax
movb (%rax,%rsi), %al
movq (%rsp), %rcx
movb %al, (%rcx)
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x62b68
callq 0x27560
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0x62a9a
callq 0x27560
jmp 0x62a9a
movq 0x2d454(%rip), %rbx     # 0x8ffe0
leaq 0x1417a(%rip), %rsi     # 0x76d0d
movl $0x26, %edx
movq %rbx, %rdi
callq 0x276c0
movl (%r12), %esi
movq %rbx, %rdi
callq 0x27ac0
movq %rax, %rbx
movq (%rax), %rax
jmp 0x62a74
movq 0x2d422(%rip), %rbx     # 0x8ffe0
leaq 0x1416f(%rip), %rsi     # 0x76d34
movl $0x29, %edx
movq %rbx, %rdi
callq 0x276c0
movl (%r15), %esi
movq %rbx, %rdi
callq 0x27ac0
movq %rax, %rdi
callq 0x27310
jmp 0x62a98
movq (%r14), %rdi
callq 0x271d0
movq (%rsp), %rcx
movb %al, (%rcx)
movb $0x1, %bpl
jmp 0x62a9a
leaq 0xfb01(%rip), %rdi      # 0x72708
xorl %eax, %eax
callq 0x278c0
leaq 0xfb51(%rip), %rdi      # 0x72766
xorl %eax, %eax
callq 0x278c0
movq %rax, %rbx
jmp 0x62c3a
jmp 0x62c23
movq %rax, %rbx
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x62c3a
callq 0x27560
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rax
cmpq %rax, %rdi
je 0x62c4e
callq 0x27560
movq %rbx, %rdi
callq 0x27b20