Directory: | ./ |
---|---|
File: | pdserv-1.1.0/src/DataType.cpp |
Date: | 2024-11-17 04:08:36 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 28 | 108 | 25.9% |
Branches: | 3 | 112 | 2.7% |
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 <ostream> | ||
28 | #include <functional> // std::multiplies | ||
29 | #include <numeric> // std::accumulate | ||
30 | |||
31 | |||
32 | using namespace PdServ; | ||
33 | |||
34 | template <class T> | ||
35 | struct TypeNum {}; | ||
36 | |||
37 | template <> | ||
38 | struct TypeNum<bool> { | ||
39 | static const DataType::Primary value = DataType::boolean_T; | ||
40 | static const size_t align = sizeof(bool); | ||
41 | }; | ||
42 | |||
43 | template <> | ||
44 | struct TypeNum<uint8_t> { | ||
45 | static const DataType::Primary value = DataType::uint8_T; | ||
46 | static const size_t align = sizeof(uint8_t); | ||
47 | }; | ||
48 | |||
49 | template <> | ||
50 | struct TypeNum<int8_t> { | ||
51 | static const DataType::Primary value = DataType::int8_T; | ||
52 | static const size_t align = sizeof(int8_t); | ||
53 | }; | ||
54 | |||
55 | template <> | ||
56 | struct TypeNum<uint16_t> { | ||
57 | static const DataType::Primary value = DataType::uint16_T; | ||
58 | static const size_t align = sizeof(uint16_t); | ||
59 | }; | ||
60 | |||
61 | template <> | ||
62 | struct TypeNum<int16_t> { | ||
63 | static const DataType::Primary value = DataType::int16_T; | ||
64 | static const size_t align = sizeof(int16_t); | ||
65 | }; | ||
66 | |||
67 | template <> | ||
68 | struct TypeNum<uint32_t> { | ||
69 | static const DataType::Primary value = DataType::uint32_T; | ||
70 | static const size_t align = sizeof(uint32_t); | ||
71 | }; | ||
72 | |||
73 | template <> | ||
74 | struct TypeNum<int32_t> { | ||
75 | static const DataType::Primary value = DataType::int32_T; | ||
76 | static const size_t align = sizeof(int32_t); | ||
77 | }; | ||
78 | |||
79 | template <> | ||
80 | struct TypeNum<uint64_t> { | ||
81 | static const DataType::Primary value = DataType::uint64_T; | ||
82 | static const size_t align = sizeof(uint64_t); | ||
83 | }; | ||
84 | |||
85 | template <> | ||
86 | struct TypeNum<int64_t> { | ||
87 | static const DataType::Primary value = DataType::int64_T; | ||
88 | static const size_t align = sizeof(int64_t); | ||
89 | }; | ||
90 | |||
91 | template <> | ||
92 | struct TypeNum<double> { | ||
93 | static const DataType::Primary value = DataType::double_T; | ||
94 | static const size_t align = sizeof(double); | ||
95 | }; | ||
96 | |||
97 | template <> | ||
98 | struct TypeNum<float> { | ||
99 | static const DataType::Primary value = DataType::single_T; | ||
100 | static const size_t align = sizeof(float); | ||
101 | }; | ||
102 | |||
103 | //////////////////////////////////////////////////////////////////////////// | ||
104 | //////////////////////////////////////////////////////////////////////////// | ||
105 | namespace { | ||
106 | template <class T> | ||
107 | 11 | class PrimaryType: public DataType { | |
108 | public: | ||
109 | 11 | PrimaryType(): DataType(sizeof(T), setValue) { | |
110 | 11 | } | |
111 | |||
112 | private: | ||
113 | ✗ | void print(std::ostream& os, const char *data, | |
114 | const char* start, const char *end) const { | ||
115 | ✗ | const T* val = reinterpret_cast<const T*>(data); | |
116 | ✗ | const T* lastVal = reinterpret_cast<const T*>(end); | |
117 | ✗ | char delim = 0; | |
118 | |||
119 | ✗ | for (;val < lastVal; val++) { | |
120 | ✗ | if ((const char*)val < start) | |
121 | ✗ | continue; | |
122 | |||
123 | ✗ | if (delim) | |
124 | ✗ | os << delim; | |
125 | ✗ | delim = ','; | |
126 | |||
127 | ✗ | os << *val; | |
128 | } | ||
129 | } | ||
130 | |||
131 | ✗ | DataType::Primary primary() const { | |
132 | ✗ | return TypeNum<T>::value; | |
133 | } | ||
134 | |||
135 | 244 | size_t align () const { | |
136 | 244 | return TypeNum<T>::align; | |
137 | } | ||
138 | |||
139 | ✗ | static void setValue(char *&dst, double src) { | |
140 | ✗ | *reinterpret_cast<T*>(dst) = static_cast<T>(src); | |
141 | ✗ | dst += sizeof(T); | |
142 | } | ||
143 | }; | ||
144 | |||
145 | template<> | ||
146 | ✗ | void PrimaryType<int8_t>::print(std::ostream& os, const char *data, | |
147 | const char* start, const char *end) const { | ||
148 | ✗ | const int8_t* val = reinterpret_cast<const int8_t*>(data); | |
149 | ✗ | const int8_t* lastVal = reinterpret_cast<const int8_t*>(end); | |
150 | ✗ | char delim = 0; | |
151 | |||
152 | ✗ | for (;val < lastVal; val++) { | |
153 | ✗ | if ((const char*)val < start) | |
154 | ✗ | continue; | |
155 | |||
156 | ✗ | if (delim) | |
157 | ✗ | os << delim; | |
158 | ✗ | delim = ','; | |
159 | |||
160 | ✗ | os << (int)*val; | |
161 | } | ||
162 | } | ||
163 | |||
164 | template<> | ||
165 | ✗ | void PrimaryType<uint8_t>::print(std::ostream& os, const char *data, | |
166 | const char* start, const char *end) const { | ||
167 | ✗ | const uint8_t* val = reinterpret_cast<const uint8_t*>(data); | |
168 | ✗ | const uint8_t* lastVal = reinterpret_cast<const uint8_t*>(end); | |
169 | ✗ | char delim = 0; | |
170 | |||
171 | ✗ | for (;val < lastVal; val++) { | |
172 | ✗ | if ((const char*)val < start) | |
173 | ✗ | continue; | |
174 | |||
175 | ✗ | if (delim) | |
176 | ✗ | os << delim; | |
177 | ✗ | delim = ','; | |
178 | |||
179 | ✗ | os << (unsigned)*val; | |
180 | } | ||
181 | } | ||
182 | } | ||
183 | |||
184 | ////////////////////////////////////////////////////////////////////// | ||
185 | ////////////////////////////////////////////////////////////////////// | ||
186 | 1 | const DataType& DataType::boolean = PrimaryType< bool>(); | |
187 | 1 | const DataType& DataType:: uint8 = PrimaryType< uint8_t>(); | |
188 | 1 | const DataType& DataType:: int8 = PrimaryType< int8_t>(); | |
189 | 1 | const DataType& DataType:: uint16 = PrimaryType<uint16_t>(); | |
190 | 1 | const DataType& DataType:: int16 = PrimaryType< int16_t>(); | |
191 | 1 | const DataType& DataType:: uint32 = PrimaryType<uint32_t>(); | |
192 | 1 | const DataType& DataType:: int32 = PrimaryType< int32_t>(); | |
193 | 1 | const DataType& DataType:: uint64 = PrimaryType<uint64_t>(); | |
194 | 1 | const DataType& DataType:: int64 = PrimaryType< int64_t>(); | |
195 | 1 | const DataType& DataType::float64 = PrimaryType< double>(); | |
196 | 1 | const DataType& DataType::float32 = PrimaryType< float>(); | |
197 | |||
198 | ////////////////////////////////////////////////////////////////////// | ||
199 | ////////////////////////////////////////////////////////////////////// | ||
200 | 120 | DataType::DimType::DimType (size_t ndims, const size_t *dim): | |
201 | 120 | std::vector<size_t>(dim, dim + ndims), | |
202 | // std::vector<size_t>(dim ? dim : &ndims, dim ? dim + ndims : &ndims + 1), | ||
203 |
2/4✓ Branch 4 taken 120 times.
✗ Branch 5 not taken.
✓ Branch 14 taken 120 times.
✗ Branch 15 not taken.
|
240 | nelem(std::accumulate(begin(), end(), 1U, std::multiplies<size_t>())) |
204 | { | ||
205 | 120 | } | |
206 | |||
207 | ////////////////////////////////////////////////////////////////////// | ||
208 | ////////////////////////////////////////////////////////////////////// | ||
209 | ✗ | DataType::Field::Field (const std::string& name, const DataType& type, | |
210 | ✗ | size_t offset, size_t ndims, const size_t *dims): | |
211 | ✗ | name(name), type(type), offset(offset), dim(ndims, dims) | |
212 | { | ||
213 | } | ||
214 | |||
215 | ////////////////////////////////////////////////////////////////////// | ||
216 | ////////////////////////////////////////////////////////////////////// | ||
217 | ✗ | DataType::DataType (const std::string& name, size_t size): | |
218 | ✗ | name(name), size(size), setValue(0) | |
219 | { | ||
220 | } | ||
221 | |||
222 | ////////////////////////////////////////////////////////////////////// | ||
223 | ✗ | DataType::DataType (const DataType& other): | |
224 | ✗ | name(other.name), size(other.size), setValue(other.setValue) | |
225 | { | ||
226 | } | ||
227 | |||
228 | ////////////////////////////////////////////////////////////////////// | ||
229 | 11 | DataType::DataType (size_t size, void (*setValue)(char *&, double )): | |
230 | 11 | size(size), setValue(setValue) | |
231 | { | ||
232 | 11 | } | |
233 | |||
234 | ////////////////////////////////////////////////////////////////////// | ||
235 | 22 | DataType::~DataType () | |
236 | { | ||
237 | 11 | for (FieldList::const_iterator it = fieldList.begin(); | |
238 |
1/2✗ Branch 6 not taken.
✓ Branch 7 taken 11 times.
|
11 | it != fieldList.end(); ++it) |
239 | ✗ | delete *it; | |
240 | 11 | } | |
241 | |||
242 | ////////////////////////////////////////////////////////////////////// | ||
243 | ✗ | bool DataType::isPrimary () const | |
244 | { | ||
245 | ✗ | return primary() != compound_T; | |
246 | } | ||
247 | |||
248 | ////////////////////////////////////////////////////////////////////// | ||
249 | ✗ | DataType::Primary DataType::primary () const | |
250 | { | ||
251 | ✗ | return compound_T; | |
252 | } | ||
253 | |||
254 | ////////////////////////////////////////////////////////////////////// | ||
255 | ✗ | void DataType::print(std::ostream& os, | |
256 | const char *data, const char *start, const char *end) const | ||
257 | { | ||
258 | ✗ | char delim = 0; | |
259 | |||
260 | ✗ | for (; data < end; data += this->size) { | |
261 | ✗ | for (FieldList::const_iterator it = fieldList.begin(); | |
262 | ✗ | it != fieldList.end(); ++it) { | |
263 | |||
264 | ✗ | const char *p1 = data + (*it)->offset; | |
265 | ✗ | if (p1 < start) | |
266 | ✗ | continue; | |
267 | |||
268 | ✗ | if (delim) | |
269 | ✗ | os << delim; | |
270 | ✗ | delim = ','; | |
271 | |||
272 | ✗ | const char *p2 = p1 + (*it)->dim.nelem * (*it)->type.size; | |
273 | ✗ | if (p2 < end) | |
274 | ✗ | (*it)->type.print(os, p1, start, p2); | |
275 | else { | ||
276 | ✗ | (*it)->type.print(os, p1, start, end); | |
277 | ✗ | return; | |
278 | } | ||
279 | } | ||
280 | } | ||
281 | } | ||
282 | |||
283 | ////////////////////////////////////////////////////////////////////// | ||
284 | ✗ | void DataType::addField (const std::string& name, const DataType& type, | |
285 | size_t offset, size_t ndims, const size_t* dims) | ||
286 | { | ||
287 | ✗ | fieldList.push_back(dims | |
288 | ✗ | ? new Field(name, type, offset, ndims, dims) | |
289 | ✗ | : new Field(name, type, offset, 1, &ndims)); | |
290 | } | ||
291 | |||
292 | ////////////////////////////////////////////////////////////////////// | ||
293 | ✗ | const DataType::FieldList& DataType::getFieldList () const | |
294 | { | ||
295 | ✗ | return fieldList; | |
296 | } | ||
297 | |||
298 | ////////////////////////////////////////////////////////////////////// | ||
299 | ✗ | size_t DataType::align () const | |
300 | { | ||
301 | ✗ | size_t n = 1U; | |
302 | ✗ | for (FieldList::const_iterator it = fieldList.begin(); | |
303 | ✗ | it != fieldList.end(); ++it) { | |
304 | ✗ | size_t n1 = (*it)->type.align(); | |
305 | ✗ | if (n < n1) | |
306 | ✗ | n = n1; | |
307 | } | ||
308 | |||
309 | ✗ | return n; | |
310 | 3 | } | |
311 |