/// /// \file cafe.cc /// \author Jan Chrin, PSI /// \date Release: June, 2015 /// \version CAFE 1.0.0 /// /// Copyright 2014, Jan Chrin, PSI /// /// This program is free software: it may be redistributed and modifified /// under the terms of the GNU General Public License as published by /// the Free Software Foundation, under License version 3 or later. /// /// This program is distributed in the hope that it will be useful, /// but WITHOUT ANY WARRANTY; without even the implied warranty of /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /// GNU General Public License for more details. /// /// The GNU General Public License can be gotten from /// http://www.gnu.org/licenses/. /// #include "cafe.h" #include "conduitGroup.h" #include bool MUTEX=true; bool CHECK_CONSISTENCY_CA_STATE=true; epicsMutex cafeMutex; cafeConduit_set cs; cafeGroup_set gs; vector PVGroupV; vector PVGroupPseudo; vector deviceCollectionV; vector globalChannelList; map, string> groupPseudoMap; #include "cafeEnum.h" #include "enumStrings.h" /** * \brief Set an array of handles with long long(s) * \param handleArray input: array of handles * \param nelem input: number of elements defining size of array * \param _val input: array of long longs * \param statusArray output: array of corresponding status * \return ECA_NORMAL if all OK else first ECAFE error encountered */ int CAFE::set(const unsigned int *handleArray, const unsigned int nelem, const long long * _val, int *statusArray) { //what is the highest native type? chtype chtMax=DBF_CHAR; ChannelRegalia channelInfo; unsigned short nbyteChType=1; unsigned short nbyteMax=nbyteChType; for (unsigned int i=0; inbyteMax && channelInfo.getDataType()< CAFE_NO_ACCESS) { chtMax=channelInfo.getDataType(); nbyteMax=4; } } } int _status=ICAFE_NORMAL; if ( chtMax == DBF_STRING) { dbr_string_t * _sVal = new dbr_string_t[nelem]; for (unsigned int i=0; i < nelem; ++i) { std::stringstream ss; ss.clear(); ss << _val[i]; strcpy(_sVal[i] , ss.str().c_str()); } _status=CAFE::set (handleArray, nelem, _sVal, statusArray); delete [] _sVal; } else if ( chtMax == DBF_DOUBLE) { dbr_double_t * _dVal = new dbr_double_t[nelem]; for (unsigned int i=0; i < nelem; ++i) { _dVal[i] = (double) _val[i]; } _status=CAFE::set (handleArray, nelem, _dVal, statusArray); delete [] _dVal; } else if ( chtMax == DBF_FLOAT) { dbr_float_t * _fVal = new dbr_float_t[nelem]; for (unsigned int i=0; i < nelem; ++i) { _fVal[i] = (float) _val[i]; } _status=CAFE::set (handleArray, nelem, _fVal, statusArray); delete [] _fVal; } else { dbr_long_t * _lVal = new dbr_long_t[nelem]; for (unsigned int i=0; i < nelem; ++i) { _lVal[i] = (dbr_long_t) _val[i]; } _status=CAFE::set (handleArray, nelem, _lVal, statusArray); delete [] _lVal; } return _status; } //5+ long long /** * Get long long(s), alarms and timeStamp * \param handle input: handle to conduit object * \param _val output: array of long longs * \param alarmStatus output: alarm status * \param alarmSeverity output: alarm Severity * \param ts output: epicsTimeStamp * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::get(const unsigned int handle, long long * _val, \ dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts) { #define __METHOD__ \ "CAFE::get(const unsigned int handle, long long * _val, \ dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts)" ChannelRegalia channelInfo; CAFE::getChannelInfo(handle, channelInfo); if ( channelInfo.getCafeConnectionState() == ICAFE_CS_NEVER_CONN) { return ICAFE_CS_NEVER_CONN; } status=ICAFE_NORMAL; unsigned int nn=handleHelper.getNelemNative(handle); if ( channelInfo.getDataType() == DBR_STRING) { dbr_string_t * _sVal = new dbr_string_t[nn]; status=cafeSoluble.get (handle, DBR_TIME_STRING, _sVal, alarmStatus, alarmSeverity, ts); if (status!=ICAFE_NORMAL) { delete [] _sVal; return status;} istringstream ss; for (unsigned short i=0; i>l; if ( !ss.fail()) { _val[i] = (long long) l; std::string strInput=_sVal[i]; std::stringstream ssOut; ssOut << l; std::string strOutput=ssOut.str(); if (strInput!=strOutput) { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** STRING TO LONG LONG CONVERSION REPORTS: " << endl; cout << "STRING VALUE: " << strInput << " CONVERTED TO: " << strOutput << endl; } } else { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** NO STRING TO LONG LONG CONVERSION for ELEMENT " << i \ << " of " << nn << " !! " << endl; cout << "***WARNING*** COULD NOT CONVERT: "; cout << _sVal[i]; cout << " TO LONG LONG ; CONVERSION NOT MADE!" << endl; cout << "Returning value 0 for element " << i << endl; _val[i]=0; } } delete [] _sVal; } else if ( channelInfo.getDataType() == DBR_DOUBLE) { dbr_double_t * _dVal = new dbr_double_t[nn]; status=cafeDoppio.get (handle, DBR_TIME_DOUBLE, _dVal, alarmStatus, alarmSeverity, ts); for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _dVal[i]; } delete [] _dVal; } else if ( channelInfo.getDataType() == DBR_FLOAT) { dbr_float_t * _fVal = new dbr_float_t[nn]; status=cafeFrappuccino.get (handle, DBR_TIME_FLOAT, _fVal, alarmStatus, alarmSeverity, ts); for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _fVal[i]; } delete [] _fVal; } else { dbr_long_t * _lVal = new dbr_long_t[nn]; status=cafeLatte.get (handle, DBR_TIME_LONG, _lVal, alarmStatus, alarmSeverity, ts); for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _lVal[i]; } delete [] _lVal; } return status; #undef __METHOD__ }; /** * Get long long(s) and alarms * \param handle input: handle to conduit object * \param _val output: array of long longs * \param alarmStatus output: alarm Status * \param alarmSeverity output: alarm Severity * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::get(const unsigned int handle, long long * _val, \ dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity) { #define __METHOD__ \ "CAFE::get(unsigned int handle, long long * _val, dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity)" ChannelRegalia channelInfo; CAFE::getChannelInfo(handle, channelInfo); if ( channelInfo.getCafeConnectionState() == ICAFE_CS_NEVER_CONN) { return ICAFE_CS_NEVER_CONN; } int _status=ICAFE_NORMAL; unsigned int nn=handleHelper.getNelemNative(handle); if ( channelInfo.getDataType() == DBR_STRING) { dbr_string_t * _sVal = new dbr_string_t[nn]; _status=cafeSoluble.get (handle, DBR_STS_STRING, _sVal, alarmStatus, alarmSeverity); if (_status!=ICAFE_NORMAL) { delete [] _sVal; return _status;} istringstream ss; for (unsigned short i=0; i>l; if ( !ss.fail()) { _val[i] = (long long) l; std::string strInput=_sVal[i]; std::stringstream ssOut; ssOut << l; std::string strOutput=ssOut.str(); if (strInput!=strOutput) { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** STRING TO LONG LONG CONVERSION REPORTS: " << endl; cout << "STRING VALUE: " << strInput << " CONVERTED TO: " << strOutput << endl; } } else { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** NO STRING TO LONG LONG CONVERSION for ELEMENT " << i \ << " of " << nn << " !! " << endl; cout << "***WARNING*** COULD NOT CONVERT: "; cout << _sVal[i]; cout << " TO LONG LONG ; CONVERSION NOT MADE!" << endl; cout << "Returning value 0 for element " << i << endl; _val[i]=0; } } delete [] _sVal; } else if ( channelInfo.getDataType() == DBR_DOUBLE) { dbr_double_t * _dVal = new dbr_double_t[nn]; _status=cafeDoppio.get (handle, DBR_STS_DOUBLE, _dVal, alarmStatus, alarmSeverity); for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _dVal[i]; } delete [] _dVal; } else if ( channelInfo.getDataType() == DBR_FLOAT) { dbr_float_t * _fVal = new dbr_float_t[nn]; _status=cafeFrappuccino.get (handle, DBR_STS_FLOAT, _fVal, alarmStatus, alarmSeverity); for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _fVal[i]; } delete [] _fVal; } else { dbr_long_t * _lVal = new dbr_long_t[nn]; _status=cafeLatte.get (handle, DBR_STS_LONG, _lVal, alarmStatus, alarmSeverity); for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _lVal[i]; } delete [] _lVal; } return _status; #undef __METHOD__ }; /** * Get long long(s) * \param handle input: handle * \param _val output: array of long longs * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::get(const unsigned int handle, long long * _val){ #define __METHOD__ \ "CAFE::get(const unsigned int handle, long long * _val)" ChannelRegalia channelInfo; CAFE::getChannelInfo(handle, channelInfo); if ( channelInfo.getCafeConnectionState() == ICAFE_CS_NEVER_CONN) { return ICAFE_CS_NEVER_CONN; } int _status=ICAFE_NORMAL; unsigned int nn=handleHelper.getNelemNative(handle); if ( channelInfo.getDataType() == DBR_STRING) { dbr_string_t * _sVal = new dbr_string_t[nn]; _status=cafeSoluble.get (handle, DBR_STRING, _sVal); if (_status!=ICAFE_NORMAL) { delete [] _sVal; return _status;} istringstream ss; for (unsigned short i=0; i>l; if ( !ss.fail()) { _val[i] = (long long) l; std::string strInput=_sVal[i]; std::stringstream ssOut; ssOut << l; std::string strOutput=ssOut.str(); if (strInput!=strOutput) { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** STRING TO LONG LONG CONVERSION REPORTS: " << endl; cout << "STRING VALUE: " << strInput << " CONVERTED TO: " << strOutput << endl; } } else { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** NO STRING TO LONG LONG CONVERSION for ELEMENT " << i \ << " of " << nn << " !! " << endl; cout << "***WARNING*** COULD NOT CONVERT: "; cout << _sVal[i]; cout << " TO LONG LONG ; CONVERSION NOT MADE!" << endl; cout << "Returning value 0 for element " << i << endl; _val[i]=0; } } delete [] _sVal; } else if ( channelInfo.getDataType() == DBR_DOUBLE) { dbr_double_t * _dVal = new dbr_double_t[nn]; _status=cafeDoppio.get (handle, DBR_DOUBLE, _dVal); if (_status!=ICAFE_NORMAL) { delete [] _dVal; return _status;} for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _dVal[i]; } delete [] _dVal; } else if ( channelInfo.getDataType() == DBR_FLOAT) { dbr_float_t * _fVal = new dbr_float_t[nn]; _status=cafeFrappuccino.get (handle, DBR_FLOAT, _fVal); if (_status!=ICAFE_NORMAL) { delete [] _fVal; return _status;} for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _fVal[i]; } delete [] _fVal; } else { dbr_long_t * _lVal = new dbr_long_t[nn]; _status=cafeLatte.get (handle, DBR_LONG, _lVal); if (_status!=ICAFE_NORMAL) { delete [] _lVal; return _status;} for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _lVal[i]; } delete [] _lVal; } return _status; #undef __METHOD__ }; /** * Sends ca_get message to IOC and returns without waiting, i.e. non-blocking \n * To be followed by a getCache method * \param handle input: handle to conduit object * \return ICAFE_NORMAL if all OK else ICAFE_WAITING_FOR_PREV_CALLBACK or other; */ int CAFE::get(const unsigned int handle) { #define __METHOD__ "CAFE::get(unsigned int handle)" status=ICAFE_NORMAL; cafeConduit_set_by_handle & handle_index = cs.get (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) { chtype dbrtype= (*it_handle).getChannelRequestMetaDataClient().getDbrDataType(); //Find Native DataType if ( (status=cafeGranules.channelVerifyGet(handle, dbrtype)) != ICAFE_NORMAL) { if(MUTEX){cafeMutex.lock();} //lock handle_index.modify(it_handle, change_status(status)); if(MUTEX){cafeMutex.unlock();}//unlock cout << __METHOD__ << "//" << __LINE__ << " for handle/pv=" << handle <<"/" << (*it_handle).getPV() < (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) { //Use Native DataType if ( (status=cafeGranules.channelVerifyGetCtrl(handle, dbf_type_to_DBR_CTRL((*it_handle).getChannelRegalia().getDataType()))) != ICAFE_NORMAL) { if(MUTEX){cafeMutex.lock();}; //lock handle_index.modify(it_handle, change_status(status)); if(MUTEX){cafeMutex.unlock();}; //unlock cout << __METHOD__ << "//" << __LINE__ << " for handle/pv=" << handle <<"/" << (*it_handle).getPV() < (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) { if ( (*it_handle).getChannelGetActionWhenMonitorPolicy().getActionKind() == CAFENUM::GET_FROM_CACHE) { if ( handleHelper.getNmonitorData(handle) >0){ bool doGetCache=true; vector mpV; handleHelper.getMonitorPolicyVector(handle, mpV); //loop for (unsigned int n=0; n (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) { return cafeGranules.waitForGetEvent(handle, (*it_handle).getChannelTimeoutPolicyGet().getTimeout()); } else {return ECAFE_INVALID_HANDLE;} }; /** * Waits until all handle callbacks have reported or timed out * \param handleV input: Vector of handles to Conduit objects * \param vRB output: vector of Bundled responses (reporting whether callback was completed) * \return overallStatus: ICAFE_NORMAL if all OK else first ECAFE error encountered */ int CAFE::waitForBundledEvents(vector handleV, vector &vRB){ #define __METHOD__ \ "int CAFE::waitForBundledEvents(vector handleV, vector vRB) " return waitForBundledEvents(&handleV[0], handleV.size(), vRB); /* int statusBundle=ICAFE_NORMAL; map bundleResponse; map::iterator pos; unsigned int nHandles=handleV.size(); vRB.clear(); vRB.reserve(nHandles); std::set uniqueHandles; std::set::iterator uniquePos; //std::vector handleArrayV(handleV); //Remove duplicate handles for (unsigned int i=0; isecond); //cout << "handle " << pos->first << " status " << pos->second << " [" << i << "] "<< endl; if(pos->second != ICAFE_NORMAL) { cout << resetCallbackGet(pos->first) << endl; } } } //for (unsigned int i=0; i vRB) " int statusBundle=ICAFE_NORMAL; map bundleResponse; map::iterator pos; vRB.clear(); vRB.reserve(nHandles); std::vector handleArrayV; handleArrayV.reserve(nHandles); handleArrayV.insert(handleArrayV.end(), &handleArray[0], &handleArray[nHandles]); std::set uniqueHandles; std::set::iterator uniquePos; //Remove duplicate handles for (unsigned int i=0; isecond); if(pos->second != ICAFE_NORMAL) { cout << resetCallbackGet(pos->first) << endl; } } } //for (unsigned int i=0; i0) { vector mpV; handleHelper.getMonitorPolicyVector(handleArray[i], mpV); //loop for (unsigned int n=0; n " << pos->second << endl; //} for (unsigned int i=0; i (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) { channelRequestMetaCtrlClient= (*it_handle).getChannelRequestMetaCtrlClient(); if (pvc.getNelem() != channelRequestMetaCtrlClient.getNelem()) { channelRequestMetaCtrlClient.setNelem(pvc.getNelem()); if(MUTEX){cafeMutex.lock();} //lock handle_index.modify(it_handle, change_channelRequestMetaCtrlClient(channelRequestMetaCtrlClient)); if(MUTEX){cafeMutex.unlock();} //unlock } //Use Native DataType if ( (status=cafeGranules.channelVerifyGetCtrl(handle, dbf_type_to_DBR_CTRL((*it_handle).getChannelRegalia().getDataType()))) != ICAFE_NORMAL) { (*it_handle).getPVCtrlHolder(pvc); pvc.status=status; return status; } if ( (status=cafeGranules.channelPrepareGetCtrl(handle)) != ICAFE_NORMAL) { (*it_handle).getPVCtrlHolder(pvc); pvc.status=status; return status; } if ( (status=cafeGranules.channelExecuteGetCtrl(handle)) != ICAFE_NORMAL) { (*it_handle).getPVCtrlHolder(pvc); pvc.status=status; return status; } (*it_handle).getPVCtrlHolder(pvc); handleHelper.setNelemToRetrieveFromCtrlCache(handle,pvc.nelem); } else { if (printErrorPolicy.getInvalidHandle()) { cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; cafeStatus.report(ECAFE_INVALID_HANDLE); pvc.status=ECAFE_INVALID_HANDLE; } return ECAFE_INVALID_HANDLE; } if(MUTEX){cafeMutex.lock();}; //lock handle_index.modify(it_handle, change_status(status)); if(MUTEX){cafeMutex.unlock();}; //unlock return status; #undef __METHOD__ }; /** * Retrieves data, packaged into an array of PVCtrlHolder class' * \param handleArray input: Array of handles to Conduit object * \param nelem input: No of array elements * \param pvcArray output: Array of PVCtrlHolder * \return overallStatus: ICAFE_NORMAL if all OK else first ECAFE error encountered */ int CAFE::getCtrl(const unsigned int * handleArray, unsigned int nelem, \ PVCtrlHolder * pvcArray) { #define __METHOD__ \ "CAFE::getCtrl(unsigned int * handleArray, unsigned int nelem, PVCtrlHolder * pvcArray)" int overallStatus=ICAFE_NORMAL; bool isGood=true; for (unsigned int i=0; i &statusV) { int overallStatus=ICAFE_NORMAL; bool isGood=true; statusV.clear(); statusV.reserve(nHandles); for (unsigned int i=0; i0) { statusV.push_back(ICAFE_NORMAL); //ICAFE_HAS_MONITOR_GET_DONE_FROM_CACHE); } else { statusV.push_back(get(handleArray[i])); } if ( (statusV[i] != ICAFE_NORMAL) && isGood) { overallStatus=statusV[i]; isGood=false; } } //ca_flush_io(); return overallStatus; // report first failure in return statement } /** * Sends ca_get messages to IOC and waits until the end before flushing.\n * To be followed by a getCache method * \param handleArray input: Array of handles to conduit object * \param nelem input: Size of array * \param statusArray output: Status array reporting from each get(handle) * \return overallStatus ICAFE_NORMAL if all OK else the first ECAFE error encountered */ int CAFE::get(const unsigned int *handleArray, unsigned int nelem, \ int *statusArray) { #define __METHOD__ "CAFE::get(unsigned int * handleArray, unsigned int nelem)" int overallStatus=ICAFE_NORMAL; bool isGood=true; for (unsigned int i=0; i0) { statusArray[i]=ICAFE_NORMAL; //ICAFE_HAS_MONITOR_GET_DONE_FROM_CACHE; } else { statusArray[i]=get(handleArray[i]); } if ( (statusArray[i] != ICAFE_NORMAL) && isGood) { overallStatus=statusArray[i]; isGood=false; } } // flush now! //ca_flush_io(); //flush in get return overallStatus; // report first failure in return statement #undef __METHOD__ }; /** * Sets data as packaged in the PVDataHolder class * \param pv input: pv name * \param pvd in/output: PVDataHolder * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, PVDataHolder & pvd) { #define __METHOD__ "CAFE::set(const char *, PVDataHolder & pvd)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) {status= CAFE::set(handle, pvd);} return status; #undef __METHOD__ } /** * Sets data as packaged in the PVDataHolder class * \param handle input: handle to Conduit object * \param pvd input/output: PVDataHolder containing data * \return ICAFE_NORMAL if all OK */ int CAFE::set(const unsigned int handle, PVDataHolder & pvd) { #define __METHOD__ "CAFE::set(unsigned int handle, PVDataHolder & pvd)" status=ICAFE_NORMAL; bool changeNelemFlag=false; unsigned int nelemPrevious=1; pvd.alarmStatus=-1; pvd.alarmSeverity=-1; pvd.ts.secPastEpoch=0; pvd.ts.nsec=0; pvd.status=ICAFE_NORMAL; cafeConduit_set_by_handle & handle_index = cs.get (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) { channelRequestMetaDataClient= (*it_handle).getChannelRequestMetaDataClient(); //cout << __METHOD__ << " pvd.getNelem() " << pvd.getNelem() << endl; //cout << " channelRequestMetaDataClient.getNelem() " << channelRequestMetaDataClient.getNelem() << endl; //cout << " channelRequestMetaDataClient.getOffset() " << channelRequestMetaDataClient.getOffset() << endl; if (pvd.getNelem() != (channelRequestMetaDataClient.getNelem() - channelRequestMetaDataClient.getOffset() )) { nelemPrevious=channelRequestMetaDataClient.getNelem(); //Do NOT*** add offset to this! //This will extend the buffer to beyond the alloted size. Offsets are for READ only! channelRequestMetaDataClient.setNelem(pvd.getNelem()); // +channelRequestMetaDataClient.getOffset()); No offset as this is for put!!! if(MUTEX){cafeMutex.lock();} //lock handle_index.modify(it_handle, change_channelRequestMetaDataClient(channelRequestMetaDataClient)); if(MUTEX){cafeMutex.unlock();} //unlock changeNelemFlag=true; } bool soFarSoGood=true; //Find Native DataType if ( soFarSoGood && (status=cafeGranules.channelVerifyPut(handle, pvd.dataType)) != ICAFE_NORMAL) { pvd.status=status; soFarSoGood=false; } if ( soFarSoGood && (status=cafeGranules.channelPreparePut(handle)) != ICAFE_NORMAL) { pvd.status=status; soFarSoGood=false; } if (!soFarSoGood) { if(MUTEX){cafeMutex.lock();}; //lock handle_index.modify(it_handle, change_status(status)); if(MUTEX){cafeMutex.unlock();}; //unlock if(changeNelemFlag) { channelRequestMetaDataClient.setNelem(nelemPrevious); //handleHelper.getNelemNative(handle)); if(MUTEX){cafeMutex.lock();} //lock handle_index.modify(it_handle, change_channelRequestMetaDataClient(channelRequestMetaDataClient)); if(MUTEX){cafeMutex.unlock();} //unlock } return status; } pvd.dbrDataType= ((*it_handle).getChannelRequestMetaPrimitive().getDbrDataType()); switch ((*it_handle).getChannelRequestMetaPrimitive().getDbrDataType()) { case DBR_STRING: status=renderString.putString(handle, pvd.val.get()); break; case DBR_SHORT: status=renderShort.put(handle, pvd.val.get(), pvd.dataType); break; case DBR_FLOAT: status=renderFloat.put(handle, pvd.val.get(), pvd.dataType); break; case DBR_ENUM: status=renderEnum.put (handle, pvd.val.get(), pvd.dataType); break; case DBR_CHAR: status=renderChar.put (handle, pvd.val.get(), pvd.dataType); break; case DBR_LONG: status=renderLong.put (handle, pvd.val.get(), pvd.dataType); break; case DBR_DOUBLE: status=renderDouble.put(handle, pvd.val.get(), pvd.dataType); break; default: cout << "ERROR: " << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; cafeStatus.report(ECAFE_INVALID_SWITCH_CASE); cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" << pvd.dataType < (); cafeConduit_set_by_handle::iterator it_handle; for (unsigned int i=0; i (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) { unsigned int c=(*it_handle).getChannelRequestMetaDataClient().getNelem(); unsigned int n=(*it_handle).getChannelRegalia().getNelem(); //cout << "c: " << c << " n: " << n << endl; dbr_char_t * val = new dbr_char_t[min(c,n)]; //dbr_char_t * val = new dbr_char_t[n]; status=cafeCappuccino.get(handle, DBR_CHAR, val); psWF = ""; chtype cdt; handleHelper.getDataTypeNative(handle, cdt); unsigned int r=(*it_handle).getChannelRequestMetaData().getNelem(); if (cdt==DBR_CHAR) { for (unsigned int i=0; i (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) { unsigned int c=(*it_handle).getChannelRequestMetaDataClient().getNelem(); unsigned int n=(*it_handle).getChannelRegalia().getNelem(); unsigned int r =min( (*it_handle).getChannelRequestMetaData().getNelemCache(), ((*it_handle).getChannelRequestMetaData().getNelem()-(*it_handle).getChannelRequestMetaData().getOffset()) ) ; //cout << "Cache c: " << c << " r: " << r << " n: " << n << endl; dbr_char_t * val = new dbr_char_t[min(r,n)]; //dbr_char_t * val = new dbr_char_t[n]; status=cafeCappuccino.getCache(handle, DBR_CHAR, val); psWF = ""; chtype cdt; handleHelper.getDataTypeNative(handle, cdt); //unsigned int r=(*it_handle).getChannelRequestMetaData().getNelem(); //r=(*it_handle).getNelemToRetrieveFromCache(); if (cdt==DBR_CHAR) { for (unsigned int i=0; i1) { nelemRequestedCheck = handleHelper.setNelemToRetrieveFromCache(handle,nelemRequested); if (nelemRequestedCheck != nelemRequested) { cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " << nelemPrevious << endl; cout << "to: " << nelemRequested << " but got instead: " << nelemRequestedCheck << endl; } } return nelemPrevious; #undef __METHOD__ } /** * Helper function to methods calling scalars * Sets number of elements to retrieve from cache to the "previous" number * \param handle input: handle to Conduit object * \param nelemPrevious input: nelem to set * \return nelements actually set (should equal nelemPrevious) */ unsigned int CAFE::setNelemToRetrieveFromCacheToPrevious(const unsigned int handle, \ unsigned int nelemPrevious) { #define __METHOD__ \ "int CAFE::setNelemToRetrieveFromCacheToPrevious(unsigned int handle, unsigned int nelemPrevious)" unsigned int nelemPreviousCheck=0; unsigned int nelemRequested=1; //Switch back to previous value if (nelemPrevious>0) { nelemPreviousCheck= handleHelper.setNelemToRetrieveFromCache(handle,nelemPrevious); if (nelemPreviousCheck != nelemPrevious) { cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: " << nelemRequested << endl; cout << "to the previous: " << nelemPrevious << " but got instead: " << nelemPreviousCheck << endl; } } return nelemPreviousCheck; #undef __METHOD__ } /** * Helper function to methods calling scalars * Sets number of elements to one * \param handle input: handle to Conduit object * \return nelements previous to the set */ unsigned int CAFE::setNelemToOne(const unsigned int handle) { #define __METHOD__ "int CAFE::setNelemToOne(const unsigned int handle)" unsigned int nelemPrevious, nelemRequestedCheck=0; unsigned int nelemRequested=1; nelemPrevious=handleHelper.getNelemClient(handle); //Check the number of elements requested? if (nelemPrevious>1) { nelemRequestedCheck = handleHelper.setNelem(handle,nelemRequested); if (nelemRequestedCheck != nelemRequested) { cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: " << nelemPrevious << endl; cout << "to: " << nelemRequested << " but got instead: " << nelemRequestedCheck << endl; } } return nelemPrevious; #undef __METHOD__ } /** * \brief Helper function to methods calling scalars * Sets number of elements to the "previous" number * \param handle input: handle to Conduit object * \param nelemPrevious input: nelem to set * \return nelements actually set (should equal nelemPrevious) */ unsigned int CAFE::setNelemToPrevious(const unsigned int handle, \ unsigned int nelemPrevious) { #define __METHOD__ \ "int CAFE::setNelemToPrevious(unsigned int handle, unsigned int nelemPrevious)" unsigned int nelemPreviousCheck=nelemPrevious; unsigned int nelemRequested=1; //Switch back to previous value //if (nelemPrevious>1) { //Apr 2015: Change from getNelemRequest(handle) to getNelemClient //This is because nelemClient(handle) also used by set methods! if(handleHelper.getNelemClient(handle)!= nelemPrevious) { nelemPreviousCheck= handleHelper.setNelem(handle,nelemPrevious); if (nelemPreviousCheck != nelemPrevious) { if (nelemPreviousCheck != handleHelper.getNelemNative(handle)) { cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: " << nelemRequested << endl; cout << "to the previous: " << nelemPrevious << " but got instead: " << nelemPreviousCheck << endl; cout << "No of native elements is " << handleHelper.getNelemNative(handle) << endl; } } } return nelemPreviousCheck; #undef __METHOD__ } /** * Set long long * \param handle input: handle to Conduit object * \param val input: array of double * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(unsigned int handle, const long long * val) { //5+ long long #define __METHOD__ \ "CAFE::set(unsigned int handle, const long long * _val)" ChannelRegalia channelInfo; CAFE::getChannelInfo(handle, channelInfo); if ( channelInfo.getCafeConnectionState() == ICAFE_CS_NEVER_CONN) { return ICAFE_CS_NEVER_CONN; } int _status=ICAFE_NORMAL; unsigned int nn=handleHelper.getNelemNative(handle); if ( channelInfo.getDataType() == DBR_STRING) { dbr_string_t * _sVal = new dbr_string_t[nn]; //Convert long long to string; for (unsigned int i=0; i < handleHelper.getNelemClient(handle); ++i) { std::stringstream ss; ss.clear(); ss << val[i]; strcpy(_sVal[i] , ss.str().c_str()); } _status=cafeSoluble.set (handle, DBR_STRING, _sVal); delete [] _sVal; } else if ( channelInfo.getDataType() == DBR_DOUBLE) { dbr_double_t * _dVal = new dbr_double_t[nn]; for (unsigned int i=0; i < handleHelper.getNelemClient(handle); ++i) { _dVal[i] = (double) val[i]; } _status=cafeDoppio.set (handle, DBR_DOUBLE, _dVal); delete [] _dVal; } else if ( channelInfo.getDataType() == DBR_FLOAT) { dbr_float_t * _fVal = new dbr_float_t[nn]; for (unsigned int i=0; i < handleHelper.getNelemClient(handle); ++i) { _fVal[i] = (float) val[i]; } _status=cafeFrappuccino.set (handle, DBR_FLOAT, _fVal); delete [] _fVal; } else { dbr_long_t * _lVal = new dbr_long_t[nn]; for (unsigned int i=0; i < handleHelper.getNelemClient(handle); ++i) { _lVal[i] = (dbr_long_t) val[i]; } _status=cafeLatte.set (handle, DBR_LONG, _lVal); delete [] _lVal; } return _status; #undef __METHOD__ } /** * Set double(s) * \param pv input: pv name * \param val input: array of double * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_double_t * val) { //6 #define __METHOD__ "CAFE::set(const char *, dbr_double_t * val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { status=CAFE::cafeDoppio.set((const unsigned int) handle, DBR_DOUBLE, val);} return status; #undef __METHOD__ } /** * Set long long(s) * \param pv input: pv name * \param val input: array of long long * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const long long * val) { //5+ long long #define __METHOD__ "CAFE::set(const char *, long long * val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { status=CAFE::set((const unsigned int) handle, val);} return status; #undef __METHOD__ } /** * Set dbr_long_t(s) * \param pv input: pv name * \param val input: array of dbr_long_t * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_long_t * val) { //5 #define __METHOD__ "CAFE::set(const char *, dbr_long_t * val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { status=CAFE::cafeLatte.set((const unsigned int) handle, DBR_LONG, val);} return status; #undef __METHOD__ } /** * Set unsigned char(s) * \param pv input: pv name * \param val input: array of dbr_char_t (unsigned char) * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_char_t * val) { //4 #define __METHOD__ "CAFE::set(const char *, dbr_char_t * val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { status=CAFE::cafeCappuccino.set((const unsigned int) handle, DBR_CHAR, val);} return status; #undef __METHOD__ } /** * Set dbr_enum_t(s) * \param pv input: pv name * \param val input: array ofdbr_enum_t (unsigned short) * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_enum_t * val) { //3 #define __METHOD__ "CAFE::set(const char *, dbr_enum_t * val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { status=CAFE::cafeEspresso.set((const unsigned int) handle, DBR_ENUM, val);} return status; #undef __METHOD__ } /** * Set float(s) * \param pv input: pv name * \param val input: array of float * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_float_t * val) { //2 #define __METHOD__ "CAFE::set(const char *, dbr_float_t * val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { status=CAFE::cafeFrappuccino.set((const unsigned int) handle, DBR_FLOAT, val);} return status; #undef __METHOD__ } /** * Set short(s) * \param pv input: pv name * \param val input: array of dbr_short_t (signed short) * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_short_t * val) { //1 #define __METHOD__ "CAFE::set(const char *, dbr_short_t * val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { status=CAFE::cafeSchale.set((const unsigned int) handle, DBR_SHORT, val);} return status; #undef __METHOD__ } /** * Set dbr_string_t(s) * \param pv input: pv name * \param val input: array of dbr_string_t (char[40]) * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_string_t * val) { //0 #define __METHOD__ "CAFE::set(const char *, dbr_string_t * val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { status=CAFE::cafeSoluble.set((const unsigned int) handle, DBR_STRING, val);} return status; #undef __METHOD__ } /** * Set dbr_double_t * \param pv input: pv name * \param _val input: dbr_double_t * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_double_t _val) { //6 #define __METHOD__ "CAFE::set(const char *, dbr_double_t val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { unsigned int nelemPrevious=CAFE::setNelemToOne(handle); dbr_double_t val[1]; val[0]= _val; status=CAFE::cafeDoppio.set((const unsigned int) handle, DBR_DOUBLE, val); CAFE::setNelemToPrevious(handle, nelemPrevious); } return status; #undef __METHOD__ } /** * Set long long * \param pv input: pv name * \param _val input:long long * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const long long _val) { //5+ long long #define __METHOD__ "CAFE::set(const char *, long long val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { unsigned int nelemPrevious=CAFE::setNelemToOne(handle); dbr_long_t val[1]; val[0]= _val; status=CAFE::set((const unsigned int) handle, val); CAFE::setNelemToPrevious(handle, nelemPrevious); } return status; #undef __METHOD__ } /** * Set dbr_long_t * \param pv input: pv name * \param _val input: dbr_long_t * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_long_t _val) { //5 #define __METHOD__ "CAFE::set(const char *, dbr_long_t val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { unsigned int nelemPrevious=CAFE::setNelemToOne(handle); dbr_long_t val[1]; val[0]= _val; status=CAFE::cafeLatte.set((const unsigned int) handle, DBR_LONG, val); CAFE::setNelemToPrevious(handle, nelemPrevious); } return status; #undef __METHOD__ } /** * Set dbr_char_t (unsigned char) * \param pv input: pv name * \param _val input: dbr_char_t * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_char_t _val) { //34 #define __METHOD__ "CAFE::set(const char *, dbr_char_t val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { unsigned int nelemPrevious=CAFE::setNelemToOne(handle); dbr_char_t val[1]; val[0]= _val; status=CAFE::cafeCappuccino.set((const unsigned int) handle, DBR_CHAR, val); CAFE::setNelemToPrevious(handle, nelemPrevious); } return status; #undef __METHOD__ } /** * Set dbr_enum_t (unsigned short) * \param pv input: pv name * \param _val input: dbr_enum_t * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_enum_t _val) { //3 #define __METHOD__ "CAFE::set(const char *, dbr_enum_t val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { unsigned int nelemPrevious=CAFE::setNelemToOne(handle); dbr_enum_t val[1]; val[0]= _val; status=CAFE::cafeEspresso.set((const unsigned int) handle, DBR_ENUM, val); CAFE::setNelemToPrevious(handle, nelemPrevious); } return status; #undef __METHOD__ } /** * Set dbr_float_t * \param pv input: pv name * \param _val input: dbr_float_t * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_float_t _val) { //1 #define __METHOD__ "CAFE::set(const char *, dbr_float_t val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { unsigned int nelemPrevious=CAFE::setNelemToOne(handle); dbr_float_t val[1]; val[0]= _val; status=CAFE::cafeFrappuccino.set((const unsigned int) handle, DBR_FLOAT, val); CAFE::setNelemToPrevious(handle, nelemPrevious); } return status; #undef __METHOD__ } /** * Set dbr_short_t * \param pv input: pv name * \param _val input: dbr_short_t * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_short_t _val) { //0 #define __METHOD__ "CAFE::set(const char *, dbr_short_t val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { unsigned int nelemPrevious=CAFE::setNelemToOne(handle); dbr_short_t val[1]; val[0]= _val; status=CAFE::cafeSchale.set((const unsigned int) handle, DBR_SHORT, val); CAFE::setNelemToPrevious(handle, nelemPrevious); } return status; #undef __METHOD__ } /** * Set dbr_string_t * \param pv input: pv name * \param _val input: dbr_string_t (char[40]) * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::set(const char * pv, const dbr_string_t _val) { //0 #define __METHOD__ "CAFE::set(const char *, dbr_string_t val)" unsigned int handle; status=ICAFE_NORMAL; try {status = open(pv, handle);} catch (CAFEException_open & e) {return e.pvEx.statusCode;} if (status == ICAFE_NORMAL) { unsigned int nelemPrevious=CAFE::setNelemToOne(handle); dbr_string_t val[1]; sprintf(val[0],"%s", _val); status=CAFE::cafeSoluble.set((const unsigned int) handle, DBR_STRING, val); CAFE::setNelemToPrevious(handle, nelemPrevious); } return status; #undef __METHOD__ } /** * waitForPut * \param h input: Array of hanldes * \param nelem input:No of elements in Array * \return ECA_NORMAL if all OK else ECAFE error */ int CAFE::waitForPut(const unsigned int *h, const unsigned int nelem) { ca_flush_io(); status=ICAFE_NORMAL; bool isGood=true; int overallStatus=status; cafeConduit_set_by_handle & handle_index = cs.get (); cafeConduit_set_by_handle::iterator it_handle; ChannelTimeoutPolicy channelTimeoutPolicyPut; for (unsigned int i=0; i reporting from: void CAFE::loadSFGroups(string suff) <--- " << endl; //Test for file directory string fName=""; char * p= NULL; char const* d = "OMC.py"; bool isFile=false; ifstream ifile; if(std::getenv("SFEL_LAYOUT_PYTHONPATH") == NULL){ cout << "SFEL_LAYOUT_PYTHONPATH is not defined, thus may be missing from PYTHONPATH" << endl; //putenv((char *) "SFEL_LAYOUT_PYTHONPATH=/afs/psi.ch/intranet/SF/Applications/on-line_model/default/scripts/VA"); //putenv((char *) "PYTHONPATH=/afs/psi.ch/intranet/SF/Applications/on-line_model/default/scripts/VA"); } //if(std::getenv("PYTHONPATH") != NULL){ // char * pp= std::getenv("PYTHONPATH"); // cout << "PYTHONPATH=" << pp << endl; //} //if(std::getenv("SFEL_LAYOUT_PYTHONPATH") != NULL){ // char * ll= std::getenv("PYTHONPATH"); // cout << "SFEL_LAYOUT_PYTHONPATH=" << ll << endl; //} if(std::getenv("SFEL_OMC_PYTHONPATH") != NULL){ p = std::getenv("SFEL_OMC_PYTHONPATH"); } if (p != NULL) { fName.append(p); fName.append("/"); fName.append(d); ifile.open(fName.c_str(),ios::in); if (ifile.good()) { ifile.close(); isFile=true; } } if (!isFile) { fName=""; fName.append("/afs/psi.ch/intranet/SF/Applications/on-line_model/default/PythonModule") ; std::cout << "Did not find file in $SFEL_OMC_PYTHONPATH " << std::endl; std::cout << "therefore using the following default directory: " << std::endl; std::cout << fName.c_str() << std::endl; fName.append("/"); fName.append(d); ifile.open(fName.c_str(),ios::in); if (ifile.good()) { ifile.close(); isFile=true; } else { std::cout << "Error opening default file: " << fName.c_str() << std::endl; } } // No luck with finding OMC.py if (!isFile) { return;} if (! Py_IsInitialized () ) { cout << "INITIALIZING PY IN CAFE" << endl; Py_Initialize(); } //Py_Initialize(); //PyEval_InitThreads(); globalChannelList.clear(); globalChannelList.reserve(9000); PyObject* psys = PyImport_ImportModule( "sys" ); if (psys==NULL) { cout << "PSYS IS NULL " << endl; } PyObject* psys_path = PyObject_GetAttrString( psys, "path" ); if (psys_path==NULL) { cout << "PSYS PATH IS NULL " << endl; } PyObject* folder_path = PyUnicode_FromString( fName.c_str()); //"/afs/psi.ch/intranet/SF/Applications/Development/OnlineModel/PythonModule" ); if (folder_path==NULL) { cout << "FOLDER PATH IS NULL " << endl; } PyList_Append( psys_path, folder_path ); //Py_DECREF(folder_path); // Load module, class and object PyObject *mymod, *pclass, *pobject; //cout << fName.c_str() << endl; //cout << " PY VERSION " << PY_MAJOR_VERSION << endl; mymod = PyImport_ImportModule("OMC"); if (mymod==NULL) { cout << " MYMOD IS NULL. Printing Error: " << endl; PyErr_Print() ; return; } pclass = PyObject_GetAttrString(mymod, "OMC"); if (pclass==NULL) { cout << " pClass IS NULL " << endl; PyErr_Print() ; return; } PyObject *pmethod, *pargs, *pret; pargs=NULL; //pobject = PyEval_CallObject(pclass,pargs); pobject = PyObject_CallObject(pclass,pargs); if (pobject==NULL) { cout << " pobject IS NULL " << endl; PyErr_Print() ; return; } pmethod = PyObject_GetAttrString(pobject, "initFunction"); if (pmethod==NULL) { cout << " pobject IS NULL " << endl; PyErr_Print() ; return; } //Required for Python3 pargs=Py_BuildValue("(s)", suff.c_str()); //pargs=Py_BuildValue("s",(suff.c_str())); if (pargs==NULL) { cout << " pargs IS NULL " << endl; PyErr_Print() ; } // PyObject * temp = PyUnicode_AsEncodedString(pargs, "ASCII", "strict"); //PyObject * my_pargs = PyBytes_AS_STRING(temp); // Borrowed pointer //my_pargs = strdup(my_pargs); //pret=PyEval_CallObject(pmethod,PyObject(pargs)); //pret=PyObject_CallFunction(pmethod, "s", suff.c_str()); pret=PyObject_CallObject(pmethod, pargs); if (pret==NULL) { cout << " pret IS NULL / " << endl; PyErr_Print() ; return; } //if (PyTuple_Check(pret)) { // cout << "pret ia a TUPLE " << endl; //} string GroupName; vector ChannelList; PyObject *plist1, *plist2, *plist3, *plist4; int i,j,li; long lj; //cout << "PyArg_ParseTuple(pret, 'iOOO', &li,&plist1, &plist2, &plist3);" << endl; if (!PyArg_ParseTuple(pret, "iOOO", &li,&plist1, &plist2, &plist3)) { cout << "is NULL " << endl; return; } /* if (PyUnicode_Check(plist2)) { // Convert string to bytes. // strdup() bytes into my_result. cout << "UNICODE " << endl; } else if (PyBytes_Check(plist2)) { // strdup() bytes into my_result. cout << "BYTES " << endl; } else if (PyTuple_Check(plist2)) { cout << "TUPLE " << endl; } else if (PyList_Check(plist2)) { cout << "List " << endl; } else if (PyByteArray_Check(plist2)) { cout << "PyByteArray " << endl; } else if (PyDict_Check(plist2)) { cout << "PyDict " << endl; } else if (PyDictKeys_Check(plist2)) { cout << "PyDict_Keys " << endl; } else if (PyMemoryView_Check(plist2)) { cout << "PymemoryView " << endl; } else if (PyModule_Check(plist2)) { cout << "PyModule " << endl; } else if (PyCell_Check(plist2)) { // strdup() bytes into my_result. cout << "PyCell " << endl; } else { // Convert into your favorite string representation. // Convert string to bytes if it is not already. // strdup() bytes into my_result. cout << "SOMEOT ELSE " << endl; } if (PyList_Check(plist1)) { // strdup() bytes into my_result. cout << "PyList check for plist1 is OK " << endl; } if (PyDictValues_Check(plist3)) { // strdup() bytes into my_result. cout << "PyList check for plist1 is OK " << endl; } */ //Py_ssize_t pli; //pli=PyList_Size(plist1); // This causes segfault for some reason... //printf("length%i\n",li); PyObject *ps, *pyi; string mystr; //Check type of pList1 etc... if (plist1 == NULL ) { cout << "pList1 is NULL" << endl; } if (plist2 == NULL ) { cout << "pList2 is NULL" << endl; } if (plist3 == NULL ) { cout << "pList3 is NULL" << endl; } //if HAVE_LIBQTXML CAFE::openGroupXMLFile("/tmp/test.xml"); //endif //cout << PY_MAJOR_VERSION << endl; for (i=0; i= 3 mystr=PyUnicode_AsUTF8(ps); #elif PY_MAJOR_VERSION < 3 mystr=PyString_AsString(ps); #endif //printf("Channel Name: %s\n",mystr.c_str()); //printf("Channel %d Name: %s\n",j, mystr.c_str()); ChannelList.push_back (mystr); globalChannelList.push_back(mystr); } //cafefunction.grouping(GroupName,ChannelList); status=CAFE::groupDefine(GroupName.c_str(), ChannelList); if (status != ICAFE_NORMAL) { CAFE::printStatusMessage(status); } //if HAVE_LIBQTXML CAFE::group2XML(GroupName.c_str(), "/tmp/test.xml"); //endif } //if HAVE_LIBQTXML CAFE::closeGroupXMLFile("/tmp/test.xml"); //endif /* cout << "psys = " << (psys->ob_refcnt) << endl; cout << "psys_path = " << (psys_path->ob_refcnt) << endl; cout << "folder_path = " << (folder_path->ob_refcnt) << endl; cout << "mymod = " << (mymod->ob_refcnt) << endl; cout << "pclass = " <<(pclass->ob_refcnt) << endl; cout << "pobject = " << (pobject->ob_refcnt) << endl; cout << "pmethod = " << (pmethod->ob_refcnt) << endl; cout << "pargs = " << (pargs->ob_refcnt) << endl; cout << "pret = " <<(pret->ob_refcnt) << endl; cout << "plist1 = " << (plist1->ob_refcnt) << endl; cout << "plist2 = " << (plist2->ob_refcnt) << endl; cout << "plist3 = " << (plist3->ob_refcnt) << endl; cout << "plist4 = " << (plist4->ob_refcnt) << endl; cout << "ps = " << (ps->ob_refcnt) << endl; cout << "pyi = " << (pyi->ob_refcnt) << endl; */ Py_DECREF(psys); Py_DECREF(psys_path); Py_DECREF(folder_path); Py_DECREF(mymod); Py_DECREF(pclass); Py_DECREF(pobject); if (pargs !=NULL) { Py_DECREF(pargs); } Py_DECREF(pret); //Cannot Py_DECREF(pmethod) in Python3 ! //if (pmethod !=NULL) { // Py_DECREF(pmethod); //} //Py_DECREF(plist1); //Py_DECREF(plist2); //Py_DECREF(plist3); //Py_DECREF(plist4); //RELATED TO PLIST3 //Py_DECREF(ps); //RELATED TO PLIST2 //Py_DECREF(pyi); //related to plist1 //Py_Finalize(); // No! /* //Note some of these objects will no longer exist after decref cout << "psys = " << (psys->ob_refcnt) << endl; cout << "psys_path = " << (psys_path->ob_refcnt) << endl; cout << "folder_path = " << (folder_path->ob_refcnt) << endl; cout << "mymod = " << (mymod->ob_refcnt) << endl; cout << "pclass = " <<(pclass->ob_refcnt) << endl; cout << "pobject = " << (pobject->ob_refcnt) << endl; cout << "pmethod = " << (pmethod->ob_refcnt) << endl; cout << "pargs = " << (pargs->ob_refcnt) << endl; cout << "pret = " <<(pret->ob_refcnt) << endl; cout << "plist1 = " << (plist1->ob_refcnt) << endl; cout << "plist2 = " << (plist2->ob_refcnt) << endl; cout << "plist3 = " << (plist3->ob_refcnt) << endl; cout << "plist4 = " << (plist4->ob_refcnt) << endl; cout << "ps = " << (ps->ob_refcnt) << endl; cout << "pyi = " << (pyi->ob_refcnt) << endl; */ return; } #endif /* #if HAVE_PYTHON_H void CAFE::loadSFGroups(string suff) { Py_Initialize(); PyEval_InitThreads(); cout << " HERE " << endl; PyObject* psys = PyImport_ImportModule( "sys" ); // cout << " HERE2a " << endl; PyObject* psys_path = PyObject_GetAttrString( psys, "path" ); PyObject* folder_path = PyUnicode_FromString( "/afs/psi.ch/intranet/SF/Applications/Development/OnlineModel/PythonModule" ); //PyObject* folder_path = PyUnicode_FromString( "/afs/psi.ch/intranet/SF/Applications/Development/Masa/git/PythonModule" ); PyList_Append( psys_path, folder_path ); // Load module, class and object PyObject *mymod, *pclass, *pobject; cout << " HERE2b " << endl; mymod = PyImport_ImportModule("OMC"); cout << " HERE2c " << endl; pclass = PyObject_GetAttrString(mymod, "OMC"); cout << " HERE2d " << endl; PyObject *pmethod, *pargs, *pret; pargs=NULL; pobject = PyEval_CallObject(pclass,pargs); cout << " HERE3 " << endl; pmethod = PyObject_GetAttrString(pobject, "initFunction"); pargs=Py_BuildValue("(s)", suff.c_str()); // cout << " HERE4 " << endl; pret=PyEval_CallObject(pmethod,pargs); // cout << " HERE5 " << endl; string GroupName; vector ChannelList; PyObject *plist1, *plist2, *plist3, *plist4; int i,j,li; long lj; PyArg_ParseTuple(pret, "iOOO", &li,&plist1, &plist2, &plist3); // cout << " HERE6 " << endl; //Py_ssize_t pli; //pli=PyList_Size(plist1); // This causes segfault for some reason... //printf("length%i\n",li); PyObject *ps, *pyi; string mystr; CAFE::openGroupXMLFile("/tmp/test.xml"); //cout << " HERE7 " << endl; for (i=0; i