cc_tools_qt
Common Environment for Protocol Analysis.
Loading...
Searching...
No Matches
FieldWrapperCreator.h
1//
2// Copyright 2016 - 2024 (C). Alex Robenko. All rights reserved.
3//
4
5// This file is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18#pragma once
19
20
21#include <memory>
22
23#include "comms/comms.h"
24
25#include "cc_tools_qt/field_wrapper/IntValueWrapper.h"
26#include "cc_tools_qt/field_wrapper/UnsignedLongValueWrapper.h"
27#include "cc_tools_qt/field_wrapper/BitmaskValueWrapper.h"
28#include "cc_tools_qt/field_wrapper/EnumValueWrapper.h"
29#include "cc_tools_qt/field_wrapper/StringWrapper.h"
30#include "cc_tools_qt/field_wrapper/BitfieldWrapper.h"
31#include "cc_tools_qt/field_wrapper/OptionalWrapper.h"
32#include "cc_tools_qt/field_wrapper/BundleWrapper.h"
33#include "cc_tools_qt/field_wrapper/ArrayListRawDataWrapper.h"
34#include "cc_tools_qt/field_wrapper/ArrayListWrapper.h"
35#include "cc_tools_qt/field_wrapper/FloatValueWrapper.h"
36#include "cc_tools_qt/field_wrapper/VariantWrapper.h"
37#include "cc_tools_qt/field_wrapper/UnknownValueWrapper.h"
38#include "ret_unique_ptr.h"
39
40namespace cc_tools_qt
41{
42
43namespace details
44{
45
46class FieldWrapperCreator
47{
48public:
49 typedef cc_tools_qt::field_wrapper::FieldWrapperPtr FieldWrapperPtr;
50
51 template <typename TField>
52 static FieldWrapperPtr createWrapper(TField& field)
53 {
54 typedef typename std::decay<decltype(field)>::type DecayedField;
55 typedef typename DecayedField::CommsTag Tag;
56 return createWrapperInternal(field, Tag());
57 }
58private:
59 typedef comms::field::tag::Int IntValueTag;
60 typedef comms::field::tag::Bitmask BitmaskValueTag;
61 typedef comms::field::tag::Enum EnumValueTag;
62 typedef comms::field::tag::String StringTag;
63 typedef comms::field::tag::Bitfield BitfieldTag;
64 typedef comms::field::tag::Optional OptionalTag;
65 typedef comms::field::tag::Bundle BundleTag;
66 typedef comms::field::tag::RawArrayList RawDataArrayListTag;
67 typedef comms::field::tag::ArrayList FieldsArrayListTag;
68 typedef comms::field::tag::Float FloatValueTag;
69 typedef comms::field::tag::Variant VariantTag;
70
71 struct RegularIntTag {};
72 struct BigUnsignedTag {};
73
74 class SubfieldsCreateHelper
75 {
76 public:
77 typedef std::function <void (FieldWrapperPtr)> WrapperDispatchFunc;
78 SubfieldsCreateHelper(WrapperDispatchFunc&& dispatchOp)
79 : m_dispatchOp(std::move(dispatchOp))
80 {
81 }
82
83 template <typename TField>
84 void operator()(TField&& field)
85 {
86 auto fieldWidget =
87 FieldWrapperCreator::createWrapper(std::forward<TField>(field));
88 m_dispatchOp(std::move(fieldWidget));
89 }
90
91 template <std::size_t TIdx, typename TField>
92 void operator()(TField&& field)
93 {
94 return operator()(field);
95 }
96
97 private:
98 WrapperDispatchFunc m_dispatchOp;
99 };
100
101
102 template <typename TField>
103 static FieldWrapperPtr createWrapperInternal(TField& field, IntValueTag)
104 {
105 typedef typename std::decay<decltype(field)>::type FieldType;
106 typedef typename FieldType::ValueType ValueType;
107
108 static_assert(std::is_integral<ValueType>::value,
109 "ValueType is expected to be integral");
110
111 using Tag = typename std::conditional<
112 std::is_signed<ValueType>::value || (sizeof(ValueType) < sizeof(std::uint64_t)),
113 RegularIntTag,
114 BigUnsignedTag
115 >::type;
116
117 return createWrapperInternal(field, Tag());
118 }
119
120 template <typename TField>
121 static FieldWrapperPtr createWrapperInternal(TField& field, RegularIntTag)
122 {
123 return field_wrapper::makeIntValueWrapper(field);
124 }
125
126 template <typename TField>
127 static FieldWrapperPtr createWrapperInternal(TField& field, BigUnsignedTag)
128 {
129 return field_wrapper::makeUnsignedLongValueWrapper(field);
130 }
131
132 template <typename TField>
133 static FieldWrapperPtr createWrapperInternal(TField& field, BitmaskValueTag)
134 {
135 return field_wrapper::makeBitmaskValueWrapper(field);
136 }
137
138 template <typename TField>
139 static FieldWrapperPtr createWrapperInternal(TField& field, EnumValueTag)
140 {
141 return field_wrapper::makeEnumValueWrapper(field);
142 }
143
144 template <typename TField>
145 static FieldWrapperPtr createWrapperInternal(TField& field, StringTag)
146 {
147 return field_wrapper::makeStringWrapper(field);
148 }
149
150 template <typename TField>
151 static FieldWrapperPtr createWrapperInternal(TField& field, BitfieldTag)
152 {
153 auto wrapper = field_wrapper::makeBitfieldWrapper(field);
154
155 typedef typename std::decay<decltype(wrapper)>::type WrapperPtrType;
156 typedef typename WrapperPtrType::element_type WrapperType;
157 typedef typename WrapperType::Members MembersWrappersList;
158
159 MembersWrappersList subWrappers;
160 auto& memberFields = field.value();
161 comms::util::tupleForEach(
162 memberFields,
163 SubfieldsCreateHelper(
164 [&subWrappers](FieldWrapperPtr fieldWrapper)
165 {
166 subWrappers.push_back(std::move(fieldWrapper));
167 }));
168
169 wrapper->setMembers(std::move(subWrappers));
170 return CC_RET_UNIQUE_PTR(wrapper);
171 }
172
173 template <typename TField>
174 static FieldWrapperPtr createWrapperInternal(TField& field, OptionalTag)
175 {
176 auto wrapper = field_wrapper::makeOptionalWrapper(field);
177 auto& wrappedField = field.field();
178 auto fieldWrapper = createWrapper(wrappedField);
179 wrapper->setFieldWrapper(std::move(fieldWrapper));
180 return CC_RET_UNIQUE_PTR(wrapper);
181 }
182
183 template <typename TField>
184 static FieldWrapperPtr createWrapperInternal(TField& field, BundleTag)
185 {
186 auto wrapper = field_wrapper::makeBundleWrapper(field);
187
188 typedef typename std::decay<decltype(wrapper)>::type WrapperPtrType;
189 typedef typename WrapperPtrType::element_type WrapperType;
190 typedef typename WrapperType::Members MembersWrappersList;
191
192 MembersWrappersList subWrappers;
193 auto& memberFields = field.value();
194 comms::util::tupleForEach(
195 memberFields,
196 SubfieldsCreateHelper(
197 [&subWrappers](FieldWrapperPtr fieldWrapper)
198 {
199 subWrappers.push_back(std::move(fieldWrapper));
200 }));
201
202 wrapper->setMembers(std::move(subWrappers));
203 return CC_RET_UNIQUE_PTR(wrapper);
204 }
205
206 template <typename TField>
207 static FieldWrapperPtr createWrapperInternal(TField& field, RawDataArrayListTag)
208 {
209 return field_wrapper::makeArrayListRawDataWrapper(field);
210 }
211
212 template <typename TField>
213 static FieldWrapperPtr createWrapperInternal(TField& field, FieldsArrayListTag)
214 {
215 typedef typename std::decay<decltype(field)>::type DecayedField;
216 typedef typename DecayedField::ValueType CollectionType;
217 typedef typename CollectionType::value_type ElementType;
218
219 auto wrapper = field_wrapper::makeDowncastedArrayListWrapper(field);
220 if (wrapper->hasFixedSize()) {
221 wrapper->adjustFixedSize();
222 }
223
224 wrapper->setWrapFieldCallback(
225 [](ElementType& memField) -> FieldWrapperPtr
226 {
227 return FieldWrapperCreator::createWrapper(memField);
228 });
229
230 wrapper->refreshMembers();
231 return CC_RET_UNIQUE_PTR(wrapper);
232 }
233
234 template <typename TField>
235 static FieldWrapperPtr createWrapperInternal(TField& field, FloatValueTag)
236 {
237 return field_wrapper::makeFloatValueWrapper(field);
238 }
239
240 template <typename TField>
241 static FieldWrapperPtr createWrapperInternal(TField& field, VariantTag)
242 {
243 auto wrapper = field_wrapper::makeVariantWrapper(field);
244
245 wrapper->setMemberCreateCallback(
246 [&field]() -> FieldWrapperPtr
247 {
248 FieldWrapperPtr ptr;
249 if (field.currentFieldValid()) {
250 field.currentFieldExec(
251 SubfieldsCreateHelper(
252 [&ptr](FieldWrapperPtr fieldWrapper) noexcept
253 {
254 ptr = std::move(fieldWrapper);
255 }));
256 }
257 return ptr;
258 });
259
260 if (field.currentFieldValid()) {
261 field.currentFieldExec(
262 SubfieldsCreateHelper(
263 [&wrapper](FieldWrapperPtr fieldWrapper)
264 {
265 wrapper->setCurrent(std::move(fieldWrapper));
266 }));
267 }
268 else {
269 wrapper->setCurrent(FieldWrapperPtr());
270 }
271
272 return CC_RET_UNIQUE_PTR(wrapper);
273 }
274
275 template <typename TField, typename TTag>
276 static FieldWrapperPtr createWrapperInternal(TField& field, TTag)
277 {
278 return field_wrapper::makeUnknownValueWrapper(field);
279 }
280};
281
282} // namespace details
283
284} // namespace cc_tools_qt
285
286
287
288
289
Main namespace for all classes / functions of the shared library.