// File: zeeev[P]DASVC/bamtools/src/api/internal/io/BamHttp_p.cpp
// Function: BamTools::Internal::BamHttp::Read(char*, unsigned int)
int64_t BamHttp::Read(char* data, const unsigned int numBytes) {

    // if BamHttp not in a valid state
    if ( !IsOpen() )
        return -1;

    int64_t numBytesReadSoFar = 0;
    while ( numBytesReadSoFar < numBytes ) {

        const size_t remaining = static_cast<size_t>( numBytes - numBytesReadSoFar );

        // if we're not holding a valid GET reponse, get one
        if ( m_response == 0 ) {
            if ( !SendGetRequest(remaining) )
                return -1;
        }
        BT_ASSERT_X(m_response, "null HTTP response");

        // check response status code
        const int statusCode = m_response->GetStatusCode();

        // if we receieved full file contents in response
        if ( statusCode == 200 ) {

            // try to read 'remaining' bytes from socket
            const int64_t socketBytesRead = ReadFromSocket(data+numBytesReadSoFar, remaining);

            // if error
            if ( socketBytesRead < 0 ) {
                SetErrorString("BamHttp::Read", m_socket->GetErrorString());
                return -1;
            }

            // EOF
            else if ( socketBytesRead == 0 )
                return numBytesReadSoFar;

            // update counters
            numBytesReadSoFar += socketBytesRead;
            m_filePosition    += socketBytesRead;

        }

        // else if we received a range of bytes in response
        else if ( statusCode == 206 ) {

            // if we've exhausted the last request
            if ( m_filePosition == m_rangeEndPosition ) {
                if ( !SendGetRequest(remaining) )
                    return -1;
            }

            else {

                // try to read 'remaining' bytes from socket
                const int64_t socketBytesRead = ReadFromSocket(data+numBytesReadSoFar, remaining);

                // if error
                if ( socketBytesRead < 0 ) {
                    SetErrorString("BamHttp::Read", m_socket->GetErrorString());
                    return -1;
                }

                // maybe EOF
                else if ( socketBytesRead == 0 ) {

                    // if we know we're not at end position, fire off a new request
                    if ( m_fileEndPosition > 0 && m_filePosition < m_fileEndPosition ) {
                        if ( !SendGetRequest() )
                            return -1;
                    } else
                        return numBytesReadSoFar;
                }

                // update counters
                numBytesReadSoFar += socketBytesRead;
                m_filePosition    += socketBytesRead;
            }
        }


        // else some other HTTP status
        else {
            SetErrorString("BamHttp::Read", "unsupported status code in response");
            return -1;
        }
    }

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

// Assembly:
subq $0x168, %rsp            # imm = 0x168
movq %rdi, 0x158(%rsp)
movq %rsi, 0x150(%rsp)
movl %edx, 0x14c(%rsp)
movq 0x158(%rsp), %rdi
movq %rdi, 0x28(%rsp)
movq (%rdi), %rax
callq *0x50(%rax)
testb $0x1, %al
jne 0xcabd6
movq $-0x1, 0x160(%rsp)
jmp 0xcb18b
movq $0x0, 0x140(%rsp)
movq 0x140(%rsp), %rax
movl 0x14c(%rsp), %ecx
cmpq %rcx, %rax
jge 0xcb17b
movq 0x28(%rsp), %rax
movl 0x14c(%rsp), %ecx
subq 0x140(%rsp), %rcx
movq %rcx, 0x138(%rsp)
cmpq $0x0, 0xa0(%rax)
jne 0xcac49
movq 0x28(%rsp), %rdi
movq 0x138(%rsp), %rsi
callq 0x7c5a0
testb $0x1, %al
jne 0xcac47
movq $-0x1, 0x160(%rsp)
jmp 0xcb18b
jmp 0xcac49
callq 0x761a0
movq 0x28(%rsp), %rax
movq 0xa0(%rax), %rdi
callq 0x72ee0
movl %eax, 0x134(%rsp)
cmpl $0xc8, 0x134(%rsp)
jne 0xcae1d
movq 0x28(%rsp), %rdi
movq 0x150(%rsp), %rsi
addq 0x140(%rsp), %rsi
movq 0x138(%rsp), %rax
movl %eax, %edx
callq 0x74ac0
movq %rax, 0x128(%rsp)
cmpq $0x0, 0x128(%rsp)
jge 0xcadc3
leaq 0x107(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x7b5f0
movq 0x20(%rsp), %rdx
leaq 0x21112(%rip), %rsi     # 0xebde2
leaq 0x108(%rsp), %rdi
callq 0x78e70
jmp 0xcacdf
movq 0x28(%rsp), %rax
movq 0x30(%rax), %rsi
leaq 0xd0(%rsp), %rdi
callq 0x77a20
jmp 0xcacf7
movq 0x28(%rsp), %rdi
leaq 0x108(%rsp), %rsi
leaq 0xd0(%rsp), %rdx
callq 0x7ab60
jmp 0xcad13
leaq 0xd0(%rsp), %rdi
callq 0x7cce8
jmp 0xcad22
leaq 0x108(%rsp), %rdi
callq 0x7cce8
jmp 0xcad31
leaq 0x107(%rsp), %rdi
callq 0x76f80
movq $-0x1, 0x160(%rsp)
jmp 0xcb18b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0xcadb1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0xcada0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0x7cce8
jmp 0xcad9e
jmp 0xcada0
leaq 0x108(%rsp), %rdi
callq 0x7cce8
jmp 0xcadaf
jmp 0xcadb1
leaq 0x107(%rsp), %rdi
callq 0x76f80
jmp 0xcb19b
cmpq $0x0, 0x128(%rsp)
jne 0xcade3
movq 0x140(%rsp), %rax
movq %rax, 0x160(%rsp)
jmp 0xcb18b
jmp 0xcade5
movq 0x28(%rsp), %rax
movq 0x128(%rsp), %rcx
addq 0x140(%rsp), %rcx
movq %rcx, 0x140(%rsp)
movq 0x128(%rsp), %rcx
addq 0xb0(%rax), %rcx
movq %rcx, 0xb0(%rax)
jmp 0xcb176
cmpl $0xce, 0x134(%rsp)
jne 0xcb061
movq 0x28(%rsp), %rcx
movq 0xb0(%rcx), %rax
cmpq 0xc0(%rcx), %rax
jne 0xcae6f
movq 0x28(%rsp), %rdi
movq 0x138(%rsp), %rsi
callq 0x7c5a0
testb $0x1, %al
jne 0xcae6a
movq $-0x1, 0x160(%rsp)
jmp 0xcb18b
jmp 0xcb05c
movq 0x28(%rsp), %rdi
movq 0x150(%rsp), %rsi
addq 0x140(%rsp), %rsi
movq 0x138(%rsp), %rax
movl %eax, %edx
callq 0x74ac0
movq %rax, 0xc8(%rsp)
cmpq $0x0, 0xc8(%rsp)
jge 0xcafbb
leaq 0xa7(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x7b5f0
movq 0x18(%rsp), %rdx
leaq 0x20f1a(%rip), %rsi     # 0xebde2
leaq 0xa8(%rsp), %rdi
callq 0x78e70
jmp 0xcaed7
movq 0x28(%rsp), %rax
movq 0x30(%rax), %rsi
leaq 0x80(%rsp), %rdi
callq 0x77a20
jmp 0xcaeef
movq 0x28(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
leaq 0x80(%rsp), %rdx
callq 0x7ab60
jmp 0xcaf0b
leaq 0x80(%rsp), %rdi
callq 0x7cce8
jmp 0xcaf1a
leaq 0xa8(%rsp), %rdi
callq 0x7cce8
jmp 0xcaf29
leaq 0xa7(%rsp), %rdi
callq 0x76f80
movq $-0x1, 0x160(%rsp)
jmp 0xcb18b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0xcafa9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0xcaf98
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
leaq 0x80(%rsp), %rdi
callq 0x7cce8
jmp 0xcaf96
jmp 0xcaf98
leaq 0xa8(%rsp), %rdi
callq 0x7cce8
jmp 0xcafa7
jmp 0xcafa9
leaq 0xa7(%rsp), %rdi
callq 0x76f80
jmp 0xcb19b
cmpq $0x0, 0xc8(%rsp)
jne 0xcb027
movq 0x28(%rsp), %rax
cmpq $0x0, 0xb8(%rax)
jle 0xcb010
movq 0x28(%rsp), %rcx
movq 0xb0(%rcx), %rax
cmpq 0xb8(%rcx), %rax
jge 0xcb010
movq 0x28(%rsp), %rdi
movl $0x10000, %esi          # imm = 0x10000
callq 0x7c5a0
testb $0x1, %al
jne 0xcb00e
movq $-0x1, 0x160(%rsp)
jmp 0xcb18b
jmp 0xcb025
movq 0x140(%rsp), %rax
movq %rax, 0x160(%rsp)
jmp 0xcb18b
jmp 0xcb027
jmp 0xcb029
movq 0x28(%rsp), %rax
movq 0xc8(%rsp), %rcx
addq 0x140(%rsp), %rcx
movq %rcx, 0x140(%rsp)
movq 0xc8(%rsp), %rcx
addq 0xb0(%rax), %rcx
movq %rcx, 0xb0(%rax)
jmp 0xcb174
leaq 0x5f(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x7b5f0
movq 0x10(%rsp), %rdx
leaq 0x20d66(%rip), %rsi     # 0xebde2
leaq 0x60(%rsp), %rdi
callq 0x78e70
jmp 0xcb088
leaq 0x37(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x7b5f0
movq 0x8(%rsp), %rdx
leaq 0x20d4d(%rip), %rsi     # 0xebdf0
leaq 0x38(%rsp), %rdi
callq 0x78e70
jmp 0xcb0af
movq 0x28(%rsp), %rdi
leaq 0x60(%rsp), %rsi
leaq 0x38(%rsp), %rdx
callq 0x7ab60
jmp 0xcb0c5
leaq 0x38(%rsp), %rdi
callq 0x7cce8
jmp 0xcb0d1
leaq 0x37(%rsp), %rdi
callq 0x76f80
leaq 0x60(%rsp), %rdi
callq 0x7cce8
jmp 0xcb0e7
leaq 0x5f(%rsp), %rdi
callq 0x76f80
movq $-0x1, 0x160(%rsp)
jmp 0xcb18b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0xcb168
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0xcb150
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x7cce8
jmp 0xcb14e
jmp 0xcb150
leaq 0x37(%rsp), %rdi
callq 0x76f80
leaq 0x60(%rsp), %rdi
callq 0x7cce8
jmp 0xcb166
jmp 0xcb168
leaq 0x5f(%rsp), %rdi
callq 0x76f80
jmp 0xcb19b
jmp 0xcb176
jmp 0xcabe2
movq 0x140(%rsp), %rax
movq %rax, 0x160(%rsp)
movq 0x160(%rsp), %rax
addq $0x168, %rsp            # imm = 0x168
retq
movq 0xf8(%rsp), %rdi
callq 0x7b550
movq %rax, %rdi
callq 0x88ef0