440 lines
15 KiB
C++
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] = ␣
|
|
}
|
|
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);
|
|
}
|