ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
DataDescriptor.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
4#include "DataDescriptor.h"
5namespace ChimeraTK {
6
7 /********************************************************************************************************************/
8
9 DataDescriptor::DataDescriptor(FundamentalType fundamentalType_, bool isIntegral_, bool isSigned_, size_t nDigits_,
10 size_t nFractionalDigits_, DataType rawDataType_, DataType transportLayerDataType_)
11 : _fundamentalType(fundamentalType_), _rawDataType(rawDataType_), _transportLayerDataType(transportLayerDataType_),
12 _isIntegral(isIntegral_), _isSigned(isSigned_), _nDigits(nDigits_), _nFractionalDigits(nFractionalDigits_) {}
13
14 /********************************************************************************************************************/
15
17 if(type.isNumeric()) {
18 _fundamentalType = FundamentalType::numeric;
19 }
20 else {
21 _fundamentalType = FundamentalType::string;
22 }
23 _isIntegral = type.isIntegral();
24 _isSigned = type.isSigned();
25
26 // the defaults
27 _nDigits = 0; // invalid for non handled types
28 _nFractionalDigits = 0; // 0 for integers
29
30 if(type == DataType::int8) { // 8 bit signed
31 _nDigits = 4; // -127 .. 128
32 }
33 else if(type == DataType::uint8) { // 8 bit unsigned
34 _nDigits = 3; // 0..256
35 }
36 else if(type == DataType::int16) { // 16 bit signed
37 _nDigits = 6; // -32000 .. 32000 (approx)
38 }
39 else if(type == DataType::uint16) { // 16 bit unsigned
40 _nDigits = 5; // 0 .. 65000 (approx)
41 }
42 else if(type == DataType::int32) { // 32 bit signed
43 _nDigits = 11; // -2e9 .. 2e9 (approx)
44 }
45 else if(type == DataType::uint32) { // 32 bit unsigned
46 _nDigits = 10; // 0 .. 4e9 (approx)
47 }
48 else if(type == DataType::int64) { // 64 bit signed // NOLINT(bugprone-branch-clone)
49 _nDigits = 20; // -9e18 .. 9e18 (approx)
50 }
51 else if(type == DataType::uint64) { // 64 bit unsigned
52 _nDigits = 20; // 0 .. 2e19 (approx)
53 }
54 else if(type == DataType::float32) { // 32 bit float IEEE 754
55 _nDigits = 3 + 45; // todo. fix comments. see RegisterInfoMap::RegisterInfo::RegisterInfo
56 _nFractionalDigits = 45;
57 }
58 else if(type == DataType::float64) { // 64 bit float IEEE 754
59 _nDigits = 3 + 325; // todo. fix comments. see RegisterInfoMap::RegisterInfo::RegisterInfo
60 _nFractionalDigits = 325;
61 }
62 else if(type == DataType::Boolean) {
63 _fundamentalType = FundamentalType::boolean;
64 }
65 else if(type == DataType::Void) {
66 _fundamentalType = FundamentalType::nodata;
67 }
68 }
69
70 /********************************************************************************************************************/
71
73 : _fundamentalType(FundamentalType::undefined), _isIntegral(false), _isSigned(false), _nDigits(0),
74 _nFractionalDigits(0) {}
75
76 /********************************************************************************************************************/
77
79 return _fundamentalType;
80 }
81
82 /********************************************************************************************************************/
83
85 assert(_fundamentalType == FundamentalType::numeric);
86 return _isSigned;
87 }
88
89 /********************************************************************************************************************/
90
92 assert(_fundamentalType == FundamentalType::numeric);
93 return _isIntegral;
94 }
95
96 /********************************************************************************************************************/
97
98 size_t DataDescriptor::nDigits() const {
99 assert(_fundamentalType == FundamentalType::numeric);
100 return _nDigits;
101 }
102
103 /********************************************************************************************************************/
104
106 assert(_fundamentalType == FundamentalType::numeric && !_isIntegral);
107 return _nFractionalDigits;
108 }
109
110 /********************************************************************************************************************/
111
113 return _rawDataType;
114 }
115
117 _rawDataType = d;
118 }
119
120 /********************************************************************************************************************/
121
123 return _transportLayerDataType;
124 }
125
126 /********************************************************************************************************************/
127
129 return _fundamentalType == other._fundamentalType && _rawDataType == other._rawDataType &&
130 _transportLayerDataType == other._transportLayerDataType && _isIntegral == other._isIntegral &&
131 _isSigned == other._isSigned && _nDigits == other._nDigits && _nFractionalDigits == other._nFractionalDigits;
132 }
133
134 /********************************************************************************************************************/
135
137 return !operator==(other);
138 }
139
140 /********************************************************************************************************************/
141
144 if(isIntegral()) {
145 if(isSigned()) {
146 if(nDigits() > 11) {
147 return typeid(int64_t);
148 }
149 if(nDigits() > 6) {
150 return typeid(int32_t);
151 }
152 if(nDigits() > 4) {
153 return typeid(int16_t);
154 }
155 return typeid(int8_t);
156 }
157 if(nDigits() > 10) {
158 return typeid(uint64_t);
159 }
160 if(nDigits() > 5) {
161 return typeid(uint32_t);
162 }
163 if(nDigits() > 3) {
164 return typeid(uint16_t);
165 }
166 return typeid(uint8_t);
167 }
168 // fractional:
169 // Maximum number of decimal digits to display a float without loss in non-exponential display, including
170 // sign, leading 0, decimal dot and one extra digit to avoid rounding issues (hence the +4).
171 // This computation matches the one performed in the NumericAddressedBackend catalogue.
172 size_t floatMaxDigits = 4 +
173 size_t(std::max(
174 std::log10(std::numeric_limits<float>::max()), -std::log10(std::numeric_limits<float>::denorm_min())));
175 if(nDigits() > floatMaxDigits) {
176 return typeid(double);
177 }
178 return typeid(float);
179 }
181 return typeid(ChimeraTK::Boolean);
182 }
184 return typeid(std::string);
185 }
187 return typeid(ChimeraTK::Void);
188 }
189 return {};
190 }
191
192 /********************************************************************************************************************/
193 /********************************************************************************************************************/
194
195 std::ostream& operator<<(std::ostream& stream, const DataDescriptor::FundamentalType& fundamentalType) {
196 if(fundamentalType == DataDescriptor::FundamentalType::nodata) {
197 stream << "nodata";
198 }
199 else if(fundamentalType == DataDescriptor::FundamentalType::boolean) {
200 stream << "boolean";
201 }
202 else if(fundamentalType == DataDescriptor::FundamentalType::numeric) {
203 stream << "numeric";
204 }
205 else if(fundamentalType == DataDescriptor::FundamentalType::string) {
206 stream << "string";
207 }
208 else if(fundamentalType == DataDescriptor::FundamentalType::undefined) {
209 stream << "undefined";
210 }
211 return stream;
212 }
213 /********************************************************************************************************************/
214
215} // namespace ChimeraTK
Wrapper Class to avoid vector<bool> problems.
Class describing the actual payload data format of a register in an abstract manner.
size_t nFractionalDigits() const
Approximate maximum number of digits after decimal dot (of base 10) needed to represent the value (ex...
FundamentalType fundamentalType() const
Get the fundamental data type.
bool isIntegral() const
Return whether the data is integral or not (e.g.
DataType transportLayerDataType() const
Get the data type on the transport layer.
DataDescriptor()
Default constructor sets fundamental type to "undefined".
DataType minimumDataType() const
Get the minimum data type required to represent the described data type in the host CPU.
void setRawDataType(const DataType &d)
Set the raw data type.
bool operator!=(const DataDescriptor &other) const
bool operator==(const DataDescriptor &other) const
size_t nDigits() const
Return the approximate maximum number of digits (of base 10) needed to represent the value (including...
DataType rawDataType() const
Get the raw data type.
bool isSigned() const
Return whether the data is signed or not.
FundamentalType
Enum for the fundamental data types.
A class to describe which of the supported data types is used.
@ uint32
Unsigned 32 bit integer.
@ int16
Signed 16 bit integer.
@ int32
Signed 32 bit integer.
@ int64
Signed 64 bit integer.
@ float32
Single precision float.
@ uint16
Unsigned 16 bit integer.
@ uint64
Unsigned 64 bit integer.
@ uint8
Unsigned 8 bit integer.
@ float64
Double precision float.
@ int8
Signed 8 bit integer.
bool isNumeric() const
Returns whether the data type is numeric.
bool isIntegral() const
Return whether the raw data type is an integer.
bool isSigned() const
Return whether the raw data type is signed.
Wrapper Class for void.
std::ostream & operator<<(std::ostream &stream, const DataDescriptor::FundamentalType &fundamentalType)