21#include "comms/comms.h"
23#include <QtCore/QString>
31COMMS_MSVC_WARNING_PUSH
32COMMS_MSVC_WARNING_DISABLE(4127)
40template <
typename TBase,
typename TField>
41class ToolsFieldBase :
public TBase
46 using SerialisedSeq =
typename Base::SerialisedSeq;
47 using Ptr =
typename Base::Ptr;
51 virtual ~ToolsFieldBase() noexcept = default;
55 explicit ToolsFieldBase(Field& fieldRef)
60 virtual const char* nameImpl()
const override
62 static_assert(Field::hasName(),
"The field class is expected use comms::option::def::HasName and define name() function.");
63 return m_field.name();
66 virtual std::size_t lengthImpl()
const override
68 return m_field.length();
71 virtual bool validImpl()
const override
73 return m_field.valid();
76 virtual bool isReadOnlyImpl()
const override
78 return Field::hasFixedValue();
81 virtual bool isHiddenSerializationImpl()
const override
83 return Field::hasEmptySerialization();
91 const Field& field()
const
96 virtual SerialisedSeq getSerialisedValueImpl()
const override
99 seq.reserve(m_field.length());
100 auto iter = std::back_inserter(seq);
101 [[maybe_unused]]
auto es = m_field.write(iter, seq.max_size());
102 assert(es == comms::ErrorStatus::Success);
103 assert(seq.size() == m_field.length());
107 virtual bool setSerialisedValueImpl(
const SerialisedSeq& value)
override
113 if ((!CollectionPrefixDetect<Field, IsCollection>::HasSizeFieldPrefix) &&
114 (!CollectionPrefixDetect<Field, IsCollection>::HasSerLengthFieldPrefix) &&
115 (!CollectionPrefixDetect<Field, IsCollection>::HasTrailingFieldSuffix) &&
116 (!CollectionPrefixDetect<Field, IsCollection>::HasTerminationFieldSuffix)) {
117 auto iter = &value[0];
118 auto es = m_field.read(iter, value.size());
119 return es == comms::ErrorStatus::Success;
122 SerialisedSeq newVal;
123 if (!writeSerialisedSize(newVal, value.size(), SerialisedSizePrefixTag())) {
127 if (!writeSerialisedLength(newVal, value.size(), SerialisedLengthPrefixTag())) {
131 auto writeIter = std::back_inserter(newVal);
132 std::copy(value.begin(), value.end(), writeIter);
134 if (!writeTrailSuffix(newVal, SerialisedTrailSuffixTag())) {
138 if (!writeTermSuffix(newVal, SerialisedTermSuffixTag())) {
142 auto iter = &newVal[0];
143 auto es = m_field.read(iter, newVal.size());
144 return es == comms::ErrorStatus::Success;
147 virtual bool canWriteImpl()
const override
149 return m_field.canWrite();
152 virtual void resetImpl()
override
158 struct HasPrefixSuffixTag {};
159 struct NoPrefixSuffixTag {};
161 template <
typename T,
bool TIsCollection>
162 struct CollectionPrefixDetect
164 static const bool HasSizeFieldPrefix =
false;
165 static const bool HasSerLengthFieldPrefix =
false;
166 static const bool HasTrailingFieldSuffix =
false;
167 static const bool HasTerminationFieldSuffix =
false;
170 template <
typename T>
171 struct CollectionPrefixDetect<T, true>
173 static const bool HasSizeFieldPrefix = Field::hasSizeFieldPrefix();
174 static const bool HasSerLengthFieldPrefix = Field::hasSerLengthFieldPrefix();
175 static const bool HasTrailingFieldSuffix = TField::hasTrailingFieldSuffix();
176 static const bool HasTerminationFieldSuffix = Field::hasTerminationFieldSuffix();
179 static constexpr bool IsCollection = comms::field::isString<Field>() || comms::field::isArrayList<Field>();
181 using SerialisedSizePrefixTag =
183 CollectionPrefixDetect<Field, IsCollection>::HasSizeFieldPrefix,
188 using SerialisedLengthPrefixTag =
190 CollectionPrefixDetect<Field, IsCollection>::HasSerLengthFieldPrefix,
195 using SerialisedTrailSuffixTag =
197 CollectionPrefixDetect<Field, IsCollection>::HasTrailingFieldSuffix,
202 using SerialisedTermSuffixTag =
204 CollectionPrefixDetect<Field, IsCollection>::HasTerminationFieldSuffix,
209 bool writeSerialisedSize(SerialisedSeq& seq, std::size_t sizeVal, HasPrefixSuffixTag)
211 using SizePrefixField =
typename Field::SizeFieldPrefix;
213 SizePrefixField sizePrefixField;
214 sizePrefixField.setValue(sizeVal);
215 auto writeIter = std::back_inserter(seq);
216 auto es = sizePrefixField.write(writeIter, seq.max_size() - seq.size());
217 return es == comms::ErrorStatus::Success;
220 bool writeSerialisedSize([[maybe_unused]] SerialisedSeq& seq, [[maybe_unused]] std::size_t sizeVal, NoPrefixSuffixTag)
225 bool writeSerialisedLength(SerialisedSeq& seq, std::size_t sizeVal, HasPrefixSuffixTag)
227 using LengthPrefixField =
typename Field::SerLengthFieldPrefix;
229 LengthPrefixField lengthPrefixField;
230 lengthPrefixField.setValue(sizeVal);
231 auto writeIter = std::back_inserter(seq);
232 auto es = lengthPrefixField.write(writeIter, seq.max_size() - seq.size());
233 return es == comms::ErrorStatus::Success;
236 bool writeSerialisedLength([[maybe_unused]] SerialisedSeq& seq, [[maybe_unused]] std::size_t sizeVal, NoPrefixSuffixTag)
241 bool writeTrailSuffix(SerialisedSeq& seq, HasPrefixSuffixTag)
243 using TrailingSuffixField =
typename Field::TrailingFieldSuffix;
245 TrailingSuffixField trailingSuffixField;
246 auto writeIter = std::back_inserter(seq);
247 auto es = trailingSuffixField.write(writeIter, seq.max_size() - seq.size());
248 return es == comms::ErrorStatus::Success;
251 bool writeTrailSuffix([[maybe_unused]] SerialisedSeq& seq, NoPrefixSuffixTag)
256 bool writeTermSuffix(SerialisedSeq& seq, HasPrefixSuffixTag)
258 using TermSuffixField =
typename Field::TerminationFieldSuffix;
259 TermSuffixField termSuffixField;
260 auto writeIter = std::back_inserter(seq);
261 auto es = termSuffixField.write(writeIter, seq.max_size() - seq.size());
262 return es == comms::ErrorStatus::Success;
265 bool writeTermSuffix([[maybe_unused]] SerialisedSeq& seq, NoPrefixSuffixTag)
279COMMS_MSVC_WARNING_POP