// File: davmac314[P]dinit/src/dinit-iostream.cc
// Function: dio::ostream::put(char const*, unsigned long)
ssize_t ostream::put(const char *msg, size_t count) noexcept
{
    if (!good()) {
        return -1;
    }

    if (count == 0) {
        return 0;
    }

    size_t remaining_bytes = count;
    while (remaining_bytes > static_cast<unsigned>(buf->get_free())) {
        struct iovec bufv[3];
        char *ptr = buf->get_ptr(0);

        bufv[0].iov_base = ptr;
        bufv[0].iov_len = buf->get_contiguous_length(ptr);
        if (buf->get_length() != bufv[0].iov_len) {
            // buffer's data in streambuf is split into two parts in this case because of cpbuffer nature.
            bufv[1].iov_base = buf->get_buf_base();
            bufv[1].iov_len = buf->get_length() - bufv[0].iov_len;
        }
        else {
            bufv[1].iov_base = nullptr;
            bufv[1].iov_len = 0;
        }
        bufv[2].iov_base = const_cast<char *>(msg);
        bufv[2].iov_len = remaining_bytes;

        ssize_t cur_written_bytes = writev_unintr(fd, bufv, 3);
        if (cur_written_bytes < 0) {
            io_error = errno;
            // Some bytes may be written in previous iteration
            return (count - remaining_bytes > 0) ? count - remaining_bytes : -1;
        }
        if (cur_written_bytes >= buf->get_length()) {
            cur_written_bytes -= buf->get_length();
            buf->consume(buf->get_length());
            remaining_bytes -= cur_written_bytes;
            if (remaining_bytes == 0) {
                return count;
            }
            msg += cur_written_bytes;
        }
        else {
            buf->consume(cur_written_bytes);
        }
    }

    buf->append(msg, remaining_bytes);
    return count;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x78(%rbp)
callq 0x1fef0
testb $0x1, %al
jne 0x1fc25
movq $-0x1, -0x8(%rbp)
jmp 0x1fed9
cmpq $0x0, -0x20(%rbp)
jne 0x1fc39
movq $0x0, -0x8(%rbp)
jmp 0x1fed9
movq -0x20(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x78(%rbp), %rdi
movq -0x28(%rbp), %rax
movq %rax, -0x80(%rbp)
addq $0x8, %rdi
callq 0x21d10
movq %rax, %rdi
callq 0x21d30
movl %eax, %ecx
movq -0x80(%rbp), %rax
movl %ecx, %ecx
cmpq %rcx, %rax
jbe 0x1feb2
movq -0x78(%rbp), %rdi
addq $0x8, %rdi
callq 0x21d10
movq %rax, %rdi
xorl %esi, %esi
callq 0x21d50
movq %rax, -0x88(%rbp)
jmp 0x1fc8f
movq -0x78(%rbp), %rdi
movq -0x88(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0x60(%rbp)
addq $0x8, %rdi
callq 0x21d10
movq %rax, %rdi
movq -0x68(%rbp), %rsi
callq 0x21d90
movl %eax, -0x8c(%rbp)
jmp 0x1fcc3
movq -0x78(%rbp), %rdi
movl -0x8c(%rbp), %eax
movl %eax, %eax
movq %rax, -0x58(%rbp)
addq $0x8, %rdi
callq 0x21d10
movq %rax, %rdi
callq 0x21e20
movl %eax, %eax
cmpq -0x58(%rbp), %rax
je 0x1fd36
movq -0x78(%rbp), %rdi
addq $0x8, %rdi
callq 0x21d10
movq %rax, %rdi
callq 0x21e40
movq %rax, -0x98(%rbp)
jmp 0x1fd0a
movq -0x78(%rbp), %rdi
movq -0x98(%rbp), %rax
movq %rax, -0x50(%rbp)
addq $0x8, %rdi
callq 0x21d10
movq %rax, %rdi
callq 0x21e20
movl %eax, %eax
subq -0x58(%rbp), %rax
movq %rax, -0x48(%rbp)
jmp 0x1fd46
movq $0x0, -0x50(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x78(%rbp), %rax
movq -0x18(%rbp), %rcx
movq %rcx, -0x40(%rbp)
movq -0x28(%rbp), %rcx
movq %rcx, -0x38(%rbp)
movl (%rax), %edi
leaq -0x60(%rbp), %rsi
movl $0x3, %edx
callq 0x21e50
movl %eax, -0x9c(%rbp)
jmp 0x1fd72
movl -0x9c(%rbp), %eax
cltq
movq %rax, -0x70(%rbp)
cmpq $0x0, -0x70(%rbp)
jge 0x1fdd5
callq 0x5050
movq %rax, %rcx
movq -0x78(%rbp), %rax
movl (%rcx), %ecx
movl %ecx, 0x10(%rax)
movq -0x20(%rbp), %rax
subq -0x28(%rbp), %rax
cmpq $0x0, %rax
jbe 0x1fdb5
movq -0x20(%rbp), %rax
subq -0x28(%rbp), %rax
movq %rax, -0xa8(%rbp)
jmp 0x1fdc5
movq $-0x1, %rax
movq %rax, -0xa8(%rbp)
jmp 0x1fdc5
movq -0xa8(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x1fed9
movq -0x78(%rbp), %rdi
movq -0x70(%rbp), %rax
movq %rax, -0xb0(%rbp)
addq $0x8, %rdi
callq 0x21d10
movq %rax, %rdi
callq 0x21e20
movl %eax, %ecx
movq -0xb0(%rbp), %rax
movl %ecx, %ecx
cmpq %rcx, %rax
jl 0x1fe92
movq -0x78(%rbp), %rdi
addq $0x8, %rdi
callq 0x21d10
movq %rax, %rdi
callq 0x21e20
movq -0x78(%rbp), %rdi
movl %eax, %eax
movl %eax, %ecx
movq -0x70(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x70(%rbp)
addq $0x8, %rdi
callq 0x21d10
movq -0x78(%rbp), %rdi
movq %rax, -0xb8(%rbp)
addq $0x8, %rdi
callq 0x21d10
movq %rax, %rdi
callq 0x21e20
movq -0xb8(%rbp), %rdi
movl %eax, %esi
callq 0x21ea0
movq -0x70(%rbp), %rcx
movq -0x28(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x1fe84
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x1fed9
movq -0x70(%rbp), %rax
addq -0x18(%rbp), %rax
movq %rax, -0x18(%rbp)
jmp 0x1fead
movq -0x78(%rbp), %rdi
addq $0x8, %rdi
callq 0x21d10
movq %rax, %rdi
movq -0x70(%rbp), %rax
movl %eax, %esi
callq 0x21ea0
jmp 0x1fc41
movq -0x78(%rbp), %rdi
addq $0x8, %rdi
callq 0x21d10
movq %rax, %rdi
movq -0x18(%rbp), %rsi
movq -0x28(%rbp), %rax
movl %eax, %edx
callq 0x21f00
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xc0, %rsp
popq %rbp
retq
movq %rax, %rdi
callq 0x103e0
nop