// File: /workspace/github_cpp_makefile_star2_O2/zeeev[P]DASVC/bamtools/src/api/internal/bam/BamReader_p.cpp
// Function: BamTools::Internal::BamReaderPrivate::LoadNextAlignment(BamTools::BamAlignment&)
bool BamReaderPrivate::LoadNextAlignment(BamAlignment& alignment) {

    // read in the 'block length' value, make sure it's not zero
    char buffer[sizeof(uint32_t)];
    fill_n(buffer, sizeof(uint32_t), 0);
    m_stream.Read(buffer, sizeof(uint32_t));
    alignment.SupportData.BlockLength = BamTools::UnpackUnsignedInt(buffer);
    if ( m_isBigEndian ) BamTools::SwapEndian_32(alignment.SupportData.BlockLength);
    if ( alignment.SupportData.BlockLength == 0 )
        return false;

    // read in core alignment data, make sure the right size of data was read
    char x[Constants::BAM_CORE_SIZE];
    if ( m_stream.Read(x, Constants::BAM_CORE_SIZE) != Constants::BAM_CORE_SIZE )
        return false;

    // swap core endian-ness if necessary
    if ( m_isBigEndian ) {
        for ( unsigned int i = 0; i < Constants::BAM_CORE_SIZE; i+=sizeof(uint32_t) )
            BamTools::SwapEndian_32p(&x[i]);
    }

    // set BamAlignment 'core' and 'support' data
    alignment.RefID    = BamTools::UnpackSignedInt(&x[0]);
    alignment.Position = BamTools::UnpackSignedInt(&x[4]);

    unsigned int tempValue = BamTools::UnpackUnsignedInt(&x[8]);
    alignment.Bin        = tempValue >> 16;
    alignment.MapQuality = tempValue >> 8 & 0xff;
    alignment.SupportData.QueryNameLength = tempValue & 0xff;

    tempValue = BamTools::UnpackUnsignedInt(&x[12]);
    alignment.AlignmentFlag = tempValue >> 16;
    alignment.SupportData.NumCigarOperations = tempValue & 0xffff;

    alignment.SupportData.QuerySequenceLength = BamTools::UnpackUnsignedInt(&x[16]);
    alignment.MateRefID    = BamTools::UnpackSignedInt(&x[20]);
    alignment.MatePosition = BamTools::UnpackSignedInt(&x[24]);
    alignment.InsertSize   = BamTools::UnpackSignedInt(&x[28]);

    // set BamAlignment length
    alignment.Length = alignment.SupportData.QuerySequenceLength;

    // read in character data - make sure proper data size was read
    bool readCharDataOK = false;
    const unsigned int dataLength = alignment.SupportData.BlockLength - Constants::BAM_CORE_SIZE;
    RaiiBuffer allCharData(dataLength);

    if ( m_stream.Read(allCharData.Buffer, dataLength) == dataLength ) {

        // store 'allCharData' in supportData structure
        alignment.SupportData.AllCharData.assign((const char*)allCharData.Buffer, dataLength);

        // set success flag
        readCharDataOK = true;

        // save CIGAR ops
        // need to calculate this here so that  BamAlignment::GetEndPosition() performs correctly,
        // even when GetNextAlignmentCore() is called
        const unsigned int cigarDataOffset = alignment.SupportData.QueryNameLength;
        uint32_t* cigarData = (uint32_t*)(allCharData.Buffer + cigarDataOffset);
        CigarOp op;
        alignment.CigarData.clear();
        alignment.CigarData.reserve(alignment.SupportData.NumCigarOperations);
        for ( unsigned int i = 0; i < alignment.SupportData.NumCigarOperations; ++i ) {

            // swap endian-ness if necessary
            if ( m_isBigEndian ) BamTools::SwapEndian_32(cigarData[i]);

            // build CigarOp structure
            op.Length = (cigarData[i] >> Constants::BAM_CIGAR_SHIFT);
            op.Type   = Constants::BAM_CIGAR_LOOKUP[ (cigarData[i] & Constants::BAM_CIGAR_MASK) ];

            // save CigarOp
            alignment.CigarData.push_back(op);
        }
    }

    // return success/failure
    return readCharDataOK;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rsi, %rbx
movq %rdi, 0x8(%rsp)
xorl %eax, %eax
cmpq $0x4, %rax
je 0x44480
movb $0x0, 0x14(%rsp,%rax)
incq %rax
jmp 0x44470
movq 0x8(%rsp), %r14
leaq 0x1e8(%r14), %r15
leaq 0x14(%rsp), %r12
pushq $0x4
popq %rdx
movq %r15, %rdi
movq %r12, %rsi
callq 0x343e0
movl (%r12), %eax
movl %eax, 0x120(%rbx)
cmpb $0x1, 0x40(%r14)
jne 0x444b8
bswapl %eax
movl %eax, 0x120(%rbx)
testl %eax, %eax
je 0x444f5
leaq 0x30(%rsp), %rsi
pushq $0x20
popq %rdx
movq %r15, %rdi
callq 0x343e0
cmpq $0x20, %rax
jne 0x444f5
movq 0x8(%rsp), %rax
cmpb $0x1, 0x40(%rax)
jne 0x444fc
xorl %eax, %eax
cmpq $0x1f, %rax
ja 0x444fc
movl 0x30(%rsp,%rax), %ecx
bswapl %ecx
movl %ecx, 0x30(%rsp,%rax)
addq $0x4, %rax
jmp 0x444df
xorl %ebp, %ebp
jmp 0x4465e
movq 0x30(%rsp), %rax
movq %rax, 0xa8(%rbx)
movl 0x38(%rsp), %eax
movzbl %ah, %ecx
movzbl %al, %edx
shrl $0x10, %eax
movw %ax, 0xb0(%rbx)
movw %cx, 0xb2(%rbx)
movl %edx, 0x128(%rbx)
movl 0x3c(%rsp), %eax
movl %eax, %ecx
shrl $0x10, %ecx
movl %ecx, 0xb4(%rbx)
andl $0xffff, %eax           # imm = 0xFFFF
movl %eax, 0x124(%rbx)
movl 0x40(%rsp), %eax
movl %eax, 0x12c(%rbx)
movq 0x44(%rsp), %rcx
movq %rcx, 0xd0(%rbx)
movl 0x4c(%rsp), %ecx
movl %ecx, 0xd8(%rbx)
movl %eax, 0x20(%rbx)
movl 0x120(%rbx), %r12d
addl $-0x20, %r12d
movq %r12, %rdi
callq 0x31080
movq %rax, %r13
movq %rax, %rdi
xorl %esi, %esi
movq %r12, %rdx
callq 0x320d0
movq %r13, 0x20(%rsp)
movq %r12, 0x28(%rsp)
movq %r15, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0x343e0
cmpq %r12, %rax
sete %bpl
jne 0x44654
leaq 0x100(%rbx), %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0x33e30
movl 0x128(%rbx), %r13d
leaq 0xb8(%rbx), %r15
movq 0xb8(%rbx), %rax
cmpq %rax, 0xc0(%rbx)
je 0x445e5
movq %rax, 0xc0(%rbx)
movl %ebp, 0x10(%rsp)
addq 0x20(%rsp), %r13
movl 0x124(%rbx), %esi
movq %r15, %rdi
callq 0x34190
xorl %ebp, %ebp
leaq 0x1759a(%rip), %r14     # 0x5bb9f
leaq 0x18(%rsp), %r12
movl 0x124(%rbx), %eax
cmpq %rax, %rbp
jae 0x44650
movl (%r13,%rbp,4), %eax
movq 0x8(%rsp), %rcx
cmpb $0x1, 0x40(%rcx)
jne 0x4462c
bswapl %eax
movl %eax, (%r13,%rbp,4)
movl %eax, %ecx
shrl $0x4, %ecx
movl %ecx, 0x1c(%rsp)
andl $0xf, %eax
movb (%rax,%r14), %al
movb %al, 0x18(%rsp)
movq %r15, %rdi
movq %r12, %rsi
callq 0x336b0
incq %rbp
jmp 0x4460a
movl 0x10(%rsp), %ebp
leaq 0x20(%rsp), %rdi
callq 0x34850
movl %ebp, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x44673
jmp 0x44673
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x34850
movq %rbx, %rdi
callq 0x34ed0