This is Unofficial EPICS BASE Doxygen Site
PVStructureArray.cpp
Go to the documentation of this file.
1 /*PVStructureArray.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 #define epicsExportSharedSymbols
15 #include <pv/pvData.h>
16 #include <pv/factory.h>
17 #include <pv/serializeHelper.h>
18 
20 using std::size_t;
21 
22 namespace epics { namespace pvData {
23 
24 size_t PVStructureArray::append(size_t number)
25 {
26  checkLength(value.size()+number);
27 
28  svector data(reuse());
29  data.resize(data.size()+number);
30 
31  StructureConstPtr structure = structureArray->getStructure();
32 
33  PVDataCreatePtr pvDataCreate = getPVDataCreate();
34  for(svector::reverse_iterator it = data.rbegin(); number; ++it, --number)
35  *it = pvDataCreate->createPVStructure(structure);
36 
37  size_t newLength = data.size();
38 
39  const_svector cdata(freeze(data));
40  swap(cdata);
41 
42  return newLength;
43 }
44 
45 bool PVStructureArray::remove(size_t offset,size_t number)
46 {
47  if (number==0)
48  return true;
49  else if (offset+number>getLength())
50  return false;
51  else if (getArray()->getArraySizeType() == Array::fixed)
52  return false;
53 
54  svector vec(reuse());
55 
56  size_t length = vec.size();
57 
58  for(size_t i = offset; i+number < length; i++) {
59  vec[i].swap(vec[i + number]);
60  }
61 
62  vec.resize(length - number);
63  const_svector cdata(freeze(vec));
64  swap(cdata);
65 
66  return true;
67 }
68 
70  if (getArray()->getArraySizeType() == Array::fixed)
71  return;
72 
73  svector vec(reuse()); // TODO: check for first NULL before realloc
74 
75  size_t length = vec.size();
76  size_t newLength = 0;
77 
78  for(size_t i=0; i<length; i++) {
79  if(vec[i]) {
80  newLength++;
81  continue;
82  }
83  // find first non 0
84  size_t notNull = 0;
85  for(size_t j=i+1;j<length;j++) {
86  if(vec[j]) {
87  notNull = j;
88  break;
89  }
90  }
91  if(notNull!=0) {
92  vec[i] = vec[notNull];
93  vec[notNull].reset();
94  newLength++;
95  continue;
96  }
97  break;
98  }
99 
100  vec.resize(newLength);
101  const_svector cdata(freeze(vec));
102  swap(cdata);
103 }
104 
105 void PVStructureArray::setCapacity(size_t capacity)
106 {
107  if (this->isCapacityMutable()) {
108  checkLength(capacity);
110  swap(value);
111  if(value.capacity()<capacity) {
112  svector mvalue(thaw(value));
113  mvalue.reserve(capacity);
114  value = freeze(mvalue);
115  }
116  swap(value);
117  }
118  else
119  THROW_EXCEPTION2(std::logic_error, "capacity immutable");
120 }
121 
122 void PVStructureArray::setLength(size_t length)
123 {
124  if(this->isImmutable())
125  THROW_EXCEPTION2(std::logic_error, "immutable");
127  swap(value);
128 
129  if (length == value.size())
130  return;
131 
132  checkLength(length);
133 
134  if (length < value.size()) {
135  value.slice(0, length);
136  } else {
137  svector mvalue(thaw(value));
138  mvalue.resize(length);
139  value = freeze(mvalue);
140  }
141  swap(value);
142 }
143 
145 {
146  if (this->isImmutable())
147  THROW_EXCEPTION2(std::logic_error, "immutable");
148 
149  // no checkLength call here
150 
151  value.swap(other);
152 }
153 
155  SerializableControl *pflusher) const {
156  serialize(pbuffer, pflusher, 0, getLength());
157 }
158 
160  DeserializableControl *pcontrol) {
161  svector data(reuse());
162 
163  size_t size = this->getArray()->getArraySizeType() == Array::fixed ?
164  this->getArray()->getMaximumCapacity() :
165  SerializeHelper::readSize(pbuffer, pcontrol);
166 
167  data.resize(size);
168 
169  StructureConstPtr structure = structureArray->getStructure();
170 
171  PVDataCreatePtr pvDataCreate = getPVDataCreate();
172 
173  for(size_t i = 0; i<size; i++) {
174  pcontrol->ensureData(1);
175  size_t temp = pbuffer->getByte();
176  if(temp==0) {
177  data[i].reset();
178  }
179  else {
180  if(data[i].get()==NULL || !data[i].unique()) {
181  data[i] = pvDataCreate->createPVStructure(structure);
182  }
183  data[i]->deserialize(pbuffer, pcontrol);
184  }
185  }
186  replace(freeze(data)); // calls postPut()
187 }
188 
190  SerializableControl *pflusher, size_t offset, size_t count) const {
191 
192  const_svector temp(view());
193  temp.slice(offset, count);
194 
195  ArrayConstPtr array = this->getArray();
196  if (array->getArraySizeType() != Array::fixed)
197  SerializeHelper::writeSize(temp.size(), pbuffer, pflusher);
198  else if (count != array->getMaximumCapacity())
199  throw std::length_error("fixed array cannot be partially serialized");
200 
201  for(size_t i = 0; i<count; i++) {
202  if(pbuffer->getRemaining()<1)
203  pflusher->flushSerializeBuffer();
204 
205  if(temp[i].get()==NULL) {
206  pbuffer->putByte(0);
207  }
208  else {
209  pbuffer->putByte(1);
210  temp[i]->serialize(pbuffer, pflusher);
211  }
212  }
213 }
214 
215 std::ostream& PVStructureArray::dumpValue(std::ostream& o) const
216 {
217  o << format::indent() << getStructureArray()->getID() << ' ' << getFieldName() << std::endl;
218  size_t length = getLength();
219  if (length > 0)
220  {
222 
223  for (size_t i = 0; i < length; i++)
224  dumpValue(o, i);
225  }
226 
227  return o;
228 }
229 
230 std::ostream& PVStructureArray::dumpValue(std::ostream& o, std::size_t index) const
231 {
232  const_svector temp(view());
233  if (index<temp.size())
234  {
235  if (temp[index])
236  o << *temp[index];
237  else
238  o << format::indent() << "(none)" << std::endl;
239  }
240  return o;
241 }
242 
244 {
245  if(isImmutable())
246  throw std::invalid_argument("destination is immutable");
247 
248  if(*getStructureArray() != *from.getStructureArray())
249  throw std::invalid_argument("structureArray definitions do not match");
250 
251  copyUnchecked(from);
252 }
253 
255 {
256  if (this == &from)
257  return;
258 
259  replace(from.view());
260 }
261 
262 }}
const std::string & getFieldName() const
Definition: pvData.h:166
void resize(size_t i)
Grow or shrink array.
Definition: sharedVector.h:457
Definition: link.h:174
virtual const_svector view() const OVERRIDE FINAL
Fetch a read-only view of the current array data.
Definition: pvData.h:1209
::epics::pvData::shared_vector< T > svector
Definition: pvData.h:1184
A holder for a contiguous piece of memory.
Definition: sharedVector.h:27
bool remove(std::size_t offset, std::size_t number)
EPICS_ALWAYS_INLINE int8 getByte()
Definition: byteBuffer.h:617
#define THROW_EXCEPTION2(TYPE, MSG)
int i
Definition: scan.c:967
StructureArrayConstPtr getStructureArray() const
Definition: pvData.h:1278
virtual void serialize(ByteBuffer *pbuffer, SerializableControl *pflusher) const OVERRIDE FINAL
shared_ptr< T > static_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:788
std::tr1::shared_ptr< const Array > ArrayConstPtr
Definition: pvIntrospect.h:154
void checkLength(size_t length) const
virtual void swap(const_svector &other) OVERRIDE FINAL
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
std::tr1::shared_ptr< const Structure > StructureConstPtr
Definition: pvIntrospect.h:162
#define NULL
Definition: catime.c:38
static void writeSize(std::size_t s, ByteBuffer *buffer, SerializableControl *flusher)
void copy(const PVStructureArray &from)
static std::size_t readSize(ByteBuffer *buffer, DeserializableControl *control)
Callback class for deserialization.
Definition: serialize.h:89
virtual std::ostream & dumpValue(std::ostream &o) const OVERRIDE FINAL
std::size_t append(std::size_t number)
std::tr1::shared_ptr< PVDataCreate > PVDataCreatePtr
Definition: pvData.h:124
virtual void replace(const const_svector &next) OVERRIDE FINAL
virtual std::ostream & dumpValue(std::ostream &o) const OVERRIDE FINAL
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *pflusher) OVERRIDE FINAL
virtual ArrayConstPtr getArray() const OVERRIDE FINAL
EPICS_ALWAYS_INLINE void putByte(int8 value)
Definition: byteBuffer.h:525
This class implements a Bytebuffer that is like the java.nio.ByteBuffer.
Definition: byteBuffer.h:233
virtual void swap(const_svector &other) OVERRIDE FINAL
std::size_t getRemaining() const
Definition: byteBuffer.h:391
std::reverse_iterator< iterator > reverse_iterator
Definition: sharedVector.h:299
size_t size() const
Number of elements visible through this vector.
Definition: sharedVector.h:220
char * pbuffer
Definition: errlog.c:85
Data class for a structureArray.
Definition: pvData.h:1236
bool isImmutable() const
Definition: pvData.h:198
virtual const_svector view() const OVERRIDE FINAL
Fetch a read-only view of the current array data.
Definition: pvData.h:1297
bool isCapacityMutable() const
Definition: PVArray.cpp:33
virtual void serialize(ByteBuffer *pbuffer, SerializableControl *pflusher) const OVERRIDE FINAL
virtual size_t getLength() const OVERRIDE FINAL
Definition: pvData.h:1203
Callback class for serialization.
Definition: serialize.h:34
void copyUnchecked(const PVStructureArray &from)
void slice(size_t offset, size_t length=(size_t)-1)
Reduce the view of this shared_vector.
Definition: sharedVector.h:244
virtual void setLength(std::size_t length) OVERRIDE FINAL
virtual void ensureData(std::size_t size)=0
void reserve(size_t i)
Set array capacity.
Definition: sharedVector.h:428
void copyUnchecked(const PVScalarArray &from)
Definition: pvData.h:691
FORCE_INLINE const PVDataCreatePtr & getPVDataCreate()
Definition: pvData.h:1648
virtual void setCapacity(size_t capacity) OVERRIDE FINAL
::epics::pvData::shared_vector< const T > const_svector
Definition: pvData.h:1185