// File: /workspace/github_c_makefile_star2_O0/agl[P]obstcp/libobstcp.c
// Function: obstcp_rbuf_read
ssize_t EXPORTED
obstcp_rbuf_read(struct obstcp_rbuf *rbuf, uint8_t *buffer, size_t len,
                 ssize_t (*read) (void *ctx, uint8_t *buffer, size_t len),
                 void *ctx) {

  size_t copied = varbuf_copy_out(buffer, len, &rbuf->out);
  len -= copied;
  off_t j = copied;

  if (!len)
    return j;

  static const size_t rbuflen = OBSTCP_MAX_FRAME + OBSTCP_MAX_PREFIX;
  uint8_t rbuffer[rbuflen];

  const ssize_t n = read(ctx, rbuffer, rbuflen);
  if (n < 1)
    return n;

  struct varbuf_cursor inc;
  varbuf_cursor_init(&inc, &rbuf->in, rbuffer, n);

  size_t consumed;
  struct iovec outiov[8];
  unsigned outlen = 8;

  if (rbuf->is_server) {
    if (obstcp_server_read((struct obstcp_server_ctx *) rbuf->ctx,
                           outiov, &outlen, &consumed,
                           (struct obstcp_cursor *) &inc) == -1)
      return -1;
  } else {
    if (obstcp_client_read((struct obstcp_client_ctx *) rbuf->ctx,
                           outiov, &outlen, &consumed,
                           (struct obstcp_cursor *) &inc) == -1)
      return -1;
  }

  // Walk the output iovec and copy into the output buffer
  struct iovec_cursor outc;
  iovec_cursor_init(&outc, outiov, outlen);

  while (len && !iovec_cursor_full(&outc)) {
    struct iovec iov;
    iovec_cursor_get(&iov, &outc, len);
    memcpy(buffer + j, iov.iov_base, iov.iov_len);
    j += iov.iov_len;
    len -= iov.iov_len;
  }

  // Buffer any remaining output
  if (!varbuf_copy_iovec_cursor(&rbuf->out, &outc) == -1)
    return -1;

  // Discard all buffered input that was consumed
  const size_t remaining = varbuf_discard(&rbuf->in, consumed);

  if (remaining < n) {
    // Not all of @buffer was consumed
    varbuf_copy_in(&rbuf->in, rbuffer + remaining, n - remaining);
  }

  if (!j) {
    errno = EAGAIN;
    return -1;
  }

  return j;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x10(%rbp), %rdx
addq $0x18, %rdx
callq 0x4820
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rcx
movq -0x20(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x45a3
movq -0x40(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x480b
movq %rsp, %rax
movq %rax, -0x48(%rbp)
movq %rsp, %rsi
addq $-0x2040, %rsi          # imm = 0xDFC0
movq %rsi, -0x160(%rbp)
movq %rsi, %rsp
movq -0x28(%rbp), %rax
movq -0x30(%rbp), %rdi
movl $0x2040, %edx           # imm = 0x2040
callq *%rax
movq %rax, -0x50(%rbp)
cmpq $0x1, -0x50(%rbp)
jge 0x45ec
movq -0x50(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0x54(%rbp)
jmp 0x4804
movq -0x160(%rbp), %rdx
movq -0x10(%rbp), %rsi
addq $0x8, %rsi
movq -0x50(%rbp), %rcx
leaq -0x88(%rbp), %rdi
callq 0x4930
movl $0x8, -0x114(%rbp)
movq -0x10(%rbp), %rax
cmpb $0x0, 0x28(%rax)
je 0x4662
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq -0x110(%rbp), %rsi
leaq -0x114(%rbp), %rdx
leaq -0x90(%rbp), %rcx
leaq -0x88(%rbp), %r8
callq 0x24c0
cmpl $-0x1, %eax
jne 0x4660
movq $-0x1, -0x8(%rbp)
movl $0x1, -0x54(%rbp)
jmp 0x4804
jmp 0x46a5
movq -0x10(%rbp), %rax
movq (%rax), %rdi
leaq -0x110(%rbp), %rsi
leaq -0x114(%rbp), %rdx
leaq -0x90(%rbp), %rcx
leaq -0x88(%rbp), %r8
callq 0x36b0
cmpl $-0x1, %eax
jne 0x46a3
movq $-0x1, -0x8(%rbp)
movl $0x1, -0x54(%rbp)
jmp 0x4804
jmp 0x46a5
leaq -0x110(%rbp), %rsi
movl -0x114(%rbp), %edx
leaq -0x140(%rbp), %rdi
callq 0x2cc0
xorl %eax, %eax
cmpq $0x0, -0x20(%rbp)
movb %al, -0x161(%rbp)
je 0x46e6
leaq -0x140(%rbp), %rdi
callq 0x3f10
cmpb $0x0, %al
setne %al
xorb $-0x1, %al
movb %al, -0x161(%rbp)
movb -0x161(%rbp), %al
testb $0x1, %al
jne 0x46f2
jmp 0x474a
movq -0x20(%rbp), %rdx
leaq -0x150(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x40f0
movq -0x18(%rbp), %rdi
addq -0x40(%rbp), %rdi
movq -0x150(%rbp), %rsi
movq -0x148(%rbp), %rdx
callq 0x10d0
movq -0x148(%rbp), %rax
addq -0x40(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x148(%rbp), %rcx
movq -0x20(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x20(%rbp)
jmp 0x46be
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
leaq -0x140(%rbp), %rsi
callq 0x49a0
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
cmpl $-0x1, %eax
jne 0x4784
movq $-0x1, -0x8(%rbp)
movl $0x1, -0x54(%rbp)
jmp 0x4804
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x90(%rbp), %rsi
callq 0x4a10
movq %rax, -0x158(%rbp)
movq -0x158(%rbp), %rax
cmpq -0x50(%rbp), %rax
jae 0x47d2
movq -0x160(%rbp), %rsi
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
addq -0x158(%rbp), %rsi
movq -0x50(%rbp), %rdx
subq -0x158(%rbp), %rdx
callq 0x4b00
cmpq $0x0, -0x40(%rbp)
jne 0x47f5
callq 0x1050
movl $0xb, (%rax)
movq $-0x1, -0x8(%rbp)
movl $0x1, -0x54(%rbp)
jmp 0x4804
movq -0x40(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0x54(%rbp)
movq -0x48(%rbp), %rax
movq %rax, %rsp
movq -0x8(%rbp), %rax
movq %rbp, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)