/*PVStructure.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 #include #define epicsExportSharedSymbols #include #include #include #include #include using std::tr1::static_pointer_cast; using std::size_t; using std::string; namespace epics { namespace pvData { PVFieldPtr PVStructure::nullPVField; PVBooleanPtr PVStructure::nullPVBoolean; PVBytePtr PVStructure::nullPVByte; PVShortPtr PVStructure::nullPVShort; PVIntPtr PVStructure::nullPVInt; PVLongPtr PVStructure::nullPVLong; PVUBytePtr PVStructure::nullPVUByte; PVUShortPtr PVStructure::nullPVUShort; PVUIntPtr PVStructure::nullPVUInt; PVULongPtr PVStructure::nullPVULong; PVFloatPtr PVStructure::nullPVFloat; PVDoublePtr PVStructure::nullPVDouble; PVStringPtr PVStructure::nullPVString; PVStructurePtr PVStructure::nullPVStructure; PVStructureArrayPtr PVStructure::nullPVStructureArray; PVUnionPtr PVStructure::nullPVUnion; PVUnionArrayPtr PVStructure::nullPVUnionArray; PVScalarArrayPtr PVStructure::nullPVScalarArray; static PVFieldPtr findSubField( string const &fieldName, const PVStructure *pvStructure); PVStructure::PVStructure(StructureConstPtr const & structurePtr) : PVField(structurePtr), structurePtr(structurePtr), extendsStructureName("") { size_t numberFields = structurePtr->getNumberFields(); FieldConstPtrArray const & fields = structurePtr->getFields(); StringArray const & fieldNames = structurePtr->getFieldNames(); // PVFieldPtrArray * xxx = const_cast(&pvFields); pvFields.reserve(numberFields); PVDataCreatePtr pvDataCreate = getPVDataCreate(); for(size_t i=0; icreatePVField(fields[i])); } for(size_t i=0; isetParentAndName(this,fieldNames[i]); } } PVStructure::PVStructure(StructureConstPtr const & structurePtr, PVFieldPtrArray const & pvs ) : PVField(structurePtr), structurePtr(structurePtr), extendsStructureName("") { size_t numberFields = structurePtr->getNumberFields(); StringArray const & fieldNames = structurePtr->getFieldNames(); pvFields.reserve(numberFields); for(size_t i=0; isetParentAndName(this,fieldNames[i]); } } PVStructure::~PVStructure() { } void PVStructure::setImmutable() { size_t numFields = pvFields.size(); for(size_t i=0; isetImmutable(); } PVField::setImmutable(); } StructureConstPtr PVStructure::getStructure() const { return structurePtr; } const PVFieldPtrArray & PVStructure::getPVFields() const { return pvFields; } PVFieldPtr PVStructure::getSubField(string const &fieldName) const { return findSubField(fieldName,this); } PVFieldPtr PVStructure::getSubField(size_t fieldOffset) const { if(fieldOffset<=getFieldOffset()) { return nullPVField; } if(fieldOffset>getNextFieldOffset()) return nullPVField; size_t numFields = pvFields.size(); for(size_t i=0; igetFieldOffset()==fieldOffset) return pvFields[i]; if(pvField->getNextFieldOffset()<=fieldOffset) continue; if(pvField->getField()->getType()==structure) { PVStructure *pvStructure = static_cast(pvField.get()); return pvStructure->getSubField(fieldOffset); } } throw std::logic_error("PVStructure.getSubField: Logic error"); } PVBooleanPtr PVStructure::getBooleanField(string const &fieldName) { return getSubField(fieldName); } PVBytePtr PVStructure::getByteField(string const &fieldName) { return getSubField(fieldName); } PVShortPtr PVStructure::getShortField(string const &fieldName) { return getSubField(fieldName); } PVIntPtr PVStructure::getIntField(string const &fieldName) { return getSubField(fieldName); } PVLongPtr PVStructure::getLongField(string const &fieldName) { return getSubField(fieldName); } PVUBytePtr PVStructure::getUByteField(string const &fieldName) { return getSubField(fieldName); } PVUShortPtr PVStructure::getUShortField(string const &fieldName) { return getSubField(fieldName); } PVUIntPtr PVStructure::getUIntField(string const &fieldName) { return getSubField(fieldName); } PVULongPtr PVStructure::getULongField(string const &fieldName) { return getSubField(fieldName); } PVFloatPtr PVStructure::getFloatField(string const &fieldName) { return getSubField(fieldName); } PVDoublePtr PVStructure::getDoubleField(string const &fieldName) { return getSubField(fieldName); } PVStringPtr PVStructure::getStringField(string const &fieldName) { return getSubField(fieldName); } PVStructurePtr PVStructure::getStructureField(string const &fieldName) { return getSubField(fieldName); } PVUnionPtr PVStructure::getUnionField(string const &fieldName) { return getSubField(fieldName); } PVScalarArrayPtr PVStructure::getScalarArrayField( string const &fieldName,ScalarType elementType) { PVFieldPtr pvField = findSubField(fieldName,this); if(pvField.get()==NULL) { return nullPVScalarArray; } FieldConstPtr field = pvField->getField(); Type type = field->getType(); if(type!=scalarArray) { return nullPVScalarArray; } ScalarArrayConstPtr pscalarArray = static_pointer_cast(pvField->getField()); if(pscalarArray->getElementType()!=elementType) { return nullPVScalarArray; } return std::tr1::static_pointer_cast(pvField); } PVStructureArrayPtr PVStructure::getStructureArrayField( string const &fieldName) { return getSubField(fieldName); } PVUnionArrayPtr PVStructure::getUnionArrayField( string const &fieldName) { return getSubField(fieldName); } void PVStructure::serialize(ByteBuffer *pbuffer, SerializableControl *pflusher) const { size_t fieldsSize = pvFields.size(); for(size_t i = 0; iserialize(pbuffer, pflusher); } void PVStructure::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol) { size_t fieldsSize = pvFields.size(); for(size_t i = 0; ideserialize(pbuffer, pcontrol); } void PVStructure::serialize(ByteBuffer *pbuffer, SerializableControl *pflusher, BitSet *pbitSet) const { PVStructure* nonConstThis = const_cast(this); size_t numberFields = nonConstThis->getNumberFields(); size_t offset = nonConstThis->getFieldOffset(); int32 next = pbitSet->nextSetBit(static_cast(offset)); // no more changes or no changes in this structure if(next<0||next>=static_cast(offset+numberFields)) return; // entire structure if(static_cast(offset)==next) { serialize(pbuffer, pflusher); return; } size_t fieldsSize = pvFields.size(); for(size_t i = 0; igetFieldOffset(); int32 inumberFields = static_cast(pvField->getNumberFields()); next = pbitSet->nextSetBit(static_cast(offset)); // no more changes if(next<0) return; // no change in this pvField if(next>=static_cast(offset+inumberFields)) continue; // serialize field or fields if(inumberFields==1) { pvField->serialize(pbuffer, pflusher); } else { PVStructurePtr pvStructure = std::tr1::static_pointer_cast(pvField); pvStructure->serialize(pbuffer, pflusher, pbitSet); } } } void PVStructure::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol, BitSet *pbitSet) { size_t offset = getFieldOffset(); size_t numberFields = getNumberFields(); int32 next = pbitSet->nextSetBit(static_cast(offset)); // no more changes or no changes in this structure if(next<0||next>=static_cast(offset+numberFields)) return; // entire structure if(static_cast(offset)==next) { deserialize(pbuffer, pcontrol); return; } size_t fieldsSize = pvFields.size(); for(size_t i = 0; igetFieldOffset(); int32 inumberFields = static_cast(pvField->getNumberFields()); next = pbitSet->nextSetBit(static_cast(offset)); // no more changes if(next<0) return; // no change in this pvField if(next>=static_cast(offset+inumberFields)) continue; // deserialize field or fields if(inumberFields==1) { pvField->deserialize(pbuffer, pcontrol); } else { PVStructurePtr pvStructure = std::tr1::static_pointer_cast(pvField); pvStructure->deserialize(pbuffer, pcontrol, pbitSet); } } } static PVFieldPtr findSubField( string const & fieldName, PVStructure const *pvStructure) { if( fieldName.length()<1) return PVFieldPtr(); string::size_type index = fieldName.find('.'); string name = fieldName; string restOfName = string(); if(index>0) { name = fieldName.substr(0, index); if(fieldName.length()>index) { restOfName = fieldName.substr(index+1); } } PVFieldPtrArray const & pvFields = pvStructure->getPVFields(); PVFieldPtr pvField; size_t numFields = pvStructure->getStructure()->getNumberFields(); for(size_t i=0; igetFieldName().compare(name); if(result==0) { if(restOfName.length()==0) return pvFields[i]; if(pvField->getField()->getType()!=structure) return PVFieldPtr(); PVStructurePtr pvStructure = std::tr1::static_pointer_cast(pvField); return findSubField(restOfName,pvStructure.get()); } } return PVFieldPtr(); } std::ostream& PVStructure::dumpValue(std::ostream& o) const { o << format::indent() << getStructure()->getID() << ' ' << getFieldName(); o << std::endl; { format::indent_scope s(o); PVFieldPtrArray const & fieldsData = getPVFields(); if (fieldsData.size() != 0) { size_t length = getStructure()->getNumberFields(); for(size_t i=0; igetField()->getType(); if (type == scalar || type == scalarArray) o << format::indent() << fieldField->getField()->getID() << ' ' << fieldField->getFieldName() << ' ' << *(fieldField.get()) << std::endl; else o << *(fieldField.get()); } } } return o; } }}