flow: Merged <feature> 'copy_refactoring' to <develop> ('default').
This commit is contained in:
@@ -18,7 +18,6 @@
|
||||
#include <pv/thread.h>
|
||||
|
||||
#include <pv/pvCopy.h>
|
||||
#include <pv/convert.h>
|
||||
|
||||
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<CopyMasterNode>(node);
|
||||
@@ -320,7 +330,7 @@ void PVCopy::dump(string *builder,CopyNodePtr const &node,int indentLevel)
|
||||
CopyNodePtrArrayPtr nodes = structureNode->nodes;
|
||||
for(size_t i=0; i<nodes->size(); ++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<PVStructure>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <sstream>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/convert.h>
|
||||
#include <pv/pvData.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
|
||||
@@ -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<const Scalar>(from);
|
||||
ScalarConstPtr yyy = static_pointer_cast<const Scalar>(to);
|
||||
return isCopyScalarCompatible(xxx,yyy);
|
||||
}
|
||||
case scalarArray:
|
||||
{
|
||||
ScalarArrayConstPtr xxx = static_pointer_cast<const ScalarArray>(from);
|
||||
ScalarArrayConstPtr yyy = static_pointer_cast<const ScalarArray>(to);
|
||||
return isCopyScalarArrayCompatible(xxx,yyy);
|
||||
}
|
||||
case structure:
|
||||
{
|
||||
StructureConstPtr xxx = static_pointer_cast<const Structure>(from);
|
||||
StructureConstPtr yyy = static_pointer_cast<const Structure>(to);
|
||||
return isCopyStructureCompatible(xxx,yyy);
|
||||
}
|
||||
case structureArray:
|
||||
{
|
||||
StructureArrayConstPtr xxx = static_pointer_cast<const StructureArray>(from);
|
||||
StructureArrayConstPtr yyy = static_pointer_cast<const StructureArray>(to);
|
||||
return isCopyStructureArrayCompatible(xxx,yyy);
|
||||
}
|
||||
case union_:
|
||||
{
|
||||
UnionConstPtr xxx = static_pointer_cast<const Union>(from);
|
||||
UnionConstPtr yyy = static_pointer_cast<const Union>(to);
|
||||
return isCopyUnionCompatible(xxx,yyy);
|
||||
}
|
||||
case unionArray:
|
||||
{
|
||||
UnionArrayConstPtr xxx = static_pointer_cast<const UnionArray>(from);
|
||||
UnionArrayConstPtr yyy = static_pointer_cast<const UnionArray>(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<PVScalar>(from);
|
||||
PVScalarPtr yyy = static_pointer_cast<PVScalar>(to);
|
||||
copyScalar(xxx,yyy);
|
||||
return;
|
||||
}
|
||||
case scalarArray:
|
||||
{
|
||||
PVScalarArrayPtr fromArray = static_pointer_cast<PVScalarArray>(from);
|
||||
PVScalarArrayPtr toArray = static_pointer_cast<PVScalarArray>(to);
|
||||
toArray->assign(*fromArray.get());
|
||||
return;
|
||||
}
|
||||
case structure:
|
||||
{
|
||||
PVStructurePtr xxx = static_pointer_cast<PVStructure>(from);
|
||||
PVStructurePtr yyy = static_pointer_cast<PVStructure>(to);
|
||||
copyStructure(xxx,yyy);
|
||||
return;
|
||||
}
|
||||
case structureArray: {
|
||||
PVStructureArrayPtr fromArray = static_pointer_cast<PVStructureArray>(from);
|
||||
PVStructureArrayPtr toArray = static_pointer_cast<PVStructureArray>(to);
|
||||
copyStructureArray(fromArray,toArray);
|
||||
return;
|
||||
}
|
||||
case union_:
|
||||
{
|
||||
PVUnionPtr xxx = static_pointer_cast<PVUnion>(from);
|
||||
PVUnionPtr yyy = static_pointer_cast<PVUnion>(to);
|
||||
copyUnion(xxx,yyy);
|
||||
return;
|
||||
}
|
||||
case unionArray: {
|
||||
PVUnionArrayPtr fromArray = static_pointer_cast<PVUnionArray>(from);
|
||||
PVUnionArrayPtr toArray = static_pointer_cast<PVUnionArray>(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; i<length; i++) {
|
||||
FieldConstPtr from = fromFields[i];
|
||||
FieldConstPtr to = toFields[i];
|
||||
Type fromType = from->getType();
|
||||
Type toType = to->getType();
|
||||
if(fromType!=toType) return false;
|
||||
switch(fromType) {
|
||||
case scalar:
|
||||
{
|
||||
ScalarConstPtr xxx = static_pointer_cast<const Scalar>(from);
|
||||
ScalarConstPtr yyy = static_pointer_cast<const Scalar>(to);
|
||||
if(!isCopyScalarCompatible(xxx,yyy)) return false;
|
||||
}
|
||||
break;
|
||||
case scalarArray:
|
||||
{
|
||||
ScalarArrayConstPtr xxx = static_pointer_cast<const ScalarArray>(from);
|
||||
ScalarArrayConstPtr yyy = static_pointer_cast<const ScalarArray>(to);
|
||||
if(!isCopyScalarArrayCompatible(xxx,yyy)) return false;
|
||||
}
|
||||
break;
|
||||
case structure:
|
||||
{
|
||||
StructureConstPtr xxx = static_pointer_cast<const Structure>(from);
|
||||
StructureConstPtr yyy = static_pointer_cast<const Structure>(to);
|
||||
if(!isCopyStructureCompatible(xxx,yyy)) return false;
|
||||
}
|
||||
break;
|
||||
case structureArray:
|
||||
{
|
||||
StructureArrayConstPtr xxx = static_pointer_cast<const StructureArray>(from);
|
||||
StructureArrayConstPtr yyy = static_pointer_cast<const StructureArray>(to);
|
||||
if(!isCopyStructureArrayCompatible(xxx,yyy)) return false;
|
||||
}
|
||||
case union_:
|
||||
{
|
||||
UnionConstPtr xxx = static_pointer_cast<const Union>(from);
|
||||
UnionConstPtr yyy = static_pointer_cast<const Union>(to);
|
||||
if(!isCopyUnionCompatible(xxx,yyy)) return false;
|
||||
}
|
||||
break;
|
||||
case unionArray:
|
||||
{
|
||||
UnionArrayConstPtr xxx = static_pointer_cast<const UnionArray>(from);
|
||||
UnionArrayConstPtr yyy = static_pointer_cast<const UnionArray>(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<PVScalar>(fromDatas[0]);
|
||||
PVScalarArrayPtr pvArray =
|
||||
static_pointer_cast<PVScalarArray>(fromDatas[1]);
|
||||
if((pvScalar->getScalar()->getScalarType()==pvInt)
|
||||
&& (pvArray->getScalarArray()->getElementType()==pvString)) {
|
||||
PVScalarArrayPtr toArray =
|
||||
static_pointer_cast<PVScalarArray>(toDatas[1]);
|
||||
toArray->assign(*pvArray.get());
|
||||
PVScalarPtr toScalar = static_pointer_cast<PVScalar>(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<PVScalar>(fromData);
|
||||
PVScalarPtr yyy = static_pointer_cast<PVScalar>(toData);
|
||||
copyScalar(xxx,yyy);
|
||||
break;
|
||||
}
|
||||
case scalarArray:
|
||||
{
|
||||
PVScalarArrayPtr fromArray = static_pointer_cast<PVScalarArray>(fromData);
|
||||
PVScalarArrayPtr toArray = static_pointer_cast<PVScalarArray>(toData);
|
||||
toArray->assign(*fromArray.get());
|
||||
break;
|
||||
}
|
||||
case structure:
|
||||
{
|
||||
PVStructurePtr xxx = static_pointer_cast<PVStructure>(fromData);
|
||||
PVStructurePtr yyy = static_pointer_cast<PVStructure>(toData);
|
||||
copyStructure(xxx,yyy);
|
||||
break;
|
||||
}
|
||||
case structureArray:
|
||||
{
|
||||
PVStructureArrayPtr fromArray =
|
||||
static_pointer_cast<PVStructureArray>(fromData);
|
||||
PVStructureArrayPtr toArray =
|
||||
static_pointer_cast<PVStructureArray>(toData);
|
||||
copyStructureArray(fromArray,toArray);
|
||||
break;
|
||||
}
|
||||
case union_:
|
||||
{
|
||||
PVUnionPtr xxx = static_pointer_cast<PVUnion>(fromData);
|
||||
PVUnionPtr yyy = static_pointer_cast<PVUnion>(toData);
|
||||
copyUnion(xxx,yyy);
|
||||
break;
|
||||
}
|
||||
case unionArray:
|
||||
{
|
||||
PVUnionArrayPtr fromArray =
|
||||
static_pointer_cast<PVUnionArray>(fromData);
|
||||
PVUnionArrayPtr toArray =
|
||||
static_pointer_cast<PVUnionArray>(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;
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
@@ -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<PVUnionArray>(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;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/convert.h>
|
||||
|
||||
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<const PVScalar*>(&from);
|
||||
PVScalar* toS = static_cast<PVScalar*>(this);
|
||||
toS->copy(*fromS);
|
||||
break;
|
||||
}
|
||||
case scalarArray:
|
||||
{
|
||||
const PVScalarArray* fromS = static_cast<const PVScalarArray*>(&from);
|
||||
PVScalarArray* toS = static_cast<PVScalarArray*>(this);
|
||||
toS->copy(*fromS);
|
||||
break;
|
||||
}
|
||||
case structure:
|
||||
{
|
||||
const PVStructure* fromS = static_cast<const PVStructure*>(&from);
|
||||
PVStructure* toS = static_cast<PVStructure*>(this);
|
||||
toS->copy(*fromS);
|
||||
break;
|
||||
}
|
||||
case structureArray:
|
||||
{
|
||||
const PVStructureArray* fromS = static_cast<const PVStructureArray*>(&from);
|
||||
PVStructureArray* toS = static_cast<PVStructureArray*>(this);
|
||||
toS->copy(*fromS);
|
||||
break;
|
||||
}
|
||||
case union_:
|
||||
{
|
||||
const PVUnion* fromS = static_cast<const PVUnion*>(&from);
|
||||
PVUnion* toS = static_cast<PVUnion*>(this);
|
||||
toS->copy(*fromS);
|
||||
break;
|
||||
}
|
||||
case unionArray:
|
||||
{
|
||||
const PVUnionArray* fromS = static_cast<const PVUnionArray*>(&from);
|
||||
PVUnionArray* toS = static_cast<PVUnionArray*>(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<const PVScalar*>(&from);
|
||||
PVScalar* toS = static_cast<PVScalar*>(this);
|
||||
toS->copyUnchecked(*fromS);
|
||||
break;
|
||||
}
|
||||
case scalarArray:
|
||||
{
|
||||
const PVScalarArray* fromS = static_cast<const PVScalarArray*>(&from);
|
||||
PVScalarArray* toS = static_cast<PVScalarArray*>(this);
|
||||
toS->copyUnchecked(*fromS);
|
||||
break;
|
||||
}
|
||||
case structure:
|
||||
{
|
||||
const PVStructure* fromS = static_cast<const PVStructure*>(&from);
|
||||
PVStructure* toS = static_cast<PVStructure*>(this);
|
||||
toS->copyUnchecked(*fromS);
|
||||
break;
|
||||
}
|
||||
case structureArray:
|
||||
{
|
||||
const PVStructureArray* fromS = static_cast<const PVStructureArray*>(&from);
|
||||
PVStructureArray* toS = static_cast<PVStructureArray*>(this);
|
||||
toS->copyUnchecked(*fromS);
|
||||
break;
|
||||
}
|
||||
case union_:
|
||||
{
|
||||
const PVUnion* fromS = static_cast<const PVUnion*>(&from);
|
||||
PVUnion* toS = static_cast<PVUnion*>(this);
|
||||
toS->copyUnchecked(*fromS);
|
||||
break;
|
||||
}
|
||||
case unionArray:
|
||||
{
|
||||
const PVUnionArray* fromS = static_cast<const PVUnionArray*>(&from);
|
||||
PVUnionArray* toS = static_cast<PVUnionArray*>(this);
|
||||
toS->copyUnchecked(*fromS);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw std::logic_error("PVField::copy unknown type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/bitSet.h>
|
||||
|
||||
@@ -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; i<fieldsSize; i++) {
|
||||
toPVFields[i]->copyUnchecked(*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<uint32>(offset)) :
|
||||
maskBitSet.nextSetBit(static_cast<uint32>(offset));
|
||||
|
||||
// no more changes or no changes in this structure
|
||||
if(next<0||next>=static_cast<int32>(offset+numberFields)) return;
|
||||
|
||||
// entire structure
|
||||
if(static_cast<int32>(offset)==next) {
|
||||
copyUnchecked(from);
|
||||
return;
|
||||
}
|
||||
|
||||
PVFieldPtrArray const & fromPVFields = from.getPVFields();
|
||||
PVFieldPtrArray const & toPVFields = getPVFields();
|
||||
|
||||
size_t fieldsSize = fromPVFields.size();
|
||||
for(size_t i = 0; i<fieldsSize; i++) {
|
||||
PVFieldPtr pvField = fromPVFields[i];
|
||||
offset = pvField->getFieldOffset();
|
||||
int32 inumberFields = static_cast<int32>(pvField->getNumberFields());
|
||||
next = inverse ?
|
||||
maskBitSet.nextClearBit(static_cast<uint32>(offset)) :
|
||||
maskBitSet.nextSetBit(static_cast<uint32>(offset));
|
||||
|
||||
// no more changes
|
||||
if(next<0) return;
|
||||
// no change in this pvField
|
||||
if(next>=static_cast<int32>(offset+inumberFields)) continue;
|
||||
|
||||
// serialize field or fields
|
||||
if(inumberFields==1) {
|
||||
toPVFields[i]->copyUnchecked(*pvField);
|
||||
} else {
|
||||
PVStructure::shared_pointer fromPVStructure = std::tr1::static_pointer_cast<PVStructure>(pvField);
|
||||
PVStructure::shared_pointer toPVStructure = std::tr1::static_pointer_cast<PVStructure>(toPVFields[i]);
|
||||
toPVStructure->copyUnchecked(*fromPVStructure, maskBitSet, inverse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/convert.h>
|
||||
#include <pv/timer.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
201
src/pv/convert.h
201
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<Convert> ConvertPtr;
|
||||
|
||||
@@ -83,38 +49,18 @@ typedef std::tr1::shared_ptr<Convert> 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.
|
||||
* <ul>
|
||||
* <li>Both arguments are numeric.</li>
|
||||
* <li>Both arguments have the same type.</li>
|
||||
* <li>Either argument is a string.</li>
|
||||
* </ul>
|
||||
* @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:
|
||||
* <ul>
|
||||
* <li>For scalar nodes this means that isCopyScalarCompatible is true.</li>
|
||||
* <li>For array nodes this means that isCopyArrayCompatible is true.</li>
|
||||
* <li>For structure nodes this means that isCopyStructureCompatible is true.</li>
|
||||
* <li>Link nodes are not copied.</li>
|
||||
* </ul>
|
||||
* @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 <byte>.
|
||||
* @param pv a PV
|
||||
@@ -464,13 +288,6 @@ public:
|
||||
*/
|
||||
inline void fromDouble(PVScalarPtr const & pv, double from) { pv->putFrom<double>(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(); }
|
||||
|
||||
@@ -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<T,T1>(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<const void> 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);}
|
||||
|
||||
}}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);}
|
||||
|
||||
}}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include <pv/requester.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/alarm.h>
|
||||
@@ -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();
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include <pv/requester.h>
|
||||
#include <pv/bitSetUtil.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
#include <pv/bitSet.h>
|
||||
|
||||
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<T>(V, STRINGIZE(T))
|
||||
|
||||
template<typename T>
|
||||
void testCopyCase(typename T::value_type val, const char* typeName)
|
||||
{
|
||||
typename T::shared_pointer pv = pvDataCreate->createPVScalar<T>();
|
||||
pv->put(val);
|
||||
|
||||
typename T::shared_pointer pv2 = pvDataCreate->createPVScalar<T>();
|
||||
pv2->copy(*pv);
|
||||
|
||||
testOk(*pv == *pv2, "testCopyCase (copy) for type '%s'", typeName);
|
||||
|
||||
typename T::shared_pointer pv3 = pvDataCreate->createPVScalar<T>();
|
||||
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<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");
|
||||
}
|
||||
|
||||
MAIN(testPVData)
|
||||
{
|
||||
testPlan(189);
|
||||
testPlan(222);
|
||||
fieldCreate = getFieldCreate();
|
||||
pvDataCreate = getPVDataCreate();
|
||||
standardField = getStandardField();
|
||||
@@ -427,6 +537,7 @@ MAIN(testPVData)
|
||||
testPVScalar();
|
||||
testScalarArray();
|
||||
testRequest();
|
||||
testCopy();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/timeStamp.h>
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user