#include #include #include #include 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(typeuserType)?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; iinsert(tag, stringData, position+1); for(i=0; itsCnt) { 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); }