// File: zeeev[P]DASVC/bamtools/src/api/BamAlignment.cpp
// Function: BamTools::BamAlignment::GetArrayTagType(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, char&) const
bool BamAlignment::GetArrayTagType(const std::string& tag, char& type) const {

    // skip if alignment is core-only
    if ( SupportData.HasCoreOnly ) {
        // TODO: set error string?
        return false;
    }

    // skip if no tags present
    if ( TagData.empty() ) {
        // TODO: set error string?
        return false;
    }

    // localize the tag data
    char* pTagData = (char*)TagData.data();
    const unsigned int tagDataLength = TagData.size();
    unsigned int numBytesParsed = 0;

    // if tag not found, return failure
    if ( !FindTag(tag, pTagData, tagDataLength, numBytesParsed) ){
        // TODO: set error string?
        return false;
    }

    // check that tag type code is array
    type = *(pTagData - 1);
    if ( type != Constants::BAM_TAG_TYPE_ARRAY ) {
        // TODO: set error string
        return false;
    }

    // fetch element type
    const char elementType = *pTagData;
    switch ( elementType ) {

        // allowable types
        case (Constants::BAM_TAG_TYPE_INT8)   :
        case (Constants::BAM_TAG_TYPE_UINT8)  :
        case (Constants::BAM_TAG_TYPE_INT16)  :
        case (Constants::BAM_TAG_TYPE_UINT16) :
        case (Constants::BAM_TAG_TYPE_INT32)  :
        case (Constants::BAM_TAG_TYPE_UINT32) :
        case (Constants::BAM_TAG_TYPE_FLOAT)  :
            type = elementType;
            break;

        default:
            //TODO: set error string
            return false;
    }

    // if we get here, return success
    return true;
}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x38(%rsp)
movq %rsi, 0x30(%rsp)
movq %rdx, 0x28(%rsp)
movq 0x38(%rsp), %rax
movq %rax, 0x8(%rsp)
testb $0x1, 0x130(%rax)
je 0x87d00
movb $0x0, 0x47(%rsp)
jmp 0x87e19
movq 0x8(%rsp), %rdi
addq $0x88, %rdi
callq 0x7aba0
testb $0x1, %al
jne 0x87d17
jmp 0x87d21
movb $0x0, 0x47(%rsp)
jmp 0x87e19
movq 0x8(%rsp), %rdi
addq $0x88, %rdi
callq 0x785e0
movq 0x8(%rsp), %rdi
movq %rax, 0x20(%rsp)
addq $0x88, %rdi
callq 0x74cd0
movq 0x8(%rsp), %rdi
movl %eax, 0x1c(%rsp)
movl $0x0, 0x18(%rsp)
movq 0x30(%rsp), %rsi
leaq 0x20(%rsp), %rdx
leaq 0x1c(%rsp), %rcx
leaq 0x18(%rsp), %r8
callq 0x77c80
testb $0x1, %al
jne 0x87d80
movb $0x0, 0x47(%rsp)
jmp 0x87e19
movq 0x20(%rsp), %rax
movb -0x1(%rax), %cl
movq 0x28(%rsp), %rax
movb %cl, (%rax)
movq 0x28(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x42, %eax
je 0x87da3
movb $0x0, 0x47(%rsp)
jmp 0x87e19
movq 0x20(%rsp), %rax
movb (%rax), %al
movb %al, 0x17(%rsp)
movsbl 0x17(%rsp), %eax
movl %eax, 0x4(%rsp)
subl $0x43, %eax
je 0x87e00
jmp 0x87dbe
movl 0x4(%rsp), %eax
subl $0x49, %eax
je 0x87e00
jmp 0x87dc9
movl 0x4(%rsp), %eax
subl $0x53, %eax
je 0x87e00
jmp 0x87dd4
movl 0x4(%rsp), %eax
subl $0x63, %eax
je 0x87e00
jmp 0x87ddf
movl 0x4(%rsp), %eax
subl $0x66, %eax
je 0x87e00
jmp 0x87dea
movl 0x4(%rsp), %eax
subl $0x69, %eax
je 0x87e00
jmp 0x87df5
movl 0x4(%rsp), %eax
subl $0x73, %eax
jne 0x87e0d
jmp 0x87e00
movb 0x17(%rsp), %cl
movq 0x28(%rsp), %rax
movb %cl, (%rax)
jmp 0x87e14
movb $0x0, 0x47(%rsp)
jmp 0x87e19
movb $0x1, 0x47(%rsp)
movb 0x47(%rsp), %al
andb $0x1, %al
addq $0x48, %rsp
retq
nopw %cs:(%rax,%rax)