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();
}
Beispiel #2
0
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");
}
Beispiel #4
0
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");
}
Beispiel #6
0
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;
            }
        }
    }
}
Beispiel #8
0
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;
}
Beispiel #9
0
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);
}