Files
cdev-1.7.2n/extensions/cdevGenericServer/include/cdevPacketBinary.h
2022-12-13 12:44:04 +01:00

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_ */