GCC Code Coverage Report


Directory: ./
File: pdserv/src/DataType.cpp
Date: 2025-08-17 04:10:43
Exec Total Coverage
Lines: 47 113 41.6%
Branches: 21 112 18.8%

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