Files
cdev-1.7.2n/extensions/cdevGenericServer/cdevPacket/cdevMessageBinary.cc
2022-12-13 12:44:04 +01:00

1511 lines
58 KiB
C++
Executable File

#include <cdevMessageBinary.h>
const unsigned BIT01 = 1;
const unsigned BIT02 = 2;
const unsigned BIT03 = 4;
const unsigned BIT04 = 8;
const unsigned BIT05 = 16;
const unsigned BIT06 = 32;
const unsigned BIT07 = 64;
const unsigned BIT08 = 128;
const unsigned BIT09 = 256;
const unsigned BIT10 = 512;
const unsigned BIT11 = 1024;
const unsigned BIT12 = 2048;
const unsigned BIT13 = 4096;
const unsigned BIT14 = 8192;
const unsigned BIT15 = 16384;
const unsigned BIT16 = 32768;
// *****************************************************************************
// * cdevMessageBinary::map2int ( void )
// * This method will convert the cdevMessageBinaryMap to a long integer.
// *****************************************************************************
unsigned cdevMessageBinary::map2int ( cdevMessageBinaryMap mapdata, unsigned & value)
{
value = (mapdata.value.version << 16);
if(mapdata.value.clientIDSet!=0) value |= BIT16;
if(mapdata.value.transIndexSet!=0) value |= BIT15;
if(mapdata.value.cancelTransIndexSet!=0) value |= BIT14;
if(mapdata.value.localDataIndexSet!=0) value |= BIT13;
if(mapdata.value.foreignDataIndexSet!=0) value |= BIT12;
if(mapdata.value.operationCodeSet!=0) value |= BIT11;
if(mapdata.value.completionCodeSet!=0) value |= BIT10;
if(mapdata.value.deviceListSet!=0) value |= BIT09;
if(mapdata.value.messageSet!=0) value |= BIT08;
if(mapdata.value.dataSet!=0) value |= BIT07;
if(mapdata.value.contextSet!=0) value |= BIT06;
if(mapdata.value.tagMapSet!=0) value |= BIT05;
return value;
}
// *****************************************************************************
// * cdevMessageBinary::int2map ( void )
// * This method will convert a long integer to a cdevMessageBinaryMap.
// *****************************************************************************
cdevMessageBinaryMap cdevMessageBinary::int2map ( cdevMessageBinaryMap &mapdata, unsigned value)
{
mapdata.rawData = 0;
mapdata.value.version = (value >> 16);
mapdata.value.clientIDSet = (value & BIT16)?1:0;
mapdata.value.transIndexSet = (value & BIT15)?1:0;
mapdata.value.cancelTransIndexSet = (value & BIT14)?1:0;
mapdata.value.localDataIndexSet = (value & BIT13)?1:0;
mapdata.value.foreignDataIndexSet = (value & BIT12)?1:0;
mapdata.value.operationCodeSet = (value & BIT11)?1:0;
mapdata.value.completionCodeSet = (value & BIT10)?1:0;
mapdata.value.deviceListSet = (value & BIT09)?1:0;
mapdata.value.messageSet = (value & BIT08)?1:0;
mapdata.value.dataSet = (value & BIT07)?1:0;
mapdata.value.contextSet = (value & BIT06)?1:0;
mapdata.value.tagMapSet = (value & BIT05)?1:0;
return mapdata;
}
// *****************************************************************************
// * cdevMessageBinary::cdevMessageBinary :
// * Copy constructaor for the class. Sets all of the variables to the
// * values stored in the referenced objects.
// *****************************************************************************
cdevMessageBinary::cdevMessageBinary ( cdevMessageBinary & packet )
: cdevPacketBinary()
{
streamIn(packet.binary, packet.binaryLen);
}
// *****************************************************************************
// * cdevMessageBinary::cdevMessageBinary :
// * This is the default and parameterized constructor. Allows the caller to
// * directly specify each of the components.
// *****************************************************************************
cdevMessageBinary::cdevMessageBinary ( short clientID,
unsigned transIndex,
unsigned cancelTransIndex,
unsigned localDataIndex,
unsigned foreignDataIndex,
unsigned operationCode,
int completionCode,
unsigned deviceCount,
char ** deviceList,
char * message,
cdevData * data,
cdevData * context,
cdevData * tagMap)
: cdevPacketBinary()
{
set(clientID, transIndex, cancelTransIndex, localDataIndex,
foreignDataIndex, operationCode, completionCode, deviceCount,
deviceList, message, data, context, tagMap);
}
// *****************************************************************************
// * cdevMessageBinary::~cdevMessageBinary :
// * This is the destructor for the class.
// *****************************************************************************
cdevMessageBinary::~cdevMessageBinary ( void )
{
// *********************************************************************
// * Execute a detach on the embedded data to ensure that it is not
// * deleted locally.
// *********************************************************************
reader.detachData();
}
// *****************************************************************************
// * cdevMessageBinary::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.
// *****************************************************************************
int cdevMessageBinary::streamIn ( char *stream, size_t len )
{
int result = -1;
unsigned packetMap = 0;
// *********************************************************************
// * Delete the binary data buffer and set its length to 0.
// *********************************************************************
if(binary!=NULL)
{
delete binary;
binary = NULL;
}
binaryLen = 0;
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(stream, len);
// *********************************************************************
// * Clear the packet map prior to reading data from the stream.
// *********************************************************************
map.rawData = 0;
// *********************************************************************
// * Read the packet map from the stream. This object contains a bit
// * field that identifies the version of the packet and tells what
// * other components are embedded in the binary stream.
// *********************************************************************
result = !reader.get(packetMap);
int2map (map, packetMap);
// *********************************************************************
// * Before processing anything else, the method must ensure that this
// * packet is of the correct version. Version 1 for this object.
// *
// * Note that reading each field is contingent on the prior fields
// * being read correctly.
// *********************************************************************
if(!result && map.value.version == CDEV_PACKET_VERSION)
{
binaryLen = len;
binary = new char[binaryLen];
memcpy(binary, stream, binaryLen);
}
else result = -1;
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *********************************************************************
// * cdevMessageBinary::attachData :
// * This method allows the caller to assign a preallocated binary
// * buffer to this object. This prevents the cdevMessageBinary class
// * from having to allocate the data.
// *********************************************************************
int cdevMessageBinary::attachData ( char * stream, size_t len )
{
int result = -1;
unsigned packetMap = 0;
// *********************************************************************
// * Delete the binary data buffer and set its length to 0.
// *********************************************************************
if(binary!=NULL)
{
delete binary;
binary = NULL;
}
binaryLen = 0;
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(stream, len);
// *********************************************************************
// * Clear the packet map prior to reading data from the stream.
// *********************************************************************
map.rawData = 0;
// *********************************************************************
// * Read the packet map from the stream. This object contains a bit
// * field that identifies the version of the packet and tells what
// * other components are embedded in the binary stream.
// *********************************************************************
result = !reader.get(packetMap);
int2map (map, packetMap);
// *********************************************************************
// * Before processing anything else, the method must ensure that this
// * packet is of the correct version. Version 1 for this object.
// *
// * Note that reading each field is contingent on the prior fields
// * being read correctly.
// *********************************************************************
if(!result && map.value.version == CDEV_PACKET_VERSION)
{
binaryLen = len;
binary = stream;
}
else result = -1;
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *****************************************************************************
// * cdevMessageBinary::asciiDump :
// * This method performs a diagnostic dump of the text representation of the
// * packets contents.
// *****************************************************************************
void cdevMessageBinary::asciiDump ( FILE * fp )
{
short clientID;
unsigned transIndex, cancelTransIndex, localDataIndex;
unsigned foreignDataIndex, operationCode, deviceCount;
int completionCode;
char ** deviceList;
char * message;
cdevData temp;
getClientID(clientID);
getTransIndex(transIndex);
getCancelTransIndex(cancelTransIndex);
getLocalDataIndex(localDataIndex);
getForeignDataIndex(foreignDataIndex);
getOperationCode (operationCode);
getCompletionCode (completionCode);
getDeviceList(deviceList, deviceCount);
getMessage(message);
fprintf(fp, "----------------------------------------------------------\n");
fprintf(fp, " Diagnostic Dump of CDEV Packet\n");
fprintf(fp, "----------------------------------------------------------\n\n");
fprintf(fp, "Packet Version : %i\n", CDEV_PACKET_VERSION);
fprintf(fp, "Binary Stream Size : %i\n", binaryLen);
fprintf(fp, "Client Identifier : %s\n", clientID==-1?"(not specified)":ltoa(clientID));
fprintf(fp, "Transaction Index : %s\n", transIndex==0?"(not specified)":ultoa(transIndex));
fprintf(fp, "Cancel Transaction : %s\n", cancelTransIndex==0?"(not specified)":ultoa(cancelTransIndex));
fprintf(fp, "Local Data Index : %s\n", localDataIndex==0?"(not specified)":ultoa(localDataIndex));
fprintf(fp, "Foreign Data Index : %s\n", foreignDataIndex==0?"(not specified)":ultoa(foreignDataIndex));
fprintf(fp, "Operation Code : %s\n", operationCode==0?"(not specified)":ultoa(operationCode));
fprintf(fp, "Completion Code : %i\n", completionCode);
fprintf(fp, "Number of Devices : %s\n", deviceCount==0?"(not specified)":ultoa(deviceCount));
fprintf(fp, "List of Devices : ");
if(deviceCount==0) fprintf(fp, "(not specified)\n");
else fprintf(fp, "%s\n", deviceList[0]);
for(int i=1; i<deviceCount; i++)
{
fprintf(fp, " %s\n", deviceList[i]);
}
fprintf(fp, "Message String : %s\n", message==NULL?"(not specified)":message);
// *********************************************************************
// * The deviceList and message string must be deleted.
// *********************************************************************
if(deviceList!=NULL)
{
for(i=0; i<deviceCount; i++) delete deviceList[i];
delete deviceList;
}
if(message != NULL) delete message;
int empty;
fprintf(fp, "Data Object : %s", (empty=getData(temp))==0?"\n":"(not specified)\n");
fflush(fp);
if(!empty) temp.asciiDump(fp);
fprintf(fp, "Context Object : %s", (empty=getContext(temp))==0?"\n":"(not specified)\n");
fflush(fp);
if(!empty) temp.asciiDump(fp);
fprintf(fp, "Tag Map : %s", (empty=getTagMap(temp))==0?"\n":"(not specified)\n");
if(!empty)
{
size_t tagNumCnt = 0;
int * tagNums = NULL;
size_t tagNameCnt = 0;
if(temp.getElems(1, &tagNumCnt)==CDEV_SUCCESS &&
temp.getElems(2, &tagNameCnt)==CDEV_SUCCESS &&
temp.getType (2)==CDEV_STRING &&
tagNumCnt==tagNameCnt)
{
char ** tagNames = NULL;
char * singleName = NULL;
tagNums = new int[tagNumCnt];
temp.get(1, tagNums);
if(tagNameCnt==1)
{
tagNames = &singleName;
temp.find(2, (void *&)singleName);
}
else temp.find(2, (void *&)tagNames);
for(int i=0; i<tagNumCnt; i++)
{
fprintf(fp, "\t%-26.26s= %i\n", tagNames[i], tagNums[i]);
}
delete tagNums;
}
}
fprintf(fp, "----------------------------------------------------------\n");
fprintf(fp, " End of Diagnostic Dump of CDEV Packet\n");
fprintf(fp, "----------------------------------------------------------\n\n");
fflush(fp);
}
// *****************************************************************************
// * cdevMessageBinary::setBinaryPosition :
// * This method will set the position of the binary stream within an
// * XDR_Reader to the specified data object.
// * This method returns 0 on success, or -1 if the data object could not be
// * selected.
// *****************************************************************************
int cdevMessageBinary::setBinaryPosition (XDR_Reader & Reader, POSITION_FLAG flag )
{
int slen;
int result = -1;
unsigned packetMap = 0;
// *********************************************************************
// * Set the position to the beginning of the data buffer.
// *********************************************************************
xdr_setpos(Reader.xdr(), 0);
// *********************************************************************
// * Clear the packet map prior to reading data from the stream.
// *********************************************************************
map.rawData = 0;
// *********************************************************************
// * Read the packet map from the stream. This object contains a bit
// * field that identifies the version of the packet and tells what
// * other components are embedded in the binary stream.
// *********************************************************************
result = !Reader.get(packetMap);
int2map ( map, packetMap );
// *********************************************************************
// * Before processing anything else, the method must ensure that this
// * packet is of the correct version. Version 1 for this object.
// *
// * Note that reading each field is contingent on the prior fields
// * being read correctly.
// *********************************************************************
if(!result && map.value.version==CDEV_PACKET_VERSION)
{
// *************************************************************
// * If the selected element is beyond the clientID, then
// * advance the buffer to the next item.
// *************************************************************
if(flag > GOTO_CLIENTID)
{
if(map.value.clientIDSet!=0)
result=!xdr_setpos(
Reader.xdr(),
xdr_getpos(Reader.xdr())+XDR_Sizeof((short)1));
}
// *************************************************************
// * Otherwise... set the result to indicate the existence (or
// * non-existence) of the clientID.
// *************************************************************
else if(flag==GOTO_CLIENTID && !map.value.clientIDSet) result=-1;
// *************************************************************
// * If the selected element is beyond the transIndex, then
// * advance the buffer to the next item.
// *************************************************************
if(flag > GOTO_TRANSINDEX)
{
if(!result && map.value.transIndexSet!=0)
result=!xdr_setpos(
Reader.xdr(),
xdr_getpos(Reader.xdr())+XDR_Sizeof((unsigned)1));
}
// *************************************************************
// * Otherwise... set the result to indicate the existence (or
// * non-existence) of the transIndex.
// *************************************************************
else if(flag==GOTO_TRANSINDEX && !map.value.transIndexSet) result=-1;
// *************************************************************
// * If the selected element is beyond the cancelTransIndex,
// * then advance the buffer to the next item.
// *************************************************************
if(flag > GOTO_CANCELTRANSINDEX)
{
if(!result && map.value.cancelTransIndexSet!=0)
result=!xdr_setpos(
Reader.xdr(),
xdr_getpos(Reader.xdr())+XDR_Sizeof((unsigned)1));
}
// *************************************************************
// * Otherwise... set the result to indicate the existence (or
// * non-existence) of the cancelTransIndex.
// *************************************************************
else if(flag==GOTO_CANCELTRANSINDEX && !map.value.cancelTransIndexSet) result=-1;
// *************************************************************
// * If the selected element is beyond the localDataIndex, then
// * advance the buffer to the next item.
// *************************************************************
if(flag > GOTO_LOCALDATAINDEX)
{
if(!result && map.value.localDataIndexSet!=0)
result=!xdr_setpos(
Reader.xdr(),
xdr_getpos(Reader.xdr())+XDR_Sizeof((unsigned)1));
}
// *************************************************************
// * Otherwise... set the result to indicate the existence (or
// * non-existence) of the localDataIndex.
// *************************************************************
else if(flag==GOTO_LOCALDATAINDEX && !map.value.localDataIndexSet) result=-1;
// *************************************************************
// * If the selected element is beyond the foreignDataIndex, then
// * advance the buffer to the next item.
// *************************************************************
if(flag > GOTO_FOREIGNDATAINDEX)
{
if(!result && map.value.foreignDataIndexSet!=0)
result=!xdr_setpos(
Reader.xdr(),
xdr_getpos(Reader.xdr())+XDR_Sizeof((unsigned)1));
}
// *************************************************************
// * Otherwise... set the result to indicate the existence (or
// * non-existence) of the foreignDataIndex.
// *************************************************************
else if(flag==GOTO_FOREIGNDATAINDEX && !map.value.foreignDataIndexSet) result=-1;
// *************************************************************
// * If the selected element is beyond the operationCode,
// * then advance the buffer to the next item.
// *************************************************************
if(flag > GOTO_OPERATIONCODE)
{
if(!result && map.value.operationCodeSet!=0)
result=!xdr_setpos(
Reader.xdr(),
xdr_getpos(Reader.xdr())+XDR_Sizeof((unsigned)1));
}
// *************************************************************
// * Otherwise... set the result to indicate the existence (or
// * non-existence) of the operationCode.
// *************************************************************
else if(flag==GOTO_OPERATIONCODE && !map.value.operationCodeSet) result=-1;
// *************************************************************
// * If the selected element is beyond the operationCode,
// * then advance the buffer to the next item.
// *************************************************************
if(flag > GOTO_COMPLETIONCODE)
{
if(!result && map.value.completionCodeSet!=0)
result=!xdr_setpos(
Reader.xdr(),
xdr_getpos(Reader.xdr())+XDR_Sizeof((int)1));
}
// *************************************************************
// * Otherwise... set the result to indicate the existence (or
// * non-existence) of the operationCode.
// *************************************************************
else if(flag==GOTO_COMPLETIONCODE && !map.value.completionCodeSet) result=-1;
// *************************************************************
// * If the selected element is beyond the deviceList, then
// * advance the buffer to the next item.
// *************************************************************
if(flag > GOTO_DEVICELIST)
{
if(!result && map.value.deviceListSet!=0)
{
int deviceCount;
if((result = !Reader.get(deviceCount))==0)
{
// *************************************
// * Step over each string in the array.
// *************************************
for(int i=0; i<deviceCount && !result; i++)
{
slen = Reader.get_string_len();
slen = XDR_Sizeof((char *)NULL, slen);
result = !xdr_setpos(
Reader.xdr(),
xdr_getpos(Reader.xdr())+slen);
}
}
}
}
// *************************************************************
// * Otherwise... set the result to indicate the existence (or
// * non-existence) of the deviceList.
// *************************************************************
else if(flag==GOTO_DEVICELIST && !map.value.deviceListSet) result=-1;
// *************************************************************
// * If the selected element is beyond the message, then
// * advance the buffer to the next item.
// *************************************************************
if(flag > GOTO_MESSAGE)
{
if(!result && map.value.messageSet!=0)
{
slen = Reader.get_string_len();
slen = XDR_Sizeof((char *)NULL, slen);
result = !xdr_setpos(
Reader.xdr(),
xdr_getpos(Reader.xdr())+slen);
}
}
// *************************************************************
// * Otherwise... set the result to indicate the existence (or
// * non-existence) of the message.
// *************************************************************
else if(flag==GOTO_MESSAGE && !map.value.messageSet) result=-1;
// *************************************************************
// * If the selected element is beyond the data, then
// * advance the buffer to the next item.
// *************************************************************
if(flag > GOTO_DATA)
{
if(!result && map.value.dataSet!=0)
{
slen = Reader.get_string_len();
slen = XDR_Sizeof((void *)NULL, slen);
result = !xdr_setpos(
Reader.xdr(),
xdr_getpos(Reader.xdr())+slen);
}
}
// *************************************************************
// * Otherwise... set the result to indicate the existence (or
// * non-existence) of the data.
// *************************************************************
else if(flag==GOTO_DATA && !map.value.dataSet) result=-1;
// *************************************************************
// * If the selected element is beyond the context, then it
// * contains an invalid value and should be cleared.
// *************************************************************
if(flag > GOTO_CONTEXT)
{
if(!result && map.value.contextSet!=0)
{
slen = Reader.get_string_len();
slen = XDR_Sizeof((void *)NULL, slen);
result = !xdr_setpos(
Reader.xdr(),
xdr_getpos(Reader.xdr())+slen);
}
}
// *************************************************************
// * Otherwise... set the result to indicate the existence (or
// * non-existence) of the context.
// *************************************************************
else if(flag==GOTO_CONTEXT && !map.value.contextSet) result=-1;
// *************************************************************
// * If the selected element is beyond the context, then it
// * contains an invalid value and should be cleared.
// *************************************************************
if(flag > GOTO_TAGMAP) result = -1;
// *************************************************************
// * Otherwise... set the result to indicate the existence (or
// * non-existence) of the context.
// *************************************************************
else if(flag==GOTO_TAGMAP && !map.value.tagMapSet) result=-1;
}
return result;
}
// *****************************************************************************
// * cdevMessageBinary::set :
// * This method will convert the user provided data into the binary stream.
// *****************************************************************************
void cdevMessageBinary::set ( short clientID,
unsigned transIndex,
unsigned cancelTransIndex,
unsigned localDataIndex,
unsigned foreignDataIndex,
unsigned operationCode,
int completionCode,
unsigned deviceCount,
char ** deviceList,
char * message,
cdevData * data,
cdevData * context,
cdevData * tagMap)
{
unsigned packetMap = 0;
size_t dataLen = 0, dataCnt = 0;
size_t contextLen = 0, contextCnt = 0;
size_t tagMapLen = 0, tagMapCnt = 0;
if(binary!=NULL)
{
delete binary;
binary = NULL;
}
binaryLen = 0;
// *********************************************************************
// * Construct the packet map to indicate which components will be
// * transmitted.
// *********************************************************************
map.rawData = 0;
map.value.version = CDEV_PACKET_VERSION;
// *********************************************************************
// * Because the cdevPacketBinary relies on the ordered existance of the
// * client identifier... this entry will automatically be tagged as
// * present, even though it may contain a default value...
// *********************************************************************
map.value.clientIDSet = 1;
// *********************************************************************
// * All other components will only be marked as present if they have
// * actually been specified.
// *********************************************************************
if(transIndex > 0) map.value.transIndexSet = 1;
if(cancelTransIndex > 0) map.value.cancelTransIndexSet = 1;
if(localDataIndex > 0) map.value.localDataIndexSet = 1;
if(foreignDataIndex > 0) map.value.foreignDataIndexSet = 1;
if(operationCode > 0) map.value.operationCodeSet = 1;
if(completionCode != 0) map.value.completionCodeSet = 1;
if(deviceCount>0 && deviceList!=NULL) map.value.deviceListSet = 1;
if(message!=NULL) map.value.messageSet = 1;
if(data!=NULL) data->xdrSize (&dataLen, &dataCnt);
if(context!=NULL) context->xdrSize(&contextLen, &contextCnt);
if(tagMap!=NULL) tagMap->xdrSize (&tagMapLen, &tagMapCnt);
if(dataCnt > 0) map.value.dataSet = 1;
if(contextCnt > 0) map.value.contextSet = 1;
if(tagMapCnt > 0) map.value.tagMapSet = 1;
// *********************************************************************
// * Calculate the total size of the packet.
// *********************************************************************
binaryLen = XDR_Sizeof( map2int(map, packetMap) );
if(map.value.clientIDSet!=0) binaryLen += XDR_Sizeof(clientID);
if(map.value.transIndexSet!=0) binaryLen += XDR_Sizeof(transIndex);
if(map.value.cancelTransIndexSet!=0) binaryLen += XDR_Sizeof(cancelTransIndex);
if(map.value.localDataIndexSet!=0) binaryLen += XDR_Sizeof(localDataIndex);
if(map.value.foreignDataIndexSet!=0) binaryLen += XDR_Sizeof(foreignDataIndex);
if(map.value.operationCodeSet!=0) binaryLen += XDR_Sizeof(operationCode);
if(map.value.completionCodeSet!=0) binaryLen += XDR_Sizeof(completionCode);
if(map.value.deviceListSet!=0)
{
binaryLen += XDR_Sizeof(deviceCount);
for(int i=0; i<deviceCount; i++) binaryLen += XDR_Sizeof(deviceList[i]);
}
if(map.value.messageSet!=0) binaryLen += XDR_Sizeof(message);
if(map.value.dataSet!=0)
{
binaryLen += XDR_Sizeof((void *)NULL, dataLen);
}
if(map.value.contextSet!=0)
{
binaryLen += XDR_Sizeof((void *)NULL, contextLen);
}
if(map.value.tagMapSet!=0)
{
binaryLen += XDR_Sizeof((void *)NULL, tagMapLen);
}
// *********************************************************************
// * Allocate the packet and then write the data items into it.
// *********************************************************************
XDR_Writer writer;
unsigned position = 0;
binary = new char[binaryLen];
writer.attachData(binary, binaryLen);
writer.put(packetMap);
if(map.value.clientIDSet!=0) writer.put(clientID);
if(map.value.transIndexSet!=0) writer.put(transIndex);
if(map.value.cancelTransIndexSet!=0) writer.put(cancelTransIndex);
if(map.value.localDataIndexSet!=0) writer.put(localDataIndex);
if(map.value.foreignDataIndexSet!=0) writer.put(foreignDataIndex);
if(map.value.operationCodeSet!=0) writer.put(operationCode);
if(map.value.completionCodeSet!=0) writer.put(completionCode);
if(map.value.deviceListSet!=0)
{
writer.put(deviceCount);
for(int i=0; i<deviceCount; i++) writer.put((char *)deviceList[i]);
}
if(map.value.messageSet!=0) writer.put((char *)message);
// *********************************************************************
// * This is an experimental insertion that allows me to place the data
// * into the xdr buffer directly without having to preallocate a buffer.
// *********************************************************************
char * tbuf;
int tpos;
if(map.value.dataSet!=0)
{
tpos = xdr_getpos(writer.xdr());
writer.put(dataLen);
tbuf = writer.buffer()+xdr_getpos(writer.xdr());
data->xdrExport(tbuf, dataLen, dataCnt);
xdr_setpos(writer.xdr(), tpos+XDR_Sizeof((void *)NULL, dataLen));
}
if(map.value.contextSet!=0)
{
tpos = xdr_getpos(writer.xdr());
writer.put(contextLen);
tbuf = writer.buffer()+xdr_getpos(writer.xdr());
context->xdrExport(tbuf, contextLen, contextCnt);
xdr_setpos(writer.xdr(), tpos+XDR_Sizeof((void *)NULL, contextLen));
}
if(map.value.tagMapSet!=0)
{
tpos = xdr_getpos(writer.xdr());
writer.put(tagMapLen);
tbuf = writer.buffer()+xdr_getpos(writer.xdr());
tagMap->xdrExport(tbuf, tagMapLen, tagMapCnt);
xdr_setpos(writer.xdr(), tpos+XDR_Sizeof((void *)NULL, tagMapLen));
}
writer.detachData();
}
// *****************************************************************************
// * cdevMessageBinary::getVersion :
// * This method is used to obtain the version number of the packet.
// *****************************************************************************
int cdevMessageBinary::getVersion ( short & version )
{
version = CDEV_PACKET_VERSION;
return 0;
}
// *****************************************************************************
// * cdevMessageBinary::getClientID :
// * This method is used to obtain the client identifier for the packet.
// * This method returns 0 on success, or -1 if the clientID was not
// * specified.
// *****************************************************************************
int cdevMessageBinary::getClientID ( short & clientID )
{
int result = -1;
clientID = -1;
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(binary, binaryLen);
// *********************************************************************
// * Reposition the binary structure to point to the correct location
// * and read the data item.
// *********************************************************************
if((result = setBinaryPosition(reader, GOTO_CLIENTID))==0)
{
if(map.value.clientIDSet!=0) result=!reader.get(clientID);
}
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *****************************************************************************
// * cdevMessageBinary::getTransIndex :
// * This method is used to obtain the transaction object index. This
// * object is used on the client side to obtain a pointer to the transaction
// * object.
// * This method returns 0 on success, or -1 if the transIndex could not
// * be read.
// *****************************************************************************
int cdevMessageBinary::getTransIndex ( unsigned & transIndex )
{
int result = -1;
transIndex = 0;
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(binary, binaryLen);
// *********************************************************************
// * Reposition the binary structure to point to the correct location
// * and read the data item.
// *********************************************************************
if((result = setBinaryPosition(reader, GOTO_TRANSINDEX))==0)
{
result = !reader.get(transIndex);
}
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *****************************************************************************
// * cdevMessageBinary::getCancelTransIndex :
// * This method is used to obtain the identifier of a transaction object
// * that is to be canceled.
// *
// * This method returns 0 on success, or -1 if the cancelCancelTransIndex could not
// * be read.
// *****************************************************************************
int cdevMessageBinary::getCancelTransIndex ( unsigned & cancelTransIndex )
{
int result = -1;
cancelTransIndex = 0;
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(binary, binaryLen);
// *********************************************************************
// * Reposition the binary structure to point to the correct location
// * and read the data item.
// *********************************************************************
if((result = setBinaryPosition(reader, GOTO_CANCELTRANSINDEX))==0)
{
result = !reader.get(cancelTransIndex);
}
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *****************************************************************************
// * cdevMessageBinary::getLocalDataIndex :
// * This method is used to obtain an index to any data that may be
// * maintained on the senders side of the connection.
// * This method returns 0 on success, or -1 if the localDataIndex could
// * not be read.
// *****************************************************************************
int cdevMessageBinary::getLocalDataIndex ( unsigned & localDataIndex )
{
int result = -1;
localDataIndex = 0;
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(binary, binaryLen);
// *********************************************************************
// * Reposition the binary structure to point to the correct location
// * and read the data item.
// *********************************************************************
if((result = setBinaryPosition(reader, GOTO_LOCALDATAINDEX))==0)
{
result = !reader.get(localDataIndex);
}
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *****************************************************************************
// * cdevMessageBinary::getForeignDataIndex :
// * This method is used to obtain an index to any data that may be
// * maintained on the senders side of the connection.
// * This method returns 0 on success, or -1 if the foreignDataIndex could
// * not be read.
// *****************************************************************************
int cdevMessageBinary::getForeignDataIndex ( unsigned & foreignDataIndex )
{
int result = -1;
foreignDataIndex = 0;
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(binary, binaryLen);
// *********************************************************************
// * Reposition the binary structure to point to the correct location
// * and read the data item.
// *********************************************************************
if((result = setBinaryPosition(reader, GOTO_FOREIGNDATAINDEX))==0)
{
result = !reader.get(foreignDataIndex);
}
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *****************************************************************************
// * cdevMessageBinary::getOperationCode :
// * This method is used to obtain the operation code. An operation code may
// * be used by the developer to define a particular message. This is faster
// * to manipulate than the supported string messages.
// *****************************************************************************
int cdevMessageBinary::getOperationCode ( unsigned & operationCode )
{
int result = -1;
operationCode = 0;
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(binary, binaryLen);
// *********************************************************************
// * Reposition the binary structure to point to the correct location
// * and read the data item.
// *********************************************************************
if((result = setBinaryPosition(reader, GOTO_OPERATIONCODE))==0)
{
result = !reader.get(operationCode);
}
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *****************************************************************************
// * cdevMessageBinary::getCompletionCode :
// * This method is used to obtain the completion code. The completion code
// * is returned by the server to indicate the result code from an operation.
// *****************************************************************************
int cdevMessageBinary::getCompletionCode ( int & completionCode )
{
int result = -1;
completionCode = 0;
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(binary, binaryLen);
// *********************************************************************
// * Reposition the binary structure to point to the correct location
// * and read the data item.
// *********************************************************************
if((result = setBinaryPosition(reader, GOTO_COMPLETIONCODE))==0)
{
result = !reader.get(completionCode);
}
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *****************************************************************************
// * cdevMessageBinary::getDeviceList :
// * This method is used to obtains an array of device names that are
// * associated with the request. It is the responsibility of the caller
// * to delete each element of the array, and the array itself when they
// * are no longer needed.
// * This method returns 0 on success, or -1 if the deviceList could
// * not be read.
// *****************************************************************************
int cdevMessageBinary::getDeviceList ( char ** & deviceList, unsigned & deviceCount)
{
int result = -1;
deviceList = NULL;
deviceCount = 0;
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(binary, binaryLen);
// *********************************************************************
// * Reposition the binary structure to point to the correct location
// * and read the data item.
// *********************************************************************
if((result = setBinaryPosition(reader, GOTO_DEVICELIST))==0)
{
if((result = !reader.get(deviceCount))==0)
{
// *********************************************
// * Allocate and initialize an array sufficient
// * to hold the contents of the stream.
// *********************************************
deviceList = new char * [deviceCount];
memset(deviceList, 0, sizeof(char *)*deviceCount);
// *********************************************
// * Read the individual strings into the array.
// * Note that the XDR_Reader will automatically
// * allocate data if the pointers are set to
// * NULL.
// *********************************************
for(int i=0; i<deviceCount && !result; i++)
result = !reader.get(&deviceList[i]);
}
// *****************************************************
// * In event that a failure occurred after the buffer
// * was allocated. Walk through the array and free
// * each data item... then free the array.
// *****************************************************
if(result!=0 && deviceList!=NULL)
{
for(int i=0; i<deviceCount; i++)
{
if(deviceList[i]!=NULL) delete deviceList[i];
}
delete deviceList;
}
}
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *****************************************************************************
// * cdevMessageBinary::getMessage :
// * This method is used to obtains an array of device names that are
// * associated with the request. It is the responsibility of the caller
// * to delete each element of the array, and the array itself when they
// * are no longer needed.
// * This method returns 0 on success, or -1 if the deviceList could
// * not be read.
// *****************************************************************************
int cdevMessageBinary::getMessage ( char * & message)
{
int result = -1;
message = NULL;
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(binary, binaryLen);
// *********************************************************************
// * Reposition the binary structure to point to the correct location
// * and read the data item.
// *********************************************************************
if((result = setBinaryPosition(reader, GOTO_MESSAGE))==0)
{
if((result = !reader.get(&message))!=0)
{
delete message;
}
}
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *****************************************************************************
// * cdevMessageBinary::getData :
// * This method is used to read the data cdevData object from the
// * binary stream.
// * This method returns 0 on success, or -1 if the data item could
// * not be read.
// *****************************************************************************
int cdevMessageBinary::getData ( cdevData & data)
{
int result = -1;
// *********************************************************************
// * Clear the contents of the context data object.
// *********************************************************************
data.remove();
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(binary, binaryLen);
// *********************************************************************
// * Reposition the binary structure to point to the correct location
// * and read the data item.
// *********************************************************************
if((result = setBinaryPosition(reader, GOTO_DATA))==0)
{
int tlen;
int tpos;
char *tbuf;
tpos = xdr_getpos(reader.xdr());
reader.get(tlen);
tbuf = reader.buffer()+xdr_getpos(reader.xdr());
if(tlen!=0 && tbuf!=NULL) data.xdrImport(tbuf, tlen);
else result = -1;
xdr_setpos(reader.xdr(), tpos+XDR_Sizeof((void *)NULL, tlen));
}
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *****************************************************************************
// * cdevMessageBinary::getContext :
// * This method is used to read the context cdevData object from the
// * binary stream.
// * This method returns 0 on success, or -1 if the context could
// * not be read.
// *****************************************************************************
int cdevMessageBinary::getContext ( cdevData & context)
{
int result = -1;
// *********************************************************************
// * Clear the contents of the context data object.
// *********************************************************************
context.remove();
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(binary, binaryLen);
// *********************************************************************
// * Reposition the binary structure to point to the correct location
// * and read the data item.
// *********************************************************************
if((result = setBinaryPosition(reader, GOTO_CONTEXT))==0)
{
int tlen;
int tpos;
char *tbuf;
tpos = xdr_getpos(reader.xdr());
reader.get(tlen);
tbuf = reader.buffer()+xdr_getpos(reader.xdr());
if(tlen!=0 && tbuf!=NULL) context.xdrImport(tbuf, tlen);
else result = -1;
xdr_setpos(reader.xdr(), tpos+XDR_Sizeof((void *)NULL, tlen));
}
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *****************************************************************************
// * cdevMessageBinary::getTagMap :
// * This method is used to read the tagMap cdevData object from the
// * binary stream.
// * This method returns 0 on success, or -1 if the tagMap could not be read.
// *****************************************************************************
int cdevMessageBinary::getTagMap ( cdevData & tagMap)
{
int result = -1;
// *********************************************************************
// * Clear the contents of the tagMap data object.
// *********************************************************************
tagMap.remove();
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(binary, binaryLen);
// *********************************************************************
// * Reposition the binary structure to point to the correct location
// * and read the data item.
// *********************************************************************
if((result = setBinaryPosition(reader, GOTO_TAGMAP))==0)
{
int tlen;
int tpos;
char *tbuf;
tpos = xdr_getpos(reader.xdr());
reader.get(tlen);
tbuf = reader.buffer()+xdr_getpos(reader.xdr());
if(tlen!=0 && tbuf!=NULL) tagMap.xdrImport(tbuf, tlen);
else result = -1;
xdr_setpos(reader.xdr(), tpos+XDR_Sizeof((void *)NULL, tlen));
}
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}
// *****************************************************************************
// * cdevMessageBinary::get :
// * This method is used to read the complete contents of the packet.
// * This method returns 0 on success, or -1 if the deviceList could
// * not be read.
// *
// * Note that all data items allocated by this call become the property of
// * the caller and must be deleted. Specifically, the deviceList and
// * message parameters must be deleted.
// *****************************************************************************
int cdevMessageBinary::get ( short & clientID,
unsigned & transIndex,
unsigned & cancelTransIndex,
unsigned & localDataIndex,
unsigned & foreignDataIndex,
unsigned & operationCode,
int & completionCode,
unsigned & deviceCount,
char ** & deviceList,
char * & message,
cdevData & data,
cdevData & context,
cdevData & tagMap)
{
int result = -1;
unsigned packetMap = 0;
// *********************************************************************
// * Set all data to a default value.
// *********************************************************************
clientID = -1;
transIndex = 0;
cancelTransIndex = 0;
localDataIndex = 0;
foreignDataIndex = 0;
operationCode = 0;
completionCode = 0;
deviceCount = 0;
deviceList = NULL;
message = NULL;
data.remove();
context.remove();
tagMap.remove();
// *********************************************************************
// * Attach the data to the XDR_Reader class so that its components
// * can be extracted.
// *********************************************************************
reader.attachData(binary, binaryLen);
// *********************************************************************
// * Set the position to the beginning of the data buffer.
// *********************************************************************
xdr_setpos(reader.xdr(), 0);
// *********************************************************************
// * Clear the packet map prior to reading data from the stream.
// *********************************************************************
map.rawData = 0;
// *********************************************************************
// * Read the packet map from the stream. This object contains a bit
// * field that identifies the version of the packet and tells what
// * other components are embedded in the binary stream.
// *********************************************************************
if((result = !reader.get(packetMap))==0)
{
int2map(map, packetMap);
}
// *********************************************************************
// * Before processing anything else, the method must ensure that this
// * packet is of the correct version. Version 1 for this object.
// *
// * Note that reading each field is contingent on the prior fields
// * being read correctly.
// *********************************************************************
if(!result && map.value.version!=CDEV_PACKET_VERSION) result=-1;
if(!result && map.value.clientIDSet!=0) result=!reader.get(clientID);
if(!result && map.value.transIndexSet!=0) result = !reader.get(transIndex);
if(!result && map.value.cancelTransIndexSet!=0) result = !reader.get(cancelTransIndex);
if(!result && map.value.localDataIndexSet!=0) result = !reader.get(localDataIndex);
if(!result && map.value.foreignDataIndexSet!=0) result = !reader.get(foreignDataIndex);
if(!result && map.value.operationCodeSet!=0) result = !reader.get(operationCode);
if(!result && map.value.completionCodeSet!=0) result = !reader.get(completionCode);
if(!result && map.value.deviceListSet!=0)
{
if((result = !reader.get(deviceCount))==0)
{
// *********************************************
// * Allocate and initialize an array sufficient
// * to hold the contents of the stream.
// *********************************************
deviceList = new char * [deviceCount];
memset(deviceList, 0, sizeof(char *)*deviceCount);
// *********************************************
// * Read the individual strings into the array.
// * Note that the XDR_Reader will automatically
// * allocate data if the pointers are set to
// * NULL.
// *********************************************
for(int i=0; i<deviceCount && !result; i++)
result = !reader.get(&deviceList[i]);
}
}
if(!result && map.value.messageSet!=0) result = !reader.get(&message);
// *********************************************************************
// * This mechanism will bypass the standard XDR extractor and allow
// * the caller to directly read the data from the stream without
// * performing an additional memory allocation.
// *********************************************************************
int tlen;
int tpos;
char *tbuf;
if(!result && map.value.dataSet!=0)
{
tpos = xdr_getpos(reader.xdr());
reader.get(tlen);
tbuf = reader.buffer()+xdr_getpos(reader.xdr());
if(tlen!=0 && tbuf!=NULL) data.xdrImport(tbuf, tlen);
else result = -1;
xdr_setpos(reader.xdr(), tpos+XDR_Sizeof((void *)NULL, tlen));
}
if(!result && map.value.contextSet)
{
tpos = xdr_getpos(reader.xdr());
reader.get(tlen);
tbuf = reader.buffer()+xdr_getpos(reader.xdr());
if(tlen!=0 && tbuf!=NULL) context.xdrImport(tbuf, tlen);
else result = -1;
xdr_setpos(reader.xdr(), tpos+XDR_Sizeof((void *)NULL, tlen));
}
if(!result && map.value.tagMapSet)
{
tpos = xdr_getpos(reader.xdr());
reader.get(tlen);
tbuf = reader.buffer()+xdr_getpos(reader.xdr());
if(tlen!=0 && tbuf!=NULL) tagMap.xdrImport(tbuf, tlen);
else result = -1;
xdr_setpos(reader.xdr(), tpos+XDR_Sizeof((void *)NULL, tlen));
}
// *****************************************************
// * In event that a failure occurred after the buffers
// * was allocated. Walk through the array and free
// * each data item... then free the array.
// *****************************************************
if(result!=0)
{
if(deviceList!=NULL)
{
for(int i=0; i<deviceCount; i++)
{
if(deviceList[i]!=NULL) delete deviceList[i];
}
delete deviceList;
deviceList = NULL;
}
if(message!=NULL)
{
delete message;
message = NULL;
}
clientID = -1;
transIndex = 0;
localDataIndex = 0;
foreignDataIndex = 0;
operationCode = 0;
completionCode = 0;
deviceCount = 0;
data.remove();
context.remove();
tagMap.remove();
}
// *********************************************************************
// * Detach the binary buffer from the XDR_Reader to prevent it from
// * being deleted when the XDR_Reader class is destroyed.
// *********************************************************************
reader.detachData();
return result;
}