// File: zeeev[P]DASVC/bamtools/src/utils/bamtools_filter_engine.h
// Function: bool BamTools::FilterEngine<BamTools::BamAlignmentChecker>::parseToken<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, BamTools::PropertyFilterValue::ValueCompareType&)
bool FilterEngine<FilterChecker>::parseToken(const std::string& token, T& value, PropertyFilterValue::ValueCompareType& type) {
    
    // skip if token is empty
    if ( token.empty() ) return false;
    
    // will store token after special chars are removed
    std::string strippedToken;
    
    // if only single character
    if ( token.length() == 1 ) {
        strippedToken = token;
        type = PropertyFilterValue::EXACT;
    } 
    
    // more than one character, check for special chars
    else {
        const int firstChar = (int)token.at(0);
        switch ( firstChar ) {
          
            case ( FilterEngine<FilterChecker>::NOT_CHAR ) :
                strippedToken = token.substr(1);       
                type = PropertyFilterValue::NOT;
                break;
                
            case ( FilterEngine<FilterChecker>::GREATER_THAN_CHAR ) :
                
                // check for '>=' case
                if ( token.at(1) == FilterEngine<FilterChecker>::EQUAL_CHAR ) {
                    if ( token.length() == 2 ) return false;
                    strippedToken = token.substr(2);
                    type = PropertyFilterValue::GREATER_THAN_EQUAL;
                } 
                
                // otherwise only '>'
                else {
                    strippedToken = token.substr(1);
                    type = PropertyFilterValue::GREATER_THAN;
                }
                
                break;
                
            case ( FilterEngine<FilterChecker>::LESS_THAN_CHAR ) : 
         
                // check for '<=' case
                if ( token.at(1) == FilterEngine<FilterChecker>::EQUAL_CHAR ) {
                    if ( token.length() == 2 ) return false;
                    strippedToken = token.substr(2);
                    type = PropertyFilterValue::LESS_THAN_EQUAL;
                } 
                
                // otherwise only '<'
                else {
                    strippedToken = token.substr(1);
                    type = PropertyFilterValue::LESS_THAN;
                }
                
                break;
                
            case ( FilterEngine<FilterChecker>::WILDCARD_CHAR ) : 
              
                // check for *str* case (CONTAINS)
                if ( token.at( token.length() - 1 ) == FilterEngine<FilterChecker>::WILDCARD_CHAR ) {
                    if ( token.length() == 2 ) return false;
                    strippedToken = token.substr(1, token.length() - 2);
                    type = PropertyFilterValue::CONTAINS;
                }
                
                // otherwise *str case (ENDS_WITH)
                else {
                    strippedToken = token.substr(1);
                    type = PropertyFilterValue::ENDS_WITH;
                }
                
                break;
               
            default :
                // check for str* case (STARTS_WITH)
                if ( token.at( token.length() - 1 ) == FilterEngine<FilterChecker>::WILDCARD_CHAR ) {
                    if ( token.length() == 2 ) return false;
                    strippedToken = token.substr(0, token.length() - 1);
                    type = PropertyFilterValue::STARTS_WITH;
                }
                
                // otherwise EXACT
                else {
                    strippedToken = token;
                    type = PropertyFilterValue::EXACT;
                }
                
                break;
        }
    }
    
    // convert stripped token to value
    std::stringstream stream(strippedToken);
    if ( strippedToken == "true" || strippedToken == "false" )
        stream >> std::boolalpha >> value;
    else 
        stream >> value;
    
    // check for valid CompareType on type T
    Variant variantCheck = value;
    
    // if T is not string AND CompareType is for string values, return false
    if ( !variantCheck.is_type<std::string>() ) {
        if ( type == PropertyFilterValue::CONTAINS || 
             type == PropertyFilterValue::ENDS_WITH || 
             type == PropertyFilterValue::STARTS_WITH )          
            
          return false;
    }
    
    // return success
    return true;
}

// Assembly:
subq $0x3b8, %rsp            # imm = 0x3B8
movq %rdi, 0x3a8(%rsp)
movq %rsi, 0x3a0(%rsp)
movq %rdx, 0x398(%rsp)
movq 0x3a8(%rsp), %rdi
callq 0x86c90
testb $0x1, %al
jne 0xa62e2
jmp 0xa62ef
movb $0x0, 0x3b7(%rsp)
jmp 0xa6c25
leaq 0x378(%rsp), %rdi
callq 0x86a30
movq 0x3a8(%rsp), %rdi
callq 0x86ac0
movq %rax, 0xa8(%rsp)
jmp 0xa6313
movq 0xa8(%rsp), %rax
cmpq $0x1, %rax
jne 0xa6364
movq 0x3a8(%rsp), %rsi
leaq 0x378(%rsp), %rdi
callq 0x86070
jmp 0xa6338
movq 0x398(%rsp), %rax
movl $0x2, (%rax)
jmp 0xa6a08
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x370(%rsp)
movl %eax, 0x36c(%rsp)
jmp 0xa6c14
movq 0x3a8(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x868c0
movq %rax, 0xa0(%rsp)
jmp 0xa637f
movq 0xa0(%rsp), %rax
movsbl (%rax), %eax
movl %eax, 0x368(%rsp)
movl 0x368(%rsp), %eax
addl $-0x21, %eax
movl %eax, %ecx
movq %rcx, 0x98(%rsp)
subl $0x1d, %eax
ja 0xa68ce
movq 0x98(%rsp), %rax
leaq 0x88a73(%rip), %rcx     # 0x12ee30
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x3a8(%rsp), %rsi
leaq 0x348(%rsp), %rdi
movl $0x1, %edx
movq $-0x1, %rcx
callq 0x86750
jmp 0xa63e9
leaq 0x378(%rsp), %rdi
leaq 0x348(%rsp), %rsi
callq 0x86070
jmp 0xa6400
leaq 0x348(%rsp), %rdi
callq 0x86f68
jmp 0xa640f
movq 0x398(%rsp), %rax
movl $0x7, (%rax)
jmp 0xa6a06
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x370(%rsp)
movl %eax, 0x36c(%rsp)
leaq 0x348(%rsp), %rdi
callq 0x86f68
jmp 0xa6445
jmp 0xa6c14
movq 0x3a8(%rsp), %rdi
movl $0x1, %esi
callq 0x868c0
movq %rax, 0x90(%rsp)
jmp 0xa6466
movq 0x90(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x3d, %eax
jne 0xa653b
movq 0x3a8(%rsp), %rdi
callq 0x86ac0
movq %rax, 0x88(%rsp)
jmp 0xa6491
movq 0x88(%rsp), %rax
cmpq $0x2, %rax
jne 0xa64b7
movb $0x0, 0x3b7(%rsp)
movl $0x1, 0x344(%rsp)
jmp 0xa6c05
movq 0x3a8(%rsp), %rsi
leaq 0x320(%rsp), %rdi
movl $0x2, %edx
movq $-0x1, %rcx
callq 0x86750
jmp 0xa64da
leaq 0x378(%rsp), %rdi
leaq 0x320(%rsp), %rsi
callq 0x86070
jmp 0xa64f1
leaq 0x320(%rsp), %rdi
callq 0x86f68
jmp 0xa6500
movq 0x398(%rsp), %rax
movl $0x4, (%rax)
jmp 0xa65bc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x370(%rsp)
movl %eax, 0x36c(%rsp)
leaq 0x320(%rsp), %rdi
callq 0x86f68
jmp 0xa6536
jmp 0xa6c14
movq 0x3a8(%rsp), %rsi
leaq 0x300(%rsp), %rdi
movl $0x1, %edx
movq $-0x1, %rcx
callq 0x86750
jmp 0xa655e
leaq 0x378(%rsp), %rdi
leaq 0x300(%rsp), %rsi
callq 0x86070
jmp 0xa6575
leaq 0x300(%rsp), %rdi
callq 0x86f68
jmp 0xa6584
movq 0x398(%rsp), %rax
movl $0x3, (%rax)
jmp 0xa65bc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x370(%rsp)
movl %eax, 0x36c(%rsp)
leaq 0x300(%rsp), %rdi
callq 0x86f68
jmp 0xa65b7
jmp 0xa6c14
jmp 0xa6a06
movq 0x3a8(%rsp), %rdi
movl $0x1, %esi
callq 0x868c0
movq %rax, 0x80(%rsp)
jmp 0xa65dd
movq 0x80(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x3d, %eax
jne 0xa66ac
movq 0x3a8(%rsp), %rdi
callq 0x86ac0
movq %rax, 0x78(%rsp)
jmp 0xa6605
movq 0x78(%rsp), %rax
cmpq $0x2, %rax
jne 0xa6628
movb $0x0, 0x3b7(%rsp)
movl $0x1, 0x344(%rsp)
jmp 0xa6c05
movq 0x3a8(%rsp), %rsi
leaq 0x2e0(%rsp), %rdi
movl $0x2, %edx
movq $-0x1, %rcx
callq 0x86750
jmp 0xa664b
leaq 0x378(%rsp), %rdi
leaq 0x2e0(%rsp), %rsi
callq 0x86070
jmp 0xa6662
leaq 0x2e0(%rsp), %rdi
callq 0x86f68
jmp 0xa6671
movq 0x398(%rsp), %rax
movl $0x6, (%rax)
jmp 0xa672d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x370(%rsp)
movl %eax, 0x36c(%rsp)
leaq 0x2e0(%rsp), %rdi
callq 0x86f68
jmp 0xa66a7
jmp 0xa6c14
movq 0x3a8(%rsp), %rsi
leaq 0x2c0(%rsp), %rdi
movl $0x1, %edx
movq $-0x1, %rcx
callq 0x86750
jmp 0xa66cf
leaq 0x378(%rsp), %rdi
leaq 0x2c0(%rsp), %rsi
callq 0x86070
jmp 0xa66e6
leaq 0x2c0(%rsp), %rdi
callq 0x86f68
jmp 0xa66f5
movq 0x398(%rsp), %rax
movl $0x5, (%rax)
jmp 0xa672d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x370(%rsp)
movl %eax, 0x36c(%rsp)
leaq 0x2c0(%rsp), %rdi
callq 0x86f68
jmp 0xa6728
jmp 0xa6c14
jmp 0xa6a06
movq 0x3a8(%rsp), %rdi
movq %rdi, 0x68(%rsp)
callq 0x86ac0
movq %rax, 0x70(%rsp)
jmp 0xa674b
movq 0x68(%rsp), %rdi
movq 0x70(%rsp), %rsi
decq %rsi
callq 0x868c0
movq %rax, 0x60(%rsp)
jmp 0xa6764
movq 0x60(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x2a, %eax
jne 0xa6848
movq 0x3a8(%rsp), %rdi
callq 0x86ac0
movq %rax, 0x58(%rsp)
jmp 0xa6789
movq 0x58(%rsp), %rax
cmpq $0x2, %rax
jne 0xa67ac
movb $0x0, 0x3b7(%rsp)
movl $0x1, 0x344(%rsp)
jmp 0xa6c05
movq 0x3a8(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x86ac0
movq %rax, 0x50(%rsp)
jmp 0xa67c5
movq 0x48(%rsp), %rsi
movq 0x50(%rsp), %rcx
addq $-0x2, %rcx
leaq 0x2a0(%rsp), %rdi
movl $0x1, %edx
callq 0x86750
jmp 0xa67e7
leaq 0x378(%rsp), %rdi
leaq 0x2a0(%rsp), %rsi
callq 0x86070
jmp 0xa67fe
leaq 0x2a0(%rsp), %rdi
callq 0x86f68
jmp 0xa680d
movq 0x398(%rsp), %rax
movl $0x0, (%rax)
jmp 0xa68c9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x370(%rsp)
movl %eax, 0x36c(%rsp)
leaq 0x2a0(%rsp), %rdi
callq 0x86f68
jmp 0xa6843
jmp 0xa6c14
movq 0x3a8(%rsp), %rsi
leaq 0x280(%rsp), %rdi
movl $0x1, %edx
movq $-0x1, %rcx
callq 0x86750
jmp 0xa686b
leaq 0x378(%rsp), %rdi
leaq 0x280(%rsp), %rsi
callq 0x86070
jmp 0xa6882
leaq 0x280(%rsp), %rdi
callq 0x86f68
jmp 0xa6891
movq 0x398(%rsp), %rax
movl $0x1, (%rax)
jmp 0xa68c9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x370(%rsp)
movl %eax, 0x36c(%rsp)
leaq 0x280(%rsp), %rdi
callq 0x86f68
jmp 0xa68c4
jmp 0xa6c14
jmp 0xa6a06
movq 0x3a8(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x86ac0
movq %rax, 0x40(%rsp)
jmp 0xa68e7
movq 0x38(%rsp), %rdi
movq 0x40(%rsp), %rsi
decq %rsi
callq 0x868c0
movq %rax, 0x30(%rsp)
jmp 0xa6900
movq 0x30(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x2a, %eax
jne 0xa69df
movq 0x3a8(%rsp), %rdi
callq 0x86ac0
movq %rax, 0x28(%rsp)
jmp 0xa6925
movq 0x28(%rsp), %rax
cmpq $0x2, %rax
jne 0xa6948
movb $0x0, 0x3b7(%rsp)
movl $0x1, 0x344(%rsp)
jmp 0xa6c05
movq 0x3a8(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x86ac0
movq %rax, 0x20(%rsp)
jmp 0xa6961
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rcx
decq %rcx
xorl %eax, %eax
movl %eax, %edx
leaq 0x260(%rsp), %rdi
callq 0x86750
jmp 0xa6981
leaq 0x378(%rsp), %rdi
leaq 0x260(%rsp), %rsi
callq 0x86070
jmp 0xa6998
leaq 0x260(%rsp), %rdi
callq 0x86f68
jmp 0xa69a7
movq 0x398(%rsp), %rax
movl $0x8, (%rax)
jmp 0xa6a04
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x370(%rsp)
movl %eax, 0x36c(%rsp)
leaq 0x260(%rsp), %rdi
callq 0x86f68
jmp 0xa69da
jmp 0xa6c14
movq 0x3a8(%rsp), %rsi
leaq 0x378(%rsp), %rdi
callq 0x86070
jmp 0xa69f6
movq 0x398(%rsp), %rax
movl $0x2, (%rax)
jmp 0xa6a06
jmp 0xa6a08
movl $0x10, %edi
movl $0x8, %esi
callq 0x928c0
movl %eax, %edx
leaq 0xd8(%rsp), %rdi
leaq 0x378(%rsp), %rsi
callq 0x86be0
jmp 0xa6a30
leaq 0x88a5f(%rip), %rsi     # 0x12f496
leaq 0x378(%rsp), %rdi
callq 0xa9570
movb %al, 0x17(%rsp)
jmp 0xa6a4a
movb 0x17(%rsp), %al
testb $0x1, %al
jne 0xa6a78
jmp 0xa6a54
leaq 0x89062(%rip), %rsi     # 0x12fabd
leaq 0x378(%rsp), %rdi
callq 0xa9570
movb %al, 0x16(%rsp)
jmp 0xa6a6e
movb 0x16(%rsp), %al
testb $0x1, %al
jne 0xa6a78
jmp 0xa6ac2
leaq 0x2b21(%rip), %rsi      # 0xa95a0
leaq 0xd8(%rsp), %rdi
callq 0x86ca0
movq %rax, 0x8(%rsp)
jmp 0xa6a93
movq 0x8(%rsp), %rdi
movq 0x3a0(%rsp), %rsi
callq 0x86900
jmp 0xa6aa7
jmp 0xa6adb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x370(%rsp)
movl %eax, 0x36c(%rsp)
jmp 0xa6bf4
movq 0x3a0(%rsp), %rsi
leaq 0xd8(%rsp), %rdi
callq 0x86900
jmp 0xa6ad9
jmp 0xa6adb
movq 0x3a0(%rsp), %rsi
leaq 0xb0(%rsp), %rdi
callq 0x86350
jmp 0xa6af2
leaq 0xd0(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x94910
jmp 0xa6b09
leaq 0xb0(%rsp), %rdi
callq 0x86f68
jmp 0xa6b18
leaq 0xd0(%rsp), %rdi
callq 0xa9640
movb %al, 0x7(%rsp)
jmp 0xa6b2b
movb 0x7(%rsp), %al
testb $0x1, %al
jne 0xa6bbf
jmp 0xa6b39
movq 0x398(%rsp), %rax
cmpl $0x0, (%rax)
je 0xa6b60
movq 0x398(%rsp), %rax
cmpl $0x1, (%rax)
je 0xa6b60
movq 0x398(%rsp), %rax
cmpl $0x8, (%rax)
jne 0xa6bbd
movb $0x0, 0x3b7(%rsp)
movl $0x1, 0x344(%rsp)
jmp 0xa6bd2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x370(%rsp)
movl %eax, 0x36c(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x86f68
jmp 0xa6b98
jmp 0xa6bf4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x370(%rsp)
movl %eax, 0x36c(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0x94a50
jmp 0xa6bf0
jmp 0xa6bbf
movb $0x1, 0x3b7(%rsp)
movl $0x1, 0x344(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0x94a50
jmp 0xa6be1
leaq 0xd8(%rsp), %rdi
callq 0x86580
jmp 0xa6bf2
jmp 0xa6bf4
jmp 0xa6c05
leaq 0xd8(%rsp), %rdi
callq 0x86580
jmp 0xa6c03
jmp 0xa6c14
leaq 0x378(%rsp), %rdi
callq 0x86f68
jmp 0xa6c25
leaq 0x378(%rsp), %rdi
callq 0x86f68
jmp 0xa6c23
jmp 0xa6c36
movb 0x3b7(%rsp), %al
andb $0x1, %al
addq $0x3b8, %rsp            # imm = 0x3B8
retq
movq 0x370(%rsp), %rdi
callq 0x86d80
movq %rax, %rdi
callq 0x91290
nopl (%rax,%rax)