// File: zeeev[P]DASVC/bamtools/src/utils/bamtools_fasta.cpp
// Function: BamTools::Fasta::FastaPrivate::CreateIndex(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
bool Fasta::FastaPrivate::CreateIndex(const string& indexFilename) {
  
    // check that file is open
    if ( !IsOpen ) {
        cerr << "FASTA error : cannot create index, FASTA file not open" << endl;
        return false;
    }
  
    // rewind FASTA file
    if ( !Rewind() ) {
        cerr << "FASTA error : could not rewind FASTA file" << endl;
        return false;
    }
    
    // clear out prior index data
    Index.clear();
    
    // -------------------------------------------
    // calculate lineLength & byteLength
    
    int lineLength = 0;
    int byteLength = 0;
    
    // skip over header
    char buffer[1024];
    if ( fgets(buffer, 1024, Stream) == 0 ) {
        cerr << "FASTA error : could not read from file" << endl;
        return false;
    }
    if ( feof(Stream) ) return false;
    if ( buffer[0] != '>' ) { 
        cerr << "FASTA error : expected header ('>'), instead : " << buffer[0] << endl;
        return false;
    }
  
    // read in first line of sequence  
    char c = fgetc(Stream);
    while ( (c >= 0) && (c != '\n') ) {
        ++byteLength;
        if (isgraph(c)) ++lineLength;
        c = fgetc(Stream);
    }
    ++byteLength; // store newline
    
    // 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 = "";
    while ( GetNextHeader(header) ) {
        
        // ---------------------------
        // build index entry data
        FastaIndexData data;
        
        // store file offset of beginning of DNA sequence (after header)
        data.Offset = ftello(Stream);
        
        // parse header, store sequence name in data.Name
        if ( !GetNameFromHeader(header, data.Name) ) {
            cerr << "FASTA error : could not parse read name from FASTA header" << endl;
            return false;
        }
        
        // retrieve FASTA sequence
        if ( !GetNextSequence(sequence) ) {
            cerr << "FASTA error : could not read in next sequence from FASTA file" << endl;
            return false;
        }
        
        // store sequence length & line/byte lengths
        data.Length = sequence.length();
        data.LineLength = lineLength;
        data.ByteLength = byteLength;
        
        // store index entry
        Index.push_back(data);
        
        // update ref Id
        ++currentId;
    }
    
    // open index file
    if ( !indexFilename.empty() ) {
        IndexStream = fopen(indexFilename.c_str(), "wb");
        if ( !IndexStream ) {
            cerr << "FASTA error : Could not open " << indexFilename << " for writing." << endl;
            return false;
        }
        IsIndexOpen = true;
    }
    
    // write index data
    if ( !WriteIndexData() ) return false;
    HasIndex = true;
    
    // close index file
    fclose(IndexStream);
    IsIndexOpen = false;
    
    // return succes status
    return true;
}

// Assembly:
subq $0x568, %rsp            # imm = 0x568
movq %rdi, 0x558(%rsp)
movq %rsi, 0x550(%rsp)
movq 0x558(%rsp), %rax
movq %rax, 0x90(%rsp)
testb $0x1, 0x8(%rax)
jne 0x109d5c
movq 0x5b2ac(%rip), %rdi     # 0x164fe0
leaq 0x29fd9(%rip), %rsi     # 0x133d14
callq 0x86700
movq %rax, %rdi
movq 0x5b226(%rip), %rsi     # 0x164f70
callq 0x86770
movb $0x0, 0x567(%rsp)
jmp 0x10a3fa
movq 0x90(%rsp), %rdi
callq 0x10a420
testb $0x1, %al
jne 0x109d9c
movq 0x5b26c(%rip), %rdi     # 0x164fe0
leaq 0x29fd0(%rip), %rsi     # 0x133d4b
callq 0x86700
movq %rax, %rdi
movq 0x5b1e6(%rip), %rsi     # 0x164f70
callq 0x86770
movb $0x0, 0x567(%rsp)
jmp 0x10a3fa
movq 0x90(%rsp), %rdi
addq $0x20, %rdi
callq 0x10c290
movq 0x90(%rsp), %rax
movl $0x0, 0x54c(%rsp)
movl $0x0, 0x548(%rsp)
leaq 0x140(%rsp), %rdi
movq (%rax), %rdx
movl $0x400, %esi            # imm = 0x400
callq 0x86ba0
cmpq $0x0, %rax
jne 0x109e15
movq 0x5b1f3(%rip), %rdi     # 0x164fe0
leaq 0x29f81(%rip), %rsi     # 0x133d75
callq 0x86700
movq %rax, %rdi
movq 0x5b16d(%rip), %rsi     # 0x164f70
callq 0x86770
movb $0x0, 0x567(%rsp)
jmp 0x10a3fa
movq 0x90(%rsp), %rax
movq (%rax), %rdi
callq 0x86b10
cmpl $0x0, %eax
je 0x109e37
movb $0x0, 0x567(%rsp)
jmp 0x10a3fa
movsbl 0x140(%rsp), %eax
cmpl $0x3e, %eax
je 0x109e83
movq 0x5b195(%rip), %rdi     # 0x164fe0
leaq 0x29f4a(%rip), %rsi     # 0x133d9c
callq 0x86700
movq %rax, %rdi
movsbl 0x140(%rsp), %esi
callq 0x86890
movq %rax, %rdi
movq 0x5b0ff(%rip), %rsi     # 0x164f70
callq 0x86770
movb $0x0, 0x567(%rsp)
jmp 0x10a3fa
movq 0x90(%rsp), %rax
movq (%rax), %rdi
callq 0x86b70
movb %al, 0x13f(%rsp)
movsbl 0x13f(%rsp), %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, 0x8f(%rsp)
jl 0x109ec5
movsbl 0x13f(%rsp), %eax
cmpl $0xa, %eax
setne %al
movb %al, 0x8f(%rsp)
movb 0x8f(%rsp), %al
testb $0x1, %al
jne 0x109ed2
jmp 0x109f22
movl 0x548(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x548(%rsp)
movsbl 0x13f(%rsp), %edi
callq 0x86680
cmpl $0x0, %eax
je 0x109f06
movl 0x54c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54c(%rsp)
movq 0x90(%rsp), %rax
movq (%rax), %rdi
callq 0x86b70
movb %al, 0x13f(%rsp)
jmp 0x109e9a
movq 0x90(%rsp), %rdi
movl 0x548(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x548(%rsp)
callq 0x10a420
testb $0x1, %al
jne 0x109f73
movq 0x5b095(%rip), %rdi     # 0x164fe0
leaq 0x29df9(%rip), %rsi     # 0x133d4b
callq 0x86700
movq %rax, %rdi
movq 0x5b00f(%rip), %rsi     # 0x164f70
callq 0x86770
movb $0x0, 0x567(%rsp)
jmp 0x10a3fa
movl $0x0, 0x138(%rsp)
leaq 0x117(%rsp), %rdi
movq %rdi, 0x80(%rsp)
callq 0x86da0
movq 0x80(%rsp), %rdx
leaq 0x2acd1(%rip), %rsi     # 0x134c73
leaq 0x118(%rsp), %rdi
callq 0x86a00
jmp 0x109fb1
leaq 0x117(%rsp), %rdi
callq 0x867b0
leaq 0xdf(%rsp), %rdi
movq %rdi, 0x78(%rsp)
callq 0x86da0
movq 0x78(%rsp), %rdx
leaq 0x2ac97(%rip), %rsi     # 0x134c73
leaq 0xe0(%rsp), %rdi
callq 0x86a00
jmp 0x109feb
leaq 0xdf(%rsp), %rdi
callq 0x867b0
movq 0x90(%rsp), %rdi
leaq 0x118(%rsp), %rsi
callq 0x10a470
movb %al, 0x77(%rsp)
jmp 0x10a013
movb 0x77(%rsp), %al
testb $0x1, %al
jne 0x10a020
jmp 0x10a258
leaq 0xa0(%rsp), %rdi
callq 0x10c2b0
jmp 0x10a02f
movq 0x90(%rsp), %rax
movq (%rax), %rdi
callq 0x86af0
movq %rax, 0x68(%rsp)
jmp 0x10a046
movq 0x90(%rsp), %rdi
movq 0x68(%rsp), %rax
movq %rax, 0xc8(%rsp)
leaq 0x118(%rsp), %rsi
leaq 0xa0(%rsp), %rdx
callq 0x10a6b0
movb %al, 0x67(%rsp)
jmp 0x10a076
movb 0x67(%rsp), %al
testb $0x1, %al
jne 0x10a154
jmp 0x10a084
movq 0x5af55(%rip), %rdi     # 0x164fe0
leaq 0x29d3a(%rip), %rsi     # 0x133dcc
callq 0x86700
movq %rax, 0x58(%rsp)
jmp 0x10a09e
movq 0x58(%rsp), %rdi
movq 0x5aec6(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0x10a0b1
movb $0x0, 0x567(%rsp)
movl $0x1, 0x9c(%rsp)
jmp 0x10a22e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
leaq 0x117(%rsp), %rdi
callq 0x867b0
jmp 0x10a40b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
leaq 0xdf(%rsp), %rdi
callq 0x867b0
jmp 0x10a3e9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
jmp 0x10a3d8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0x10c330
jmp 0x10a253
movq 0x90(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x10a970
movb %al, 0x57(%rsp)
jmp 0x10a16f
movb 0x57(%rsp), %al
testb $0x1, %al
jne 0x10a1bb
jmp 0x10a179
movq 0x5ae60(%rip), %rdi     # 0x164fe0
leaq 0x29c7f(%rip), %rsi     # 0x133e06
callq 0x86700
movq %rax, 0x48(%rsp)
jmp 0x10a193
movq 0x48(%rsp), %rdi
movq 0x5add1(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0x10a1a6
movb $0x0, 0x567(%rsp)
movl $0x1, 0x9c(%rsp)
jmp 0x10a22e
leaq 0xe0(%rsp), %rdi
callq 0x86ac0
movq %rax, 0x40(%rsp)
jmp 0x10a1cf
movq 0x90(%rsp), %rdi
movq 0x40(%rsp), %rax
movl %eax, 0xc0(%rsp)
movl 0x54c(%rsp), %eax
movl %eax, 0xd0(%rsp)
movl 0x548(%rsp), %eax
movl %eax, 0xd4(%rsp)
addq $0x20, %rdi
leaq 0xa0(%rsp), %rsi
callq 0x10c2c0
jmp 0x10a212
movl 0x138(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x138(%rsp)
movl $0x0, 0x9c(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0x10c330
jmp 0x10a23d
movl 0x9c(%rsp), %eax
testl %eax, %eax
jne 0x10a3a4
jmp 0x10a24e
jmp 0x109ff8
jmp 0x10a3d8
movq 0x550(%rsp), %rdi
callq 0x86c90
movb %al, 0x3f(%rsp)
jmp 0x10a26b
movb 0x3f(%rsp), %al
testb $0x1, %al
jne 0x10a33c
jmp 0x10a279
movq 0x550(%rsp), %rdi
callq 0x86320
movq %rax, 0x30(%rsp)
jmp 0x10a28d
movq 0x30(%rsp), %rdi
leaq 0x29bab(%rip), %rsi     # 0x133e44
callq 0x86810
movq %rax, 0x28(%rsp)
jmp 0x10a2a5
movq 0x90(%rsp), %rax
movq 0x28(%rsp), %rcx
movq %rcx, 0x10(%rax)
cmpq $0x0, 0x10(%rax)
jne 0x10a330
movq 0x5ad1c(%rip), %rdi     # 0x164fe0
leaq 0x29b7c(%rip), %rsi     # 0x133e47
callq 0x86700
movq %rax, 0x20(%rsp)
jmp 0x10a2d7
movq 0x20(%rsp), %rdi
movq 0x550(%rsp), %rsi
callq 0x86640
movq %rax, 0x18(%rsp)
jmp 0x10a2f0
movq 0x18(%rsp), %rdi
leaq 0x25349(%rip), %rsi     # 0x12f645
callq 0x86700
movq %rax, 0x10(%rsp)
jmp 0x10a308
movq 0x10(%rsp), %rdi
movq 0x5ac5c(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0x10a31b
movb $0x0, 0x567(%rsp)
movl $0x1, 0x9c(%rsp)
jmp 0x10a3a4
movq 0x90(%rsp), %rax
movb $0x1, 0x19(%rax)
movq 0x90(%rsp), %rdi
callq 0x10ac00
movb %al, 0xf(%rsp)
jmp 0x10a34f
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0x10a36e
jmp 0x10a359
movb $0x0, 0x567(%rsp)
movl $0x1, 0x9c(%rsp)
jmp 0x10a3a4
movq 0x90(%rsp), %rax
movb $0x1, 0x18(%rax)
movq 0x10(%rax), %rdi
callq 0x86710
jmp 0x10a385
movq 0x90(%rsp), %rax
movb $0x0, 0x19(%rax)
movb $0x1, 0x567(%rsp)
movl $0x1, 0x9c(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x86f68
jmp 0x10a3b3
leaq 0x118(%rsp), %rdi
callq 0x86f68
jmp 0x10a3fa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x108(%rsp)
movl %eax, 0x104(%rsp)
jmp 0x10a3e9
leaq 0xe0(%rsp), %rdi
callq 0x86f68
jmp 0x10a3e7
jmp 0x10a3e9
leaq 0x118(%rsp), %rdi
callq 0x86f68
jmp 0x10a3f8
jmp 0x10a40b
movb 0x567(%rsp), %al
andb $0x1, %al
addq $0x568, %rsp            # imm = 0x568
retq
movq 0x108(%rsp), %rdi
callq 0x86d80
movq %rax, %rdi
callq 0x91290