// File: /workspace/github_cpp_makefile_star2_O3/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 $0x48, %rsp
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x44(%rsp), %r15
movl $0x0, (%r15)
leaq 0x1e8(%rdi), %r12
movl $0x4, %edx
movq %r12, %rdi
movq %r15, %rsi
callq 0x283c0
movl (%r15), %eax
movl %eax, 0x120(%rbx)
cmpb $0x1, 0x40(%r14)
jne 0x3b189
bswapl %eax
movl %eax, 0x120(%rbx)
testl %eax, %eax
je 0x3b382
leaq 0x20(%rsp), %rsi
movl $0x20, %edx
movq %r12, %rdi
callq 0x283c0
cmpq $0x20, %rax
jne 0x3b382
cmpb $0x1, 0x40(%r14)
jne 0x3b1f4
xorl %eax, %eax
pxor %xmm0, %xmm0
movdqa 0x20(%rsp,%rax,4), %xmm1
movdqa %xmm1, %xmm2
punpckhbw %xmm0, %xmm2    # xmm2 = xmm2[8],xmm0[8],xmm2[9],xmm0[9],xmm2[10],xmm0[10],xmm2[11],xmm0[11],xmm2[12],xmm0[12],xmm2[13],xmm0[13],xmm2[14],xmm0[14],xmm2[15],xmm0[15]
pshuflw $0x1b, %xmm2, %xmm2     # xmm2 = xmm2[3,2,1,0,4,5,6,7]
pshufhw $0x1b, %xmm2, %xmm2     # xmm2 = xmm2[0,1,2,3,7,6,5,4]
punpcklbw %xmm0, %xmm1    # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
pshuflw $0x1b, %xmm1, %xmm1     # xmm1 = xmm1[3,2,1,0,4,5,6,7]
pshufhw $0x1b, %xmm1, %xmm1     # xmm1 = xmm1[0,1,2,3,7,6,5,4]
packuswb %xmm2, %xmm1
movdqa %xmm1, 0x20(%rsp,%rax,4)
addq $0x4, %rax
cmpq $0x8, %rax
jne 0x3b1ba
movq 0x20(%rsp), %rax
movq %rax, 0xa8(%rbx)
movl 0x28(%rsp), %eax
movzbl %ah, %ecx
movzbl %al, %edx
shrl $0x10, %eax
movw %ax, 0xb0(%rbx)
movw %cx, 0xb2(%rbx)
movl %edx, 0x128(%rbx)
movl 0x2c(%rsp), %eax
movl %eax, %ecx
shrl $0x10, %ecx
movl %ecx, 0xb4(%rbx)
andl $0xffff, %eax           # imm = 0xFFFF
movl %eax, 0x124(%rbx)
movl 0x30(%rsp), %eax
movl %eax, 0x12c(%rbx)
movq 0x34(%rsp), %rcx
movq %rcx, 0xd0(%rbx)
movl 0x3c(%rsp), %ecx
movl %ecx, 0xd8(%rbx)
movl %eax, 0x20(%rbx)
movl 0x120(%rbx), %r13d
addl $-0x20, %r13d
movq %r13, %rdi
callq 0x26070
movq %rax, %r15
movq %rax, %rdi
xorl %esi, %esi
movq %r13, %rdx
callq 0x26bc0
movq %r12, %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0x283c0
cmpq %r13, %rax
sete %bpl
jne 0x3b378
leaq 0x100(%rbx), %rdi
movq 0x108(%rbx), %rdx
xorl %esi, %esi
movq %r15, %rcx
movq %r13, %r8
callq 0x285a0
leaq 0xb8(%rbx), %r12
movq 0xb8(%rbx), %rax
cmpq %rax, 0xc0(%rbx)
je 0x3b2d5
movq %rax, 0xc0(%rbx)
movl %ebp, 0x1c(%rsp)
movq %r15, 0x8(%rsp)
movl 0x128(%rbx), %r13d
movl 0x124(%rbx), %esi
movq %r12, %rdi
callq 0x281d0
cmpl $0x0, 0x124(%rbx)
je 0x3b36f
movq 0x8(%rsp), %r15
addq %r13, %r15
xorl %r13d, %r13d
leaq 0x1a84c(%rip), %rbp     # 0x55b5a
movl (%r15,%r13,4), %eax
cmpb $0x1, 0x40(%r14)
jne 0x3b31f
bswapl %eax
movl %eax, (%r15,%r13,4)
movl %eax, %ecx
shrl $0x4, %ecx
movl %ecx, 0x14(%rsp)
andl $0xf, %eax
movb (%rax,%rbp), %al
movb %al, 0x10(%rsp)
movq 0xc0(%rbx), %rsi
cmpq 0xc8(%rbx), %rsi
je 0x3b354
movq 0x10(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0xc0(%rbx)
jmp 0x3b361
movq %r12, %rdi
leaq 0x10(%rsp), %rdx
callq 0x27490
incq %r13
movl 0x124(%rbx), %eax
cmpq %rax, %r13
jb 0x3b30e
movq 0x8(%rsp), %r15
movl 0x1c(%rsp), %ebp
movq %r15, %rdi
callq 0x27e60
jmp 0x3b384
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3b39e
movq %r15, 0x8(%rsp)
jmp 0x3b39e
movq %rax, %rbx
movq 0x8(%rsp), %rdi
callq 0x27e60
movq %rbx, %rdi
callq 0x28c10
nop