COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
MsgDataLayer.h
Go to the documentation of this file.
1//
2// Copyright 2014 - 2026 (C). Alex Robenko. All rights reserved.
3//
4// SPDX-License-Identifier: MPL-2.0
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
12
13#pragma once
14
15#include "comms/Assert.h"
16#include "comms/Field.h"
17#include "comms/details/detect.h"
18#include "comms/details/tag.h"
19#include "comms/frame/details/MsgDataLayerOptionsParser.h"
21#include "comms/Message.h"
22#include "comms/MessageBase.h"
23#include "comms/util/Tuple.h"
25
26#include <cstddef>
27#include <iterator>
28#include <tuple>
29#include <type_traits>
30
31namespace comms
32{
33
34namespace frame
35{
36
42template <typename... TOptions>
44{
45 using ParsedOptionsInternal = details::MsgDataLayerOptionsParser<TOptions...>;
46
47public:
49 using ThisLayer = MsgDataLayer<TOptions...>;
50
53 {
54 return *this;
55 }
56
58 const ThisLayer& thisLayer() const
59 {
60 return *this;
61 }
62
68 using Field = typename ParsedOptionsInternal::FieldType;
69
71 using AllFields = std::tuple<Field>;
72
75 using AllMessages = void;
76
79 using MsgFactory = void;
80
82 static const std::size_t NumOfLayers = 1;
83
85 MsgDataLayer() = default;
86
88 MsgDataLayer(const MsgDataLayer&) = default;
89
92
94 ~MsgDataLayer() noexcept = default;
95
97 MsgDataLayer& operator=(const MsgDataLayer&) = default;
98
100 MsgDataLayer& operator=(MsgDataLayer&&) = default;
101
105 static constexpr bool canSplitRead()
106 {
107 return true;
108 }
109
129 template <typename TMsg, typename TIter, typename... TExtraValues>
131 TMsg& msg,
132 TIter& iter,
133 std::size_t size,
134 TExtraValues... extraValues)
135 {
136 using MsgType = typename std::decay<decltype(msg)>::type;
137 using Tag =
139 comms::isMessageBase<MsgType>()
140 >::template Type<
141 DirectOpTag<>,
143 comms::isMessage<MsgType>()
144 >::template Type<
145 InterfaceOpTag<>,
146 typename comms::util::LazyShallowConditional<
147 std::is_pointer<MsgType>::value
148 >::template Type<
149 PointerOpTag,
150 OtherOpTag
151 >
152 >
153 >;
154
155 if (setPayloadRequiredInternal(extraValues...)) {
156 auto fromIter = iter;
157 auto es = readInternal(msg, iter, size, Tag(), extraValues...);
158 setMsgPayloadInternal(fromIter, static_cast<std::size_t>(std::distance(fromIter, iter)), extraValues...);
159 return es;
160 }
161
162 return readInternal(msg, iter, size, Tag(), extraValues...);
163 }
164
168 template <typename TMsg, typename TIter, typename... TExtraValues>
170 TMsg& msg,
171 TIter& iter,
172 std::size_t size,
173 TExtraValues...)
174 {
175 static_cast<void>(msg);
176 static_cast<void>(iter);
177 static_cast<void>(size);
179 }
180
185 template <typename TMsg, typename TIter, typename... TExtraValues>
187 TMsg& msg,
188 TIter& iter,
189 std::size_t size,
190 TExtraValues... extraValues)
191 {
192 return read(msg, iter, size, extraValues...);
193 }
194
219 template <typename TAllFields, typename TMsg, typename TIter, typename... TExtraValues>
221 TAllFields& allFields,
222 TMsg& msg,
223 TIter& iter,
224 std::size_t size,
225 TExtraValues... extraValues)
226 {
227
229 "Expected TAllFields to be tuple.");
230
231 using AllFieldsDecayed = typename std::decay<TAllFields>::type;
232 static_assert(util::tupleIsTailOf<AllFields, AllFieldsDecayed>(), "Passed tuple is wrong.");
233 static const std::size_t Idx =
234 std::tuple_size<AllFieldsDecayed>::value -
235 std::tuple_size<AllFields>::value;
236
237 static_assert((Idx + 1) == std::tuple_size<TAllFields>::value,
238 "All fields must be read when MsgDataLayer is reached");
239
240 using IterType = typename std::decay<decltype(iter)>::type;
241 using IterTag = typename std::iterator_traits<IterType>::iterator_category;
242 static_assert(std::is_base_of<std::random_access_iterator_tag, IterTag>::value,
243 "Caching read from non random access iterators are not supported at this moment.");
244
245 auto& dataField = std::get<Idx>(allFields);
246
247 using FieldType = typename std::decay<decltype(dataField)>::type;
248 static_assert(
249 std::is_same<Field, FieldType>::value,
250 "Field has wrong type");
251
252 auto dataIter = iter;
253 auto es = read(msg, iter, size, extraValues...);
254 if (es != ErrorStatus::Success) {
255 return es;
256 }
257
258 auto dataSize = static_cast<std::size_t>(std::distance(dataIter, iter));
259 setMsgPayloadInternal(dataIter, dataSize, extraValues...);
260
261 auto dataEs = dataField.read(dataIter, dataSize);
262 static_cast<void>(dataEs);
264 return es;
265 }
266
270 template <typename TAllFields, typename TMsg, typename TIter, typename... TExtraValues>
272 TAllFields& allFields,
273 TMsg& msg,
274 TIter& iter,
275 std::size_t size,
276 TExtraValues...)
277 {
278 static_cast<void>(allFields);
279 static_cast<void>(msg);
280 static_cast<void>(iter);
281 static_cast<void>(size);
283 }
284
289 template <typename TAllFields, typename TMsg, typename TIter, typename... TExtraValues>
291 TAllFields& allFields,
292 TMsg& msg,
293 TIter& iter,
294 std::size_t size,
295 TExtraValues... extraValues)
296 {
297 return readFieldsCached(allFields, msg, iter, size, extraValues...);
298 }
299
317 template <typename TMsg, typename TIter>
319 const TMsg& msg,
320 TIter& iter,
321 std::size_t size)
322 {
323 using MsgType = typename std::decay<decltype(msg)>::type;
324
325 static_assert(
326 comms::isMessage<MsgType>(),
327 "The provided message object must inherit from comms::Message");
328
329 using Tag =
331 comms::isMessageBase<MsgType>()
332 >::template Type<
333 DirectOpTag<>,
335 comms::isMessage<MsgType>()
336 >::template Type<
337 InterfaceOpTag<>,
338 typename comms::util::LazyShallowConditional<
339 std::is_pointer<MsgType>::value
340 >::template Type<
341 PointerOpTag,
342 OtherOpTag
343 >
344 >
345 >;
346
347 return writeInternal(msg, iter, size, Tag());
348 }
349
365 template <typename TAllFields, typename TMsg, typename TIter>
367 TAllFields& allFields,
368 const TMsg& msg,
369 TIter& iter,
370 std::size_t size)
371 {
373 "Expected TAllFields to be tuple.");
374
375 using AllFieldsDecayed = typename std::decay<TAllFields>::type;
376 static_assert(util::tupleIsTailOf<AllFields, AllFieldsDecayed>(), "Passed tuple is wrong.");
377 static const std::size_t Idx =
378 std::tuple_size<AllFieldsDecayed>::value -
379 std::tuple_size<AllFields>::value;
380
381 static_assert((Idx + 1) == std::tuple_size<TAllFields>::value,
382 "All fields must be written when MsgDataLayer is reached");
383
384 auto& dataField = std::get<Idx>(allFields);
385 using FieldType = typename std::decay<decltype(dataField)>::type;
386 static_assert(
387 std::is_same<Field, FieldType>::value,
388 "Field has wrong type");
389
390 using IterType = typename std::decay<decltype(iter)>::type;
391 using IterTag = typename std::iterator_traits<IterType>::iterator_category;
392 return writeWithFieldCachedInternal(dataField, msg, iter, size, IterTag());
393 }
394
408 template <typename TIter>
409 static comms::ErrorStatus update(TIter& iter, std::size_t size)
410 {
411 std::advance(iter, size);
413 }
414
421 template <typename TMsg, typename TIter>
422 static comms::ErrorStatus update(const TMsg& msg, TIter& iter, std::size_t size)
423 {
424 static_cast<void>(msg);
425 return update(iter, size);
426 }
427
441 template <typename TAllFields, typename TIter>
443 TAllFields& allFields,
444 TIter& iter,
445 std::size_t size)
446 {
447 static_cast<void>(allFields);
448 std::advance(iter, size);
450 }
451
467 template <typename TAllFields, typename TMsg, typename TIter>
469 TAllFields& allFields,
470 const TMsg& msg,
471 TIter& iter,
472 std::size_t size)
473 {
474 static_cast<void>(allFields);
475 static_cast<void>(msg);
476 std::advance(iter, size);
478 }
479
485 static constexpr std::size_t length()
486 {
487 return 0U;
488 }
489
498 template <typename TMsg>
499 static constexpr std::size_t length(const TMsg& msg)
500 {
501 using MsgType = typename std::decay<decltype(msg)>::type;
502
503 static_assert(
504 comms::isMessage<MsgType>(),
505 "The provided message object must inherit from comms::Message");
506
507 using Tag =
508 typename comms::util::LazyShallowConditional<
509 details::FrameLayerHasFieldsImpl<MsgType>::Value
510 >::template Type<
511 MsgDirectLengthTag,
512 MsgHasLengthTag
513 >;
514 return getMsgLength(msg, Tag());
515 }
516
521 template <typename TAllFields>
522 static auto accessCachedField(TAllFields& allFields) ->
523 decltype(std::get<std::tuple_size<typename std::decay<TAllFields>::type>::value - std::tuple_size<AllFields>::value>(allFields))
524 {
525 using AllFieldsDecayed = typename std::decay<TAllFields>::type;
526 static_assert(util::tupleIsTailOf<AllFields, AllFieldsDecayed>(), "Passed tuple is wrong.");
527 static const std::size_t Idx =
528 std::tuple_size<AllFieldsDecayed>::value -
529 std::tuple_size<AllFields>::value;
530
531 return std::get<Idx>(allFields);
532 }
533
534private:
535 template <typename... TParams>
536 using MsgHasLengthTag = comms::details::tag::Tag1<>;
537
538 template <typename... TParams>
539 using MsgNoLengthTag = comms::details::tag::Tag2<>;
540
541 template <typename... TParams>
542 using MsgDirectLengthTag = comms::details::tag::Tag3<>;
543
544 template <typename... TParams>
545 using DirectOpTag = comms::details::tag::Tag4<>;
546
547 template <typename... TParams>
548 using InterfaceOpTag = comms::details::tag::Tag5<>;
549
550 template <typename... TParams>
551 using PointerOpTag = comms::details::tag::Tag6<>;
552
553 template <typename... TParams>
554 using OtherOpTag = comms::details::tag::Tag7<>;
555
556 template <typename TMsg, typename TIter>
557 static ErrorStatus writeWithFieldCachedInternal(
558 Field& field,
559 const TMsg& msg,
560 TIter& iter,
561 std::size_t size,
562 std::random_access_iterator_tag)
563 {
564 return writeWithFieldCachedRandomAccess(field, msg, iter, size);
565 }
566
567 template <typename TMsg, typename TIter>
568 static ErrorStatus writeWithFieldCachedInternal(
569 Field& field,
570 const TMsg& msg,
571 TIter& iter,
572 std::size_t size,
573 std::output_iterator_tag)
574 {
575 return writeWithFieldCachedOutput(field, msg, iter, size);
576 }
577
578 template <typename TMsg, typename TIter>
579 static ErrorStatus writeWithFieldCachedRandomAccess(
580 Field& field,
581 const TMsg& msg,
582 TIter& iter,
583 std::size_t size)
584 {
585 auto dataReadIter = iter;
586 auto es = write(msg, iter, size);
587 if (es != comms::ErrorStatus::Success) {
588 return es;
589 }
590
591 auto writtenCount = static_cast<std::size_t>(std::distance(dataReadIter, iter));
592 auto dataEs = field.read(dataReadIter, writtenCount);
594 static_cast<void>(dataEs);
596 }
597
598 template <typename TMsg, typename TCollection>
599 static ErrorStatus writeWithFieldCachedOutput(
600 Field& field,
601 const TMsg& msg,
602 std::back_insert_iterator<TCollection>& iter,
603 std::size_t size)
604 {
605 auto es = write(msg, iter, size);
606 if (es != comms::ErrorStatus::Success) {
607 return es;
608 }
609
610 TCollection col;
611 auto dataWriteIter = std::back_inserter(col);
612 auto dataWriteEs = write(msg, dataWriteIter, size);
614 static_cast<void>(dataWriteEs);
615
616 auto dataReadIter = col.cbegin();
617 auto dataReadEs = field.read(dataReadIter, col.size());
619 static_cast<void>(dataReadEs);
620
622 }
623
624 template <typename TMsg, typename... TParams>
625 static std::size_t getMsgLength(const TMsg& msg, MsgHasLengthTag<TParams...>)
626 {
627 using MsgType = typename std::decay<decltype(msg)>::type;
628 static_assert(MsgType::hasLength(), "Message interface must define length()");
629 return msg.length();
630 }
631
632 template <typename TMsg, typename... TParams>
633 static constexpr std::size_t getMsgLength(const TMsg& msg, MsgDirectLengthTag<TParams...>)
634 {
635 using MsgType = typename std::decay<decltype(msg)>::type;
636 static_assert(MsgType::hasFields(), "FieldsImpl option hasn't been used");
637 return msg.doLength();
638 }
639
640 template <typename TMsg, typename... TParams>
641 static constexpr std::size_t getMsgLength(const TMsg&, MsgNoLengthTag<TParams...>)
642 {
643 return 0U;
644 }
645
646 template <typename TMsg, typename TIter, typename... TExtraValues>
647 static ErrorStatus readInternalPolymorphic(
648 TMsg& msg,
649 TIter& iter,
650 std::size_t size,
651 TExtraValues... extraValues)
652 {
653 using MsgType = typename std::decay<decltype(msg)>::type;
654
655 static_assert(
656 comms::isMessage<MsgType>(),
657 "The provided message object must inherit from comms::Message");
658
659 static_assert(MsgType::hasRead(),
660 "Message interface must support polymorphic read operation");
661
662 using IterType = typename std::decay<decltype(iter)>::type;
663
664 static_assert(std::is_convertible<IterType, typename MsgType::ReadIterator>::value,
665 "The provided iterator is not convertible to ReadIterator defined by Message class");
666
667 using ReadIter = typename std::add_lvalue_reference<typename MsgType::ReadIterator>::type;
668
669 auto result = msg.read(static_cast<ReadIter>(iter), size);
670 if ((result == ErrorStatus::NotEnoughData) &&
671 missingSizeRequiredInternal(extraValues...)) {
672 using Tag =
673 typename comms::util::LazyShallowConditional<
674 MsgType::hasLength()
675 >::template Type<
676 MsgHasLengthTag,
677 MsgNoLengthTag
678 >;
679
680 std::size_t missingSize = 1U;
681 auto msgLen = getMsgLength(msg, Tag());
682 if (size < msgLen) {
683 missingSize = msgLen - size;
684 }
685 updateMissingSizeInternal(missingSize, extraValues...);
686 }
687 return result;
688 }
689
690 template <typename TMsg, typename TIter, typename... TExtraValues>
691 static ErrorStatus readInternalDirect(
692 TMsg& msg,
693 TIter& iter,
694 std::size_t size,
695 TExtraValues... extraValues)
696 {
697 using MsgType = typename std::decay<decltype(msg)>::type;
698
699 static_assert(
700 comms::isMessageBase<MsgType>(),
701 "The provided message object must inherit from comms::MessageBase");
702
703 static_assert(details::frameLayerHasFieldsImpl<MsgType>(),
704 "Message class must use FieldsImpl option");
705
706 auto result = msg.doRead(iter, size);
707 if ((result == ErrorStatus::NotEnoughData) &&
708 (missingSizeRequiredInternal(extraValues...))) {
709 std::size_t missingSize = 1U;
710 auto msgLen = getMsgLength(msg, MsgDirectLengthTag<>());
711 if (size < msgLen) {
712 missingSize = msgLen - size;
713 }
714 updateMissingSizeInternal(missingSize, extraValues...);
715 }
716 return result;
717 }
718
719 template <typename TMsg, typename TIter, typename... TExtraValues>
720 static ErrorStatus readInternal(
721 TMsg& msg,
722 TIter& iter,
723 std::size_t size,
724 DirectOpTag<>,
725 TExtraValues... extraValues)
726 {
727 return readInternalDirect(msg, iter, size, extraValues...);
728 }
729
730 template <typename TMsg, typename TIter, typename... TExtraValues>
731 static ErrorStatus readInternal(
732 TMsg& msg,
733 TIter& iter,
734 std::size_t size,
735 InterfaceOpTag<>,
736 TExtraValues... extraValues)
737 {
738 static_assert(comms::isMessage<TMsg>(), "Must be interface class");
739 static_assert(TMsg::hasRead(),
740 "Message interface must support polymorphic read operation");
741
742 return readInternalPolymorphic(msg, iter, size, extraValues...);
743 }
744
745 template <typename TMsg, typename TIter, typename... TExtraValues>
746 static ErrorStatus readInternal(
747 TMsg& msg,
748 TIter& iter,
749 std::size_t size,
750 PointerOpTag<>,
751 TExtraValues... extraValues)
752 {
753 return read(*msg, iter, size, extraValues...);
754 }
755
756 template <typename TMsg, typename TIter, typename... TExtraValues>
757 static ErrorStatus readInternal(
758 TMsg& msg,
759 TIter& iter,
760 std::size_t size,
761 OtherOpTag<>,
762 TExtraValues... extraValues)
763 {
764 using MsgType = typename std::decay<decltype(msg)>::type;
765 static_assert(comms::details::hasElementType<MsgType>(),
766 "Unsupported type of message object, expected to be either message itself, raw pointer or smart pointer");
767 return read(*msg, iter, size, extraValues...);
768 }
769
770 template <typename TMsg, typename TIter, typename... TParams>
771 static ErrorStatus writeInternal(
772 const TMsg& msg,
773 TIter& iter,
774 std::size_t size,
775 DirectOpTag<TParams...>)
776 {
777 return msg.doWrite(iter, size);
778 }
779
780 template <typename TMsg, typename TIter, typename... TParams>
781 static ErrorStatus writeInternal(
782 const TMsg& msg,
783 TIter& iter,
784 std::size_t size,
785 InterfaceOpTag<TParams...>)
786 {
787 using MsgType = typename std::decay<decltype(msg)>::type;
788
789 static_assert(MsgType::hasWrite(),
790 "Message interface must support polymorphic write operation");
791
792 using IterType = typename std::decay<decltype(iter)>::type;
793
794 static_assert(std::is_convertible<IterType, typename MsgType::WriteIterator>::value,
795 "The provided iterator is not convertible to WriteIterator defined by Message class");
796
797 using WriteIter = typename std::add_lvalue_reference<typename MsgType::WriteIterator>::type;
798
799 return msg.write(static_cast<WriteIter>(iter), size);
800 }
801
802 template <typename TMsg, typename TIter, typename... TParams>
803 static ErrorStatus writeInternal(
804 const TMsg& msg,
805 TIter& iter,
806 std::size_t size,
807 PointerOpTag<TParams...>)
808 {
809 return write(*msg, iter, size);
810 }
811
812 template <typename TMsg, typename TIter, typename... TParams>
813 static ErrorStatus writeInternal(
814 const TMsg& msg,
815 TIter& iter,
816 std::size_t size,
817 OtherOpTag<TParams...>)
818 {
819 using MsgType = typename std::decay<decltype(msg)>::type;
820 static_assert(comms::details::hasElementType<MsgType>(),
821 "Unsupported type of message object, expected to be either message itself, raw pointer or smart pointer");
822
823 return write(*msg, iter, size);
824 }
825
826 static constexpr bool missingSizeRequiredInternal()
827 {
828 return false;
829 }
830
831 template <typename... TExtraValues>
832 static bool missingSizeRequiredInternal(details::MissingSizeRetriever<>, TExtraValues...)
833 {
834 return true;
835 }
836
837 template <typename T, typename... TExtraValues>
838 static bool missingSizeRequiredInternal(T, TExtraValues... extraValues)
839 {
840 static_assert(
841 !details::isMissingSizeRetriever<T>(),
842 "Mustn't be missing size retriever");
843 return missingSizeRequiredInternal(extraValues...);
844 }
845
846 static void updateMissingSizeInternal(std::size_t val)
847 {
848 static_cast<void>(val);
849 }
850
851 template <typename... TExtraValues>
852 static void updateMissingSizeInternal(
853 std::size_t val,
854 details::MissingSizeRetriever<> retriever,
855 TExtraValues... extraValues)
856 {
857 retriever.setValue(val);
858 updateMissingSizeInternal(val, extraValues...);
859 }
860
861 template <typename T, typename... TExtraValues>
862 static void updateMissingSizeInternal(std::size_t val, T retriever, TExtraValues... extraValues)
863 {
864 static_cast<void>(retriever);
865 static_assert(
866 !details::isMissingSizeRetriever<typename std::decay<decltype(retriever)>::type>(),
867 "Mustn't be missing size retriever");
868 updateMissingSizeInternal(val, extraValues...);
869 }
870
871 static constexpr bool setPayloadRequiredInternal()
872 {
873 return false;
874 }
875
876 template <typename TIter, typename... TExtraValues>
877 static bool setPayloadRequiredInternal(details::MsgPayloadRetriever<TIter>, TExtraValues...)
878 {
879 return true;
880 }
881
882 template <typename T, typename... TExtraValues>
883 static bool setPayloadRequiredInternal(T, TExtraValues... extraValues)
884 {
885 static_assert(
886 !details::isMsgPayloadRetriever<T>(),
887 "Mustn't be message payload retriever");
888 return setPayloadRequiredInternal(extraValues...);
889 }
890
891 template <typename TIter>
892 static void setMsgPayloadInternal(TIter iter, std::size_t len)
893 {
894 static_cast<void>(iter);
895 static_cast<void>(len);
896 }
897
898 template <typename TIter, typename TOtherIter, typename... TExtraValues>
899 static void setMsgPayloadInternal(
900 TIter iter,
901 std::size_t len,
902 details::MsgPayloadRetriever<TOtherIter> retriever,
903 TExtraValues... extraValues)
904 {
905 retriever.setValue(iter, len);
906 setMsgPayloadInternal(iter, len, extraValues...);
907 }
908
909 template <typename TIter, typename T, typename... TExtraValues>
910 static void setMsgPayloadInternal(
911 TIter iter,
912 std::size_t len,
913 T retriever,
914 TExtraValues... extraValues)
915 {
916 static_cast<void>(retriever);
917 static_assert(
918 !details::isMsgPayloadRetriever<typename std::decay<decltype(retriever)>::type>(),
919 "Mustn't be message payload retriever");
920 setMsgPayloadInternal(iter, len, extraValues...);
921 }
922};
923
924namespace details
925{
926template <typename T>
927struct MsgDataLayerCheckHelper
928{
929 static const bool Value = false;
930};
931
932template <typename... TExtraOpts>
933struct MsgDataLayerCheckHelper<MsgDataLayer<TExtraOpts...> >
934{
935 static const bool Value = true;
936};
937
938} // namespace details
939
943template <typename T>
944constexpr bool isMsgDataLayer()
945{
946 return details::MsgDataLayerCheckHelper<T>::Value;
947}
948
949template <typename... TExtraOpts>
950constexpr
951MsgDataLayer<TExtraOpts...>&
953{
954 return layer;
955}
956
957template <typename... TExtraOpts>
958constexpr
959const MsgDataLayer<TExtraOpts...>&
960toFrameLayerBase(const MsgDataLayer<TExtraOpts...>& layer)
961{
962 return layer;
963}
964
965} // namespace frame
966
967} // namespace comms
968
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
Contains definition of comms::Field class.
Contains definition of comms::frame::FrameLayerBase.
Provides common base class for the custom messages with default implementation.
Contains definition of Message object interface and various base classes for custom messages.
Contains various tuple type manipulation classes and functions.
Base class to all the field classes.
Definition Field.h:36
Message data layer.
Definition MsgDataLayer.h:44
MsgDataLayer()=default
Default constructor.
static ErrorStatus readFromData(TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Same as read().
Definition MsgDataLayer.h:186
static constexpr std::size_t length()
Get remaining length of wrapping transport information.
Definition MsgDataLayer.h:485
static comms::ErrorStatus update(const TMsg &msg, TIter &iter, std::size_t size)
Update recently written (using write()) message contents data.
Definition MsgDataLayer.h:422
constexpr bool isMsgDataLayer()
Compile time check of whether the provided type is a variant of MsgDataLayer.
Definition MsgDataLayer.h:944
std::tuple< Field > AllFields
All fields of the remaining transport layers, contains only Field.
Definition MsgDataLayer.h:71
static const std::size_t NumOfLayers
Static constant indicating amount of transport layers used.
Definition MsgDataLayer.h:82
typename ParsedOptionsInternal::FieldType Field
Raw data field type.
Definition MsgDataLayer.h:68
MsgDataLayer(const MsgDataLayer &)=default
Copy constructor.
static comms::ErrorStatus update(TIter &iter, std::size_t size)
Update recently written (using write()) message contents data.
Definition MsgDataLayer.h:409
~MsgDataLayer() noexcept=default
Destructor.
static ErrorStatus readFieldsCached(TAllFields &allFields, TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Read the message contents while caching the read transport information fields.
Definition MsgDataLayer.h:220
void AllMessages
Default value of AllMessages type.
Definition MsgDataLayer.h:75
static ErrorStatus readUntilDataFieldsCached(TAllFields &allFields, TMsg &msg, TIter &iter, std::size_t size, TExtraValues...)
Read transport fields with caching until data layer.
Definition MsgDataLayer.h:271
static auto accessCachedField(TAllFields &allFields) -> decltype(std::get< std::tuple_size< typename std::decay< TAllFields >::type >::value - std::tuple_size< AllFields >::value >(allFields))
Access appropriate field from "cached" bundle of all the frame fields.
Definition MsgDataLayer.h:522
void MsgFactory
Default value of MsgFactory type.
Definition MsgDataLayer.h:79
static ErrorStatus readUntilData(TMsg &msg, TIter &iter, std::size_t size, TExtraValues...)
Read transport fields until data layer.
Definition MsgDataLayer.h:169
static ErrorStatus readFromDataFeildsCached(TAllFields &allFields, TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Same as readFieldsCached().
Definition MsgDataLayer.h:290
static constexpr std::size_t length(const TMsg &msg)
Get remaining length of wrapping transport information + length of the provided message.
Definition MsgDataLayer.h:499
static ErrorStatus write(const TMsg &msg, TIter &iter, std::size_t size)
Write the message contents.
Definition MsgDataLayer.h:318
static ErrorStatus updateFieldsCached(TAllFields &allFields, TIter &iter, std::size_t size)
Update recently written (using writeFieldsCached()) message data as well as cached transport informat...
Definition MsgDataLayer.h:442
static ErrorStatus read(TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Read the message contents.
Definition MsgDataLayer.h:130
ThisLayer & thisLayer()
Get access to this layer object.
Definition MsgDataLayer.h:52
static ErrorStatus writeFieldsCached(TAllFields &allFields, const TMsg &msg, TIter &iter, std::size_t size)
Write the message contents while caching the written transport information fields.
Definition MsgDataLayer.h:366
static ErrorStatus updateFieldsCached(TAllFields &allFields, const TMsg &msg, TIter &iter, std::size_t size)
Update recently written (using writeFieldsCached()) message data as well as cached transport informat...
Definition MsgDataLayer.h:468
MsgDataLayer(MsgDataLayer &&)=default
Move constructor.
const ThisLayer & thisLayer() const
Get "const" access to this layer object.
Definition MsgDataLayer.h:58
static constexpr bool canSplitRead()
Compile time check whether split read "until" and "from" data layer is allowed.
Definition MsgDataLayer.h:105
details::MissingSizeRetriever missingSize(std::size_t &val)
Add "missing size" output parameter to frame's "read" operation.
Definition FrameLayerBase.h:1564
FrameLayerBase< TField, TNextLayer, TDerived, TOptions... > & toFrameLayerBase(FrameLayerBase< TField, TNextLayer, TDerived, TOptions... > &layer)
Upcast protocol layer in order to have access to its internal types.
Definition FrameLayerBase.h:1524
comms::option::def::MsgType< TMsg > MsgType
Same as comms::option::def::MsgType.
Definition options.h:1500
comms::frame::MsgDataLayer< TOptions... > MsgDataLayer
Alias to the comms::frame::MsgDataLayer.
Definition MsgDataLayer.h:27
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.
Replacement to std::conditional.
Definition type_traits.h:32
Check whether provided type is a variant of std::tuple.
Definition Tuple.h:39
Replacement to some types from standard type_traits.