cc_tools_qt
Common Environment for Protocol Analysis.
Loading...
Searching...
No Matches
ToolsFieldCreator.h
1//
2// Copyright 2016 - 2025 (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/details/ToolsArrayListFieldImpl.h"
26#include "cc_tools_qt/details/ToolsBitfieldFieldImpl.h"
27#include "cc_tools_qt/details/ToolsBitmaskFieldImpl.h"
28#include "cc_tools_qt/details/ToolsBundleFieldImpl.h"
29#include "cc_tools_qt/details/ToolsEnumFieldImpl.h"
30#include "cc_tools_qt/details/ToolsFloatFieldImpl.h"
31#include "cc_tools_qt/details/ToolsIntFieldImpl.h"
32#include "cc_tools_qt/details/ToolsOptionalFieldImpl.h"
33#include "cc_tools_qt/details/ToolsRawDataFieldImpl.h"
34#include "cc_tools_qt/details/ToolsStringFieldImpl.h"
35#include "cc_tools_qt/details/ToolsUnknownFieldImpl.h"
36#include "cc_tools_qt/details/ToolsUnsignedLongFieldImpl.h"
37#include "cc_tools_qt/details/ToolsVariantFieldImpl.h"
38
39#include <vector>
40
41namespace cc_tools_qt
42{
43
44namespace details
45{
46
47class ToolsFieldCreator
48{
49public:
50 using ToolsFieldPtr = cc_tools_qt::ToolsFieldPtr;
51 using FieldsList = std::vector<ToolsFieldPtr>;
52
53 explicit ToolsFieldCreator(FieldsList& fields) : m_fields(fields) {}
54
55 template <typename TField>
56 static ToolsFieldPtr createField(TField& field)
57 {
58 using DecayedField = typename std::decay<decltype(field)>::type;
59 using Tag = typename DecayedField::CommsTag;
60 return createFieldInternal(field, Tag());
61 }
62
63 template <typename TField>
64 void operator()(TField& field)
65 {
66 m_fields.push_back(createField(field));
67 }
68private:
69 using IntValueTag = comms::field::tag::Int;
70 using BitmaskValueTag = comms::field::tag::Bitmask;
71 using EnumValueTag = comms::field::tag::Enum;
72 using StringTag = comms::field::tag::String;
73 using BitfieldTag = comms::field::tag::Bitfield;
74 using OptionalTag = comms::field::tag::Optional;
75 using BundleTag = comms::field::tag::Bundle;
76 using RawDataArrayListTag = comms::field::tag::RawArrayList;
77 using FieldsArrayListTag = comms::field::tag::ArrayList;
78 using FloatValueTag = comms::field::tag::Float;
79 using VariantTag = comms::field::tag::Variant;
80
81 struct RegularIntTag {};
82 struct BigUnsignedTag {};
83
84 class SubfieldsCreateHelper
85 {
86 public:
87 using FieldCreateFunc = std::function <void (ToolsFieldPtr)>;
88 SubfieldsCreateHelper(FieldCreateFunc&& dispatchOp)
89 : m_dispatchOp(std::move(dispatchOp))
90 {
91 }
92
93 template <typename TField>
94 void operator()(TField&& field)
95 {
96 auto fieldWidget =
97 ToolsFieldCreator::createField(std::forward<TField>(field));
98 m_dispatchOp(std::move(fieldWidget));
99 }
100
101 template <std::size_t TIdx, typename TField>
102 void operator()(TField&& field)
103 {
104 return operator()(field);
105 }
106
107 private:
108 FieldCreateFunc m_dispatchOp;
109 };
110
111
112 template <typename TField>
113 static ToolsFieldPtr createFieldInternal(TField& field, IntValueTag)
114 {
115 using FieldType = std::decay_t<decltype(field)>;
116 using ValueType = typename FieldType::ValueType;
117
118 static_assert(std::is_integral<ValueType>::value,
119 "ValueType is expected to be integral");
120
121 using Tag =
122 std::conditional_t<
123 std::is_signed_v<ValueType> || (sizeof(ValueType) < sizeof(std::uint64_t)),
124 RegularIntTag,
125 BigUnsignedTag
126 >;
127
128 return createFieldInternal(field, Tag());
129 }
130
131 template <typename TField>
132 static ToolsFieldPtr createFieldInternal(TField& field, RegularIntTag)
133 {
134 return makeIntField(field);
135 }
136
137 template <typename TField>
138 static ToolsFieldPtr createFieldInternal(TField& field, BigUnsignedTag)
139 {
140 return makeUnsignedLongField(field);
141 }
142
143 template <typename TField>
144 static ToolsFieldPtr createFieldInternal(TField& field, BitmaskValueTag)
145 {
146 return makeBitmaskField(field);
147 }
148
149 template <typename TField>
150 static ToolsFieldPtr createFieldInternal(TField& field, EnumValueTag)
151 {
152 return makeEnumField(field);
153 }
154
155 template <typename TField>
156 static ToolsFieldPtr createFieldInternal(TField& field, StringTag)
157 {
158 return makeStringField(field);
159 }
160
161 template <typename TField>
162 static ToolsFieldPtr createFieldInternal(TField& field, BitfieldTag)
163 {
164 auto toolsField = makeBitfieldField(field);
165
166 using FieldPtrType = std::decay_t<decltype(toolsField)>;
167 using FieldType = typename FieldPtrType::element_type;
168 using MembersListType = typename FieldType::Members;
169
170 MembersListType subFields;
171 auto& memberFields = field.value();
172 comms::util::tupleForEach(
173 memberFields,
174 SubfieldsCreateHelper(
175 [&subFields](ToolsFieldPtr fieldParam)
176 {
177 subFields.push_back(std::move(fieldParam));
178 }));
179
180 toolsField->setMembers(std::move(subFields));
181 return toolsField;
182 }
183
184 template <typename TField>
185 static ToolsFieldPtr createFieldInternal(TField& field, OptionalTag)
186 {
187 auto toolsField = makeOptionalField(field);
188 auto& wrappedField = field.field();
189 auto wrappedToolsField = createField(wrappedField);
190 toolsField->setField(std::move(wrappedToolsField));
191 return toolsField;
192 }
193
194 template <typename TField>
195 static ToolsFieldPtr createFieldInternal(TField& field, BundleTag)
196 {
197 auto toolsField = makeBundleField(field);
198
199 using FieldPtrType = std::decay_t<decltype(toolsField)>;
200 using FieldType = typename FieldPtrType::element_type;
201 using MemberFieldsList = typename FieldType::Members;
202
203 MemberFieldsList subFields;
204 auto& memberFields = field.value();
205 comms::util::tupleForEach(
206 memberFields,
207 SubfieldsCreateHelper(
208 [&subFields](ToolsFieldPtr fieldParam)
209 {
210 subFields.push_back(std::move(fieldParam));
211 }));
212
213 toolsField->setMembers(std::move(subFields));
214 return toolsField;
215 }
216
217 template <typename TField>
218 static ToolsFieldPtr createFieldInternal(TField& field, RawDataArrayListTag)
219 {
220 return makeRawDataField(field);
221 }
222
223 template <typename TField>
224 static ToolsFieldPtr createFieldInternal(TField& field, FieldsArrayListTag)
225 {
226 using DecayedField = std::decay_t<decltype(field)>;
227 using CollectionType = typename DecayedField::ValueType;
228 using ElementType = typename CollectionType::value_type;
229
230 auto toolsField = makeArrayListField(field);
231 if (toolsField->hasFixedSize()) {
232 toolsField->adjustFixedSize();
233 }
234
235 toolsField->setWrapFieldCallback(
236 [](ElementType& memField) -> ToolsFieldPtr
237 {
238 return ToolsFieldCreator::createField(memField);
239 });
240
241 toolsField->refreshMembers();
242 return toolsField;
243 }
244
245 template <typename TField>
246 static ToolsFieldPtr createFieldInternal(TField& field, FloatValueTag)
247 {
248 return makeFloatField(field);
249 }
250
251 template <typename TField>
252 static ToolsFieldPtr createFieldInternal(TField& field, VariantTag)
253 {
254 auto toolsField = makeVariantField(field);
255
256 toolsField->setMemberCreateCallback(
257 [&field]() -> ToolsFieldPtr
258 {
259 ToolsFieldPtr ptr;
260 if (field.currentFieldValid()) {
261 field.currentFieldExec(
262 SubfieldsCreateHelper(
263 [&ptr](ToolsFieldPtr wrappedToolsField) noexcept
264 {
265 ptr = std::move(wrappedToolsField);
266 }));
267 }
268 return ptr;
269 });
270
271 if (field.currentFieldValid()) {
272 field.currentFieldExec(
273 SubfieldsCreateHelper(
274 [&toolsField](ToolsFieldPtr wrappedToolsField)
275 {
276 toolsField->setCurrent(std::move(wrappedToolsField));
277 }));
278 }
279 else {
280 toolsField->setCurrent(ToolsFieldPtr());
281 }
282
283 return toolsField;
284 }
285
286 template <typename TField, typename TTag>
287 static ToolsFieldPtr createFieldInternal(TField& field, TTag)
288 {
289 return makeUnknownField(field);
290 }
291
292private:
293 FieldsList& m_fields;
294};
295
296} // namespace details
297
298} // namespace cc_tools_qt
299
300
301
302
303
Main namespace for all classes / functions of the shared library.