/***************************************************************
* PrDataOutput.cpp
*
* This is an implementation of DataOutput methods.
*
****************************************************************/

/*
* modification history
*----------------------
*
* 02/14/98: K.C. Chang: created.
*/

#include "PrDataOutput.h"
#include "PrSocket.h"

#include <assert.h>
#include <stdio.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

/*typedef union
{
	double d;
	struct 
	{
		long l,h;
	} s;
} RemapDouble;*/

PrDataOutput::PrDataOutput( PrSocket *socket, int bufferSize )
{
   socketFD_ = socket->socketFD();
   Init(bufferSize);
}

PrDataOutput::~PrDataOutput()
{
   delete[] buffer_;
}

void PrDataOutput::bufferSize(int nbytes)
{
   delete[] buffer_;
   Init(nbytes);
}

int PrDataOutput::Send( CMsg& msg )
{
   char* buffer = NULL;
   int cBytes = msg.GetRawMsg( buffer );

   assert( cBytes > 0 && buffer != NULL );
   byteCounter_ = cBytes;
   Send( buffer );

   return byteCounter_ - InitByteCounter();
}

/*
int PrDataOutput::flush( int type )
{
	Pack2B(buffer_,(short)byteCounter_);
	Pack2B(buffer_+2,(short)type);
	int n=Send( buffer_ );
	if (n!= byteCounter_)
		perror("PrDataOutput: flush() error");

	memset(buffer_,'\0',bufferSize_);
	return ( n - InitByteCounter() );
}*/

// little endian
//   [0] [1] [2] [3]
//    1   0   0   0
// big endian
//   [0] [1] [2] [3]
//    0   0   0   1
/*int PrDataOutput::Endian()
{
	int aint=1;
	char *cptr = (char *)&aint;
	if (*cptr == '\0')
		return PR_BIG_ENDIAN; // 1 => big endian
	else
		return PR_LITTLE_ENDIAN;
}*/

void PrDataOutput::Init(int nbytes)
{
   //endian_ = Endian();

   bufferSize_ = nbytes + InitByteCounter();
   buffer_ = new char[bufferSize_];
   memset(buffer_,'\0',bufferSize_);
}


// p279 in UNIX Network Programming by Stevens
int PrDataOutput::Send( const char* buffer ) const
{
   const char *ptr = buffer;
   int nleft,nwritten;

   nleft = byteCounter_;
   while(nleft>0)
   {
      nwritten = send(socketFD_,ptr,nleft,0);
      if(nwritten<=0) return (nwritten); /* error */
      nleft -= nwritten;
      ptr += nwritten;
   }
   return(byteCounter_ - nleft);
}



