cc_tools_qt
Common Environment for Protocol Analysis.
Loading...
Searching...
No Matches
ToolsStringFieldImpl.h
1//
2// Copyright 2015 - 2026 (C). Alex Robenko. All rights reserved.
3//
4// SPDX-License-Identifier: GPL-3.0-or-later
5//
6
7// This file is free software: you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation, either version 3 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20#pragma once
21
22#include "cc_tools_qt/details/ToolsFieldBase.h"
23#include "cc_tools_qt/field/ToolsStringField.h"
24
25#include "comms/field/String.h"
26
27#include <cstdint>
28#include <cassert>
29#include <limits>
30#include <memory>
31#include <type_traits>
32
33namespace cc_tools_qt
34{
35
36namespace details
37{
38
39template <typename TField>
40class ToolsStringFieldImpl : public ToolsFieldBase<cc_tools_qt::field::ToolsStringField, TField>
41{
42 using Base = ToolsFieldBase<cc_tools_qt::field::ToolsStringField, TField>;
43 using Field = TField;
44
45public:
46 using SerialisedSeq = typename Base::SerialisedSeq;
47 using Ptr = typename Base::Ptr;
48 using ActPtr = typename Base::ActPtr;
49
50 explicit ToolsStringFieldImpl(Field& fieldRef)
51 : Base(fieldRef)
52 {
53 }
54
55 ToolsStringFieldImpl(const ToolsStringFieldImpl&) = default;
56 ToolsStringFieldImpl(ToolsStringFieldImpl&&) = default;
57 virtual ~ToolsStringFieldImpl() noexcept = default;
58
59 ToolsStringFieldImpl& operator=(const ToolsStringFieldImpl&) = delete;
60
61protected:
62
63 virtual QString getValueImpl() const override
64 {
65 auto& strField = Base::field();
66 return QString::fromUtf8(strField.getValue().c_str(), static_cast<int>(strField.getValue().size()));
67 }
68
69 virtual void setValueImpl(const QString& val) override
70 {
71 using Tag =
72 std::conditional_t<
73 Field::hasFixedValue(),
74 NoFeatureTag,
75 HasFeatureTag
76 >;
77
78 setValueInternal(val, Tag());
79 }
80
81 virtual bool setSerialisedValueImpl([[maybe_unused]] const SerialisedSeq& value) override
82 {
83 [[maybe_unused]] static constexpr bool Must_not_be_called = false;
84 assert(Must_not_be_called);
85 return false;
86 }
87
88 virtual int maxSizeImpl() const override
89 {
90 return maxSizeInternal(SizeExistanceTag());
91 }
92
93 virtual Ptr cloneImpl() override
94 {
95 return ActPtr(new ToolsStringFieldImpl<TField>(Base::field()));
96 }
97
98private:
99 struct SizeFieldExistsTag {};
100 struct SerLengthFieldExistsTag {};
101 struct NoSizeFieldTag {};
102 struct HasFeatureTag {};
103 struct NoFeatureTag {};
104
105 using SizeExistanceTag =
106 std::conditional_t<
107 Field::hasSizeFieldPrefix(),
108 SizeFieldExistsTag,
109 std::conditional_t<
110 Field::hasSerLengthFieldPrefix(),
111 SerLengthFieldExistsTag,
112 NoSizeFieldTag
113 >
114 >;
115
116 template <typename TPrefixField>
117 static int maxSizeByPrefix()
118 {
119 if (sizeof(int) <= TPrefixField::maxLength()) {
120 return std::numeric_limits<int>::max();
121 }
122
123 auto shift =
124 TPrefixField::maxLength() * std::numeric_limits<std::uint8_t>::digits;
125
126 return static_cast<int>((1U << shift) - 1);
127 }
128
129 static int maxSizeInternal(SizeFieldExistsTag)
130 {
131 using SizeField = typename Field::SizeFieldPrefix;
132 return maxSizeByPrefix<SizeField>();
133 }
134
135 static int maxSizeInternal(SerLengthFieldExistsTag)
136 {
137 using LengthField = typename Field::SerLengthFieldPrefix;
138 return maxSizeByPrefix<LengthField>();
139 }
140
141 int maxSizeInternal(NoSizeFieldTag) const
142 {
143 return
144 static_cast<int>(
145 std::min(
146 static_cast<std::size_t>(std::numeric_limits<int>::max()),
147 Base::field().getValue().max_size()));
148 }
149
150 void setValueInternal(const QString& val, HasFeatureTag)
151 {
152 Base::field().setValue(val.toStdString().c_str());
153 }
154
155 void setValueInternal([[maybe_unused]] const QString& val, NoFeatureTag)
156 {
157 [[maybe_unused]] static constexpr bool Must_not_be_called = false;
158 assert(Must_not_be_called);
159 }
160};
161
162template <typename TField>
163auto makeStringField(TField& field)
164{
165 return std::make_unique<ToolsStringFieldImpl<TField>>(field);
166}
167
168} // namespace details
169
170} // namespace cc_tools_qt
171
Main namespace for all classes / functions of the shared library.