// File: /workspace/github_cpp_makefile_star2_O3/nvanbenschoten[P]byzantine-agreement/src/general.cc
// Function: generals::SendMessage(std::shared_ptr<udp::Client const>, msg::Message const&)
void SendMessage(udp::ClientPtr client, const msg::Message& msg) {
  size_t size =
      sizeof(msg::ByzantineMessage) + sizeof(uint32_t) * msg.ids.size();
  char buf[size];
  bzero(buf, size);

  // Copy the message part.
  msg::ByzantineMessage* c_msg = reinterpret_cast<msg::ByzantineMessage*>(buf);
  c_msg->type = htonl(kByzantineMessageType);
  c_msg->size = htonl(size);
  c_msg->round = htonl(msg.round);
  c_msg->order = htonl(static_cast<int>(msg.order));

  // C++ does not support flexible arrays, so we need to be a little tricky
  // here. We already made sure the buffer was the correct size by adding space
  // for each of the ids at the end of ByzantineMessage. Now we populate the
  // array.
  uint32_t* id_buf = reinterpret_cast<uint32_t*>(buf + sizeof(*c_msg));
  for (size_t i = 0; i < msg.ids.size(); ++i) {
    id_buf[i] = htonl(msg.ids[i]);
  }

  // Passed to SendWithAck to verify that any acknowledgement we hear is valid.
  auto isValidAck = [msg](udp::ClientPtr _, char* buf, size_t n) {
    auto ackRound = RoundOfAck(buf, n);
    bool valid = ackRound && *ackRound == msg.round;
    if (!valid) return udp::ServerAction::Continue;
    return udp::ServerAction::Stop;
  };

  client->SendWithAck(buf, size, kSendAttempts, isValidAck);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rsi, %r13
movq %rdi, -0x68(%rbp)
leaq 0x8(%rsi), %rax
movq %rax, -0x60(%rbp)
movq 0x8(%rsi), %r15
movq 0x10(%rsi), %r12
movq %r12, %rax
subq %r15, %rax
leaq 0x10(%rax), %rdx
movq %rdx, -0x30(%rbp)
movq %rsp, %r14
movq %r14, -0x58(%rbp)
leaq 0x1f(%rax), %rbx
andq $-0x10, %rbx
subq %rbx, %r14
movq %r14, %rsp
movq %r14, %rdi
xorl %esi, %esi
callq 0x51f0
negq %rbx
movl $0x1000000, (%r14)      # imm = 0x1000000
movq -0x30(%rbp), %rax
bswapl %eax
movl %eax, 0x4(%r14)
movl (%r13), %eax
bswapl %eax
movl %eax, 0x8(%r14)
movl 0x4(%r13), %eax
bswapl %eax
movq -0x58(%rbp), %rcx
movl %eax, 0xc(%rcx,%rbx)
subq %r15, %r12
je 0x11460
sarq $0x2, %r12
cmpq $0x1, %r12
adcq $0x0, %r12
xorl %eax, %eax
movl (%r15,%rax,4), %ecx
bswapl %ecx
movl %ecx, 0x10(%r14,%rax,4)
incq %rax
cmpq %rax, %r12
jne 0x1144d
movq (%r13), %rax
leaq -0x80(%rbp), %r13
movq %rax, -0x8(%r13)
movq %r13, %rdi
movq -0x60(%rbp), %rsi
callq 0x12e2e
movq -0x68(%rbp), %rax
movq (%rax), %r15
xorps %xmm0, %xmm0
movaps %xmm0, -0x40(%rbp)
movaps %xmm0, -0x50(%rbp)
movl $0x20, %edi
callq 0x5330
movq %rax, %r12
movq -0x88(%rbp), %rax
movq %rax, (%r12)
movq %r12, %rdi
addq $0x8, %rdi
movq %r13, %rsi
callq 0x12e2e
leaq -0x50(%rbp), %r8
movq %r12, (%r8)
leaq 0x1087(%rip), %rax      # 0x12546
movq %rax, 0x18(%r8)
leaq 0x10b0(%rip), %rax      # 0x1257a
movq %rax, 0x10(%r8)
movq %r15, %rdi
movq %r14, %rsi
movq -0x30(%rbp), %rdx
movl $0x3, %ecx
callq 0x103d0
movq -0x40(%rbp), %rax
testq %rax, %rax
je 0x114f9
leaq -0x50(%rbp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movq -0x80(%rbp), %rdi
testq %rdi, %rdi
je 0x1150e
movq -0x70(%rbp), %rsi
subq %rdi, %rsi
callq 0x5340
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x11566
movq %rax, %rbx
movq -0x40(%rbp), %rax
testq %rax, %rax
je 0x11571
leaq -0x50(%rbp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
jmp 0x11571
jmp 0x11566
movq %rax, %rbx
movl $0x20, %esi
movq %r12, %rdi
callq 0x5340
movq -0x40(%rbp), %rax
testq %rax, %rax
je 0x11571
leaq -0x50(%rbp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
jmp 0x11571
movq %rax, %rdi
callq 0x9b59
movq %rax, %rbx
movq -0x80(%rbp), %rdi
testq %rdi, %rdi
je 0x11586
movq -0x70(%rbp), %rsi
subq %rdi, %rsi
callq 0x5340
movq %rbx, %rdi
callq 0x5600