This is Unofficial EPICS BASE Doxygen Site
PVField.cpp
Go to the documentation of this file.
1 /*PVField.cpp*/
2 /*
3  * Copyright information and license terms for this software can be
4  * found in the file LICENSE that is included with the distribution
5  */
9 #include <cstddef>
10 #include <cstdlib>
11 #include <string>
12 #include <cstdio>
13 
14 #include <epicsMutex.h>
15 
16 #define epicsExportSharedSymbols
17 #include <pv/lock.h>
18 #include <pv/pvData.h>
19 #include <pv/factory.h>
20 #include <pv/reftrack.h>
21 
23 using std::size_t;
24 using std::string;
25 
26 namespace epics { namespace pvData {
27 
29 
31 : parent(NULL),field(field),
32  fieldOffset(0), nextFieldOffset(0),
33  immutable(false)
34 {
35  REFTRACE_INCREMENT(num_instances);
36 }
37 
39 {
40  REFTRACE_DECREMENT(num_instances);
41 }
42 
43 
45 {
46  if(nextFieldOffset==0) computeOffset(this);
47  return fieldOffset;
48 }
49 
51 {
52  if(nextFieldOffset==0) computeOffset(this);
53  return nextFieldOffset;
54 }
55 
57 {
58  if(nextFieldOffset==0) computeOffset(this);
59  return (nextFieldOffset - fieldOffset);
60 }
61 
62 
63 void PVField::setImmutable() {immutable = true;}
64 
66 {
67  if(postHandler) postHandler->postPut();
68 }
69 
71 {
72  if(postHandler) {
73  if(postHandler.get()==handler.get()) return;
74  throw std::logic_error(
75  "PVField::setPostHandler a postHandler is already registered");
76 
77  }
78  postHandler = handler;
79 }
80 
81 void PVField::setParentAndName(PVStructure * xxx,string const & name)
82 {
83  parent = xxx;
84  fieldName = name;
85 }
86 
88 {
89  return pv==*this;
90 }
91 
92 std::ostream& operator<<(std::ostream& o, const PVField& f)
93 {
94  return f.dumpValue(o);
95 };
96 
97 string PVField::getFullName() const
98 {
99  string ret(fieldName);
100  for(const PVField *fld=getParent(); fld; fld=fld->getParent())
101  {
102  if(fld->getFieldName().size()==0) break;
103  ret = fld->getFieldName() + '.' + ret;
104  }
105  return ret;
106 }
107 
108 void PVField::computeOffset(const PVField * pvField) {
109  const PVStructure * pvTop = pvField->getParent();
110  if(pvTop==NULL) {
111  if(pvField->getField()->getType()!=structure) {
112  PVField *xxx = const_cast<PVField *>(pvField);
113  xxx->fieldOffset = 0;
114  xxx->nextFieldOffset = 1;
115  return;
116  }
117  pvTop = static_cast<const PVStructure *>(pvField);
118  } else {
119  while(pvTop->getParent()!=NULL) pvTop = pvTop->getParent();
120  }
121  size_t offset = 0;
122  size_t nextOffset = 1;
123  const PVFieldPtrArray & pvFields = pvTop->getPVFields();
124  for(size_t i=0; i < pvTop->getStructure()->getNumberFields(); i++) {
125  offset = nextOffset;
126  PVField *pvField = pvFields[i].get();
127  FieldConstPtr field = pvField->getField();
128  switch(field->getType()) {
129  case scalar:
130  case scalarArray:
131  case structureArray:
132  case union_:
133  case unionArray: {
134  nextOffset++;
135  pvField->fieldOffset = offset;
136  pvField->nextFieldOffset = nextOffset;
137  break;
138  }
139  case structure: {
140  pvField->computeOffset(pvField,offset);
141  nextOffset = pvField->getNextFieldOffset();
142  }
143  }
144  }
145  PVField *top = (PVField *)pvTop;
146  PVField *xxx = const_cast<PVField *>(top);
147  xxx->fieldOffset = 0;
148  xxx->nextFieldOffset = nextOffset;
149 }
150 
151 void PVField::computeOffset(const PVField * pvField,size_t offset) {
152  size_t beginOffset = offset;
153  size_t nextOffset = offset + 1;
154  const PVStructure *pvStructure = static_cast<const PVStructure *>(pvField);
155  const PVFieldPtrArray & pvFields = pvStructure->getPVFields();
156  for(size_t i=0; i < pvStructure->getStructure()->getNumberFields(); i++) {
157  offset = nextOffset;
158  PVField *pvSubField = pvFields[i].get();
159  FieldConstPtr field = pvSubField->getField();
160  switch(field->getType()) {
161  case scalar:
162  case scalarArray:
163  case structureArray:
164  case union_:
165  case unionArray: {
166  nextOffset++;
167  pvSubField->fieldOffset = offset;
168  pvSubField->nextFieldOffset = nextOffset;
169  break;
170  }
171  case structure: {
172  pvSubField->computeOffset(pvSubField,offset);
173  nextOffset = pvSubField->getNextFieldOffset();
174  }
175  }
176  }
177  PVField *xxx = const_cast<PVField *>(pvField);
178  xxx->fieldOffset = beginOffset;
179  xxx->nextFieldOffset = nextOffset;
180 }
181 
182 void PVField::copy(const PVField& from)
183 {
184  if(isImmutable())
185  throw std::invalid_argument("destination is immutable");
186 
187  if (getField() != from.getField())
188  throw std::invalid_argument("field types do not match");
189 
190  copyUnchecked(from);
191 }
192 
194 {
195  assert(getField()==from.getField());
196 
197  switch(getField()->getType())
198  {
199  case scalar:
200  {
201  const PVScalar* fromS = static_cast<const PVScalar*>(&from);
202  PVScalar* toS = static_cast<PVScalar*>(this);
203  toS->copyUnchecked(*fromS);
204  break;
205  }
206  case scalarArray:
207  {
208  const PVScalarArray* fromS = static_cast<const PVScalarArray*>(&from);
209  PVScalarArray* toS = static_cast<PVScalarArray*>(this);
210  toS->copyUnchecked(*fromS);
211  break;
212  }
213  case structure:
214  {
215  const PVStructure* fromS = static_cast<const PVStructure*>(&from);
216  PVStructure* toS = static_cast<PVStructure*>(this);
217  toS->copyUnchecked(*fromS);
218  break;
219  }
220  case structureArray:
221  {
222  const PVStructureArray* fromS = static_cast<const PVStructureArray*>(&from);
223  PVStructureArray* toS = static_cast<PVStructureArray*>(this);
224  toS->copyUnchecked(*fromS);
225  break;
226  }
227  case union_:
228  {
229  const PVUnion* fromS = static_cast<const PVUnion*>(&from);
230  PVUnion* toS = static_cast<PVUnion*>(this);
231  toS->copyUnchecked(*fromS);
232  break;
233  }
234  case unionArray:
235  {
236  const PVUnionArray* fromS = static_cast<const PVUnionArray*>(&from);
237  PVUnionArray* toS = static_cast<PVUnionArray*>(this);
238  toS->copyUnchecked(*fromS);
239  break;
240  }
241  default:
242  {
243  throw std::logic_error("PVField::copy unknown type");
244  }
245  }
246 }
247 
248 
249 }}
const PVFieldPtrArray & getPVFields() const
Definition: pvData.h:736
PVScalar is the base class for each scalar field.
Definition: pvData.h:272
Data class for a unionArray.
Definition: pvData.h:1335
void copyUnchecked(const PVUnionArray &from)
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
void setParentAndName(PVStructure *parent, std::string const &fieldName)
Definition: PVField.cpp:81
void setPostHandler(PostHandlerPtr const &postHandler)
Definition: PVField.cpp:70
int i
Definition: scan.c:967
virtual void setImmutable()
Definition: PVField.cpp:63
Definition: tool_lib.h:67
const FieldConstPtr & getField() const
Definition: pvData.h:208
PVField(FieldConstPtr field)
Definition: PVField.cpp:30
virtual void copyUnchecked(const PVScalar &from)=0
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
static size_t num_instances
Definition: pvData.h:241
#define NULL
Definition: catime.c:38
PVField is the base class for each PVData field.
Definition: pvData.h:152
std::ostream & operator<<(std::ostream &o, const Field &f)
std::size_t getFieldOffset() const
Definition: PVField.cpp:44
void copyUnchecked(const PVStructure &from)
std::string getFullName() const
Definition: PVField.cpp:97
std::tr1::shared_ptr< PostHandler > PostHandlerPtr
Definition: pvData.h:55
APIs for the epicsMutex mutual exclusion semaphore.
Base class for a scalarArray.
Definition: pvData.h:618
void copyUnchecked(const PVField &from)
Definition: PVField.cpp:193
PVUnion has a single subfield.
Definition: pvData.h:940
std::vector< PVFieldPtr > PVFieldPtrArray
Definition: pvData.h:70
Data interface for a structure,.
Definition: pvData.h:712
std::tr1::shared_ptr< const Field > FieldConstPtr
Definition: pvIntrospect.h:137
Data class for a structureArray.
Definition: pvData.h:1236
bool isImmutable() const
Definition: pvData.h:198
const StructureConstPtr & getStructure() const
Definition: pvData.h:731
void copyUnchecked(const PVStructureArray &from)
shared_ptr< T > const_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:798
virtual std::ostream & dumpValue(std::ostream &o) const =0
void copyUnchecked(const PVUnion &from)
Definition: PVUnion.cpp:210
virtual bool equals(PVField &pv)
Definition: PVField.cpp:87
PVStructure * getParent()
Definition: pvData.h:213
void copyUnchecked(const PVScalarArray &from)
Definition: pvData.h:691
void copy(const PVField &from)
Definition: PVField.cpp:182
#define false
Definition: flexdef.h:85
std::size_t getNextFieldOffset() const
Definition: PVField.cpp:50
std::size_t getNumberFields() const
Definition: PVField.cpp:56