// File: /workspace/github_c_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
cmpb $0x0, 0x2c(%rdi)
je 0xba43
movq %rdx, %r14
movq %rsi, %rbx
movq %rdi, %r15
movl 0x38(%rdi), %esi
imull %r14d, %esi
addl 0x34(%rdi), %esi
leaq -0x40(%rbp), %r12
movq %r12, %rdi
callq 0xab68
movl 0x28(%r15), %edi
movq %rbx, -0x30(%rbp)
movq %rbx, %rsi
movq %r14, %rdx
callq 0x8490
xorl %r13d, %r13d
testq %rax, %rax
cmovgq %rax, %r13
movq %r14, %rbx
subq %r13, %rbx
jbe 0xba31
movq %r12, %rdi
callq 0xabfc
testq %rax, %rax
jle 0xba31
movl 0x30(%r15), %ecx
cmpl %eax, %ecx
cmovbl %ecx, %eax
movq %r15, %rdi
movl %eax, %esi
callq 0xb77c
testb %al, %al
je 0xb993
cmpq $0x2, %r14
jb 0xb9ef
cmpl $-0x1, 0x30(%r15)
jne 0xb9ef
movq %r15, %rdi
callq 0xb6c2
addq %r13, %rax
movq %r14, %rsi
subq %rax, %rsi
jbe 0xb9ef
movq %r15, %rdi
callq 0xb90a
movl 0x28(%r15), %edi
movq -0x30(%rbp), %rax
leaq (%rax,%r13), %rsi
movq %rbx, %rdx
callq 0x8490
testq %rax, %rax
jle 0xba6d
addq %rax, %r13
cmpq %r14, %r13
je 0xba2e
jbe 0xb993
pushq $0x28
popq %rdi
callq 0x81a0
movq %rax, %rbx
leaq 0xc93d(%rip), %rsi      # 0x18361
movq %rax, %rdi
callq 0xcee8
jmp 0xba87
movq %r14, %r13
movq %r13, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x28
popq %rdi
callq 0x81a0
movq %rax, %rbx
leaq 0xc8b2(%rip), %rsi      # 0x18307
movq %rax, %rdi
callq 0xd2ca
leaq 0x1427c(%rip), %rsi     # 0x1fce0
leaq 0x193d(%rip), %rdx      # 0xd3a8
jmp 0xba95
pushq $0x28
popq %rdi
callq 0x81a0
movq %rax, %rbx
leaq 0xc895(%rip), %rsi      # 0x18314
movq %rax, %rdi
callq 0xcee8
leaq 0x14222(%rip), %rsi     # 0x1fcb0
leaq 0x1531(%rip), %rdx      # 0xcfc6
movq %rbx, %rdi
callq 0x8590
jmp 0xbaa1
jmp 0xbaa1
movq %rax, %r14
movq %rbx, %rdi
callq 0x8240
movq %r14, %rdi
callq 0x85c0