#include <config.h>
#include <errno.h>
#include <sys/types.h>
#include "IIIMPTrans.hh"
#include "IMUtil.hh"
#include "IMLog.hh"

bool
IIIMPTrans::send(
    IIIMP_message *pmes
)
{
    IIIMF_status st;

#ifdef DEBUG
    fputs("S->C", stdout);
    iiimp_message_print(pimplibstate, pmes);
#endif
    if (iiimf_stream_send(pstream, pimplibstate, pmes)
	!= IIIMF_STATUS_SUCCESS)
	return false;

    return true;
}

IIIMP_message*
IIIMPTrans::receive()
{
    IIIMF_status st;
    IIIMP_message *pmes;
 
    st = iiimf_stream_receive(pstream, pimplibstate, &pmes);
    if (st != IIIMF_STATUS_SUCCESS) return NULL;
#ifdef DEBUG
    fputs("C->S", stdout);
    iiimp_message_print(pimplibstate, pmes);
#endif

    return pmes;
}

IIIMPTrans::IIIMPTrans(
    IMSocketTrans *x_pimst
)
{
    pimst = x_pimst;
    iiimf_create_stream(IIIMPTrans_read, IIIMPTrans_write, this, 0, &pstream);
    pimplibstate = iiimp_data_s_new();
    open = true;
}

IIIMPTrans::~IIIMPTrans()
{
    delete pimst;
    iiimf_stream_delete(pstream);
    iiimp_data_s_delete(pimplibstate);
}

IIIMF_status
IIIMPTrans_read(
    IIIMF_stream_private ptrans,
    void *buf,
    size_t nbyte
)
{
    int st;
    int n = nbyte;
    unsigned char *p = (unsigned char*) buf;
    IIIMPTrans *pimt = (IIIMPTrans*) ptrans;
    while (n > 0) {
	// TODO!! (NOWAIT support)
	st = pimt->pimst->recv(p, n);
	if (st == -1) {
	    if (errno = EINTR) continue;
	    return IIIMF_STATUS_STREAM_RECEIVE;
	} else if (st == 0) {
	    // socket is closed.
	    pimt->open = false;
	    return IIIMF_STATUS_STREAM_RECEIVE;
	}
	n -= st;
	p += st;
    }

    return IIIMF_STATUS_SUCCESS;
}

IIIMF_status
IIIMPTrans_write(
    IIIMF_stream_private ptrans,
    const void* buf,
    size_t nbyte
)
{
    int st;
    int n = nbyte;
    const unsigned char *p = (const unsigned char*) buf;
    IIIMPTrans *pimt = (IIIMPTrans*) ptrans;

    while (n > 0) {
	// TODO!!
	st = pimt->pimst->send(p, n);
	if (st == -1) {
	    if (errno = EINTR) continue;
	    return IIIMF_STATUS_STREAM_RECEIVE;
	}
	n -= st;
	p += st;
    }

    return IIIMF_STATUS_SUCCESS;
}

//
/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
