16#include "comms/field/basic/CommonFuncs.h"
18#include "comms/details/tag.h"
29template <
typename TLenField, comms::ErrorStatus TStatus,
typename TBase>
32 using BaseImpl = TBase;
33 using LenField = TLenField;
34 static const std::size_t MaxAllowedElemLength =
35 static_cast<std::size_t
>(LenField::maxValue());
37 static_assert(!LenField::isVersionDependent(),
38 "Prefix fields must not be version dependent");
41 using ValueType =
typename BaseImpl::ValueType;
42 using ElementType =
typename BaseImpl::ElementType;
52 : BaseImpl(
std::move(val))
61 std::size_t length()
const
64 using LenFieldLengthTag =
65 typename comms::util::LazyShallowConditional<
66 LenField::minLength() == LenField::maxLength()
68 FixedLengthLenFieldTag,
72 return lengthInternal(LenFieldLengthTag());
75 static constexpr std::size_t minLength()
77 return LenField::minLength();
80 static constexpr std::size_t maxLength()
82 return basic::CommonFuncs::maxSupportedLength();
85 template <
typename TIter>
86 ErrorStatus readElement(ElementType& elem, TIter& iter, std::size_t& len)
const
94 std::size_t elemLen = elemLen_;
95 auto es = BaseImpl::readElement(elem, iter, elemLen);
105 std::advance(iter, elemLen);
110 template <
typename TIter>
111 void readElementNoStatus(ElementType& elem, TIter& iter)
const =
delete;
113 template <
typename TIter>
121 auto es = readLen(iter, len);
126 return basic::CommonFuncs::readSequence(*
this, iter, len);
129 static constexpr bool hasReadNoStatus()
134 template <
typename TIter>
135 void readNoStatus(TIter& iter) =
delete;
137 template <
typename TIter>
138 ErrorStatus readN(std::size_t count, TIter& iter, std::size_t& len)
141 auto es = readLen(iter, len);
149 return basic::CommonFuncs::readSequenceN(*
this, count, iter, len);
152 template <
typename TIter>
153 void readNoStatusN(std::size_t count, TIter& iter) =
delete;
155 bool canWriteElement(
const ElementType& elem)
const
157 if (!BaseImpl::canWriteElement(elem)) {
161 auto elemLen = elem.length();
162 if (MaxAllowedElemLength < elemLen) {
167 lenField.setValue(elemLen);
168 return lenField.canWrite();
171 bool canWrite()
const
173 if (BaseImpl::getValue().empty()) {
174 return BaseImpl::canWrite();
177 return BaseImpl::canWrite() && canWriteElement(BaseImpl::getValue().front());
180 template <
typename TIter>
181 ErrorStatus write(TIter& iter, std::size_t len)
const
183 if (!BaseImpl::getValue().empty()) {
184 if (!canWriteElement(BaseImpl::getValue().front())) {
188 auto es = writeLen(iter, len);
194 return basic::CommonFuncs::writeSequence(*
this, iter, len);
197 static constexpr bool hasWriteNoStatus()
202 template <
typename TIter>
203 void writeNoStatus(TIter& iter)
const =
delete;
205 template <
typename TIter>
206 ErrorStatus writeN(std::size_t count, TIter& iter, std::size_t& len)
const
210 if (!canWriteElement(BaseImpl::getValue().front())) {
214 auto es = writeLen(iter, len);
220 return basic::CommonFuncs::writeSequenceN(*
this, count, iter, len);
223 template <
typename TIter>
224 void writeNoStatusN(std::size_t count, TIter& iter)
const =
delete;
228 return BaseImpl::valid() && canWrite();
233 template <
typename... TParams>
234 using FixedLengthLenFieldTag = comms::details::tag::Tag1<>;
236 template <
typename... TParams>
237 using VarLengthLenFieldTag = comms::details::tag::Tag2<>;
239 template <
typename... TParams>
240 std::size_t lengthInternal(FixedLengthLenFieldTag<TParams...>)
const
242 std::size_t prefixLen = 0U;
243 if (!BaseImpl::getValue().empty()) {
244 prefixLen = LenField::minLength();
246 return (prefixLen + BaseImpl::length());
249 template <
typename... TParams>
250 std::size_t lengthInternal(VarLengthLenFieldTag<TParams...>)
const
252 std::size_t prefixLen = 0U;
253 if (!BaseImpl::getValue().empty()) {
256 std::min(BaseImpl::minElementLength(), std::size_t(MaxAllowedElemLength)));
257 prefixLen = lenField.length();
260 return (prefixLen + BaseImpl::length());
263 template <
typename TIter>
264 static void advanceWriteIterator(TIter& iter, std::size_t len)
266 basic::CommonFuncs::advanceWriteIterator(iter, len);
269 template <
typename TIter>
272 auto fromIter = iter;
274 auto es = lenField.read(iter, len);
279 auto diff =
static_cast<std::size_t
>(std::distance(fromIter, iter));
283 elemLen_ =
static_cast<std::size_t
>(lenField.getValue());
284 if (elemLen_ == MaxLengthLimit) {
291 template <
typename TIter>
292 ErrorStatus writeLen(TIter& iter, std::size_t& len)
const
294 auto elemLength = BaseImpl::minElementLength();
296 lenField.setValue(elemLength);
297 auto es = lenField.write(iter, len);
302 len -= lenField.length();
306 template <
typename TIter>
307 void writeLenNoStatus(TIter& iter)
const
309 auto elemLength = BaseImpl::minElementLength();
311 lenField.setValue(elemLength);
312 lenField.writeNoStatus(iter);
315 static_assert(BaseImpl::minElementLength() == BaseImpl::maxElementLength(),
316 "Option SequenceElemFixedSerLengthFieldPrefix can be used only with fixed length "
318 static_assert(1U <= LenField::minLength(),
"Invalid min length assumption");
320 static const std::size_t MaxLengthLimit =
321 std::numeric_limits<std::size_t>::max();
322 std::size_t elemLen_ = MaxLengthLimit;
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
This file contain definition of error statuses used by comms module.
comms::option::def::SequenceElemFixedSerLengthFieldPrefix< TField, TReadErrorStatus > SequenceElemFixedSerLengthFieldPrefix
Same as comms::option::def::SequenceElemFixedSerLengthFieldPrefix.
Definition options.h:1523
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:17
@ Success
Used to indicate successful outcome of the operation.
@ InvalidMsgData
Used to indicate that a message has invalid data.
Replacement to some types from standard type_traits.