GCC Code Coverage Report


Directory: ./
File: pdserv/src/DataType.cpp
Date: 2024-12-29 04:08:32
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