This is Unofficial EPICS BASE Doxygen Site
typeCast.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  */
5 /* Author: Michael Davidsaver */
6 #include <algorithm>
7 #include <sstream>
8 
9 #include <string.h>
10 
11 #include <epicsConvert.h>
12 
13 #define epicsExportSharedSymbols
14 #include "pv/typeCast.h"
15 
16 using epics::pvData::castUnsafe;
19 using std::string;
20 
21 namespace {
22 
23 static void noconvert()
24 {
25  throw std::runtime_error("castUnsafeV: Conversion not supported");
26 }
27 
28 template<typename TO, typename FROM>
29 static void castVTyped(size_t count, void *draw, const void *sraw)
30 {
31  TO *dest=(TO*)draw;
32  const FROM *src=(FROM*)sraw;
33 
34  //std::transform(src, src+count, dest, castUnsafe<TO,FROM>);
35 
36  try {
37  for(size_t i=0; i<count; i++) {
38  dest[i] = castUnsafe<TO,FROM>(src[i]);
39  }
40  } catch (std::exception& ex) {
41  // do not report index for scalars (or arrays with one element)
42  if (count > 1)
43  {
44  std::ostringstream os;
45  os << "failed to parse element at index " << (src - (FROM*)sraw);
46  os << ": " << ex.what();
47  throw std::runtime_error(os.str());
48  }
49  else
50  throw;
51  }
52 }
53 
54 template<typename T>
55 static void copyV(size_t count, void *draw, const void *sraw)
56 {
57  T *dest=(T*)draw;
58  const T *src=(const T*)sraw;
59  std::copy(src, src+count, dest);
60 }
61 
62 template<int N>
63 static void copyMem(size_t count, void *draw, const void *sraw)
64 {
65  memcpy(draw, sraw, count*N);
66 }
67 
68 } // end namespace
69 
70 namespace epics { namespace pvData {
71 
72 void castUnsafeV(size_t count, ScalarType to, void *dest, ScalarType from, const void *src)
73 {
74 #define COPYMEM(N) copyMem<N>(count, dest, src)
75 #define CAST(TO, FROM) castVTyped<TO, FROM>(count, dest, src)
76 
77  switch(to) {
78  case pvBoolean:
79  switch(from) {
80  case pvBoolean: COPYMEM(1); return;
81  case pvString: CAST(boolean, std::string); return;
82  default: noconvert(); return;
83  }
84  break;
85 
86  case pvByte:
87  switch(from) {
88  case pvBoolean: noconvert(); return;
89  case pvByte:
90  case pvUByte: COPYMEM(1); return;
91  case pvShort: CAST(int8, int16); return;
92  case pvUShort: CAST(int8, uint16); return;
93  case pvInt: CAST(int8, int32); return;
94  case pvUInt: CAST(int8, uint32); return;
95  case pvLong: CAST(int8, int64); return;
96  case pvULong: CAST(int8, uint64); return;
97  case pvFloat: CAST(int8, float); return;
98  case pvDouble: CAST(int8, double); return;
99  case pvString: CAST(int8, std::string); return;
100  }
101  break;
102 
103  case pvUByte:
104  switch(from) {
105  case pvBoolean: noconvert(); return;
106  case pvByte:
107  case pvUByte: COPYMEM(1); return;
108  case pvShort: CAST(uint8, int16); return;
109  case pvUShort: CAST(uint8, uint16); return;
110  case pvInt: CAST(uint8, int32); return;
111  case pvUInt: CAST(uint8, uint32); return;
112  case pvLong: CAST(uint8, int64); return;
113  case pvULong: CAST(uint8, uint64); return;
114  case pvFloat: CAST(uint8, float); return;
115  case pvDouble: CAST(uint8, double); return;
116  case pvString: CAST(uint8, std::string); return;
117  }
118  break;
119 
120  case pvShort:
121  switch(from) {
122  case pvBoolean: noconvert(); return;
123  case pvByte: CAST(int16, int8); return;
124  case pvUByte: CAST(int16, uint8); return;
125  case pvShort:
126  case pvUShort: COPYMEM(2); return;
127  case pvInt: CAST(int16, int32); return;
128  case pvUInt: CAST(int16, uint32); return;
129  case pvLong: CAST(int16, int64); return;
130  case pvULong: CAST(int16, uint64); return;
131  case pvFloat: CAST(int16, float); return;
132  case pvDouble: CAST(int16, double); return;
133  case pvString: CAST(int16, std::string); return;
134  }
135  break;
136 
137  case pvUShort:
138  switch(from) {
139  case pvBoolean: noconvert(); return;
140  case pvByte: CAST(uint16, int8); return;
141  case pvUByte: CAST(uint16, uint8); return;
142  case pvShort:
143  case pvUShort: COPYMEM(2); return;
144  case pvInt: CAST(uint16, int32); return;
145  case pvUInt: CAST(uint16, uint32); return;
146  case pvLong: CAST(uint16, int64); return;
147  case pvULong: CAST(uint16, uint64); return;
148  case pvFloat: CAST(uint16, float); return;
149  case pvDouble: CAST(uint16, double); return;
150  case pvString: CAST(uint16, std::string); return;
151  }
152  break;
153 
154  case pvInt:
155  switch(from) {
156  case pvBoolean: noconvert(); return;
157  case pvByte: CAST(int32, int8); return;
158  case pvUByte: CAST(int32, uint8); return;
159  case pvShort: CAST(int32, int16); return;
160  case pvUShort: CAST(int32, uint16); return;
161  case pvInt:
162  case pvUInt: COPYMEM(4); return;
163  case pvLong: CAST(int32, int64); return;
164  case pvULong: CAST(int32, uint64); return;
165  case pvFloat: CAST(int32, float); return;
166  case pvDouble: CAST(int32, double); return;
167  case pvString: CAST(int32, std::string); return;
168  }
169  break;
170 
171  case pvUInt:
172  switch(from) {
173  case pvBoolean: noconvert(); return;
174  case pvByte: CAST(uint32, int8); return;
175  case pvUByte: CAST(uint32, uint8); return;
176  case pvShort: CAST(uint32, int16); return;
177  case pvUShort: CAST(uint32, uint16); return;
178  case pvInt:
179  case pvUInt: COPYMEM(4); return;
180  case pvLong: CAST(uint32, int64); return;
181  case pvULong: CAST(uint32, uint64); return;
182  case pvFloat: CAST(uint32, float); return;
183  case pvDouble: CAST(uint32, double); return;
184  case pvString: CAST(uint32, std::string); return;
185  }
186  break;
187 
188  case pvLong:
189  switch(from) {
190  case pvBoolean: noconvert(); return;
191  case pvByte: CAST(int64, int8); return;
192  case pvUByte: CAST(int64, uint8); return;
193  case pvShort: CAST(int64, int16); return;
194  case pvUShort: CAST(int64, uint16); return;
195  case pvInt: CAST(int64, int32); return;
196  case pvUInt: CAST(int64, uint32); return;
197  case pvLong:
198  case pvULong: COPYMEM(8); return;
199  case pvFloat: CAST(int64, float); return;
200  case pvDouble: CAST(int64, double); return;
201  case pvString: CAST(int64, std::string); return;
202  }
203  break;
204 
205  case pvULong:
206  switch(from) {
207  case pvBoolean: noconvert(); return;
208  case pvByte: CAST(uint64, int8); return;
209  case pvUByte: CAST(uint64, uint8); return;
210  case pvShort: CAST(uint64, int16); return;
211  case pvUShort: CAST(uint64, uint16); return;
212  case pvInt: CAST(uint64, int32); return;
213  case pvUInt: CAST(uint64, uint32); return;
214  case pvLong:
215  case pvULong: COPYMEM(8); return;
216  case pvFloat: CAST(uint64, float); return;
217  case pvDouble: CAST(uint64, double); return;
218  case pvString: CAST(uint64, std::string); return;
219  }
220  break;
221 
222  case pvFloat:
223  switch(from) {
224  case pvBoolean: noconvert(); return;
225  case pvByte: CAST(float, int8); return;
226  case pvUByte: CAST(float, uint8); return;
227  case pvShort: CAST(float, int16); return;
228  case pvUShort: CAST(float, uint16); return;
229  case pvInt: CAST(float, int32); return;
230  case pvUInt: CAST(float, uint32); return;
231  case pvLong: CAST(float, int64); return;
232  case pvULong: CAST(float, uint64); return;
233  case pvFloat: COPYMEM(4); return;
234  case pvDouble: CAST(float, double); return;
235  case pvString: CAST(float, std::string); return;
236  }
237  break;
238 
239  case pvDouble:
240  switch(from) {
241  case pvBoolean: noconvert(); return;
242  case pvByte: CAST(double, int8); return;
243  case pvUByte: CAST(double, uint8); return;
244  case pvShort: CAST(double, int16); return;
245  case pvUShort: CAST(double, uint16); return;
246  case pvInt: CAST(double, int32); return;
247  case pvUInt: CAST(double, uint32); return;
248  case pvLong: CAST(double, int64); return;
249  case pvULong: CAST(double, uint64); return;
250  case pvFloat: CAST(double, float); return;
251  case pvDouble: COPYMEM(8); return;
252  case pvString: CAST(double, std::string); return;
253  }
254  break;
255 
256  case pvString:
257  switch(from) {
258  case pvBoolean: CAST(std::string, boolean); return;
259  case pvByte: CAST(std::string, int8); return;
260  case pvUByte: CAST(std::string, uint8); return;
261  case pvShort: CAST(std::string, int16); return;
262  case pvUShort: CAST(std::string, uint16); return;
263  case pvInt: CAST(std::string, int32); return;
264  case pvUInt: CAST(std::string, uint32); return;
265  case pvLong: CAST(std::string, int64); return;
266  case pvULong: CAST(std::string, uint64); return;
267  case pvFloat: CAST(std::string, float); return;
268  case pvDouble: CAST(std::string, double); return;
269  case pvString: copyV<std::string>(count, dest, src); return;
270  }
271  break;
272  }
273 
274  THROW_EXCEPTION2(std::logic_error, "Undefined cast");
275 }
276 
277 }}
int8_t int8
Definition: pvType.h:75
#define THROW_EXCEPTION2(TYPE, MSG)
uint16_t uint16
Definition: pvType.h:95
int i
Definition: scan.c:967
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
#define COPYMEM(N)
void copy(PVValueArray< T > &pvFrom, size_t fromOffset, size_t fromStride, PVValueArray< T > &pvTo, size_t toOffset, size_t toStride, size_t count)
Copy a subarray from one scalar array to another.
uint64_t uint64
Definition: pvType.h:103
int64_t int64
Definition: pvType.h:87
epicsShareExtern void castUnsafeV(size_t count, ScalarType to, void *dest, ScalarType from, const void *src)
Definition: typeCast.cpp:72
#define CAST(TO, FROM)
int16_t int16
Definition: pvType.h:79
int32_t int32
Definition: pvType.h:83
uint8_t uint8
Definition: pvType.h:91
uint32_t uint32
Definition: pvType.h:99