// File: zeeev[P]DASVC/bamtools/src/api/internal/io/BgzfStream_p.cpp
// Function: BamTools::Internal::BgzfStream::Read(char*, unsigned long)
size_t BgzfStream::Read(char* data, const size_t dataLength) {

    if ( dataLength == 0 )
        return 0;

    // if stream not open for reading
    BT_ASSERT_X( m_device, "BgzfStream::Read() - trying to read from null device");
    if ( !m_device->IsOpen() || (m_device->Mode() != IBamIODevice::ReadOnly) )
        return 0;

    // read blocks as needed until desired data length is retrieved
    char* output = data;
    size_t numBytesRead = 0;
    while ( numBytesRead < dataLength ) {

        // determine bytes available in current block
        int bytesAvailable = m_blockLength - m_blockOffset;

        // read (and decompress) next block if needed
        if ( bytesAvailable <= 0 ) {
            ReadBlock();
            bytesAvailable = m_blockLength - m_blockOffset;
            if ( bytesAvailable <= 0 )
                break;
        }

        // copy data from uncompressed source buffer into data destination buffer
        const size_t copyLength = min( (dataLength-numBytesRead), (size_t)bytesAvailable );
        memcpy(output, m_uncompressedBlock.Buffer + m_blockOffset, copyLength);

        // update counters
        m_blockOffset += copyLength;
        output        += copyLength;
        numBytesRead  += copyLength;
    }

    // update block data
    if ( m_blockOffset == m_blockLength ) {
        m_blockAddress = m_device->Tell();
        m_blockOffset  = 0;
        m_blockLength  = 0;
    }

    // return actual number of bytes read
    return numBytesRead;
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x48(%rsp)
movq %rsi, 0x40(%rsp)
movq %rdx, 0x38(%rsp)
movq 0x48(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, 0x38(%rsp)
jne 0xcea72
movq $0x0, 0x50(%rsp)
jmp 0xcebc9
callq 0x761a0
movq (%rsp), %rax
movq 0x18(%rax), %rdi
movq (%rdi), %rax
callq *0x50(%rax)
testb $0x1, %al
jne 0xcea8b
jmp 0xcea9e
movq (%rsp), %rax
movq 0x18(%rax), %rdi
movq (%rdi), %rax
callq *0x58(%rax)
cmpl $0x1, %eax
je 0xceaac
movq $0x0, 0x50(%rsp)
jmp 0xcebc9
movq 0x40(%rsp), %rax
movq %rax, 0x30(%rsp)
movq $0x0, 0x28(%rsp)
movq 0x28(%rsp), %rax
cmpq 0x38(%rsp), %rax
jae 0xceb8e
movq (%rsp), %rcx
movl (%rcx), %eax
subl 0x4(%rcx), %eax
movl %eax, 0x24(%rsp)
cmpl $0x0, 0x24(%rsp)
jg 0xceb07
movq (%rsp), %rdi
callq 0x73150
movq (%rsp), %rcx
movl (%rcx), %eax
subl 0x4(%rcx), %eax
movl %eax, 0x24(%rsp)
cmpl $0x0, 0x24(%rsp)
jg 0xceb05
jmp 0xceb8e
jmp 0xceb07
movq 0x38(%rsp), %rax
subq 0x28(%rsp), %rax
movq %rax, 0x10(%rsp)
movslq 0x24(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x10(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x74f40
movq %rax, %rcx
movq (%rsp), %rax
movq (%rcx), %rcx
movq %rcx, 0x18(%rsp)
movq 0x30(%rsp), %rdi
movq 0x20(%rax), %rsi
movslq 0x4(%rax), %rax
addq %rax, %rsi
movq 0x18(%rsp), %rdx
callq 0x757c0
movq (%rsp), %rax
movq 0x18(%rsp), %rdx
movslq 0x4(%rax), %rcx
addq %rdx, %rcx
movl %ecx, 0x4(%rax)
movq 0x18(%rsp), %rax
addq 0x30(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x18(%rsp), %rax
addq 0x28(%rsp), %rax
movq %rax, 0x28(%rsp)
jmp 0xceabf
movq (%rsp), %rcx
movl 0x4(%rcx), %eax
cmpl (%rcx), %eax
jne 0xcebbf
movq (%rsp), %rax
movq 0x18(%rax), %rdi
movq (%rdi), %rax
callq *0x38(%rax)
movq %rax, %rcx
movq (%rsp), %rax
movq %rcx, 0x8(%rax)
movl $0x0, 0x4(%rax)
movl $0x0, (%rax)
movq 0x28(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rax
addq $0x58, %rsp
retq
nopw %cs:(%rax,%rax)