// File: zeeev[P]DASVC/bamtools/src/utils/bamtools_fasta.cpp
// Function: BamTools::Fasta::FastaPrivate::GetSequence(int const&, int const&, int const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)
bool Fasta::FastaPrivate::GetSequence(const int& refId, const int& start, const int& stop, string& sequence) {
 
    // 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 stop position 
        if ( (start < 0) || (start > stop) || (stop > referenceData.Length) ) {
            cerr << "FASTA error: invalid start/stop positions specified: " << start << ", " << stop << endl;
            return false;
        }
        
        // seek to beginning of sequence data
        if ( fseeko(Stream, referenceData.Offset, SEEK_SET) != 0 ) {
            cerr << "FASTA error : could not sek in file" << endl;
            return false;
        }
      
        // retrieve full sequence
        string fullSequence = "";
        if ( !GetNextSequence(fullSequence) ) {
            cerr << "FASTA error : could not retrieve sequence from FASTA file" << endl;
            return false;
        }
        
        // set sub-sequence & return success
        const int seqLength = (stop - start) + 1;
        sequence = fullSequence.substr(start, seqLength);
        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 fullSequence = "";
        
        // get first entry
        GetNextHeader(header);
        GetNextSequence(fullSequence);
        
        while ( currentId != refId ) {
            GetNextHeader(header);
            GetNextSequence(fullSequence);
            ++currentId;
        }
        
        // get desired substring from sequence
        // TODO: error reporting on invalid start/stop positions
        if ( currentId == refId && (fullSequence.length() >= (size_t)stop) ) {          
            const int seqLength = (stop - start) + 1;
            sequence = fullSequence.substr(start, seqLength);
            return true;
        }
      
        // could not get sequence
        return false;
    }
  
    // return success
    return true;
}

// Assembly:
subq $0x158, %rsp            # imm = 0x158
movq %rdi, 0x148(%rsp)
movq %rsi, 0x140(%rsp)
movq %rdx, 0x138(%rsp)
movq %rcx, 0x130(%rsp)
movq %r8, 0x128(%rsp)
movq 0x148(%rsp), %rax
movq %rax, 0x40(%rsp)
testb $0x1, 0x8(%rax)
jne 0x10b511
movq 0x59af7(%rip), %rdi     # 0x164fe0
leaq 0x28975(%rip), %rsi     # 0x133e65
callq 0x86700
movq %rax, %rdi
movq 0x59a71(%rip), %rsi     # 0x164f70
callq 0x86770
movb $0x0, 0x157(%rsp)
jmp 0x10bb2d
movq 0x40(%rsp), %rax
testb $0x1, 0x18(%rax)
je 0x10b86a
movq 0x40(%rsp), %rdi
addq $0x20, %rdi
callq 0x10c340
testb $0x1, %al
jne 0x10b86a
movq 0x140(%rsp), %rax
cmpl $0x0, (%rax)
jl 0x10b56a
movq 0x40(%rsp), %rdi
movq 0x140(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x3c(%rsp)
addq $0x20, %rdi
callq 0x10c390
movq %rax, %rcx
movl 0x3c(%rsp), %eax
cmpl %ecx, %eax
jl 0x10b5ab
movq 0x59a6f(%rip), %rdi     # 0x164fe0
leaq 0x28915(%rip), %rsi     # 0x133e8d
callq 0x86700
movq %rax, %rdi
movq 0x140(%rsp), %rax
movl (%rax), %esi
callq 0x86d40
movq %rax, %rdi
movq 0x599d7(%rip), %rsi     # 0x164f70
callq 0x86770
movb $0x0, 0x157(%rsp)
jmp 0x10bb2d
movq 0x40(%rsp), %rdi
addq $0x20, %rdi
movq 0x140(%rsp), %rax
movslq (%rax), %rsi
callq 0x10c3b0
movq %rax, 0x120(%rsp)
movq 0x138(%rsp), %rax
cmpl $0x0, (%rax)
jl 0x10b606
movq 0x138(%rsp), %rax
movl (%rax), %eax
movq 0x130(%rsp), %rcx
cmpl (%rcx), %eax
jg 0x10b606
movq 0x130(%rsp), %rax
movl (%rax), %eax
movq 0x120(%rsp), %rcx
cmpl 0x20(%rcx), %eax
jle 0x10b668
movq 0x599d3(%rip), %rdi     # 0x164fe0
leaq 0x288ef(%rip), %rsi     # 0x133f03
callq 0x86700
movq %rax, %rdi
movq 0x138(%rsp), %rax
movl (%rax), %esi
callq 0x86d40
movq %rax, %rdi
leaq 0x28904(%rip), %rsi     # 0x133f39
callq 0x86700
movq %rax, %rdi
movq 0x130(%rsp), %rax
movl (%rax), %esi
callq 0x86d40
movq %rax, %rdi
movq 0x5991a(%rip), %rsi     # 0x164f70
callq 0x86770
movb $0x0, 0x157(%rsp)
jmp 0x10bb2d
movq 0x40(%rsp), %rax
movq (%rax), %rdi
movq 0x120(%rsp), %rax
movq 0x28(%rax), %rsi
xorl %edx, %edx
callq 0x86c60
cmpl $0x0, %eax
je 0x10b6b7
movq 0x59951(%rip), %rdi     # 0x164fe0
leaq 0x288a6(%rip), %rsi     # 0x133f3c
callq 0x86700
movq %rax, %rdi
movq 0x598cb(%rip), %rsi     # 0x164f70
callq 0x86770
movb $0x0, 0x157(%rsp)
jmp 0x10bb2d
leaq 0xff(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x86da0
movq 0x30(%rsp), %rdx
leaq 0x2959e(%rip), %rsi     # 0x134c73
leaq 0x100(%rsp), %rdi
callq 0x86a00
jmp 0x10b6e4
leaq 0xff(%rsp), %rdi
callq 0x867b0
movq 0x40(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x10a970
movb %al, 0x2f(%rsp)
jmp 0x10b709
movb 0x2f(%rsp), %al
testb $0x1, %al
jne 0x10b79b
jmp 0x10b717
movq 0x598c2(%rip), %rdi     # 0x164fe0
leaq 0x2883b(%rip), %rsi     # 0x133f60
callq 0x86700
movq %rax, 0x20(%rsp)
jmp 0x10b731
movq 0x20(%rsp), %rdi
movq 0x59833(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0x10b744
movb $0x0, 0x157(%rsp)
movl $0x1, 0xe8(%rsp)
jmp 0x10b844
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
leaq 0xff(%rsp), %rdi
callq 0x867b0
jmp 0x10bb3e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
jmp 0x10b856
movq 0x130(%rsp), %rax
movl (%rax), %eax
movq 0x138(%rsp), %rcx
movl (%rcx), %ecx
subl %ecx, %eax
incl %eax
movl %eax, 0xe4(%rsp)
movq 0x138(%rsp), %rax
movslq (%rax), %rdx
movslq 0xe4(%rsp), %rcx
leaq 0xc0(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x86750
jmp 0x10b7e4
movq 0x128(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x86070
jmp 0x10b7fb
leaq 0xc0(%rsp), %rdi
callq 0x86f68
jmp 0x10b80a
movb $0x1, 0x157(%rsp)
movl $0x1, 0xe8(%rsp)
jmp 0x10b844
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0x86f68
jmp 0x10b842
jmp 0x10b856
leaq 0x100(%rsp), %rdi
callq 0x86f68
jmp 0x10bb2d
leaq 0x100(%rsp), %rdi
callq 0x86f68
jmp 0x10b865
jmp 0x10bb3e
movq 0x40(%rsp), %rdi
callq 0x10a420
testb $0x1, %al
jne 0x10b8a7
movq 0x59761(%rip), %rdi     # 0x164fe0
leaq 0x284c5(%rip), %rsi     # 0x133d4b
callq 0x86700
movq %rax, %rdi
movq 0x596db(%rip), %rsi     # 0x164f70
callq 0x86770
movb $0x0, 0x157(%rsp)
jmp 0x10bb2d
movl $0x0, 0xbc(%rsp)
leaq 0x97(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x86da0
movq 0x18(%rsp), %rdx
leaq 0x293a3(%rip), %rsi     # 0x134c73
leaq 0x98(%rsp), %rdi
callq 0x86a00
jmp 0x10b8df
leaq 0x97(%rsp), %rdi
callq 0x867b0
leaq 0x6f(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x86da0
movq 0x10(%rsp), %rdx
leaq 0x2936c(%rip), %rsi     # 0x134c73
leaq 0x70(%rsp), %rdi
callq 0x86a00
jmp 0x10b913
leaq 0x6f(%rsp), %rdi
callq 0x867b0
movq 0x40(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x10a470
jmp 0x10b931
movq 0x40(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x10a970
jmp 0x10b942
jmp 0x10b944
movl 0xbc(%rsp), %eax
movq 0x140(%rsp), %rcx
cmpl (%rcx), %eax
je 0x10b9f5
movq 0x40(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x10a470
jmp 0x10b96f
movq 0x40(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x10a970
jmp 0x10b980
movl 0xbc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xbc(%rsp)
jmp 0x10b944
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
leaq 0x97(%rsp), %rdi
callq 0x867b0
jmp 0x10bb3e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
leaq 0x6f(%rsp), %rdi
callq 0x867b0
jmp 0x10bb1c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
jmp 0x10bb0e
movl 0xbc(%rsp), %eax
movq 0x140(%rsp), %rcx
cmpl (%rcx), %eax
jne 0x10baca
leaq 0x70(%rsp), %rdi
callq 0x86ac0
movq %rax, 0x8(%rsp)
jmp 0x10ba1d
movq 0x8(%rsp), %rax
movq 0x130(%rsp), %rcx
movslq (%rcx), %rcx
cmpq %rcx, %rax
jb 0x10baca
movq 0x130(%rsp), %rax
movl (%rax), %eax
movq 0x138(%rsp), %rcx
movl (%rcx), %ecx
subl %ecx, %eax
incl %eax
movl %eax, 0x68(%rsp)
movq 0x138(%rsp), %rax
movslq (%rax), %rdx
movslq 0x68(%rsp), %rcx
leaq 0x48(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x86750
jmp 0x10ba73
movq 0x128(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x86070
jmp 0x10ba87
leaq 0x48(%rsp), %rdi
callq 0x86f68
jmp 0x10ba93
movb $0x1, 0x157(%rsp)
movl $0x1, 0xe8(%rsp)
jmp 0x10badd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x86f68
jmp 0x10bac8
jmp 0x10bb0e
movb $0x0, 0x157(%rsp)
movl $0x1, 0xe8(%rsp)
leaq 0x70(%rsp), %rdi
callq 0x86f68
jmp 0x10bae9
leaq 0x98(%rsp), %rdi
callq 0x86f68
jmp 0x10bb2d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf0(%rsp)
movl %eax, 0xec(%rsp)
jmp 0x10bb1c
leaq 0x70(%rsp), %rdi
callq 0x86f68
jmp 0x10bb1a
jmp 0x10bb1c
leaq 0x98(%rsp), %rdi
callq 0x86f68
jmp 0x10bb2b
jmp 0x10bb3e
movb 0x157(%rsp), %al
andb $0x1, %al
addq $0x158, %rsp            # imm = 0x158
retq
movq 0xf0(%rsp), %rdi
callq 0x86d80
movq %rax, %rdi
callq 0x91290
nopw %cs:(%rax,%rax)