FieldBuilderPtr FieldBuilder::addArray(string const & name, FieldConstPtr const & element) { switch (element->getType()) { case structure: fields.push_back(fieldCreate->createStructureArray(static_pointer_cast<const Structure>(element))); break; case union_: fields.push_back(fieldCreate->createUnionArray(static_pointer_cast<const Union>(element))); break; case scalar: if (std::tr1::dynamic_pointer_cast<const BoundedString>(element).get()) throw std::invalid_argument("bounded string arrays are not supported"); fields.push_back(fieldCreate->createScalarArray(static_pointer_cast<const Scalar>(element)->getScalarType())); break; // scalarArray? default: std::ostringstream msg("unsupported array element type: "); msg << element->getType(); throw std::invalid_argument(msg.str()); } fieldNames.push_back(name); return shared_from_this(); }
void PVField::computeOffset(const PVField * pvField,size_t offset) { size_t beginOffset = offset; size_t nextOffset = offset + 1; const PVStructure *pvStructure = static_cast<const PVStructure *>(pvField); const PVFieldPtrArray & pvFields = pvStructure->getPVFields(); for(size_t i=0; i < pvStructure->getStructure()->getNumberFields(); i++) { offset = nextOffset; PVField *pvSubField = pvFields[i].get(); FieldConstPtr field = pvSubField->getField(); switch(field->getType()) { case scalar: case scalarArray: case structureArray: case union_: case unionArray: { nextOffset++; pvSubField->fieldOffset = offset; pvSubField->nextFieldOffset = nextOffset; break; } case structure: { pvSubField->computeOffset(pvSubField,offset); nextOffset = pvSubField->getNextFieldOffset(); } } } PVField *xxx = const_cast<PVField *>(pvField); xxx->fieldOffset = beginOffset; xxx->nextFieldOffset = nextOffset; }
PVFieldPtr PVDataCreate::createPVField(FieldConstPtr const & field) { switch(field->getType()) { case scalar: { ScalarConstPtr xx = static_pointer_cast<const Scalar>(field); return createPVScalar(xx); } case scalarArray: { ScalarArrayConstPtr xx = static_pointer_cast<const ScalarArray>(field); return createPVScalarArray(xx); } case structure: { StructureConstPtr xx = static_pointer_cast<const Structure>(field); return createPVStructure(xx); } case structureArray: { StructureArrayConstPtr xx = static_pointer_cast<const StructureArray>(field); return createPVStructureArray(xx); } case union_: { UnionConstPtr xx = static_pointer_cast<const Union>(field); return createPVUnion(xx); } case unionArray: { UnionArrayConstPtr xx = static_pointer_cast<const UnionArray>(field); return createPVUnionArray(xx); } } throw std::logic_error("PVDataCreate::createPVField should never get here"); }
PVScalarArrayPtr PVStructure::getScalarArrayField( String const &fieldName,ScalarType elementType) { PVFieldPtr pvField = findSubField(fieldName,this); if(pvField.get()==NULL) { String message("fieldName "); message += fieldName + " does not exist"; this->message(message, errorMessage); return nullPVScalarArray; } FieldConstPtr field = pvField->getField(); Type type = field->getType(); if(type!=scalarArray) { String message("fieldName "); message += fieldName + " does not have type array "; this->message(message, errorMessage); return nullPVScalarArray; } ScalarArrayConstPtr pscalarArray = static_pointer_cast<const ScalarArray>(pvField->getField()); if(pscalarArray->getElementType()!=elementType) { String message("fieldName "); message += fieldName + " is array but does not have elementType "; ScalarTypeFunc::toString(&message,elementType); this->message(message, errorMessage); return nullPVScalarArray; } return std::tr1::static_pointer_cast<PVScalarArray>(pvField); }
static void setValue(PVUnionPtr const &pvUnion, double value) { UnionConstPtr u = pvUnion->getUnion(); FieldConstPtr field = u->getField(0); Type type = field->getType(); if(type==scalar) { ScalarConstPtr scalar = static_pointer_cast<const Scalar>(field); ScalarType scalarType = scalar->getScalarType(); if(scalarType==pvDouble) { PVDoublePtr pvValue = static_pointer_cast<PVDouble>( pvDataCreate->createPVScalar(pvDouble)); pvValue->put(value); pvUnion->set(0,pvValue); return; } if(scalarType==pvString) { PVStringPtr pvValue = static_pointer_cast<PVString>( pvDataCreate->createPVScalar(pvString)); stringstream ss; ss << "value" << value; pvValue->put(ss.str()); pvUnion->set(0,pvValue); return; } throw std::runtime_error("only pvDouble and pvString are supported"); } if(type==scalarArray) { ScalarArrayConstPtr scalarArray = static_pointer_cast<const ScalarArray>(field); ScalarType scalarType = scalarArray->getElementType(); if(scalarType==pvDouble) { size_t num = 5; PVDoubleArrayPtr pvValue = static_pointer_cast<PVDoubleArray>( pvDataCreate->createPVScalarArray(pvDouble)); shared_vector<double> data(num); for(size_t i=0; i<num; ++i) data[i] = value +i; pvValue->replace(freeze(data)); pvUnion->set(0,pvValue); return; } if(scalarType==pvString) { size_t num = 5; PVStringArrayPtr pvValue = static_pointer_cast<PVStringArray>( pvDataCreate->createPVScalarArray(pvString)); shared_vector<string> data(num); for(size_t i=0; i<num; ++i) { stringstream ss; ss << "value" << value << i; data[i] = ss.str(); } pvValue->replace(freeze(data)); pvUnion->set(0,pvValue); return; } throw std::runtime_error("only pvDouble and pvString are supported"); } throw std::runtime_error("only scalar and scalarArray fields are supported"); }
void testSerializeCommon(FieldConstPtr serverField1, FieldConstPtr clientField2) { //server serializes field 1 serialize(serverField1,serverRegistry); //full should be serialized buffer->flip(); checkTypeCode(IntrospectionRegistry::FULL_WITH_ID_TYPE_CODE); //client deserializes 1 FieldConstPtr clientField1 = deserialize(clientRegistry); assert(serverField1->getFieldName() == clientField1->getFieldName()); assert(serverField1->getType() == clientField1->getType()); //client serializes the same field serialize(serverField1,clientRegistry); //only id should be serialized buffer->flip(); checkTypeCode(IntrospectionRegistry::ONLY_ID_TYPE_CODE); //server deserializes the same field serverField1 = deserialize(serverRegistry); assert(serverField1->getFieldName() == clientField1->getFieldName()); assert(serverField1->getType() == clientField1->getType()); //client requests new field serialize(clientField2,clientRegistry); //full should be serialized buffer->flip(); checkTypeCode(IntrospectionRegistry::FULL_WITH_ID_TYPE_CODE); //server deserializes new field FieldConstPtr serverField2 = deserialize(serverRegistry); assert(serverField2->getFieldName() == clientField2->getFieldName()); assert(serverField2->getType() == clientField2->getType()); }
void Structure::dumpFields(std::ostream& o) const { size_t numberFields = fields.size(); for(size_t i=0; i<numberFields; i++) { FieldConstPtr pfield = fields[i]; o << format::indent() << pfield->getID() << ' ' << fieldNames[i] << std::endl; switch(pfield->getType()) { case scalar: case scalarArray: break; case structure: { Field const *xxx = pfield.get(); Structure const *pstruct = static_cast<Structure const*>(xxx); format::indent_scope s(o); pstruct->dumpFields(o); break; } case structureArray: { format::indent_scope s(o); Field const *xxx = pfield.get(); StructureArray const *pstructureArray = static_cast<StructureArray const*>(xxx); o << *pstructureArray->getStructure(); break; } case union_: { Field const *xxx = pfield.get(); Union const *punion = static_cast<Union const*>(xxx); format::indent_scope s(o); punion->dumpFields(o); break; } case unionArray: { format::indent_scope s(o); Field const *xxx = pfield.get(); UnionArray const *punionArray = static_cast<UnionArray const*>(xxx); o << *punionArray->getUnion(); break; } } } }
void PVField::computeOffset(const PVField * pvField) { const PVStructure * pvTop = pvField->getParent(); if(pvTop==NULL) { if(pvField->getField()->getType()!=structure) { PVField *xxx = const_cast<PVField *>(pvField); xxx->fieldOffset = 0; xxx->nextFieldOffset = 1; return; } pvTop = static_cast<const PVStructure *>(pvField); } else { while(pvTop->getParent()!=NULL) pvTop = pvTop->getParent(); } size_t offset = 0; size_t nextOffset = 1; const PVFieldPtrArray & pvFields = pvTop->getPVFields(); for(size_t i=0; i < pvTop->getStructure()->getNumberFields(); i++) { offset = nextOffset; PVField *pvField = pvFields[i].get(); FieldConstPtr field = pvField->getField(); switch(field->getType()) { case scalar: case scalarArray: case structureArray: case union_: case unionArray: { nextOffset++; pvField->fieldOffset = offset; pvField->nextFieldOffset = nextOffset; break; } case structure: { pvField->computeOffset(pvField,offset); nextOffset = pvField->getNextFieldOffset(); } } } PVField *top = (PVField *)pvTop; PVField *xxx = const_cast<PVField *>(top); xxx->fieldOffset = 0; xxx->nextFieldOffset = nextOffset; }
StructureConstPtr StandardField::createProperties(String id,FieldConstPtr field,String properties) { bool gotAlarm = false; bool gotTimeStamp = false; bool gotDisplay = false; bool gotControl = false; bool gotValueAlarm = false; int numProp = 0; if(properties.find("alarm")!=String::npos) { gotAlarm = true; numProp++; } if(properties.find("timeStamp")!=String::npos) { gotTimeStamp = true; numProp++; } if(properties.find("display")!=String::npos) { gotDisplay = true; numProp++; } if(properties.find("control")!=String::npos) { gotControl = true; numProp++; } if(properties.find("valueAlarm")!=String::npos) { gotValueAlarm = true; numProp++; } StructureConstPtr valueAlarm; Type type= field->getType(); while(gotValueAlarm) { if(type==epics::pvData::scalar || type==epics::pvData::scalarArray) { ScalarType scalarType = (type==epics::pvData::scalar) ? static_pointer_cast<const Scalar>(field)->getScalarType() : static_pointer_cast<const ScalarArray>(field)->getElementType(); switch(scalarType) { case pvBoolean: valueAlarm = booleanAlarmField; break; case pvByte: valueAlarm = byteAlarmField; break; case pvShort: valueAlarm = shortAlarmField; break; case pvInt: valueAlarm = intAlarmField; break; case pvLong: valueAlarm = longAlarmField; break; case pvUByte: valueAlarm = ubyteAlarmField; break; case pvUShort: valueAlarm = ushortAlarmField; break; case pvUInt: valueAlarm = uintAlarmField; break; case pvULong: valueAlarm = ulongAlarmField; break; case pvFloat: valueAlarm = floatAlarmField; break; case pvDouble: valueAlarm = doubleAlarmField; break; case pvString: throw std::logic_error(String("valueAlarm property not supported for pvString")); } break; } if(type==structure) { StructureConstPtr structurePtr = static_pointer_cast<const Structure>(field); StringArray names = structurePtr->getFieldNames(); if(names.size()==2) { FieldConstPtrArray fields = structurePtr->getFields(); FieldConstPtr first = fields[0]; FieldConstPtr second = fields[1]; String nameFirst = names[0]; String nameSecond = names[1]; int compareFirst = nameFirst.compare("index"); int compareSecond = nameSecond.compare("choices"); if(compareFirst==0 && compareSecond==0) { if(first->getType()==epics::pvData::scalar && second->getType()==epics::pvData::scalarArray) { ScalarConstPtr scalarFirst = static_pointer_cast<const Scalar>(first); ScalarArrayConstPtr scalarArraySecond = static_pointer_cast<const ScalarArray>(second); if(scalarFirst->getScalarType()==pvInt && scalarArraySecond->getElementType()==pvString) { valueAlarm = enumeratedAlarmField; break; } } } } } throw std::logic_error(String("valueAlarm property for illegal type")); } size_t numFields = numProp+1; FieldConstPtrArray fields(numFields); StringArray names(numFields); int next = 0; names[0] = "value"; fields[next++] = field; if(gotAlarm) { names[next] = "alarm"; fields[next++] = alarmField; } if(gotTimeStamp) { names[next] = "timeStamp"; fields[next++] = timeStampField; } if(gotDisplay) { names[next] = "display"; fields[next++] = displayField; } if(gotControl) { names[next] = "control"; fields[next++] = controlField; } if(gotValueAlarm) { names[next] = "valueAlarm"; fields[next++] = valueAlarm; } return fieldCreate->createStructure(id,names,fields); }