// File: guoxuanhan[P]NetServer/tcpconnection.cpp
// Function: sendn(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)
int sendn(int fd, std::string &bufferout)
{
    ssize_t nbyte = 0;
    int sendsum = 0;
    //char buffer[BUFSIZE+1];
    size_t length = 0;
    //length = bufferout.copy(buffer, BUFSIZE, 0);
    //buffer[length] = '\0';
    // if(bufferout.size() >= BUFSIZE)
    // {
    // 	length =  BUFSIZE;
    // }
    // else
    // {
    // 	length =  bufferout.size();
    // }
    //无拷贝优化
    length = bufferout.size();
    if(length >= BUFSIZE)
    {
        length = BUFSIZE;
    }
    for (;;)
    {
        //nbyte = send(fd, buffer, length, 0);
        //nbyte = send(fd, bufferout.c_str(), length, 0);
        nbyte = write(fd, bufferout.c_str(), length);
        if (nbyte > 0)
        {
            sendsum += nbyte;
            bufferout.erase(0, nbyte);
            //length = bufferout.copy(buffer, BUFSIZE, 0);
            //buffer[length] = '\0';
            length = bufferout.size();
            if(length >= BUFSIZE)
            {
                length = BUFSIZE;
            }
            if (length == 0 )
            {
                return sendsum;
            }
        }
        else if (nbyte < 0)//异常
        {
            if (errno == EAGAIN)//系统缓冲区满，非阻塞返回
            {
                std::cout << "write errno == EAGAIN,not finish!" << std::endl;
                return sendsum;
            }
            else if (errno == EINTR)
            {
                std::cout << "write errno == EINTR" << std::endl;
                continue;
            }
            else if (errno == EPIPE)
            {
                //客户端已经close，并发了RST，继续wirte会报EPIPE，返回0，表示close
                perror("write error");
                std::cout << "write errno == client send RST" << std::endl;
                return -1;
            }
            else
            {
                perror("write error");//Connection reset by peer
                std::cout << "write error, unknow error" << std::endl;
                return -1;
            }
        }
        else//返回0
        {
            //应该不会返回0
            //std::cout << "client close the Socket!" << std::endl;
            return 0;
        }
    }
}

// Assembly:
subq $0x38, %rsp
movl %edi, 0x30(%rsp)
movq %rsi, 0x28(%rsp)
movq $0x0, 0x20(%rsp)
movl $0x0, 0x1c(%rsp)
movq $0x0, 0x10(%rsp)
movq 0x28(%rsp), %rdi
callq 0x52b0
movq %rax, 0x10(%rsp)
cmpq $0x1000, 0x10(%rsp)     # imm = 0x1000
jb 0x1cd3a
movq $0x1000, 0x10(%rsp)     # imm = 0x1000
jmp 0x1cd3c
movl 0x30(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0x28(%rsp), %rdi
callq 0x5190
movl 0xc(%rsp), %edi
movq %rax, %rsi
movq 0x10(%rsp), %rdx
callq 0x5140
movq %rax, 0x20(%rsp)
cmpq $0x0, 0x20(%rsp)
jle 0x1cdcd
movq 0x20(%rsp), %rcx
movslq 0x1c(%rsp), %rax
addq %rcx, %rax
movl %eax, 0x1c(%rsp)
movq 0x28(%rsp), %rdi
movq 0x20(%rsp), %rdx
xorl %eax, %eax
movl %eax, %esi
callq 0x50b0
movq 0x28(%rsp), %rdi
callq 0x52b0
movq %rax, 0x10(%rsp)
cmpq $0x1000, 0x10(%rsp)     # imm = 0x1000
jb 0x1cdb3
movq $0x1000, 0x10(%rsp)     # imm = 0x1000
cmpq $0x0, 0x10(%rsp)
jne 0x1cdc8
movl 0x1c(%rsp), %eax
movl %eax, 0x34(%rsp)
jmp 0x1cecc
jmp 0x1cec7
cmpq $0x0, 0x20(%rsp)
jge 0x1cebd
callq 0x5060
cmpl $0xb, (%rax)
jne 0x1ce12
movq 0x1e1c6(%rip), %rdi     # 0x3afb0
leaq 0xc307(%rip), %rsi      # 0x290f8
callq 0x53a0
movq %rax, %rdi
movq 0x1e180(%rip), %rsi     # 0x3af80
callq 0x53f0
movl 0x1c(%rsp), %eax
movl %eax, 0x34(%rsp)
jmp 0x1cecc
callq 0x5060
cmpl $0x4, (%rax)
jne 0x1ce43
movq 0x1e18d(%rip), %rdi     # 0x3afb0
leaq 0xc2f0(%rip), %rsi      # 0x2911a
callq 0x53a0
movq %rax, %rdi
movq 0x1e147(%rip), %rsi     # 0x3af80
callq 0x53f0
jmp 0x1cd3c
callq 0x5060
cmpl $0x20, (%rax)
jne 0x1ce85
leaq 0xc2db(%rip), %rdi      # 0x2912f
callq 0x5320
movq 0x1e150(%rip), %rdi     # 0x3afb0
leaq 0xc2d4(%rip), %rsi      # 0x2913b
callq 0x53a0
movq %rax, %rdi
movq 0x1e10a(%rip), %rsi     # 0x3af80
callq 0x53f0
movl $0xffffffff, 0x34(%rsp) # imm = 0xFFFFFFFF
jmp 0x1cecc
leaq 0xc2a3(%rip), %rdi      # 0x2912f
callq 0x5320
movq 0x1e118(%rip), %rdi     # 0x3afb0
leaq 0xc2bb(%rip), %rsi      # 0x2915a
callq 0x53a0
movq %rax, %rdi
movq 0x1e0d2(%rip), %rsi     # 0x3af80
callq 0x53f0
movl $0xffffffff, 0x34(%rsp) # imm = 0xFFFFFFFF
jmp 0x1cecc
movl $0x0, 0x34(%rsp)
jmp 0x1cecc
jmp 0x1cd3c
movl 0x34(%rsp), %eax
addq $0x38, %rsp
retq
nopw %cs:(%rax,%rax)