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