void PVUnionArray::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol) { svector data(reuse()); size_t size = this->getArray()->getArraySizeType() == Array::fixed ? this->getArray()->getMaximumCapacity() : SerializeHelper::readSize(pbuffer, pcontrol); data.resize(size); UnionConstPtr punion = unionArray->getUnion(); PVDataCreatePtr pvDataCreate = getPVDataCreate(); for(size_t i = 0; i<size; i++) { pcontrol->ensureData(1); size_t temp = pbuffer->getByte(); if(temp==0) { data[i].reset(); } else { if(data[i].get()==NULL || !data[i].unique()) { data[i] = pvDataCreate->createPVUnion(punion); } data[i]->deserialize(pbuffer, pcontrol); } } replace(freeze(data)); // calls postPut() }
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; }
size_t PVUnionArray::append(size_t number) { checkLength(value.size()+number); svector data(reuse()); data.resize(data.size()+number); UnionConstPtr punion = unionArray->getUnion(); PVDataCreatePtr pvDataCreate = getPVDataCreate(); for(svector::reverse_iterator it = data.rbegin(); number; ++it, --number) *it = pvDataCreate->createPVUnion(punion); size_t newLength = data.size(); const_svector cdata(freeze(data)); swap(cdata); return newLength; }
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); }
static void testCopy() { TEST_COPY(PVBoolean, 1); TEST_COPY(PVByte, 12); TEST_COPY(PVShort, 128); TEST_COPY(PVInt, 128000); TEST_COPY(PVLong, 128000000); TEST_COPY(PVUByte, 12); TEST_COPY(PVUShort, 128); TEST_COPY(PVUInt, 128000); TEST_COPY(PVULong, 128000000); TEST_COPY(PVFloat, 12.8); TEST_COPY(PVDouble, 8.12); TEST_COPY(PVString, "jikes"); int32 testValue = 128; // PVStructure test PVStructurePtr pvStructure = standardPVField->scalar(pvInt, alarmTimeStampValueAlarm); pvStructure->getSubField<PVInt>("value")->put(testValue); PVTimeStamp timeStamp; timeStamp.attach(pvStructure->getSubField<PVStructure>("timeStamp")); TimeStamp current; current.getCurrent(); timeStamp.set(current); PVStructurePtr pvStructureCopy = standardPVField->scalar(pvInt, alarmTimeStampValueAlarm); pvStructureCopy->copy(*pvStructure); testOk(*pvStructure == *pvStructureCopy, "PVStructure copy"); PVStructurePtr pvStructureCopy2 = standardPVField->scalar(pvInt, alarmTimeStampValueAlarm); pvStructureCopy2->copyUnchecked(*pvStructure); testOk(*pvStructure == *pvStructureCopy2, "PVStructure copyUnchecked"); BitSet mask(pvStructure->getNumberFields()); PVStructurePtr pvStructureCopy3 = standardPVField->scalar(pvInt, alarmTimeStampValueAlarm); PVStructurePtr pvStructureCopy4 = standardPVField->scalar(pvInt, alarmTimeStampValueAlarm); pvStructureCopy3->copyUnchecked(*pvStructure, mask); testOk(*pvStructureCopy3 == *pvStructureCopy4, "PVStructure copyUnchecked w/ cleared mask"); mask.set(pvStructure->getSubField<PVInt>("value")->getFieldOffset()); pvStructureCopy3->copyUnchecked(*pvStructure, mask); pvStructureCopy4->getSubField<PVInt>("value")->put(testValue); testOk(*pvStructureCopy3 == *pvStructureCopy4, "PVStructure copyUnchecked w/ value mask only"); mask.set(pvStructure->getSubField<PVStructure>("timeStamp")->getFieldOffset()); PVStructurePtr pvStructureCopy5 = standardPVField->scalar(pvInt, alarmTimeStampValueAlarm); pvStructureCopy5->copyUnchecked(*pvStructure, mask); testOk(*pvStructure == *pvStructureCopy5, "PVStructure copyUnchecked w/ value+timeStamp mask"); UnionConstPtr _union = fieldCreate->createFieldBuilder()-> add("doubleValue", pvDouble)-> add("intValue", pvInt)-> add("timeStamp",standardField->timeStamp())-> createUnion(); PVUnionPtr pvUnion = pvDataCreate->createPVUnion(_union); PVUnionPtr pvUnion2 = pvDataCreate->createPVUnion(_union); pvUnion2->copy(*pvUnion); testOk(*pvUnion == *pvUnion2, "null PVUnion copy"); pvUnion->select<PVInt>("intValue")->put(123); pvUnion2->copy(*pvUnion); testOk(*pvUnion == *pvUnion2, "PVUnion scalar copy, to null PVUnion"); pvUnion->select("doubleValue"); pvUnion2->copy(*pvUnion); testOk(*pvUnion == *pvUnion2, "PVUnion scalar copy, to different type PVUnion"); pvUnion->select<PVStructure>("timeStamp")->copy( *pvStructure->getSubField<PVStructure>("timeStamp") ); pvUnion2->copy(*pvUnion); testOk(*pvUnion == *pvUnion2, "PVUnion PVStructure copy, to different type PVUnion"); }