/*!
  \file
  \brief 標準入出力

  \author Satofumi KAMIMURA

  $Id: StandardIo_lin.cpp 1302 2009-09-15 21:51:30Z satofumi $
*/

#include "StandardIo.h"
#include <string>
#include <sys/poll.h>

using namespace qrk;
using namespace std;


struct StandardIo::pImpl
{
  string error_message_;
  struct pollfd nfds_;


  pImpl(void)
  {
    nfds_.fd = 0;
    nfds_.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
    nfds_.revents = 0;
  }
};


StandardIo::StandardIo(void) : pimpl(new pImpl)
{
}


StandardIo::~StandardIo(void)
{
}


const char* StandardIo::what(void) const
{
  return pimpl->error_message_.c_str();
}


bool StandardIo::connect(const char* device, long baudrate)
{
  static_cast<void>(device);
  static_cast<void>(baudrate);

  // 実装しない

  return true;
}


void StandardIo::disconnect(void)
{
  // 実装しない
}


bool StandardIo::setBaudrate(long baudrate)
{
  // 実装しない
  return true;
}


long StandardIo::baudrate(void) const
{
  // 実装しない
  return 0;
}


bool StandardIo::isConnected(void) const
{
  return true;
}


int StandardIo::send(const char* data, size_t count)
{
  return fwrite(data, 1, count, stdout);
}


int StandardIo::receive(char* data, size_t count, int timeout)
{
  int filled = 0;

  while (filled < static_cast<int>(count)) {
    if (poll(&pimpl->nfds_, 1, timeout) == 0) {
      break;                    // timeout
    }

    int n = fread(&data[filled], 1, count - filled, stdin);
    if (n < 0) {
      return filled;
    }
    filled += n;
  }
  return filled;
}


size_t StandardIo::size(void) const
{
  // 実装しない
  return 0;
}


void StandardIo::flush(void)
{
  fflush(stdout);
}


void StandardIo::clear(void)
{
  // 実装しない
}


void StandardIo::ungetc(const char ch)
{
  std::ungetc(ch, stdin);
}
