diff --git a/configure/RELEASE b/configure/RELEASE index 52bc6fd..91ce9d3 100644 --- a/configure/RELEASE +++ b/configure/RELEASE @@ -34,8 +34,8 @@ TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top # do not edit the locations in this file # create RELEASE.local with the paths to your EPICS_BASE and PVDATA -PVDATA=/home/mrk/hg/pvDataCPP -EPICS_BASE=/home/install/epics/base +#PVDATA=/home/mrk/hg/pvDataCPP +#EPICS_BASE=/home/install/epics/base # Set RULES here if you want to take build rules from somewhere # other than EPICS_BASE: diff --git a/pvAccessApp/client/pvAccess.h b/pvAccessApp/client/pvAccess.h index 4a9d7b5..613e77d 100644 --- a/pvAccessApp/client/pvAccess.h +++ b/pvAccessApp/client/pvAccess.h @@ -780,7 +780,7 @@ namespace pvAccess { * @author mse * */ - class CreateRequest : private epics::pvData::NoDefaultMethods { + class CreateRequest { public: POINTER_DEFINITIONS(CreateRequest); @@ -793,7 +793,9 @@ namespace pvAccess { * @param requester The requester; * @return The request structure if an invalid request was given. */ - virtual epics::pvData::PVStructure::shared_pointer createRequest(epics::pvData::String request) = 0; + virtual epics::pvData::PVStructure::shared_pointer createRequest( + epics::pvData::String request, + epics::pvData::Requester::shared_pointer const & requester) = 0; }; extern CreateRequest::shared_pointer getCreateRequest(); diff --git a/pvAccessApp/factory/CreateRequestFactory.cpp b/pvAccessApp/factory/CreateRequestFactory.cpp index 7665a64..869b74a 100644 --- a/pvAccessApp/factory/CreateRequestFactory.cpp +++ b/pvAccessApp/factory/CreateRequestFactory.cpp @@ -11,208 +11,272 @@ #include using namespace epics::pvData; +using std::tr1::static_pointer_cast; + namespace epics { namespace pvAccess { +static PVDataCreatePtr pvDataCreate = getPVDataCreate(); + class CreateRequestImpl : public CreateRequest { private: - static void trim(std::string& str) - { - std::string::size_type pos = str.find_last_not_of(' '); - if(pos != std::string::npos) { - str.erase(pos + 1); - pos = str.find_first_not_of(' '); - if(pos != std::string::npos) str.erase(0, pos); - } - else str.erase(str.begin(), str.end()); - } + static void trim(String& str) + { + String::size_type pos = str.find_last_not_of(' '); + if(pos != String::npos) { + str.erase(pos + 1); + pos = str.find_first_not_of(' '); + if(pos != String::npos) str.erase(0, pos); + } + else str.erase(str.begin(), str.end()); + } - static size_t findMatchingBrace(std::string& request, int index, int numOpen) { - size_t openBrace = request.find('{', index+1); - size_t closeBrace = request.find('}', index+1); - if(openBrace == std::string::npos && closeBrace == std::string::npos) return std::string::npos; - if (openBrace != std::string::npos) { - if(openBraceopenBrace)) { - //find matching brace - size_t closeBrace = findMatchingBrace(request,openBrace+1,1); - if(closeBrace==std::string::npos) { - THROW_BASE_EXCEPTION("mismatched { }"); - } - String fieldName = request.substr(0,openBrace); + static std::vector split(String commaSeparatedList) { + String::size_type numValues = 1; + String::size_type index=0; + while(true) { + String::size_type pos = commaSeparatedList.find(',',index); + if(pos==String::npos) break; + numValues++; + index = pos +1; + } + std::vector valueList(numValues,""); + index=0; + for(size_t i=0; icreatePVStructure(fieldNames, fields)); - createFieldRequest(pvStructure,request.substr(openBrace+1,closeBrace-openBrace-1),false); - pvParent->appendPVField(fieldName, pvStructure); - if(request.length()>closeBrace+1) { - if(request.at(closeBrace+1) != ',') { - THROW_BASE_EXCEPTION("misssing , after }"); - } - createFieldRequest(pvParent,request.substr(closeBrace+2),false); - } - return; - } - if(openBracket==std::string::npos && fieldListOK) { - PVStringPtr pvStringField(std::tr1::static_pointer_cast(getPVDataCreate()->createPVScalar(pvString))); - pvStringField->put(request); - pvParent->appendPVField("fieldList", pvStringField); - return; - } - if(openBracket!=std::string::npos && (comma==std::string::npos || comma>openBracket)) { - size_t closeBracket = request.find(']'); - if(closeBracket==std::string::npos) { - THROW_BASE_EXCEPTION("option does not have matching []"); - } - createLeafFieldRequest(pvParent,request.substr(0, closeBracket+1)); - size_t commaLoc = request.rfind(','); - if(commaLoc!=std::string::npos && commaLoc>closeBracket) { - int nextComma = request.find(',', closeBracket); - createFieldRequest(pvParent,request.substr(nextComma+1),false); - } - return; - } - if(comma!=std::string::npos) { - createLeafFieldRequest(pvParent,request.substr(0, comma)); - createFieldRequest(pvParent,request.substr(comma+1),false); - return; - } - createLeafFieldRequest(pvParent,request); - } - static void createLeafFieldRequest(PVStructurePtr const & pvParent,String request) { - size_t openBracket = request.find('['); - String fullName = request; - if(openBracket != std::string::npos) fullName = request.substr(0,openBracket); - size_t indLast = fullName.rfind('.'); - String fieldName = fullName; - if(indLast>1 && indLast != std::string::npos) fieldName = fullName.substr(indLast+1); - PVFieldPtrArray fields; - StringArray fieldNames; - PVStructurePtr pvStructure(getPVDataCreate()->createPVStructure(fieldNames, fields)); - PVStructurePtr pvLeaf(getPVDataCreate()->createPVStructure(fieldNames, fields)); - PVStringPtr pvStringField(std::tr1::static_pointer_cast(getPVDataCreate()->createPVScalar(pvString))); - pvStringField->put(fullName); - pvLeaf->appendPVField("source", pvStringField); - if(openBracket != std::string::npos) { - size_t closeBracket = request.find(']'); - if(closeBracket==std::string::npos) { - THROW_BASE_EXCEPTION("option does not have matching []"); - } - createRequestOptions(pvLeaf,request.substr(openBracket+1, closeBracket-openBracket-1)); - } - pvStructure->appendPVField("leaf", pvLeaf); - pvParent->appendPVField("fieldName", pvStructure); - } + static bool createRequestOptions( + PVStructurePtr const & pvParent, + String request, + Requester::shared_pointer const & requester) + { + trim(request); + if(request.length()<=1) return true; + std::vector items = split(request); + size_t nitems = items.size(); + StringArray fieldNames; + PVFieldPtrArray pvFields; + fieldNames.reserve(nitems); + pvFields.reserve(nitems); + for(size_t j=0; jmessage(item + " illegal option", errorMessage); - static void createRequestOptions(PVStructurePtr const & pvParent,std::string request) { - trim(request); - if(request.length()<=1) return; + return false; + } + String name = item.substr(0,equals); + String value = item.substr(equals+1); + fieldNames.push_back(name); + PVStringPtr pvValue = static_pointer_cast(getPVDataCreate()->createPVScalar(pvString)); + pvValue->put(value); + pvFields.push_back(pvValue); + } + PVStructurePtr pvOptions = getPVDataCreate()->createPVStructure(fieldNames,pvFields); + pvParent->appendPVField("_options",pvOptions); + return true; + } - std::string token; - std::istringstream iss(request); - while (getline(iss, token, ',')) - { - size_t equalsPos = token.find('='); - size_t equalsRPos = token.rfind('='); - if (equalsPos != equalsRPos) - { - THROW_BASE_EXCEPTION("illegal option"); - } + static bool createFieldRequest( + PVStructurePtr const & pvParent, + String request, + Requester::shared_pointer const & requester) + { + static PVFieldPtrArray emptyFields; + static StringArray emptyFieldNames; - if (equalsPos != std::string::npos) - { - PVStringPtr pvStringField(std::tr1::static_pointer_cast(getPVDataCreate()->createPVScalar(pvString))); - pvStringField->put(token.substr(equalsPos+1)); - pvParent->appendPVField(token.substr(0, equalsPos), pvStringField); - } - } - } + trim(request); + if(request.length()<=0) return true; + size_t comma = request.find(','); + if(comma==0) { + return createFieldRequest(pvParent,request.substr(1),requester); + } + size_t openBrace = request.find('{'); + size_t openBracket = request.find('['); + PVStructurePtr pvStructure = pvDataCreate->createPVStructure(emptyFieldNames, emptyFields); + if(comma==String::npos && openBrace==std::string::npos && openBracket==std::string::npos) { + size_t period = request.find('.'); + if(period!=String::npos && period!=0) { + String fieldName = request.substr(0,period); + request = request.substr(period+1); + pvParent->appendPVField(fieldName, pvStructure); + return createFieldRequest(pvStructure,request,requester); + } + pvParent->appendPVField(request, pvStructure); + return true; + } + size_t end = comma; + if(openBrace!=String::npos && (end>openBrace || end==std::string::npos)) end = openBrace; + if(openBracket!=String::npos && (end>openBracket || end==std::string::npos)) end = openBracket; + String nextFieldName = request.substr(0,end); + if(end==comma) { + size_t period = nextFieldName.find('.'); + if(period!=String::npos && period!=0) { + String fieldName = nextFieldName.substr(0,period); + PVStructurePtr xxx= pvDataCreate->createPVStructure(emptyFieldNames, emptyFields); + String rest = nextFieldName.substr(period+1); + createFieldRequest(xxx,rest,requester); + pvParent->appendPVField(fieldName, xxx); + } else { + pvParent->appendPVField(nextFieldName, pvStructure); + } + request = request.substr(end+1); + return createFieldRequest(pvParent,request,requester); + } + if(end==openBracket) { + size_t closeBracket = request.find(']'); + if(closeBracket==String::npos || closeBracket==0) { + requester->message(request + " does not have matching ]", errorMessage); + return false; + } + String options = request.substr(openBracket+1, closeBracket-openBracket-1); + size_t period = nextFieldName.find('.'); + if(period!=String::npos && period!=0) { + String fieldName = nextFieldName.substr(0,period); + PVStructurePtr xxx = pvDataCreate->createPVStructure(emptyFieldNames, emptyFields); + if(!createRequestOptions(xxx,options,requester)) return false; + String rest = nextFieldName.substr(period+1); + createFieldRequest(xxx,rest,requester); + pvParent->appendPVField(fieldName, xxx); + } else { + if(!createRequestOptions(pvStructure,options,requester)) return false; + pvParent->appendPVField(nextFieldName, pvStructure); + } + request = request.substr(end+1); + return createFieldRequest(pvParent,request,requester); + } + // end== openBrace + size_t closeBrace = findMatchingBrace(request,openBrace+1,1); + if(closeBrace==String::npos || closeBrace==0) { + requester->message(request + " does not have matching }", errorMessage); + return false; + } + String subFields = request.substr(openBrace+1, closeBrace-openBrace-1); + if(!createFieldRequest(pvStructure,subFields,requester)) return false; + request = request.substr(closeBrace+1); + size_t period = nextFieldName.find('.'); + if(period==String::npos) { + pvParent->appendPVField(nextFieldName,pvStructure); + return createFieldRequest(pvParent,request,requester); + } + PVStructure::shared_pointer yyy = pvParent; + while(period!=String::npos && period!=0) { + String fieldName = nextFieldName.substr(0,period); + PVStructurePtr xxx = pvDataCreate->createPVStructure(emptyFieldNames, emptyFields); + yyy->appendPVField(fieldName,xxx); + nextFieldName = nextFieldName.substr(period+1); + period = nextFieldName.find('.'); + if(period==String::npos || period==0) { + xxx->appendPVField(nextFieldName, pvStructure); + break; + } + yyy = xxx; + } + return createFieldRequest(pvParent,request,requester); + } public: - virtual PVStructure::shared_pointer createRequest(String request) - { - static PVFieldPtrArray emptyFields; - static StringArray emptyFieldNames; + virtual PVStructure::shared_pointer createRequest( + String request, + Requester::shared_pointer const & requester) + { + PVFieldPtrArray pvFields; + StringArray fieldNames; + PVStructurePtr emptyPVStructure = pvDataCreate->createPVStructure(fieldNames,pvFields); + static PVStructure::shared_pointer nullStructure; - if (!request.empty()) trim(request); - if (request.empty()) - { - PVStructure::shared_pointer pvStructure(getPVDataCreate()->createPVStructure(emptyFieldNames, emptyFields)); - return pvStructure; - } - - size_t offsetRecord = request.find("record["); - size_t offsetField = request.find("field("); - size_t offsetPutField = request.find("putField("); - size_t offsetGetField = request.find("getField("); - - PVStructure::shared_pointer pvStructure(getPVDataCreate()->createPVStructure(emptyFieldNames, emptyFields)); - - if (offsetRecord != std::string::npos) { - size_t offsetBegin = request.find('[', offsetRecord); - size_t offsetEnd = request.find(']', offsetBegin); - if(offsetEnd == std::string::npos) { - THROW_BASE_EXCEPTION("record[ does not have matching ]"); - } - PVStructure::shared_pointer pvStruct(getPVDataCreate()->createPVStructure(emptyFieldNames, emptyFields)); - createRequestOptions(pvStruct,request.substr(offsetBegin+1, offsetEnd-offsetBegin-1)); - pvStructure->appendPVField("record", pvStruct); - } - if (offsetField != std::string::npos) { - size_t offsetBegin = request.find('(', offsetField); - size_t offsetEnd = request.find(')', offsetBegin); - if(offsetEnd == std::string::npos) { - THROW_BASE_EXCEPTION("field( does not have matching )"); - } - PVStructure::shared_pointer pvStruct(getPVDataCreate()->createPVStructure(emptyFieldNames, emptyFields)); - createFieldRequest(pvStruct,request.substr(offsetBegin+1, offsetEnd-offsetBegin-1),true); - pvStructure->appendPVField("field", pvStruct); - } - if (offsetPutField != std::string::npos) { - size_t offsetBegin = request.find('(', offsetPutField); - size_t offsetEnd = request.find(')', offsetBegin); - if(offsetEnd == std::string::npos) { - THROW_BASE_EXCEPTION("putField( does not have matching )"); - } - PVStructure::shared_pointer pvStruct(getPVDataCreate()->createPVStructure(emptyFieldNames, emptyFields)); - createFieldRequest(pvStruct,request.substr(offsetBegin+1, offsetEnd-offsetBegin-1),true); - pvStructure->appendPVField("putField", pvStruct); - } - if (offsetGetField != std::string::npos) { - size_t offsetBegin = request.find('(', offsetGetField); - size_t offsetEnd = request.find(')', offsetBegin); - if(offsetEnd == std::string::npos) { - THROW_BASE_EXCEPTION("getField( does not have matching )"); - } - PVStructure::shared_pointer pvStruct(getPVDataCreate()->createPVStructure(emptyFieldNames, emptyFields)); - createFieldRequest(pvStruct,request.substr(offsetBegin+1, offsetEnd-offsetBegin-1),true); - pvStructure->appendPVField("getField", pvStruct); - } - if (pvStructure.get()->getStructure()->getNumberFields()==0) { - createFieldRequest(pvStructure,request,true); - } - return pvStructure; - } + if (!request.empty()) trim(request); + if (request.empty()) + { + return emptyPVStructure; + } + size_t offsetRecord = request.find("record["); + size_t offsetField = request.find("field("); + size_t offsetPutField = request.find("putField("); + size_t offsetGetField = request.find("getField("); + PVStructurePtr pvStructure = pvDataCreate->createPVStructure(emptyPVStructure); + if (offsetRecord != String::npos) { + size_t offsetBegin = request.find('[', offsetRecord); + size_t offsetEnd = request.find(']', offsetBegin); + if(offsetEnd == String::npos) { + requester->message(request.substr(offsetRecord) + " record[ does not have matching ]", errorMessage); + return nullStructure; + } + PVStructurePtr pvStruct = pvDataCreate->createPVStructure(emptyPVStructure); + if(!createRequestOptions(pvStruct,request.substr(offsetBegin+1, offsetEnd-offsetBegin-1),requester)) { + return nullStructure; + } + pvStructure->appendPVField("record", pvStruct); + } + if (offsetField != String::npos) { + size_t offsetBegin = request.find('(', offsetField); + size_t offsetEnd = request.find(')', offsetBegin); + if(offsetEnd == String::npos) { + requester->message(request.substr(offsetField) + " field( does not have matching )", errorMessage); + return nullStructure; + } + PVStructurePtr pvStruct = pvDataCreate->createPVStructure(emptyPVStructure); + if(!createFieldRequest(pvStruct,request.substr(offsetBegin+1, offsetEnd-offsetBegin-1),requester)) { + return nullStructure; + } + pvStructure->appendPVField("field", pvStruct); + } + if (offsetPutField != String::npos) { + size_t offsetBegin = request.find('(', offsetPutField); + size_t offsetEnd = request.find(')', offsetBegin); + if(offsetEnd == String::npos) { + requester->message(request.substr(offsetField) + " putField( does not have matching )", errorMessage); + return nullStructure; + } + PVStructurePtr pvStruct = pvDataCreate->createPVStructure(emptyPVStructure); + if(!createFieldRequest(pvStruct,request.substr(offsetBegin+1, offsetEnd-offsetBegin-1),requester)) { + return nullStructure; + } + pvStructure->appendPVField("putField", pvStruct); + } + if (offsetGetField != String::npos) { + size_t offsetBegin = request.find('(', offsetGetField); + size_t offsetEnd = request.find(')', offsetBegin); + if(offsetEnd == String::npos) { + requester->message(request.substr(offsetField) + " getField( does not have matching )", errorMessage); + return nullStructure; + } + PVStructurePtr pvStruct = pvDataCreate->createPVStructure(emptyPVStructure); + if(!createFieldRequest(pvStruct,request.substr(offsetBegin+1, offsetEnd-offsetBegin-1),requester)) { + return nullStructure; + } + pvStructure->appendPVField("getField", pvStruct); + } + if (pvStructure.get()->getStructure()->getNumberFields()==0) { + if(!createFieldRequest(pvStructure,request,requester)) return nullStructure; + } + return pvStructure; + } }; diff --git a/testApp/client/testCreateRequest.cpp b/testApp/client/testCreateRequest.cpp index 7aa9321..6b9f0fb 100644 --- a/testApp/client/testCreateRequest.cpp +++ b/testApp/client/testCreateRequest.cpp @@ -16,174 +16,125 @@ using namespace epics::pvData; using namespace epics::pvAccess; +class RequesterImpl : public Requester, + public std::tr1::enable_shared_from_this +{ +public: + + virtual String getRequesterName() + { + return "RequesterImpl"; + }; + + virtual void message(String message,MessageType messageType) + { + std::cout << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl; + } +}; + void testCreateRequest() { - printf("testCreateRequest... "); + printf("testCreateRequest... \n"); + Requester::shared_pointer requester(new RequesterImpl()); + CreateRequest::shared_pointer createRequest = getCreateRequest(); - String out; - String request = ""; - std::tr1::shared_ptr pvRequest(getCreateRequest()->createRequest(request)); - assert(pvRequest); - out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; + String out; + String request = ""; + std::cout << std::endl << String("request") <createRequest(request,requester); + assert(pvRequest.get()); + out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; - request = "alarm,timeStamp,power.value"; - pvRequest = getCreateRequest()->createRequest(request); - assert(pvRequest); - out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; + request = "alarm,timeStamp,power.value"; + std::cout << std::endl << String("request") <createRequest(request,requester); + assert(pvRequest.get()); + out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; - request = "record[process=true]field(alarm,timeStamp,power.value)"; - pvRequest = getCreateRequest()->createRequest(request); - assert(pvRequest); - out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; + request = "record[process=true]field(alarm,timeStamp,power.value)"; + std::cout << std::endl << String("request") <createRequest(request,requester); + assert(pvRequest.get()); + out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; - request = "record[process=true]field(alarm,timeStamp[algorithm=onChange,causeMonitor=false],power{power.value,power.alarm})"; - pvRequest = getCreateRequest()->createRequest(request); - assert(pvRequest); - out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; + request = "record[process=true]field(alarm,timeStamp[algorithm=onChange,causeMonitor=false],power{value,alarm})"; + std::cout << String("request") <createRequest(request,requester); + assert(pvRequest.get()); + out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; - request = "record[process=true,xxx=yyy]field(alarm,timeStamp[shareData=true],power.value)"; - pvRequest = getCreateRequest()->createRequest(request); - assert(pvRequest); - out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; + request = "record[process=true,xxx=yyy]field(alarm,timeStamp[shareData=true],power.value)"; + std::cout << String("request") <createRequest(request,requester); + assert(pvRequest.get()); + out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; - request = String("record[process=true,xxx=yyy]") - + "putField(power.value)" - + "getField(alarm,timeStamp,power{power.value,power.alarm}," - + "current{current.value,current.alarm},voltage{voltage.value,voltage.alarm})"; - pvRequest = getCreateRequest()->createRequest(request); - assert(pvRequest); - out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; + request = String("record[process=true,xxx=yyy]") + + "putField(power.value)" + + "getField(alarm,timeStamp,power{value,alarm}," + + "current{value,alarm},voltage{value,alarm})"; + std::cout << String("request") <createRequest(request,requester); + assert(pvRequest.get()); + out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; - request = String("record[process=true,xxx=yyy]") - + "putField(power.value)" - + "getField(alarm,timeStamp,power{power.value,power.alarm}," - + "current{current.value,current.alarm},voltage{voltage.value,voltage.alarm}," - + "ps0{" - + "ps0.alarm,ps0.timeStamp,power{ps0.power.value,ps0.power.alarm}," - + "current{ps0.current.value,ps0.current.alarm},voltage{ps0.voltage.value,ps0.voltage.alarm}}," - + "ps1{" - + "ps1.alarm,ps1.timeStamp,power{ps1.power.value,ps1.power.alarm}," - + "current{ps1.current.value,ps1.current.alarm},voltage{ps1.voltage.value,ps1.voltage.alarm}" - + "})"; - pvRequest = getCreateRequest()->createRequest(request); - assert(pvRequest); - out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; + request = String("field(alarm,timeStamp,supply{") + + "0{voltage.value,current.value,power.value}," + + "1{voltage.value,current.value,power.value}" + + "})"; + std::cout << String("request") <createRequest(request,requester); + assert(pvRequest.get()); + out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; - request = "a{b{c{d}}}"; - pvRequest = getCreateRequest()->createRequest(request); - assert(pvRequest); - out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; + request = String("record[process=true,xxx=yyy]") + + "putField(power.value)" + + "getField(alarm,timeStamp,power{value,alarm}," + + "current{value,alarm},voltage{value,alarm}," + + "ps0{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}}," + + "ps1{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}}" + + ")"; + std::cout << String("request") <createRequest(request,requester); + assert(pvRequest.get()); + out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; - request = "record[process=true,xxx=yyy]field(alarm,timeStamp[shareData=true],power.value"; - std::cout << std::endl << "Error Expected for next call!!" << std::endl; - try - { - pvRequest = getCreateRequest()->createRequest(request); - assert(false); - } - catch(std::exception& e) - { - std::cout << e.what() << std::endl; - } - - request = String("record[process=true,xxx=yyy]") - + "putField(power.value)" - + "getField(alarm,timeStamp,power{power.value,power.alarm}," - + "current{current.value,current.alarm},voltage{voltage.value,voltage.alarm}," - + "ps0{" - + "ps0.alarm,ps0.timeStamp,power{ps0.power.value,ps0.power.alarm}," - + "current{ps0.current.value,ps0.current.alarm},voltage{ps0.voltage.value,ps0.voltage.alarm}}," - + "ps1{" - + "ps1.alarm,ps1.timeStamp,power{ps1.power.value,ps1.power.alarm}," - + "current{ps1.current.value,ps1.current.alarm},voltage{ps1.voltage.value,ps1.voltage.alarm}" - + ")"; - std::cout << std::endl << "Error Expected for next call!!" << std::endl; - try - { - pvRequest = getCreateRequest()->createRequest(request); - assert(false); - } - catch(std::exception& e) - { - std::cout << e.what() << std::endl; - } - - - request = "record[process=true,power.value"; - std::cout << std::endl << "Error Expected for next call!!" << std::endl; - try - { - pvRequest = getCreateRequest()->createRequest(request); - assert(false); - } - catch(std::exception& e) - { - std::cout << e.what() << std::endl; - } - - - request = "field(power.value"; - std::cout << std::endl << "Error Expected for next call!!" << std::endl; - try - { - pvRequest = getCreateRequest()->createRequest(request); - assert(false); - } - catch(std::exception& e) - { - std::cout << e.what() << std::endl; - } - - - request = "putField(power.value"; - std::cout << std::endl << "Error Expected for next call!!" << std::endl; - try - { - pvRequest = getCreateRequest()->createRequest(request); - assert(false); - } - catch(std::exception& e) - { - std::cout << e.what() << std::endl; - } - - - request = "getField(power.value"; - std::cout << std::endl << "Error Expected for next call!!" << std::endl;\ - try - { - pvRequest = getCreateRequest()->createRequest(request); - assert(false); - } - catch(std::exception& e) - { - std::cout << e.what() << std::endl; - } - - - request = "record[process=true=power.value]"; - std::cout << std::endl << "Error Expected for next call!!" << std::endl; - try - { - pvRequest = getCreateRequest()->createRequest(request); - assert(false); - } - catch(std::exception& e) - { - std::cout << e.what() << std::endl; - } - - printf("PASSED\n"); + request = "a{b{c{d}}}"; + std::cout << String("request") <createRequest(request,requester); + assert(pvRequest.get()); + out.clear(); pvRequest->toString(&out); std::cout << out << std::endl; + request = "record[process=true,xxx=yyy]field(alarm,timeStamp[shareData=true],power.value"; + std::cout << String("request") <createRequest(request,requester); + assert(pvRequest.get()==NULL); + request = String("record[process=true,xxx=yyy]") + + "putField(power.value)" + + "getField(alarm,timeStamp,power{value,alarm}," + + "current{value,alarm},voltage{value,alarm}," + + "ps0{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}}," + + "ps1{alarm,timeStamp,power{value,alarm},current{value,alarm},voltage{value,alarm}" + + ")"; + std::cout << String("request") <createRequest(request,requester); + assert(pvRequest.get()==NULL); + request = "record[process=true,power.value"; + std::cout << String("request") <createRequest(request,requester); + assert(pvRequest.get()==NULL); } int main(int argc,char *argv[]) { - testCreateRequest(); + testCreateRequest(); - std::cout << "-----------------------------------------------------------------------" << std::endl; - epicsExitCallAtExits(); - CDRMonitor::get().show(stdout, true); - return 0; + std::cout << "-----------------------------------------------------------------------" << std::endl; + epicsExitCallAtExits(); + CDRMonitor::get().show(stdout, true); + return 0; } diff --git a/testApp/remote/eget.cpp b/testApp/remote/eget.cpp index 2961b19..8a1f472 100644 --- a/testApp/remote/eget.cpp +++ b/testApp/remote/eget.cpp @@ -20,6 +20,21 @@ using namespace std::tr1; using namespace epics::pvData; using namespace epics::pvAccess; +class RequesterImpl : public Requester, + public std::tr1::enable_shared_from_this +{ +public: + + virtual String getRequesterName() + { + return "RequesterImpl"; + }; + + virtual void message(String message,MessageType messageType) + { + std::cout << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl; + } +}; /// terse mode functions @@ -773,6 +788,8 @@ int main (int argc, char *argv[]) int opt; /* getopt() current option */ bool debug = false; bool cleanupAndReport = false; + + Requester::shared_pointer requester(new RequesterImpl()); bool serviceRequest = false; string service; @@ -869,10 +886,9 @@ int main (int argc, char *argv[]) pvs.push_back(argv[optind]); /* Copy PV names from command line */ PVStructure::shared_pointer pvRequest; - try { - pvRequest = getCreateRequest()->createRequest(request); - } catch (std::exception &ex) { - printf("failed to parse request string: %s\n", ex.what()); + pvRequest = getCreateRequest()->createRequest(request,requester); + if(pvRequest.get()==NULL) { + printf("failed to parse request string\n"); return 1; } @@ -927,10 +943,9 @@ int main (int argc, char *argv[]) // TODO simply empty? PVStructure::shared_pointer pvRequest; - try { - pvRequest = getCreateRequest()->createRequest(request); - } catch (std::exception &ex) { - printf("failed to parse request string: %s\n", ex.what()); + pvRequest = getCreateRequest()->createRequest(request,requester); + if(pvRequest.get()==NULL) { + printf("failed to parse request string\n"); return 1; } diff --git a/testApp/remote/pvget.cpp b/testApp/remote/pvget.cpp index 6ab0990..a56a1eb 100644 --- a/testApp/remote/pvget.cpp +++ b/testApp/remote/pvget.cpp @@ -19,19 +19,25 @@ using namespace std::tr1; using namespace epics::pvData; using namespace epics::pvAccess; - - - - void convertStructure(StringBuilder buffer,PVStructure *data,int notFirst); void convertArray(StringBuilder buffer,PVScalarArray * pv,int notFirst); void convertStructureArray(StringBuilder buffer,PVStructureArray * pvdata,int notFirst); +class RequesterImpl : public Requester, + public std::tr1::enable_shared_from_this +{ +public: + virtual String getRequesterName() + { + return "RequesterImpl"; + }; - - - + virtual void message(String message,MessageType messageType) + { + std::cout << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl; + } +}; void convertToString(StringBuilder buffer,PVField * pv,int notFirst) @@ -594,12 +600,12 @@ int main (int argc, char *argv[]) bool allOK = true; { + Requester::shared_pointer requester(new RequesterImpl()); PVStructure::shared_pointer pvRequest; - try { - pvRequest = getCreateRequest()->createRequest(request); - } catch (std::exception &ex) { - printf("failed to parse request string: %s\n", ex.what()); + pvRequest = getCreateRequest()->createRequest(request,requester); + if(pvRequest.get()==NULL) { + printf("failed to parse request string\n"); return 1; } diff --git a/testApp/remote/pvput.cpp b/testApp/remote/pvput.cpp index ea2d9d2..8bb66ce 100644 --- a/testApp/remote/pvput.cpp +++ b/testApp/remote/pvput.cpp @@ -17,20 +17,25 @@ using namespace std::tr1; using namespace epics::pvData; using namespace epics::pvAccess; - - - - void convertStructure(StringBuilder buffer,PVStructure *data,int notFirst); void convertArray(StringBuilder buffer,PVScalarArray * pv,int notFirst); void convertStructureArray(StringBuilder buffer,PVStructureArray * pvdata,int notFirst); +class RequesterImpl : public Requester, + public std::tr1::enable_shared_from_this +{ +public: + virtual String getRequesterName() + { + return "RequesterImpl"; + }; - - - - + virtual void message(String message,MessageType messageType) + { + std::cout << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl; + } +}; void convertToString(StringBuilder buffer,PVField * pv,int notFirst) { @@ -543,6 +548,8 @@ int main (int argc, char *argv[]) int opt; /* getopt() current option */ bool debug = false; + Requester::shared_pointer requester(new RequesterImpl()); + setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */ while ((opt = getopt(argc, argv, ":hr:w:t")) != -1) { @@ -602,10 +609,9 @@ int main (int argc, char *argv[]) for (int n = 0; optind < argc; n++, optind++) values.push_back(argv[optind]); /* Copy values from command line */ - try { - pvRequest = getCreateRequest()->createRequest(request); - } catch (std::exception &ex) { - printf("failed to parse request string: %s\n", ex.what()); + pvRequest = getCreateRequest()->createRequest(request,requester); + if(pvRequest.get()==NULL) { + printf("failed to parse request string\n"); return 1; } diff --git a/testApp/remote/pvrpc.cpp b/testApp/remote/pvrpc.cpp index 617c1fc..4c7fb69 100644 --- a/testApp/remote/pvrpc.cpp +++ b/testApp/remote/pvrpc.cpp @@ -26,6 +26,23 @@ bool terseMode = false; PVStructure::shared_pointer pvRequest; +class RequesterImpl : public Requester, + public std::tr1::enable_shared_from_this +{ +public: + + virtual String getRequesterName() + { + return "RequesterImpl"; + }; + + virtual void message(String message,MessageType messageType) + { + std::cout << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl; + } +}; + + void usage () { fprintf (stderr, "\nUsage: pvrpc [options] ...\n\n" @@ -156,6 +173,8 @@ int main (int argc, char *argv[]) int opt; /* getopt() current option */ bool debug = false; + Requester::shared_pointer requester(new RequesterImpl()); + setvbuf(stdout,NULL,_IOLBF,BUFSIZ); /* Set stdout to line buffering */ while ((opt = getopt(argc, argv, ":hr:w:t")) != -1) { @@ -215,10 +234,9 @@ int main (int argc, char *argv[]) for (int n = 0; optind < argc; n++, optind++) values.push_back(argv[optind]); /* Copy values from command line */ - try { - pvRequest = getCreateRequest()->createRequest(request); - } catch (std::exception &ex) { - printf("failed to parse request string: %s\n", ex.what()); + pvRequest = getCreateRequest()->createRequest(request,requester); + if(pvRequest.get()==NULL) { + printf("failed to parse request string\n"); return 1; } diff --git a/testApp/remote/testGetPerformance.cpp b/testApp/remote/testGetPerformance.cpp index 766b528..d5f2b2c 100644 --- a/testApp/remote/testGetPerformance.cpp +++ b/testApp/remote/testGetPerformance.cpp @@ -32,6 +32,23 @@ string request(DEFAULT_REQUEST); PVStructure::shared_pointer pvRequest; +class RequesterImpl : public Requester, + public std::tr1::enable_shared_from_this +{ +public: + + virtual String getRequesterName() + { + return "RequesterImpl"; + }; + + virtual void message(String message,MessageType messageType) + { + std::cout << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl; + } +}; + + void usage (void) { fprintf (stderr, "\nUsage: testGetPerformance [options] ...\n\n" @@ -242,6 +259,8 @@ printf("this does not work... since this impl. requires bulk get control... tODO return -1; int opt; // getopt() current option + Requester::shared_pointer requester(new RequesterImpl()); + setvbuf(stdout,NULL,_IOLBF,BUFSIZ); // Set stdout to line buffering while ((opt = getopt(argc, argv, ":hr:w:t")) != -1) { @@ -288,12 +307,11 @@ return -1; } - try { - pvRequest = getCreateRequest()->createRequest(request); - } catch (std::exception &ex) { - printf("failed to parse request string: %s\n", ex.what()); - return 1; - } + pvRequest = getCreateRequest()->createRequest(request,requester); + if(pvRequest.get()==NULL) { + printf("failed to parse request string\n"); + return 1; + } // typedef enum {logLevelInfo, logLevelDebug, logLevelError, errlogFatal} errlogSevEnum; SET_LOG_LEVEL(logLevelError); diff --git a/testApp/remote/testRemoteClientImpl.cpp b/testApp/remote/testRemoteClientImpl.cpp index 3829f46..94b6c25 100644 --- a/testApp/remote/testRemoteClientImpl.cpp +++ b/testApp/remote/testRemoteClientImpl.cpp @@ -479,7 +479,7 @@ int main(int argc,char *argv[]) { ChannelGetRequester::shared_pointer channelGetRequesterImpl(new ChannelGetRequesterImpl()); - PVStructure::shared_pointer pvRequest = getCreateRequest()->createRequest("field()"); + PVStructure::shared_pointer pvRequest = getCreateRequest()->createRequest("field()",channelGetRequesterImpl); ChannelGet::shared_pointer channelGet = channel->createChannelGet(channelGetRequesterImpl, pvRequest); epicsThreadSleep ( 3.0 ); channelGet->get(false); @@ -489,7 +489,7 @@ int main(int argc,char *argv[]) { ChannelPutRequester::shared_pointer channelPutRequesterImpl(new ChannelPutRequesterImpl()); - PVStructure::shared_pointer pvRequest = getCreateRequest()->createRequest("field(value,timeStamp)"); + PVStructure::shared_pointer pvRequest = getCreateRequest()->createRequest("field(value,timeStamp)",channelPutRequesterImpl); ChannelPut::shared_pointer channelPut = channel->createChannelPut(channelPutRequesterImpl, pvRequest); epicsThreadSleep ( 1.0 ); channelPut->get(); @@ -501,7 +501,7 @@ int main(int argc,char *argv[]) { ChannelPutGetRequester::shared_pointer channelPutGetRequesterImpl(new ChannelPutGetRequesterImpl()); - PVStructure::shared_pointer pvRequest = getCreateRequest()->createRequest("putField(value,timeStamp)getField(timeStamp)"); + PVStructure::shared_pointer pvRequest = getCreateRequest()->createRequest("putField(value,timeStamp)getField(timeStamp)",channelPutGetRequesterImpl); ChannelPutGet::shared_pointer channelPutGet = channel->createChannelPutGet(channelPutGetRequesterImpl, pvRequest); epicsThreadSleep ( 1.0 ); channelPutGet->getGet(); @@ -515,7 +515,7 @@ int main(int argc,char *argv[]) { ChannelRPCRequester::shared_pointer channelRPCRequesterImpl(new ChannelRPCRequesterImpl()); - PVStructure::shared_pointer pvRequest = getCreateRequest()->createRequest("record[]field(arguments)"); + PVStructure::shared_pointer pvRequest = getCreateRequest()->createRequest("record[]field(arguments)",channelRPCRequesterImpl); ChannelRPC::shared_pointer channelRPC = channel->createChannelRPC(channelRPCRequesterImpl, pvRequest); epicsThreadSleep ( 1.0 ); // for test simply use pvRequest as arguments @@ -543,7 +543,7 @@ int main(int argc,char *argv[]) { MonitorRequester::shared_pointer monitorRequesterImpl(new MonitorRequesterImpl()); - PVStructure::shared_pointer pvRequest = getCreateRequest()->createRequest("field()"); + PVStructure::shared_pointer pvRequest = getCreateRequest()->createRequest("field()",monitorRequesterImpl); Monitor::shared_pointer monitor = channel->createMonitor(monitorRequesterImpl, pvRequest); epicsThreadSleep( 1.0 );