diff --git a/pvDataApp/Makefile b/pvDataApp/Makefile index e66a3e1..cf66ef2 100644 --- a/pvDataApp/Makefile +++ b/pvDataApp/Makefile @@ -60,7 +60,6 @@ SRC_DIRS += $(PVDATA)/factory INC += factory.h LIBSRCS += TypeFunc.cpp LIBSRCS += FieldCreateFactory.cpp -LIBSRCS += PVAuxInfoImpl.cpp LIBSRCS += PVField.cpp LIBSRCS += PVScalar.cpp LIBSRCS += PVArray.cpp @@ -97,6 +96,14 @@ LIBSRCS += pvEnumerated.cpp LIBSRCS += timeStamp.cpp LIBSRCS += pvTimeStamp.cpp + +SRC_DIRS += $(PVDATA)/copy +INC += createRequest.h +INC += pvCopy.h +LIBSRCS += createRequest.cpp +LIBSRCS += pvCopy.cpp + + SRC_DIRS += $(PVDATA)/pvMisc INC += bitSetUtil.h LIBSRCS += bitSetUtil.cpp diff --git a/pvDataApp/copy/createRequest.cpp b/pvDataApp/copy/createRequest.cpp new file mode 100644 index 0000000..101edb6 --- /dev/null +++ b/pvDataApp/copy/createRequest.cpp @@ -0,0 +1,532 @@ +/** + * Copyright - See the COPYRIGHT that is included with this distribution. + * pvAccessCPP is distributed subject to a Software License Agreement found + * in file LICENSE that is included with this distribution. + */ + +#include +#include + +#include +#include + +#define epicsExportSharedSymbols +#include + +using namespace epics::pvData; +using std::tr1::static_pointer_cast; +using std::cout; +using std::endl; + +namespace epics { namespace pvData { + +static PVDataCreatePtr pvDataCreate = getPVDataCreate(); +static FieldCreatePtr fieldCreate = getFieldCreate(); + +class CreateRequestImpl : public CreateRequest { +private: + + void removeBlanks(String& str) + { + while(true) { + String::size_type pos = str.find_first_of(' '); + if(pos==String::npos) return; + str.erase(pos,1); + } + } + + size_t findMatchingBrace(String& request, size_t index, int numOpen) { + size_t openBrace = request.find('{', index+1); + size_t closeBrace = request.find('}', index+1); + if(openBrace == String::npos && closeBrace == std::string::npos){ + message = request + " missing }"; + return std::string::npos; + } + if (openBrace != String::npos && openBrace!=0) { + if(openBrace=request.size()) return request.size(); + ind = closeBrace; + continue; + } + if(ind>=maxind) break; + ++ind; + } + return request.size(); + } + + std::vector split(String const & 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; i items = split(request); + size_t nitems = items.size(); + StringArray fieldNames(nitems); + FieldConstPtrArray fields(nitems); + for(size_t j=0; jcreateScalar(pvString); + } + return fieldCreate->createStructure(fieldNames,fields); + } + + void initRequestOptions( + PVStructurePtr const & pvParent, + String request) + { + if(request.length()<=1) return; + std::vector items = split(request); + size_t nitems = items.size(); + for(size_t j=0; jgetSubField(name); + pvValue->put(value); + } + } + + StructureConstPtr createSubFieldRequest( + StructureConstPtr parent, + String request) + { + if(request.length()<=0) return parent; + size_t period = request.find('.'); + size_t openBracket = request.find('['); + size_t openBrace = request.find('{'); + + // name only + if(period==String::npos + && openBracket==String::npos + && openBrace==String::npos) + { + StructureConstPtr subField = fieldCreate->createStructure(); + parent = fieldCreate->appendField(parent,request,subField); + return parent; + } + + // period is first + if(period!=String::npos + && (openBracket==String::npos || periodcreateStructure(); + subField = createSubFieldRequest(subField,request.substr(period+1)); + if(subField==NULL) return subField; + parent = fieldCreate->appendField(parent,fieldName,subField); + return parent; + } + + // brace before [ or . + if(openBrace!=String::npos + && (openBracket==String::npos || openBrace= request.size()) nextChar = String::npos; + if(nextChar!=String::npos) { + message = request + " syntax error " + request[nextChar] + " after } illegal"; + return StructureConstPtr(); + } + StructureConstPtr subField = fieldCreate->createStructure(); + String subRequest = request.substr(openBrace+1,closeBrace-openBrace-1); + subField = createFieldRequest(subField,subRequest); + if(subField==NULL) return subField; + parent = fieldCreate->appendField(parent,fieldName,subField); + return parent; + } + + // [ is before brace or . + if(openBracket!=String::npos + && (openBrace==String::npos || openBracket= request.size()) nextChar = String::npos; + if(nextChar==String::npos) { + StringArray fieldNames(1); + FieldConstPtrArray fields(1); + fieldNames[0] = "_options"; + fields[0] = createRequestOptions( + request.substr(openBracket+1,closeBracket-openBracket-1)); + StructureConstPtr subField = fieldCreate->createStructure(fieldNames,fields); + parent = fieldCreate->appendField(parent,fieldName,subField); + return parent; + } + if(request[nextChar]=='.') { + StructureConstPtr subField = fieldCreate->createStructure(); + subField = createSubFieldRequest(subField,request.substr(nextChar+1)); + if(subField==NULL) return StructureConstPtr(); + if(subField->getNumberFields()!=1) { + message = request + " logic error createSubFieldRequest openBracket subField"; + return StructureConstPtr(); + } + StringArray fieldNames(2); + FieldConstPtrArray fields(2); + fieldNames[0] = "_options"; + fields[0] = createRequestOptions( + request.substr(openBracket+1,closeBracket-openBracket-1)); + fieldNames[1] = subField->getFieldNames()[0]; + fields[1] = subField; + subField = fieldCreate->createStructure(fieldNames,fields); + parent = fieldCreate->appendField(parent,fieldName,subField); + return parent; + } + if(request[nextChar]=='{') { + size_t closeBrace = findMatchingBrace(request,openBrace,1); + if(closeBrace==String::npos) return StructureConstPtr(); + StructureConstPtr subField = fieldCreate->createStructure(); + String subRequest = request.substr(openBrace+1,closeBrace-openBrace-1); + subField = createFieldRequest(subField,subRequest); + if(subField==NULL) return subField; + size_t numSub = subField->getNumberFields(); + StringArray fieldNames(numSub + 1); + FieldConstPtrArray fields(numSub+1); + fieldNames[0] = "_options"; + fields[0] = createRequestOptions( + request.substr(openBracket+1,closeBracket-openBracket-1)); + StringArray subNames = subField->getFieldNames(); + FieldConstPtrArray subFields = subField->getFields(); + for(size_t i=0; iappendFields(parent,fieldNames,fields); + parent = fieldCreate->appendField(parent,fieldName,subField); + return parent; + } + } + message = request + " logic error createSubFieldRequest"; + return StructureConstPtr(); + } + + + StructureConstPtr createFieldRequest( + StructureConstPtr parent, + String request) + { + size_t length = request.length(); + if(length<=0) return parent; + size_t end = findEndField(request); + if(end==String::npos) return StructureConstPtr(); + StringArray fieldNames; + FieldConstPtrArray fields; + StructureConstPtr subField = fieldCreate->createStructure(); + subField = createSubFieldRequest(subField,request.substr(0,end)); + if(subField==NULL) return subField; + fieldNames.push_back(subField->getFieldNames()[0]); + fields.push_back(subField->getFields()[0]); + if(end!=length) { + if(request[end]!=',') { + message = request; + message += " expected char "; + message += length; + message += " to be ,"; + return StructureConstPtr(); + } + StructureConstPtr nextSubField = fieldCreate->createStructure(); + nextSubField = createFieldRequest(nextSubField,request.substr(end+1)); + if(nextSubField==NULL) return nextSubField; + size_t numFields = nextSubField->getNumberFields(); + StringArray subNames = nextSubField->getFieldNames(); + FieldConstPtrArray subFields = nextSubField->getFields(); + for(size_t i=0; iappendFields(parent,fieldNames,fields); + return parent; + } + + void initSubFieldOptions( + PVStructurePtr const & pvParent, + String request) + { + if(request.length()<=0) return; + size_t period = request.find('.'); + size_t openBracket = request.find('['); + size_t openBrace = request.find('{'); + // name only + if(period==String::npos + && openBracket==String::npos + && openBrace==String::npos) + { + return; + } + + // period is first + if(period!=String::npos + && (openBracket==String::npos || period(pvParent->getPVFields()[0]); + initSubFieldOptions(pvSubField,request.substr(period+1)); + return; + } + + // brace before [ or . + if(openBrace!=String::npos + && (openBracket==String::npos || openBrace(pvParent->getPVFields()[0]); + size_t closeBrace = findMatchingBrace(request,openBrace,1); + String subRequest = request.substr(openBrace+1,closeBrace-openBrace-1); + initFieldOptions(pvSubField,subRequest); + return; + } + PVStructurePtr pvOptions = pvParent->getSubField("_options"); + if(pvOptions==NULL) throw std::logic_error("initSubFieldOptions pvOptions NULL"); + size_t closeBracket = findMatchingBracket(request,openBracket); + initRequestOptions(pvOptions,request.substr(openBracket+1,closeBracket-openBracket-1)); + size_t nextChar = closeBracket+1; + if(nextChar>= request.size()) nextChar = String::npos; + if(nextChar==String::npos) return; + if(request[nextChar]=='.') { + PVStructurePtr pvSubField = static_pointer_cast(pvParent->getPVFields()[1]); + initSubFieldOptions(pvSubField,request.substr(nextChar+1)); + return; + } + if(request[nextChar]!='{') throw std::logic_error("initSubFieldOptions request[nextChar]!='{'"); + size_t closeBrace = findMatchingBrace(request,openBrace,1); + const PVFieldPtrArray &pvFields = pvParent->getPVFields(); + String subRequest = request.substr(openBrace+1,closeBrace-openBrace-1); + for(size_t i=1; i(pvFields[i]); + size_t comma = subRequest.find(','); + initSubFieldOptions(pvSubField, subRequest.substr(0,comma-1)); + subRequest = subRequest.substr(comma+1); + } + } + + void initFieldOptions( + PVStructurePtr const & pvParent, + String request) + { + if(request.find('[')==String::npos) return; + size_t num = pvParent->getStructure()->getNumberFields(); + if(num==0) return; + if(num==1) { + initSubFieldOptions(pvParent,request); + return; + } + size_t end = findEndField(request); + size_t start = 0; + for(size_t i=0; i(pvParent->getPVFields()[i]); + String subRequest = request.substr(start, end - start); + initSubFieldOptions(pvSub,subRequest); + if(i==num-1) break; + start = end +1; + String xxx = request.substr(start); + end += findEndField(xxx) + 1; + } + } + + +public: + + virtual PVStructure::shared_pointer createRequest( + String const & crequest) + { + String request = crequest; + StructureConstPtr topStructure = fieldCreate->createStructure(); + + if (!request.empty()) removeBlanks(request); + if (request.empty()) + { + PVFieldPtrArray pvFields; + StringArray fieldNames; + return pvDataCreate->createPVStructure(fieldNames,pvFields); + } + size_t offsetRecord = request.find("record["); + size_t offsetField = request.find("field("); + size_t offsetPutField = request.find("putField("); + size_t offsetGetField = request.find("getField("); + if(offsetRecord==String::npos + && offsetField==String::npos + && offsetPutField==String::npos + && offsetGetField==String::npos) + { + request = "field(" + crequest + ")"; + offsetField = request.find("field("); + } + if (offsetRecord != String::npos) { + size_t openBracket = request.find('[', offsetRecord); + size_t closeBracket = request.find(']', openBracket); + if(closeBracket == String::npos) { + message = request.substr(offsetRecord) + + " record[ does not have matching ]"; + return PVStructurePtr(); + } + StructureConstPtr structure = createRequestOptions( + request.substr(openBracket+1,closeBracket-openBracket-1)); + if(structure==NULL) + { + return PVStructurePtr(); + } + topStructure = fieldCreate->appendField(topStructure,"record",structure); + } + if (offsetField != String::npos) { + size_t openBrace = request.find('(', offsetField); + size_t closeBrace = request.find(')', openBrace); + if(closeBrace == String::npos) { + message = request.substr(offsetField) + + " field( does not have matching )"; + return PVStructurePtr(); + } + StructureConstPtr structure = fieldCreate->createStructure(); + structure = createFieldRequest(structure,request.substr(openBrace+1,closeBrace-openBrace-1)); + if(structure==NULL) + { + return PVStructurePtr(); + } + topStructure = fieldCreate->appendField(topStructure,"field",structure); + } + if (offsetPutField != String::npos) { + size_t openBrace = request.find('(', offsetPutField); + size_t closeBrace = request.find(')', openBrace); + if(closeBrace == String::npos) { + message = request.substr(offsetField) + + " putField( does not have matching )"; + return PVStructurePtr(); + } + StructureConstPtr structure = fieldCreate->createStructure(); + structure = createFieldRequest(structure,request.substr(openBrace+1,closeBrace-openBrace-1)); + if(structure==NULL) + { + return PVStructurePtr(); + } + topStructure = fieldCreate->appendField(topStructure,"putField",structure); + } + if (offsetGetField != String::npos) { + size_t openBrace = request.find('(', offsetGetField); + size_t closeBrace = request.find(')', openBrace); + if(closeBrace == String::npos) { + message = request.substr(offsetField) + + " getField( does not have matching )"; + return PVStructurePtr(); + } + StructureConstPtr structure = fieldCreate->createStructure(); + structure = createFieldRequest(structure,request.substr(openBrace+1,closeBrace-openBrace-1)); + if(structure==NULL) + { + return PVStructurePtr(); + } + topStructure = fieldCreate->appendField(topStructure,"getField",structure); + } + PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); + if (offsetRecord != String::npos) { + size_t openBracket = request.find('[', offsetRecord); + size_t closeBracket = request.find(']', openBracket); + initRequestOptions( + pvStructure->getSubField("record"), + request.substr(openBracket+1,closeBracket-openBracket-1)); + } + if (offsetField != String::npos) { + size_t openParam = request.find('(', offsetField); + size_t closeParam = request.find(')', openParam); + PVStructurePtr pvSub = pvStructure->getSubField("field"); + if(pvSub->getStructure()->getNumberFields()==1) { + pvSub = static_pointer_cast(pvSub->getPVFields()[0]); + } + if(pvSub!=NULL) initFieldOptions(pvSub,request.substr(openParam+1,closeParam-openParam-1)); + } + if (offsetPutField != String::npos) { + size_t openParam = request.find('(', offsetPutField); + size_t closeParam = request.find(')', openParam); + PVStructurePtr pvSub = pvStructure->getSubField("putField"); + if(pvSub->getStructure()->getNumberFields()==1) { + pvSub = static_pointer_cast(pvSub->getPVFields()[0]); + } + if(pvSub!=NULL) initFieldOptions(pvSub,request.substr(openParam+1,closeParam-openParam-1)); + } + if (offsetGetField != String::npos) { + size_t openParam = request.find('(', offsetGetField); + size_t closeParam = request.find(')', openParam); + PVStructurePtr pvSub = pvStructure->getSubField("getField"); + if(pvSub->getStructure()->getNumberFields()==1) { + pvSub = static_pointer_cast(pvSub->getPVFields()[0]); + } + if(pvSub!=NULL) initFieldOptions(pvSub,request.substr(openParam+1,closeParam-openParam-1)); + } + return pvStructure; + } + +}; + +CreateRequest::shared_pointer CreateRequest::create() +{ + CreateRequest::shared_pointer createRequest(new CreateRequestImpl()); + return createRequest; +} + +}} + diff --git a/pvDataApp/copy/createRequest.h b/pvDataApp/copy/createRequest.h new file mode 100644 index 0000000..33b5a4c --- /dev/null +++ b/pvDataApp/copy/createRequest.h @@ -0,0 +1,60 @@ +/*createRequest.h*/ +/** + * Copyright - See the COPYRIGHT that is included with this distribution. + * pvDataCPP is distributed subject to a Software License Agreement found + * in file LICENSE that is included with this distribution. + */ + +#ifndef CREATEREQUEST_H +#define CREATEREQUEST_H +#include +#include + +#ifdef epicsExportSharedSymbols +# define pvDataEpicsExportSharedSymbols +# undef epicsExportSharedSymbols +#endif + + +#include +#include + +#ifdef pvDataEpicsExportSharedSymbols +# define epicsExportSharedSymbols +# undef pvDataEpicsExportSharedSymbols +#endif + + + +namespace epics { namespace pvData { + +class epicsShareClass CreateRequest { + public: + POINTER_DEFINITIONS(CreateRequest); + static CreateRequest::shared_pointer create(); + virtual ~CreateRequest() {}; + /** + * Create a request structure for the create calls in Channel. + * See the package overview documentation for details. + * @param request The field request. See the package overview documentation for details. + * @param requester The requester; + * @return The request PVStructure if a valid request was given. + * If a NULL PVStructure is returned then getMessage will return + * the reason. + */ + virtual PVStructure::shared_pointer createRequest(String const & request) = 0; + /** + * Get the error message of createRequest returns NULL + * return the error message + */ + String getMessage() {return message;} +protected: + CreateRequest() {} + String message; +}; + + +}} + +#endif /* CREATEREQUEST_H */ + diff --git a/pvDataApp/copy/pvCopy.cpp b/pvDataApp/copy/pvCopy.cpp new file mode 100644 index 0000000..0f4a836 --- /dev/null +++ b/pvDataApp/copy/pvCopy.cpp @@ -0,0 +1,682 @@ +/* pvCopy.cpp */ +/** + * Copyright - See the COPYRIGHT that is included with this distribution. + * EPICS pvData is distributed subject to a Software License Agreement found + * in file LICENSE that is included with this distribution. + */ +/** + * @author Marty Kraimer + * @date 2013.04 + */ +#include +#include +#include +#include + +#include + +#include +#include + + +namespace epics { namespace pvData { + +using namespace epics::pvData; +using std::tr1::static_pointer_cast; +using std::tr1::dynamic_pointer_cast; +using std::size_t; +using std::cout; +using std::endl; + +static PVCopyPtr NULLPVCopy; +static FieldConstPtr NULLField; +static StructureConstPtr NULLStructure; +static PVStructurePtr NULLPVStructure; +static CopyNodePtr NULLCopyNode; +static CopyMasterNodePtr NULLCopyMasterNode; + +struct CopyNode { + CopyNode() + : isStructure(false), + structureOffset(0), + nfields(0) + {} + bool isStructure; + size_t structureOffset; // In the copy + size_t nfields; + PVStructurePtr options; +}; + +struct CopyMasterNode : public CopyNode{ + PVFieldPtr masterPVField; +}; + +typedef std::vector CopyNodePtrArray; +typedef std::tr1::shared_ptr CopyNodePtrArrayPtr; + +struct CopyStructureNode : public CopyNode { + CopyNodePtrArrayPtr nodes; +}; + +PVCopyPtr PVCopy::create( + PVStructurePtr const &pvMaster, + PVStructurePtr const &pvRequest, + String const & structureName) +{ + PVStructurePtr pvStructure(pvRequest); + if(structureName.size()>0) { + if(pvRequest->getStructure()->getNumberFields()>0) { + pvStructure = pvRequest->getStructureField(structureName); + if(pvStructure.get()==NULL) return NULLPVCopy; + } + } else if(pvStructure->getSubField("field")!=NULL) { + pvStructure = pvRequest->getStructureField("field"); + } + PVCopyPtr pvCopy = PVCopyPtr(new PVCopy(pvMaster)); + bool result = pvCopy->init(pvStructure); + if(!result) pvCopy.reset(); + return pvCopy; +} + +PVCopy::PVCopy( + PVStructurePtr const &pvMaster) +: pvMaster(pvMaster) +{ +} + +void PVCopy::destroy() +{ + headNode.reset(); +} + +PVStructurePtr PVCopy::getPVMaster() +{ + return pvMaster; +} + +void PVCopy::traverseMaster(CopyNodePtr const &innode, PVCopyTraverseMasterCallbackPtr const & callback) +{ + CopyNodePtr node = innode; + if(!node->isStructure) { + CopyMasterNodePtr masterNode = static_pointer_cast(node); + callback->nextMasterPVField(masterNode->masterPVField); + return; + } + CopyStructureNodePtr structNode = static_pointer_cast(node); + CopyNodePtrArrayPtr nodes = structNode->nodes; + for(size_t i=0; i< nodes->size(); i++) { + node = (*nodes)[i]; + traverseMaster(node,callback); + } +} + +StructureConstPtr PVCopy::getStructure() +{ + return structure; +} + +PVStructurePtr PVCopy::createPVStructure() +{ + if(cacheInitStructure.get()!=NULL) { + PVStructurePtr save = cacheInitStructure; + cacheInitStructure.reset(); + return save; + } + PVStructurePtr pvStructure = + getPVDataCreate()->createPVStructure(structure); + return pvStructure; +} + +PVStructurePtr PVCopy::getOptions( + PVStructurePtr const ©PVStructure,std::size_t fieldOffset) +{ + CopyNodePtr node = headNode; + while(true) { + if(!node->isStructure) { + if(node->structureOffset==fieldOffset) return node->options; + return NULLPVStructure; + } + CopyStructureNodePtr structNode = static_pointer_cast(node); + CopyNodePtrArrayPtr nodes = structNode->nodes; + boolean okToContinue = false; + for(size_t i=0; i< nodes->size(); i++) { + node = (*nodes)[i]; + size_t soff = node->structureOffset; + if(fieldOffset>=soff && fieldOffsetnfields) { + if(fieldOffset==soff) return node->options; + if(!node->isStructure) { + return NULLPVStructure; + } + okToContinue = true; + break; + } + } + if(okToContinue) continue; + throw std::invalid_argument("fieldOffset not valid"); + } +} + +size_t PVCopy::getCopyOffset(PVFieldPtr const &masterPVField) +{ + if(!headNode->isStructure) { + CopyMasterNodePtr masterNode = static_pointer_cast(headNode); + if((masterNode->masterPVField.get())==masterPVField.get()) { + return headNode->structureOffset; + } + PVStructure * parent = masterPVField->getParent(); + size_t offsetParent = parent->getFieldOffset(); + size_t off = masterPVField->getFieldOffset(); + size_t offdiff = off -offsetParent; + if(offdiffnfields) return headNode->structureOffset + offdiff; + return String::npos; + } + CopyStructureNodePtr node = static_pointer_cast(headNode); + CopyMasterNodePtr masterNode = getCopyOffset(node,masterPVField); + if(masterNode.get()!=NULL) return masterNode->structureOffset; + return String::npos; +} + +size_t PVCopy::getCopyOffset( + PVStructurePtr const &masterPVStructure, + PVFieldPtr const &masterPVField) +{ + CopyMasterNodePtr masterNode; + if(!headNode->isStructure) { + masterNode = static_pointer_cast(headNode); + if(masterNode->masterPVField.get()!=masterPVStructure.get()) return String::npos; + } else { + CopyStructureNodePtr node = static_pointer_cast(headNode); + masterNode = getCopyOffset(node,masterPVField); + } + if(masterNode.get()==NULL) return String::npos; + size_t diff = masterPVField->getFieldOffset() + - masterPVStructure->getFieldOffset(); + return masterNode->structureOffset + diff; +} + +PVFieldPtr PVCopy::getMasterPVField(size_t structureOffset) +{ + CopyMasterNodePtr masterNode; + if(!headNode->isStructure) { + masterNode = static_pointer_cast(headNode); + } else { + CopyStructureNodePtr node = static_pointer_cast(headNode); + masterNode = getMasterNode(node,structureOffset); + } + if(masterNode.get()==NULL) { + throw std::invalid_argument( + "PVCopy::getMasterPVField: setstructureOffset not valid"); + } + size_t diff = structureOffset - masterNode->structureOffset; + PVFieldPtr pvMasterField = masterNode->masterPVField; + if(diff==0) return pvMasterField; + PVStructurePtr pvStructure + = static_pointer_cast(pvMasterField); + return pvStructure->getSubField( + pvMasterField->getFieldOffset() + diff); +} + +void PVCopy::initCopy( + PVStructurePtr const ©PVStructure, + BitSetPtr const &bitSet) +{ + bitSet->clear(); + bitSet->set(0); + updateCopyFromBitSet(copyPVStructure,bitSet); +} + +void PVCopy::updateCopySetBitSet( + PVStructurePtr const ©PVStructure, + BitSetPtr const &bitSet) +{ + if(headNode->isStructure) { + CopyStructureNodePtr node = static_pointer_cast(headNode); + updateStructureNodeSetBitSet(copyPVStructure,node,bitSet); + } else { + CopyMasterNodePtr masterNode = static_pointer_cast(headNode); + PVFieldPtr pvMasterField= masterNode->masterPVField; + PVFieldPtr copyPVField = copyPVStructure; + PVFieldPtrArray const & pvCopyFields = copyPVStructure->getPVFields(); + if(pvCopyFields.size()==1) { + copyPVField = pvCopyFields[0]; + } + PVFieldPtr pvField = pvMasterField; + if(pvField->getField()->getType()==epics::pvData::structure) { + updateSubFieldSetBitSet(copyPVField,pvMasterField,bitSet); + return; + } + if(pvCopyFields.size()!=1) { + throw std::logic_error("Logic error"); + } + ConvertPtr convert = getConvert(); + bool isEqual = convert->equals(copyPVField,pvField); + if(!isEqual) { + convert->copy(pvField, copyPVField); + bitSet->set(copyPVField->getFieldOffset()); + } + } +} + +void PVCopy::updateCopyFromBitSet( + PVStructurePtr const ©PVStructure, + BitSetPtr const &bitSet) +{ + bool doAll = bitSet->get(0); + if(headNode->isStructure) { + CopyStructureNodePtr node = static_pointer_cast(headNode); + updateStructureNodeFromBitSet(copyPVStructure,node,bitSet,true,doAll); + } else { + CopyMasterNodePtr masterNode = static_pointer_cast(headNode); + PVFieldPtrArray const & pvCopyFields = copyPVStructure->getPVFields(); + if(pvCopyFields.size()==1) { + updateSubFieldFromBitSet( + pvCopyFields[0], + masterNode->masterPVField,bitSet, + true,doAll); + } else { + updateSubFieldFromBitSet( + copyPVStructure, + masterNode->masterPVField,bitSet, + true,doAll); + } + } +} + +void PVCopy::updateMaster( + PVStructurePtr const ©PVStructure, + BitSetPtr const &bitSet) +{ + bool doAll = bitSet->get(0); + if(headNode->isStructure) { + CopyStructureNodePtr node = + static_pointer_cast(headNode); + updateStructureNodeFromBitSet( + copyPVStructure,node,bitSet,false,doAll); + } else { + CopyMasterNodePtr masterNode = + static_pointer_cast(headNode); + PVFieldPtrArray const & pvCopyFields = + copyPVStructure->getPVFields(); + if(pvCopyFields.size()==1) { + updateSubFieldFromBitSet( + pvCopyFields[0], + masterNode->masterPVField,bitSet, + false,doAll); + } else { + updateSubFieldFromBitSet( + copyPVStructure, + masterNode->masterPVField,bitSet, + false,doAll); + } + } +} + +epics::pvData::String PVCopy::dump() +{ + String builder; + dump(&builder,headNode,0); + return builder; +} + +void PVCopy::dump(String *builder,CopyNodePtr const &node,int indentLevel) +{ + getConvert()->newLine(builder,indentLevel); + std::stringstream ss; + ss << (node->isStructure ? "structureNode" : "masterNode"); + ss << " structureOffset " << node->structureOffset; + ss << " nfields " << node->nfields; + *builder += ss.str(); + PVStructurePtr options = node->options; + if(options.get()!=NULL) { + getConvert()->newLine(builder,indentLevel +1); + options->toString(builder); + getConvert()->newLine(builder,indentLevel); + } + if(!node->isStructure) { + CopyMasterNodePtr masterNode = static_pointer_cast(node); + String name = masterNode->masterPVField->getFullName(); + *builder += " masterField " + name; + return; + } + CopyStructureNodePtr structureNode = + static_pointer_cast(node); + CopyNodePtrArrayPtr nodes = structureNode->nodes; + for(size_t i=0; isize(); ++i) { + if((*nodes)[i].get()==NULL) { + getConvert()->newLine(builder,indentLevel +1); + ss.str(""); + ss << "node[" << i << "] is null"; + *builder += ss.str(); + continue; + } + dump(builder,(*nodes)[i],indentLevel+1); + } +} + +bool PVCopy::init(epics::pvData::PVStructurePtr const &pvRequest) +{ + PVStructurePtr pvMasterStructure = pvMaster; + size_t len = pvRequest->getPVFields().size(); + bool entireMaster = false; + if(len==String::npos) entireMaster = true; + if(len==0) entireMaster = true; + PVStructurePtr pvOptions; + if(len==1 && pvRequest->getSubField("_options")!=NULL) { + pvOptions = pvRequest->getStructureField("_options"); + } + if(entireMaster) { + structure = pvMasterStructure->getStructure(); + CopyMasterNodePtr masterNode(new CopyMasterNode()); + headNode = masterNode; + masterNode->options = pvOptions; + masterNode->isStructure = false; + masterNode->structureOffset = 0; + masterNode->masterPVField = pvMasterStructure; + masterNode->nfields = pvMasterStructure->getNumberFields(); + return true; + } + structure = createStructure(pvMasterStructure,pvRequest); + if(structure==NULL) return false; + cacheInitStructure = createPVStructure(); + headNode = createStructureNodes( + pvMaster, + pvRequest, + cacheInitStructure); + return true; +} + +epics::pvData::String PVCopy::dump( + String const &value, + CopyNodePtr const &node, + int indentLevel) +{ + throw std::logic_error(String("Not Implemented")); +} + + +StructureConstPtr PVCopy::createStructure( + PVStructurePtr const &pvMaster, + PVStructurePtr const &pvFromRequest) +{ + if(pvFromRequest->getStructure()->getNumberFields()==0) { + return pvMaster->getStructure(); + } + PVFieldPtrArray const &pvFromRequestFields = pvFromRequest->getPVFields(); + StringArray const &fromRequestFieldNames = pvFromRequest->getStructure()->getFieldNames(); + size_t length = pvFromRequestFields.size(); + if(length==0) return NULLStructure; + FieldConstPtrArray fields; fields.reserve(length); + StringArray fieldNames; fields.reserve(length); + for(size_t i=0; igetSubField(fieldName); + if(pvMasterField==NULL) continue; + FieldConstPtr field = pvMasterField->getField(); + if(field->getType()==epics::pvData::structure) { + PVStructurePtr pvRequestStructure = static_pointer_cast( + pvFromRequestFields[i]); + if(pvRequestStructure->getNumberFields()>0) { + StringArray const &names = pvRequestStructure->getStructure()-> + getFieldNames(); + size_t num = names.size(); + if(num>0 && names[0].compare("_options")==0) --num; + if(num>0) { + if(pvMasterField->getField()->getType()!=epics::pvData::structure) continue; + fieldNames.push_back(fieldName); + fields.push_back(createStructure( + static_pointer_cast(pvMasterField), + pvRequestStructure)); + continue; + } + } + } + fieldNames.push_back(fieldName); + fields.push_back(field); + } + size_t numsubfields = fields.size(); + if(numsubfields==0) return NULLStructure; + return getFieldCreate()->createStructure(fieldNames, fields); +} + +CopyNodePtr PVCopy::createStructureNodes( + PVStructurePtr const &pvMasterStructure, + PVStructurePtr const &pvFromRequest, + PVStructurePtr const &pvFromCopy) +{ + PVFieldPtrArray const & copyPVFields = pvFromCopy->getPVFields(); + PVStructurePtr pvOptions; + PVFieldPtr pvField = pvFromRequest->getSubField("_options"); + if(pvField!=NULL) pvOptions = static_pointer_cast(pvField); + size_t number = copyPVFields.size(); + CopyNodePtrArrayPtr nodes(new CopyNodePtrArray()); + nodes->reserve(number); + for(size_t i=0; igetFieldName(); + + PVStructurePtr requestPVStructure = static_pointer_cast( + pvFromRequest->getSubField(fieldName)); + PVStructurePtr pvSubFieldOptions; + PVFieldPtr pvField = requestPVStructure->getSubField("_options"); + if(pvField!=NULL) pvSubFieldOptions = static_pointer_cast(pvField); + PVFieldPtr pvMasterField; + PVFieldPtrArray const & pvMasterFields = pvMasterStructure->getPVFields(); + for(size_t j=0; igetFieldName().compare(fieldName)==0) { + pvMasterField = pvMasterFields[j]; + break; + } + } + size_t numberRequest = requestPVStructure->getPVFields().size(); + if(pvSubFieldOptions!=NULL) numberRequest--; + if(numberRequest>0) { + nodes->push_back(createStructureNodes( + static_pointer_cast(pvMasterField), + requestPVStructure, + static_pointer_cast(copyPVField))); + continue; + } + CopyMasterNodePtr masterNode(new CopyMasterNode()); + masterNode->options = pvSubFieldOptions; + masterNode->isStructure = false; + masterNode->masterPVField = pvMasterField; + masterNode->nfields = copyPVField->getNumberFields(); + masterNode->structureOffset = copyPVField->getFieldOffset(); + nodes->push_back(masterNode); + } + CopyStructureNodePtr structureNode(new CopyStructureNode()); + structureNode->isStructure = true; + structureNode->nodes = nodes; + structureNode->structureOffset = pvFromCopy->getFieldOffset(); + structureNode->nfields = pvFromCopy->getNumberFields(); + structureNode->options = pvOptions; + return structureNode; +} + +void PVCopy::updateStructureNodeSetBitSet( + PVStructurePtr const &pvCopy, + CopyStructureNodePtr const &structureNode, + epics::pvData::BitSetPtr const &bitSet) +{ + for(size_t i=0; inodes->size(); i++) { + CopyNodePtr node = (*structureNode->nodes)[i]; + PVFieldPtr pvField = pvCopy->getSubField(node->structureOffset); + if(node->isStructure) { + PVStructurePtr xxx = static_pointer_cast(pvField); + CopyStructureNodePtr yyy = + static_pointer_cast(node); + updateStructureNodeSetBitSet(xxx,yyy,bitSet); + } else { + CopyMasterNodePtr masterNode = + static_pointer_cast(node); + updateSubFieldSetBitSet(pvField,masterNode->masterPVField,bitSet); + } + } +} + +void PVCopy::updateSubFieldSetBitSet( + PVFieldPtr const &pvCopy, + PVFieldPtr const &pvMaster, + BitSetPtr const &bitSet) +{ + FieldConstPtr field = pvCopy->getField(); + Type type = field->getType(); + if(type!=epics::pvData::structure) { + ConvertPtr convert = getConvert(); + bool isEqual = convert->equals(pvCopy,pvMaster); + if(isEqual) { + if(type==structureArray) { + // always act as though a change occurred. + // Note that array elements are shared. + bitSet->set(pvCopy->getFieldOffset()); + } + } + if(isEqual) return; + convert->copy(pvMaster, pvCopy); + bitSet->set(pvCopy->getFieldOffset()); + return; + } + PVStructurePtr pvCopyStructure = static_pointer_cast(pvCopy); + PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields(); + PVStructurePtr pvMasterStructure = + static_pointer_cast(pvMaster); + PVFieldPtrArray const & pvMasterFields = + pvMasterStructure->getPVFields(); + size_t length = pvCopyFields.size(); + for(size_t i=0; istructureOffset; + if(!doAll) { + size_t nextSet = bitSet->nextSetBit(offset); + if(nextSet==String::npos) return; + } + if(offset>=pvCopy->getNextFieldOffset()) return; + if(!doAll) doAll = bitSet->get(offset); + CopyNodePtrArrayPtr nodes = structureNode->nodes; + for(size_t i=0; isize(); i++) { + CopyNodePtr node = (*nodes)[i]; + PVFieldPtr pvField = pvCopy->getSubField(node->structureOffset); + if(node->isStructure) { + PVStructurePtr xxx = static_pointer_cast(pvField); + CopyStructureNodePtr subStructureNode = + static_pointer_cast(node); + updateStructureNodeFromBitSet( + xxx,subStructureNode,bitSet,toCopy,doAll); + } else { + CopyMasterNodePtr masterNode = + static_pointer_cast(node); + updateSubFieldFromBitSet( + pvField,masterNode->masterPVField,bitSet,toCopy,doAll); + } + } +} + +void PVCopy::updateSubFieldFromBitSet( + PVFieldPtr const &pvCopy, + PVFieldPtr const &pvMasterField, + BitSetPtr const &bitSet, + bool toCopy, + bool doAll) +{ + if(!doAll) { + doAll = bitSet->get(pvCopy->getFieldOffset()); + } + if(!doAll) { + size_t offset = pvCopy->getFieldOffset(); + size_t nextSet = bitSet->nextSetBit(offset); + if(nextSet==String::npos) return; + if(nextSet>=pvCopy->getNextFieldOffset()) return; + } + ConvertPtr convert = getConvert(); + if(pvCopy->getField()->getType()==epics::pvData::structure) { + PVStructurePtr pvCopyStructure = + static_pointer_cast(pvCopy); + PVFieldPtrArray const & pvCopyFields = pvCopyStructure->getPVFields(); + if(pvMasterField->getField()->getType() + !=epics::pvData::structure) + { + if(pvCopyFields.size()!=1) { + throw std::logic_error(String("Logic error")); + } + if(toCopy) { + convert->copy(pvMasterField, pvCopyFields[0]); + } else { + convert->copy(pvCopyFields[0], pvMasterField); + } + return; + } + PVStructurePtr pvMasterStructure = + static_pointer_cast(pvMasterField); + PVFieldPtrArray const & pvMasterFields = + pvMasterStructure->getPVFields(); + for(size_t i=0; icopy(pvMasterField, pvCopy); + } else { + convert->copy(pvCopy, pvMasterField); + } + } +} + +CopyMasterNodePtr PVCopy::getCopyOffset( + CopyStructureNodePtr const &structureNode, + PVFieldPtr const &masterPVField) +{ + size_t offset = masterPVField->getFieldOffset(); + CopyNodePtrArrayPtr nodes = structureNode->nodes; + for(size_t i=0; i< nodes->size(); i++) { + CopyNodePtr node = (*nodes)[i]; + if(!node->isStructure) { + CopyMasterNodePtr masterNode = + static_pointer_cast(node); + size_t off = masterNode->masterPVField->getFieldOffset(); + size_t nextOffset = masterNode->masterPVField->getNextFieldOffset(); + if(offset>= off && offset(node); + CopyMasterNodePtr masterNode = + getCopyOffset(subNode,masterPVField); + if(masterNode.get()!=NULL) return masterNode; + } + } + return NULLCopyMasterNode; +} + +CopyMasterNodePtr PVCopy::getMasterNode( + CopyStructureNodePtr const &structureNode, + std::size_t structureOffset) +{ + CopyNodePtrArrayPtr nodes = structureNode->nodes; + for(size_t i=0; i< nodes->size(); i++) { + CopyNodePtr node = (*nodes)[i]; + if(structureOffset>=(node->structureOffset + node->nfields)) continue; + if(!node->isStructure) { + CopyMasterNodePtr masterNode = + static_pointer_cast(node); + return masterNode; + } + CopyStructureNodePtr subNode = + static_pointer_cast(node); + return getMasterNode(subNode,structureOffset); + } + return NULLCopyMasterNode; +} + +}} diff --git a/pvDataApp/copy/pvCopy.h b/pvDataApp/copy/pvCopy.h new file mode 100644 index 0000000..9d36ed3 --- /dev/null +++ b/pvDataApp/copy/pvCopy.h @@ -0,0 +1,145 @@ +/* pvCopy.h */ +/** + * Copyright - See the COPYRIGHT that is included with this distribution. + * EPICS pvData is distributed subject to a Software License Agreement found + * in file LICENSE that is included with this distribution. + */ +/** + * @author Marty Kraimer + * @date 2013.04 + */ +#ifndef PVCOPY_H +#define PVCOPY_H +#include +#include +#include + +#include + +#include +#include + +namespace epics { namespace pvData{ + +class PVCopyTraverseMasterCallback; +typedef std::tr1::shared_ptr PVCopyTraverseMasterCallbackPtr; + +class epicsShareClass PVCopyTraverseMasterCallback +{ +public: + POINTER_DEFINITIONS(PVCopyTraverseMasterCallback); + virtual ~PVCopyTraverseMasterCallback() {} + virtual void nextMasterPVField(epics::pvData::PVFieldPtr const &pvField) = 0; +}; + + +class PVCopy; +typedef std::tr1::shared_ptr PVCopyPtr; + +struct CopyNode; +typedef std::tr1::shared_ptr CopyNodePtr; +struct CopyMasterNode; +typedef std::tr1::shared_ptr CopyMasterNodePtr; +struct CopyStructureNode; +typedef std::tr1::shared_ptr CopyStructureNodePtr; + + +class epicsShareClass PVCopy : + public std::tr1::enable_shared_from_this +{ +public: + POINTER_DEFINITIONS(PVCopy); + static PVCopyPtr create( + PVStructurePtr const &pvMaster, + PVStructurePtr const &pvRequest, + String const & structureName); + virtual ~PVCopy(){} + virtual void destroy(); + PVStructurePtr getPVMaster(); + void traverseMaster(PVCopyTraverseMasterCallbackPtr const & callback) + { + traverseMaster(headNode,callback); + } + StructureConstPtr getStructure(); + PVStructurePtr createPVStructure(); + std::size_t getCopyOffset(PVFieldPtr const &masterPVField); + std::size_t getCopyOffset( + PVStructurePtr const &masterPVStructure, + PVFieldPtr const &masterPVField); + PVFieldPtr getMasterPVField(std::size_t structureOffset); + void initCopy( + PVStructurePtr const ©PVStructure, + BitSetPtr const &bitSet); + void updateCopySetBitSet( + PVStructurePtr const ©PVStructure, + BitSetPtr const &bitSet); + void updateCopyFromBitSet( + PVStructurePtr const ©PVStructure, + BitSetPtr const &bitSet); + void updateMaster( + PVStructurePtr const ©PVStructure, + BitSetPtr const &bitSet); + PVStructurePtr getOptions( + PVStructurePtr const ©PVStructure,std::size_t fieldOffset); + String dump(); +private: + void dump( + String *builder, + CopyNodePtr const &node, + int indentLevel); + PVCopyPtr getPtrSelf() + { + return shared_from_this(); + } + void traverseMaster(CopyNodePtr const &node, PVCopyTraverseMasterCallbackPtr const & callback); + + PVStructurePtr pvMaster; + StructureConstPtr structure; + CopyNodePtr headNode; + PVStructurePtr cacheInitStructure; + PVCopy(PVStructurePtr const &pvMaster); + friend class PVCopyMonitor; + bool init(PVStructurePtr const &pvRequest); + String dump( + String const &value, + CopyNodePtr const &node, + int indentLevel); + StructureConstPtr createStructure( + PVStructurePtr const &pvMaster, + PVStructurePtr const &pvFromRequest); + CopyNodePtr createStructureNodes( + PVStructurePtr const &pvMasterStructure, + PVStructurePtr const &pvFromRequest, + PVStructurePtr const &pvFromField); + void updateStructureNodeSetBitSet( + PVStructurePtr const &pvCopy, + CopyStructureNodePtr const &structureNode, + BitSetPtr const &bitSet); + void updateSubFieldSetBitSet( + PVFieldPtr const &pvCopy, + PVFieldPtr const &pvMaster, + BitSetPtr const &bitSet); + void updateStructureNodeFromBitSet( + PVStructurePtr const &pvCopy, + CopyStructureNodePtr const &structureNode, + BitSetPtr const &bitSet, + bool toCopy, + bool doAll); + void updateSubFieldFromBitSet( + PVFieldPtr const &pvCopy, + PVFieldPtr const &pvMasterField, + BitSetPtr const &bitSet, + bool toCopy, + bool doAll); + CopyMasterNodePtr getCopyOffset( + CopyStructureNodePtr const &structureNode, + PVFieldPtr const &masterPVField); + CopyMasterNodePtr getMasterNode( + CopyStructureNodePtr const &structureNode, + std::size_t structureOffset); + +}; + +}} + +#endif /* PVCOPY_H */ diff --git a/pvDataApp/factory/FieldCreateFactory.cpp b/pvDataApp/factory/FieldCreateFactory.cpp index c88cc02..5e010a9 100644 --- a/pvDataApp/factory/FieldCreateFactory.cpp +++ b/pvDataApp/factory/FieldCreateFactory.cpp @@ -781,6 +781,13 @@ ScalarArrayConstPtr FieldCreate::createScalarArray(ScalarType elementType) const return scalarArrays[elementType]; } +StructureConstPtr FieldCreate::createStructure () const +{ + StringArray fieldNames; + FieldConstPtrArray fields; + return createStructure(fieldNames,fields); +} + StructureConstPtr FieldCreate::createStructure ( StringArray const & fieldNames,FieldConstPtrArray const & fields) const { diff --git a/pvDataApp/factory/PVAuxInfoImpl.cpp b/pvDataApp/factory/PVAuxInfoImpl.cpp deleted file mode 100644 index 907b580..0000000 --- a/pvDataApp/factory/PVAuxInfoImpl.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/*PVAuxInfo.cpp*/ -/** - * Copyright - See the COPYRIGHT that is included with this distribution. - * EPICS pvData is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - */ -/** - * @author mrk - */ -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include -#include -#include -#include -#include - -namespace epics { namespace pvData { - - -PVAuxInfo::PVAuxInfo(PVField * pvField) - : pvField(pvField), - pvInfos(std::map > ()) -{ -} - -PVAuxInfo::~PVAuxInfo() -{ -} - - -PVField * PVAuxInfo::getPVField() { - return pvField; -} - - -PVScalarPtr PVAuxInfo::createInfo(String const & key,ScalarType scalarType) -{ - PVInfoIter iter = pvInfos.find(key); - if(iter!=pvInfos.end()) { - String message = key.c_str(); - message += " already exists "; - pvField->message(message,errorMessage); - return nullPVScalar; - } - PVScalarPtr pvScalar = getPVDataCreate()->createPVScalar(scalarType); - pvInfos.insert(PVInfoPair(key,pvScalar)); - return pvScalar; -} - -PVScalarPtr PVAuxInfo::getInfo(String const & key) -{ - PVInfoIter iter; - iter = pvInfos.find(key); - if(iter==pvInfos.end()) return nullPVScalar; - return iter->second; -} - -PVAuxInfo::PVInfoMap & PVAuxInfo::getInfoMap() -{ - return pvInfos; -} - - -void PVAuxInfo::toString(StringBuilder buf) -{ - PVAuxInfo::toString(buf,0); -} - -void PVAuxInfo::toString(StringBuilder buf,int indentLevel) -{ - if(pvInfos.size()<=0) return; - ConvertPtr convert = getConvert(); - convert->newLine(buf,indentLevel); - *buf += "auxInfo"; - for(PVInfoIter iter = pvInfos.begin(); iter!= pvInfos.end(); ++iter) { - convert->newLine(buf,indentLevel+1); - PVFieldPtr value = iter->second; - value->toString(buf,indentLevel + 1); - } -} -}} diff --git a/pvDataApp/factory/PVDataCreateFactory.cpp b/pvDataApp/factory/PVDataCreateFactory.cpp index 81ba888..b3e29a2 100644 --- a/pvDataApp/factory/PVDataCreateFactory.cpp +++ b/pvDataApp/factory/PVDataCreateFactory.cpp @@ -557,16 +557,6 @@ PVScalarPtr PVDataCreate::createPVScalar(PVScalarPtr const & scalarToClone) ScalarType scalarType = scalarToClone->getScalar()->getScalarType(); PVScalarPtr pvScalar = createPVScalar(scalarType); getConvert()->copyScalar(scalarToClone, pvScalar); - PVAuxInfoPtr from = scalarToClone->getPVAuxInfo(); - PVAuxInfoPtr to = pvScalar->getPVAuxInfo(); - PVAuxInfo::PVInfoMap & map = from->getInfoMap(); - for(PVAuxInfo::PVInfoIter iter = map.begin(); iter!= map.end(); ++iter) { - String key = iter->first; - PVScalarPtr pvFrom = iter->second; - ScalarConstPtr scalar = pvFrom->getScalar(); - PVScalarPtr pvTo = to->createInfo(key,scalar->getScalarType()); - getConvert()->copyScalar(pvFrom,pvTo); - } return pvScalar; } @@ -616,16 +606,6 @@ PVScalarArrayPtr PVDataCreate::createPVScalarArray( PVScalarArrayPtr pvArray = createPVScalarArray( arrayToClone->getScalarArray()->getElementType()); pvArray->assign(*arrayToClone.get()); - PVAuxInfoPtr from = arrayToClone->getPVAuxInfo(); - PVAuxInfoPtr to = pvArray->getPVAuxInfo(); - PVAuxInfo::PVInfoMap & map = from->getInfoMap(); - for(PVAuxInfo::PVInfoIter iter = map.begin(); iter!= map.end(); ++iter) { - String key = iter->first; - PVScalarPtr pvFrom = iter->second; - ScalarConstPtr scalar = pvFrom->getScalar(); - PVScalarPtr pvTo = to->createInfo(key,scalar->getScalarType()); - getConvert()->copyScalar(pvFrom,pvTo); - } return pvArray; } diff --git a/pvDataApp/factory/PVField.cpp b/pvDataApp/factory/PVField.cpp index a01c537..0e80c08 100644 --- a/pvDataApp/factory/PVField.cpp +++ b/pvDataApp/factory/PVField.cpp @@ -35,49 +35,6 @@ PVField::PVField(FieldConstPtr field) PVField::~PVField() { } -void PVField::message( - String message, - MessageType messageType, - String fullFieldName) -{ - if(parent!=NULL) { - if(fullFieldName.length()>0) { - fullFieldName = fieldName + '.' + fullFieldName; - } else { - fullFieldName = fieldName; - } - parent->message(message,messageType,fullFieldName); - return; - } - message = fullFieldName + " " + message; - if(requester) { - requester->message(message,messageType); - } else { - printf("%s %s %s\n", - getMessageTypeName(messageType).c_str(), - fieldName.c_str(), - message.c_str()); - } -} - -void PVField::message(String message,MessageType messageType) -{ - PVField::message(message,messageType,""); -} - -void PVField::setRequester(RequesterPtr const &req) -{ - if(parent!=NULL) { - throw std::logic_error( - "PVField::setRequester only legal for top level structure"); - } - if(requester.get()!=NULL) { - if(requester.get()==req.get()) return; - throw std::logic_error( - "PVField::setRequester requester is already present"); - } - requester = req; -} size_t PVField::getFieldOffset() const { @@ -97,12 +54,6 @@ size_t PVField::getNumberFields() const return (nextFieldOffset - fieldOffset); } -PVAuxInfoPtr & PVField::getPVAuxInfo(){ - if(pvAuxInfo.get()==NULL) { - pvAuxInfo = PVAuxInfoPtr(new PVAuxInfo(this)); - } - return pvAuxInfo; -} bool PVField::isImmutable() const {return immutable;} @@ -112,46 +63,6 @@ const FieldConstPtr & PVField::getField() const {return field;} PVStructure *PVField::getParent() const {return parent;} -void PVField::replacePVField(const PVFieldPtr & newPVField) -{ - if(parent==NULL) { - throw std::logic_error("no parent"); - } - PVFieldPtrArray pvFields = parent->getPVFields(); - StructureConstPtr structure = parent->getStructure(); - StringArray fieldNames = structure->getFieldNames(); - for(size_t i=0; igetFieldName().compare(fieldNames[i]) == 0) { - pvFields[i] = newPVField; - return; - } - } - throw std::logic_error("Did not find field in parent"); -} - -void PVField::replaceField(FieldConstPtr &xxx) -{ - field = xxx; -} - -void PVField::renameField(String const & newName) -{ - if(parent==NULL) { - throw std::logic_error("no parent"); - } - std::tr1::shared_ptr parentStructure = const_pointer_cast( - parent->getStructure()); - PVFieldPtrArray pvFields = parent->getPVFields(); - for(size_t i=0; irenameField(i,newName); - fieldName = newName; - return; - } - } - throw std::logic_error("Did not find field in parent"); -} - void PVField::postPut() { if(postHandler.get()!=NULL) postHandler->postPut(); @@ -187,14 +98,11 @@ void PVField::toString(StringBuilder buf) void PVField::toString(StringBuilder buf,int indentLevel) { Convert().getString(buf,this,indentLevel); - if(pvAuxInfo.get()!=NULL) pvAuxInfo->toString(buf,indentLevel); } std::ostream& operator<<(std::ostream& o, const PVField& f) { std::ostream& ro = f.dumpValue(o); - // TODO I do not want to call getPVAuxInfo() since it lazily creates a new instance of it - //if (f.pvAuxInfo.get()!=NULL) ro << *(f.pvAuxInfo.get()); return ro; }; diff --git a/pvDataApp/factory/PVStructure.cpp b/pvDataApp/factory/PVStructure.cpp index 64d47cc..6ed658b 100644 --- a/pvDataApp/factory/PVStructure.cpp +++ b/pvDataApp/factory/PVStructure.cpp @@ -60,7 +60,7 @@ PVStructure::PVStructure(StructureConstPtr const & structurePtr) pvFields.reserve(numberFields); PVDataCreatePtr pvDataCreate = getPVDataCreate(); for(size_t i=0; icreatePVField(fields[i])); + pvFields.push_back(pvDataCreate->createPVField(fields[i])); } for(size_t i=0; isetParentAndName(this,fieldNames[i]); @@ -134,110 +134,6 @@ PVFieldPtr PVStructure::getSubField(size_t fieldOffset) const throw std::logic_error("PVStructure.getSubField: Logic error"); } -void PVStructure::fixParentStructure() -{ - PVStructure *parent = getParent(); - if(parent==NULL) return; - StructureConstPtr parentStructure = parent->structurePtr; - String fieldName = getFieldName(); - size_t index = parentStructure->getFieldIndex(fieldName); - StringArray const &fieldNames = parentStructure->getFieldNames(); - size_t num = fieldNames.size(); - FieldConstPtrArray fields(num); - FieldConstPtrArray const & oldFields = parentStructure->getFields(); - for(size_t i=0; i< num; i++) { - if(i==index) { - fields[i] = structurePtr; - } else { - fields[i] = oldFields[i]; - } - } - FieldConstPtr field = getFieldCreate()->createStructure( - parentStructure->getID(),fieldNames,fields); - parent->replaceField(field); - parent->fixParentStructure(); -} - -void PVStructure::appendPVField( - String const &fieldName, - PVFieldPtr const & pvField) -{ - size_t origLength = pvFields.size(); - size_t newLength = origLength+1; - PVFieldPtrArray * xxx = const_cast(&pvFields); - xxx->push_back(pvField); - FieldConstPtr field = getFieldCreate()->appendField( - structurePtr,fieldName,pvField->getField()); - replaceField(field); - structurePtr = static_pointer_cast(field); - StringArray fieldNames = structurePtr->getFieldNames(); - for(size_t i=0; isetParentAndName(this,fieldNames[i]); - } - fixParentStructure(); -} - -void PVStructure::appendPVFields( - StringArray const & fieldNames, - PVFieldPtrArray const & pvFields) -{ - size_t origLength = this->pvFields.size(); - size_t extra = fieldNames.size(); - if(extra==0) return; - size_t newLength = origLength + extra; - PVFieldPtrArray * xxx = const_cast(&this->pvFields); - xxx->reserve(newLength); - for(size_t i=0; ipush_back(pvFields[i]); - } - FieldConstPtrArray fields; - fields.reserve(extra); - for(size_t i=0; igetField()); - FieldConstPtr field = getFieldCreate()->appendFields( - structurePtr,fieldNames,fields); - replaceField(field); - structurePtr = static_pointer_cast(field); - StringArray names = structurePtr->getFieldNames(); - for(size_t i=0; isetParentAndName(this,names[i]); - } - fixParentStructure(); -} - -void PVStructure::removePVField(String const &fieldName) -{ - PVFieldPtr pvField = getSubField(fieldName); - if(pvField.get()==NULL) { - return; - } - size_t origLength = pvFields.size(); - size_t newLength = origLength - 1; - PVFieldPtrArray const & origPVFields = pvFields; - FieldConstPtrArray origFields = structurePtr->getFields(); - PVFieldPtrArray newPVFields; - newPVFields.reserve(newLength); - StringArray newFieldNames; - newFieldNames.reserve(newLength); - FieldConstPtrArray fields; - fields.reserve(newLength); - for(size_t i=0; igetFieldName()); - newPVFields.push_back(origPVFields[i]); - fields.push_back(origFields[i]); - } - } - PVFieldPtrArray * xxx = const_cast(&pvFields); - xxx->swap(newPVFields); - FieldConstPtr field = getFieldCreate()->createStructure( - structurePtr->getID(),newFieldNames,fields); - replaceField(field); - structurePtr = static_pointer_cast(field); - StringArray fieldNames = structurePtr->getFieldNames(); - for(size_t i=0; isetParentAndName(this,fieldNames[i]); - } -} PVBooleanPtr PVStructure::getBooleanField(String const &fieldName) { @@ -341,18 +237,6 @@ PVUnionArrayPtr PVStructure::getUnionArrayField( return getSubField(fieldName); } -String PVStructure::getExtendsStructureName() const -{ - return extendsStructureName; -} - -bool PVStructure::putExtendsStructureName( - String const &xxx) -{ - if(extendsStructureName.length()!=0) return false; - extendsStructureName = xxx; - return true; -} void PVStructure::serialize(ByteBuffer *pbuffer, SerializableControl *pflusher) const { @@ -477,10 +361,6 @@ static PVFieldPtr findSubField( std::ostream& PVStructure::dumpValue(std::ostream& o) const { o << format::indent() << getStructure()->getID() << ' ' << getFieldName(); - String extendsName = getExtendsStructureName(); - if(extendsName.length()>0) { - o << " extends " << extendsName; - } o << std::endl; { format::indent_scope s(o); diff --git a/pvDataApp/factory/printer.cpp b/pvDataApp/factory/printer.cpp index 8d74304..37a075f 100644 --- a/pvDataApp/factory/printer.cpp +++ b/pvDataApp/factory/printer.cpp @@ -199,9 +199,6 @@ void PrinterPlain::beginStructure(const PVStructure& pv) { indentN(S(), ilvl); S() << pv.getStructure()->getID() << " " << pv.getFieldName(); - String ename(pv.getExtendsStructureName()); - if(!ename.empty()) - S() << " extends " << ename; S() << std::endl; ilvl++; } diff --git a/pvDataApp/monitor/monitor.h b/pvDataApp/monitor/monitor.h index 74006a3..882d59d 100644 --- a/pvDataApp/monitor/monitor.h +++ b/pvDataApp/monitor/monitor.h @@ -15,6 +15,7 @@ #include #include #include +#include #include diff --git a/pvDataApp/property/pvAlarm.cpp b/pvDataApp/property/pvAlarm.cpp index 001fb44..6506646 100644 --- a/pvDataApp/property/pvAlarm.cpp +++ b/pvDataApp/property/pvAlarm.cpp @@ -25,25 +25,17 @@ String PVAlarm::notAttached("Not attached to an alarm structure"); bool PVAlarm::attach(PVFieldPtr const & pvField) { - if(pvField->getField()->getType()!=structure) { - pvField->message(noAlarmFound,errorMessage); - return false; - } + if(pvField->getField()->getType()!=structure) return false; PVStructurePtr pvStructure = static_pointer_cast(pvField); pvSeverity = pvStructure->getIntField("severity"); - if(pvSeverity.get()==NULL) { - pvField->message(noAlarmFound,errorMessage); - return false; - } + if(pvSeverity.get()==NULL) return false; pvStatus = pvStructure->getIntField("status"); if(pvStatus.get()==NULL) { - pvField->message(noAlarmFound,errorMessage); pvSeverity.reset(); return false; } pvMessage = pvStructure->getStringField("message"); if(pvMessage.get()==NULL) { - pvField->message(noAlarmFound,errorMessage); pvSeverity.reset(); pvStatus.reset(); return false; diff --git a/pvDataApp/property/pvControl.cpp b/pvDataApp/property/pvControl.cpp index 8f761ff..c1b8576 100644 --- a/pvDataApp/property/pvControl.cpp +++ b/pvDataApp/property/pvControl.cpp @@ -25,20 +25,13 @@ String PVControl::notAttached("Not attached to an control structure"); bool PVControl::attach(PVFieldPtr const & pvField) { - if(pvField->getField()->getType()!=structure) { - pvField->message(noControlFound,errorMessage); - return false; - } + if(pvField->getField()->getType()!=structure) return false; PVStructurePtr pvStructure = static_pointer_cast(pvField); pvLow = pvStructure->getDoubleField("limitLow"); - if(pvLow.get()==NULL) { - pvField->message(noControlFound,errorMessage); - return false; - } + if(pvLow.get()==NULL) return false; pvHigh = pvStructure->getDoubleField(String("limitHigh")); if(pvHigh.get()==NULL) { pvLow.reset(); - pvField->message(noControlFound,errorMessage); return false; } return true; diff --git a/pvDataApp/property/pvDisplay.cpp b/pvDataApp/property/pvDisplay.cpp index f7e6887..a5dd085 100644 --- a/pvDataApp/property/pvDisplay.cpp +++ b/pvDataApp/property/pvDisplay.cpp @@ -25,37 +25,27 @@ String PVDisplay::notAttached("Not attached to an display structure"); bool PVDisplay::attach(PVFieldPtr const & pvField) { - if(pvField->getField()->getType()!=structure) { - pvField->message(noDisplayFound,errorMessage); - return false; - } + if(pvField->getField()->getType()!=structure) return false; PVStructurePtr pvStructure = static_pointer_cast(pvField); pvDescription = pvStructure->getStringField("description"); - if(pvDescription.get()==NULL) { - pvField->message(noDisplayFound,errorMessage); - return false; - } + if(pvDescription.get()==NULL) return false; pvFormat = pvStructure->getStringField("format"); if(pvFormat.get()==NULL) { - pvField->message(noDisplayFound,errorMessage); detach(); return false; } pvUnits = pvStructure->getStringField("units"); if(pvUnits.get()==NULL) { - pvField->message(noDisplayFound,errorMessage); detach(); return false; } pvLow = pvStructure->getDoubleField(String("limitLow")); if(pvLow.get()==NULL) { - pvField->message(noDisplayFound,errorMessage); detach(); return false; } pvHigh = pvStructure->getDoubleField(String("limitHigh")); if(pvHigh.get()==NULL) { - pvField->message(noDisplayFound,errorMessage); detach(); return false; } diff --git a/pvDataApp/property/pvEnumerated.cpp b/pvDataApp/property/pvEnumerated.cpp index 25f883f..05ec180 100644 --- a/pvDataApp/property/pvEnumerated.cpp +++ b/pvDataApp/property/pvEnumerated.cpp @@ -25,21 +25,14 @@ String PVEnumerated::notAttached("Not attached to an enumerated structure"); bool PVEnumerated::attach(PVFieldPtr const & pvField) { - if(pvField->getField()->getType()!=structure) { - pvField->message(notFound,errorMessage); - return false; - } + if(pvField->getField()->getType()!=structure) return false; PVStructurePtr pvStructure = static_pointer_cast(pvField); pvIndex = pvStructure->getIntField("index"); - if(pvIndex.get()==NULL) { - pvField->message(notFound,errorMessage); - return false; - } + if(pvIndex.get()==NULL) return false; PVScalarArrayPtr pvScalarArray = pvStructure->getScalarArrayField( "choices",pvString); if(pvScalarArray.get()==NULL) { pvIndex.reset(); - pvField->message(notFound,errorMessage); return false; } pvChoices = static_pointer_cast(pvScalarArray); diff --git a/pvDataApp/property/pvTimeStamp.cpp b/pvDataApp/property/pvTimeStamp.cpp index daf2352..92233c9 100644 --- a/pvDataApp/property/pvTimeStamp.cpp +++ b/pvDataApp/property/pvTimeStamp.cpp @@ -25,10 +25,7 @@ String PVTimeStamp::notAttached("Not attached to a timeStamp structure"); bool PVTimeStamp::attach(PVFieldPtr const & pvField) { - if(pvField->getField()->getType()!=structure) { - pvField->message(noTimeStamp,errorMessage); - return false; - } + if(pvField->getField()->getType()!=structure) return false; PVStructurePtr xxx = static_pointer_cast(pvField); PVStructure* pvStructure = xxx.get(); while(true) { diff --git a/pvDataApp/pv/pvData.h b/pvDataApp/pv/pvData.h index 41b6876..ba9ddf5 100644 --- a/pvDataApp/pv/pvData.h +++ b/pvDataApp/pv/pvData.h @@ -14,14 +14,6 @@ #define NOMINMAX #endif -#if defined(__GNUC__) && !(defined(__vxworks) && !defined(_WRS_VXWORKS_MAJOR)) -#define USAGE_DEPRECATED __attribute__((deprecated)) -#define USAGE_ERROR(MSG) __attribute__((error(MSG))) -#else -#define USAGE_DEPRECATED -#define USAGE_ERROR(MSG) { throw std::runtime_error(MSG); } -#endif - #include #include #include @@ -31,7 +23,6 @@ #include #include -#include #include #include @@ -106,7 +97,6 @@ epicsShareExtern array_at_internal operator<<(std::ostream& str, array_at const& }; -class PVAuxInfo; class PostHandler; class PVField; @@ -124,11 +114,6 @@ template class PVScalarValue; template class PVValueArray; -/** - * typedef for a pointer to a PVAuxInfo. - */ -typedef std::tr1::shared_ptr PVAuxInfoPtr; - /** * typedef for a pointer to a PostHandler. */ @@ -198,67 +183,6 @@ typedef std::tr1::shared_ptr PVUnionArrayPtrArrayPtr; class PVDataCreate; typedef std::tr1::shared_ptr PVDataCreatePtr; -/** - * This class provides auxillary information about a PVField. - * Each item is stored as a PVScalar. - * A (key,value) is provided for accessing the items where the key is a String. - */ -class epicsShareClass PVAuxInfo : private NoDefaultMethods { -public: - typedef std::map PVInfoMap; - typedef std::map::iterator PVInfoIter; - typedef std::pair PVInfoPair; - - /** - * Constructor - * @param The fields to which the Auxinfo is attached. - */ - PVAuxInfo(PVField *pvField); - /** - * Destructor - */ - ~PVAuxInfo(); - /** - * Get the PVField to which the Auxinfo is attached. - * @return The fields to which the Auxinfo is attached. - */ - PVField * getPVField(); - /** - * Add a new auxiliary item or retrieve the interface to an existing item. - * - * @param key The key. - * @param scalarType The scalarType for the new item being added/ - * @return The new PVScalar that has been added to the Auxinfo. - */ - PVScalarPtr createInfo(String const & key,ScalarType scalarType); - /** - * Get the Auxinfo with the specified key. - * @return The PVScalar or null if it does not exist. - */ - PVScalarPtr getInfo(String const & key); - /** - * Get the map for the info. - * @return The map; - */ - PVInfoMap & getInfoMap(); - /** - * Convert the Auxinfo to a string and add it to builder. - * @param builder The string builder. - */ - void toString(StringBuilder buf); - /** - * Convert the Auxinfo to a string and add it to builder. - * @param builder The string builder. - * @param indentLevel The number of blanks at the beginning of new lines. - */ - void toString(StringBuilder buf,int indentLevel); -private: - PVScalarPtr nullPVScalar; - PVField * pvField; - PVInfoMap pvInfos; - friend class PVDataCreate; -}; - /** * This class is implemented by code that calls setPostHander */ @@ -294,12 +218,6 @@ public: * Destructor */ virtual ~PVField(); - /** - * Called to report errors associated with the field. - * @param message The message. - * @param messageType The message type. - */ - virtual void message(String message,MessageType messageType) ; /** * Get the fieldName for this field. * @return The name or empty string if top level field. @@ -311,12 +229,6 @@ public: * each name. */ String getFullName() const; - /** - * Register the message requester. - * At most one requester can be registered. - * @param prequester The requester. - */ - virtual void setRequester(RequesterPtr const &prequester); /** * Get offset of the PVField field within top level structure. * Every field within the PVStructure has a unique offset. @@ -338,11 +250,6 @@ public: * This is equal to nextFieldOffset - fieldOffset. */ std::size_t getNumberFields() const; - /** - * Get the PVAuxInfo interface for the PVField. - * @return The PVAuxInfo interface. - */ - PVAuxInfoPtr & getPVAuxInfo(); /** * Is the field immutable, i.e. does it not allow changes. * @return (false,true) if it (is not, is) immutable. @@ -363,16 +270,6 @@ public: * @return The parent interface or null if this is PVRecord */ PVStructure * getParent() const ; - /** - * Replace the data implementation for the field. - * @param newPVField The new implementation - */ - void replacePVField(const PVFieldPtr& newPVField); - /** - * Rename the field name. - * @param newName The new name. - */ - void renameField(String const & newName); /** * postPut. Called when the field is updated by the implementation. */ @@ -417,20 +314,16 @@ protected: } PVField(FieldConstPtr field); void setParentAndName(PVStructure *parent, String const & fieldName); - void replaceField(FieldConstPtr &field); private: - void message(String message,MessageType messageType,String fullFieldName); static void computeOffset(const PVField *pvField); static void computeOffset(const PVField *pvField,std::size_t offset); String notImplemented; - PVAuxInfoPtr pvAuxInfo; String fieldName; PVStructure *parent; FieldConstPtr field; size_t fieldOffset; size_t nextFieldOffset; bool immutable; - RequesterPtr requester; PostHandlerPtr postHandler; friend class PVDataCreate; friend class PVStructure; @@ -696,31 +589,6 @@ private: epicsShareExtern std::ostream& operator<<(format::array_at_internal const& manip, const PVArray& array); -/** - * Class provided by caller of get - */ -template -class PVArrayData { -private: - std::vector init; -public: - POINTER_DEFINITIONS(PVArrayData); - typedef T value_type; - typedef T* pointer; - typedef const T* const_pointer; - /** - * The data array. - */ - std::vector & data; - /** - * The offset. This is the offset into the actual array of the first element in data, - */ - std::size_t offset; - PVArrayData() - : data(init) - {} -}; - /** * Base class for a scalarArray. @@ -864,24 +732,6 @@ public: return std::tr1::shared_ptr(); } - /** - * Append a field to the structure. - * @param fieldName The name of the field to append. - * @param pvField The field to append. - */ - void appendPVField(String const &fieldName,PVFieldPtr const & pvField); - /** - * Append fields to the structure. - * @param fieldNames The names of the fields to add. - * @param pvFields The fields to append. - * @return Pointer to the field or null if field does not exist. - */ - void appendPVFields(StringArray const & fieldNames,PVFieldPtrArray const & pvFields); - /** - * Remove a field from the structure. - * @param fieldName The name of the field to remove. - */ - void removePVField(String const &fieldName); /** * Get a boolean field with the specified name. * @param fieldName The name of the field to get. @@ -987,17 +837,6 @@ public: * @return Pointer to the field of null if a field with that name and type does not exist. */ PVUnionArrayPtr getUnionArrayField(String const &fieldName) ; - /** - * Get the name if this structure extends another structure. - * @return The string which may be null. - */ - String getExtendsStructureName() const; - /** - * Put the extends name. - * @param extendsStructureName The name. - */ - bool putExtendsStructureName( - String const &extendsStructureName); /** * Serialize. * @param pbuffer The byte buffer. @@ -1043,7 +882,6 @@ public: virtual std::ostream& dumpValue(std::ostream& o) const; private: - void fixParentStructure(); static PVFieldPtr nullPVField; static PVBooleanPtr nullPVBoolean; static PVBytePtr nullPVByte; @@ -1225,12 +1063,6 @@ namespace detail { typedef ::epics::pvData::shared_vector svector; typedef ::epics::pvData::shared_vector const_svector; - // begin deprecated - typedef PVArrayData ArrayDataType; - typedef std::vector vector; - typedef const std::vector const_vector; - typedef std::tr1::shared_ptr shared_vector; - // end deprecated protected: PVVectorStorage() : Base() {} @@ -1279,79 +1111,6 @@ namespace detail { return thaw(result); } - /** - * Get array elements - * @param offset The offset of the first element, - * @param length The number of elements to get. - * @param data The place where the data is placed. - */ - std::size_t get( - std::size_t offset, std::size_t length, ArrayDataType &data) USAGE_DEPRECATED - { - const_svector ref = this->view(); - ref.slice(offset, length); - data.data.resize(ref.size()); - data.offset = 0; - std::copy(ref.begin(), ref.end(), data.data.begin()); - return ref.size(); - } - - /** - * Copy data into the array growing the length as needed. - * @param offset The offset of the first element, - * @param length The number of elements to get. - * @param from The new values to put into the array. - * @param fromOffset The offset in from. - * @return The number of elements put into the array. - * calls postPut() - */ - std::size_t put(std::size_t offset, - std::size_t length, const_pointer from, std::size_t fromOffset) USAGE_DEPRECATED - { - from += fromOffset; - - svector temp(this->reuse()); - if(temp.size() < length+offset) - temp.resize(length+offset); - else - temp.make_unique(); - - std::copy(from, from + length, temp.begin() + offset); - this->replace(freeze(temp)); - return length; - } - - std::size_t put(std::size_t offset, - std::size_t length, const_vector &from, std::size_t fromOffset) USAGE_DEPRECATED - { return this->put(offset,length, &from[0], fromOffset); } - - /** - * Share data from another source. - * @param value The data to share. - * @param capacity The capacity of the array. - * @param length The length of the array. - * Does @b not call postPut() - */ - void shareData( - shared_vector const & value, - std::size_t capacity, - std::size_t length) USAGE_DEPRECATED - { - vector& vref = *value.get(); - typename svector::shared_pointer_type p(&vref[0], - detail::shared_ptr_vector_deletor(value)); - const_svector temp(p, 0, std::min(length, vref.size())); - this->swap(temp); - } - - pointer get() const USAGE_DEPRECATED { - // evil unsafe cast! - return (pointer)this->view().data(); - } - - vector const & getVector() USAGE_ERROR("No longer implemented. Replace with view()"); - shared_vector const & getSharedVector() USAGE_ERROR("No longer implemented. Replace with view()"); - }; } // namespace detail @@ -1368,14 +1127,6 @@ public: typedef ::epics::pvData::shared_vector svector; typedef ::epics::pvData::shared_vector const_svector; - // begin deprecated - typedef PVArrayData ArrayDataType; - typedef std::vector vector; - typedef const std::vector const_vector; - typedef std::tr1::shared_ptr shared_vector; - typedef PVValueArray & reference; - typedef const PVValueArray & const_reference; - // end deprecated static const ScalarType typeCode; @@ -1421,10 +1172,6 @@ protected: friend class PVDataCreate; }; -/** - * This is provided by code that calls get. - */ -typedef PVArrayData StructureArrayData; /** * Data class for a structureArray @@ -1438,10 +1185,6 @@ public: typedef PVStructurePtr value_type; typedef PVStructurePtr* pointer; typedef const PVStructurePtr* const_pointer; - typedef PVArrayData ArrayDataType; - typedef std::vector vector; - typedef const std::vector const_vector; - typedef std::tr1::shared_ptr shared_vector; typedef PVStructureArray &reference; typedef const PVStructureArray& const_reference; @@ -1519,10 +1262,6 @@ private: }; -/** - * This is provided by code that calls get. - */ -typedef PVArrayData UnionArrayData; /** * Data class for a unionArray @@ -1536,10 +1275,6 @@ public: typedef PVUnionPtr value_type; typedef PVUnionPtr* pointer; typedef const PVUnionPtr* const_pointer; - typedef PVArrayData ArrayDataType; - typedef std::vector vector; - typedef const std::vector const_vector; - typedef std::tr1::shared_ptr shared_vector; typedef PVUnionArray &reference; typedef const PVUnionArray& const_reference; @@ -1620,51 +1355,39 @@ private: /** * Definitions for the various scalarArray types. */ -typedef PVArrayData BooleanArrayData; typedef PVValueArray PVBooleanArray; typedef std::tr1::shared_ptr PVBooleanArrayPtr; -typedef PVArrayData ByteArrayData; typedef PVValueArray PVByteArray; typedef std::tr1::shared_ptr PVByteArrayPtr; -typedef PVArrayData ShortArrayData; typedef PVValueArray PVShortArray; typedef std::tr1::shared_ptr PVShortArrayPtr; -typedef PVArrayData IntArrayData; typedef PVValueArray PVIntArray; typedef std::tr1::shared_ptr PVIntArrayPtr; -typedef PVArrayData LongArrayData; typedef PVValueArray PVLongArray; typedef std::tr1::shared_ptr PVLongArrayPtr; -typedef PVArrayData UByteArrayData; typedef PVValueArray PVUByteArray; typedef std::tr1::shared_ptr PVUByteArrayPtr; -typedef PVArrayData UShortArrayData; typedef PVValueArray PVUShortArray; typedef std::tr1::shared_ptr PVUShortArrayPtr; -typedef PVArrayData UIntArrayData; typedef PVValueArray PVUIntArray; typedef std::tr1::shared_ptr PVUIntArrayPtr; -typedef PVArrayData ULongArrayData; typedef PVValueArray PVULongArray; typedef std::tr1::shared_ptr PVULongArrayPtr; -typedef PVArrayData FloatArrayData; typedef PVValueArray PVFloatArray; typedef std::tr1::shared_ptr PVFloatArrayPtr; -typedef PVArrayData DoubleArrayData; typedef PVValueArray PVDoubleArray; typedef std::tr1::shared_ptr PVDoubleArrayPtr; -typedef PVArrayData StringArrayData; typedef PVValueArray PVStringArray; typedef std::tr1::shared_ptr PVStringArrayPtr; @@ -1818,8 +1541,6 @@ private: epicsShareExtern PVDataCreatePtr getPVDataCreate(); -#undef USAGE_DEPRECATED -#undef USAGE_ERROR }} #endif /* PVDATA_H */ diff --git a/pvDataApp/pv/pvIntrospect.h b/pvDataApp/pv/pvIntrospect.h index f85d57d..24acc6a 100644 --- a/pvDataApp/pv/pvIntrospect.h +++ b/pvDataApp/pv/pvIntrospect.h @@ -812,6 +812,11 @@ public: * @return An {@code Array} Interface for the newly created object. */ StructureArrayConstPtr createStructureArray(StructureConstPtr const & structure) const; + /** + * Create a {@code Structure} field. + * @return a {@code Structure} interface for the newly created object. + */ + StructureConstPtr createStructure () const; /** * Create a {@code Structure} field. * @param fieldNames The array of {@code fieldNames} for the structure. diff --git a/testApp/Makefile b/testApp/Makefile index a2771b3..6d49e69 100644 --- a/testApp/Makefile +++ b/testApp/Makefile @@ -3,5 +3,6 @@ include $(TOP)/configure/CONFIG DIRS += misc DIRS += pv DIRS += property +DIRS += copy include $(TOP)/configure/RULES_DIRS diff --git a/testApp/copy/Makefile b/testApp/copy/Makefile new file mode 100644 index 0000000..dab7623 --- /dev/null +++ b/testApp/copy/Makefile @@ -0,0 +1,22 @@ +TOP=../.. + +include $(TOP)/configure/CONFIG + +PROD_HOST += testCreateRequest +testCreateRequest_SRCS = testCreateRequest.cpp +testCreateRequest_LIBS = pvData Com +TESTS += testCreateRequest + +PROD_HOST += testPVCopy +testPVCopy_SRCS += testPVCopy.cpp +testPVCopy_LIBS += pvData Com +TESTS += testPVCopy + +TESTSCRIPTS_HOST += $(TESTS:%=%.t) + + + +include $(TOP)/configure/RULES +#---------------------------------------- +# ADD RULES AFTER THIS LINE + diff --git a/testApp/copy/testCreateRequest.cpp b/testApp/copy/testCreateRequest.cpp new file mode 100644 index 0000000..98fb4e2 --- /dev/null +++ b/testApp/copy/testCreateRequest.cpp @@ -0,0 +1,327 @@ +/* testCreateRequest.cpp */ +/* Author: Matej Sekoranja Date: 2010.12.27 */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +using namespace epics::pvData; +using std::cout; +using std::endl; + +static bool debug = false; + +void testCreateRequest() { + printf("testCreateRequest... \n"); + CreateRequest::shared_pointer createRequest = CreateRequest::create(); + + String out; + String request = ""; + if(debug) { cout << "request " << request <createRequest(request); + if(debug) { cout<< createRequest->getMessage() << endl;} + testOk1(pvRequest!=NULL); + if(debug) { cout << pvRequest->dumpValue(cout) << endl;} + testOk1(pvRequest->getStructure()->getNumberFields()==0); + testPass("request %s",request.c_str()); + + + request = "record[a=b,x=y]field(a) putField(a),getField(a)"; + pvRequest = createRequest->createRequest(request); + if(pvRequest==NULL) { + cout << createRequest->getMessage() << endl; + } + if(debug) { cout << "request " << request <dumpValue(cout) << endl;} + PVStringPtr pvString = pvRequest->getSubField("record.a"); + String sval = pvString->get(); + testOk(sval.compare("b")==0,"record.a = b"); + pvString = pvRequest->getSubField("record.x"); + sval = pvString->get(); + testOk(sval.compare("y")==0,"record.x = y"); + testOk1(pvRequest->getSubField("field.a")!=NULL); + testOk1(pvRequest->getSubField("putField.a")!=NULL); + testOk1(pvRequest->getSubField("getField.a")!=NULL); + testPass("request %s",request.c_str()); + + request = "field(a.b[x=y])"; + pvRequest = createRequest->createRequest(request); + if(pvRequest==NULL) { + cout << createRequest->getMessage() << endl; + } + if(debug) { cout << "request " << request <dumpValue(cout) << endl;} + pvString = pvRequest->getSubField("field.a.b._options.x"); + sval = pvString->get(); + testOk(sval.compare("y")==0,"field.a.b._options.x = y"); + testPass("request %s",request.c_str()); + + request = "field(a.b{c.d})"; + pvRequest = createRequest->createRequest(request); + if(debug) { cout << "request " << request <getMessage() << endl; + } + testOk1(pvRequest!=NULL); + testOk1(pvRequest->getSubField("field.a.b.c.d")!=NULL); + if(debug) { cout << pvRequest->dumpValue(cout) << endl;} + testPass("request %s",request.c_str()); + + request = "field(a.b[x=y]{c.d})"; + pvRequest = createRequest->createRequest(request); + if(debug) { cout << "request " << request <getMessage() << endl; + } + testOk1(pvRequest!=NULL); + pvString = pvRequest->getSubField("field.a.b._options.x"); + sval = pvString->get(); + testOk(sval.compare("y")==0,"field.a.b._options.x = y"); + testOk1(pvRequest->getSubField("field.a.b.c.d")!=NULL); + if(debug) { cout << pvRequest->dumpValue(cout) << endl;} + testPass("request %s",request.c_str()); + + request = "field(a.b[x=y]{c.d[x=y]})"; + pvRequest = createRequest->createRequest(request); + if(debug) { cout << "request " << request <getMessage() << endl; + } + testOk1(pvRequest!=NULL); + pvString = pvRequest->getSubField("field.a.b._options.x"); + sval = pvString->get(); + testOk(sval.compare("y")==0,"field.a.b._options.x = y"); + pvString = pvRequest->getSubField("field.a.b.c.d._options.x"); + sval = pvString->get(); + testOk(sval.compare("y")==0,"field.a.b.c.d._options.x = y"); + if(debug) { cout << pvRequest->dumpValue(cout) << endl;} + testPass("request %s",request.c_str()); + + request = "record[a=b,c=d] field(a.a[a=b]{a.a[a=b]},b.a[a=b]{a,b})"; + pvRequest = createRequest->createRequest(request); + if(debug) { cout << "request " << request <getMessage() << endl; + } + testOk1(pvRequest!=NULL); + pvString = pvRequest->getSubField("field.a.a._options.a"); + sval = pvString->get(); + testOk(sval.compare("b")==0,"field.a.a._options.a = b"); + pvString = pvRequest->getSubField("field.a.a.a.a._options.a"); + sval = pvString->get(); + testOk(sval.compare("b")==0,"field.a.a.a.a._options.a = b"); + pvString = pvRequest->getSubField("field.b.a._options.a"); + sval = pvString->get(); + testOk(sval.compare("b")==0,"field.b.a._options.a = b"); + testOk1(pvRequest->getSubField("field.b.a.a")!=NULL); + testOk1(pvRequest->getSubField("field.b.a.b")!=NULL); + if(debug) { cout << pvRequest->dumpValue(cout) << endl;} + testPass("request %s",request.c_str()); + + + request = "alarm,timeStamp,power.value"; + pvRequest = createRequest->createRequest(request); + if(debug) { cout << endl << String("request") <getMessage() << endl; + } + testOk1(pvRequest!=NULL); + testOk1(pvRequest->getSubField("field.alarm")!=NULL); + testOk1(pvRequest->getSubField("field.timeStamp")!=NULL); + testOk1(pvRequest->getSubField("field.power.value")!=NULL); + if(debug) { cout << pvRequest->dumpValue(cout) << endl;} + testPass("request %s",request.c_str()); + + request = "record[process=true]field(alarm,timeStamp,power.value)"; + pvRequest = createRequest->createRequest(request); + if(debug) { cout << endl << String("request") <getMessage() << endl; + } + testOk1(pvRequest!=NULL); + pvString = pvRequest->getSubField("record.process"); + sval = pvString->get(); + testOk(sval.compare("true")==0,"record.process = true"); + testOk1(pvRequest->getSubField("field.alarm")!=NULL); + testOk1(pvRequest->getSubField("field.timeStamp")!=NULL); + testOk1(pvRequest->getSubField("field.power.value")!=NULL); + if(debug) {cout << pvRequest->dumpValue(cout) << endl;} + testPass("request %s",request.c_str()); + + request = "record[process=true]field(alarm,timeStamp[algorithm=onChange,causeMonitor=false],power{value,alarm})"; + pvRequest = createRequest->createRequest(request); + if(debug) { cout << String("request") <getMessage() << endl; + } + testOk1(pvRequest!=NULL); + pvString = pvRequest->getSubField("record.process"); + sval = pvString->get(); + testOk(sval.compare("true")==0,"record.process = true"); + testOk1(pvRequest->getSubField("field.alarm")!=NULL); + testOk1(pvRequest->getSubField("field.timeStamp")!=NULL); + pvString = pvRequest->getSubField("field.timeStamp._options.algorithm"); + sval = pvString->get(); + testOk(sval.compare("onChange")==0,"field.timeStamp._options.algorithm = onChange"); + pvString = pvRequest->getSubField("field.timeStamp._options.causeMonitor"); + sval = pvString->get(); + testOk(sval.compare("false")==0,"field.timeStamp._options.causeMonitor = false"); + testOk1(pvRequest->getSubField("field.power.value")!=NULL); + testOk1(pvRequest->getSubField("field.power.alarm")!=NULL); + if(debug) {cout << pvRequest->dumpValue(cout) << endl;} + testPass("request %s",request.c_str()); + + request = "record[int=2,float=3.14159]field(alarm,timeStamp[shareData=true],power.value)"; + pvRequest = createRequest->createRequest(request); + if(debug) { cout << String("request") <getMessage() << endl; + } + testOk1(pvRequest!=NULL); + pvString = pvRequest->getSubField("record.int"); + sval = pvString->get(); + testOk(sval.compare("2")==0,"record.int = 2"); + pvString = pvRequest->getSubField("record.float"); + sval = pvString->get(); + testOk(sval.compare("3.14159")==0,"record.float = 3.14159"); + testOk1(pvRequest->getSubField("field.alarm")!=NULL); + pvString = pvRequest->getSubField("field.timeStamp._options.shareData"); + sval = pvString->get(); + testOk(sval.compare("true")==0,"field.timeStamp._options.shareData = true"); + testOk1(pvRequest->getSubField("field.power.value")!=NULL); + if(debug) {cout << pvRequest->dumpValue(cout) << endl;} + testPass("request %s",request.c_str()); + + request = String("record[process=true,xxx=yyy]") + + "putField(power.value)" + + "getField(alarm,timeStamp,power{value,alarm}," + + "current{value,alarm},voltage{value,alarm})"; + pvRequest = createRequest->createRequest(request); + if(debug) { cout << String("request") <getMessage() << endl; + } + testOk1(pvRequest!=NULL); + testOk1(pvRequest->getSubField("putField.power.value")!=NULL); + testOk1(pvRequest->getSubField("getField.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.timeStamp")!=NULL); + testOk1(pvRequest->getSubField("getField.power.value")!=NULL); + testOk1(pvRequest->getSubField("getField.power.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.current.value")!=NULL); + testOk1(pvRequest->getSubField("getField.current.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.voltage.value")!=NULL); + testOk1(pvRequest->getSubField("getField.voltage.alarm")!=NULL); + if(debug) {cout << pvRequest->dumpValue(cout) << endl;} + testPass("request %s",request.c_str()); + + request = String("field(alarm,timeStamp,supply{") + + "0{voltage.value,current.value,power.value}," + + "1{voltage.value,current.value,power.value}" + + "})"; + pvRequest = createRequest->createRequest(request); + if(debug) { cout << String("request") <getMessage() << endl; + } + testOk1(pvRequest!=NULL); + testOk1(pvRequest->getSubField("field.alarm")!=NULL); + testOk1(pvRequest->getSubField("field.timeStamp")!=NULL); + testOk1(pvRequest->getSubField("field.supply.0.voltage.value")!=NULL); + testOk1(pvRequest->getSubField("field.supply.0.current.value")!=NULL); + testOk1(pvRequest->getSubField("field.supply.0.power.value")!=NULL); + testOk1(pvRequest->getSubField("field.supply.1.voltage.value")!=NULL); + testOk1(pvRequest->getSubField("field.supply.1.current.value")!=NULL); + testOk1(pvRequest->getSubField("field.supply.1.power.value")!=NULL); + if(debug) {cout << pvRequest->dumpValue(cout) << endl;} + testPass("request %s",request.c_str()); + + 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}}" + + ")"; + pvRequest = createRequest->createRequest(request); + if(debug) { cout << String("request") <getMessage() << endl; + } + testOk1(pvRequest!=NULL); + testOk1(pvRequest->getSubField("putField.power.value")!=NULL); + testOk1(pvRequest->getSubField("getField.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.timeStamp")!=NULL); + testOk1(pvRequest->getSubField("getField.power.value")!=NULL); + testOk1(pvRequest->getSubField("getField.power.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.current.value")!=NULL); + testOk1(pvRequest->getSubField("getField.current.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.voltage.value")!=NULL); + testOk1(pvRequest->getSubField("getField.voltage.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.ps0.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.ps0.timeStamp")!=NULL); + testOk1(pvRequest->getSubField("getField.ps0.power.value")!=NULL); + testOk1(pvRequest->getSubField("getField.ps0.power.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.ps0.current.value")!=NULL); + testOk1(pvRequest->getSubField("getField.ps0.current.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.ps0.voltage.value")!=NULL); + testOk1(pvRequest->getSubField("getField.ps0.voltage.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.ps1.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.ps1.timeStamp")!=NULL); + testOk1(pvRequest->getSubField("getField.ps1.power.value")!=NULL); + testOk1(pvRequest->getSubField("getField.ps1.power.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.ps1.current.value")!=NULL); + testOk1(pvRequest->getSubField("getField.ps1.current.alarm")!=NULL); + testOk1(pvRequest->getSubField("getField.ps1.voltage.value")!=NULL); + testOk1(pvRequest->getSubField("getField.ps1.voltage.alarm")!=NULL); + if(debug) {cout << pvRequest->dumpValue(cout) << endl;} + testPass("request %s",request.c_str()); + + request = "a{b{c{d}}}"; + pvRequest = createRequest->createRequest(request); + if(debug) { cout << String("request") <getSubField("field.a.b.c.d")!=NULL); + if(debug) {cout << pvRequest->dumpValue(cout) << endl;} + testPass("request %s",request.c_str()); + + 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}" + + ")"; + if(debug) { cout << endl << "Error Expected for next call!!" << endl;} + if(debug) { cout << String("request") <createRequest(request); + assert(pvRequest.get()==NULL); + if(debug) {cout << "reason " << createRequest->getMessage() << endl;} + testPass("request %s",request.c_str()); + + request = "record[process=true,power.value"; + if(debug) { cout << String("request") <createRequest(request); + assert(pvRequest.get()==NULL); + if(debug) { cout << "reason " << createRequest->getMessage() << endl;} + testPass("request %s",request.c_str()); +} + +MAIN(testCreateRequest) +{ + testPlan(111); + testCreateRequest(); + return testDone(); +} + + diff --git a/testApp/copy/testPVCopy.cpp b/testApp/copy/testPVCopy.cpp new file mode 100644 index 0000000..a2909d1 --- /dev/null +++ b/testApp/copy/testPVCopy.cpp @@ -0,0 +1,356 @@ +/*testPVCopyMain.cpp */ +/** + * Copyright - See the COPYRIGHT that is included with this distribution. + * EPICS pvData is distributed subject to a Software License Agreement found + * in file LICENSE that is included with this distribution. + */ +/** + * @author mrk + */ + +/* Author: Marty Kraimer */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + + +using namespace std; +using std::tr1::static_pointer_cast; +using namespace epics::pvData; + +//static bool debug = true; + +static void testPVScalar( + String const & valueNameMaster, + String const & valueNameCopy, + PVStructurePtr const & pvMaster, + PVCopyPtr const & pvCopy) +{ + PVStructurePtr pvStructureCopy; + PVFieldPtr pvField; + PVScalarPtr pvValueMaster; + PVScalarPtr pvValueCopy; + BitSetPtr bitSet; + String builder; + size_t offset; + ConvertPtr convert = getConvert(); + + cout << endl; + pvField = pvMaster->getSubField(valueNameMaster); + pvValueMaster = static_pointer_cast(pvField); + convert->fromDouble(pvValueMaster,.04); + StructureConstPtr structure = pvCopy->getStructure(); + builder.clear(); structure->toString(&builder); + cout << "structure from copy" << endl << builder << endl; + pvStructureCopy = pvCopy->createPVStructure(); + pvField = pvStructureCopy->getSubField(valueNameCopy); + pvValueCopy = static_pointer_cast(pvField); + bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields())); + pvCopy->initCopy(pvStructureCopy, bitSet); + cout << "after initCopy pvValueCopy " << convert->toDouble(pvValueCopy); + cout << endl; + convert->fromDouble(pvValueMaster,.06); + pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet); + cout << "after put(.06) pvValueCopy " << convert->toDouble(pvValueCopy); + builder.clear(); + bitSet->toString(&builder); + cout << " bitSet " << builder; + cout << endl; + offset = pvCopy->getCopyOffset(pvValueMaster); + cout << "getCopyOffset() " << offset; + cout << " pvValueCopy->getOffset() " << pvValueCopy->getFieldOffset(); + cout << " pvValueMaster->getOffset() " << pvValueMaster->getFieldOffset(); + cout << " bitSet " << builder; + cout << endl; + bitSet->clear(); + convert->fromDouble(pvValueMaster,1.0); + builder.clear(); + bitSet->toString(&builder); + cout << "before updateCopyFromBitSet"; + cout << " masterValue " << convert->toDouble(pvValueMaster); + cout << " copyValue " << convert->toDouble(pvValueCopy); + cout << " bitSet " << builder; + cout << endl; + bitSet->set(0); + pvCopy->updateCopyFromBitSet(pvStructureCopy,bitSet); + cout << "after updateCopyFromBitSet"; + cout << " masterValue " << convert->toDouble(pvValueMaster); + cout << " copyValue " << convert->toDouble(pvValueCopy); + cout << " bitSet " << builder; + cout << endl; + convert->fromDouble(pvValueCopy,2.0); + bitSet->set(0); + cout << "before updateMaster"; + cout << " masterValue " << convert->toDouble(pvValueMaster); + cout << " copyValue " << convert->toDouble(pvValueCopy); + cout << " bitSet " << builder; + cout << endl; + pvCopy->updateMaster(pvStructureCopy,bitSet); + cout << "after updateMaster"; + cout << " masterValue " << convert->toDouble(pvValueMaster); + cout << " copyValue " << convert->toDouble(pvValueCopy); + cout << " bitSet " << builder; + cout << endl; +} + +static void testPVScalarArray( + ScalarType scalarType, + String const & valueNameMaster, + String const & valueNameCopy, + PVStructurePtr const & pvMaster, + PVCopyPtr const & pvCopy) +{ + PVStructurePtr pvStructureCopy; + PVScalarArrayPtr pvValueMaster; + PVScalarArrayPtr pvValueCopy; + BitSetPtr bitSet; + String builder; + size_t offset; + size_t n = 5; + shared_vector values(n); + cout << endl; + pvValueMaster = pvMaster->getScalarArrayField(valueNameMaster,scalarType); + for(size_t i=0; i xxx(freeze(values)); + pvValueMaster->putFrom(xxx); + StructureConstPtr structure = pvCopy->getStructure(); + builder.clear(); structure->toString(&builder); + cout << "structure from copy" << endl << builder << endl; + pvStructureCopy = pvCopy->createPVStructure(); + pvValueCopy = pvStructureCopy->getScalarArrayField(valueNameCopy,scalarType); + bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields())); + pvCopy->initCopy(pvStructureCopy, bitSet); + builder.clear(); pvValueCopy->toString(&builder); + cout << "after initCopy pvValueCopy " << builder << endl; + cout << endl; + values.resize(n); + for(size_t i=0; i yyy(freeze(values)); + pvValueMaster->putFrom(yyy); + pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet); + builder.clear(); pvValueCopy->toString(&builder); + cout << "after put(i+ .06) pvValueCopy " << builder << endl; + builder.clear(); + bitSet->toString(&builder); + cout << " bitSet " << builder; + cout << endl; + offset = pvCopy->getCopyOffset(pvValueMaster); + cout << "getCopyOffset() " << offset; + cout << " pvValueCopy->getOffset() " << pvValueCopy->getFieldOffset(); + cout << " pvValueMaster->getOffset() " << pvValueMaster->getFieldOffset(); + builder.clear(); + bitSet->toString(&builder); + cout << " bitSet " << builder; + cout << endl; + bitSet->clear(); + values.resize(n); + for(size_t i=0; i zzz(freeze(values)); + pvValueMaster->putFrom(zzz); + builder.clear(); + bitSet->toString(&builder); + cout << "before updateCopyFromBitSet"; + builder.clear(); pvValueMaster->toString(&builder); + cout << " masterValue " << builder << endl; + builder.clear(); pvValueCopy->toString(&builder); + cout << " copyValue " << builder << endl; + cout << " bitSet " << builder; + builder.clear(); + bitSet->toString(&builder); + cout << endl; + bitSet->set(0); + pvCopy->updateCopyFromBitSet(pvStructureCopy,bitSet); + cout << "after updateCopyFromBitSet"; + builder.clear(); pvValueMaster->toString(&builder); + cout << " masterValue " << builder << endl; + builder.clear(); pvValueCopy->toString(&builder); + cout << " copyValue " << builder << endl; + builder.clear(); + bitSet->toString(&builder); + cout << " bitSet " << builder; + cout << endl; + values.resize(n); + for(size_t i=0; i ttt(freeze(values)); + pvValueMaster->putFrom(ttt); + bitSet->set(0); + cout << "before updateMaster"; + builder.clear(); pvValueMaster->toString(&builder); + cout << " masterValue " << builder << endl; + builder.clear(); pvValueCopy->toString(&builder); + cout << " copyValue " << builder << endl; + builder.clear(); + bitSet->toString(&builder); + cout << " bitSet " << builder; + cout << endl; + pvCopy->updateMaster(pvStructureCopy,bitSet); + cout << "after updateMaster"; + builder.clear(); pvValueMaster->toString(&builder); + cout << " masterValue " << builder << endl; + builder.clear(); pvValueCopy->toString(&builder); + cout << " copyValue " << builder << endl; + builder.clear(); + bitSet->toString(&builder); + cout << " bitSet " << builder; + cout << endl; +} + +static void scalarTest() +{ + cout << endl << endl << "****scalarTest****" << endl; + PVStructurePtr pvMaster; + String request; + PVStructurePtr pvRequest; + PVFieldPtr pvMasterField; + PVCopyPtr pvCopy; + String builder; + String valueNameMaster; + String valueNameCopy; + + StandardPVFieldPtr standardPVField = getStandardPVField(); + pvMaster = standardPVField->scalar(pvDouble,"alarm,timeStamp,display"); + + valueNameMaster = request = "value"; + CreateRequest::shared_pointer createRequest = CreateRequest::create(); + pvRequest = createRequest->createRequest(request); + builder.clear(); pvRequest->toString(&builder); + cout << "request " << request << endl; + cout << "pvRequest" << endl << builder; + pvCopy = PVCopy::create(pvMaster,pvRequest,""); + valueNameCopy = "value"; + testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy); + request = ""; + valueNameMaster = "value"; + pvRequest = createRequest->createRequest(request); + builder.clear(); pvRequest->toString(&builder); + cout << "request " << request << endl << "pvRequest" << endl << builder << endl; + pvCopy = PVCopy::create(pvMaster,pvRequest,""); + valueNameCopy = "value"; + testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy); + request = "alarm,timeStamp,value"; + valueNameMaster = "value"; + pvRequest = createRequest->createRequest(request); + builder.clear(); pvRequest->toString(&builder); + cout << "request " << request << endl << "pvRequest" << endl << builder << endl; + pvCopy = PVCopy::create(pvMaster,pvRequest,""); + valueNameCopy = "value"; + testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy); +} + +static void arrayTest() +{ + cout << endl << endl << "****arrayTest****" << endl; + PVStructurePtr pvMaster; + String request; + PVStructurePtr pvRequest; + PVFieldPtr pvMasterField; + PVCopyPtr pvCopy; + String builder; + String valueNameMaster; + String valueNameCopy; + + CreateRequest::shared_pointer createRequest = CreateRequest::create(); + StandardPVFieldPtr standardPVField = getStandardPVField(); + pvMaster = standardPVField->scalarArray(pvDouble,"alarm,timeStamp"); + valueNameMaster = request = "value"; + pvRequest = createRequest->createRequest(request); + builder.clear(); pvRequest->toString(&builder); + cout << "request " << request << endl; + cout << "pvRequest" << endl << builder; + pvCopy = PVCopy::create(pvMaster,pvRequest,""); + valueNameCopy = "value"; + testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy); + request = ""; + valueNameMaster = "value"; + pvRequest = createRequest->createRequest(request); + builder.clear(); pvRequest->toString(&builder); + cout << "request " << request << endl << "pvRequest" << endl << builder << endl; + pvCopy = PVCopy::create(pvMaster,pvRequest,""); + valueNameCopy = "value"; + testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy); + request = "alarm,timeStamp,value"; + valueNameMaster = "value"; + pvRequest = createRequest->createRequest(request); + builder.clear(); pvRequest->toString(&builder); + cout << "request " << request << endl << "pvRequest" << endl << builder << endl; + pvCopy = PVCopy::create(pvMaster,pvRequest,""); + valueNameCopy = "value"; + testPVScalarArray(pvDouble,valueNameMaster,valueNameCopy,pvMaster,pvCopy); +} + +#ifdef XXXXXX +static void powerSupplyTest() +{ + cout << endl << endl << "****powerSupplyTest****" << endl; + RequesterPtr requester(new MyRequester("exampleTest")); + PowerSupplyPtr pvMaster; + String request; + PVStructurePtr pvRequest; + PVFieldPtr pvMasterField; + PVCopyPtr pvCopy; + String builder; + String valueNameMaster; + String valueNameCopy; + + CreateRequest::shared_pointer createRequest = CreateRequest::create(); + PVStructurePtr pv = createPowerSupply(); + pvMaster = PowerSupply::create("powerSupply",pv); + valueNameMaster = request = "power.value"; + pvRequest = createRequest->createRequest(request); + builder.clear(); pvRequest->toString(&builder); + cout << "request " << request << endl; + cout << "pvRequest" << endl << builder; + pvCopy = PVCopy::create(pvMaster,pvRequest,""); + valueNameCopy = "power.value"; + testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy); + request = ""; + valueNameMaster = "power.value"; + pvRequest = createRequest->createRequest(request); + builder.clear(); pvRequest->toString(&builder); + cout << "request " << request << endl << "pvRequest" << endl << builder << endl; + pvCopy = PVCopy::create(pvMaster,pvRequest,""); + valueNameCopy = "power.value"; + testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy); + request = "alarm,timeStamp,voltage.value,power.value,current.value"; + valueNameMaster = "power.value"; + pvRequest = createRequest->createRequest(request); + builder.clear(); pvRequest->toString(&builder); + cout << "request " << request << endl << "pvRequest" << endl << builder << endl; + pvCopy = PVCopy::create(pvMaster,pvRequest,""); + valueNameCopy = "power.value"; + testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy); + request = "alarm,timeStamp,voltage{value,alarm},power{value,alarm,display},current.value"; + valueNameMaster = "power.value"; + pvRequest = createRequest->createRequest(request); + builder.clear(); pvRequest->toString(&builder); + cout << "request " << request << endl << "pvRequest" << endl << builder << endl; + pvCopy = PVCopy::create(pvMaster,pvRequest,""); + valueNameCopy = "power.value"; + testPVScalar(valueNameMaster,valueNameCopy,pvMaster,pvCopy); + pvMaster->destroy(); +} +#endif + +MAIN(testPVCopy) +{ + testPlan(0); + scalarTest(); + arrayTest(); +// powerSupplyTest(); + return testDone(); +} + diff --git a/testApp/pv/Makefile b/testApp/pv/Makefile index 4dc7c30..c9faf7a 100644 --- a/testApp/pv/Makefile +++ b/testApp/pv/Makefile @@ -12,21 +12,11 @@ testIntrospect_SRCS += testIntrospect.cpp testIntrospect_LIBS += pvData Com TESTS += testIntrospect -PROD_HOST += testPVAppend -testPVAppend_SRCS += testPVAppend.cpp -testPVAppend_LIBS += pvData Com -TESTS += testPVAppend - PROD_HOST += testPVType testPVType_SRCS += testPVType.cpp testPVType_LIBS += pvData Com TESTS += testPVType -PROD_HOST += testPVAuxInfo -testPVAuxInfo_SRCS += testPVAuxInfo.cpp -testPVAuxInfo_LIBS += pvData Com -TESTS += testPVAuxInfo - PROD_HOST += testStandardField testStandardField_SRCS += testStandardField.cpp testStandardField_LIBS += pvData Com diff --git a/testApp/pv/testPVAppend.cpp b/testApp/pv/testPVAppend.cpp deleted file mode 100644 index 7dd1a91..0000000 --- a/testApp/pv/testPVAppend.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* testPVAppend.cpp */ -/** - * Copyright - See the COPYRIGHT that is included with this distribution. - * EPICS pvData is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - */ -/* Author: Marty Kraimer Date: 2010.11 */ - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace epics::pvData; -using std::tr1::static_pointer_cast; -using std::size_t; - -static bool debug = false; - -static FieldCreatePtr fieldCreate; -static PVDataCreatePtr pvDataCreate; -static StandardFieldPtr standardField; -static StandardPVFieldPtr standardPVField; -static ConvertPtr convert; -static String builder(""); -static String alarmTimeStamp("alarm,timeStamp"); -static String alarmTimeStampValueAlarm("alarm,timeStamp,valueAlarm"); -static String allProperties("alarm,timeStamp,display,control,valueAlarm"); - -static void checkNameAndParent( - PVStructurePtr & pvStructure, int indentLevel) -{ - builder.clear(); - if(debug) { - convert->newLine(&builder,indentLevel); - printf("%s this %p indentLevel %d", - builder.c_str(),pvStructure.get(),indentLevel); - } - PVFieldPtrArray pvFields = pvStructure->getPVFields(); - StringArray fieldNames = pvStructure->getStructure()->getFieldNames(); - for(size_t i = 0; igetParent()==pvStructure.get()); - testOk1(pvField->getFieldName().compare(fieldNames[i])==0); - builder.clear(); - if(debug) { - convert->newLine(&builder,indentLevel); - printf("%s this %p name %s parent %p", - builder.c_str(), - pvField.get(), - pvField->getFieldName().c_str(), - pvField->getParent()); - } - if(pvField->getField()->getType()==structure) { - PVStructurePtr xxx = static_pointer_cast(pvField); - checkNameAndParent(xxx,indentLevel+1); - } - } - builder.clear(); -} - -static void testAppendSimple() -{ - if(debug) printf("\ntestAppendSimple\n"); - PVFieldPtrArray fields; - StringArray names; - PVStructurePtr pvParent = pvDataCreate->createPVStructure(names,fields); - PVStringPtr pvStringField = static_pointer_cast( - pvDataCreate->createPVScalar(pvString)); - pvStringField->put("value,timeStamp"); - PVFieldPtr pvField = pvStringField; - pvParent->appendPVField("fieldlist",pvField); - pvStringField = static_pointer_cast( - pvDataCreate->createPVScalar(pvString)); - pvStringField->put("junk"); - pvField = pvStringField; - pvParent->appendPVField("extra",pvField); - builder.clear(); - pvParent->toString(&builder); - if(debug) printf("%s\n",builder.c_str()); - printf("testAppendSimple PASSED\n"); -} - -static void testAppendMore() -{ - if(debug) printf("\ntestAppendMore\n"); - PVFieldPtrArray fields; - StringArray names; - PVStructurePtr pvStructure = pvDataCreate->createPVStructure(names,fields); - PVStructurePtr pvChild1 = pvDataCreate->createPVStructure(names,fields); - PVStringPtr pvStringField = static_pointer_cast( - pvDataCreate->createPVScalar(pvString)); - pvStringField->put("bla"); - PVFieldPtr pvField = pvStringField; - pvChild1->appendPVField("value",pvField); - pvField = pvChild1; - pvStructure->appendPVField("child1",pvField); - PVStructurePtr pvChild2 = pvDataCreate->createPVStructure(names,fields); - pvStringField = static_pointer_cast( - pvDataCreate->createPVScalar(pvString)); - pvStringField->put("blabla"); - pvField = pvStringField; - pvChild2->appendPVField("value",pvField); - pvField = pvChild2; - pvStructure->appendPVField("child2",pvField); - builder.clear(); - pvStructure->toString(&builder); - if(debug) printf("%s\n",builder.c_str()); - checkNameAndParent(pvStructure,0); - printf("testAppendMore PASSED\n"); -} - -static void testAppendStructures() -{ - if(debug) printf("\ntestAppendStructures\n"); - PVFieldPtrArray fields; - StringArray names; - PVStructurePtr pvParent = pvDataCreate->createPVStructure(names,fields); - PVFieldPtrArray topFields; - StringArray topNames; - PVStructurePtr pvTop = pvDataCreate->createPVStructure(topNames,topFields); - pvParent->appendPVField("top",pvTop); - PVFieldPtrArray valueFields; - StringArray valueNames; - PVStructurePtr pvValue = pvDataCreate->createPVStructure(valueNames,valueFields); - pvTop->appendPVField("value",pvValue); - PVFieldPtrArray indexFields; - StringArray indexNames; - PVStructurePtr pvIndex = pvDataCreate->createPVStructure(indexNames,indexFields); - pvValue->appendPVField("index",pvIndex); - builder.clear(); - pvParent->toString(&builder); - if(debug) printf("%s\n",builder.c_str()); - builder.clear(); - pvParent->getField()->toString(&builder); - if(debug) printf("field\n%s\n",builder.c_str()); - printf("testAppendStructures PASSED\n"); -} - -static void append2(PVStructurePtr &pvStructure, - const char *oneName,const char *twoName, - const char *oneValue,const char *twoValue) -{ - PVFieldPtrArray pvFields; - pvFields.reserve(2); - StringArray names; - names.reserve(2); - PVStringPtr pvStringField = static_pointer_cast( - pvDataCreate->createPVScalar(pvString)); - pvStringField->put(oneValue); - names.push_back(oneName); - pvFields.push_back(pvStringField); - pvStringField = static_pointer_cast( - pvDataCreate->createPVScalar(pvString)); - pvStringField->put(twoValue); - names.push_back(twoName); - pvFields.push_back(pvStringField); - pvStructure->appendPVFields(names,pvFields); -} -static void testAppends() -{ - if(debug) printf("\ntestAppends\n"); - PVFieldPtrArray emptyPVFields; - StringArray emptyNames; - PVFieldPtrArray pvFields; - pvFields.reserve(2); - StringArray names; - names.reserve(2); - names.push_back("child1"); - PVStructurePtr pvChild = pvDataCreate->createPVStructure( - emptyNames,emptyPVFields); - append2(pvChild,"Joe","Mary","Good Guy","Good Girl"); - pvFields.push_back(pvChild); - names.push_back("child2"); - pvChild = pvDataCreate->createPVStructure( - emptyNames,emptyPVFields); - append2(pvChild,"Bill","Jane","Bad Guy","Bad Girl"); - pvFields.push_back(pvChild); - PVStructurePtr pvStructure = pvDataCreate->createPVStructure( - names,pvFields); - builder.clear(); - pvStructure->toString(&builder); - if(debug) printf("%s\n",builder.c_str()); - checkNameAndParent(pvStructure,0); - PVFieldPtr pvField = pvStructure->getSubField("child2.Bill"); - testOk1(pvField.get()!=NULL); - pvField->renameField("Joe"); - builder.clear(); - pvStructure->toString(&builder); - if(debug) printf("%s\n",builder.c_str()); - pvField->getParent()->removePVField("Joe"); - builder.clear(); - pvStructure->toString(&builder); - if(debug) printf("%s\n",builder.c_str()); - checkNameAndParent(pvStructure,0); - printf("testAppends PASSED\n"); -} - -MAIN(testPVAppend) -{ - testPlan(31); - fieldCreate = getFieldCreate(); - pvDataCreate = getPVDataCreate(); - standardField = getStandardField(); - standardPVField = getStandardPVField(); - convert = getConvert(); - testAppendStructures(); - testAppendSimple(); - testAppendMore(); - testAppends(); - return testDone(); -} - diff --git a/testApp/pv/testPVAuxInfo.cpp b/testApp/pv/testPVAuxInfo.cpp deleted file mode 100644 index 52d510b..0000000 --- a/testApp/pv/testPVAuxInfo.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* testPVAuxInfo.cpp */ -/** - * Copyright - See the COPYRIGHT that is included with this distribution. - * EPICS pvData is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - */ -/* Author: Marty Kraimer Date: 2010.11 */ - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace epics::pvData; -using std::tr1::static_pointer_cast; - -static bool debug = false; - -static FieldCreatePtr fieldCreate; -static PVDataCreatePtr pvDataCreate; -static StandardFieldPtr standardField; -static StandardPVFieldPtr standardPVField; -static ConvertPtr convert; -static String buffer; - -static void printOffsets(PVStructurePtr pvStructure) -{ - printf("%s offset %lu next %lu number %lu\n", - pvStructure->getFieldName().c_str(), - (long unsigned)pvStructure->getFieldOffset(), - (long unsigned)pvStructure->getNextFieldOffset(), - (long unsigned)pvStructure->getNumberFields()); - PVFieldPtrArray fields = pvStructure->getPVFields(); - int number = (int)pvStructure->getStructure()->getNumberFields(); - for(int i=0; igetField()->getType()==structure) { - PVStructurePtr xxx = static_pointer_cast(pvField); - printOffsets(xxx); - continue; - } - printf("%s offset %lli next %lli number %lli\n", - pvField->getFieldName().c_str(), - (long long)pvField->getFieldOffset(), - (long long)pvField->getNextFieldOffset(), - (long long)pvField->getNumberFields()); - } -} - -static void testPVAuxInfo() -{ - if(debug) printf("\ntestPVAuxInfo\n"); - PVStructurePtr pvStructure = standardPVField->scalar( - pvDouble,"alarm,timeStamp,display,control"); - PVStructurePtr display - = pvStructure->getStructureField("display"); - testOk1(display.get()!=NULL); - PVAuxInfoPtr auxInfo = display->getPVAuxInfo(); - auxInfo->createInfo("factory",pvString); - auxInfo->createInfo("junk",pvDouble); - PVScalarPtr pscalar = auxInfo->getInfo(String("factory")); - testOk1(pscalar.get()!=0); - convert->fromString(pscalar,"factoryName"); - pscalar = auxInfo->getInfo("junk"); - testOk1(pscalar.get()!=0); - convert->fromString(pscalar,"3.0"); - buffer.clear(); - pvStructure->toString(&buffer); - if(debug) printf("%s\n",buffer.c_str()); - // now show field offsets - if(debug) printOffsets(pvStructure); - printf("testPVAuxInfo PASSED\n"); -} - -MAIN(testPVAuxInfo) -{ - testPlan(3); - fieldCreate = getFieldCreate(); - pvDataCreate = getPVDataCreate(); - standardField = getStandardField(); - standardPVField = getStandardPVField(); - convert = getConvert(); - testPVAuxInfo(); - return testDone(); -} - diff --git a/testApp/pv/testPVData.cpp b/testApp/pv/testPVData.cpp index 020cca8..e37069a 100644 --- a/testApp/pv/testPVData.cpp +++ b/testApp/pv/testPVData.cpp @@ -24,6 +24,8 @@ using namespace epics::pvData; using std::tr1::static_pointer_cast; +using std::cout; +using std::endl; static bool debug = false; @@ -37,24 +39,6 @@ static String alarmTimeStamp("alarm,timeStamp"); static String alarmTimeStampValueAlarm("alarm,timeStamp,valueAlarm"); static String allProperties("alarm,timeStamp,display,control,valueAlarm"); -static void testAppend() -{ - if(debug) printf("\ntestAppend\n"); - PVFieldPtrArray pvFields; - StringArray fieldNames; - PVStructurePtr pvParent = pvDataCreate->createPVStructure( - fieldNames,pvFields); - PVStringPtr pvStringField = static_pointer_cast( - pvDataCreate->createPVScalar(pvString)); - pvStringField->put(String("value,timeStamp")); - PVFieldPtr pvField = pvStringField; - pvParent->appendPVField("request",pvField); - builder.clear(); - pvParent->toString(&builder); - if(debug) printf("%s\n",builder.c_str()); - printf("testAppend PASSED\n"); -} - static void testCreatePVStructure() { if(debug) printf("\ntestCreatePVStructure\n"); @@ -360,7 +344,7 @@ static void testScalarArrayCommon(String /*fieldName*/,ScalarType stype) pvStructure->toString(&builder); if(debug) printf("%s\n",builder.c_str()); PVFieldPtr pvField = pvStructure->getSubField("alarm.status"); - pvField->message("this is a test",infoMessage); + testOk1(pvField!=NULL); } static void testScalarArray() @@ -377,18 +361,72 @@ static void testScalarArray() printf("testScalarArray PASSED\n"); } +static void testRequest() +{ + if(debug) printf("\ntestScalarArray\n"); + StringArray nullNames; + FieldConstPtrArray nullFields; + StringArray optionNames(1); + FieldConstPtrArray optionFields(1); + optionNames[0] = "process"; + optionFields[0] = fieldCreate->createScalar(pvString); + StringArray recordNames(1); + FieldConstPtrArray recordFields(1); + recordNames[0] = "_options"; + recordFields[0] = fieldCreate->createStructure(optionNames,optionFields); + StringArray fieldNames(2); + FieldConstPtrArray fieldFields(2); + fieldNames[0] = "alarm"; + fieldFields[0] = fieldCreate->createStructure(nullNames,nullFields); + fieldNames[1] = "timeStamp"; + fieldFields[1] = fieldCreate->createStructure(nullNames,nullFields); + StringArray topNames(2); + FieldConstPtrArray topFields(2); + topNames[0] = "record"; + topFields[0] = fieldCreate->createStructure(recordNames,recordFields); + topNames[1] = "field"; + topFields[1] = fieldCreate->createStructure(fieldNames,fieldFields); + StructureConstPtr topStructure = fieldCreate->createStructure( + topNames,topFields); +String buffer; +topStructure->toString(&buffer); +cout << buffer.c_str() << endl; + PVStructurePtr pvTop = pvDataCreate->createPVStructure(topStructure); +buffer.clear(); +pvTop->toString(&buffer); +cout << buffer.c_str() << endl; +buffer.clear(); +pvTop->getStructure()->toString(&buffer); +cout << buffer.c_str() << endl; +PVStructurePtr xxx = pvTop->getSubField("record"); +buffer.clear(); +xxx->toString(&buffer); +cout << buffer.c_str() << endl; +xxx = pvTop->getSubField("field"); +buffer.clear(); +xxx->toString(&buffer); +cout << buffer.c_str() << endl; +PVStringPtr pvString = pvTop->getSubField("record._options.process"); +pvString->put("true"); +buffer.clear(); +pvTop->toString(&buffer); +cout << buffer.c_str() << endl; +cout << pvTop->dumpValue(cout) << endl; + +} + MAIN(testPVData) { - testPlan(179); + testPlan(187); fieldCreate = getFieldCreate(); pvDataCreate = getPVDataCreate(); standardField = getStandardField(); standardPVField = getStandardPVField(); convert = getConvert(); - testAppend(); testCreatePVStructure(); testPVScalar(); testScalarArray(); + testRequest(); return testDone(); }