Directory: | ./ |
---|---|
File: | pdserv/src/DataType.cpp |
Date: | 2024-11-17 04:08:36 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 47 | 113 | 41.6% |
Branches: | 21 | 112 | 18.8% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /***************************************************************************** | ||
2 | * | ||
3 | * $Id$ | ||
4 | * | ||
5 | * Copyright (C) 2012 Richard Hacker (lerichi at gmx dot net) | ||
6 | * | ||
7 | * This file is part of the pdserv library. | ||
8 | * | ||
9 | * The pdserv library is free software: you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU Lesser General Public License as published | ||
11 | * by the Free Software Foundation, either version 3 of the License, or (at | ||
12 | * your option) any later version. | ||
13 | * | ||
14 | * The pdserv library is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
16 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | ||
17 | * License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU Lesser General Public License | ||
20 | * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>. | ||
21 | * | ||
22 | *****************************************************************************/ | ||
23 | |||
24 | #include "DataType.h" | ||
25 | #include "Debug.h" | ||
26 | #include <stdint.h> | ||
27 | #include <functional> // std::multiplies | ||
28 | #include <numeric> // std::accumulate | ||
29 | |||
30 | |||
31 | using namespace PdServ; | ||
32 | |||
33 | template <class T> | ||
34 | struct TypeNum {}; | ||
35 | |||
36 | template <> | ||
37 | struct TypeNum<bool> { | ||
38 | static const DataType::Primary value = DataType::boolean_T; | ||
39 | static const size_t align = sizeof(bool); | ||
40 | }; | ||
41 | |||
42 | template <> | ||
43 | struct TypeNum<uint8_t> { | ||
44 | static const DataType::Primary value = DataType::uint8_T; | ||
45 | static const size_t align = sizeof(uint8_t); | ||
46 | }; | ||
47 | |||
48 | template <> | ||
49 | struct TypeNum<int8_t> { | ||
50 | static const DataType::Primary value = DataType::int8_T; | ||
51 | static const size_t align = sizeof(int8_t); | ||
52 | }; | ||
53 | |||
54 | template <> | ||
55 | struct TypeNum<uint16_t> { | ||
56 | static const DataType::Primary value = DataType::uint16_T; | ||
57 | static const size_t align = sizeof(uint16_t); | ||
58 | }; | ||
59 | |||
60 | template <> | ||
61 | struct TypeNum<int16_t> { | ||
62 | static const DataType::Primary value = DataType::int16_T; | ||
63 | static const size_t align = sizeof(int16_t); | ||
64 | }; | ||
65 | |||
66 | template <> | ||
67 | struct TypeNum<uint32_t> { | ||
68 | static const DataType::Primary value = DataType::uint32_T; | ||
69 | static const size_t align = sizeof(uint32_t); | ||
70 | }; | ||
71 | |||
72 | template <> | ||
73 | struct TypeNum<int32_t> { | ||
74 | static const DataType::Primary value = DataType::int32_T; | ||
75 | static const size_t align = sizeof(int32_t); | ||
76 | }; | ||
77 | |||
78 | template <> | ||
79 | struct TypeNum<uint64_t> { | ||
80 | static const DataType::Primary value = DataType::uint64_T; | ||
81 | static const size_t align = sizeof(uint64_t); | ||
82 | }; | ||
83 | |||
84 | template <> | ||
85 | struct TypeNum<int64_t> { | ||
86 | static const DataType::Primary value = DataType::int64_T; | ||
87 | static const size_t align = sizeof(int64_t); | ||
88 | }; | ||
89 | |||
90 | template <> | ||
91 | struct TypeNum<double> { | ||
92 | static const DataType::Primary value = DataType::double_T; | ||
93 | static const size_t align = sizeof(double); | ||
94 | }; | ||
95 | |||
96 | template <> | ||
97 | struct TypeNum<float> { | ||
98 | static const DataType::Primary value = DataType::single_T; | ||
99 | static const size_t align = sizeof(float); | ||
100 | }; | ||
101 | |||
102 | //////////////////////////////////////////////////////////////////////////// | ||
103 | //////////////////////////////////////////////////////////////////////////// | ||
104 | namespace { | ||
105 | template <class T> | ||
106 | 33 | class PrimaryType: public DataType { | |
107 | public: | ||
108 | 33 | PrimaryType(): DataType(sizeof(T), setValue) { | |
109 | 33 | } | |
110 | |||
111 | private: | ||
112 | 207 | void print(std::ostream& os, const char *data, | |
113 | const char* start, const char *end) const { | ||
114 | 207 | const T* val = reinterpret_cast<const T*>(data); | |
115 | 207 | const T* lastVal = reinterpret_cast<const T*>(end); | |
116 | 207 | char delim = 0; | |
117 | |||
118 |
8/18✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 11 times.
✓ Branch 7 taken 11 times.
✓ Branch 8 taken 367 times.
✓ Branch 9 taken 147 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 43 times.
✓ Branch 15 taken 43 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
|
1085 | for (;val < lastVal; val++) { |
119 |
4/18✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 18 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 11 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 367 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 43 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
|
439 | if ((const char*)val < start) |
120 | ✗ | continue; | |
121 | |||
122 |
6/18✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 11 times.
✓ Branch 8 taken 220 times.
✓ Branch 9 taken 147 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 43 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
|
439 | if (delim) |
123 | 232 | os << delim; | |
124 | 439 | delim = ','; | |
125 | |||
126 |
0/2✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
439 | os << *val; |
127 | } | ||
128 | 207 | } | |
129 | |||
130 | 8132 | DataType::Primary primary() const { | |
131 | 8132 | return TypeNum<T>::value; | |
132 | } | ||
133 | |||
134 | 3870 | size_t align () const { | |
135 | 3870 | return TypeNum<T>::align; | |
136 | } | ||
137 | |||
138 | ✗ | static void setValue(char *&dst, double src) { | |
139 | ✗ | *reinterpret_cast<T*>(dst) = static_cast<T>(src); | |
140 | ✗ | dst += sizeof(T); | |
141 | } | ||
142 | }; | ||
143 | |||
144 | template<> | ||
145 | ✗ | void PrimaryType<int8_t>::print(std::ostream& os, const char *data, | |
146 | const char* start, const char *end) const { | ||
147 | ✗ | const int8_t* val = reinterpret_cast<const int8_t*>(data); | |
148 | ✗ | const int8_t* lastVal = reinterpret_cast<const int8_t*>(end); | |
149 | ✗ | char delim = 0; | |
150 | |||
151 | ✗ | for (;val < lastVal; val++) { | |
152 | ✗ | if ((const char*)val < start) | |
153 | ✗ | continue; | |
154 | |||
155 | ✗ | if (delim) | |
156 | ✗ | os << delim; | |
157 | ✗ | delim = ','; | |
158 | |||
159 | ✗ | os << (int)*val; | |
160 | } | ||
161 | } | ||
162 | |||
163 | template<> | ||
164 | ✗ | void PrimaryType<uint8_t>::print(std::ostream& os, const char *data, | |
165 | const char* start, const char *end) const { | ||
166 | ✗ | const uint8_t* val = reinterpret_cast<const uint8_t*>(data); | |
167 | ✗ | const uint8_t* lastVal = reinterpret_cast<const uint8_t*>(end); | |
168 | ✗ | char delim = 0; | |
169 | |||
170 | ✗ | for (;val < lastVal; val++) { | |
171 | ✗ | if ((const char*)val < start) | |
172 | ✗ | continue; | |
173 | |||
174 | ✗ | if (delim) | |
175 | ✗ | os << delim; | |
176 | ✗ | delim = ','; | |
177 | |||
178 | ✗ | os << (unsigned)*val; | |
179 | } | ||
180 | } | ||
181 | } | ||
182 | |||
183 | ////////////////////////////////////////////////////////////////////// | ||
184 | ////////////////////////////////////////////////////////////////////// | ||
185 | 3 | const DataType& DataType::boolean = PrimaryType< bool>(); | |
186 | 3 | const DataType& DataType:: uint8 = PrimaryType< uint8_t>(); | |
187 | 3 | const DataType& DataType:: int8 = PrimaryType< int8_t>(); | |
188 | 3 | const DataType& DataType:: uint16 = PrimaryType<uint16_t>(); | |
189 | 3 | const DataType& DataType:: int16 = PrimaryType< int16_t>(); | |
190 | 3 | const DataType& DataType:: uint32 = PrimaryType<uint32_t>(); | |
191 | 3 | const DataType& DataType:: int32 = PrimaryType< int32_t>(); | |
192 | 3 | const DataType& DataType:: uint64 = PrimaryType<uint64_t>(); | |
193 | 3 | const DataType& DataType:: int64 = PrimaryType< int64_t>(); | |
194 | 3 | const DataType& DataType::float64 = PrimaryType< double>(); | |
195 | 3 | const DataType& DataType::float32 = PrimaryType< float>(); | |
196 | |||
197 | ////////////////////////////////////////////////////////////////////// | ||
198 | ////////////////////////////////////////////////////////////////////// | ||
199 | 5272 | DataType::DimType::DimType (size_t ndims, const size_t *dim): | |
200 | 5272 | std::vector<size_t>(dim, dim + ndims), | |
201 | // std::vector<size_t>(dim ? dim : &ndims, dim ? dim + ndims : &ndims + 1), | ||
202 |
2/4✓ Branch 4 taken 5272 times.
✗ Branch 5 not taken.
✓ Branch 14 taken 5272 times.
✗ Branch 15 not taken.
|
10544 | nelem(std::accumulate(begin(), end(), 1U, std::multiplies<size_t>())) |
203 | { | ||
204 | 5272 | } | |
205 | |||
206 | ////////////////////////////////////////////////////////////////////// | ||
207 | ////////////////////////////////////////////////////////////////////// | ||
208 | ✗ | DataType::Field::Field (const std::string& name, const DataType& type, | |
209 | ✗ | size_t offset, size_t ndims, const size_t *dims): | |
210 | ✗ | name(name), type(type), offset(offset), dim(ndims, dims) | |
211 | { | ||
212 | } | ||
213 | |||
214 | ////////////////////////////////////////////////////////////////////// | ||
215 | ////////////////////////////////////////////////////////////////////// | ||
216 | ✗ | DataType::DataType (const std::string& name, size_t size): | |
217 | ✗ | name(name), size(size), setValue(0) | |
218 | { | ||
219 | } | ||
220 | |||
221 | ////////////////////////////////////////////////////////////////////// | ||
222 | ✗ | DataType::DataType (const DataType& other): | |
223 | ✗ | name(other.name), size(other.size), setValue(other.setValue) | |
224 | { | ||
225 | } | ||
226 | |||
227 | ////////////////////////////////////////////////////////////////////// | ||
228 | 33 | DataType::DataType (size_t size, void (*setValue)(char *&, double )): | |
229 | 33 | size(size), setValue(setValue) | |
230 | { | ||
231 | 33 | } | |
232 | |||
233 | ////////////////////////////////////////////////////////////////////// | ||
234 | 66 | DataType::~DataType () | |
235 | { | ||
236 | 33 | for (FieldList::const_iterator it = fieldList.begin(); | |
237 |
1/2✗ Branch 6 not taken.
✓ Branch 7 taken 33 times.
|
33 | it != fieldList.end(); ++it) |
238 | ✗ | delete *it; | |
239 | 33 | } | |
240 | |||
241 | ////////////////////////////////////////////////////////////////////// | ||
242 | 7854 | bool DataType::isPrimary () const | |
243 | { | ||
244 | 7854 | return primary() != compound_T; | |
245 | } | ||
246 | |||
247 | ////////////////////////////////////////////////////////////////////// | ||
248 | ✗ | DataType::Primary DataType::primary () const | |
249 | { | ||
250 | ✗ | return compound_T; | |
251 | } | ||
252 | |||
253 | ////////////////////////////////////////////////////////////////////// | ||
254 | ✗ | bool DataType::operator==(const DataType& other) const | |
255 | { | ||
256 | ✗ | return this == &other; | |
257 | } | ||
258 | |||
259 | ////////////////////////////////////////////////////////////////////// | ||
260 | 4 | bool DataType::operator!=(const DataType& other) const | |
261 | { | ||
262 | 4 | return this != &other; | |
263 | } | ||
264 | |||
265 | ////////////////////////////////////////////////////////////////////// | ||
266 | ✗ | void DataType::print(std::ostream& os, | |
267 | const char *data, const char *start, const char *end) const | ||
268 | { | ||
269 | ✗ | char delim = 0; | |
270 | |||
271 | ✗ | for (; data < end; data += this->size) { | |
272 | ✗ | for (FieldList::const_iterator it = fieldList.begin(); | |
273 | ✗ | it != fieldList.end(); ++it) { | |
274 | |||
275 | ✗ | const char *p1 = data + (*it)->offset; | |
276 | ✗ | if (p1 < start) | |
277 | ✗ | continue; | |
278 | |||
279 | ✗ | if (delim) | |
280 | ✗ | os << delim; | |
281 | ✗ | delim = ','; | |
282 | |||
283 | ✗ | const char *p2 = p1 + (*it)->dim.nelem * (*it)->type.size; | |
284 | ✗ | if (p2 < end) | |
285 | ✗ | (*it)->type.print(os, p1, start, p2); | |
286 | else { | ||
287 | ✗ | (*it)->type.print(os, p1, start, end); | |
288 | ✗ | return; | |
289 | } | ||
290 | } | ||
291 | } | ||
292 | } | ||
293 | |||
294 | ////////////////////////////////////////////////////////////////////// | ||
295 | ✗ | void DataType::addField (const std::string& name, const DataType& type, | |
296 | size_t offset, size_t ndims, const size_t* dims) | ||
297 | { | ||
298 | ✗ | fieldList.push_back(dims | |
299 | ✗ | ? new Field(name, type, offset, ndims, dims) | |
300 | ✗ | : new Field(name, type, offset, 1, &ndims)); | |
301 | } | ||
302 | |||
303 | ////////////////////////////////////////////////////////////////////// | ||
304 | 270 | const DataType::FieldList& DataType::getFieldList () const | |
305 | { | ||
306 | 270 | return fieldList; | |
307 | } | ||
308 | |||
309 | ////////////////////////////////////////////////////////////////////// | ||
310 | ✗ | size_t DataType::align () const | |
311 | { | ||
312 | ✗ | size_t n = 1U; | |
313 | ✗ | for (FieldList::const_iterator it = fieldList.begin(); | |
314 | ✗ | it != fieldList.end(); ++it) { | |
315 | ✗ | size_t n1 = (*it)->type.align(); | |
316 | ✗ | if (n < n1) | |
317 | ✗ | n = n1; | |
318 | } | ||
319 | |||
320 | ✗ | return n; | |
321 | 9 | } | |
322 |