This is Unofficial EPICS BASE Doxygen Site
Compare.cpp
Go to the documentation of this file.
1 /*
2  * Copyright information and license terms for this software can be
3  * found in the file LICENSE that is included with the distribution
4  */
9 #include <algorithm>
10 #include <iterator>
11 #include <sstream>
12 
13 #define epicsExportSharedSymbols
14 #include <pv/pvData.h>
15 
16 using std::string;
17 
18 namespace epics { namespace pvData {
19 
20 // Introspection object comparison
21 
26 bool compare(const Field& a, const Field& b)
27 {
28  if(&a==&b)
29  return true;
30  if(a.getType()!=b.getType())
31  return false;
32  switch(a.getType()) {
33  case scalar: {
34  const Scalar &A=static_cast<const Scalar&>(a);
35  const Scalar &B=static_cast<const Scalar&>(b);
36  return compare(A, B);
37  }
38  case scalarArray: {
39  const ScalarArray &A=static_cast<const ScalarArray&>(a);
40  const ScalarArray &B=static_cast<const ScalarArray&>(b);
41  return compare(A, B);
42  }
43  case structure: {
44  const Structure &A=static_cast<const Structure&>(a);
45  const Structure &B=static_cast<const Structure&>(b);
46  return compare(A, B);
47  }
48  case structureArray: {
49  const StructureArray &A=static_cast<const StructureArray&>(a);
50  const StructureArray &B=static_cast<const StructureArray&>(b);
51  return compare(A, B);
52  }
53  case union_: {
54  const Union &A=static_cast<const Union&>(a);
55  const Union &B=static_cast<const Union&>(b);
56  return compare(A, B);
57  }
58  case unionArray: {
59  const UnionArray &A=static_cast<const UnionArray&>(a);
60  const UnionArray &B=static_cast<const UnionArray&>(b);
61  return compare(A, B);
62  }
63  default:
64  throw std::logic_error("Invalid Field type in comparison");
65  }
66 }
67 
68 bool compare(const Scalar& a, const Scalar& b)
69 {
70  if(&a==&b)
71  return true;
72  return a.getScalarType()==b.getScalarType();
73 }
74 
75 bool compare(const ScalarArray& a, const ScalarArray& b)
76 {
77  if(&a==&b)
78  return true;
79  return a.getElementType()==b.getElementType();
80 }
81 
82 bool compare(const Structure& a, const Structure& b)
83 {
84  if(&a==&b)
85  return true;
86  if (a.getID()!=b.getID())
87  return false;
88  size_t nflds=a.getNumberFields();
89  if (b.getNumberFields()!=nflds)
90  return false;
91 
92  // std::equals does not work, since FieldConstPtrArray is an array of shared_pointers
93  FieldConstPtrArray const & af = a.getFields();
94  FieldConstPtrArray const & bf = b.getFields();
95  for (size_t i = 0; i < nflds; i++)
96  if (*(af[i].get()) != *(bf[i].get()))
97  return false;
98 
99  StringArray const & an = a.getFieldNames();
100  StringArray const & bn = b.getFieldNames();
101  return std::equal( an.begin(), an.end(), bn.begin() );
102 }
103 
104 bool compare(const StructureArray& a, const StructureArray& b)
105 {
106  return *(a.getStructure().get())==*(b.getStructure().get());
107 }
108 
109 bool compare(const Union& a, const Union& b)
110 {
111  if(&a==&b)
112  return true;
113  if (a.getID()!=b.getID())
114  return false;
115  size_t nflds=a.getNumberFields();
116  if (b.getNumberFields()!=nflds)
117  return false;
118 
119  // std::equals does not work, since FieldConstPtrArray is an array of shared_pointers
120  FieldConstPtrArray const & af = a.getFields();
121  FieldConstPtrArray const & bf = b.getFields();
122  for (size_t i = 0; i < nflds; i++)
123  if (*(af[i].get()) != *(bf[i].get()))
124  return false;
125 
126  StringArray const & an = a.getFieldNames();
127  StringArray const & bn = b.getFieldNames();
128  return std::equal( an.begin(), an.end(), bn.begin() );
129 }
130 
131 bool compare(const UnionArray& a, const UnionArray& b)
132 {
133  return *(a.getUnion().get())==*(b.getUnion().get());
134 }
135 
136 bool compare(const BoundedString& a, const BoundedString& b)
137 {
138  if(&a==&b)
139  return true;
140  return a.getMaximumLength()==b.getMaximumLength();
141 }
142 
143 // PVXXX object comparison
144 
145 namespace {
146 
147 // fully typed comparisons
148 
149 template<typename T>
150 bool compareScalar(const PVScalarValue<T>* left, const PVScalarValue<T>* right)
151 {
152  return left->get()==right->get();
153 }
154 
155 template<typename T>
156 bool compareArray(const PVValueArray<T>* left, const PVValueArray<T>* right)
157 {
158  typename PVValueArray<T>::const_svector lhs(left->view()), rhs(right->view());
159  return std::equal(lhs.begin(), lhs.end(), rhs.begin());
160 }
161 
162 // partially typed comparisons
163 
164 bool compareField(const PVScalar* left, const PVScalar* right)
165 {
166  ScalarType lht = left->getScalar()->getScalarType();
167  if(lht != right->getScalar()->getScalarType())
168  return false;
169  switch(lht) {
170 #define OP(ENUM, TYPE) case ENUM: return compareScalar(static_cast<const PVScalarValue<TYPE>*>(left), static_cast<const PVScalarValue<TYPE>*>(right))
171  OP(pvBoolean, uint8);
172  OP(pvUByte, uint8);
173  OP(pvByte, int8);
174  OP(pvUShort, uint16);
175  OP(pvShort, int16);
176  OP(pvUInt, uint32);
177  OP(pvInt, int32);
178  OP(pvULong, uint64);
179  OP(pvLong, int64);
180  OP(pvFloat, float);
181  OP(pvDouble, double);
182 #undef OP
183  case pvString: {
184  const PVString *a=static_cast<const PVString*>(left), *b=static_cast<const PVString*>(right);
185  return a->get()==b->get();
186  }
187  }
188  throw std::logic_error("PVScalar with invalid scalar type!");
189 }
190 
191 bool compareField(const PVScalarArray* left, const PVScalarArray* right)
192 {
193  ScalarType lht = left->getScalarArray()->getElementType();
194  if(lht != right->getScalarArray()->getElementType())
195  return false;
196 
197  if(left->getLength()!=right->getLength())
198  return false;
199 
200  switch(lht) {
201 #define OP(ENUM, TYPE) case ENUM: return compareArray(static_cast<const PVValueArray<TYPE>*>(left), static_cast<const PVValueArray<TYPE>*>(right))
202  OP(pvBoolean, uint8);
203  OP(pvUByte, uint8);
204  OP(pvByte, int8);
205  OP(pvUShort, uint16);
206  OP(pvShort, int16);
207  OP(pvUInt, uint32);
208  OP(pvInt, int32);
209  OP(pvULong, uint64);
210  OP(pvLong, int64);
211  OP(pvFloat, float);
212  OP(pvDouble, double);
213  OP(pvString, string);
214 #undef OP
215  }
216  throw std::logic_error("PVScalarArray with invalid element type!");
217 }
218 
219 bool compareField(const PVStructure* left, const PVStructure* right)
220 {
221  StructureConstPtr ls = left->getStructure();
222 
223  if(*ls!=*right->getStructure())
224  return false;
225 
226  const PVFieldPtrArray& lf = left->getPVFields();
227  const PVFieldPtrArray& rf = right->getPVFields();
228 
229  for(size_t i=0, nfld=ls->getNumberFields(); i<nfld; i++) {
230  if(*lf[i]!=*rf[i])
231  return false;
232  }
233  return true;
234 }
235 
236 bool compareField(const PVStructureArray* left, const PVStructureArray* right)
237 {
238  if(*left->getStructureArray()->getStructure()
239  != *right->getStructureArray()->getStructure())
240  return false;
241 
242  PVStructureArray::const_svector ld=left->view(), rd=right->view();
243 
244  if(ld.size()!=rd.size())
245  return false;
246 
248 
249  for(lit=ld.begin(), lend=ld.end(), rit=rd.begin();
250  lit!=lend;
251  ++lit, ++rit)
252  {
253  // element can be null
254  if (!(*lit) || !(*rit))
255  {
256  if (*lit || *rit)
257  return false;
258  }
259  else if (**lit != **rit)
260  return false;
261  }
262  return true;
263 }
264 
265 bool compareField(const PVUnion* left, const PVUnion* right)
266 {
267  UnionConstPtr ls = left->getUnion();
268 
269  if(*ls!=*right->getUnion())
270  return false;
271 
272  if (ls->isVariant())
273  {
274  const PVField::const_shared_pointer& lval = left->get();
275  if (lval.get() == 0)
276  return right->get().get() == 0;
277  else
278  return *(lval.get()) == *(right->get().get());
279  }
280  else
281  {
282  int32 lix = left->getSelectedIndex();
283  if (lix == right->getSelectedIndex())
284  {
285  if (lix == PVUnion::UNDEFINED_INDEX || *(left->get()) == *(right->get().get()))
286  return true;
287  else
288  return false;
289  }
290  else
291  return false;
292  }
293 }
294 
295 bool compareField(const PVUnionArray* left, const PVUnionArray* right)
296 {
297  if(*left->getUnionArray()->getUnion()
298  != *right->getUnionArray()->getUnion())
299  return false;
300 
301  PVUnionArray::const_svector ld=left->view(), rd=right->view();
302 
303  if(ld.size()!=rd.size())
304  return false;
305 
307 
308  for(lit=ld.begin(), lend=ld.end(), rit=rd.begin();
309  lit!=lend;
310  ++lit, ++rit)
311  {
312  // element can be null
313  if (!(*lit) || !(*rit))
314  {
315  if (*lit || *rit)
316  return false;
317  }
318  else if (**lit != **rit)
319  return false;
320  }
321  return true;
322 }
323 
324 } // end namespace
325 
326 // untyped comparison
327 
328 bool operator==(const PVField& left, const PVField& right)
329 {
330  if(&left == &right)
331  return true;
332 
333  Type lht = left.getField()->getType();
334  if(lht != right.getField()->getType())
335  return false;
336 
337  switch(lht) {
338  case scalar: return compareField(static_cast<const PVScalar*>(&left), static_cast<const PVScalar*>(&right));
339  case scalarArray: return compareField(static_cast<const PVScalarArray*>(&left), static_cast<const PVScalarArray*>(&right));
340  case structure: return compareField(static_cast<const PVStructure*>(&left), static_cast<const PVStructure*>(&right));
341  case structureArray: return compareField(static_cast<const PVStructureArray*>(&left), static_cast<const PVStructureArray*>(&right));
342  case union_: return compareField(static_cast<const PVUnion*>(&left), static_cast<const PVUnion*>(&right));
343  case unionArray: return compareField(static_cast<const PVUnionArray*>(&left), static_cast<const PVUnionArray*>(&right));
344  }
345  throw std::logic_error("PVField with invalid type!");
346 }
347 
348 }} // namespace epics::pvData
int8_t int8
Definition: pvType.h:75
const PVFieldPtrArray & getPVFields() const
Definition: pvData.h:736
This class implements introspection object for Scalar.
Definition: pvIntrospect.h:397
const PVFieldPtr & get()
Definition: pvData.h:968
virtual const_svector view() const OVERRIDE FINAL
Fetch a read-only view of the current array data.
Definition: pvData.h:1209
PVScalar is the base class for each scalar field.
Definition: pvData.h:272
This class implements introspection object for a union.
Definition: pvIntrospect.h:866
Data class for a unionArray.
Definition: pvData.h:1335
std::size_t getNumberFields() const
Definition: pvIntrospect.h:720
int32 getSelectedIndex() const
Definition: pvData.h:1014
uint16_t uint16
Definition: pvType.h:95
int i
Definition: scan.c:967
StructureArrayConstPtr getStructureArray() const
Definition: pvData.h:1278
const UnionConstPtr & getUnion() const
Definition: pvData.h:962
const FieldConstPtr & getField() const
Definition: pvData.h:208
const StructureConstPtr & getStructure() const
Definition: pvIntrospect.h:617
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
std::size_t getNumberFields() const
Definition: pvIntrospect.h:900
std::tr1::shared_ptr< const Structure > StructureConstPtr
Definition: pvIntrospect.h:162
FieldConstPtrArray const & getFields() const
Definition: pvIntrospect.h:823
ScalarType getElementType() const
Definition: pvIntrospect.h:512
PVField is the base class for each PVData field.
Definition: pvData.h:152
virtual std::string getID() const OVERRIDE FINAL
storage_t::arg_type get() const
Definition: pvData.h:396
This class implements introspection object for field.
Definition: pvIntrospect.h:336
const ScalarConstPtr getScalar() const
Definition: PVScalar.cpp:27
uint64_t uint64
Definition: pvType.h:103
PVString is special case, since it implements SerializableArray.
Definition: pvData.h:521
virtual std::string getID() const OVERRIDE FINAL
Type getType() const
Definition: pvIntrospect.h:348
std::tr1::shared_ptr< const Union > UnionConstPtr
Definition: pvIntrospect.h:170
virtual std::size_t getLength() const =0
This class implements introspection object for a structure.
Definition: pvIntrospect.h:697
template class for all extensions of PVArray.
Definition: pvData.h:55
bool compare(const Field &a, const Field &b)
Definition: Compare.cpp:26
Base class for a scalarArray.
Definition: pvData.h:618
StringArray const & getFieldNames() const
meta::decorate_const< const PVStructurePtr >::type * const_iterator
Definition: sharedVector.h:300
PVUnion has a single subfield.
Definition: pvData.h:940
std::vector< FieldConstPtr > FieldConstPtrArray
Definition: pvIntrospect.h:146
const ScalarArrayConstPtr getScalarArray() const
This class implements introspection object for BoundedString.
Definition: pvIntrospect.h:437
This class implements introspection object for a unionArray.
Definition: pvIntrospect.h:652
std::vector< PVFieldPtr > PVFieldPtrArray
Definition: pvData.h:70
Data interface for a structure,.
Definition: pvData.h:712
size_t size() const
Number of elements visible through this vector.
Definition: sharedVector.h:220
This class implements introspection object for scalar array.
Definition: pvIntrospect.h:497
This class implements introspection object for a structureArray.
Definition: pvIntrospect.h:607
int64_t int64
Definition: pvType.h:87
Data class for a structureArray.
Definition: pvData.h:1236
bool operator==(const PVField &left, const PVField &right)
Definition: Compare.cpp:328
UnionConstPtr getUnion() const
Definition: pvIntrospect.h:662
Class that holds the data for each possible scalar type.
Definition: pvData.h:54
std::vector< std::string > StringArray
Definition: pvType.h:110
virtual const_svector view() const OVERRIDE FINAL
Fetch a read-only view of the current array data.
Definition: pvData.h:1297
std::size_t getMaximumLength() const
const StructureConstPtr & getStructure() const
Definition: pvData.h:731
int16_t int16
Definition: pvType.h:79
FieldConstPtrArray const & getFields() const
#define OP(ENUM, TYPE)
virtual const_svector view() const OVERRIDE
Fetch a read-only view of the current array data.
Definition: pvData.h:1396
ScalarType getScalarType() const
Definition: pvIntrospect.h:407
UnionArrayConstPtr getUnionArray() const
Definition: pvData.h:1377
int32_t int32
Definition: pvType.h:83
static const int32 UNDEFINED_INDEX
Definition: pvData.h:956
uint8_t uint8
Definition: pvType.h:91
StringArray const & getFieldNames() const
Definition: pvIntrospect.h:828
uint32_t uint32
Definition: pvType.h:99