diff --git a/src/copy/pvCopy.cpp b/src/copy/pvCopy.cpp index 9c36913..15502b5 100644 --- a/src/copy/pvCopy.cpp +++ b/src/copy/pvCopy.cpp @@ -18,7 +18,6 @@ #include #include -#include using std::tr1::static_pointer_cast; using std::tr1::dynamic_pointer_cast; @@ -29,6 +28,18 @@ using std::endl; namespace epics { namespace pvData { +/** + * Convenience method for implementing dump. + * It generates a newline and inserts blanks at the beginning of the newline. + * @param builder The std::string * being constructed. + * @param indentLevel Indent level, Each level is four spaces. + */ +static void newLine(string *buffer, int indentLevel) +{ + *buffer += "\n"; + *buffer += string(indentLevel*4, ' '); +} + static PVCopyPtr NULLPVCopy; static FieldConstPtr NULLField; static StructureConstPtr NULLStructure; @@ -243,10 +254,9 @@ void PVCopy::updateCopySetBitSet( updateSubFieldSetBitSet(copyPVField,pvMasterField,bitSet); return; } - ConvertPtr convert = getConvert(); - bool isEqual = convert->equals(copyPVField,pvField); + bool isEqual = (*copyPVField == *pvField); if(!isEqual) { - convert->copy(pvField, copyPVField); + copyPVField->copyUnchecked(*pvField); bitSet->set(copyPVField->getFieldOffset()); } } @@ -292,7 +302,7 @@ string PVCopy::dump() void PVCopy::dump(string *builder,CopyNodePtr const &node,int indentLevel) { - getConvert()->newLine(builder,indentLevel); + newLine(builder,indentLevel); std::stringstream ss; ss << (node->isStructure ? "structureNode" : "masterNode"); ss << " structureOffset " << node->structureOffset; @@ -300,14 +310,14 @@ void PVCopy::dump(string *builder,CopyNodePtr const &node,int indentLevel) *builder += ss.str(); PVStructurePtr options = node->options; if(options) { - getConvert()->newLine(builder,indentLevel +1); + newLine(builder,indentLevel +1); // TODO !!! ugly std::ostringstream oss; oss << *options; *builder += oss.str(); - getConvert()->newLine(builder,indentLevel); + newLine(builder,indentLevel); } if(!node->isStructure) { CopyMasterNodePtr masterNode = static_pointer_cast(node); @@ -320,7 +330,7 @@ void PVCopy::dump(string *builder,CopyNodePtr const &node,int indentLevel) CopyNodePtrArrayPtr nodes = structureNode->nodes; for(size_t i=0; isize(); ++i) { if((*nodes)[i].get()==NULL) { - getConvert()->newLine(builder,indentLevel +1); + newLine(builder,indentLevel +1); ss.str(""); ss << "node[" << i << "] is null"; *builder += ss.str(); @@ -499,17 +509,16 @@ void PVCopy::updateSubFieldSetBitSet( FieldConstPtr field = pvCopy->getField(); Type type = field->getType(); if(type!=epics::pvData::structure) { - ConvertPtr convert = getConvert(); - bool isEqual = convert->equals(pvCopy,pvMaster); + bool isEqual = (*pvCopy == *pvMaster); if(isEqual) { if(type==structureArray) { // always act as though a change occurred. // Note that array elements are shared. - bitSet->set(pvCopy->getFieldOffset()); + bitSet->set(pvCopy->getFieldOffset()); } } if(isEqual) return; - convert->copy(pvMaster, pvCopy); + pvCopy->copyUnchecked(*pvMaster); bitSet->set(pvCopy->getFieldOffset()); return; } @@ -574,7 +583,6 @@ void PVCopy::updateSubFieldFromBitSet( if(nextSet==string::npos) return; if(nextSet>=pvCopy->getNextFieldOffset()) return; } - ConvertPtr convert = getConvert(); if(pvCopy->getField()->getType()==epics::pvData::structure) { PVStructurePtr pvCopyStructure = static_pointer_cast(pvCopy); @@ -595,9 +603,9 @@ void PVCopy::updateSubFieldFromBitSet( } } else { if(toCopy) { - convert->copy(pvMasterField, pvCopy); + pvCopy->copyUnchecked(*pvMasterField); } else { - convert->copy(pvCopy, pvMasterField); + pvMasterField->copyUnchecked(*pvCopy); } } } diff --git a/src/factory/Compare.cpp b/src/factory/Compare.cpp index 19c0230..116e9e9 100644 --- a/src/factory/Compare.cpp +++ b/src/factory/Compare.cpp @@ -12,7 +12,7 @@ #include #define epicsExportSharedSymbols -#include +#include using std::string; diff --git a/src/factory/Convert.cpp b/src/factory/Convert.cpp index 359ea75..dfdc5dc 100644 --- a/src/factory/Convert.cpp +++ b/src/factory/Convert.cpp @@ -152,388 +152,6 @@ size_t Convert::toStringArray(PVScalarArrayPtr const & pv, return data.size(); } -bool Convert::isCopyCompatible(FieldConstPtr const &from, FieldConstPtr const &to) -{ - if(from->getType()!=to->getType()) return false; - switch(from->getType()) { - case scalar: - { - ScalarConstPtr xxx = static_pointer_cast(from); - ScalarConstPtr yyy = static_pointer_cast(to); - return isCopyScalarCompatible(xxx,yyy); - } - case scalarArray: - { - ScalarArrayConstPtr xxx = static_pointer_cast(from); - ScalarArrayConstPtr yyy = static_pointer_cast(to); - return isCopyScalarArrayCompatible(xxx,yyy); - } - case structure: - { - StructureConstPtr xxx = static_pointer_cast(from); - StructureConstPtr yyy = static_pointer_cast(to); - return isCopyStructureCompatible(xxx,yyy); - } - case structureArray: - { - StructureArrayConstPtr xxx = static_pointer_cast(from); - StructureArrayConstPtr yyy = static_pointer_cast(to); - return isCopyStructureArrayCompatible(xxx,yyy); - } - case union_: - { - UnionConstPtr xxx = static_pointer_cast(from); - UnionConstPtr yyy = static_pointer_cast(to); - return isCopyUnionCompatible(xxx,yyy); - } - case unionArray: - { - UnionArrayConstPtr xxx = static_pointer_cast(from); - UnionArrayConstPtr yyy = static_pointer_cast(to); - return isCopyUnionArrayCompatible(xxx,yyy); - } - } - string message("Convert::isCopyCompatible should never get here"); - throw std::logic_error(message); -} - -void Convert::copy(PVFieldPtr const & from, PVFieldPtr const & to) -{ - switch(from->getField()->getType()) { - case scalar: - { - PVScalarPtr xxx = static_pointer_cast(from); - PVScalarPtr yyy = static_pointer_cast(to); - copyScalar(xxx,yyy); - return; - } - case scalarArray: - { - PVScalarArrayPtr fromArray = static_pointer_cast(from); - PVScalarArrayPtr toArray = static_pointer_cast(to); - toArray->assign(*fromArray.get()); - return; - } - case structure: - { - PVStructurePtr xxx = static_pointer_cast(from); - PVStructurePtr yyy = static_pointer_cast(to); - copyStructure(xxx,yyy); - return; - } - case structureArray: { - PVStructureArrayPtr fromArray = static_pointer_cast(from); - PVStructureArrayPtr toArray = static_pointer_cast(to); - copyStructureArray(fromArray,toArray); - return; - } - case union_: - { - PVUnionPtr xxx = static_pointer_cast(from); - PVUnionPtr yyy = static_pointer_cast(to); - copyUnion(xxx,yyy); - return; - } - case unionArray: { - PVUnionArrayPtr fromArray = static_pointer_cast(from); - PVUnionArrayPtr toArray = static_pointer_cast(to); - copyUnionArray(fromArray,toArray); - return; - } - } -} - -bool Convert::isCopyScalarCompatible( - ScalarConstPtr const & fromField, ScalarConstPtr const & toField) -{ - ScalarType fromScalarType = fromField->getScalarType(); - ScalarType toScalarType = toField->getScalarType(); - if(fromScalarType==toScalarType) return true; - if(ScalarTypeFunc::isNumeric(fromScalarType) - && ScalarTypeFunc::isNumeric(toScalarType)) return true; - if(fromScalarType==pvString) return true; - if(toScalarType==pvString) return true; - return false; -} - -void Convert::copyScalar(PVScalarPtr const & from, PVScalarPtr const & to) -{ - if(to->isImmutable()) { - if(from==to) return; - string message("Convert.copyScalar destination is immutable"); - throw std::invalid_argument(message); - } - to->assign(*from.get()); -} - -bool Convert::isCopyScalarArrayCompatible(ScalarArrayConstPtr const &fromArray, - ScalarArrayConstPtr const &toArray) -{ - ScalarType fromType = fromArray->getElementType(); - ScalarType toType = toArray->getElementType(); - if(fromType==toType) return true; - if(ScalarTypeFunc::isNumeric(fromType) - && ScalarTypeFunc::isNumeric(toType)) return true; - if(toType==pvString) return true; - if(fromType==pvString) return true; - return false; -} - -bool Convert::isCopyStructureCompatible( - StructureConstPtr const &fromStruct, StructureConstPtr const &toStruct) -{ - FieldConstPtrArray const & fromFields = fromStruct->getFields(); - FieldConstPtrArray const & toFields = toStruct->getFields(); - size_t length = fromStruct->getNumberFields(); - if(length!=toStruct->getNumberFields()) return false; - for(size_t i=0; igetType(); - Type toType = to->getType(); - if(fromType!=toType) return false; - switch(fromType) { - case scalar: - { - ScalarConstPtr xxx = static_pointer_cast(from); - ScalarConstPtr yyy = static_pointer_cast(to); - if(!isCopyScalarCompatible(xxx,yyy)) return false; - } - break; - case scalarArray: - { - ScalarArrayConstPtr xxx = static_pointer_cast(from); - ScalarArrayConstPtr yyy = static_pointer_cast(to); - if(!isCopyScalarArrayCompatible(xxx,yyy)) return false; - } - break; - case structure: - { - StructureConstPtr xxx = static_pointer_cast(from); - StructureConstPtr yyy = static_pointer_cast(to); - if(!isCopyStructureCompatible(xxx,yyy)) return false; - } - break; - case structureArray: - { - StructureArrayConstPtr xxx = static_pointer_cast(from); - StructureArrayConstPtr yyy = static_pointer_cast(to); - if(!isCopyStructureArrayCompatible(xxx,yyy)) return false; - } - case union_: - { - UnionConstPtr xxx = static_pointer_cast(from); - UnionConstPtr yyy = static_pointer_cast(to); - if(!isCopyUnionCompatible(xxx,yyy)) return false; - } - break; - case unionArray: - { - UnionArrayConstPtr xxx = static_pointer_cast(from); - UnionArrayConstPtr yyy = static_pointer_cast(to); - if(!isCopyUnionArrayCompatible(xxx,yyy)) return false; - } - break; - } - } - return true; -} - -void Convert::copyStructure(PVStructurePtr const & from, PVStructurePtr const & to) -{ - if(to->isImmutable()) { - if(from==to) return; - throw std::invalid_argument("Convert.copyStructure destination is immutable"); - } - if(from==to) return; - PVFieldPtrArray const & fromDatas = from->getPVFields(); - PVFieldPtrArray const & toDatas = to->getPVFields(); - if(from->getStructure()->getNumberFields() - != to->getStructure()->getNumberFields()) { - string message("Convert.copyStructure Illegal copyStructure"); - throw std::invalid_argument(message); - } - size_t numberFields = from->getStructure()->getNumberFields(); - if(numberFields>=2) { - string name0 = fromDatas[0]->getFieldName(); - string name1 = fromDatas[1]->getFieldName(); - // look for enumerated structure and copy choices first - if(name0.compare("index")==0 && name1.compare("choices")==0) { - FieldConstPtr fieldIndex = fromDatas[0]->getField(); - FieldConstPtr fieldChoices = fromDatas[1]->getField(); - if(fieldIndex->getType()==scalar - && fieldChoices->getType()==scalarArray) { - PVScalarPtr pvScalar = static_pointer_cast(fromDatas[0]); - PVScalarArrayPtr pvArray = - static_pointer_cast(fromDatas[1]); - if((pvScalar->getScalar()->getScalarType()==pvInt) - && (pvArray->getScalarArray()->getElementType()==pvString)) { - PVScalarArrayPtr toArray = - static_pointer_cast(toDatas[1]); - toArray->assign(*pvArray.get()); - PVScalarPtr toScalar = static_pointer_cast(toDatas[0]); - copyScalar(pvScalar,toScalar); - return; - } - } - } - } - for(size_t i=0; i < numberFields; i++) { - PVFieldPtr fromData = fromDatas[i]; - PVFieldPtr toData = toDatas[i]; - Type fromType = fromData->getField()->getType(); - Type toType = toData->getField()->getType(); - if(fromType!=toType) { - string message("Convert.copyStructure Illegal copyStructure"); - throw std::invalid_argument(message); - } - if(toData->isImmutable()) { - if(fromData==toData) return; - throw std::invalid_argument("Convert.copyStructure destination is immutable"); - } - switch(fromType) { - case scalar: - { - PVScalarPtr xxx = static_pointer_cast(fromData); - PVScalarPtr yyy = static_pointer_cast(toData); - copyScalar(xxx,yyy); - break; - } - case scalarArray: - { - PVScalarArrayPtr fromArray = static_pointer_cast(fromData); - PVScalarArrayPtr toArray = static_pointer_cast(toData); - toArray->assign(*fromArray.get()); - break; - } - case structure: - { - PVStructurePtr xxx = static_pointer_cast(fromData); - PVStructurePtr yyy = static_pointer_cast(toData); - copyStructure(xxx,yyy); - break; - } - case structureArray: - { - PVStructureArrayPtr fromArray = - static_pointer_cast(fromData); - PVStructureArrayPtr toArray = - static_pointer_cast(toData); - copyStructureArray(fromArray,toArray); - break; - } - case union_: - { - PVUnionPtr xxx = static_pointer_cast(fromData); - PVUnionPtr yyy = static_pointer_cast(toData); - copyUnion(xxx,yyy); - break; - } - case unionArray: - { - PVUnionArrayPtr fromArray = - static_pointer_cast(fromData); - PVUnionArrayPtr toArray = - static_pointer_cast(toData); - copyUnionArray(fromArray,toArray); - break; - } - } - } -} - -bool Convert::isCopyUnionCompatible( - UnionConstPtr const &from, UnionConstPtr const &to) -{ - return *(from.get()) == *(to.get()); -} - -static PVDataCreatePtr pvDataCreate = getPVDataCreate(); - -void Convert::copyUnion(PVUnionPtr const & from, PVUnionPtr const & to) -{ - if(to->isImmutable()) { - if(from==to) return; - throw std::invalid_argument("Convert.copyUnion destination is immutable"); - } - if(from==to) return; - if(!isCopyUnionCompatible(from->getUnion(), to->getUnion())) { - throw std::invalid_argument("Illegal copyUnion"); - } - - PVFieldPtr fromValue = from->get(); - if (from->getUnion()->isVariant()) - { - if (fromValue.get() == 0) - to->set(PVField::shared_pointer()); - else - { - PVFieldPtr toValue = to->get(); - if (toValue.get() == 0 || *toValue->getField() != *fromValue->getField()) - { - toValue = pvDataCreate->createPVField(fromValue->getField()); - to->set(toValue); - } - copy(fromValue, toValue); - to->postPut(); - } - } - else - { - if (fromValue.get() == 0) - to->select(PVUnion::UNDEFINED_INDEX); - else - { - copy(fromValue, to->select(from->getSelectedIndex())); - } - to->postPut(); - } -} - -bool Convert::isCopyStructureArrayCompatible( - StructureArrayConstPtr const &from, StructureArrayConstPtr const &to) -{ - StructureConstPtr xxx = from->getStructure(); - StructureConstPtr yyy = to->getStructure(); - return isCopyStructureCompatible(xxx,yyy); -} - -void Convert::copyStructureArray( - PVStructureArrayPtr const & from, PVStructureArrayPtr const & to) -{ - if(from==to) { - return; - } else if(to->isImmutable()) { - throw std::invalid_argument("Convert.copyStructureArray destination is immutable"); - } - to->replace(from->view()); -} - -bool Convert::isCopyUnionArrayCompatible( - UnionArrayConstPtr const &from, UnionArrayConstPtr const &to) -{ - UnionConstPtr xxx = from->getUnion(); - UnionConstPtr yyy = to->getUnion(); - return isCopyUnionCompatible(xxx,yyy); -} - -void Convert::copyUnionArray( - PVUnionArrayPtr const & from, PVUnionArrayPtr const & to) -{ - if(from==to) { - return; - } else if(to->isImmutable()) { - throw std::invalid_argument("Convert.copyUnionArray destination is immutable"); - } - to->replace(from->view()); -} - -void Convert::newLine(string *buffer, int indentLevel) -{ - *buffer += "\n"; - *buffer += string(indentLevel*4, ' '); -} - ConvertPtr Convert::getConvert() { static ConvertPtr convert; diff --git a/src/factory/FieldCreateFactory.cpp b/src/factory/FieldCreateFactory.cpp index 3f4c250..c26dd34 100644 --- a/src/factory/FieldCreateFactory.cpp +++ b/src/factory/FieldCreateFactory.cpp @@ -22,7 +22,6 @@ #define epicsExportSharedSymbols #include #include -#include #include #include diff --git a/src/factory/PVDataCreateFactory.cpp b/src/factory/PVDataCreateFactory.cpp index e8eb148..a622384 100644 --- a/src/factory/PVDataCreateFactory.cpp +++ b/src/factory/PVDataCreateFactory.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -537,7 +536,7 @@ PVFieldPtr PVDataCreate::createPVField(PVFieldPtr const & fieldToClone) StructureArrayConstPtr structureArray = from->getStructureArray(); PVStructureArrayPtr to = createPVStructureArray( structureArray); - getConvert()->copyStructureArray(from, to); + to->copyUnchecked(*from); return to; } case union_: @@ -552,7 +551,7 @@ PVFieldPtr PVDataCreate::createPVField(PVFieldPtr const & fieldToClone) = static_pointer_cast(fieldToClone); UnionArrayConstPtr unionArray = from->getUnionArray(); PVUnionArrayPtr to = createPVUnionArray(unionArray); - getConvert()->copyUnionArray(from, to); + to->copyUnchecked(*from); return to; } } @@ -602,7 +601,7 @@ PVScalarPtr PVDataCreate::createPVScalar(PVScalarPtr const & scalarToClone) { ScalarType scalarType = scalarToClone->getScalar()->getScalarType(); PVScalarPtr pvScalar = createPVScalar(scalarType); - getConvert()->copyScalar(scalarToClone, pvScalar); + pvScalar->copyUnchecked(*scalarToClone); return pvScalar; } @@ -712,7 +711,7 @@ PVStructurePtr PVDataCreate::createPVStructure(PVStructurePtr const & structToCl } StructureConstPtr structure = structToClone->getStructure(); PVStructurePtr pvStructure(new PVStructure(structure)); - getConvert()->copyStructure(structToClone,pvStructure); + pvStructure->copyUnchecked(*structToClone); return pvStructure; } diff --git a/src/factory/PVField.cpp b/src/factory/PVField.cpp index 20db350..04a1769 100644 --- a/src/factory/PVField.cpp +++ b/src/factory/PVField.cpp @@ -16,7 +16,6 @@ #include #include #include -#include using std::tr1::const_pointer_cast; using std::size_t; @@ -180,4 +179,117 @@ void PVField::computeOffset(const PVField * pvField,size_t offset) { xxx->nextFieldOffset = nextOffset; } +void PVField::copy(const PVField& from) +{ + if(isImmutable()) + throw std::invalid_argument("destination is immutable"); + + if (getField()->getType() != from.getField()->getType()) + throw std::invalid_argument("field types do not match"); + + switch(getField()->getType()) + { + case scalar: + { + const PVScalar* fromS = static_cast(&from); + PVScalar* toS = static_cast(this); + toS->copy(*fromS); + break; + } + case scalarArray: + { + const PVScalarArray* fromS = static_cast(&from); + PVScalarArray* toS = static_cast(this); + toS->copy(*fromS); + break; + } + case structure: + { + const PVStructure* fromS = static_cast(&from); + PVStructure* toS = static_cast(this); + toS->copy(*fromS); + break; + } + case structureArray: + { + const PVStructureArray* fromS = static_cast(&from); + PVStructureArray* toS = static_cast(this); + toS->copy(*fromS); + break; + } + case union_: + { + const PVUnion* fromS = static_cast(&from); + PVUnion* toS = static_cast(this); + toS->copy(*fromS); + break; + } + case unionArray: + { + const PVUnionArray* fromS = static_cast(&from); + PVUnionArray* toS = static_cast(this); + toS->copy(*fromS); + break; + } + default: + { + throw std::logic_error("PVField::copy unknown type"); + } + } +} + +void PVField::copyUnchecked(const PVField& from) +{ + switch(getField()->getType()) + { + case scalar: + { + const PVScalar* fromS = static_cast(&from); + PVScalar* toS = static_cast(this); + toS->copyUnchecked(*fromS); + break; + } + case scalarArray: + { + const PVScalarArray* fromS = static_cast(&from); + PVScalarArray* toS = static_cast(this); + toS->copyUnchecked(*fromS); + break; + } + case structure: + { + const PVStructure* fromS = static_cast(&from); + PVStructure* toS = static_cast(this); + toS->copyUnchecked(*fromS); + break; + } + case structureArray: + { + const PVStructureArray* fromS = static_cast(&from); + PVStructureArray* toS = static_cast(this); + toS->copyUnchecked(*fromS); + break; + } + case union_: + { + const PVUnion* fromS = static_cast(&from); + PVUnion* toS = static_cast(this); + toS->copyUnchecked(*fromS); + break; + } + case unionArray: + { + const PVUnionArray* fromS = static_cast(&from); + PVUnionArray* toS = static_cast(this); + toS->copyUnchecked(*fromS); + break; + } + default: + { + throw std::logic_error("PVField::copy unknown type"); + } + } +} + + }} diff --git a/src/factory/PVStructure.cpp b/src/factory/PVStructure.cpp index e53e25f..841e919 100644 --- a/src/factory/PVStructure.cpp +++ b/src/factory/PVStructure.cpp @@ -16,7 +16,6 @@ #define epicsExportSharedSymbols #include #include -#include #include #include @@ -382,4 +381,79 @@ std::ostream& PVStructure::dumpValue(std::ostream& o) const return o; } + +void PVStructure::copy(const PVStructure& from) +{ + if(isImmutable()) + throw std::invalid_argument("destination is immutable"); + + if(*getStructure() != *from.getStructure()) + throw std::invalid_argument("structure definitions do not match"); + + copyUnchecked(from); +} + +void PVStructure::copyUnchecked(const PVStructure& from) +{ + if (this == &from) + return; + + PVFieldPtrArray const & fromPVFields = from.getPVFields(); + PVFieldPtrArray const & toPVFields = getPVFields(); + + size_t fieldsSize = fromPVFields.size(); + for(size_t i = 0; icopyUnchecked(*fromPVFields[i]); + } +} + +void PVStructure::copyUnchecked(const PVStructure& from, const BitSet& maskBitSet, bool inverse) +{ + if (this == &from) + return; + + size_t numberFields = from.getNumberFields(); + size_t offset = from.getFieldOffset(); + int32 next = inverse ? + maskBitSet.nextClearBit(static_cast(offset)) : + maskBitSet.nextSetBit(static_cast(offset)); + + // no more changes or no changes in this structure + if(next<0||next>=static_cast(offset+numberFields)) return; + + // entire structure + if(static_cast(offset)==next) { + copyUnchecked(from); + return; + } + + PVFieldPtrArray const & fromPVFields = from.getPVFields(); + PVFieldPtrArray const & toPVFields = getPVFields(); + + size_t fieldsSize = fromPVFields.size(); + for(size_t i = 0; igetFieldOffset(); + int32 inumberFields = static_cast(pvField->getNumberFields()); + next = inverse ? + maskBitSet.nextClearBit(static_cast(offset)) : + maskBitSet.nextSetBit(static_cast(offset)); + + // no more changes + if(next<0) return; + // no change in this pvField + if(next>=static_cast(offset+inumberFields)) continue; + + // serialize field or fields + if(inumberFields==1) { + toPVFields[i]->copyUnchecked(*pvField); + } else { + PVStructure::shared_pointer fromPVStructure = std::tr1::static_pointer_cast(pvField); + PVStructure::shared_pointer toPVStructure = std::tr1::static_pointer_cast(toPVFields[i]); + toPVStructure->copyUnchecked(*fromPVStructure, maskBitSet, inverse); + } + } +} + + }} diff --git a/src/factory/PVStructureArray.cpp b/src/factory/PVStructureArray.cpp index ffb5a37..2345044 100644 --- a/src/factory/PVStructureArray.cpp +++ b/src/factory/PVStructureArray.cpp @@ -14,7 +14,6 @@ #define epicsExportSharedSymbols #include -#include #include #include @@ -242,4 +241,23 @@ std::ostream& PVStructureArray::dumpValue(std::ostream& o, std::size_t index) co return o; } +void PVStructureArray::copy(const PVStructureArray& from) +{ + if(isImmutable()) + throw std::invalid_argument("destination is immutable"); + + if(*getStructureArray() != *from.getStructureArray()) + throw std::invalid_argument("structureArray definitions do not match"); + + copyUnchecked(from); +} + +void PVStructureArray::copyUnchecked(const PVStructureArray& from) +{ + if (this == &from) + return; + + replace(from.view()); +} + }} diff --git a/src/factory/PVUnion.cpp b/src/factory/PVUnion.cpp index 9848cb7..b7102dc 100644 --- a/src/factory/PVUnion.cpp +++ b/src/factory/PVUnion.cpp @@ -16,7 +16,6 @@ #define epicsExportSharedSymbols #include #include -#include #include #include @@ -29,6 +28,8 @@ namespace epics { namespace pvData { #define PVUNION_UNDEFINED_INDEX -1 int32 PVUnion::UNDEFINED_INDEX = PVUNION_UNDEFINED_INDEX; +PVDataCreatePtr PVUnion::pvDataCreate(getPVDataCreate()); + PVUnion::PVUnion(UnionConstPtr const & unionPtr) : PVField(unionPtr), unionPtr(unionPtr), @@ -87,7 +88,7 @@ PVFieldPtr PVUnion::select(int32 index) FieldConstPtr field = unionPtr->getField(index); selector = index; - value = getPVDataCreate()->createPVField(field); + value = pvDataCreate->createPVField(field); return value; } @@ -171,7 +172,7 @@ void PVUnion::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol) { // try to reuse existing field instance if (!value.get() || *value->getField() != *field) - value = getPVDataCreate()->createPVField(field); + value = pvDataCreate->createPVField(field); value->deserialize(pbuffer, pcontrol); } else @@ -188,7 +189,7 @@ void PVUnion::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol) FieldConstPtr field = unionPtr->getField(selector); // try to reuse existing field instance if (!value.get() || *value->getField() != *field) - value = getPVDataCreate()->createPVField(field); + value = pvDataCreate->createPVField(field); } value->deserialize(pbuffer, pcontrol); } @@ -217,4 +218,57 @@ std::ostream& PVUnion::dumpValue(std::ostream& o) const return o; } +void PVUnion::copy(const PVUnion& from) +{ + if(isImmutable()) + throw std::invalid_argument("destination is immutable"); + + if(*getUnion() != *from.getUnion()) + throw std::invalid_argument("union definitions do not match"); + + copyUnchecked(from); +} + +void PVUnion::copyUnchecked(const PVUnion& from) +{ + + PVFieldPtr fromValue = from.get(); + if (from.getUnion()->isVariant()) + { + if (fromValue.get() == 0) + { + set(PVField::shared_pointer()); + } + else + { + PVFieldPtr toValue = get(); + if (toValue.get() == 0 || *toValue->getField() != *fromValue->getField()) + { + toValue = pvDataCreate->createPVField(fromValue->getField()); + toValue->copyUnchecked(*fromValue); + set(toValue); + } + else + { + toValue->copyUnchecked(*fromValue); + postPut(); + } + } + } + else + { + if (fromValue.get() == 0) + { + select(PVUnion::UNDEFINED_INDEX); + } + else + { + select(from.getSelectedIndex())->copyUnchecked(*fromValue); + } + postPut(); + } + +} + + }} diff --git a/src/factory/PVUnionArray.cpp b/src/factory/PVUnionArray.cpp index ed516c6..db46c08 100644 --- a/src/factory/PVUnionArray.cpp +++ b/src/factory/PVUnionArray.cpp @@ -14,7 +14,6 @@ #define epicsExportSharedSymbols #include -#include #include #include @@ -241,4 +240,24 @@ std::ostream& PVUnionArray::dumpValue(std::ostream& o, std::size_t index) const return o; } +void PVUnionArray::copy(const PVUnionArray& from) +{ + if(isImmutable()) + throw std::invalid_argument("destination is immutable"); + + if(*getUnionArray() != *from.getUnionArray()) + throw std::invalid_argument("unionArray definitions do not match"); + + copyUnchecked(from); +} + +void PVUnionArray::copyUnchecked(const PVUnionArray& from) +{ + if (this == &from) + return; + + replace(from.view()); +} + + }} diff --git a/src/factory/StandardPVField.cpp b/src/factory/StandardPVField.cpp index f5738d6..3fff6fb 100644 --- a/src/factory/StandardPVField.cpp +++ b/src/factory/StandardPVField.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/src/misc/timer.cpp b/src/misc/timer.cpp index 6915471..b10f22f 100644 --- a/src/misc/timer.cpp +++ b/src/misc/timer.cpp @@ -14,9 +14,9 @@ #include #include +#include #define epicsExportSharedSymbols -#include #include using std::string; diff --git a/src/pv/convert.h b/src/pv/convert.h index 04baac9..b497caa 100644 --- a/src/pv/convert.h +++ b/src/pv/convert.h @@ -22,40 +22,6 @@ namespace epics { namespace pvData { -bool epicsShareExtern operator==(const PVField&, const PVField&); - -static inline bool operator!=(const PVField& a, const PVField& b) -{return !(a==b);} - - -bool epicsShareExtern operator==(const Field&, const Field&); -bool epicsShareExtern operator==(const Scalar&, const Scalar&); -bool epicsShareExtern operator==(const ScalarArray&, const ScalarArray&); -bool epicsShareExtern operator==(const Structure&, const Structure&); -bool epicsShareExtern operator==(const StructureArray&, const StructureArray&); -bool epicsShareExtern operator==(const Union&, const Union&); -bool epicsShareExtern operator==(const UnionArray&, const UnionArray&); -bool epicsShareExtern operator==(const BoundedString&, const BoundedString&); - -static inline bool operator!=(const Field& a, const Field& b) -{return !(a==b);} -static inline bool operator!=(const Scalar& a, const Scalar& b) -{return !(a==b);} -static inline bool operator!=(const ScalarArray& a, const ScalarArray& b) -{return !(a==b);} -static inline bool operator!=(const Structure& a, const Structure& b) -{return !(a==b);} -static inline bool operator!=(const StructureArray& a, const StructureArray& b) -{return !(a==b);} -static inline bool operator!=(const Union& a, const Union& b) -{return !(a==b);} -static inline bool operator!=(const UnionArray& a, const UnionArray& b) -{return !(a==b);} -static inline bool operator!=(const BoundedString& a, const BoundedString& b) -{return !(a==b);} - - - class Convert; typedef std::tr1::shared_ptr ConvertPtr; @@ -83,38 +49,18 @@ typedef std::tr1::shared_ptr ConvertPtr; class epicsShareClass Convert { public: static ConvertPtr getConvert(); - /** - * Get the full fieldName for the pvField. - * @param buf The string that will have the result. - * @param pvField The pvField. - */ - void getFullName(std::string *buf,PVFieldPtr const & pvField) - { - *buf = pvField->getFullName(); - } /** - * Do fields have the same definition. - * - * @param a First field - * @param b Second field - * @return (false, true) if the fields (are not, are) the same. + * Copy from a PVField to another PVField. + * This calls one on copyScalar, copyArray, copyStructure. + * The two arguments must be compatible. + * @param from The source. + * @param to The destination + * @throws std::invalid_argument if the arguments are not compatible. + * @DEPRECATED use "to->copy[Unchecked](*from)" instead */ - inline bool equals(PVFieldPtr const &a,PVFieldPtr const &b) - { - return *a==*b; - } - - /** - * Do fields have the same definition. - * - * @param a First field - * @param b Second field - * @return (false, true) if the fields (are not, are) the same. - */ - inline bool equals(PVField &a,PVField &b) - { - return a==b; + void copy(PVFieldPtr const & from, PVFieldPtr const & to) { + to->copy(*from); } /** @@ -197,128 +143,6 @@ public: std::size_t length, StringArray & to, std::size_t toOffset); - /** - * Are from and to valid arguments to copy. - * This first checks of both arguments have the same Type. - * Then calls one of isCopyScalarCompatible, - * isCopyArrayCompatible, or isCopyStructureCompatible. - * @param from The source. - * @param to The destination. - * @return (false,true) is the arguments (are not, are) compatible. - */ - bool isCopyCompatible(FieldConstPtr const & from, FieldConstPtr const & to); - /** - * Copy from a PVField to another PVField. - * This calls one on copyScalar, copyArray, copyStructure. - * The two arguments must be compatible. - * @param from The source. - * @param to The destination - * @throws std::invalid_argument if the arguments are not compatible. - */ - void copy(PVFieldPtr const & from, PVFieldPtr const & to); - /** - * Are from and to valid arguments to copyScalar. - * false will be returned if either argument is not a scalar as defined by Type.isScalar(). - * If both are scalars the return value is true if any of the following are true. - *
    - *
  • Both arguments are numeric.
  • - *
  • Both arguments have the same type.
  • - *
  • Either argument is a string.
  • - *
- * @param from The introspection interface for the from data. - * @param to The introspection interface for the to data.. - * @return (false,true) If the arguments (are not, are) compatible. - */ - bool isCopyScalarCompatible( - ScalarConstPtr const & from, - ScalarConstPtr const & to); - /** - * Copy from a scalar pv to another scalar pv. - * @param from the source. - * @param to the destination. - * @throws std::invalid_argument if the arguments are not compatible. - */ - void copyScalar(PVScalarPtr const & from, PVScalarPtr const & to); - /** - * Are from and to valid arguments to copyArray. - * The results are like isCopyScalarCompatible except that the tests are made on the elementType. - * @param from The from array. - * @param to The to array. - * @return (false,true) If the arguments (are not, are) compatible. - */ - bool isCopyScalarArrayCompatible( - ScalarArrayConstPtr const & from, - ScalarArrayConstPtr const & to); - /** - * Are from and to valid arguments for copyStructure. - * They are only compatible if they have the same Structure description. - * @param from from structure. - * @param to structure. - * @return (false,true) If the arguments (are not, are) compatible. - */ - bool isCopyStructureCompatible( - StructureConstPtr const & from, StructureConstPtr const & to); - /** - * Copy from a structure pv to another structure pv. - * NOTE: Only compatible nodes are copied. This means: - *
    - *
  • For scalar nodes this means that isCopyScalarCompatible is true.
  • - *
  • For array nodes this means that isCopyArrayCompatible is true.
  • - *
  • For structure nodes this means that isCopyStructureCompatible is true.
  • - *
  • Link nodes are not copied.
  • - *
- * @param from The source. - * @param to The destination. - * @throws std::invalid_argument if the arguments are not compatible. - */ - void copyStructure(PVStructurePtr const & from, PVStructurePtr const & to); - /** - * Are from and to valid for copyStructureArray. - * @param from The from StructureArray. - * @param to The to StructureArray. - * @return (false,true) If the arguments (are not, are) compatible. - */ - bool isCopyStructureArrayCompatible( - StructureArrayConstPtr const & from, StructureArrayConstPtr const & to); - /** - * Copy from a structure array to another structure array. - * @param from The source array. - * @param to The destination array. - */ - void copyStructureArray( - PVStructureArrayPtr const & from, PVStructureArrayPtr const & to); - /** - * Are from and to valid arguments for copyUnion. - * They are only compatible if they have the same Union description. - * @param from from union. - * @param to union. - * @return (false,true) If the arguments (are not, are) compatible. - */ - bool isCopyUnionCompatible( - UnionConstPtr const & from, UnionConstPtr const & to); - /** - * Copy from a union pv to another union pv. - * NOTE: Only compatible nodes are copied. - * @param from The source. - * @param to The destination. - * @throws std::invalid_argument if the arguments are not compatible. - */ - void copyUnion(PVUnionPtr const & from, PVUnionPtr const & to); - /** - * Are from and to valid for copyUnionArray. - * @param from The from UnionArray. - * @param to The to UnionArray. - * @return (false,true) If the arguments (are not, are) compatible. - */ - bool isCopyUnionArrayCompatible( - UnionArrayConstPtr const & from, UnionArrayConstPtr const & to); - /** - * Copy from a union array to another union array. - * @param from The source array. - * @param to The destination array. - */ - void copyUnionArray( - PVUnionArrayPtr const & from, PVUnionArrayPtr const & to); /** * Convert a PV to a . * @param pv a PV @@ -464,13 +288,6 @@ public: */ inline void fromDouble(PVScalarPtr const & pv, double from) { pv->putFrom(from); } - /** - * Convenience method for implementing dump. - * It generates a newline and inserts blanks at the beginning of the newline. - * @param builder The std::string * being constructed. - * @param indentLevel Indent level, Each level is four spaces. - */ - void newLine(std::string * buf, int indentLevel); }; static inline ConvertPtr getConvert() { return Convert::getConvert(); } diff --git a/src/pv/pvData.h b/src/pv/pvData.h index e045cb1..b8afbc5 100644 --- a/src/pv/pvData.h +++ b/src/pv/pvData.h @@ -233,6 +233,9 @@ public: */ virtual std::ostream& dumpValue(std::ostream& o) const = 0; + void copy(const PVField& from); + void copyUnchecked(const PVField& from); + protected: PVField::shared_pointer getPtrSelf() { @@ -320,6 +323,9 @@ public: virtual void assign(const PVScalar&) = 0; + virtual void copy(const PVScalar& from) = 0; + virtual void copyUnchecked(const PVScalar& from) = 0; + protected: PVScalar(ScalarConstPtr const & scalar); }; @@ -385,6 +391,25 @@ public: put(castUnsafe(val)); } + virtual void assign(const PVScalar& scalar) + { + if(isImmutable()) + throw std::invalid_argument("destination is immutable"); + copyUnchecked(scalar); + } + virtual void copy(const PVScalar& from) + { + assign(from); + } + virtual void copyUnchecked(const PVScalar& from) + { + if(this==&from) + return; + T result; + from.getAs((void*)&result, typeCode); + put(result); + } + protected: PVScalarValue(ScalarConstPtr const & scalar) : PVScalar(scalar) {} @@ -399,16 +424,6 @@ protected: castUnsafeV(1, typeCode, (void*)&result, stype, src); put(result); } - virtual void assign(const PVScalar& scalar) - { - if(this==&scalar) - return; - if(isImmutable()) - throw std::invalid_argument("Destination is immutable"); - T result; - scalar.getAs((void*)&result, typeCode); - put(result); - } private: friend class PVDataCreate; @@ -600,9 +615,21 @@ public: * If the types do match then a new refernce to the provided * data is kept. */ - void assign(PVScalarArray& pv) { + void assign(const PVScalarArray& pv) { + if (isImmutable()) + throw std::invalid_argument("destination is immutable"); + copyUnchecked(pv); + } + + void copy(const PVScalarArray& from) { + assign(from); + } + + void copyUnchecked(const PVScalarArray& from) { + if (this==&from) + return; shared_vector temp; - pv._getAsVoid(temp); + from._getAsVoid(temp); _putFromVoid(temp); } @@ -842,6 +869,11 @@ public: virtual std::ostream& dumpValue(std::ostream& o) const; + void copy(const PVStructure& from); + + void copyUnchecked(const PVStructure& from); + void copyUnchecked(const PVStructure& from, const BitSet& maskBitSet, bool inverse = false); + private: static PVFieldPtr nullPVField; static PVBooleanPtr nullPVBoolean; @@ -995,7 +1027,12 @@ public: virtual std::ostream& dumpValue(std::ostream& o) const; + void copy(const PVUnion& from); + void copyUnchecked(const PVUnion& from); + private: + static PVDataCreatePtr pvDataCreate; + friend class PVDataCreate; UnionConstPtr unionPtr; @@ -1238,6 +1275,9 @@ public: virtual std::ostream& dumpValue(std::ostream& o) const; virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const; + void copy(const PVStructureArray& from); + void copyUnchecked(const PVStructureArray& from); + protected: PVValueArray(StructureArrayConstPtr const & structureArray) :base_t(structureArray) @@ -1335,6 +1375,9 @@ public: virtual std::ostream& dumpValue(std::ostream& o) const; virtual std::ostream& dumpValue(std::ostream& o, std::size_t index) const; + void copy(const PVUnionArray& from); + void copyUnchecked(const PVUnionArray& from); + protected: PVValueArray(UnionArrayConstPtr const & unionArray) :base_t(unionArray) @@ -1564,6 +1607,11 @@ private: epicsShareExtern PVDataCreatePtr getPVDataCreate(); +bool epicsShareExtern operator==(const PVField&, const PVField&); + +static inline bool operator!=(const PVField& a, const PVField& b) +{return !(a==b);} + }} /** diff --git a/src/pv/pvIntrospect.h b/src/pv/pvIntrospect.h index cde0421..a7a1cfb 100644 --- a/src/pv/pvIntrospect.h +++ b/src/pv/pvIntrospect.h @@ -1219,6 +1219,32 @@ struct StructureArrayHashFunction { size_t operator() (const StructureArray& structureArray) const { StructureHashFunction shf; return (0x10 | shf(*(structureArray.getStructure()))); } }; +bool epicsShareExtern operator==(const Field&, const Field&); +bool epicsShareExtern operator==(const Scalar&, const Scalar&); +bool epicsShareExtern operator==(const ScalarArray&, const ScalarArray&); +bool epicsShareExtern operator==(const Structure&, const Structure&); +bool epicsShareExtern operator==(const StructureArray&, const StructureArray&); +bool epicsShareExtern operator==(const Union&, const Union&); +bool epicsShareExtern operator==(const UnionArray&, const UnionArray&); +bool epicsShareExtern operator==(const BoundedString&, const BoundedString&); + +static inline bool operator!=(const Field& a, const Field& b) +{return !(a==b);} +static inline bool operator!=(const Scalar& a, const Scalar& b) +{return !(a==b);} +static inline bool operator!=(const ScalarArray& a, const ScalarArray& b) +{return !(a==b);} +static inline bool operator!=(const Structure& a, const Structure& b) +{return !(a==b);} +static inline bool operator!=(const StructureArray& a, const StructureArray& b) +{return !(a==b);} +static inline bool operator!=(const Union& a, const Union& b) +{return !(a==b);} +static inline bool operator!=(const UnionArray& a, const UnionArray& b) +{return !(a==b);} +static inline bool operator!=(const BoundedString& a, const BoundedString& b) +{return !(a==b);} + }} /** diff --git a/testApp/property/testProperty.cpp b/testApp/property/testProperty.cpp index 53a3e96..3ff363f 100644 --- a/testApp/property/testProperty.cpp +++ b/testApp/property/testProperty.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -41,7 +40,6 @@ static FieldCreatePtr fieldCreate; static PVDataCreatePtr pvDataCreate; static StandardFieldPtr standardField; static StandardPVFieldPtr standardPVField; -static ConvertPtr convert; static string alarmTimeStamp("alarm,timeStamp"); static string allProperties("alarm,timeStamp,display,control"); @@ -236,7 +234,6 @@ MAIN(testProperty) pvDataCreate = getPVDataCreate(); standardField = getStandardField(); standardPVField = getStandardPVField(); - convert = getConvert(); createRecords(); testAlarm(); testTimeStamp(); diff --git a/testApp/pv/testBitSetUtil.cpp b/testApp/pv/testBitSetUtil.cpp index d709aae..c54975c 100644 --- a/testApp/pv/testBitSetUtil.cpp +++ b/testApp/pv/testBitSetUtil.cpp @@ -18,7 +18,6 @@ #include #include -#include #include #include @@ -32,7 +31,6 @@ static FieldCreatePtr fieldCreate; static PVDataCreatePtr pvDataCreate; static StandardFieldPtr standardField; static StandardPVFieldPtr standardPVField; -static ConvertPtr convert; static void test() { @@ -175,7 +173,6 @@ MAIN(testBitSetUtil) pvDataCreate = getPVDataCreate(); standardField = getStandardField(); standardPVField = getStandardPVField(); - convert = getConvert(); test(); return testDone(); } diff --git a/testApp/pv/testPVData.cpp b/testApp/pv/testPVData.cpp index 3e1c804..ed1f024 100644 --- a/testApp/pv/testPVData.cpp +++ b/testApp/pv/testPVData.cpp @@ -21,6 +21,8 @@ #include #include #include +#include +#include using namespace epics::pvData; using std::tr1::static_pointer_cast; @@ -415,9 +417,117 @@ cout << "fieldName " << fieldName << " fullName " << fullName << endl; } +#define STRINGIZE(A) #A +#define TEST_COPY(T, V) testCopyCase(V, STRINGIZE(T)) + +template +void testCopyCase(typename T::value_type val, const char* typeName) +{ + typename T::shared_pointer pv = pvDataCreate->createPVScalar(); + pv->put(val); + + typename T::shared_pointer pv2 = pvDataCreate->createPVScalar(); + pv2->copy(*pv); + + testOk(*pv == *pv2, "testCopyCase (copy) for type '%s'", typeName); + + typename T::shared_pointer pv3 = pvDataCreate->createPVScalar(); + pv3->copy(*pv); + + testOk(*pv == *pv3, "testCopyCase (copyUnchecked) for type '%s'", typeName); +} + +static void testCopy() +{ + if(debug) + std::cout << std::endl << "testCopy" << std::endl; + + 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("value")->put(testValue); + + PVTimeStamp timeStamp; + timeStamp.attach(pvStructure->getSubField("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("value")->getFieldOffset()); + pvStructureCopy3->copyUnchecked(*pvStructure, mask); + pvStructureCopy4->getSubField("value")->put(testValue); + testOk(*pvStructureCopy3 == *pvStructureCopy4, "PVStructure copyUnchecked w/ value mask only"); + + mask.set(pvStructure->getSubField("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("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("timeStamp")->copy( + *pvStructure->getSubField("timeStamp") + ); + pvUnion2->copy(*pvUnion); + testOk(*pvUnion == *pvUnion2, "PVUnion PVStructure copy, to different type PVUnion"); +} + MAIN(testPVData) { - testPlan(189); + testPlan(222); fieldCreate = getFieldCreate(); pvDataCreate = getPVDataCreate(); standardField = getStandardField(); @@ -427,6 +537,7 @@ MAIN(testPVData) testPVScalar(); testScalarArray(); testRequest(); + testCopy(); return testDone(); } diff --git a/testApp/pv/testPVUnion.cpp b/testApp/pv/testPVUnion.cpp index cb64321..faf5d04 100644 --- a/testApp/pv/testPVUnion.cpp +++ b/testApp/pv/testPVUnion.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -35,7 +34,6 @@ static FieldCreatePtr fieldCreate = getFieldCreate(); static PVDataCreatePtr pvDataCreate = getPVDataCreate(); static StandardFieldPtr standardField = getStandardField(); static StandardPVFieldPtr standardPVField = getStandardPVField(); -static ConvertPtr convert = getConvert(); static void testPVUnionType() {