This is Unofficial EPICS BASE Doxygen Site
PVUnionArray.cpp
Go to the documentation of this file.
1 /*PVUnionArray.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 PVUnionArray::append(size_t number)
25 {
26  checkLength(value.size()+number);
27 
28  svector data(reuse());
29  data.resize(data.size()+number);
30 
31  UnionConstPtr punion = unionArray->getUnion();
32 
33  PVDataCreatePtr pvDataCreate = getPVDataCreate();
34  for(svector::reverse_iterator it = data.rbegin(); number; ++it, --number)
35  *it = pvDataCreate->createPVUnion(punion);
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 PVUnionArray::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 PVUnionArray::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 PVUnionArray::setLength(size_t length)
123 {
124  if(this->isImmutable())
125  THROW_EXCEPTION2(std::logic_error, "immutable");
127  swap(value);
128  if (length == value.size())
129  return;
130 
131  checkLength(length);
132 
133  if (length < value.size()) {
134  value.slice(0, length);
135  } else {
136  svector mvalue(thaw(value));
137  mvalue.resize(length);
138  value = freeze(mvalue);
139  }
140  swap(value);
141 }
142 
144 {
145  if(this->isImmutable())
146  THROW_EXCEPTION2(std::logic_error,"Immutable");
147 
148  // no checkLength call here
149 
150  value.swap(other);
151 }
152 
154  SerializableControl *pflusher) const {
155  serialize(pbuffer, pflusher, 0, getLength());
156 }
157 
159  DeserializableControl *pcontrol) {
160  svector data(reuse());
161 
162  size_t size = this->getArray()->getArraySizeType() == Array::fixed ?
163  this->getArray()->getMaximumCapacity() :
164  SerializeHelper::readSize(pbuffer, pcontrol);
165 
166  data.resize(size);
167 
168  UnionConstPtr punion = unionArray->getUnion();
169 
170  PVDataCreatePtr pvDataCreate = getPVDataCreate();
171 
172  for(size_t i = 0; i<size; i++) {
173  pcontrol->ensureData(1);
174  size_t temp = pbuffer->getByte();
175  if(temp==0) {
176  data[i].reset();
177  }
178  else {
179  if(data[i].get()==NULL || !data[i].unique()) {
180  data[i] = pvDataCreate->createPVUnion(punion);
181  }
182  data[i]->deserialize(pbuffer, pcontrol);
183  }
184  }
185  replace(freeze(data)); // calls postPut()
186 }
187 
189  SerializableControl *pflusher, size_t offset, size_t count) const {
190 
191  const_svector temp(view());
192  temp.slice(offset, count);
193 
194  ArrayConstPtr array = this->getArray();
195  if (array->getArraySizeType() != Array::fixed)
196  SerializeHelper::writeSize(temp.size(), pbuffer, pflusher);
197  else if (count != array->getMaximumCapacity())
198  throw std::length_error("fixed array cannot be partially serialized");
199 
200  for(size_t i = 0; i<count; i++) {
201  if(pbuffer->getRemaining()<1)
202  pflusher->flushSerializeBuffer();
203 
204  if(temp[i].get()==NULL) {
205  pbuffer->putByte(0);
206  }
207  else {
208  pbuffer->putByte(1);
209  temp[i]->serialize(pbuffer, pflusher);
210  }
211  }
212 }
213 
214 std::ostream& PVUnionArray::dumpValue(std::ostream& o) const
215 {
216  o << format::indent() << getUnionArray()->getID() << ' ' << getFieldName() << std::endl;
217  size_t length = getLength();
218  if (length > 0)
219  {
221 
222  for (size_t i = 0; i < length; i++)
223  dumpValue(o, i);
224  }
225 
226  return o;
227 }
228 
229 std::ostream& PVUnionArray::dumpValue(std::ostream& o, std::size_t index) const
230 {
231  const_svector temp(view());
232  if (index<temp.size())
233  {
234  if (temp[index])
235  o << *temp[index];
236  else
237  o << format::indent() << "(none)" << std::endl;
238  }
239  return o;
240 }
241 
243 {
244  if(isImmutable())
245  throw std::invalid_argument("destination is immutable");
246 
247  if(*getUnionArray() != *from.getUnionArray())
248  throw std::invalid_argument("unionArray definitions do not match");
249 
250  copyUnchecked(from);
251 }
252 
254 {
255  if (this == &from)
256  return;
257 
258  replace(from.view());
259 }
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
Data class for a unionArray.
Definition: pvData.h:1335
void copyUnchecked(const PVUnionArray &from)
::epics::pvData::shared_vector< T > svector
Definition: pvData.h:1184
virtual void serialize(ByteBuffer *pbuffer, SerializableControl *pflusher) const OVERRIDE FINAL
A holder for a contiguous piece of memory.
Definition: sharedVector.h:27
EPICS_ALWAYS_INLINE int8 getByte()
Definition: byteBuffer.h:617
#define THROW_EXCEPTION2(TYPE, MSG)
int i
Definition: scan.c:967
virtual void setCapacity(size_t capacity) OVERRIDE FINAL
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
std::size_t append(std::size_t number)
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
#define NULL
Definition: catime.c:38
static void writeSize(std::size_t s, ByteBuffer *buffer, SerializableControl *flusher)
static std::size_t readSize(ByteBuffer *buffer, DeserializableControl *control)
Callback class for deserialization.
Definition: serialize.h:89
std::tr1::shared_ptr< PVDataCreate > PVDataCreatePtr
Definition: pvData.h:124
virtual void replace(const const_svector &next) OVERRIDE FINAL
std::tr1::shared_ptr< const Union > UnionConstPtr
Definition: pvIntrospect.h:170
virtual std::ostream & dumpValue(std::ostream &o) const OVERRIDE FINAL
virtual void setLength(std::size_t length) OVERRIDE FINAL
virtual std::ostream & dumpValue(std::ostream &o) const OVERRIDE FINAL
virtual void swap(const_svector &other) OVERRIDE
void copy(const PVUnionArray &from)
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
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *pflusher) OVERRIDE FINAL
bool remove(std::size_t offset, std::size_t number)
bool isImmutable() const
Definition: pvData.h:198
bool isCapacityMutable() const
Definition: PVArray.cpp:33
virtual size_t getLength() const OVERRIDE FINAL
Definition: pvData.h:1203
Callback class for serialization.
Definition: serialize.h:34
void slice(size_t offset, size_t length=(size_t)-1)
Reduce the view of this shared_vector.
Definition: sharedVector.h:244
virtual const_svector view() const OVERRIDE
Fetch a read-only view of the current array data.
Definition: pvData.h:1396
virtual void ensureData(std::size_t size)=0
UnionArrayConstPtr getUnionArray() const
Definition: pvData.h:1377
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
::epics::pvData::shared_vector< const T > const_svector
Definition: pvData.h:1185