// File: mh0fm4[P]SCDC/src/components/transport/transport_tcp.cc
// Function: scdc_transport_tcp::receive(scdc_transport_connection_t*, void*, long long)
scdcint_t scdc_transport_tcp::receive(scdc_transport_connection_t *conn, void *buf, scdcint_t max_buf_size)
{
  SCDC_TRACE("receive: conn: '" << conn << "', buf: '" << buf << "', max_buf_size: " << max_buf_size);

  scdc_transport_tcp_connection_t *tcp_conn = static_cast<scdc_transport_tcp_connection_t *>(conn);

  if (max_buf_size <= 0)
  {
    SCDC_TRACE("connection: " << tcp_conn << ": receive: nothing to receive");
    return 0;
  }

  scdcint_t n = 0;

  bool except = false;

#if SCDC_TRANSPORT_TCP_USE_SHUTDOWN_EXCEPTION
  try
  {
#endif

do_recv:
    n = ::recv(tcp_conn->socket, buf, max_buf_size, 0);

    if (n < 0 && errno == EINTR)
    {
      SCDC_TRACE("receive: continuing after EINTR");
      goto do_recv;
    }

#if SCDC_TRANSPORT_TCP_USE_SHUTDOWN_EXCEPTION
  } catch (const scdc_transport_tcp_shutdown_ex &ex)
  {
    SCDC_INFO("connection " << tcp_conn << ": receive: catch shutdown receive");
    n = -1;
    except = false;
  }
#endif

  if (n < 0)
  {
    if (!except) SCDC_ERROR("connection: " << tcp_conn << ": receive: receive failed: '" << strerror(errno) << "'");
    return -1;
  }

  SCDC_TRACE("connection " << tcp_conn << ": receive: received " << n << " byte(s)");

  /* receiving 0 bytes signals that the socket was closed */
  if (n == 0) n = -1;

  return n;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
jmp 0x9c1ca
movq -0x18(%rbp), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x28(%rbp)
jg 0x9c1ea
jmp 0x9c1db
jmp 0x9c1dd
movq $0x0, -0x8(%rbp)
jmp 0x9c332
movq $0x0, -0x38(%rbp)
movb $0x0, -0x39(%rbp)
movq -0x30(%rbp), %rax
movl 0x2d4(%rax), %edi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
xorl %ecx, %ecx
callq 0xc1c0
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jge 0x9c22a
callq 0xc080
cmpl $0x4, (%rax)
jne 0x9c22a
jmp 0x9c226
jmp 0x9c228
jmp 0x9c1f6
cmpq $0x0, -0x38(%rbp)
jge 0x9c317
testb $0x1, -0x39(%rbp)
jne 0x9c30d
jmp 0x9c241
leaq 0x38460(%rip), %rax     # 0xd46a8
movq (%rax), %rdi
callq 0x2e8e0
cmpq $0x0, %rax
je 0x9c309
leaq 0x38447(%rip), %rax     # 0xd46a8
movq (%rax), %rdi
callq 0x2e900
leaq 0x38438(%rip), %rax     # 0xd46a8
movq (%rax), %rdi
callq 0x2e8e0
movq %rax, %rdi
leaq 0xa226(%rip), %rsi      # 0xa64a8
callq 0xc670
movq %rax, %rdi
leaq 0xd968(%rip), %rsi      # 0xa9bf9
callq 0xc670
movq %rax, %rdi
leaq 0xd8eb(%rip), %rsi      # 0xa9b8b
callq 0xc670
movq %rax, %rdi
movq -0x30(%rbp), %rsi
callq 0xc4f0
movq %rax, %rdi
leaq 0xda8f(%rip), %rsi      # 0xa9d4a
callq 0xc670
movq %rax, -0x48(%rbp)
callq 0xc080
movl (%rax), %edi
callq 0xc1d0
movq -0x48(%rbp), %rdi
movq %rax, %rsi
callq 0xc670
movq %rax, %rdi
leaq 0xc0ed(%rip), %rsi      # 0xa83d3
callq 0xc670
movq %rax, %rdi
movq 0x37ccb(%rip), %rsi     # 0xd3fc0
callq 0xc6d0
leaq 0x383a7(%rip), %rax     # 0xd46a8
movq (%rax), %rdi
callq 0x2e920
jmp 0x9c30b
jmp 0x9c30d
movq $-0x1, -0x8(%rbp)
jmp 0x9c332
jmp 0x9c319
jmp 0x9c31b
cmpq $0x0, -0x38(%rbp)
jne 0x9c32a
movq $-0x1, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax)