size_t fromString(PVUnionArrayPtr const &pv, StringArray const & from, size_t fromStartIndex = 0) { int processed = 0; size_t fromValueCount = from.size(); // first get count if (fromStartIndex >= fromValueCount) throw std::runtime_error("not enough of values"); size_t numberOfUnions; istringstream iss(from[fromStartIndex]); iss >> numberOfUnions; // not fail and entire value is parsed (e.g. to detect 1.2 parsing to 1) if (iss.fail() || !iss.eof()) throw runtime_error("failed to parse element count value (uint) of field '" + pv->getFieldName() + "' from string value '" + from[fromStartIndex] + "'"); fromStartIndex++; processed++; PVUnionArray::svector pvUnions; pvUnions.reserve(numberOfUnions); PVDataCreatePtr pvDataCreate = getPVDataCreate(); for (size_t i = 0; i < numberOfUnions; ++i) { PVUnionPtr pvUnion = pvDataCreate->createPVUnion(pv->getUnionArray()->getUnion()); size_t count = fromString(pvUnion, from, fromStartIndex); processed += count; fromStartIndex += count; pvUnions.push_back(pvUnion); } pv->replace(freeze(pvUnions)); return processed; }
PVFieldPtr PVDataCreate::createPVField(PVFieldPtr const & fieldToClone) { switch(fieldToClone->getField()->getType()) { case scalar: { PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(fieldToClone); return createPVScalar(pvScalar); } case scalarArray: { PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(fieldToClone); return createPVScalarArray(pvScalarArray); } case structure: { PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(fieldToClone); StringArray const & fieldNames = pvStructure->getStructure()->getFieldNames(); PVFieldPtrArray const & pvFieldPtrArray = pvStructure->getPVFields(); return createPVStructure(fieldNames,pvFieldPtrArray); } case structureArray: { PVStructureArrayPtr from = static_pointer_cast<PVStructureArray>(fieldToClone); StructureArrayConstPtr structureArray = from->getStructureArray(); PVStructureArrayPtr to = createPVStructureArray( structureArray); to->copyUnchecked(*from); return to; } case union_: { PVUnionPtr pvUnion = static_pointer_cast<PVUnion>(fieldToClone); return createPVUnion(pvUnion); } case unionArray: { PVUnionArrayPtr from = static_pointer_cast<PVUnionArray>(fieldToClone); UnionArrayConstPtr unionArray = from->getUnionArray(); PVUnionArrayPtr to = createPVUnionArray(unionArray); to->copyUnchecked(*from); return to; } } throw std::logic_error("PVDataCreate::createPVField should never get here"); }
static void test() { NTMultiChannelBuilderPtr builder = NTMultiChannel::createBuilder(); testOk(builder.get() != 0, "Got builder"); NTMultiChannelPtr multiChannel = builder-> addDescriptor()-> addAlarm()-> addTimeStamp()-> addSeverity() -> add("extra1",fieldCreate->createScalar(pvString)) -> add("extra2",fieldCreate->createScalarArray(pvString)) -> create(); testOk1(multiChannel.get() != 0); PVStructurePtr pvStructure = multiChannel->getPVStructure(); testOk1(pvStructure.get()!=NULL); testOk1(NTMultiChannel::is_a(pvStructure->getStructure())); size_t nchan = 3; shared_vector<string> names(nchan); names[0] = "channel 0"; names[1] = "channel 1"; names[2] = "channel 2"; shared_vector<const string> channelNames(freeze(names)); PVStringArrayPtr pvChannelName = multiChannel->getChannelName(); pvChannelName->replace(channelNames); if(debug) {cout << *pvStructure << endl;} UnionConstPtr unionPtr = fieldCreate->createFieldBuilder()-> add("doubleValue", pvDouble)-> add("intValue", pvInt)-> createUnion(); multiChannel = builder-> value(unionPtr) -> addDescriptor()-> addAlarm()-> addTimeStamp()-> addSeverity() -> addIsConnected() -> create(); testOk1(multiChannel.get() != 0); pvStructure = multiChannel->getPVStructure(); if(debug) {cout << *pvStructure << endl;} pvChannelName = multiChannel->getChannelName(); pvChannelName->replace(channelNames); PVUnionArrayPtr pvValue = multiChannel->getValue(); shared_vector<PVUnionPtr> unions(nchan); unions[0] = pvDataCreate->createPVUnion(unionPtr); unions[1] = pvDataCreate->createPVUnion(unionPtr); unions[2] = pvDataCreate->createPVUnion(unionPtr); unions[0]->select("doubleValue"); unions[1]->select("intValue"); unions[2]->select("intValue"); PVDoublePtr pvDouble = unions[0]->get<PVDouble>(); pvDouble->put(1.235); PVIntPtr pvInt = unions[1]->get<PVInt>(); pvInt->put(5); pvInt = unions[2]->get<PVInt>(); pvInt->put(7); pvValue->replace(freeze(unions)); shared_vector<int32> severities(nchan); severities[0] = 0; severities[1] = 1; severities[2] = 2; PVIntArrayPtr pvSeverity = multiChannel->getSeverity(); pvSeverity->replace(freeze(severities)); if(debug) {cout << *pvStructure << endl;} PVBooleanArrayPtr pvIsConnected = multiChannel->getIsConnected(); shared_vector<const epics::pvData::boolean> isConnected = pvIsConnected->view(); multiChannel = builder-> value(unionPtr) -> addDescriptor()-> addAlarm()-> addTimeStamp()-> addSeverity() -> addStatus() -> addMessage() -> addSecondsPastEpoch() -> addNanoseconds() -> addUserTag() -> addIsConnected() -> create(); testOk1(multiChannel.get() != 0); pvStructure = multiChannel->getPVStructure(); if(debug) {cout << *pvStructure << endl;} testOk1(NTMultiChannel::isCompatible(pvStructure)==true); PVStructurePtr pvTimeStamp = multiChannel->getTimeStamp(); testOk1(pvTimeStamp.get() !=0); PVStructurePtr pvAlarm = multiChannel->getAlarm(); testOk1(pvAlarm.get() !=0); pvValue = multiChannel->getValue(); testOk1(pvValue.get() !=0); pvChannelName = multiChannel->getChannelName(); testOk1(pvChannelName.get() !=0); pvIsConnected = multiChannel->getIsConnected(); testOk1(pvIsConnected.get() !=0); pvSeverity = multiChannel->getSeverity(); testOk1(pvSeverity.get() !=0); PVIntArrayPtr pvStatus = multiChannel->getStatus(); testOk1(pvStatus.get() !=0); PVStringArrayPtr pvMessage = multiChannel->getMessage(); testOk1(pvMessage.get() !=0); PVLongArrayPtr pvSecondsPastEpoch = multiChannel->getSecondsPastEpoch(); testOk1(pvSecondsPastEpoch.get() !=0); PVIntArrayPtr pvNanoseconds = multiChannel->getNanoseconds(); testOk1(pvNanoseconds.get() !=0); PVIntArrayPtr pvUserTag = multiChannel->getUserTag(); testOk1(pvUserTag.get() !=0); PVStringPtr pvDescriptor = multiChannel->getDescriptor(); testOk1(pvDescriptor.get() !=0); }