GCC Code Coverage Report


Directory: ./
File: pdserv/src/DataType.h
Date: 2024-12-15 04:08:34
Exec Total Coverage
Lines: 23 41 56.1%
Branches: 26 48 54.2%

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