22#include "comms/comms.h"
24#include <QtCore/QString>
32COMMS_MSVC_WARNING_PUSH
33COMMS_MSVC_WARNING_DISABLE(4127)
41template <
typename TBase,
typename TField>
42class ToolsFieldBase :
public TBase
47 using SerialisedSeq =
typename Base::SerialisedSeq;
48 using Ptr =
typename Base::Ptr;
52 virtual ~ToolsFieldBase() noexcept = default;
56 explicit ToolsFieldBase(Field& fieldRef)
61 virtual const char* nameImpl()
const override
63 static_assert(Field::hasName(),
"The field class is expected use comms::option::def::HasName and define name() function.");
64 return m_field.name();
67 virtual std::size_t lengthImpl()
const override
69 return m_field.length();
72 virtual bool validImpl()
const override
74 return m_field.valid();
77 virtual bool isReadOnlyImpl()
const override
79 return Field::hasFixedValue();
82 virtual bool isHiddenSerializationImpl()
const override
84 return Field::hasEmptySerialization();
92 const Field& field()
const
97 virtual SerialisedSeq getSerialisedValueImpl()
const override
100 seq.reserve(m_field.length());
101 auto iter = std::back_inserter(seq);
102 [[maybe_unused]]
auto es = m_field.write(iter, seq.max_size());
103 assert(es == comms::ErrorStatus::Success);
104 assert(seq.size() == m_field.length());
108 virtual bool setSerialisedValueImpl(
const SerialisedSeq& value)
override
114 if ((!CollectionPrefixDetect<Field, IsCollection>::HasSizeFieldPrefix) &&
115 (!CollectionPrefixDetect<Field, IsCollection>::HasSerLengthFieldPrefix) &&
116 (!CollectionPrefixDetect<Field, IsCollection>::HasTrailingFieldSuffix) &&
117 (!CollectionPrefixDetect<Field, IsCollection>::HasTerminationFieldSuffix)) {
118 auto iter = &value[0];
119 auto es = m_field.read(iter, value.size());
120 return es == comms::ErrorStatus::Success;
123 SerialisedSeq newVal;
124 if (!writeSerialisedSize(newVal, value.size(), SerialisedSizePrefixTag())) {
128 if (!writeSerialisedLength(newVal, value.size(), SerialisedLengthPrefixTag())) {
132 auto writeIter = std::back_inserter(newVal);
133 std::copy(value.begin(), value.end(), writeIter);
135 if (!writeTrailSuffix(newVal, SerialisedTrailSuffixTag())) {
139 if (!writeTermSuffix(newVal, SerialisedTermSuffixTag())) {
143 auto iter = &newVal[0];
144 auto es = m_field.read(iter, newVal.size());
145 return es == comms::ErrorStatus::Success;
148 virtual bool canWriteImpl()
const override
150 return m_field.canWrite();
153 virtual void resetImpl()
override
159 struct HasPrefixSuffixTag {};
160 struct NoPrefixSuffixTag {};
162 template <
typename T,
bool TIsCollection>
163 struct CollectionPrefixDetect
165 static const bool HasSizeFieldPrefix =
false;
166 static const bool HasSerLengthFieldPrefix =
false;
167 static const bool HasTrailingFieldSuffix =
false;
168 static const bool HasTerminationFieldSuffix =
false;
171 template <
typename T>
172 struct CollectionPrefixDetect<T, true>
174 static const bool HasSizeFieldPrefix = Field::hasSizeFieldPrefix();
175 static const bool HasSerLengthFieldPrefix = Field::hasSerLengthFieldPrefix();
176 static const bool HasTrailingFieldSuffix = TField::hasTrailingFieldSuffix();
177 static const bool HasTerminationFieldSuffix = Field::hasTerminationFieldSuffix();
180 static constexpr bool IsCollection = comms::field::isString<Field>() || comms::field::isArrayList<Field>();
182 using SerialisedSizePrefixTag =
184 CollectionPrefixDetect<Field, IsCollection>::HasSizeFieldPrefix,
189 using SerialisedLengthPrefixTag =
191 CollectionPrefixDetect<Field, IsCollection>::HasSerLengthFieldPrefix,
196 using SerialisedTrailSuffixTag =
198 CollectionPrefixDetect<Field, IsCollection>::HasTrailingFieldSuffix,
203 using SerialisedTermSuffixTag =
205 CollectionPrefixDetect<Field, IsCollection>::HasTerminationFieldSuffix,
210 bool writeSerialisedSize(SerialisedSeq& seq, std::size_t sizeVal, HasPrefixSuffixTag)
212 using SizePrefixField =
typename Field::SizeFieldPrefix;
214 SizePrefixField sizePrefixField;
215 sizePrefixField.setValue(sizeVal);
216 auto writeIter = std::back_inserter(seq);
217 auto es = sizePrefixField.write(writeIter, seq.max_size() - seq.size());
218 return es == comms::ErrorStatus::Success;
221 bool writeSerialisedSize([[maybe_unused]] SerialisedSeq& seq, [[maybe_unused]] std::size_t sizeVal, NoPrefixSuffixTag)
226 bool writeSerialisedLength(SerialisedSeq& seq, std::size_t sizeVal, HasPrefixSuffixTag)
228 using LengthPrefixField =
typename Field::SerLengthFieldPrefix;
230 LengthPrefixField lengthPrefixField;
231 lengthPrefixField.setValue(sizeVal);
232 auto writeIter = std::back_inserter(seq);
233 auto es = lengthPrefixField.write(writeIter, seq.max_size() - seq.size());
234 return es == comms::ErrorStatus::Success;
237 bool writeSerialisedLength([[maybe_unused]] SerialisedSeq& seq, [[maybe_unused]] std::size_t sizeVal, NoPrefixSuffixTag)
242 bool writeTrailSuffix(SerialisedSeq& seq, HasPrefixSuffixTag)
244 using TrailingSuffixField =
typename Field::TrailingFieldSuffix;
246 TrailingSuffixField trailingSuffixField;
247 auto writeIter = std::back_inserter(seq);
248 auto es = trailingSuffixField.write(writeIter, seq.max_size() - seq.size());
249 return es == comms::ErrorStatus::Success;
252 bool writeTrailSuffix([[maybe_unused]] SerialisedSeq& seq, NoPrefixSuffixTag)
257 bool writeTermSuffix(SerialisedSeq& seq, HasPrefixSuffixTag)
259 using TermSuffixField =
typename Field::TerminationFieldSuffix;
260 TermSuffixField termSuffixField;
261 auto writeIter = std::back_inserter(seq);
262 auto es = termSuffixField.write(writeIter, seq.max_size() - seq.size());
263 return es == comms::ErrorStatus::Success;
266 bool writeTermSuffix([[maybe_unused]] SerialisedSeq& seq, NoPrefixSuffixTag)
278COMMS_MSVC_WARNING_POP