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

  \author Satofumi KAMIMURA

  $Id: StandardIo_lin.cpp 1811 2010-04-30 16:12:05Z satofumi $
*/

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

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)
{
    static_cast<void>(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
        }

        fgets(&data[filled], count - filled, stdin);
        int n = strlen(&data[filled]);
        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);
}
