PVRecordFieldPtr PVRecord::findPVRecordField( PVRecordStructurePtr const & pvrs, PVFieldPtr const & pvField) { size_t desiredOffset = pvField->getFieldOffset(); PVFieldPtr pvf = pvrs->getPVField(); size_t offset = pvf->getFieldOffset(); if(offset==desiredOffset) return pvrs; PVRecordFieldPtrArrayPtr pvrfpap = pvrs->getPVRecordFields(); PVRecordFieldPtrArray::iterator iter; for (iter = pvrfpap.get()->begin(); iter!=pvrfpap.get()->end(); iter++ ) { PVRecordFieldPtr pvrf = *iter; pvf = pvrf->getPVField(); offset = pvf->getFieldOffset(); if(offset==desiredOffset) return pvrf; size_t nextOffset = pvf->getNextFieldOffset(); if(nextOffset<=desiredOffset) continue; return findPVRecordField( static_pointer_cast<PVRecordStructure>(pvrf), pvField); } throw std::logic_error( recordName + " pvField " + pvField->getFieldName() + " not in PVRecord"); }
void PVStructure::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol, BitSet *pbitSet) { size_t offset = getFieldOffset(); size_t numberFields = getNumberFields(); int32 next = pbitSet->nextSetBit(offset); // no more changes or no changes in this structure if(next<0||next>=static_cast<int32>(offset+numberFields)) return; // entire structure if(static_cast<int32>(offset)==next) { deserialize(pbuffer, pcontrol); return; } size_t fieldsSize = pvFields.size(); for(size_t i = 0; i<fieldsSize; i++) { PVFieldPtr pvField = pvFields[i]; offset = pvField->getFieldOffset(); int32 inumberFields = pvField->getNumberFields(); next = pbitSet->nextSetBit(offset); // no more changes if(next<0) return; // no change in this pvField if(next>=static_cast<int32>(offset+inumberFields)) continue; // deserialize field or fields if(inumberFields==1) { pvField->deserialize(pbuffer, pcontrol); } else { PVStructurePtr pvStructure = std::tr1::static_pointer_cast<PVStructure>(pvField); pvStructure->deserialize(pbuffer, pcontrol, pbitSet); } } }
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; i<numFields; i++) { PVFieldPtr pvField = pvFields[i]; if(pvField->getFieldOffset()==fieldOffset) return pvFields[i]; if(pvField->getNextFieldOffset()<=fieldOffset) continue; if(pvField->getField()->getType()==structure) { PVStructure *pvStructure = static_cast<PVStructure *>(pvField.get()); return pvStructure->getSubField(fieldOffset); } } throw std::logic_error("PVStructure.getSubField: Logic error"); }
static void test() { std::ostringstream oss; testDiag("\ntestBitSetUtil\n"); StringArray fieldNames; PVFieldPtrArray pvFields; fieldNames.reserve(5); pvFields.reserve(5); fieldNames.push_back("timeStamp"); fieldNames.push_back("alarm"); fieldNames.push_back("voltage"); fieldNames.push_back("power"); fieldNames.push_back("current"); pvFields.push_back( pvDataCreate->createPVStructure(standardField->timeStamp())); pvFields.push_back( pvDataCreate->createPVStructure(standardField->alarm())); pvFields.push_back( pvDataCreate->createPVStructure( standardField->scalar(pvDouble,"alarm"))); pvFields.push_back( pvDataCreate->createPVStructure( standardField->scalar(pvDouble,"alarm"))); pvFields.push_back( pvDataCreate->createPVStructure( standardField->scalar(pvDouble,"alarm"))); PVStructurePtr pvs = pvDataCreate->createPVStructure( fieldNames,pvFields); int32 nfields = (int32)pvs->getNumberFields(); BitSetPtr bitSet = BitSet::create(nfields); for(int32 i=0; i<nfields; i++) bitSet->set(i); BitSetUtil::compress(bitSet,pvs); bitSet->clear(); PVFieldPtr pvField = pvs->getSubField<PVStructure>("timeStamp"); int32 offsetTimeStamp = (int32)pvField->getFieldOffset(); pvField = pvs->getSubField<PVLong>("timeStamp.secondsPastEpoch"); int32 offsetSeconds = (int32)pvField->getFieldOffset(); pvField = pvs->getSubField<PVInt>("timeStamp.nanoseconds"); int32 offsetNano = (int32)pvField->getFieldOffset(); pvField = pvs->getSubField<PVInt>("timeStamp.userTag"); int32 offsetUserTag = (int32)pvField->getFieldOffset(); bitSet->set(offsetSeconds); BitSetUtil::compress(bitSet,pvs); testOk1(bitSet->get(offsetSeconds)==true); bitSet->set(offsetNano); bitSet->set(offsetUserTag); BitSetUtil::compress(bitSet,pvs); testOk1(bitSet->get(offsetSeconds)==false); testOk1(bitSet->get(offsetTimeStamp)==true); bitSet->clear(); pvField = pvs->getSubField<PVStructure>("current"); int32 offsetCurrent = (int32)pvField->getFieldOffset(); pvField = pvs->getSubField<PVDouble>("current.value"); int32 offsetValue = (int32)pvField->getFieldOffset(); pvField = pvs->getSubField<PVStructure>("current.alarm"); int32 offsetAlarm = (int32)pvField->getFieldOffset(); pvField = pvs->getSubField<PVInt>("current.alarm.severity"); int32 offsetSeverity = (int32)pvField->getFieldOffset(); pvField = pvs->getSubField<PVInt>("current.alarm.status"); int32 offsetStatus = (int32)pvField->getFieldOffset(); pvField = pvs->getSubField<PVString>("current.alarm.message"); int32 offsetMessage = (int32)pvField->getFieldOffset(); bitSet->set(offsetValue); bitSet->set(offsetSeverity); bitSet->set(offsetStatus); bitSet->set(offsetMessage); BitSetUtil::compress(bitSet,pvs); testOk1(bitSet->get(offsetCurrent)==true); bitSet->clear(); bitSet->set(offsetSeverity); bitSet->set(offsetStatus); bitSet->set(offsetMessage); BitSetUtil::compress(bitSet,pvs); testOk1(bitSet->get(offsetAlarm)==true); bitSet->clear(); printf("testBitSetUtil PASSED\n"); }