// File: white0dew[P]WebServer/http/http_conn.cpp
// Function: http_conn::write()
bool http_conn::write()
{
    int temp = 0;
    //表示响应报文为空，一般不会出现这种情况
    if (bytes_to_send == 0)
    {
        modfd(m_epollfd, m_sockfd, EPOLLIN, m_TRIGMode);
        init();
        return true;
    }

    while (1)
    {
        //将响应报文的状态行、消息头、空行和响应正文发送给浏览器端
        temp = writev(m_sockfd, m_iv, m_iv_count);
        //error
        if (temp < 0)
        {
            //判断缓冲区是否满了
            if (errno == EAGAIN)
            {
                modfd(m_epollfd, m_sockfd, EPOLLOUT, m_TRIGMode);
                return true;
            }
            unmap();
            return false;
        }
        //更新已发送字节
        bytes_have_send += temp;
        //更新wei发送字节
        bytes_to_send -= temp;
        //第一个iovec头部信息的数据已发送完，发送第二个iovec数据
        if (bytes_have_send >= m_iv[0].iov_len)
        {
            //不再继续发送头部信息
            m_iv[0].iov_len = 0;
            m_iv[1].iov_base = m_file_address + (bytes_have_send - m_write_idx);
            m_iv[1].iov_len = bytes_to_send;
        }
        //继续发送第一个iovec头部信息的数据
        else
        {
            m_iv[0].iov_base = m_write_buf + bytes_have_send;
            m_iv[0].iov_len = m_iv[0].iov_len - bytes_have_send;
        }

        //判断条件，数据已全部发送完
        if (bytes_to_send <= 0)
        {
            //如果发送失败，但不是缓冲区问题，取消映射
            unmap();
            //重新注册写事件
            modfd(m_epollfd, m_sockfd, EPOLLIN, m_TRIGMode);

            //浏览器的请求为长连接
            if (m_linger)
            {
                //重新初始化HTTP对象**
                init();
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x0, -0x14(%rbp)
cmpl $0x0, 0xdf0(%rax)
jne 0x6533
movq -0x20(%rbp), %rax
movl 0xdf52(%rip), %edi      # 0x14460
movl 0x14(%rax), %esi
movl 0xe30(%rax), %ecx
movl $0x1, %edx
callq 0x4d40
movq -0x20(%rbp), %rdi
callq 0x4f50
movb $0x1, -0x1(%rbp)
jmp 0x66a0
jmp 0x6535
movq -0x20(%rbp), %rax
movl 0x14(%rax), %edi
movq %rax, %rsi
addq $0xdc0, %rsi            # imm = 0xDC0
movl 0xde0(%rax), %edx
callq 0x3260
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
jge 0x659c
callq 0x3060
cmpl $0xb, (%rax)
jne 0x658a
movq -0x20(%rbp), %rax
movl 0xdef2(%rip), %edi      # 0x14460
movl 0x14(%rax), %esi
movl 0xe30(%rax), %ecx
movl $0x4, %edx
callq 0x4d40
movb $0x1, -0x1(%rbp)
jmp 0x66a0
movq -0x20(%rbp), %rdi
callq 0x6490
movb $0x0, -0x1(%rbp)
jmp 0x66a0
movq -0x20(%rbp), %rcx
movl -0x14(%rbp), %eax
addl 0xdf4(%rcx), %eax
movl %eax, 0xdf4(%rcx)
movl -0x14(%rbp), %edx
movl 0xdf0(%rcx), %eax
subl %edx, %eax
movl %eax, 0xdf0(%rcx)
movslq 0xdf4(%rcx), %rax
cmpq 0xdc8(%rcx), %rax
jb 0x660f
movq -0x20(%rbp), %rax
movq $0x0, 0xdc8(%rax)
movq 0xd28(%rax), %rcx
movl 0xdf4(%rax), %edx
subl 0xc34(%rax), %edx
movslq %edx, %rdx
addq %rdx, %rcx
movq %rcx, 0xdd0(%rax)
movslq 0xdf0(%rax), %rcx
movq %rcx, 0xdd8(%rax)
jmp 0x6646
movq -0x20(%rbp), %rax
movq %rax, %rcx
addq $0x834, %rcx            # imm = 0x834
movslq 0xdf4(%rax), %rdx
addq %rdx, %rcx
movq %rcx, 0xdc0(%rax)
movq 0xdc8(%rax), %rcx
movslq 0xdf4(%rax), %rdx
subq %rdx, %rcx
movq %rcx, 0xdc8(%rax)
movq -0x20(%rbp), %rax
cmpl $0x0, 0xdf0(%rax)
jg 0x669b
movq -0x20(%rbp), %rdi
callq 0x6490
movq -0x20(%rbp), %rax
movl 0xddfa(%rip), %edi      # 0x14460
movl 0x14(%rax), %esi
movl 0xe30(%rax), %ecx
movl $0x1, %edx
callq 0x4d40
movq -0x20(%rbp), %rax
testb $0x1, 0xd24(%rax)
je 0x6695
movq -0x20(%rbp), %rdi
callq 0x4f50
movb $0x1, -0x1(%rbp)
jmp 0x66a0
movb $0x0, -0x1(%rbp)
jmp 0x66a0
jmp 0x6535
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax,%rax)