57class SyncPrefixLayer :
public comms::frame::details::SyncPrefixLayerBase<TField, TNextLayer, TOptions...>
59 using BaseImpl = comms::frame::details::SyncPrefixLayerBase<TField, TNextLayer, TOptions...>;
60 using ParsedOptionsInternal = comms::frame::details::SyncPrefixLayerOptionsParser<TOptions...>;
64 using Field =
typename BaseImpl::Field;
68 using EscField =
typename ParsedOptionsInternal::EscField;
84 static constexpr
bool hasExtendingClass()
86 return ParsedOptionsInternal::HasExtendingClass;
117 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
123 TNextLayerReader&& nextLayerReader,
124 TExtraValues... extraValues)
127 typename comms::util::LazyShallowConditional<
128 ParsedOptionsInternal::HasSeekField
140 std::forward<TNextLayerReader>(nextLayerReader),
162 template <
typename TMsg,
typename TIter,
typename TNextLayerWriter>
168 TNextLayerWriter&& nextLayerWriter)
const
170 auto& thisObj = BaseImpl::thisLayer();
171 thisObj.prepareFieldForWrite(field);
172 auto es = thisObj.doWriteField(&msg, field, iter, size);
173 if (es != ErrorStatus::Success) {
178 return nextLayerWriter.write(msg, iter, size - field.length());
190 return field ==
Field();
199 template <
typename TEscField>
202 return field == TEscField();
214 static_cast<void>(field);
218 template <
typename... TParams>
219 using SeekFieldTag = comms::details::tag::Tag1<>;
221 template <
typename... TParams>
222 using InstantOpTag = comms::details::tag::Tag2<>;
224 template <
typename... TParams>
225 using EscapeSupportedTag = comms::details::tag::Tag3<>;
227 template <
typename... TParams>
228 using NoEscapeTag = comms::details::tag::Tag4<>;
230 template <
typename TMsg,
typename TIter,
typename TReader,
typename... TExtraValues>
236 TReader&& nextLayerReader,
238 TExtraValues... extraValues)
240 using IterType =
typename std::decay<
decltype(iter)>::type;
241 static_assert(std::is_same<typename std::iterator_traits<IterType>::iterator_category, std::random_access_iterator_tag>::value,
242 "The read operation is expected to use random access iterator");
244 auto& thisObj = BaseImpl::thisLayer();
245 auto* msgPtr = BaseImpl::toMsgPtr(msg);
247 auto fromIter = iter;
248 std::size_t consumed = 0U;
249 while (consumed < size) {
251 auto remSize = size - consumed;
253 auto fieldEs = thisObj.doReadField(msgPtr, field, iterTmp, remSize);
254 if (fieldEs == ErrorStatus::NotEnoughData) {
255 BaseImpl::updateMissingSize(field, remSize, extraValues...);
256 BaseImpl::resetMsg(msg);
260 if ((fieldEs == ErrorStatus::Success) &&
261 (!fieldEscapedInternal(fromIter, iter)) &&
262 (thisObj.verifyFieldValue(field))) {
272 if (size <= consumed) {
274 return ErrorStatus::NotEnoughData;
277 auto remSize = size -
static_cast<std::size_t
>(std::distance(fromIter, iter));
278 return nextLayerReader.read(msg, iter, remSize, extraValues...);
281 template <
typename TMsg,
typename TIter,
typename TReader,
typename... TExtraValues>
287 TReader&& nextLayerReader,
289 TExtraValues... extraValues)
291 auto& thisObj = BaseImpl::thisLayer();
292 auto* msgPtr = BaseImpl::toMsgPtr(msg);
293 auto beforeReadIter = iter;
295 auto es = thisObj.doReadField(msgPtr, field, iter, size);
297 BaseImpl::updateMissingSize(field, size, extraValues...);
304 bool verified = thisObj.verifyFieldValue(field);
309 auto fieldLen =
static_cast<std::size_t
>(std::distance(beforeReadIter, iter));
310 return nextLayerReader.read(msg, iter, size - fieldLen, extraValues...);
313 template <
typename TIter>
314 bool fieldEscapedInternal(TIter from, TIter to, NoEscapeTag<>)
316 static_cast<void>(from);
317 static_cast<void>(to);
321 template <
typename TIter>
322 bool fieldEscapedInternal(TIter from, TIter to, EscapeSupportedTag<>)
324 unsigned escCount = 0U;
325 auto& thisObj = BaseImpl::thisLayer();
328 auto dist =
static_cast<std::size_t
>(std::distance(from, to));
329 dist = std::min(dist, EscField::maxLength());
330 if (dist < EscField::minLength()) {
334 auto maxLenIter = to;
335 std::advance(maxLenIter, -
static_cast<int>(dist));
338 std::advance(iter, -
static_cast<int>(EscField::minLength()));
339 auto prevCount = escCount;
343 auto len =
static_cast<std::size_t
>(std::distance(iterTmp, to));
344 auto es = escField.read(iterTmp, len);
347 (thisObj.verifyEscFieldValue(escField))) {
352 if (iter == maxLenIter) {
356 std::advance(iter, -1);
359 if (prevCount == escCount) {
369 return (escCount & 0x1) != 0U;
372 template <
typename TIter>
373 bool fieldEscapedInternal(TIter from, TIter to)
376 typename comms::util::LazyShallowConditional<
377 std::is_same<EscField, void>::value
383 return fieldEscapedInternal(from, to, EscTag());
comms::ErrorStatus doRead(Field &field, TMsg &msg, TIter &iter, std::size_t size, TNextLayerReader &&nextLayerReader, TExtraValues... extraValues)
Customized read functionality, invoked by read().
Definition SyncPrefixLayer.h:118