GCC Code Coverage Report


Directory: ./
File: pdserv/src/DataType.h
Date: 2025-08-17 04:10:43
Exec Total Coverage
Lines: 23 41 56.1%
Branches: 26 48 54.2%

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 #ifndef DATATYPE_H
23 #define DATATYPE_H
24
25 #include "Debug.h"
26
27 #include <list>
28 #include <stdint.h>
29 #include <vector>
30 #include <string>
31 #include <ostream>
32
33 namespace PdServ {
34
35 class DataType {
36 public:
37 15744 struct DimType: public std::vector<size_t> {
38 DimType(size_t ndims, const size_t *dim);
39 const size_t nelem;
40
41 4852 bool isScalar() const {
42 4852 return nelem == 1;
43 }
44
45 66 bool isVector() const {
46 66 return size() == 1;
47 }
48
49 bool isMultiDim() const {
50 return size() > 1;
51 }
52
53 };
54
55 struct Field {
56 Field(const std::string& name, const DataType& type,
57 size_t offset, size_t ndims, const size_t *dims);
58 const std::string name;
59 const DataType& type;
60 const size_t offset;
61 const DimType dim;
62 };
63
64 enum Primary {
65 compound_T = 0,
66 boolean_T,
67 uint8_T, int8_T,
68 uint16_T, int16_T,
69 uint32_T, int32_T,
70 uint64_T, int64_T,
71 double_T, single_T
72 };
73
74 DataType( const std::string& name, size_t size);
75 virtual ~DataType();
76
77 const std::string name;
78 const size_t size;
79 virtual Primary primary() const;
80 bool isPrimary() const;
81 static const size_t maxWidth = 8; /**< Maximum supported data type
82 size in bytes */
83
84 virtual size_t align() const;
85
86 void addField(const std::string& name,
87 const DataType& type,
88 size_t offset,
89 size_t ndims = 1,
90 const size_t* dims = 0);
91
92 66 struct FieldList: public std::list<const Field*> {
93 friend std::ostream& operator<<(std::ostream& os,
94 const FieldList& fieldList);
95 };
96 const FieldList& getFieldList() const;
97
98 bool operator==(const DataType& other) const;
99 bool operator!=(const DataType& other) const;
100 void (* const setValue)(char *&, double);
101
102 static const DataType& boolean;
103 static const DataType& uint8;
104 static const DataType& int8;
105 static const DataType& uint16;
106 static const DataType& int16;
107 static const DataType& uint32;
108 static const DataType& int32;
109 static const DataType& uint64;
110 static const DataType& int64;
111 static const DataType& float64;
112 static const DataType& float32;
113
114 virtual void print(std::ostream& os, const char *data,
115 const char* start, const char* end) const;
116
117 struct Printer {
118 Printer(const DataType* dt, const char *addr, size_t nelem):
119 type(dt), addr(addr), size(nelem * dt->size) {
120 }
121
122 friend std::ostream& operator<<(std::ostream& os,
123 const Printer& obj) {
124 obj.type->print(os, obj.addr, obj.addr,
125 obj.addr + obj.size);
126 return os;
127 }
128
129 const DataType* const type;
130 const char * const addr;
131 const size_t size;
132 };
133
134 Printer operator()(const void *addr, size_t n = 1) const {
135 return Printer(this, reinterpret_cast<const char*>(addr), n);
136 }
137
138 ////////////// Iterator to walk through the DataType
139 // Requires a class with the following members:
140 // bool newVariable(
141 // const PdServ::DataType& dtype,
142 // const PdServ::DataType::DimType& dim,
143 // size_t dimIdx, size_t elemIdx, size_t offset) const;
144 // void newDimension(
145 // const PdServ::DataType& dtype,
146 // const PdServ::DataType::DimType& dim,
147 // size_t dimIdx, size_t elemIdx,
148 // CreateChannels& c, size_t offset);
149 // void newField(const PdServ::DataType::Field *field,
150 // CreateChannels& c, size_t offset);
151
152 template <class C>
153 struct Iterator {
154 Iterator(const DataType& dtype,
155 const DimType& dim, const C& c);
156
157 void dispatch(
158 const DataType& dtype, size_t dtypeSize,
159 const DimType& dim, size_t dimIdx,
160 size_t elemIdx, C c, size_t offset);
161
162 void iterateDims(
163 const DataType& dtype, size_t dtypeSize,
164 const DimType& dim,
165 size_t dimIdx, size_t elemIdx, C& c, size_t offset);
166
167 void iterateFields(const FieldList& fieldList,
168 C& c, size_t offset);
169 };
170
171
172 protected:
173 DataType(const DataType& other);
174 explicit DataType(size_t size, void (*)(char *&dst, double src));
175
176 private:
177
178 FieldList fieldList;
179 };
180
181 /////////////////////////////////////////////////////////////////////////////
182 template <class C>
183 1848 DataType::Iterator<C>::Iterator(const DataType& dtype,
184 const DataType::DimType& dim, const C& c)
185 {
186
2/4
✓ Branch 8 taken 924 times.
✗ Branch 9 not taken.
✓ Branch 24 taken 924 times.
✗ Branch 25 not taken.
1848 dispatch(dtype, dtype.size * dim.nelem, dim, 0, 0, c, 0);
187 1848 }
188
189
190 /////////////////////////////////////////////////////////////////////////////
191 template <class C>
192 4312 void DataType::Iterator<C>::dispatch(
193 const DataType& dtype, size_t dtypeSize, const DimType& dim,
194 size_t dimIdx, size_t elemIdx, C c, size_t offset)
195 {
196
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 2772 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1540 times.
4312 if (c.newVariable(dtype,dim,dimIdx,elemIdx,offset))
197 return;
198
199
12/12
✓ Branch 2 taken 2156 times.
✓ Branch 3 taken 616 times.
✓ Branch 6 taken 616 times.
✓ Branch 7 taken 1540 times.
✓ Branch 8 taken 616 times.
✓ Branch 9 taken 2156 times.
✓ Branch 12 taken 770 times.
✓ Branch 13 taken 770 times.
✓ Branch 16 taken 154 times.
✓ Branch 17 taken 616 times.
✓ Branch 18 taken 154 times.
✓ Branch 19 taken 1386 times.
4312 if (!dim.isScalar() and dimIdx != dim.size())
200 770 iterateDims(dtype, dtypeSize, dim, dimIdx, elemIdx, c, offset);
201
2/4
✗ Branch 4 not taken.
✓ Branch 5 taken 2156 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1386 times.
3542 else if (!dtype.isPrimary())
202 iterateFields(dtype.getFieldList(), c, offset);
203 }
204
205 /////////////////////////////////////////////////////////////////////////////
206 template <class C>
207 770 void DataType::Iterator<C>::iterateDims(
208 const DataType& dtype, size_t dtypeSize, const DimType& dim,
209 size_t dimIdx, size_t /*elemIdx*/, C& c, size_t offset)
210 {
211 770 size_t end = dim[dimIdx];
212
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 616 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 154 times.
770 dtypeSize /= dim[dimIdx];
213 770 ++dimIdx;
214
4/4
✓ Branch 0 taken 1848 times.
✓ Branch 1 taken 616 times.
✓ Branch 2 taken 616 times.
✓ Branch 3 taken 154 times.
3234 for (size_t i = 0; i < end; ++i) {
215 2464 c.newDimension(dtype, dim, dimIdx, i, c, offset);
216
2/4
✓ Branch 5 taken 1848 times.
✗ Branch 6 not taken.
✓ Branch 18 taken 616 times.
✗ Branch 19 not taken.
2464 dispatch(dtype, dtypeSize, dim, dimIdx, i, c, offset);
217 2464 offset += dtypeSize;
218 }
219 770 }
220
221 /////////////////////////////////////////////////////////////////////////////
222 template <class C>
223 void DataType::Iterator<C>::iterateFields(
224 const FieldList& fieldList, C& c, size_t offset)
225 {
226 for (FieldList::const_iterator it = fieldList.begin();
227 it != fieldList.end(); ++it) {
228 const Field *field = *it;
229 c.newField(field, c, offset + field->offset);
230 dispatch(field->type, field->type.size, field->dim,
231 0, 0, c, offset + field->offset);
232 }
233 }
234
235 };
236
237 #endif //DATATYPE_H
238