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