13#include "comms/details/tag.h"
15#include "comms/field/basic/CommonFuncs.h"
33template <
typename TLenField, comms::ErrorStatus TStatus,
typename TBase>
36 using BaseImpl = TBase;
37 using LenField = TLenField;
38 static const std::size_t MaxAllowedElemLength =
39 static_cast<std::size_t
>(LenField::maxValue());
41 static_assert(!LenField::isVersionDependent(),
42 "Prefix fields must not be version dependent");
45 using ValueType =
typename BaseImpl::ValueType;
46 using ElementType =
typename BaseImpl::ElementType;
56 : BaseImpl(
std::move(val))
65 std::size_t length()
const
68 using LenFieldLengthTag =
69 typename comms::util::LazyShallowConditional<
70 LenField::minLength() == LenField::maxLength()
72 FixedLengthLenFieldTag,
76 return lengthInternal(LenFieldLengthTag());
79 static constexpr std::size_t minLength()
81 return LenField::minLength();
84 static constexpr std::size_t maxLength()
86 return basic::CommonFuncs::maxSupportedLength();
89 template <
typename TIter>
90 ErrorStatus readElement(ElementType& elem, TIter& iter, std::size_t& len)
const
94 if (len < m_elemLen) {
98 std::size_t elemLen = m_elemLen;
99 auto es = BaseImpl::readElement(elem, iter, elemLen);
109 std::advance(iter, elemLen);
114 template <
typename TIter>
115 void readElementNoStatus(ElementType& elem, TIter& iter)
const =
delete;
117 template <
typename TIter>
125 auto es = readLen(iter, len);
130 return basic::CommonFuncs::readSequence(*
this, iter, len);
133 static constexpr bool hasReadNoStatus()
138 template <
typename TIter>
139 void readNoStatus(TIter& iter) =
delete;
141 template <
typename TIter>
142 ErrorStatus readN(std::size_t count, TIter& iter, std::size_t& len)
145 auto es = readLen(iter, len);
153 return basic::CommonFuncs::readSequenceN(*
this, count, iter, len);
156 template <
typename TIter>
157 void readNoStatusN(std::size_t count, TIter& iter) =
delete;
159 bool canWriteElement(
const ElementType& elem)
const
161 if (!BaseImpl::canWriteElement(elem)) {
165 auto elemLen = elem.length();
166 if (MaxAllowedElemLength < elemLen) {
171 lenField.setValue(elemLen);
172 return lenField.canWrite();
175 bool canWrite()
const
177 if (BaseImpl::getValue().empty()) {
178 return BaseImpl::canWrite();
181 return BaseImpl::canWrite() && canWriteElement(BaseImpl::getValue().front());
184 template <
typename TIter>
185 ErrorStatus write(TIter& iter, std::size_t len)
const
187 if (!BaseImpl::getValue().empty()) {
188 if (!canWriteElement(BaseImpl::getValue().front())) {
192 auto es = writeLen(iter, len);
198 return basic::CommonFuncs::writeSequence(*
this, iter, len);
201 static constexpr bool hasWriteNoStatus()
206 template <
typename TIter>
207 void writeNoStatus(TIter& iter)
const =
delete;
209 template <
typename TIter>
210 ErrorStatus writeN(std::size_t count, TIter& iter, std::size_t& len)
const
214 if (!canWriteElement(BaseImpl::getValue().front())) {
218 auto es = writeLen(iter, len);
224 return basic::CommonFuncs::writeSequenceN(*
this, count, iter, len);
227 template <
typename TIter>
228 void writeNoStatusN(std::size_t count, TIter& iter)
const =
delete;
232 return BaseImpl::valid() && canWrite();
237 template <
typename... TParams>
238 using FixedLengthLenFieldTag = comms::details::tag::Tag1<>;
240 template <
typename... TParams>
241 using VarLengthLenFieldTag = comms::details::tag::Tag2<>;
243 template <
typename... TParams>
244 std::size_t lengthInternal(FixedLengthLenFieldTag<TParams...>)
const
246 std::size_t prefixLen = 0U;
247 if (!BaseImpl::getValue().empty()) {
248 prefixLen = LenField::minLength();
250 return (prefixLen + BaseImpl::length());
253 template <
typename... TParams>
254 std::size_t lengthInternal(VarLengthLenFieldTag<TParams...>)
const
256 std::size_t prefixLen = 0U;
257 if (!BaseImpl::getValue().empty()) {
260 std::min(BaseImpl::minElementLength(), std::size_t(MaxAllowedElemLength)));
261 prefixLen = lenField.length();
264 return (prefixLen + BaseImpl::length());
267 template <
typename TIter>
268 static void advanceWriteIterator(TIter& iter, std::size_t len)
270 basic::CommonFuncs::advanceWriteIterator(iter, len);
273 template <
typename TIter>
276 auto fromIter = iter;
278 auto es = lenField.read(iter, len);
283 auto diff =
static_cast<std::size_t
>(std::distance(fromIter, iter));
287 m_elemLen =
static_cast<std::size_t
>(lenField.getValue());
288 if (m_elemLen == MaxLengthLimit) {
295 template <
typename TIter>
296 ErrorStatus writeLen(TIter& iter, std::size_t& len)
const
298 auto elemLength = BaseImpl::minElementLength();
300 lenField.setValue(elemLength);
301 auto es = lenField.write(iter, len);
306 len -= lenField.length();
310 template <
typename TIter>
311 void writeLenNoStatus(TIter& iter)
const
313 auto elemLength = BaseImpl::minElementLength();
315 lenField.setValue(elemLength);
316 lenField.writeNoStatus(iter);
319 static_assert(BaseImpl::minElementLength() == BaseImpl::maxElementLength(),
320 "Option SequenceElemFixedSerLengthFieldPrefix can be used only with fixed length "
322 static_assert(1U <= LenField::minLength(),
"Invalid min length assumption");
324 static const std::size_t MaxLengthLimit =
325 std::numeric_limits<std::size_t>::max();
326 std::size_t m_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:1580
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:19
@ 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.