// File: /workspace/github_c_makefile_star2_O0/patriciogonzalezvivo[P]tprint/include/serial/unix.cc
// Function: serial::Serial::SerialImpl::read(unsigned char*, unsigned long)
size_t
Serial::SerialImpl::read (uint8_t *buf, size_t size)
{
  // If the port is not open, throw
  if (!is_open_) {
    throw PortNotOpenedException ("Serial::read");
  }
  size_t bytes_read = 0;

  // Calculate total timeout in milliseconds t_c + (t_m * N)
  long total_timeout_ms = timeout_.read_timeout_constant;
  total_timeout_ms += timeout_.read_timeout_multiplier * static_cast<long> (size);
  MillisecondTimer total_timeout(total_timeout_ms);

  // Pre-fill buffer with available bytes
  {
    ssize_t bytes_read_now = ::read (fd_, buf, size);
    if (bytes_read_now > 0) {
      bytes_read = bytes_read_now;
    }
  }

  while (bytes_read < size) {
    int64_t timeout_remaining_ms = total_timeout.remaining();
    if (timeout_remaining_ms <= 0) {
      // Timed out
      break;
    }
    // Timeout for the next select is whichever is less of the remaining
    // total read timeout and the inter-byte timeout.
    uint32_t timeout = std::min(static_cast<uint32_t> (timeout_remaining_ms),
                                timeout_.inter_byte_timeout);
    // Wait for the device to be readable, and then attempt to read.
    if (waitReadable(timeout)) {
      // If it's a fixed-length multi-byte read, insert a wait here so that
      // we can attempt to grab the whole thing in a single IO call. Skip
      // this wait if a non-max inter_byte_timeout is specified.
      if (size > 1 && timeout_.inter_byte_timeout == Timeout::max()) {
        size_t bytes_available = available();
        if (bytes_available + bytes_read < size) {
          waitByteTimes(size - (bytes_available + bytes_read));
        }
      }
      // This should be non-blocking returning only what is available now
      //  Then returning so that select can block again.
      ssize_t bytes_read_now =
        ::read (fd_, buf + bytes_read, size - bytes_read);
      // read should always return some data as select reported it was
      // ready to read when we get to this point.
      if (bytes_read_now < 1) {
        // Disconnected devices, at least on Linux, show the
        // behavior that they are always ready to read immediately
        // but reading returns nothing.
        throw SerialException ("device reports readiness to read but "
                               "returned no data (device disconnected?)");
      }
      // Update bytes_read
      bytes_read += static_cast<size_t> (bytes_read_now);
      // If bytes_read == size then we have read everything we need
      if (bytes_read == size) {
        break;
      }
      // If bytes_read < size then we have more to read
      if (bytes_read < size) {
        continue;
      }
      // If bytes_read > size then we have over read, which shouldn't happen
      if (bytes_read > size) {
        throw SerialException ("read over read, too many bytes where "
                               "read, this shouldn't happen, might be "
                               "a logical error!");
      }
    }
  }
  return bytes_read;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x78(%rbp)
testb $0x1, 0x2c(%rax)
jne 0x15a68
movl $0x28, %edi
callq 0xd1e0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x80(%rbp)
leaq 0x17876(%rip), %rsi     # 0x2d2a6
callq 0x18610
jmp 0x15a37
movq -0x80(%rbp), %rdi
leaq 0x2028e(%rip), %rsi     # 0x35cd0
leaq 0x2d07(%rip), %rdx      # 0x18750
callq 0xd720
movq -0x80(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
callq 0xd2c0
jmp 0x15c97
movq -0x78(%rbp), %rax
movq $0x0, -0x30(%rbp)
movl 0x34(%rax), %ecx
movq %rcx, -0x38(%rbp)
movl 0x38(%rax), %eax
imulq -0x18(%rbp), %rax
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movl %eax, %esi
leaq -0x48(%rbp), %rdi
callq 0x14090
movq -0x78(%rbp), %rax
movl 0x28(%rax), %edi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0xd600
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
jle 0x15ac1
movq -0x50(%rbp), %rax
movq %rax, -0x30(%rbp)
jmp 0x15ac3
movq -0x30(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x15c8a
leaq -0x48(%rbp), %rdi
callq 0x14180
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
jg 0x15aea
jmp 0x15c8a
movq -0x78(%rbp), %rsi
movq -0x58(%rbp), %rax
movl %eax, -0x60(%rbp)
addq $0x30, %rsi
leaq -0x60(%rbp), %rdi
callq 0x18790
movq -0x78(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %esi
callq 0x15630
testb $0x1, %al
jne 0x15b1c
jmp 0x15c85
cmpq $0x1, -0x18(%rbp)
jbe 0x15b76
movq -0x78(%rbp), %rax
movl 0x30(%rax), %eax
movl %eax, -0x84(%rbp)
callq 0x187d0
movl %eax, %ecx
movl -0x84(%rbp), %eax
cmpl %ecx, %eax
jne 0x15b76
movq -0x78(%rbp), %rdi
callq 0x15510
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
addq -0x30(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x15b74
movq -0x78(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x68(%rbp), %rax
addq -0x30(%rbp), %rax
subq %rax, %rsi
callq 0x159a0
jmp 0x15b76
movq -0x78(%rbp), %rax
movl 0x28(%rax), %edi
movq -0x10(%rbp), %rsi
addq -0x30(%rbp), %rsi
movq -0x18(%rbp), %rdx
subq -0x30(%rbp), %rdx
callq 0xd600
movq %rax, -0x70(%rbp)
cmpq $0x1, -0x70(%rbp)
jge 0x15bf9
movl $0x28, %edi
callq 0xd1e0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x90(%rbp)
leaq 0x176f8(%rip), %rsi     # 0x2d2b3
callq 0x17ff0
jmp 0x15bc2
movq -0x90(%rbp), %rdi
leaq 0x200d0(%rip), %rsi     # 0x35ca0
leaq 0x2559(%rip), %rdx      # 0x18130
callq 0xd720
movq -0x90(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
callq 0xd2c0
jmp 0x15c97
movq -0x70(%rbp), %rax
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x18(%rbp), %rax
jne 0x15c11
jmp 0x15c8a
movq -0x30(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x15c20
jmp 0x15ac3
movq -0x30(%rbp), %rax
cmpq -0x18(%rbp), %rax
jbe 0x15c83
movl $0x28, %edi
callq 0xd1e0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x98(%rbp)
leaq 0x176b8(%rip), %rsi     # 0x2d300
callq 0x17ff0
jmp 0x15c4f
movq -0x98(%rbp), %rdi
leaq 0x20043(%rip), %rsi     # 0x35ca0
leaq 0x24cc(%rip), %rdx      # 0x18130
callq 0xd720
movq -0x98(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
callq 0xd2c0
jmp 0x15c97
jmp 0x15c85
jmp 0x15ac3
movq -0x30(%rbp), %rax
addq $0xa0, %rsp
popq %rbp
retq
movq -0x20(%rbp), %rdi
callq 0xd750