// File: /workspace/github_c_makefile_star2_O0/agl[P]obstcp/libobstcp.c
// Function: obstcp_accum_prepare
void EXPORTED
obstcp_accum_prepare(struct obstcp_accum *ac,
                     struct iovec *out, unsigned *onumout,
                     const struct iovec *in, unsigned numin) {
  const unsigned numout = *onumout;
  struct iovec_cursor outc, inc, inccopy;
  struct obstcp_accum_buffer *ab = NULL;
  uint8_t c;

  iovec_cursor_init(&outc, out, numout);
  iovec_cursor_init(&inc, (struct iovec *) in, numin);

  // walk the list of buffers and add them to the output list
  for (c = ac->data_head; c != 0xff; c = ab->next) {
    ab = &ac->buffers[c];

    if (iovec_cursor_full(&outc)) goto out;
    if (ab->prefix_used < ab->prefix_len) {
      iovec_cursor_append(&outc,
                          ab->prefix + ab->prefix_used,
                          ab->prefix_len - ab->prefix_used);
    }

    if (iovec_cursor_full(&outc)) goto out;
    iovec_cursor_copy(&outc, &inc, ab->payload_len - ab->payload_used);
  }

  if (iovec_cursor_full(&outc) || iovec_cursor_full(&inc)) goto out;

  // If there are buffers remaining and data still in the input, we might as
  // well encrypt some more.
  while (ac->free_head != 0xff && !iovec_cursor_full(&inc)) {
    unsigned frame_remaining = ac->frame_size;
    struct iovec iov, iniov;

    // save the current cursor so that we can copy from it later
    memcpy(&inccopy, &inc, sizeof(inc));

    // try to fill up a whole frame
    while (frame_remaining && !iovec_cursor_full(&inc)) {
      iovec_cursor_get(&iov, &inc, frame_remaining);
      if (ac->is_server) {
        obstcp_server_encrypt((struct obstcp_server_ctx *) ac->ctx,
                              iov.iov_base, iov.iov_base, iov.iov_len);
      } else {
        obstcp_client_encrypt((struct obstcp_client_ctx *) ac->ctx,
                              iov.iov_base, iov.iov_base, iov.iov_len);
      }
      frame_remaining -= iov.iov_len;
    }

    // pop a buffer from the free list
    const uint8_t buffer_num = ac->free_head;
    ab = &ac->buffers[ac->free_head];
    ac->free_head = ab->next;

    if (ac->data_tail != 0xff) {
      ac->buffers[ac->data_tail].next = buffer_num;
    } else {
      ac->data_head = buffer_num;
    }
    ac->data_tail = buffer_num;

    ab->payload_len = ac->frame_size - frame_remaining;
    ab->payload_used = ab->prefix_used = 0;
    ab->next = 0xff;

    if (ac->is_server) {
      obstcp_server_prefix((struct obstcp_server_ctx *) ac->ctx, &iniov);
    } else {
      obstcp_client_prefix((struct obstcp_client_ctx *) ac->ctx, &iniov);
    }

    assert(iniov.iov_len < OBSTCP_MAX_PREFIX);
    memcpy(ab->prefix, iniov.iov_base, iniov.iov_len);
    ab->prefix_len = iniov.iov_len;

    if (!iovec_cursor_full(&outc)) {
      iovec_cursor_append(&outc, ab->prefix, ab->prefix_len);
    }
    if (!iovec_cursor_full(&outc)) {
      iovec_cursor_copy(&outc, &inccopy, ab->payload_len);
    }
  }

 out:
  *onumout = outc.i;
  return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x28(%rbp)
movq $0x0, -0xa8(%rbp)
movq -0x10(%rbp), %rsi
movl -0x28(%rbp), %edx
leaq -0x50(%rbp), %rdi
callq 0x2cc0
movq -0x20(%rbp), %rsi
movl -0x24(%rbp), %edx
leaq -0x78(%rbp), %rdi
callq 0x2cc0
movq -0x8(%rbp), %rax
movb 0x1bb(%rax), %al
movb %al, -0xa9(%rbp)
movzbl -0xa9(%rbp), %eax
cmpl $0xff, %eax
je 0x3beb
movq -0x8(%rbp), %rax
addq $0xa, %rax
movzbl -0xa9(%rbp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0xa8(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x3f10
cmpb $0x0, %al
je 0x3b44
jmp 0x3efa
movq -0xa8(%rbp), %rax
movzbl 0x5(%rax), %eax
movq -0xa8(%rbp), %rcx
movzbl 0x4(%rcx), %ecx
cmpl %ecx, %eax
jge 0x3b9d
movq -0xa8(%rbp), %rsi
addq $0x8, %rsi
movq -0xa8(%rbp), %rax
movzbl 0x5(%rax), %eax
cltq
addq %rax, %rsi
movq -0xa8(%rbp), %rax
movzbl 0x4(%rax), %eax
movq -0xa8(%rbp), %rcx
movzbl 0x5(%rcx), %ecx
subl %ecx, %eax
movslq %eax, %rdx
leaq -0x50(%rbp), %rdi
callq 0x3f30
leaq -0x50(%rbp), %rdi
callq 0x3f10
cmpb $0x0, %al
je 0x3baf
jmp 0x3efa
movq -0xa8(%rbp), %rax
movzwl (%rax), %eax
movq -0xa8(%rbp), %rcx
movzwl 0x2(%rcx), %ecx
subl %ecx, %eax
movslq %eax, %rdx
leaq -0x50(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x3f90
movq -0xa8(%rbp), %rax
movb 0x6(%rax), %al
movb %al, -0xa9(%rbp)
jmp 0x3b03
leaq -0x50(%rbp), %rdi
callq 0x3f10
movsbl %al, %eax
cmpl $0x0, %eax
jne 0x3c0d
leaq -0x78(%rbp), %rdi
callq 0x3f10
movsbl %al, %eax
cmpl $0x0, %eax
je 0x3c12
jmp 0x3efa
jmp 0x3c14
movq -0x8(%rbp), %rax
movzbl 0x1ba(%rax), %ecx
xorl %eax, %eax
cmpl $0xff, %ecx
movb %al, -0xd2(%rbp)
je 0x3c45
leaq -0x78(%rbp), %rdi
callq 0x3f10
cmpb $0x0, %al
setne %al
xorb $-0x1, %al
movb %al, -0xd2(%rbp)
movb -0xd2(%rbp), %al
testb $0x1, %al
jne 0x3c54
jmp 0x3ef8
movq -0x8(%rbp), %rax
movzwl 0x8(%rax), %eax
movl %eax, -0xb0(%rbp)
leaq -0xa0(%rbp), %rdi
leaq -0x78(%rbp), %rsi
movl $0x28, %edx
callq 0x10d0
xorl %eax, %eax
cmpl $0x0, -0xb0(%rbp)
movb %al, -0xd3(%rbp)
je 0x3c9e
leaq -0x78(%rbp), %rdi
callq 0x3f10
cmpb $0x0, %al
setne %al
xorb $-0x1, %al
movb %al, -0xd3(%rbp)
movb -0xd3(%rbp), %al
testb $0x1, %al
jne 0x3cad
jmp 0x3d31
movl -0xb0(%rbp), %eax
movl %eax, %edx
leaq -0xc0(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x40f0
movq -0x8(%rbp), %rax
cmpb $0x0, 0x1bd(%rax)
je 0x3cf5
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movq -0xc0(%rbp), %rsi
movq -0xc0(%rbp), %rdx
movq -0xb8(%rbp), %rcx
callq 0x2f70
jmp 0x3d16
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movq -0xc0(%rbp), %rsi
movq -0xc0(%rbp), %rdx
movq -0xb8(%rbp), %rcx
callq 0x3900
movq -0xb8(%rbp), %rcx
movl -0xb0(%rbp), %eax
subq %rcx, %rax
movl %eax, -0xb0(%rbp)
jmp 0x3c77
movq -0x8(%rbp), %rax
movb 0x1ba(%rax), %al
movb %al, -0xd1(%rbp)
movq -0x8(%rbp), %rax
addq $0xa, %rax
movq -0x8(%rbp), %rcx
movzbl 0x1ba(%rcx), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
movb 0x6(%rax), %cl
movq -0x8(%rbp), %rax
movb %cl, 0x1ba(%rax)
movq -0x8(%rbp), %rax
movzbl 0x1bc(%rax), %eax
cmpl $0xff, %eax
je 0x3dad
movb -0xd1(%rbp), %cl
movq -0x8(%rbp), %rax
addq $0xa, %rax
movq -0x8(%rbp), %rdx
movzbl 0x1bc(%rdx), %edx
imulq $0x48, %rdx, %rdx
addq %rdx, %rax
movb %cl, 0x6(%rax)
jmp 0x3dbd
movb -0xd1(%rbp), %cl
movq -0x8(%rbp), %rax
movb %cl, 0x1bb(%rax)
movb -0xd1(%rbp), %cl
movq -0x8(%rbp), %rax
movb %cl, 0x1bc(%rax)
movq -0x8(%rbp), %rax
movzwl 0x8(%rax), %eax
subl -0xb0(%rbp), %eax
movw %ax, %cx
movq -0xa8(%rbp), %rax
movw %cx, (%rax)
movq -0xa8(%rbp), %rax
movb $0x0, 0x5(%rax)
movq -0xa8(%rbp), %rax
movw $0x0, 0x2(%rax)
movq -0xa8(%rbp), %rax
movb $-0x1, 0x6(%rax)
movq -0x8(%rbp), %rax
cmpb $0x0, 0x1bd(%rax)
je 0x3e2d
movq -0x8(%rbp), %rax
movq (%rax), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x2ff0
jmp 0x3e40
movq -0x8(%rbp), %rax
movq (%rax), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x3940
cmpq $0x40, -0xc8(%rbp)
jae 0x3e4c
jmp 0x3e6b
leaq 0x834b(%rip), %rdi      # 0xc19e
leaq 0x82c3(%rip), %rsi      # 0xc11d
movl $0x411, %edx            # imm = 0x411
leaq 0x835a(%rip), %rcx      # 0xc1c0
callq 0x1080
movq -0xa8(%rbp), %rdi
addq $0x8, %rdi
movq -0xd0(%rbp), %rsi
movq -0xc8(%rbp), %rdx
callq 0x10d0
movq -0xc8(%rbp), %rax
movb %al, %cl
movq -0xa8(%rbp), %rax
movb %cl, 0x4(%rax)
leaq -0x50(%rbp), %rdi
callq 0x3f10
cmpb $0x0, %al
jne 0x3eca
movq -0xa8(%rbp), %rsi
addq $0x8, %rsi
movq -0xa8(%rbp), %rax
movzbl 0x4(%rax), %eax
movl %eax, %edx
leaq -0x50(%rbp), %rdi
callq 0x3f30
leaq -0x50(%rbp), %rdi
callq 0x3f10
cmpb $0x0, %al
jne 0x3ef3
movq -0xa8(%rbp), %rax
movzwl (%rax), %eax
movl %eax, %edx
leaq -0x50(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x3f90
jmp 0x3c14
jmp 0x3efa
movl -0x34(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, (%rax)
addq $0xe0, %rsp
popq %rbp
retq
nopl (%rax)