cc_tools_qt
Common Environment for Protocol Analysis.
Loading...
Searching...
No Matches
ArrayListRawDataWrapper.h
1//
2// Copyright 2015 - 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
19#pragma once
20
21
22#include <cstdint>
23#include <cassert>
24#include <memory>
25#include <limits>
26
27#include <QtCore/QString>
28
29#include "comms/comms.h"
30
31#include "FieldWrapper.h"
32
33namespace cc_tools_qt
34{
35
36namespace field_wrapper
37{
38
39class CC_API ArrayListRawDataWrapper : public FieldWrapper
40{
41public:
42
43 typedef std::unique_ptr<ArrayListRawDataWrapper> Ptr;
44
45 ArrayListRawDataWrapper();
46 virtual ~ArrayListRawDataWrapper() noexcept;
47
48 QString getValue() const;
49
50 void setValue(const QString& val);
51
52 int maxSize() const;
53
54 int minSize() const;
55
56 Ptr clone();
57
58 bool getForcedShowAll() const;
59 void setForcedShowAll(bool val = true);
60 bool isTruncated() const;
61
62protected:
63 virtual QString getValueImpl() const = 0;
64 virtual void setValueImpl(const QString& val) = 0;
65 virtual int maxSizeImpl() const = 0;
66 virtual int minSizeImpl() const = 0;
67 virtual Ptr cloneImpl() = 0;
68
69 void dispatchImpl(FieldWrapperHandler& handler);
70
71 static const std::size_t TruncateLength = 128;
72
73private:
74 bool m_forcedShowAll = false;
75};
76
77template <typename TField>
78class ArrayListRawDataWrapperT : public FieldWrapperT<ArrayListRawDataWrapper, TField>
79{
80 using Base = FieldWrapperT<ArrayListRawDataWrapper, TField>;
81 using Field = TField;
82
83public:
84 using SerialisedSeq = typename Base::SerialisedSeq;
85 typedef typename Base::Ptr Ptr;
86
87 explicit ArrayListRawDataWrapperT(Field& fieldRef)
88 : Base(fieldRef)
89 {
90 }
91
92 ArrayListRawDataWrapperT(const ArrayListRawDataWrapperT&) = default;
93 ArrayListRawDataWrapperT(ArrayListRawDataWrapperT&&) = default;
94 virtual ~ArrayListRawDataWrapperT() noexcept = default;
95
96 ArrayListRawDataWrapperT& operator=(const ArrayListRawDataWrapperT&) = delete;
97
98protected:
99
100 virtual QString getValueImpl() const override
101 {
102 QString retStr;
103 auto& dataField = Base::field();
104 auto& data = dataField.value();
105
106 int maxLen = static_cast<int>(Base::length() * 2);
107 if (Base::isTruncated()) {
108 maxLen = static_cast<decltype(maxLen)>(Base::TruncateLength * 2);
109 }
110
111 for (auto byte : data) {
112 if (maxLen <= retStr.size()) {
113 break;
114 }
115
116 retStr.append(QString("%1").arg(static_cast<uint>(byte), 2, 16, QChar('0')));
117 }
118 return retStr;
119 }
120
121 virtual void setValueImpl(const QString& val) override
122 {
123 SerialisedSeq data;
124 QString byteStr;
125
126 auto addByteToData =
127 [&data, &byteStr]() mutable
128 {
129 bool ok = false;
130 auto intVal = byteStr.toInt(&ok, 16);
131 if (!ok) {
132 return;
133 }
134
135 data.push_back(static_cast<typename SerialisedSeq::value_type>(intVal));
136 byteStr.clear();
137 };
138
139 for (auto ch : val) {
140 if (((ch < '0') || ('9' < ch)) &&
141 ((ch.toLower() < 'a') || ('f' < ch.toLower()))) {
142 continue;
143 }
144
145 byteStr.append(ch);
146
147 if (2 <= byteStr.size()) {
148 addByteToData();
149 }
150 }
151
152 if (!byteStr.isEmpty()) {
153 byteStr.append('0');
154 addByteToData();
155 }
156
157 Base::setSerialisedValueImpl(data);
158 }
159
160 virtual SerialisedSeq getSerialisedValueImpl() const override
161 {
162 auto serValue = Base::getSerialisedValueImpl();
163 if (Base::isTruncated()) {
164 serValue.resize(Base::TruncateLength);
165 }
166
167 return serValue;
168 }
169
170 virtual bool setSerialisedValueImpl([[maybe_unused]] const SerialisedSeq& value) override
171 {
172 [[maybe_unused]] static constexpr bool Must_not_be_called = false;
173 assert(Must_not_be_called);
174 return false;
175 }
176
177 virtual int maxSizeImpl() const override
178 {
179 return maxSizeInternal(SizeExistanceTag());
180 }
181
182 virtual int minSizeImpl() const override
183 {
184 return minSizeInternal(SizeExistanceTag());
185 }
186
187 virtual Ptr cloneImpl() override
188 {
189 return Ptr(new ArrayListRawDataWrapperT<TField>(Base::field()));
190 }
191
192private:
193 struct SizeFieldExistsTag {};
194 struct SerLengthFieldExistsTag {};
195 struct FixedSizeTag {};
196 struct NoLimitsTag {};
197
198 typedef typename std::conditional<
199 Field::hasSizeFieldPrefix(),
200 SizeFieldExistsTag,
201 typename std::conditional<
202 Field::hasSerLengthFieldPrefix(),
203 SerLengthFieldExistsTag,
204 typename std::conditional<
205 Field::hasFixedSize(),
206 FixedSizeTag,
207 NoLimitsTag
208 >::type
209 >::type
210 >::type SizeExistanceTag;
211
212 template <typename TPrefixField>
213 static int maxSizeByPrefix()
214 {
215 if (sizeof(int) <= TPrefixField::maxLength()) {
216 return std::numeric_limits<int>::max();
217 }
218
219 auto shift =
220 TPrefixField::maxLength() * std::numeric_limits<std::uint8_t>::digits;
221
222 return static_cast<int>((1U << shift) - 1);
223 }
224
225 static int maxSizeInternal(SizeFieldExistsTag)
226 {
227 typedef typename Field::SizeFieldPrefix PrefixField;
228 return maxSizeByPrefix<PrefixField>();
229 }
230
231 static int maxSizeInternal(SerLengthFieldExistsTag)
232 {
233 typedef typename Field::SerLengthFieldPrefix PrefixField;
234 return maxSizeByPrefix<PrefixField>();
235 }
236
237 static int maxSizeInternal(FixedSizeTag)
238 {
239 return static_cast<int>(Field::fixedSize());
240 }
241
242 int maxSizeInternal(NoLimitsTag) const
243 {
244 return
245 static_cast<int>(
246 std::min(
247 static_cast<std::size_t>(std::numeric_limits<int>::max()),
248 Base::field().value().max_size()));
249 }
250
251 static int minSizeInternal(SizeFieldExistsTag)
252 {
253 return 0;
254 }
255
256 static int minSizeInternal(SerLengthFieldExistsTag)
257 {
258 return 0;
259 }
260
261 static int minSizeInternal(FixedSizeTag)
262 {
263 return static_cast<int>(Field::fixedSize());
264 }
265
266 int minSizeInternal(NoLimitsTag) const
267 {
268 return 0;
269 }
270};
271
272using ArrayListRawDataWrapperPtr = ArrayListRawDataWrapper::Ptr;
273
274template <typename TField>
275ArrayListRawDataWrapperPtr
276makeArrayListRawDataWrapper(TField& field)
277{
278 return
279 ArrayListRawDataWrapperPtr(
280 new ArrayListRawDataWrapperT<TField>(field));
281}
282
283} // namespace field_wrapper
284
285} // namespace cc_tools_qt
286
287
288
Main namespace for all classes / functions of the shared library.