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

440 lines
15 KiB
C++

#include <cdevSystem.h>
#include <cdevRequestObject.h>
#include <cdevData.h>
#include <cdevCallback.h>
class rnsQueryCollector
{
private:
cdevData * data;
int deleteFlag;
unsigned char * byteData;
short * shortData;
unsigned short * ushortData;
long * longData;
unsigned long * ulongData;
float * floatData;
double * doubleData;
cdev_TS_STAMP * tsData;
size_t byteCnt;
size_t shortCnt;
size_t ushortCnt;
size_t longCnt;
size_t ulongCnt;
size_t floatCnt;
size_t doubleCnt;
size_t tsCnt;
public:
rnsQueryCollector ( cdevData & userData, int deleteData = 0 )
: data(&userData), deleteFlag(deleteData),
byteData(NULL), shortData(NULL), ushortData(NULL),
longData(NULL), ulongData(NULL), floatData(NULL),
doubleData(NULL), tsData(NULL), byteCnt(0),
shortCnt(0), ushortCnt(0), longCnt(0), ulongCnt(0),
floatCnt(0), doubleCnt(0), tsCnt(0)
{
data->remove();
}
~rnsQueryCollector ( void )
{
if(deleteFlag) delete data;
if(byteData) delete byteData;
if(shortData) delete shortData;
if(ushortData) delete ushortData;
if(longData) delete longData;
if(ulongData) delete ulongData;
if(floatData) delete floatData;
if(doubleData) delete doubleData;
if(tsData) delete tsData;
}
cdevData * getData ( void ) { return data; }
void clearData ( void ) { data->remove(); }
inline int collect ( cdevData & userData );
private:
inline int collectAttribute ( cdevData & userData, int tag, int position );
inline void collectByteAttribute ( cdevData & userData, int tag, int position );
inline void collectShortAttribute ( cdevData & userData, int tag, int position );
inline void collectUShortAttribute ( cdevData & userData, int tag, int position );
inline void collectLongAttribute ( cdevData & userData, int tag, int position );
inline void collectULongAttribute ( cdevData & userData, int tag, int position );
inline void collectFloatAttribute ( cdevData & userData, int tag, int position );
inline void collectDoubleAttribute ( cdevData & userData, int tag, int position );
inline void collectStringAttribute ( cdevData & userData, int tag, int position );
inline void collectTimestampAttribute ( cdevData & userData, int tag, int position );
};
// *****************************************************************************
// * class rnsQueryCallback :
// * This class provides the methods to allow a rnsQueryCollector to be
// * incorporated into a cdevCallback. The localCallback function will
// * be called with results until the data has been completely collected,
// * and only then will the user callback be executed - providing full
// * data.
// *****************************************************************************
class rnsQueryCallback : public cdevCallback
{
private:
rnsQueryCollector collector;
cdevCallback callback;
public:
rnsQueryCallback ( cdevCallback & Callback )
: cdevCallback(), callback(Callback), collector(*(new cdevData), 1)
{
userarg_ = this;
function_ = rnsQueryCallback::localCallback;
}
virtual ~rnsQueryCallback ( void )
{
}
static void localCallback ( int status, void * arg, cdevRequestObject & req, cdevData & data)
{
rnsQueryCallback * qCallback;
if((qCallback = (rnsQueryCallback *)arg)!=NULL)
{
if(status==CDEV_SUCCESS ||
status==CDEV_INCOMPLETE)
{
qCallback->collector.collect(data);
}
if(status==CDEV_SUCCESS ||
status==CDEV_ERROR ||
status==CDEV_NOTFOUND ||
status==CDEV_MSG_ERR)
{
qCallback->callback.fireCallback(status, qCallback->callback.userarg(),
req, *qCallback->collector.getData(), 0);
}
}
}
};
// *****************************************************************************
// * rnsQueryCollector::collect :
// * This method is called when a cdevData object needs to be appended to
// * the cdevData object that is serving as a collection. This method will
// * transfer each of the data items in the userData object to the proper
// * position in the local data object.
// *****************************************************************************
int rnsQueryCollector::collect ( cdevData & userData )
{
int cnt = 0;
size_t size = 0;
cdevDataIterator iter(&userData);
cdevDataIterator dIter(data);
// *********************************************************************
// * Look through the existing data and determine the largest number
// * of items that exist in a single tagged item. This value will be
// * used to specify the position of the data that is being added to the
// * array.
// *********************************************************************
dIter.init();
while(dIter.tag()!=0)
{
size_t elems = 0;
data->getElems(dIter.tag(), &elems);
if(elems>size) size = elems;
++dIter;
}
// *********************************************************************
// * Walk through the list of tagged data items that are stored in the
// * inbound data object. Call the collectAttribute method for each
// * data item. This method will copy the contents of the inbound
// * data object to the correct position in the local data object.
// *********************************************************************
iter.init();
while(iter.tag()!=0)
{
cnt+=(collectAttribute(userData, iter.tag(), size)==0)?1:0;
++iter;
}
// *********************************************************************
// * Return the count of data items that were assimilated into the
// * local data object.
// *********************************************************************
return cnt;
}
// *****************************************************************************
// * rnsQueryCollector::collectAttribute :
// * This method will assimilate a single attribute from the specified
// * userData object into the local cdevData object at the specified
// * position.
// *****************************************************************************
int rnsQueryCollector::collectAttribute ( cdevData & userData, int tag, int position )
{
cdevSystem & sys = cdevSystem::defaultSystem();
int result = 0;
size_t dim = 0;
size_t userDim = 0;
cdevDataTypes type = data->getType(tag);
cdevDataTypes userType = userData.getType(tag);
if(userData.getDim(tag, &dim)==CDEV_NOTFOUND || dim > 0)
{
sys.reportError(CDEV_SEVERITY_ERROR, "Name Server", NULL,
"Cannot add array data to query reply");
result = -1;
}
else if(data->getDim(tag, &dim)!=CDEV_NOTFOUND && dim > 1)
{
sys.reportError(CDEV_SEVERITY_ERROR, "Name Server", NULL,
"Cannot assemble a query with multi-dimensional data");
result = -1;
}
else if (userType == CDEV_INVALID)
{
sys.reportError(CDEV_SEVERITY_ERROR, "Name Server", NULL,
"Inbound query data object has invalid data type");
result = -1;
}
else {
if(type!=CDEV_INVALID)
{
if(type<CDEV_TIMESTAMP && userType<CDEV_TIMESTAMP)
{
type = (type>userType)?type:userType;
}
else if(type==CDEV_TIMESTAMP) type = userType;
}
else type = userType;
switch(type)
{
case CDEV_BYTE:
collectByteAttribute(userData, tag, position);
break;
case CDEV_INT16:
collectShortAttribute(userData, tag, position);
break;
case CDEV_UINT16:
collectUShortAttribute(userData, tag, position);
break;
case CDEV_INT32:
collectLongAttribute(userData, tag, position);
break;
case CDEV_UINT32:
collectULongAttribute(userData, tag, position);
break;
case CDEV_FLOAT:
collectFloatAttribute(userData, tag, position);
break;
case CDEV_DOUBLE:
collectDoubleAttribute(userData, tag, position);
break;
case CDEV_STRING:
collectStringAttribute(userData, tag, position);
break;
case CDEV_TIMESTAMP:
collectTimestampAttribute(userData, tag, position);
break;
default:
result = -1;
break;
}
}
return result;
}
// *****************************************************************************
// * rnsQueryCollector::collectByteAttribute :
// * This method will transfer the byte attribute stored in the userData
// * object into the local cdevData object at the specified position.
// *****************************************************************************
void rnsQueryCollector::collectByteAttribute (cdevData & userData, int tag, int position )
{
if((position+1)>byteCnt)
{
if(byteData!=NULL) delete byteData;
byteCnt = ((position+1)>100)?(position+100):100;
byteData = new unsigned char [byteCnt];
}
memset(byteData, 0, byteCnt*sizeof(unsigned char));
data->get(tag, byteData);
userData.get(tag, &byteData[position]);
data->insert(tag, byteData, position+1);
}
// *****************************************************************************
// * rnsQueryCollector::collectShortAttribute :
// * This method will transfer the short attribute stored in the userData
// * object into the local cdevData object at the specified position.
// *****************************************************************************
void rnsQueryCollector::collectShortAttribute (cdevData & userData, int tag, int position )
{
if((position+1)>shortCnt)
{
if(shortData!=NULL) delete shortData;
shortCnt = ((position+1)>100)?(position+100):100;
shortData = new short [shortCnt];
}
memset(shortData, 0, shortCnt*sizeof(short));
data->get(tag, shortData);
userData.get(tag, &shortData[position]);
data->insert(tag, shortData, position+1);
}
// *****************************************************************************
// * rnsQueryCollector::collectUShortAttribute :
// * This method will transfer the unsigned short attribute stored in the
// * userData object into the local cdevData object at the specified
// * position.
// *****************************************************************************
void rnsQueryCollector::collectUShortAttribute (cdevData & userData, int tag, int position )
{
if((position+1)>ushortCnt)
{
if(ushortData!=NULL) delete ushortData;
ushortCnt = ((position+1)>100)?(position+100):100;
ushortData = new unsigned short [ushortCnt];
}
memset(ushortData, 0, ushortCnt*sizeof(unsigned short));
data->get(tag, ushortData);
userData.get(tag, &ushortData[position]);
data->insert(tag, ushortData, position+1);
}
// *****************************************************************************
// * rnsQueryCollector::collectLongAttribute :
// * This method will transfer the long attribute stored in the
// * userData object into the local cdevData object at the specified
// * position.
// *****************************************************************************
void rnsQueryCollector::collectLongAttribute (cdevData & userData, int tag, int position )
{
if((position+1)>longCnt)
{
if(longData!=NULL) delete longData;
longCnt = ((position+1)>100)?(position+100):100;
longData = new long [longCnt];
}
memset(longData, 0, longCnt*sizeof(long));
data->get(tag, longData);
userData.get(tag, &longData[position]);
data->insert(tag, longData, position+1);
}
// *****************************************************************************
// * rnsQueryCollector::collectULongAttribute :
// * This method will transfer the unsigned long attribute stored in the
// * userData object into the local cdevData object at the specified
// * position.
// *****************************************************************************
void rnsQueryCollector::collectULongAttribute (cdevData & userData, int tag, int position )
{
if((position+1)>ulongCnt)
{
if(ulongData!=NULL) delete ulongData;
ulongCnt = ((position+1)>100)?(position+100):100;
ulongData = new unsigned long [ulongCnt];
}
memset(ulongData, 0, ulongCnt*sizeof(unsigned long));
data->get(tag, ulongData);
userData.get(tag, &ulongData[position]);
data->insert(tag, ulongData, position+1);
}
// *****************************************************************************
// * rnsQueryCollector::collectFloatAttribute :
// * This method will transfer the float attribute stored in the
// * userData object into the local cdevData object at the specified
// * position.
// *****************************************************************************
void rnsQueryCollector::collectFloatAttribute (cdevData & userData, int tag, int position )
{
if((position+1)>floatCnt)
{
if(floatData!=NULL) delete floatData;
floatCnt = ((position+1)>100)?(position+100):100;
floatData = new float [floatCnt];
}
memset(floatData, 0, floatCnt*sizeof(float));
data->get(tag, floatData);
userData.get(tag, &floatData[position]);
data->insert(tag, floatData, position+1);
}
// *****************************************************************************
// * rnsQueryCollector::collectDoubleAttribute :
// * This method will transfer the double attribute stored in the
// * userData object into the local cdevData object at the specified
// * position.
// *****************************************************************************
void rnsQueryCollector::collectDoubleAttribute (cdevData & userData, int tag, int position )
{
if((position+1)>doubleCnt)
{
if(doubleData!=NULL) delete doubleData;
doubleCnt = ((position+1)>100)?(position+100):100;
doubleData = new double [doubleCnt];
}
memset(doubleData, 0, doubleCnt*sizeof(double));
data->get(tag, doubleData);
userData.get(tag, &doubleData[position]);
data->insert(tag, doubleData, position+1);
}
// *****************************************************************************
// * rnsQueryCollector::collectStringAttribute :
// * This method will transfer the string attribute stored in the
// * userData object into the local cdevData object at the specified
// * position.
// *****************************************************************************
void rnsQueryCollector::collectStringAttribute (cdevData & userData, int tag, int position )
{
int i;
char blank = 0;
char ** stringData = new char * [ position+1 ];
memset(stringData, 0, (position+1)*sizeof(char *));
data->get(tag, stringData);
userData.get(tag, &stringData[position]);
for(i=0; i<position+1; i++)
{
if(stringData[i] == NULL) stringData[i] = &blank;
}
data->insert(tag, stringData, position+1);
for(i=0; i<position+1; i++)
{
if(stringData[i]!=&blank) delete stringData[i];
}
delete stringData;
}
// *****************************************************************************
// * rnsQueryCollector::collectTimestampAttribute :
// * This method will transfer the time stamp attribute stored in the
// * userData object into the local cdevData object at the specified
// * position.
// *****************************************************************************
void rnsQueryCollector::collectTimestampAttribute (cdevData & userData, int tag, int position )
{
if((position+1)>tsCnt)
{
if(tsData!=NULL) delete tsData;
tsCnt = ((position+1)>100)?(position+100):100;
tsData = new cdev_TS_STAMP [tsCnt];
}
memset(tsData, 0, tsCnt);
data->get(tag, tsData);
userData.get(tag, &tsData[position]);
data->insert(tag, tsData, position+1);
}