/* pvStructureCopy.h */ /* * Copyright information and license terms for this software can be * found in the file LICENSE that is included with the distribution */ /** * @author Marty Kraimer * @date 2013.04 */ #ifndef PVSTRUCTURECOPY_H #define PVSTRUCTURECOPY_H #ifdef epicsExportSharedSymbols # define pvaConstantsepicsExportSharedSymbols # undef epicsExportSharedSymbols #endif #include #include #include #include #include #ifdef pvdatabaseEpicsExportSharedSymbols # define epicsExportSharedSymbols # undef pvdatabaseEpicsExportSharedSymbols #endif #include namespace epics { namespace pvCopy{ class PVCopyTraverseMasterCallback; typedef std::tr1::shared_ptr PVCopyTraverseMasterCallbackPtr; /** * @brief Callback for traversing master structure * * Must be implemented by code that creates pvCopy. * * This was originally name pvCopy.h and implemented in pvDataCPP * When it was moved to pvDatabaseCPP it was renamed to prevent conflicts with * the version in pvDataCPP. * Also the namespace was changed from epics::pvData to epics::pvCopy */ class epicsShareClass PVCopyTraverseMasterCallback { public: POINTER_DEFINITIONS(PVCopyTraverseMasterCallback); virtual ~PVCopyTraverseMasterCallback() {} /** * Called once for each field in master. * @param pvField The field in master. */ 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 CopyStructureNode; typedef std::tr1::shared_ptr CopyStructureNodePtr; /** * @brief Support for subset of fields in a pvStructure. * * Class that manages one or more PVStructures that holds an arbitrary subset of the fields * in another PVStructure called master. */ class epicsShareClass PVCopy : public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(PVCopy); /** * Create a new pvCopy * @param pvMaster The top-level structure for which a copy of * an arbitrary subset of the fields in master will be created and managed. * @param pvRequest Selects the set of subfields desired and options for each field. * @param structureName The name for the top level of any PVStructure created. */ static PVCopyPtr create( epics::pvData::PVStructurePtr const &pvMaster, epics::pvData::PVStructurePtr const &pvRequest, std::string const & structureName); virtual ~PVCopy(){} virtual void destroy(); /** * Get the top-level structure of master * @returns The master top-level structure. * This should not be modified. */ epics::pvData::PVStructurePtr getPVMaster(); /** * Traverse all the fields in master. * @param callback This is called for each field on master. */ void traverseMaster(PVCopyTraverseMasterCallbackPtr const & callback); /** * Get the introspection interface for a PVStructure for e copy. */ epics::pvData::StructureConstPtr getStructure(); /** * Create a copy instance. Monitors keep a queue of monitor elements. * Since each element needs a PVStructure, multiple top-level structures will be created. */ epics::pvData::PVStructurePtr createPVStructure(); /** * Given a field in pvMaster. return the offset in copy for the same field. * A value of std::string::npos means that the copy does not have this field. * @param masterPVField The field in master. */ std::size_t getCopyOffset(epics::pvData::PVFieldPtr const &masterPVField); /** * Given a field in pvMaster. return the offset in copy for the same field. * A value of std::string::npos means that the copy does not have this field. * @param masterPVStructure A structure in master that has masterPVField. * @param masterPVField The field in master. */ std::size_t getCopyOffset( epics::pvData::PVStructurePtr const &masterPVStructure, epics::pvData::PVFieldPtr const &masterPVField); /** * Given an offset in the copy get the corresponding field in pvMaster. * @param structureOffset The offset in the copy. */ epics::pvData::PVFieldPtr getMasterPVField(std::size_t structureOffset); /** * Initialize the fields in copyPVStructure by giving each field * the value from the corresponding field in pvMaster. * bitSet will be set to show that all fields are changed. * @param copyPVStructure A copy top-level structure. * @param bitSet A bitSet for copyPVStructure. */ void initCopy( epics::pvData::PVStructurePtr const ©PVStructure, epics::pvData::BitSetPtr const &bitSet); /** * Set all fields in copyPVStructure to the value of the corresponding field in pvMaster. * Each field that is changed has it's corresponding bit set in bitSet. * @param copyPVStructure A copy top-level structure. * @param bitSet A bitSet for copyPVStructure. * @returns (false,true) if client (should not,should) receive changes. */ bool updateCopySetBitSet( epics::pvData::PVStructurePtr const ©PVStructure, epics::pvData::BitSetPtr const &bitSet); /** * For each set bit in bitSet * set the field in copyPVStructure to the value of the corresponding field in pvMaster. * @param copyPVStructure A copy top-level structure. * @param bitSet A bitSet for copyPVStructure. * @returns (false,true) if client (should not,should) receive changes. */ bool updateCopyFromBitSet( epics::pvData::PVStructurePtr const ©PVStructure, epics::pvData::BitSetPtr const &bitSet); /** * For each set bit in bitSet * set the field in pvMaster to the value of the corresponding field in copyPVStructure * @param copyPVStructure A copy top-level structure. * @param bitSet A bitSet for copyPVStructure. */ void updateMaster( epics::pvData::PVStructurePtr const ©PVStructure, epics::pvData::BitSetPtr const &bitSet); /** * Get the options for the field at the specified offset. * @param fieldOffset the offset in copy. * @returns A NULL is returned if no options were specified for the field. * If options were specified,PVStructurePtr is a structures * with a set of PVString subfields that specify name,value pairs.s * name is the subField name and value is the subField value. */ epics::pvData::PVStructurePtr getOptions(std::size_t fieldOffset); /** * For debugging. */ std::string dump(); private: PVCopyPtr getPtrSelf() { return shared_from_this(); } epics::pvData::PVStructurePtr pvMaster; epics::pvData::StructureConstPtr structure; CopyNodePtr headNode; epics::pvData::PVStructurePtr cacheInitStructure; epics::pvData::BitSetPtr ignorechangeBitSet; void traverseMaster( CopyNodePtr const &node, PVCopyTraverseMasterCallbackPtr const & callback); void updateCopySetBitSet( epics::pvData::PVFieldPtr const &pvCopy, epics::pvData::PVFieldPtr const &pvMaster, epics::pvData::BitSetPtr const &bitSet); void updateCopySetBitSet( epics::pvData::PVFieldPtr const &pvCopy, CopyNodePtr const &node, epics::pvData::BitSetPtr const &bitSet); void updateCopyFromBitSet( epics::pvData::PVFieldPtr const &pvCopy, CopyNodePtr const &node, epics::pvData::BitSetPtr const &bitSet); void updateMasterField( CopyNodePtr const & node, epics::pvData::PVFieldPtr const & pvCopy, epics::pvData::PVFieldPtr const &pvMaster, epics::pvData::BitSetPtr const &bitSet); void updateMasterCheckBitSet( epics::pvData::PVStructurePtr const ©PVStructure, epics::pvData::BitSetPtr const &bitSet, size_t nextSet); CopyNodePtr getCopyNode(std::size_t fieldOffset); PVCopy(epics::pvData::PVStructurePtr const &pvMaster); bool init(epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::StructureConstPtr createStructure( epics::pvData::PVStructurePtr const &pvMaster, epics::pvData::PVStructurePtr const &pvFromRequest); CopyNodePtr createStructureNodes( epics::pvData::PVStructurePtr const &pvMasterStructure, epics::pvData::PVStructurePtr const &pvFromRequest, epics::pvData::PVStructurePtr const &pvFromField); void initPlugin( CopyNodePtr const & node, epics::pvData::PVStructurePtr const & pvOptions, epics::pvData::PVFieldPtr const & pvMasterField); void traverseMasterInitPlugin(); void traverseMasterInitPlugin(CopyNodePtr const & node); CopyNodePtr getCopyOffset( CopyStructureNodePtr const &structureNode, epics::pvData::PVFieldPtr const &masterPVField); bool checkIgnore( epics::pvData::PVStructurePtr const & copyPVStructure, epics::pvData::BitSetPtr const & bitSet); void setIgnore(CopyNodePtr const & node); CopyNodePtr getMasterNode( CopyStructureNodePtr const &structureNode, std::size_t structureOffset); void dump( std::string *builder, CopyNodePtr const &node, int indentLevel); }; }} #endif /* PVSTRUCTURECOPY_H */