www.pudn.com > zfxcengine-0.1.0.zip > ceNetpacket.cpp


/* $Id: ceNetpacket.cpp,v 1.2 2005/07/03 17:34:43 andreaskohn Exp $ */ 
// METAINFO tapstop=4 
//  Module:     nepacket 
//  File:       ceNetpacket.cpp 
//  Created:    Mo Jun  6 02:26:31 CEST 2005 
//  Author:     Jürgen Buntrock aka jubu 
 
#include "Core/ceExceptions.h" 
#include "Core/ceDebug.h" 
#include "Math/ceMath.h" 
#include "Network/ceNetpacket.h" 
 
#include  
#include  
#include  
 
#ifdef WIN32 
#include  
#else 
#include  
#endif 
 
// XXX This File is not ready for doxgen sorry. 
 
// This is for the representation layer. 
// No network IO is done in this class. 
// 32bit words are coded with htonl 
// 32bit float ist cast to 32bit and coded with htonl 
// 64bit int is coded most significant 32bit part first 
// strings coded with 32bit length followed by the byte sequence 
 
// Error handling: 
// There is no special error handling for now. 
// If an error occur it will rais an exception 
// via CE_EXCEPTION(..., CELS_ERROR) the whole 
// programm will termitnate in this case. 
 
using namespace std; 
 
namespace ZFXCE { 
namespace Network { 
const int HEADER_SIZE = 4; // header ist just length of the packet. 
const int MIN_SIZE = 32; // Minimum bytes to alloc for the internel buffer. 
int g_packid = 100; // global variable to number each packet unique. 
	netpacket::netpacket(){ 
		PUSH_FUNCTION 
		m_id = g_packid++; //unique packetid, should be unique over the net in future. 
		m_buf_size = 0; // current buffersize. 
		m_len = 0; // current used bytes in buffer. 
		m_pointer = 0; // used by getval. Points to next untranslateted byte. 
		m_finished = 0; // The buffer is ready to transmit or to translate. 
		m_buffer = NULL; // buffer may be changed with realloc. 
		m_nofree = 0; // buffer is owned by other, don't free it when delete Object. 
	} 
	netpacket::~netpacket(){ 
		PUSH_FUNCTION 
		// This should handled better in future. The nofree concept is bad. 
		if(m_buffer && !m_nofree){ 
			free(m_buffer); 
			m_buffer = NULL; 
		} 
	} 
    void netpacket::putval(int val){ 
		PUSH_FUNCTION 
		checkalloc(4); 
		int nval = htonl(val); 
		memcpy(&m_buffer[m_len],(char *)&nval,4); 
		m_len += 4; 
	} 
	void netpacket::getval(int &val){ 
		PUSH_FUNCTION 
		int nval; 
		checkpointer(4); 
		memcpy(&nval,&m_buffer[m_pointer],4); 
		val = ntohl(nval); 
		m_pointer += 4; 
	} 
 
	char *netpacket::getcstring(){ 
		PUSH_FUNCTION 
		int len; 
		char *buf; 
		getval(len); 
		buf = (char *)malloc(len+1); 
		if(!buf){ 
			CE_EXCEPTION("Bad Malloc", CELS_ERROR); 
		} 
		checkpointer(len); 
		memcpy(buf,&m_buffer[m_pointer],len); 
		buf[len] = 0; 
		m_pointer += len; 
		return(buf); 
	} 
 
    void netpacket::putval(int len,const char* data){ 
		PUSH_FUNCTION 
		checkalloc(4+len); 
		putval(len); 
		memcpy(&m_buffer[m_len],data,len); 
		m_len += len; 
	} 
    void netpacket::putval(int64 val){ 
		PUSH_FUNCTION 
		checkalloc(8); 
		int nval[2] = {htonl((int)(val>>32)), htonl((int)((val)))}; 
		memcpy(&m_buffer[m_len],(char *)nval,8); 
		m_len += 8; 
	} 
	void netpacket::getval(int64 &val){ 
		PUSH_FUNCTION 
		int xval[2]; 
		getval(xval[0]); 
		getval(xval[1]); 
		val = ((int64)(xval[0])<<32) | (((int64)xval[1]) & 0xffffffff); 
	} 
    void netpacket::putval(float val){ 
		PUSH_FUNCTION 
		checkalloc(4); 
		int nval = htonl(*(int*)&val); 
		memcpy(&m_buffer[m_len],(char *)&nval,4); 
		m_len += 4; 
	} 
	void netpacket::getval(float &val){ 
		PUSH_FUNCTION 
		checkpointer(4); 
		int xval; 
		getval(xval); 
		val = *(float*)&xval; 
	} 
 
    void netpacket::putval(ceVec3f val){ 
		PUSH_FUNCTION 
		checkalloc(12); 
		putval(val.x); 
		putval(val.y); 
		putval(val.z); 
	} 
    void netpacket::getval(ceVec3f &val){ 
		PUSH_FUNCTION 
		checkpointer(12); 
		getval(val.x); 
		getval(val.y); 
		getval(val.z); 
	} 
 
    int netpacket::getlen(){ 
		PUSH_FUNCTION 
		return(m_len); 
	} 
	void netpacket::putnetdata(int len,char *data){ 
		PUSH_FUNCTION 
		if(m_buf_size || m_len || m_finished || m_buffer){ 
			CE_EXCEPTION("Packet is not new", CELS_ERROR); 
		} 
		m_buffer = data; 
		m_buf_size = len; 
		m_finished = 1; 
		m_pointer = 0; 
		int len1; 
		m_len = len; 
		getval(len1); 
		if(m_len != len1 + 4){ 
		    cout << " m_len=" << m_len << " len=" << len << " len1=" << len1 << endl; 
			CE_EXCEPTION("Bad Packetsize", CELS_ERROR); 
		} 
		//cout << "putnetdata id= " << m_id << endl; 
	} 
	void netpacket::putval(string str){ 
		putval(str.length(),str.c_str()); 
	} 
	void netpacket::putnetdataNF(int len,char *data){ 
		m_nofree = 1; 
		putnetdata(len,data); 
	} 
	char* netpacket::getnetdata(){ 
		PUSH_FUNCTION 
		if(!m_finished){ 
			CE_EXCEPTION("Packet is not finished", CELS_ERROR); 
		} 
		return(m_buffer); 
	} 
	void netpacket::finish(){ 
		PUSH_FUNCTION 
		if(m_finished && m_buf_size>=4){ 
			CE_EXCEPTION("Packet is finished", CELS_ERROR); 
		} 
		int len = m_len; 
		m_len = 0; 
		putval(len-4); 
		m_len = len; 
		m_finished = 1; 
	} 
	void netpacket::printdata(){ 
		PUSH_FUNCTION 
		cout << "printdata m_len=" << m_len 
			<< " m_buf_size=" << m_buf_size 
			<< " m_finished=" << m_finished 
			<< " m_pointer=" << m_pointer 
			<< endl; 
		cout << hex; 
		for(int i=0;im_len){ 
			printdata(); 
			CE_EXCEPTION("Bad Pointer in Packet", CELS_ERROR); 
		} 
		 
	} 
	int m_buf_size,m_len,m_pointer; 
	int m_finished; 
	char *m_buffer; 
} 
}