323 lines
10 KiB
C++
323 lines
10 KiB
C++
#ifndef _CDEV_PACKET_H_
|
|
#define _CDEV_PACKET_H_
|
|
|
|
#include <cdevPlatforms.h>
|
|
#include <cdevData.h>
|
|
#include <xdrClass.h>
|
|
|
|
// *****************************************************************************
|
|
// * struct cdevPacketBinaryMap :
|
|
// * This is the first 32 bit integer that is passed through the socket. It
|
|
// * contains a bitmap that identifies the version of the packet, as well as
|
|
// * a bit field that indicates the contents of the packet. This bitfield
|
|
// * simplifies the process of decoding the packet and results in a smaller
|
|
// * transmission size.
|
|
// *****************************************************************************
|
|
typedef union
|
|
{
|
|
unsigned rawData;
|
|
struct {
|
|
unsigned version : 16;
|
|
unsigned pad : 16;
|
|
} value;
|
|
} cdevPacketBinaryMap;
|
|
|
|
// *****************************************************************************
|
|
// * class cdevPacketBinary :
|
|
// * This is the base class for all cdevPacketBinary classes. It is a pure
|
|
// * virtual class that defines the mechanisms necessary for identifying
|
|
// * the version of a class as well as reading or generating a binary
|
|
// * stream.
|
|
// *
|
|
// * Enforced structural contraints...
|
|
// *
|
|
// * 1) Every packet that inherits from the cdevPacketBinary must have an
|
|
// * XDR encoded 4 byte integer at the beginning...
|
|
// *
|
|
// * a) The first two bytes of that 4 byte integer is the packet version.
|
|
// *
|
|
// * b) The second two bytes of that 4 byte integer is user defined data.
|
|
// *
|
|
// * 2) The next four bytes of the packet contains a XDR encoded short
|
|
// * integer that contains a 16 bit client identifier.
|
|
// *****************************************************************************
|
|
class GENERIC_SERVER_API cdevPacketBinary
|
|
{
|
|
protected:
|
|
// *********************************************************************
|
|
// * These are the data storage variables.
|
|
// *********************************************************************
|
|
char * binary;
|
|
size_t binaryLen;
|
|
|
|
public:
|
|
cdevPacketBinary ( void );
|
|
cdevPacketBinary ( cdevPacketBinary & packet );
|
|
virtual ~cdevPacketBinary ( void );
|
|
|
|
unsigned map2int ( cdevPacketBinaryMap map, unsigned & value);
|
|
cdevPacketBinaryMap int2map ( cdevPacketBinaryMap &map, unsigned value);
|
|
|
|
virtual int getVersion ( short & version );
|
|
virtual int getPad ( short & pad );
|
|
virtual int getClientID ( short & clientID );
|
|
virtual int setClientID ( short clientID );
|
|
virtual int streamOut ( char ** stream, size_t * len );
|
|
virtual int streamIn ( char * stream, size_t len );
|
|
virtual void detachData ( void );
|
|
virtual int attachData ( char * stream, size_t len );
|
|
};
|
|
|
|
// *****************************************************************************
|
|
// * cdevPacketBinary::map2int ( void )
|
|
// * This method will convert the cdevPacketBinaryMap to a long integer.
|
|
// *****************************************************************************
|
|
inline unsigned cdevPacketBinary::map2int ( cdevPacketBinaryMap map, unsigned & value)
|
|
{
|
|
value = (map.value.version << 16);
|
|
value |= (map.value.pad & 0xFFFF);
|
|
|
|
return value;
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * cdevPacketBinary::int2map ( void )
|
|
// * This method will convert a long integer to a cdevPacketBinaryMap.
|
|
// *****************************************************************************
|
|
inline cdevPacketBinaryMap cdevPacketBinary::int2map ( cdevPacketBinaryMap &map, unsigned value)
|
|
{
|
|
map.rawData = 0;
|
|
map.value.version = (value >> 16);
|
|
map.value.pad = (value & 0xFFFF);
|
|
return map;
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevPacketBinary::getVersion :
|
|
// * This method is used to obtain the version number of the packet.
|
|
// *
|
|
// * Returns 0 on Success or -1 on Error
|
|
// *****************************************************************************
|
|
inline int cdevPacketBinary::getVersion ( short & version )
|
|
{
|
|
int result=-1;
|
|
XDR_Reader reader;
|
|
cdevPacketBinaryMap map;
|
|
|
|
version = -1;
|
|
|
|
if(binary!=NULL && binaryLen>0)
|
|
{
|
|
unsigned packetMap = 0;
|
|
reader.attachData(binary, binaryLen);
|
|
map.rawData = 0;
|
|
if((result = !reader.get(packetMap))==0)
|
|
{
|
|
int2map(map, packetMap);
|
|
version = map.value.version;
|
|
}
|
|
reader.detachData();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * cdevPacketBinary::getPad :
|
|
// * This method is used to obtain the 16 bit integer that follows the
|
|
// * packet version.
|
|
// *****************************************************************************
|
|
inline int cdevPacketBinary::getPad ( short & pad )
|
|
{
|
|
int result=-1;
|
|
XDR_Reader reader;
|
|
cdevPacketBinaryMap map;
|
|
|
|
pad = -1;
|
|
|
|
if(binary!=NULL && binaryLen>0)
|
|
{
|
|
unsigned packetMap = 0;
|
|
reader.attachData(binary, binaryLen);
|
|
map.rawData = 0;
|
|
if((result = !reader.get(packetMap))==0)
|
|
{
|
|
int2map(map, packetMap);
|
|
pad = map.value.pad;
|
|
}
|
|
reader.detachData();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevPacketBinary::getClientID :
|
|
// * This method is used to obtain the 16 bit integer that contains the
|
|
// * client identifier.
|
|
// *****************************************************************************
|
|
inline int cdevPacketBinary::getClientID ( short & clientID )
|
|
{
|
|
int result = -1;
|
|
XDR_Reader reader;
|
|
|
|
clientID = -1;
|
|
|
|
if(binary!=NULL && binaryLen>0)
|
|
{
|
|
reader.attachData(binary, binaryLen);
|
|
if((result = !xdr_setpos(reader.xdr(), XDR_Sizeof((unsigned)1)))==0)
|
|
{
|
|
result = !reader.get(clientID);
|
|
}
|
|
reader.detachData();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevPacketBinary::getClientID :
|
|
// * This method is used to insert the 16 bit integer that contains the
|
|
// * client identifier.
|
|
// *****************************************************************************
|
|
inline int cdevPacketBinary::setClientID ( short clientID )
|
|
{
|
|
int result = -1;
|
|
XDR_Writer writer;
|
|
|
|
if(binary!=NULL && binaryLen>0)
|
|
{
|
|
writer.attachData(binary, binaryLen);
|
|
if((result = !xdr_setpos(writer.xdr(), XDR_Sizeof((unsigned)1)))==0)
|
|
{
|
|
result = !writer.put(clientID);
|
|
}
|
|
writer.detachData();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevPacketBinary::streamIn :
|
|
// * The streamIn function will read a memory buffer provided by the caller
|
|
// * and then populate the class with these values. This stream remains the
|
|
// * property of the caller and he is responsible for deleting it.
|
|
// *
|
|
// * Returns 0 on Success
|
|
// *****************************************************************************
|
|
inline int cdevPacketBinary::streamIn ( char * stream, size_t len )
|
|
{
|
|
if(binary!=NULL)
|
|
{
|
|
delete binary;
|
|
binary = NULL;
|
|
}
|
|
binaryLen = 0;
|
|
|
|
if(len>0 && stream!=NULL)
|
|
{
|
|
binary = new char[len];
|
|
binaryLen = len;
|
|
memcpy(binary, stream, binaryLen);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * cdevPacketBinary::streamOut :
|
|
// * The streamOut and streamIn functions are the bread and butter of the
|
|
// * cdevPacketBinary classes. They allow the class to convert itself into a
|
|
// * binary stream for transmission and then be reconstructed into a class
|
|
// * when they are received on the other side.
|
|
// *
|
|
// * The streamOut function will allocate a memory buffer to the stream
|
|
// * variable that is sufficient to store the binary representation of
|
|
// * the data that is to be transmitted. This stream remains the
|
|
// * property of the cdevPacketBinary class and should not be deleted by the
|
|
// * caller.
|
|
// *
|
|
// * Returns 0 on Success
|
|
// *****************************************************************************
|
|
inline int cdevPacketBinary::streamOut ( char ** stream, size_t * len )
|
|
{
|
|
*stream = binary;
|
|
*len = binaryLen;
|
|
return 0;
|
|
}
|
|
|
|
// *********************************************************************
|
|
// * cdevPacketBinary::detachData :
|
|
// * This method allows the caller to obtain a copy of the binary
|
|
// * image that is stored in the cdevPacketBinary object (using
|
|
// * streamOut), and then force the cdevPacket object to detach it
|
|
// * (preventing it from being deleted when the object is destroyed.)
|
|
// *
|
|
// * Returns nothing.
|
|
// *********************************************************************
|
|
inline void cdevPacketBinary::detachData ( void )
|
|
{
|
|
binary = NULL;
|
|
binaryLen = 0;
|
|
}
|
|
|
|
// *********************************************************************
|
|
// * cdevPacketBinary::attachData :
|
|
// * This method allows the caller to assign a preallocated binary
|
|
// * buffer to this object. This prevents the cdevPacketBinary class
|
|
// * from having to allocate the data.
|
|
// *
|
|
// * Returns 0 on Success
|
|
// *********************************************************************
|
|
inline int cdevPacketBinary::attachData ( char * stream, size_t len )
|
|
{
|
|
if(binary!=NULL)
|
|
{
|
|
delete binary;
|
|
binary = NULL;
|
|
}
|
|
binaryLen = 0;
|
|
|
|
if(stream!=NULL && len>0)
|
|
{
|
|
binary = stream;
|
|
binaryLen = len;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * cdevPacketBinary::cdevPacketBinary :
|
|
// * This is the default constructor for the class.
|
|
// *****************************************************************************
|
|
inline cdevPacketBinary::cdevPacketBinary ( void )
|
|
: binary(NULL), binaryLen(0)
|
|
{}
|
|
|
|
// *****************************************************************************
|
|
// * cdevPacketBinary::cdevPacketBinary :
|
|
// * This is the copy constructor for the class.
|
|
// *****************************************************************************
|
|
inline cdevPacketBinary::cdevPacketBinary ( cdevPacketBinary & packet )
|
|
: binary(NULL), binaryLen(0)
|
|
{
|
|
streamIn(packet.binary, packet.binaryLen);
|
|
}
|
|
|
|
// *****************************************************************************
|
|
// * cdevPacketBinary::~cdevPacketBinary :
|
|
// * This is the destructor for the object.
|
|
// *****************************************************************************
|
|
inline cdevPacketBinary::~cdevPacketBinary ( void )
|
|
{
|
|
if(binary!=NULL)
|
|
{
|
|
delete binary;
|
|
binary = NULL;
|
|
}
|
|
binaryLen = 0;
|
|
}
|
|
|
|
#endif /* _CDEV_PACKET_H_ */
|