/*******************************************************************************
 *	BEvent.cpp	File Event class
 *			T.Barnaby,	BEAM Ltd,	2005-07-08
 *******************************************************************************
 */
#include	<stdlib.h>
#include	<unistd.h>
#include	<errno.h>
#include	<BEvent.h>
#include	<BPoll.h>

BEvent::BEvent(uint32_t	type) : otype(type){
}

BEvent::~BEvent(){
}

uint32_t BEvent::getType(){
	return otype;
}

BError BEvent::getBinary(void* data, uint32_t& size){
	BError	err;
	
	memcpy(data, &otype, sizeof(otype));
	size = sizeof(otype);
	
	return err;
}

BError BEvent::setBinary(void* data, uint32_t& size){
	BError	err;
	
	memcpy(&otype, data, sizeof(otype));
	size = sizeof(otype);
	
	return err;
}

BEventError::BEventError(int errNo, BString errStr) : BError(errNo, errStr), BEvent(BEventTypeError){
}

BError BEventError::getBinary(void* data, uint32_t& size){
	BError	err;
	char*	d = (char*)data;
	int	errNo;
	
	if(! (err = BEvent::getBinary(data, size))){
		errNo = getErrorNo();
		memcpy(&d[size], &errNo, sizeof(errNo));
		size += sizeof(errNo);
		memcpy(&d[size], getString().retStr(), getString().len() + 1);
		size += getString().len() + 1;
	}
	
	return err;
}

BError BEventError::setBinary(void* data, uint32_t& size){
	BError		err;
	char*		d = (char*)data;
	uint32_t&	s = size;
	int		errNo;
	
	if(! (err = BEvent::setBinary(data, s))){
		memcpy(&errNo, &d[s], sizeof(errNo));
		s += sizeof(errNo);
		set(errNo, &d[s]);
		s += (getString().len() + 1);
		size = s;
	}
	
	return err;
}



BEventPipe::BEventPipe(){
	pipe(ofds);
}

BEventPipe::~BEventPipe(){
	close(ofds[0]);
	close(ofds[1]);
}


BError BEventPipe::sendEvent(BEvent* event){
	BError		err;
	uint32_t	buffer[256];
	uint32_t	size = sizeof(buffer);
	
	err = event->getBinary(&buffer[1], size);
	buffer[0] = size;
	
	if(!err)
		write(ofds[1], buffer, 4 + size);
	
	return err;
}

BError BEventPipe::getEvent(BEvent* event, int timeOutUs){
	BError		err;
	uint32_t	buffer[256];
	uint32_t	size = sizeof(buffer);
	BPoll		poll;
	int		fd;
	
	if(timeOutUs >= 0){
		poll.append(ofds[0]);
		if(err = poll.doPoll(fd, timeOutUs))
			return err;
	}
	
	read(ofds[0], buffer, 4);
	size = buffer[0];
	read(ofds[0], &buffer[1], size);

	err = event->setBinary(&buffer[1], size);
	
	return err;
	
}

int BEventPipe::getReceiveFd(){
	return ofds[0];
}

	
BEventInt::BEventInt(){
	pipe(ofds);
}

BEventInt::~BEventInt(){
	close(ofds[0]);
	close(ofds[1]);
}

BError BEventInt::sendEvent(int event){
	BError	err;
	
	write(ofds[1], &event, sizeof(event));
	
	return err;
}

BError BEventInt::getEvent(int& event, int timeOutUs){
	BError		err;
	BPoll		poll;
	int		fd;
	
	if(timeOutUs >= 0){
		poll.append(ofds[0]);
		if(err = poll.doPoll(fd, timeOutUs))
			return err;
	}
		
	read(ofds[0], &event, sizeof(event));
	
	return err;
}

int BEventInt::getFd(){
	return ofds[0];
}
