cdev-1.7.2n

This commit is contained in:
2022-12-13 12:44:04 +01:00
commit b3b88fc333
1357 changed files with 338883 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
ARCH = OS
SHOBJ = YES
include ../include/makeinclude/Makefile.$(ARCH)
APPNAME = "Packet/Message Source"
CXXINCLUDES = -I./
LIBS = $(CDEVLIBS) $(OSLIBS)
TARGETS = $(BASEBIN)/cdevPacketTest $(BASEBIN)/sparsePacketTest
targets: $(TARGETS)
$(BASEBIN)/cdevPacketTest: $(OBJDIR)/test.o $(OBJDIR)/cdevPacket.o $(OBJDIR)/cdevMessageBinary.o $(OBJDIR)/cdevMessage.o
$(LINK.cc) $^ -o $@ $(LIBS)
$(BASEBIN)/sparsePacketTest: $(OBJDIR)/sparsePacketTest.o $(OBJDIR)/cdevPacket.o $(OBJDIR)/cdevMessageBinary.o $(OBJDIR)/cdevMessage.o
$(LINK.cc) $^ -o $@ $(LIBS)
@@ -0,0 +1,28 @@
.SUFFIXES: .cc .obj
APPNAME = CDEV Packet/Message Test Program
ARCH = WINNT-4.0
BASEBIN = .
BINARIES = $(BASEBIN)\cdevPacketTest.exe $(BASEBIN)\sparsePacketTest.exe
include ..\include\makeinclude\Makefile.WINNT-4.0
CXXINCLUDES = /I .\\
CXXEXTRA = /D "GENERIC_SERVER_API= "
TARGETS = $(BASEBIN)\cdevPacketTest.exe $(BASEBIN)\sparsePacketTest.exe
targets : $(TARGETS)
$(BASEBIN)\cdevPacketTest.exe : .exec\$(TARGETDIR)\test.obj .exec\$(TARGETDIR)\cdevPacket.obj .exec\$(TARGETDIR)\cdevMessageBinary.obj .exec\$(TARGETDIR)\cdevMessage.obj
-@if exist $@ erase $@
@echo ^ ^ ^ ^ ^ ^ =^> Linking $(@F)
$(LINK) $(CDEVLIB)\cdev.lib\
$(LINK_EXE_FLAGS) /out:$@ $?
@echo ^ ^ ^ ^ ^ ^ ^ ^ ^ Done...
$(BASEBIN)\sparsePacketTest.exe : .exec\$(TARGETDIR)\sparsePacketTest.obj .exec\$(TARGETDIR)\cdevPacket.obj .exec\$(TARGETDIR)\cdevMessageBinary.obj .exec\$(TARGETDIR)\cdevMessage.obj
-@if exist $@ erase $@
@echo ^ ^ ^ ^ ^ ^ =^> Linking $(@F)
$(LINK) $(CDEVLIB)\cdev.lib\
$(LINK_EXE_FLAGS) /out:$@ $?
@echo ^ ^ ^ ^ ^ ^ ^ ^ ^ Done...
+310
View File
@@ -0,0 +1,310 @@
#include <cdevMessage.h>
// *****************************************************************************
// * cdevMessage::import :
// * This metod is used by the cdevPacket class to generate a cdevMessage
// * object from a cdevBinaryPacket object. In order for the cdevPacket
// * class to perform this task, the import method and the
// * CDEV_PACKET_VERSION must be registered using the
// * cdevPacket::registerImportMethod function.
// *****************************************************************************
cdevPacket * cdevMessage::import( cdevPacketBinary & packet)
{
char * binary = NULL;
size_t binaryLen = 0;
packet.streamOut(&binary, &binaryLen);
return new cdevMessage(binary, binaryLen);
}
// *****************************************************************************
// * cdevMessage::cdevMessage :
// * This is a parameterized constructor for the cdevMessage object. If none
// * of the parameters are specified then this constructor will build a
// * cdevMessage object made completely from defaults.
// *****************************************************************************
cdevMessage::cdevMessage ( 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)
: clientID (ClientID),
transIndex (TransIndex),
cancelTransIndex (CancelTransIndex),
localDataIndex (LocalDataIndex),
foreignDataIndex (ForeignDataIndex),
operationCode (OperationCode),
completionCode (CompletionCode),
deviceCount (DeviceCount),
deviceList (NULL),
message (NULL),
data (NULL),
context (NULL),
tagMap (NULL)
{
saveTbl.rawData=0;
if(DeviceCount>0 && DeviceList!=NULL)
{
deviceList = (char **)new char * [deviceCount];
for(int i=0; i<deviceCount; i++)
{
deviceList[i] = strdup(DeviceList[i]);
}
}
if(Message!=NULL) message = strdup(Message);
if(Data!=NULL) data = new cdevData(*Data);
if(Context!=NULL) context = new cdevData(*Context);
if(TagMap!=NULL) tagMap = new cdevData(*TagMap);
}
// *****************************************************************************
// * cdevMessage::cdevMessage :
// * This is the constructor for the object. It serves to initialize the
// * internals of the object with default values or the user specified
// * binary data if provided.
// *****************************************************************************
cdevMessage::cdevMessage ( char * binary, size_t binaryLen )
: deviceCount(0), deviceList(NULL), message(NULL),
data(NULL), context(NULL), tagMap(NULL)
{
saveTbl.rawData = 0;
streamIn(binary, binaryLen);
}
// *****************************************************************************
// * cdevMessage::cdevMessage :
// * This is the copy constructor for the object. It creates a new
// * cdevMessage object that contains all of the data specified in the
// * user provided object.
// *****************************************************************************
cdevMessage::cdevMessage ( cdevMessage & Message )
: clientID (Message.clientID),
transIndex (Message.transIndex),
cancelTransIndex (Message.cancelTransIndex),
localDataIndex (Message.localDataIndex),
foreignDataIndex (Message.foreignDataIndex),
operationCode (Message.operationCode),
completionCode (Message.completionCode),
deviceCount (Message.deviceCount),
deviceList (NULL),
message (NULL),
data (NULL),
context (NULL),
tagMap (NULL)
{
saveTbl.rawData = 0;
if(Message.deviceCount>0 && Message.deviceList!=NULL)
{
deviceList = (char **)new char * [deviceCount];
for(int i=0; i<deviceCount; i++)
{
deviceList[i] = strdup(Message.deviceList[i]);
}
}
if(Message.message!=NULL) message = strdup(Message.message);
if(Message.data!=NULL) data = new cdevData(*Message.data);
if(Message.context!=NULL) context = new cdevData(*Message.context);
if(Message.tagMap!=NULL) tagMap = new cdevData(*Message.tagMap);
}
// *****************************************************************************
// * cdevMessage::~cdevMessage :
// * This is the destructor for the class. It releases any previously
// * allocated memory prior to the destruction of the object.
// *****************************************************************************
cdevMessage::~cdevMessage ( void )
{
clear();
}
// *****************************************************************************
// * cdevMessage::clear :
// * This is the clear mechanism for the object. It is used to deallocate
// * any memory that has been allocated and set all data items to their
// * initial default values.
// *****************************************************************************
void cdevMessage::clear ( void )
{
setClientID(-1);
setTransIndex(0);
setCancelTransIndex(0);
setLocalDataIndex(0);
setForeignDataIndex(0);
setOperationCode(0);
setCompletionCode(0);
setDeviceList(NULL, 0, 0);
setMessage(NULL);
setData(NULL);
setContext(NULL);
setTagMap(NULL);
}
// *****************************************************************************
// * cdevMessage::streamIn :
// * This mechanism is used to use a binary packet to populate the
// * cdevMessage object.
// *
// * The binary stream remains the property of the caller and must be
// * delete by him.
// *****************************************************************************
int cdevMessage::streamIn( char * binary, size_t binaryLen )
{
int result = 0;
cdevMessageBinary packet;
clear();
packet.attachData(binary, binaryLen);
if(packet.hasClientID()) result+=packet.getClientID(clientID);
if(packet.hasTransIndex()) result+=packet.getTransIndex(transIndex);
if(packet.hasCancelTransIndex()) result+=packet.getCancelTransIndex(cancelTransIndex);
if(packet.hasLocalDataIndex()) result+=packet.getLocalDataIndex(localDataIndex);
if(packet.hasForeignDataIndex()) result+=packet.getForeignDataIndex(foreignDataIndex);
if(packet.hasOperationCode()) result+=packet.getOperationCode(operationCode);
if(packet.hasCompletionCode()) result+=packet.getCompletionCode(completionCode);
if(packet.hasDeviceList()) result+=packet.getDeviceList(deviceList, deviceCount);
if(packet.hasMessage()) result+=packet.getMessage(message);
if(packet.hasData())
{
data = new cdevData;
result+=packet.getData(*data);
}
if(packet.hasContext())
{
context = new cdevData;
result+=packet.getContext(*context);
}
if(packet.hasTagMap())
{
tagMap = new cdevData;
result+=packet.getTagMap(*tagMap);
}
packet.detachData();
return result;
}
// *****************************************************************************
// * cdevMessage::streamOut :
// * This mechanism is used to generate a binary representation of the
// * cdevMessage object.
// *
// * The binary stream becomes the property of the caller and he must delete
// * it when it is no longer needed.
// *****************************************************************************
int cdevMessage::streamOut( char ** binary, size_t * binaryLen )
{
cdevMessageBinary packet;
packet.set(clientID, transIndex, cancelTransIndex,
localDataIndex, foreignDataIndex, operationCode,
completionCode, deviceCount, deviceList,
message, data, context, tagMap);
packet.streamOut (binary, binaryLen);
packet.detachData();
return 0;
}
// *****************************************************************************
// * cdevMessage::asciiDump :
// * This mechanism is included to provide the ability to generate a
// * diagnostic dump of the cdevMessage object.
// *****************************************************************************
void cdevMessage::asciiDump ( FILE * fp )
{
fprintf(fp, "----------------------------------------------------------\n");
fprintf(fp, " Diagnostic Dump of CDEV Message\n");
fprintf(fp, "----------------------------------------------------------\n\n");
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, "Save Table :\n");
fprintf(fp, " Device List %s Permanent\n", saveTbl.value.saveDeviceList?"IS":"IS NOT");
fprintf(fp, " Message %s Permanent\n", saveTbl.value.saveMessage?"IS":"IS NOT");
fprintf(fp, " Data %s Permanent\n", saveTbl.value.saveData?"IS":"IS NOT");
fprintf(fp, " Context %s Permanent\n", saveTbl.value.saveContext?"IS":"IS NOT");
fprintf(fp, " Tag Map %s Permanent\n", saveTbl.value.saveTagMap?"IS":"IS NOT");
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);
fprintf(fp, "Data Object : %s", data!=NULL?"\n":"(not specified)\n");
fflush(fp);
if(data) data->asciiDump(fp);
fprintf(fp, "Context Object : %s", context!=NULL?"\n":"(not specified)\n");
fflush(fp);
if(context) context->asciiDump(fp);
fprintf(fp, "Tag Map : %s", tagMap!=NULL?"\n":"(not specified)\n");
if(tagMap)
{
size_t tagNumCnt = 0;
int * tagNums = NULL;
size_t tagNameCnt = 0;
char ** tagNames = NULL;
if(tagMap->getElems(1, &tagNumCnt)==CDEV_SUCCESS &&
tagMap->getElems(2, &tagNameCnt)==CDEV_SUCCESS &&
tagMap->getType (2)==CDEV_STRING &&
tagNumCnt==tagNameCnt)
{
char ** tagNames = NULL;
char * singleName = NULL;
tagNums = new int[tagNumCnt];
tagMap->get(1, tagNums);
if(tagNameCnt==1)
{
tagNames = &singleName;
tagMap->find(2, (void *&)singleName);
}
else tagMap->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 Message\n");
fprintf(fp, "----------------------------------------------------------\n\n");
fflush(fp);
}
+129
View File
@@ -0,0 +1,129 @@
#ifndef _CDEV_MESSAGE_H_
#define _CDEV_MESSAGE_H_ 1
#include <cdevData.h>
#include <cdevPacket.h>
#include <cdevMessageBinary.h>
class GENERIC_SERVER_API cdevMessage : public cdevPacket
{
private:
typedef union
{
unsigned char rawData;
struct {
unsigned char saveDeviceList : 1;
unsigned char saveMessage : 1;
unsigned char saveData : 1;
unsigned char saveContext : 1;
unsigned char saveTagMap : 1;
unsigned pad : 3;
} value;
} SaveTable;
SaveTable saveTbl;
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;
public:
enum { CDEV_PACKET_VERSION = cdevMessageBinary::CDEV_PACKET_VERSION };
static cdevPacket *import( cdevPacketBinary & );
cdevMessage ( short ClientID = -1,
unsigned TransIndex = 0,
unsigned CancelTransIndex = 0,
unsigned LocalDataIndex = 0,
unsigned ForeignDataIndex = 0,
unsigned OperationCode = 0,
int CompletionCode = 0,
unsigned DeviceCount = 0,
char ** DeviceList = NULL,
char * Message = NULL,
cdevData * Data = NULL,
cdevData * Context = NULL,
cdevData * TagMap = NULL);
cdevMessage ( char * binary, size_t binaryLen );
cdevMessage ( class cdevMessage & message );
virtual ~cdevMessage ( void );
virtual void clear ( void );
virtual int streamIn ( char * binary, size_t binaryLen );
virtual int streamOut ( char ** binary, size_t * binaryLen );
virtual void asciiDump ( FILE * fp = stdout );
virtual short getVersion ( void ) { return CDEV_PACKET_VERSION; }
virtual short getClientID ( void ) { return clientID; }
virtual unsigned getTransIndex ( void ) { return transIndex; }
unsigned getCancelTransIndex ( void ) { return cancelTransIndex; }
unsigned getLocalDataIndex ( void ) { return localDataIndex; }
unsigned getForeignDataIndex ( void ) { return foreignDataIndex; }
unsigned getOperationCode ( void ) { return operationCode; }
int getCompletionCode ( void ) { return completionCode; }
unsigned getDeviceCount ( void ) { return deviceCount; }
char ** getDeviceList ( void ) { return deviceList; }
char * getMessage ( void ) { return message; }
cdevData * getData ( void ) { return data; }
cdevData * getContext ( void ) { return context; }
cdevData * getTagMap ( void ) { return tagMap; }
virtual void setClientID ( short ClientID ) { clientID = ClientID; }
virtual void setTransIndex( unsigned TransIndex ) { transIndex = TransIndex; }
void setCancelTransIndex ( unsigned CancelTransIndex ) { cancelTransIndex = CancelTransIndex; }
void setLocalDataIndex ( unsigned LocalDataIndex ) { localDataIndex = LocalDataIndex; }
void setForeignDataIndex ( unsigned ForeignDataIndex ) { foreignDataIndex = ForeignDataIndex; }
void setOperationCode ( unsigned OperationCode ) { operationCode = OperationCode; }
void setCompletionCode ( int CompletionCode ) { completionCode = CompletionCode; }
void setDeviceList ( char ** DeviceList, int DeviceCount, int permanent = 0 )
{
if(deviceList!=NULL && !saveTbl.value.saveDeviceList)
{
for(int i=0; i<deviceCount; i++) delete deviceList[i];
delete deviceList;
}
deviceList = DeviceList;
deviceCount = DeviceCount;
saveTbl.value.saveDeviceList = permanent;
}
void setMessage ( char * Message, int permanent = 0 )
{
if(message!=NULL && !saveTbl.value.saveMessage) delete message;
message = Message;
saveTbl.value.saveMessage = permanent;
}
void setData ( cdevData * Data, int permanent = 0 )
{
if(data!=NULL && !saveTbl.value.saveData) delete data;
data = Data;
saveTbl.value.saveData = permanent;
}
void setContext ( cdevData * Context, int permanent = 0 )
{
if(context!=NULL && !saveTbl.value.saveContext) delete context;
context = Context;
saveTbl.value.saveContext = permanent;
}
void setTagMap ( cdevData * TagMap, int permanent = 0 )
{
if(tagMap!=NULL && !saveTbl.value.saveTagMap) delete tagMap;
tagMap = TagMap;
saveTbl.value.saveTagMap = permanent;
}
};
#endif /* _CDEV_MESSAGE_H_ */
File diff suppressed because it is too large Load Diff
+277
View File
@@ -0,0 +1,277 @@
#ifndef _CDEV_PACKET_BINARY_H_
#define _CDEV_PACKET_BINARY_H_
#include <cdevPacketBinary.h>
// *****************************************************************************
// * OperationCode Definitions :
// * CDEV_NORMAL_OP = 0 : This is a message that is to be processed by the
// * developer's server interface.
// * CDEV_SERVER_OP = 1 : This is a message that is to be processed by the
// * Generic Server Interface.
// *****************************************************************************
enum {
CDEV_NORMAL_OP = 0,
CDEV_SERVER_OP = 1
};
// *****************************************************************************
// * struct cdevMessageBinaryMap :
// * 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 clientIDSet : 1;
unsigned transIndexSet : 1;
unsigned cancelTransIndexSet : 1;
unsigned localDataIndexSet : 1;
unsigned foreignDataIndexSet : 1;
unsigned operationCodeSet : 1;
unsigned completionCodeSet : 1;
unsigned deviceListSet : 1;
unsigned messageSet : 1;
unsigned dataSet : 1;
unsigned contextSet : 1;
unsigned tagMapSet : 1;
unsigned pad : 4;
} value;
} cdevMessageBinaryMap;
// *****************************************************************************
// * The following elements are contained within a cdevMessageBinary binary
// * object.
// *
// * short version : This is the version of the cdevPacketBinary
// * that is being constructed. The format and
// * structure of the remainder of the data is
// * based on version 1.
// *
// * short clientID : **** REQUIRED ****
// * This is the clientID that the server will use
// * to uniquely identify this client.
// *
// * unsigned transIndex : **** REQUIRED ****
// * This is the index that will be used on the
// * client side to locate the transaction object
// * associated with this request.
// *
// *
// * unsigned cancelTransIndex : This is the transaction index of a transaction
// * that should be canceled. This field is
// * typically used to terminate a monitor.
// *
// * unsigned localDataIndex : This is the index that will be used on the
// * ~packet senders~ side to identify a list
// * of devices.
// *
// * unsigned foreignDataIndex : This is the index that will be used on the
// * ~packet receivers~ side to identify a list
// * of devices.
// *
// *
// * unsigned operationCode : This is a user defined operation code that
// * may be used to reduce the size of the data
// * that is transmitted between the client and
// * the server by using integer operation codes
// * rather than character strings.
// *
// * int completionCode : This is the result of the operation on the
// * server side.
// *
// * unsigned deviceCount : This is the number of device names that will
// * be contained in the following list.
// *
// * char ** deviceList : This is a list of character strings that
// * identify cdevDevices.
// *
// * char * message : This is the message text.
// *
// * cdevData data : This is a cdevData object containing the
// * data associated with the request or
// * the result of the request if this packet
// * is a response from a server.
// *
// * cdevData context : This is a cdevData object specifying the
// * context of the request.
// *
// * cdevData tagMap : This is a cdevData object that contains the
// * mapping of the cdevData tag table for the
// * client. By virtue of the fact that this table
// * cannot rely on any of the known tags to exist
// * of be the same... the following integer values
// * will be used.
// *
// * 1) An array of integers that identify the
// * tag numbers.
// *
// * 2) An array of strings that identify the
// * tag names.
// *
// *****************************************************************************
class GENERIC_SERVER_API cdevMessageBinary : public cdevPacketBinary
{
private:
cdevMessageBinaryMap map;
XDR_Reader reader;
protected:
typedef enum
{
GOTO_CLIENTID=1,
GOTO_TRANSINDEX,
GOTO_CANCELTRANSINDEX,
GOTO_LOCALDATAINDEX,
GOTO_FOREIGNDATAINDEX,
GOTO_OPERATIONCODE,
GOTO_COMPLETIONCODE,
GOTO_DEVICELIST,
GOTO_MESSAGE,
GOTO_DATA,
GOTO_CONTEXT,
GOTO_TAGMAP} POSITION_FLAG;
// *********************************************************************
// * 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 setBinaryPosition (XDR_Reader & reader, POSITION_FLAG flag );
public:
enum { CDEV_PACKET_VERSION = 2 };
cdevMessageBinary ( cdevMessageBinary &packet );
cdevMessageBinary ( short clientID = -1,
unsigned transIndex = 0,
unsigned cancelTransIndex = 0,
unsigned localDataIndex = 0,
unsigned foreignDataIndex = 0,
unsigned operationCode = 0,
int completionCode = 0,
unsigned deviceCount = 0,
char ** deviceList = NULL,
char * message = NULL,
cdevData * data = NULL,
cdevData * context = NULL,
cdevData * tagMap = NULL );
virtual ~cdevMessageBinary ( void );
// *********************************************************************
// * map2int ( void )
// * This method will convert the cdevMessageBinaryMap to an unsigned
// *********************************************************************
unsigned map2int ( cdevMessageBinaryMap map, unsigned & value);
// *********************************************************************
// * int2map ( void )
// * This method will convert an unsigned to a cdevMessageBinaryMap.
// *********************************************************************
cdevMessageBinaryMap int2map ( cdevMessageBinaryMap &map, unsigned value);
// *********************************************************************
// * The streamIn function will populate the cdevMessageBinary using the
// * data that is specified in the stream. The stream remains the
// * property of the caller, who must delete it when it is no longer
// * needed.
// *********************************************************************
virtual int streamIn ( char * stream, size_t len );
// *********************************************************************
// * 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 attachData ( char * stream, size_t len );
// *********************************************************************
// * Performs a diagnostic dump of the object.
// *********************************************************************
virtual void asciiDump ( FILE * fp = stdout );
// *********************************************************************
// * The set mechanism:
// * Allows the caller to dynamically change the contents of the
// * binary structure.
// *********************************************************************
void set ( short clientID = -1,
unsigned transIndex = 0,
unsigned cancelTransIndex = 0,
unsigned localDataIndex = 0,
unsigned foreignDataIndex = 0,
unsigned operationCode = 0,
int completionCode = 0,
unsigned deviceCount = 0,
char ** deviceList = NULL,
char * message = NULL,
cdevData * data = NULL,
cdevData * context = NULL,
cdevData * tagMap = NULL );
// *********************************************************************
// * The get mechanisms:
// * The pointers that are retrieved by these functions are the
// * actual pointers that are used within the class. They should not
// * be altered by the caller. The caller may alter the contents of
// * these objects by using the set mechanisms.
// *********************************************************************
virtual int getVersion ( short & version );
virtual int getClientID ( short & clientID );
int getTransIndex ( unsigned & transIndex );
int getCancelTransIndex ( unsigned & cancelTransIndex );
int getLocalDataIndex ( unsigned & localDataIndex );
int getForeignDataIndex ( unsigned & foreignDataIndex );
int getOperationCode ( unsigned & operationCode );
int getCompletionCode ( int & completionCode );
int getDeviceList ( char ** & deviceList, unsigned & deviceCount );
int getMessage ( char * & message );
int getData ( cdevData & data );
int getContext ( cdevData & context );
int getTagMap ( cdevData & tagMap );
int 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);
// *********************************************************************
// * The has mechanisms:
// * This collection of functions allows the caller to determine if
// * certain components of the packet are present.
// *********************************************************************
int hasClientID ( void ) { return map.value.clientIDSet; }
int hasTransIndex ( void ) { return map.value.transIndexSet; }
int hasCancelTransIndex ( void ) { return map.value.cancelTransIndexSet; }
int hasLocalDataIndex ( void ) { return map.value.localDataIndexSet; }
int hasForeignDataIndex ( void ) { return map.value.foreignDataIndexSet; }
int hasOperationCode ( void ) { return map.value.operationCodeSet; }
int hasCompletionCode ( void ) { return map.value.completionCodeSet; }
int hasDeviceList ( void ) { return map.value.deviceListSet; }
int hasMessage ( void ) { return map.value.messageSet; }
int hasData ( void ) { return map.value.dataSet; }
int hasContext ( void ) { return map.value.contextSet; }
int hasTagMap ( void ) { return map.value.tagMapSet; }
};
#endif /* CDEV_PACKET_BINARY_H_ */
+76
View File
@@ -0,0 +1,76 @@
#include <cdevPacket.h>
cdevPacket::ImportTable * cdevPacket::importTables = NULL;
int cdevPacket::maxTables = 0;
// *****************************************************************************
// * cdevPacket::import :
// * The import mechanism will walk through the importTables and attempt to
// * locate an entry that has the same packet version as the cdevPacketBinary
// * parameter. If a matching netry is found, then it will be used to decode
// * the binary and create a cdevPacket object from it, otherwise NULL will
// * be returned.
// *
// * Note: Subclasses of the cdevPacket class that wish to employ this
// * functionality must register their import methods and their packet
// * versions using the registerImportMethod mechanism.
// *****************************************************************************
cdevPacket * cdevPacket::import ( cdevPacketBinary & packet )
{
short packetVersion = 0;
int idx = 0;
int found = 0;
cdevPacket * result = NULL;
packet.getVersion(packetVersion);
while(idx<maxTables &&
importTables[idx].packetVersion!=0 &&
!found)
{
if(packetVersion == importTables[idx].packetVersion)
{
result = (*importTables[idx].importMethod)(packet);
found = 1;
}
else idx++;
}
return result;
}
// *****************************************************************************
// * cdevPacket::registerImportMethod :
// * This mechanism allows the user to associate an import method with a
// * particular packet version. The ImportMethod must take a reference to
// * a cdevPacketBinary as an argument and produce a pointer to a new
// * cdevPacket object.
// *****************************************************************************
void cdevPacket::registerImportMethod(short version, ImportMethod method)
{
int idx = 0;
for(idx = 0;
idx<maxTables &&
importTables[idx].packetVersion != 0 &&
importTables[idx].packetVersion != version;
idx++);
if(idx==maxTables)
{
if(maxTables==0)
{
importTables = (ImportTable *)malloc(sizeof(ImportTable));
memset(importTables, 0, sizeof(ImportTable));
maxTables = 1;
}
else {
importTables = (ImportTable *)realloc(importTables, maxTables*2*sizeof(ImportTable));
memset(&importTables[maxTables], 0, maxTables*sizeof(ImportTable));
maxTables *= 2;
}
}
importTables[idx].packetVersion = version;
importTables[idx].importMethod = method;
}
+35
View File
@@ -0,0 +1,35 @@
#ifndef _CDEV_PACKET_
#define _CDEV_PACKET_
#include <cdevPacketBinary.h>
class GENERIC_SERVER_API cdevPacket
{
public:
typedef cdevPacket * (*ImportMethod)(cdevPacketBinary &);
typedef struct
{
short packetVersion;
ImportMethod importMethod;
} ImportTable;
static cdevPacket * import ( cdevPacketBinary & );
static void registerImportMethod ( short, ImportMethod );
cdevPacket ( void ) {}
virtual ~cdevPacket ( void ) {}
virtual int streamIn ( char * binary, size_t binaryLen ) = 0;
virtual int streamOut ( char ** binary, size_t * binaryLen ) = 0;
virtual void asciiDump ( FILE * fp = stdout ) = 0;
virtual short getVersion ( void ) = 0;
virtual short getClientID ( void ) = 0;
virtual void setClientID ( short ClientID ) = 0;
private:
static ImportTable * importTables;
static int maxTables;
};
#endif
+322
View File
@@ -0,0 +1,322 @@
#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_ */
+103
View File
@@ -0,0 +1,103 @@
#include <cdevMessageBinary.h>
#include <cdevMessage.h>
char * myDevices[10] =
{
"Device 0",
"Device 1",
"Device 2",
"Device 3",
"Device 4",
"Device 5",
"Device 6",
"Device 7",
"Device 8",
"Device 9"
};
int myTags[] =
{
1,2,3,4,5,6,7,8,9
};
char * myTagNames[] =
{
"My Tag 1",
"My Tag 2",
"My Tag 3",
"My Tag 4",
"My tag 5",
"My Tag 6",
"My Tag 7",
"My Tag 8",
"My Tag 9"
};
char * valueTag[2] = {"This is a test1", "This is a test2"};
int statusTag[2] = {1, 2};
double severityTag[2] = {2.0, 3.0};
int main()
{
short clientID;
unsigned transIndex, cancelTransIndex;
unsigned localDataIndex;
unsigned foreignDataIndex;
unsigned operationCode;
int completionCode;
unsigned deviceCount;
char ** deviceList;
char * message;
cdevData data, context, tagMap;
data.insert("value", valueTag, 2, 1);
data.insert("status", statusTag, 2, 1);
data.insert("severity", severityTag, 2, 1);
context.insert("value", valueTag, 1, 1);
context.insert("status", statusTag, 1, 1);
context.insert("severity", severityTag, 1, 1);
tagMap.insert (1, myTags, 9);
tagMap.insert (2, myTagNames, 9);
cdevMessageBinary packet11(1, 2, 500, 3, 4, 5, 6, 10, myDevices, "set VAL", &data, &context, &tagMap);
packet11.asciiDump();
cdevMessageBinary packet22;
packet11.get(clientID, transIndex, cancelTransIndex, localDataIndex, foreignDataIndex, operationCode, completionCode, deviceCount, deviceList, message, data, context, tagMap);
packet22.set(clientID, transIndex, cancelTransIndex, localDataIndex, foreignDataIndex, operationCode, completionCode, deviceCount, deviceList, message, &data, &context, &tagMap);
packet22.asciiDump();
for(int i=0; i<deviceCount; i++) delete deviceList[i];
delete deviceList;
delete message;
char * binary;
size_t binaryLen;
packet22.streamOut(&binary, &binaryLen);
cdevMessage message1(binary, binaryLen);
message1.asciiDump();
binary = NULL;
binaryLen = 0;
message1.streamOut(&binary, &binaryLen);
cdevMessageBinary packet23;
packet23.attachData(binary, binaryLen);
packet23.asciiDump();
fprintf(stdout, "#####################################################\n");
fprintf(stdout, "### TESTING THE REGISTER AND IMPORT METHODS ###\n");
fprintf(stdout, "#####################################################\n");
cdevPacket::registerImportMethod(cdevMessageBinary::CDEV_PACKET_VERSION,
cdevMessage::import);
cdevPacket * message2 = cdevPacket::import(packet23);
message2->asciiDump();
delete message2;
return 0;
}
+154
View File
@@ -0,0 +1,154 @@
#include <cdevMessageBinary.h>
#include <cdevMessage.h>
char * myDevices[10] =
{
"Device 0",
"Device 1",
"Device 2",
"Device 3",
"Device 4",
"Device 5",
"Device 6",
"Device 7",
"Device 8",
"Device 9"
};
int myTags[] =
{
1,2,3,4,5,6,7,8,9
};
char * myTagNames[] =
{
"My Tag 1",
"My Tag 2",
"My Tag 3",
"My Tag 4",
"My tag 5",
"My Tag 6",
"My Tag 7",
"My Tag 8",
"My Tag 9"
};
int main()
{
short clientID;
unsigned transIndex, cancelTransIndex;
unsigned localDataIndex;
unsigned foreignDataIndex;
unsigned operationCode;
int completionCode;
unsigned deviceCount;
char ** deviceList;
char * message;
cdevData data, context, tagMap;
data.insert("value", "This is a test value");
data.insert("status", "This is a test status");
data.insert("displayLow", 1);
data.insert("displayHigh", 2);
data.insert("controlLow", 3);
data.insert("controlHigh", 4);
context.insert("value", "This is a context test value");
context.insert("status", "This is a context test status");
context.insert("displayLow", 5);
context.insert("displayHigh", 6);
context.insert("controlLow", 7);
context.insert("controlHigh", 8);
tagMap.insert (1, myTags, 9);
tagMap.insert (2, myTagNames, 9);
cdevMessageBinary packet1;
cdevMessageBinary packet2 (1);
cdevMessageBinary packet3 (1, 2);
cdevMessageBinary packet3a(1, 2, 500);
cdevMessageBinary packet4 (1, 2, 500, 3);
cdevMessageBinary packet5 (1, 2, 500, 3, 4);
cdevMessageBinary packet5a(1, 2, 500, 3, 4, 5);
cdevMessageBinary packet6 (1, 2, 500, 3, 4, 5, 6, 10);
cdevMessageBinary packet7 (1, 2, 500, 3, 4, 5, 6, 10, myDevices);
cdevMessageBinary packet8 (1, 2, 500, 3, 4, 5, 6, 10, myDevices, "set VAL");
cdevMessageBinary packet9 (1, 2, 500, 3, 4, 5, 6, 10, myDevices, "set VAL", &data);
cdevMessageBinary packet10(1, 2, 500, 3, 4, 5, 6, 10, myDevices, "set VAL", &data, &context);
cdevMessageBinary packet11(1, 2, 500, 3, 4, 5, 6, 10, myDevices, "set VAL", &data, &context, &tagMap);
cdevMessageBinary packet12(-1, 2, 500, 3, 4, 5, 6, 10, myDevices, "set VAL", &data, &context, &tagMap);
cdevMessageBinary packet13(-1, 0, 500, 3, 4, 5, 6, 10, myDevices, "set VAL", &data, &context, &tagMap);
cdevMessageBinary packet14(-1, 0, 0, 3, 4, 5, 6, 10, myDevices, "set VAL", &data, &context, &tagMap);
cdevMessageBinary packet14a(-1, 0, 0, 0, 4, 5, 6, 10, myDevices, "set VAL", &data, &context, &tagMap);
cdevMessageBinary packet15(-1, 0, 0, 0, 0, 5, 6, 10, myDevices, "set VAL", &data, &context, &tagMap);
cdevMessageBinary packet16(-1, 0, 0, 0, 0, 0, 0, 10, myDevices, "set VAL", &data, &context, &tagMap);
cdevMessageBinary packet16a(-1, 0, 0, 0, 0, 0, 0, 0, myDevices, "set VAL", &data, &context, &tagMap);
cdevMessageBinary packet17(-1, 0, 0, 0, 0, 0, 0, 0, NULL, "set VAL", &data, &context, &tagMap);
cdevMessageBinary packet18(-1, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, &data, &context, &tagMap);
cdevMessageBinary packet19(-1, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, &context, &tagMap);
cdevMessageBinary packet20(-1, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, &tagMap);
cdevMessageBinary packet21(-1, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
packet1.asciiDump();
packet2.asciiDump();
packet3.asciiDump();
packet3a.asciiDump();
packet4.asciiDump();
packet5.asciiDump();
packet5a.asciiDump();
packet6.asciiDump();
packet7.asciiDump();
packet8.asciiDump();
packet9.asciiDump();
packet10.asciiDump();
packet11.asciiDump();
packet12.asciiDump();
packet13.asciiDump();
packet14.asciiDump();
packet14a.asciiDump();
packet15.asciiDump();
packet16.asciiDump();
packet16a.asciiDump();
packet17.asciiDump();
packet18.asciiDump();
packet19.asciiDump();
packet20.asciiDump();
packet21.asciiDump();
cdevMessageBinary packet22;
packet11.get(clientID, transIndex, cancelTransIndex, localDataIndex, foreignDataIndex, operationCode, completionCode, deviceCount, deviceList, message, data, context, tagMap);
packet22.set(clientID, transIndex, cancelTransIndex, localDataIndex, foreignDataIndex, operationCode, completionCode, deviceCount, deviceList, message, &data, &context, &tagMap);
packet22.asciiDump();
for(int i=0; i<deviceCount; i++) delete deviceList[i];
delete deviceList;
delete message;
char * binary;
size_t binaryLen;
packet22.streamOut(&binary, &binaryLen);
cdevMessage message1(binary, binaryLen);
message1.asciiDump();
binary = NULL;
binaryLen = 0;
message1.streamOut(&binary, &binaryLen);
cdevMessageBinary packet23;
packet23.attachData(binary, binaryLen);
packet23.asciiDump();
fprintf(stdout, "#####################################################\n");
fprintf(stdout, "### TESTING THE REGISTER AND IMPORT METHODS ###\n");
fprintf(stdout, "#####################################################\n");
cdevPacket::registerImportMethod(cdevMessageBinary::CDEV_PACKET_VERSION,
cdevMessage::import);
cdevPacket * message2 = cdevPacket::import(packet23);
message2->asciiDump();
delete message2;
return 0;
}