#include "pxx_fd_buffer.ih"
#include "pxx_sys_error.ih"

#include <unistd.h>

namespace pxx
{

FD_Buffer::FD_Buffer (
  int _fd, size_t _size /* = Buffer::default_size */
) :
  Buffer (_size),
  fd (_fd),
  eod (false),
  nofill_flag (false)
{}

FD_Buffer::~FD_Buffer ()
{}

size_t FD_Buffer::write ()
{
  cursor = buf;
  while (length > 0) {
    ssize_t res = ::write(fd, cursor, length);
    if (res < 0) throw_sys_error(errno);
    if (res == 0) break;
    cursor += res;
    length -= res;
  }
  size_t ret = cursor - buf;
  cursor = buf;
  return ret;
}

size_t FD_Buffer::read ()
{
  length = 0;
  cursor = buf;
  if (!eod) {
    while (length < capacity) {
      if (associated != null) associated->write();
      ssize_t res = ::read(fd, buf + length, capacity - length);
      if (res < 0) throw_sys_error(errno);
      if (res == 0) { eod = true; break; }
      length += res;
      if (nofill_flag) break;
    }
  }
  return length;
}

}

