GCC Code Coverage Report


Directory: ./
File: src/Variable.cpp
Date: 2024-03-27 13:09:52
Exec Total Coverage
Lines: 46 60 76.7%
Branches: 95 438 21.7%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * Copyright (C) 2015-2016 Richard Hacker (lerichi at gmx dot net)
4 *
5 * This file is part of the PdCom library.
6 *
7 * The PdCom 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 by
9 * the Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * The PdCom 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 PdCom library. If not, see <http://www.gnu.org/licenses/>.
19 *
20 *****************************************************************************/
21 #include "Variable.h"
22
23 #include "Debug.h"
24 #include "Future.h"
25 #include "Process.h"
26 #include "Selector.h"
27 #include "TemplateVodoo.inc"
28
29 #include <algorithm>
30 #include <array>
31 #include <cassert>
32 #include <numeric>
33 #include <pdcom5/Subscriber.h>
34 #include <pdcom5/Subscription.h>
35 #include <pdcom5/Variable.h>
36 #include <sstream>
37 #include <stdint.h>
38
39 namespace {
40
41 using copyFn = void (*)(void *, const void *, size_t, size_t);
42
43 template <
44 PdCom::TypeInfo::DataType dest_type,
45 PdCom::TypeInfo::DataType src_type>
46 struct DataConverter
47 {
48 using Src = typename PdCom::details::DataTypeTraits<src_type>::value_type;
49 using Dest = typename PdCom::details::DataTypeTraits<dest_type>::value_type;
50
51 static void
52 101 copyData(void *_dest, const void *_src, size_t nelem, size_t offset)
53 {
54 101 auto dest = reinterpret_cast<Dest *>(_dest);
55 101 auto src = reinterpret_cast<const Src *>(_src) + offset;
56
28/288
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 4 times.
✓ Branch 21 taken 4 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 3 times.
✓ Branch 35 taken 3 times.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✓ Branch 52 taken 21 times.
✓ Branch 53 taken 17 times.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✓ Branch 58 taken 8 times.
✓ Branch 59 taken 2 times.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✓ Branch 66 taken 5 times.
✓ Branch 67 taken 4 times.
✓ Branch 68 taken 4 times.
✓ Branch 69 taken 2 times.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✓ Branch 82 taken 2 times.
✓ Branch 83 taken 2 times.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✓ Branch 96 taken 1 times.
✓ Branch 97 taken 1 times.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✓ Branch 116 taken 12 times.
✓ Branch 117 taken 12 times.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✓ Branch 124 taken 2 times.
✓ Branch 125 taken 2 times.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
✓ Branch 130 taken 25 times.
✓ Branch 131 taken 9 times.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✗ Branch 141 not taken.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
✗ Branch 144 not taken.
✗ Branch 145 not taken.
✗ Branch 146 not taken.
✗ Branch 147 not taken.
✗ Branch 148 not taken.
✗ Branch 149 not taken.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 152 not taken.
✗ Branch 153 not taken.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✗ Branch 156 not taken.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✗ Branch 159 not taken.
✗ Branch 160 not taken.
✗ Branch 161 not taken.
✗ Branch 162 not taken.
✗ Branch 163 not taken.
✗ Branch 164 not taken.
✗ Branch 165 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 168 not taken.
✗ Branch 169 not taken.
✗ Branch 170 not taken.
✗ Branch 171 not taken.
✗ Branch 172 not taken.
✗ Branch 173 not taken.
✗ Branch 174 not taken.
✗ Branch 175 not taken.
✗ Branch 176 not taken.
✗ Branch 177 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 180 not taken.
✗ Branch 181 not taken.
✓ Branch 182 taken 20 times.
✓ Branch 183 taken 5 times.
✗ Branch 184 not taken.
✗ Branch 185 not taken.
✗ Branch 186 not taken.
✗ Branch 187 not taken.
✗ Branch 188 not taken.
✗ Branch 189 not taken.
✗ Branch 190 not taken.
✗ Branch 191 not taken.
✗ Branch 192 not taken.
✗ Branch 193 not taken.
✗ Branch 194 not taken.
✗ Branch 195 not taken.
✗ Branch 196 not taken.
✗ Branch 197 not taken.
✗ Branch 198 not taken.
✗ Branch 199 not taken.
✗ Branch 200 not taken.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✗ Branch 203 not taken.
✗ Branch 204 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✗ Branch 207 not taken.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✗ Branch 210 not taken.
✗ Branch 211 not taken.
✗ Branch 212 not taken.
✗ Branch 213 not taken.
✗ Branch 214 not taken.
✗ Branch 215 not taken.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✗ Branch 219 not taken.
✗ Branch 220 not taken.
✗ Branch 221 not taken.
✗ Branch 222 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 225 not taken.
✗ Branch 226 not taken.
✗ Branch 227 not taken.
✗ Branch 228 not taken.
✗ Branch 229 not taken.
✗ Branch 230 not taken.
✗ Branch 231 not taken.
✗ Branch 232 not taken.
✗ Branch 233 not taken.
✗ Branch 234 not taken.
✗ Branch 235 not taken.
✗ Branch 236 not taken.
✗ Branch 237 not taken.
✗ Branch 238 not taken.
✗ Branch 239 not taken.
✗ Branch 240 not taken.
✗ Branch 241 not taken.
✗ Branch 242 not taken.
✗ Branch 243 not taken.
✗ Branch 244 not taken.
✗ Branch 245 not taken.
✗ Branch 246 not taken.
✗ Branch 247 not taken.
✗ Branch 248 not taken.
✗ Branch 249 not taken.
✓ Branch 250 taken 4 times.
✓ Branch 251 taken 4 times.
✗ Branch 252 not taken.
✗ Branch 253 not taken.
✗ Branch 254 not taken.
✗ Branch 255 not taken.
✗ Branch 256 not taken.
✗ Branch 257 not taken.
✗ Branch 258 not taken.
✗ Branch 259 not taken.
✓ Branch 260 taken 34 times.
✓ Branch 261 taken 34 times.
✗ Branch 262 not taken.
✗ Branch 263 not taken.
✗ Branch 264 not taken.
✗ Branch 265 not taken.
✗ Branch 266 not taken.
✗ Branch 267 not taken.
✗ Branch 268 not taken.
✗ Branch 269 not taken.
✗ Branch 270 not taken.
✗ Branch 271 not taken.
✗ Branch 272 not taken.
✗ Branch 273 not taken.
✗ Branch 274 not taken.
✗ Branch 275 not taken.
✗ Branch 276 not taken.
✗ Branch 277 not taken.
✗ Branch 278 not taken.
✗ Branch 279 not taken.
✗ Branch 280 not taken.
✗ Branch 281 not taken.
✗ Branch 282 not taken.
✗ Branch 283 not taken.
✗ Branch 284 not taken.
✗ Branch 285 not taken.
✗ Branch 286 not taken.
✗ Branch 287 not taken.
246 for (size_t i = 0; i < nelem; ++i)
57
0/24
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 153 not taken.
✗ Branch 154 not taken.
✗ Branch 179 not taken.
✗ Branch 180 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✗ Branch 231 not taken.
✗ Branch 232 not taken.
✗ Branch 257 not taken.
✗ Branch 258 not taken.
✗ Branch 283 not taken.
✗ Branch 284 not taken.
✗ Branch 309 not taken.
✗ Branch 310 not taken.
145 dest[i] = static_cast<Dest>(src[i]);
58 101 }
59 };
60
61 template <
62 PdCom::TypeInfo::DataType dest_type,
63 PdCom::TypeInfo::DataType... src_types>
64 constexpr std::array<copyFn, sizeof...(src_types)>
65 getcopyFnRow(sequence<src_types...>)
66 {
67 return {{DataConverter<dest_type, src_types>::copyData...}};
68 }
69
70 template <PdCom::TypeInfo::DataType... dest_types>
71 constexpr std::
72 array<std::array<copyFn, sizeof...(dest_types)>, sizeof...(dest_types)>
73 getcopyFnMatrix(sequence<dest_types...> seq)
74 {
75 return {{getcopyFnRow<dest_types>(seq)...}};
76 }
77
78
79 /** Some comments on the template vodoo:
80 * DataTypeSequence will expand to a struct sequence<boolean_T, char_T, ...,
81 * double_T, single_T>. The template arguments of sequence (boolean_T, ...,
82 * single_T) can then be used to initialize (list initialization) an array by
83 * applying one function on each of these template arguments.
84 * This is used to generate the matrix row by row
85 */
86
87
88 } // namespace
89
90 101 void PdCom::details::copyData(
91 void *dst,
92 TypeInfo::DataType dst_type,
93 const void *src,
94 TypeInfo::DataType src_type,
95 size_t nelem,
96 size_t offset)
97 {
98 using PdCom::TypeInfo;
99
2/4
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✗ Branch 3 not taken.
101 if (dst_type < TypeInfo::DataTypeBegin or dst_type >= TypeInfo::DataTypeEnd
100
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 or src_type < TypeInfo::DataTypeBegin
101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 101 times.
101 or src_type >= TypeInfo::DataTypeEnd)
102 return;
103
104 static constexpr auto copyMatrix = getcopyFnMatrix(DataTypeSequence {});
105 static_assert(
106 copyMatrix.size() == DataTypeCount, "Copy Matrix size mismatch");
107 // first index: dst, second index: sr
108
109 101 copyMatrix[dst_type][src_type](dst, src, nelem, offset);
110 }
111
112 constexpr PdCom::TypeInfo PdCom::details::TypeInfoTraits<uint8_t>::type_info;
113 constexpr PdCom::TypeInfo PdCom::details::TypeInfoTraits<uint16_t>::type_info;
114 constexpr PdCom::TypeInfo PdCom::details::TypeInfoTraits<uint32_t>::type_info;
115 constexpr PdCom::TypeInfo PdCom::details::TypeInfoTraits<uint64_t>::type_info;
116 constexpr PdCom::TypeInfo PdCom::details::TypeInfoTraits<int8_t>::type_info;
117 constexpr PdCom::TypeInfo PdCom::details::TypeInfoTraits<int16_t>::type_info;
118 constexpr PdCom::TypeInfo PdCom::details::TypeInfoTraits<int32_t>::type_info;
119 constexpr PdCom::TypeInfo PdCom::details::TypeInfoTraits<int64_t>::type_info;
120 constexpr PdCom::TypeInfo PdCom::details::TypeInfoTraits<bool>::type_info;
121 constexpr PdCom::TypeInfo PdCom::details::TypeInfoTraits<float>::type_info;
122 constexpr PdCom::TypeInfo PdCom::details::TypeInfoTraits<double>::type_info;
123 constexpr PdCom::TypeInfo PdCom::details::TypeInfoTraits<char>::type_info;
124
125
126 using PdCom::Variable;
127
128 107 PdCom::SizeInfo Variable::getSizeInfo() const
129 {
130
4/4
✓ Branch 3 taken 106 times.
✓ Branch 4 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 106 times.
108 if (auto p = pimpl_.lock())
131
3/4
✓ Branch 3 taken 106 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 106 times.
212 return p->size_info;
132
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 throw EmptyVariable();
133 }
134
135 99 PdCom::TypeInfo Variable::getTypeInfo() const
136 {
137
4/4
✓ Branch 3 taken 98 times.
✓ Branch 4 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 98 times.
100 if (auto p = pimpl_.lock())
138
2/2
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 98 times.
196 return *p->type_info;
139
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 throw EmptyVariable();
140 }
141
142 2 std::string Variable::getName() const
143 {
144
4/4
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
3 if (auto p = pimpl_.lock())
145
3/4
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
2 return p->getName();
146
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 throw EmptyVariable();
147 }
148
149 55 std::string Variable::getPath() const
150 {
151
4/4
✓ Branch 3 taken 53 times.
✓ Branch 4 taken 2 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 53 times.
57 if (auto p = pimpl_.lock())
152
3/4
✓ Branch 5 taken 53 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 53 times.
106 return p->getPath();
153
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 throw EmptyVariable();
154 }
155
156 21 Variable::SetValueFuture Variable::setValue(
157 const void *data,
158 PdCom::TypeInfo::DataType t,
159 size_t count,
160 const PdCom::Selector &selector) const
161 {
162
4/4
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 5 times.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 15 times.
27 if (auto p = pimpl_.lock()) {
163
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
16 if (selector.impl_)
164 return selector.impl_->applySetValue(*p, data, t, count);
165
4/4
✓ Branch 6 taken 15 times.
✓ Branch 7 taken 1 times.
✓ Branch 12 taken 5 times.
✓ Branch 13 taken 15 times.
17 return PdCom::impl::Selector().applySetValue(*p, data, t, count);
166 }
167
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 throw EmptyVariable();
168 }
169
170 Variable::SetValueFuture Variable::setValue(
171 const void *src,
172 PdCom::TypeInfo::DataType src_type,
173 size_t count,
174 size_t offset) const
175 {
176 if (auto p = pimpl_.lock()) {
177 return p->setValue(src, src_type, offset, count);
178 }
179 throw EmptyVariable();
180 }
181
182 1 std::string Variable::getAlias() const
183 {
184
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 if (auto p = pimpl_.lock())
185 return p->getAlias();
186
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 throw EmptyVariable();
187 }
188
189 2 int Variable::getTaskId() const
190 {
191
4/4
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
3 if (auto p = pimpl_.lock())
192
3/4
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
2 return p->getTaskId();
193
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 throw EmptyVariable();
194 }
195
196 1 bool Variable::isWriteable() const
197 {
198
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
1 if (auto p = pimpl_.lock())
199
2/4
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
2 return p->isWriteable();
200 throw EmptyVariable();
201 }
202
203 std::chrono::duration<double> Variable::getSampleTime() const
204 {
205 if (auto p = pimpl_.lock())
206 return p->getSampleTime();
207 throw EmptyVariable();
208 }
209
210 1 PdCom::Process *Variable::getProcess() const
211 {
212
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
1 if (auto p = pimpl_.lock()) {
213
2/4
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
1 if (const auto process = p->process.lock()) {
214
1/2
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
2 return process->This;
215 }
216 throw ProcessGoneAway();
217 }
218 throw EmptyVariable();
219 }
220
221 template class PdCom::Future<
222 PdCom::Exception const &,
223 PdCom::VariablePollResult,
224 std::chrono::nanoseconds>;
225
226 template class PdCom::Future<PdCom::Exception const &>;
227
228 using PdCom::details::is_contiguous;
229 static_assert(
230 is_contiguous<std::vector<int>>::value,
231 "vector<int> is contiguous");
232 static_assert(
233 !is_contiguous<std::vector<bool>>::value,
234 "vector<bool> is not contiguous");
235 static_assert(
236 is_contiguous<std::array<int, 5>>::value,
237 "array<int> is contiguous");
238 static_assert(is_contiguous<std::string>::value, "string is contiguous");
239